 |
forums.ps2dev.org Homebrew PS2, PSP & PS3 Development Discussions
|
| View previous topic :: View next topic |
| Author |
Message |
Shazz

Joined: 31 Aug 2004 Posts: 244 Location: Somewhere over the rainbow
|
Posted: Sun Feb 19, 2006 3:48 am Post subject: |
|
|
Short question, what do we have in 0xbc100080 ?????? (And the value 7 for ?)
| Code: |
li k0, 0xbc100000
li t0, 7
sw t0, 80(k0)
|
Shouldn't it be 0xbc100050 to enable the ME clock ?
Thx _________________ - TiTAN Art Division -
http://www.titandemo.org
Last edited by Shazz on Tue Feb 21, 2006 12:46 am; edited 1 time in total |
|
| Back to top |
|
 |
Shazz

Joined: 31 Aug 2004 Posts: 244 Location: Somewhere over the rainbow
|
Posted: Mon Feb 20, 2006 7:09 pm Post subject: |
|
|
Hum, and an other little question, what's missing/the we should implement/... on the m.e side to have threads support ???? (as it's done on the core side, without reimplementing the wheel) _________________ - TiTAN Art Division -
http://www.titandemo.org |
|
| Back to top |
|
 |
crazyc
Joined: 17 Jun 2005 Posts: 410
|
Posted: Tue Feb 21, 2006 2:39 am Post subject: |
|
|
| Shazz wrote: | Short question, what do we have in 0xbc100080 ?????? (And the value 7 for ?)
| Code: |
li k0, 0xbc100000
li t0, 7
sw t0, 80(k0)
|
Shouldn't it be 0xbc100050 to enable the ME clock ?
Thx |
Access to system memory causes an exception unless that is done.
| Quote: | | Hum, and an other little question, what's missing/the we should implement/... on the m.e side to have threads support ? |
The me has no kernel. Any threading would have to be written from scratch. |
|
| Back to top |
|
 |
Shazz

Joined: 31 Aug 2004 Posts: 244 Location: Somewhere over the rainbow
|
Posted: Tue Feb 21, 2006 4:21 am Post subject: |
|
|
Thanks for the tip ;-) _________________ - TiTAN Art Division -
http://www.titandemo.org |
|
| Back to top |
|
 |
jockyw2001
Joined: 29 Sep 2005 Posts: 339
|
Posted: Wed Jul 05, 2006 8:33 pm Post subject: |
|
|
I've started adding AVC hw decode support in the PMP VLC mediaplayer. The problem is that either ME or AVC can be used for video decoding. So I'd like to reset the ME after playing a non-AVC video and likewise to reset the AVC after playing an AVC video.
My questions therefore are how to reset the ME and how to reset the AVC hw. Since this thread is about ME let's just focus on the first question.
The ME is initialized with a call to me_struct_init() and a function is started with me_start(int func, int param)
| Code: |
struct me_struct
{
int start;
int end;
void (*func)(int);
int param;
};
volatile struct me_struct *nocache;
void me_stub(void);
void me_stub_end(void);
void me_startproc(u32 func, u32 param)
{
memcpy((void *) 0xbfc00040, me_stub, (int) (me_stub_end - me_stub));
_sw(func, 0xbfc00600);
_sw(param, 0xbfc00604);
sceKernelDcacheWritebackAll();
sceSysregMeResetEnable();
sceSysregMeBusClockEnable();
sceSysregMeResetDisable();
}
void me_function(int unused)
{
while (1)
{
while (nocache->start == 0);
nocache->start = 0;
nocache->func(nocache->param);
nocache->end = 1;
}
}
int me_struct_init()
{
nocache = malloc_64(sizeof(struct me_struct));
if (nocache == 0) return(0);
nocache = (volatile struct me_struct *) (((int) nocache) | 0x40000000);
sceKernelDcacheWritebackInvalidateAll();
nocache->start = 0;
nocache->end = 1;
nocache->func = 0;
nocache->param = 0;
me_startproc((u32) me_function, 0);
return(1);
}
void me_start(int func, int param)
{
nocache->end = 0;
nocache->func = (void (*)(int)) func;
nocache->param = param;
nocache->start = 1;
}
|
Does anyone have ideas how to reset the ME ? |
|
| Back to top |
|
 |
groepaz

Joined: 01 Sep 2005 Posts: 305
|
|
| Back to top |
|
 |
hlide
Joined: 10 Sep 2006 Posts: 750
|
Posted: Tue Oct 10, 2006 8:32 pm Post subject: |
|
|
| Brunni wrote: | Okay thx
I did some tries to get it to work and synchronize with the main CPU. But I'm having some serious problems. I was first invalidating the d-cache each time I finished to write informations to variables that should be used by the ME, but it slows down quite a lot.
So I replaced this method with writing to uncached addresses. Altrough I've found anywhere, I assumed that I could also add 0x40000000 to bypass cache with RAM variables (0x80000000). I did a simple synchronization:
...< cut >...
|
I'm not an expert, but there is an instruction "sync" which may help you. Here is what I found :
EXAMPLE : These code fragments show how SYNC can be used to coordinate the
use of shared data between separate writer and reader instruction streams in a
multiprocessor environment. The FLAG location is used by the instruction streams to
determine whether the shared data item DATA is valid. The SYNC executed by
processor A forces the store of DATA to be performed globally before the store to FLAG
is performed. The SYNC executed by processor B ensures that DATA is not read until
after the FLAG value indicates that the shared data is valid.
Implementation Notes:
There may be side effects of uncached loads and stores that affect cached coherent load
and store operations. To permit the reliable use of such side effects, buffered uncached
stores that occur before the SYNC must be written to memory before cached coherent
loads and stores after the SYNC may be performed.
Processor A (writer) | Code: | # Conditions at entry:
# The value 0 has been stored in FLAG and that value is observable by B.
SW R1, DATA # change shared DATA value
LI R2, 1
SYNC # perform DATA store before performing FLAG store
SW R2, FLAG # say that the shared DATA value is valid |
Processor B (reader)
| Code: | LI R2, 1
1: LW R1, FLAG # get FLAG
BNE R2, R1, 1B # if it says that DATA is not valid, poll again
NOP
SYNC # FLAG value checked before doing DATA reads
LW R1, DATA # read (valid) shared DATA values |
|
|
| Back to top |
|
 |
hlide
Joined: 10 Sep 2006 Posts: 750
|
Posted: Wed Nov 29, 2006 8:18 pm Post subject: |
|
|
| crazyc wrote: | | The local ram is at 0x80000000, in my library I use it for heap and stack, that seems to be what sony does too. What's at 0x04000000 is probably mmio, but all I know for sure is that it's not ram. |
could it be the interface which allows ME processor to reprogram AVC decoder or VME DSP (I was heard it is kind of a FPGA) ? |
|
| Back to top |
|
 |
NeoTechni
Joined: 30 Oct 2006 Posts: 15
|
Posted: Sat Dec 02, 2006 1:28 pm Post subject: Custom soundtracks |
|
|
Has anyone figured out how to use the media engine for MP3 playback?
I have custom soundtracks implimented in my game, but I'd prefer to have the full main processor for the game itself |
|
| Back to top |
|
 |
jockyw2001
Joined: 29 Sep 2005 Posts: 339
|
Posted: Mon Feb 12, 2007 7:04 am Post subject: |
|
|
| My user mode prx program invokes functions in a kernel mode prx to run functions on the ME. The key function is me_start() which is listed in my posting above. As long as I pass a kernel space function address to me_start() the function executes just fine, however functions in user space don't work. I wonder if the ME can access user space memory using some kind of trick. Can that be done? It would make porting of apps which use ME from 1.50 to 3.x so much easier. |
|
| Back to top |
|
 |
crazyc
Joined: 17 Jun 2005 Posts: 410
|
Posted: Mon Feb 12, 2007 7:22 am Post subject: |
|
|
| jockyw2001 wrote: | | I wonder if the ME can access user space memory using some kind of trick. Can that be done? |
I don't know if this is the problem, but if you put this in you ME startup code, it will disable the kernel memory protection.
| Code: | li $t0, 0xbc00002c
li $t1, 0xbc000000
li $t2, -1
c:
sw $t2, 0($t1)
bne $t1, $t0, c |
|
|
| Back to top |
|
 |
jockyw2001
Joined: 29 Sep 2005 Posts: 339
|
Posted: Mon Feb 12, 2007 7:43 am Post subject: |
|
|
| crazyc wrote: | I don't know if this is the problem, but if you put this in you ME startup code, it will disable the kernel memory protection.
| Code: | li $t0, 0xbc00002c
li $t1, 0xbc000000
li $t2, -1
c:
sw $t2, 0($t1)
bne $t1, $t0, c |
|
Like this?
| Code: | #include <regdef.h>
#define STATUS $12
#define CAUSE $13
#define CONFIG $16
#define TAGLO $28
#define TAGHI $29
#define IXIST 0x01
#define DXIST 0x11
.global me_stub
.global me_stub_end
.set noreorder
.set noat
me_stub:
li k0, 0xbc100000
li t0, 7
sw t0, 80(k0)
mtc0 zero, TAGLO
mtc0 zero, TAGHI
li k1, 8192
a:
addi k1, k1, -64
bne k1, zero, a
cache IXIST, 0(k1)
li k1, 8192
b:
addi k1, k1, -64
bne k1, zero, b
cache DXIST, 0(k1)
mtc0 zero, CAUSE
li t0, 0xbc00002c
li t1, 0xbc000000
li t2, -1
c:
sw t2, 0(t1)
bne t1, t0, c
li k0, 0x20000000
mtc0 k0, STATUS
sync
li t0, 0xbfc00000
lw a0, 0x604(t0)
lw k0, 0x600(t0)
li sp, 0x80200000
jr k0
nop
me_stub_end: |
The problem is that a function with for example address 0x08123456 (user space) doesn't run, whereas a function with for example address 0x88123456 (kernel space) runs fine. |
|
| Back to top |
|
 |
hlide
Joined: 10 Sep 2006 Posts: 750
|
Posted: Mon Feb 12, 2007 4:14 pm Post subject: |
|
|
| jockyw2001 wrote: |
| Code: |
...
li t0, 0xbc00002c
li t1, 0xbc000000
li t2, -1
c:
sw t2, 0(t1)
bne t1, t0, c
li k0, 0x20000000
...
|
|
shouldn't be
| Code: |
...
li t0, 0xbc00002c
li t1, 0xbc000000
li t2, -1
c:
sw t2, 0(t1)
bne t1, t0, c
addiu t1, t1, 4
li k0, 0x20000000
...
| ?
so far as I remember you can access data with a "user mode" address. But I never try to call such an address. What for ? usually you don't call a function in user mode with ME processor because those functions are normally for ME processor and then can be executed in kernel mode. Any direct jump or call can be executed without any problem since they don't care about segments. For indirect jump or call, it is another story because you can change the segment this way (kseg and kuseg) if the register contains an address to another segment. I don't see why you cannot enter in user mode but it would be a problem to return kernel mode since a user mode function cannot call a function or jump into a kernel mode from a user mode for security reason. The only way to return kernel mode is through a syscall.
So if you need to use a user mode function through an indirect call, don't forget to or the register with 0x80000000 beforehand.
I see register but in C see it as a pointer onto a function. |
|
| Back to top |
|
 |
jockyw2001
Joined: 29 Sep 2005 Posts: 339
|
Posted: Mon Feb 12, 2007 6:30 pm Post subject: |
|
|
[quote="hlide"]shouldn't be
| Code: |
...
addiu t1, t1, 4
...
|
Yes, that looks better. But afaik this is just for enabling 64MB ?
| Quote: | | so far as I remember you can access data with a "user mode" address. |
No, doesn't work
| Quote: | | But I never try to call such an address. What for ? |
The whole idea is to port apps to 3.x firmwares and minimize the porting work. And the bulk of the routines I like to run on ME are in the parent user mode module. It's a bit of a pain to separate these routines out and put them in the ME kernel mode child module.
| Quote: | | usually you don't call a function in user mode with ME processor because those functions are normally for ME processor and then can be executed in kernel mode. Any direct jump or call can be executed without any problem since they don't care about segments. For indirect jump or call, it is another story because you can change the segment this way (kseg and kuseg) if the register contains an address to another segment. I don't see why you cannot enter in user mode but it would be a problem to return kernel mode since a user mode function cannot call a function or jump into a kernel mode from a user mode for security reason. The only way to return kernel mode is through a syscall. |
Yes, i see the problem. The caller function (me_function) runs in kernel mode and calls my function which is user mode.
| Quote: | | So if you need to use a user mode function through an indirect call, don't forget to or the register with 0x80000000 beforehand. |
I tried or-ing the function address with 0x80000000 already. It didn't work, perhaps because some variables in the function are in user space?
If it is indeed the recommended solution, how can I then make a syscall to my function? :
| Code: | void me_function(int unused)
{
while (1) // this kernel mode function is running forever in ME
{
while (nocache->start == 0);
nocache->start = 0;
nocache->func(nocache->param); // our user mode function is called here. Can we change this into a syscall? If so, what's the syntax?
nocache->end = 1;
}
} |
|
|
| Back to top |
|
 |
NeoTechni
Joined: 30 Oct 2006 Posts: 15
|
Posted: Mon Feb 12, 2007 7:41 pm Post subject: |
|
|
| Anyone got the ME playing MP3s? |
|
| Back to top |
|
 |
moonlight
Joined: 26 Oct 2005 Posts: 567
|
Posted: Mon Feb 12, 2007 8:13 pm Post subject: |
|
|
| Does anyone know if the vram can be accesed with the me? |
|
| Back to top |
|
 |
crazyc
Joined: 17 Jun 2005 Posts: 410
|
Posted: Tue Feb 13, 2007 1:26 am Post subject: |
|
|
| hlide wrote: |
shouldn't be
| Code: |
...
li t0, 0xbc00002c
li t1, 0xbc000000
li t2, -1
c:
sw t2, 0(t1)
bne t1, t0, c
addiu t1, t1, 4
li k0, 0x20000000
...
| ?
|
Yeah, oops.
Anyway, this probably won't fix your problem, unless you are switching the ME into user mode. |
|
| Back to top |
|
 |
jockyw2001
Joined: 29 Sep 2005 Posts: 339
|
Posted: Tue Feb 13, 2007 1:56 am Post subject: |
|
|
| crazyc wrote: |
Anyway, this probably won't fix your problem, unless you are switching the ME into user mode. |
Excuse my ignorance, but what exactly is the additional code good for? |
|
| Back to top |
|
 |
crazyc
Joined: 17 Jun 2005 Posts: 410
|
Posted: Tue Feb 13, 2007 2:00 am Post subject: |
|
|
| jockyw2001 wrote: | | crazyc wrote: |
Anyway, this probably won't fix your problem, unless you are switching the ME into user mode. |
Excuse my ignorance, but what exactly is the additional code good for? |
It disables the kernel memory memory protection. It's what prevents user mode code from accessing the lower memory where the kernel is located. |
|
| Back to top |
|
 |
hlide
Joined: 10 Sep 2006 Posts: 750
|
Posted: Tue Feb 13, 2007 5:35 am Post subject: |
|
|
| jockyw2001 wrote: |
| Quote: | | so far as I remember you can access data with a "user mode" address. |
No, doesn't work
|
sorry to say but you can because there is no USEG but a KUSEG at 0x00000000-0x7fffffff, which means accessible in user or kernel mode. And meseems I already tried to read kuseg segment without problem.
| jockyw2001 wrote: |
The whole idea is to port apps to 3.x firmwares and minimize the porting work. And the bulk of the routines I like to run on ME are in the parent user mode module. It's a bit of a pain to separate these routines out and put them in the ME kernel mode child module
|
i have some functions that I can call with SC or ME processors (but I admit i use kernel mode in SC processor too). As I say, you can call those functions with SC processor but they run in kernel mode. But ONE important thing NO TO DO is to call some PRX functions relying on hardware - like IO or GU manipulations because they are specific to SC processor.
| jockyw2001 wrote: |
Yes, i see the problem. The caller function (me_function) runs in kernel mode and calls my function which is user mode.
| Quote: | | So if you need to use a user mode function through an indirect call, don't forget to or the register with 0x80000000 beforehand. |
I tried or-ing the function address with 0x80000000 already. It didn't work, perhaps because some variables in the function are in user space?
|
use mode variables are in KUSEG !!!! that Kernel And User Segment, so there is no reason why a kernel code cannot access this segment. Anyway , kernel has all the rights.
| jockyw2001 wrote: |
If it is indeed the recommended solution, how can I then make a syscall to my function? |
a syscall ? there is no syscall in ME processor, unless you are coding your own OS. |
|
| Back to top |
|
 |
hlide
Joined: 10 Sep 2006 Posts: 750
|
Posted: Tue Feb 13, 2007 5:46 am Post subject: |
|
|
| moonlight wrote: | | Does anyone know if the vram can be accesed with the me? |
so far as I know it doesn't seem to be possible. We know how to protect/unprotect the lower 64MB main memory and the 2MB VRAM (fast RAM of ME processor) but nothing for enabling access to VIDEO RAM (0x04000000-0x041FFFFF don't raise a bus address exception but it is mapped on nothing). I wouldn't expect too much for this possibility to exist. |
|
| Back to top |
|
 |
crazyc
Joined: 17 Jun 2005 Posts: 410
|
Posted: Tue Feb 13, 2007 5:52 am Post subject: |
|
|
| hlide wrote: |
| jockyw2001 wrote: |
The whole idea is to port apps to 3.x firmwares and minimize the porting work. And the bulk of the routines I like to run on ME are in the parent user mode module. It's a bit of a pain to separate these routines out and put them in the ME kernel mode child module
|
i have some functions that I can call with SC or ME processors (but I admit i use kernel mode in SC processor too). As I say, you can call those functions with SC processor but they run in kernel mode. But ONE important thing NO TO DO is to call some PRX functions relying on hardware - like IO or GU manipulations because they are specific to SC processor. |
...and they cannot be user-kernel transition calls ("module"ForUser), because even if your app is running in kernel mode those are syscalls and would require a ME syscall hander (it would be possible to obtain the syscall table then write a handler, but it might not be worthwhile).
| hlide wrote: |
| jockyw2001 wrote: |
Yes, i see the problem. The caller function (me_function) runs in kernel mode and calls my function which is user mode.
| Quote: | | So if you need to use a user mode function through an indirect call, don't forget to or the register with 0x80000000 beforehand. |
I tried or-ing the function address with 0x80000000 already. It didn't work, perhaps because some variables in the function are in user space?
|
use mode variables are in KUSEG !!!! that Kernel And User Segment, so there is no reason why a kernel code cannot access this segment. Anyway , kernel has all the rights.
|
Not necessarily. Although I haven't tested it, it may be that the code I posted earlier affects kernel mode too if the oxbc0000xx registers affect any access to KUSEG regardless of mode. |
|
| Back to top |
|
 |
crazyc
Joined: 17 Jun 2005 Posts: 410
|
Posted: Tue Feb 13, 2007 6:00 am Post subject: |
|
|
| hlide wrote: | | moonlight wrote: | | Does anyone know if the vram can be accesed with the me? |
so far as I know it doesn't seem to be possible. We know how to protect/unprotect the lower 64MB main memory and the 2MB VRAM (fast RAM of ME processor) but nothing for enabling access to VIDEO RAM (0x04000000-0x041FFFFF don't raise a bus address exception but it is mapped on nothing). I wouldn't expect too much for this possibility to exist. |
That region isn't mapped to nothing. The ME OS uses it a lot, but it seems to load pointers to tables and structures around 0x04002000 and other places. There is definitely something interesting there, but not VRAM. That isn't to say it isn't possible to access the VRAM, just that the ME OS doesn't and it isn't mapped anywhere else by default. |
|
| Back to top |
|
 |
hlide
Joined: 10 Sep 2006 Posts: 750
|
Posted: Tue Feb 13, 2007 6:07 am Post subject: |
|
|
| crazyc wrote: | | hlide wrote: | | moonlight wrote: | | Does anyone know if the vram can be accesed with the me? |
so far as I know it doesn't seem to be possible. We know how to protect/unprotect the lower 64MB main memory and the 2MB VRAM (fast RAM of ME processor) but nothing for enabling access to VIDEO RAM (0x04000000-0x041FFFFF don't raise a bus address exception but it is mapped on nothing). I wouldn't expect too much for this possibility to exist. |
That region isn't mapped to nothing. The ME OS uses it a lot, but it seems to load pointers to tables and structures around 0x04002000 and other places. There is definitely something interesting there, but not VRAM. That isn't to say it isn't possible to access the VRAM, just that the ME OS doesn't and it isn't mapped anywhere else by default. |
well i NEVER say it is ALWAYS mapped to nothing. By default it is mapped to nothing, meaning you always get the same fixed value whatever you try to put into. But yes maybe there is protected area on this range which has some meaning to be discovered.
Since you are saying that 0x04002000 is used to load pointers to table (?) could you say in which code ? is that relative with audio ? with video ? and so on. You may open some perspective here !!! |
|
| Back to top |
|
 |
hlide
Joined: 10 Sep 2006 Posts: 750
|
Posted: Tue Feb 13, 2007 6:13 am Post subject: |
|
|
| crazyc wrote: | | hlide wrote: |
use mode variables are in KUSEG !!!! that Kernel And User Segment, so there is no reason why a kernel code cannot access this segment. Anyway , kernel has all the rights.
|
Not necessarily. Although I haven't tested it, it may be that the code I posted earlier affects kernel mode too if the oxbc0000xx registers affect any access to KUSEG regardless of mode. |
i'm ASSUMING you already give user and kernel access rights to main memory through those 0xBC0000xx registers of course. |
|
| Back to top |
|
 |
moonlight
Joined: 26 Oct 2005 Posts: 567
|
Posted: Tue Feb 13, 2007 6:51 am Post subject: |
|
|
| hlide wrote: | | crazyc wrote: | | hlide wrote: | | moonlight wrote: | | Does anyone know if the vram can be accesed with the me? |
so far as I know it doesn't seem to be possible. We know how to protect/unprotect the lower 64MB main memory and the 2MB VRAM (fast RAM of ME processor) but nothing for enabling access to VIDEO RAM (0x04000000-0x041FFFFF don't raise a bus address exception but it is mapped on nothing). I wouldn't expect too much for this possibility to exist. |
That region isn't mapped to nothing. The ME OS uses it a lot, but it seems to load pointers to tables and structures around 0x04002000 and other places. There is definitely something interesting there, but not VRAM. That isn't to say it isn't possible to access the VRAM, just that the ME OS doesn't and it isn't mapped anywhere else by default. |
well i NEVER say it is ALWAYS mapped to nothing. By default it is mapped to nothing, meaning you always get the same fixed value whatever you try to put into. But yes maybe there is protected area on this range which has some meaning to be discovered.
Since you are saying that 0x04002000 is used to load pointers to table (?) could you say in which code ? is that relative with audio ? with video ? and so on. You may open some perspective here !!! |
The ipl which is rumored to be started in the me uses also some of those funny addresses... 0x040f0000 and then 0x04000000... |
|
| Back to top |
|
 |
crazyc
Joined: 17 Jun 2005 Posts: 410
|
Posted: Tue Feb 13, 2007 7:07 am Post subject: |
|
|
| Quote: | | Since you are saying that 0x04002000 is used to load pointers to table (?) could you say in which code ? is that relative with audio ? with video ? and so on. You may open some perspective here !!! |
Here's an example that I found interesting.
| Code: | lui $t1, 0x4410
lui $a3, 0x4000
move $t0, $a3
ins $t0, $a0, 0, 0x1D
addiu $v0, $a2, 0xFFFF
addiu $a0, $t1, 0xF010
li $v1, 0x40 # '@'
sw $t0, 0x40FF010
sw $v0, 4($a0)
sw $a1, 8($a0)
jr $ra
sw $v1, -8($a0)
|
This is at 0x83747F8 of the meimg.img from 3.02. The calling parameters from one place where this is called has a0 = 0x1118f8, a1 = 0x8000 and a2 = 992. 0x1118f8 has a 992 entry table whose first several items are:
| Code: | .word 1048576,1048570,1048554,1048528,1048492,1048446 # 0
.word 1048391,1048326,1048250,1048165,1048070,1047965 # 6
.word 1047851,1047726,1047592,1047447,1047293,1047129 # 12
.word 1046955,1046772,1046578,1046375,1046161,1045938 # 18 |
and the values keep descending until halfway through the table. My knowledge of audio and video decoding is rudimentary at best so I haven't been able to really make sense of it. |
|
| Back to top |
|
 |
jockyw2001
Joined: 29 Sep 2005 Posts: 339
|
Posted: Tue Feb 13, 2007 7:13 am Post subject: |
|
|
| hlide wrote: |
sorry to say but you can because there is no USEG but a KUSEG at 0x00000000-0x7fffffff, which means accessible in user or kernel mode. And meseems I already tried to read kuseg segment without problem.
|
hmm, then I wonder why I can't pass user mode function pointers to my main ME loop:
| Code: | void me_function(int unused)
{
while (1) // this kernel mode function is running forever in ME
{
while (nocache->start == 0);
nocache->start = 0;
nocache->func(nocache->param); // our function is called here. kernel mode function pointers work, user mode pointers don't (psp freezes)
nocache->end = 1;
}
} |
Any ideas guys? |
|
| Back to top |
|
 |
hlide
Joined: 10 Sep 2006 Posts: 750
|
Posted: Tue Feb 13, 2007 7:57 am Post subject: |
|
|
| jockyw2001 wrote: | | hlide wrote: |
sorry to say but you can because there is no USEG but a KUSEG at 0x00000000-0x7fffffff, which means accessible in user or kernel mode. And meseems I already tried to read kuseg segment without problem.
|
hmm, then I wonder why I can't pass user mode function pointers to my main ME loop:
| Code: | void me_function(int unused)
{
while (1) // this kernel mode function is running forever in ME
{
while (nocache->start == 0);
nocache->start = 0;
nocache->func(nocache->param); // our function is called here. kernel mode function pointers work, user mode pointers don't (psp freezes)
nocache->end = 1;
}
} |
Any ideas guys? |
can you give us more details about nocache->func ? |
|
| Back to top |
|
 |
jockyw2001
Joined: 29 Sep 2005 Posts: 339
|
Posted: Tue Feb 13, 2007 6:22 pm Post subject: |
|
|
| hlide wrote: | | can you give us more details about nocache->func ? |
Sure, here is the major part of the sourcecode (me.c, mestub.S and Makefile). It's originally from jonny's PMP Mod player. PMP Mod is a kernel mode app. My app (PMP VLC) is a normal mode app which calls exported functions from the ME kernel mode prx (memodule.prx)
'nocache' is a structure allocated in uncached memory through which functions and function state is communicated between SC and ME. So basically a simple RPC implementation.
me.c:
| Code: | /*
PMP Mod
Copyright (C) 2006 jonny
Homepage: http://jonny.leffe.dnsalias.com
E-mail: jonny@leffe.dnsalias.com
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
simple lib to use the psp me
a lot of code is taken from here: http://forums.ps2dev.org/viewtopic.php?t=2652
thanks to crazyc, mrbrown, Brunni, xdeadbeef and anyone else involved
(major optimizations in libavcodec are done with the me)
*/
#include <pspsdk.h>
#include <pspkernel.h>
#include <string.h>
#include <stdio.h>
#include "me.h"
#include "mem64.h"
PSP_MODULE_INFO("MEPRX", 0x1000, 1, 1);
PSP_HEAP_SIZE_KB(1024);
struct me_struct
{
int start;
int end;
void (*func)(int); // function ptr func which takes argument nochache->param and returns void
int param; // function parameter func
int signaled;
unsigned int k1; // k1 register
};
volatile struct me_struct *nocache;
void me_stub(void);
void me_stub_end(void);
#define WELCOME_MESSAGE "Hello from the PRX\n"
int me_idct_start_row;
int main(int argc, char **argv)
{
int i;
printf(WELCOME_MESSAGE);
for(i = 0; i < argc; i++)
{
printf("Arg %d: %s\n", i, argv[i]);
}
sceKernelSleepThread();
return 0;
}
void me_startproc(u32 func, u32 param)
{
memcpy((void *) 0xbfc00040, me_stub, (int) (me_stub_end - me_stub));
_sw(func, 0xbfc00600); // k0
_sw(param, 0xbfc00604); // a0
sceKernelDcacheWritebackAll();
sceSysregMeResetEnable();
sceSysregMeBusClockEnable();
sceSysregMeResetDisable();
fprintf(stdout,"me.c: me_startproc()\n");
}
void me_function(int unused)
{
while (1) // ME runs this loop forever
{
while (nocache->start == 0); // me_start() clears this loop by setting start=1 and end=0
nocache->start = 0;
// nocache->k1 = pspSdkSetK1(0);
nocache->func(nocache->param); // run this function
// pspSdkSetK1(nocache->k1);
nocache->end = 1;
}
}
int me_struct_init()
{
nocache = malloc_64(sizeof(struct me_struct));
if (nocache == 0) return(0);
fprintf(stdout,"me.c: me_struct_init()\n");
nocache = (volatile struct me_struct *) (((int) nocache) | 0x40000000);
sceKernelDcacheWritebackInvalidateAll();
nocache->start = 0;
nocache->end = 1;
nocache->func = 0;
nocache->param = 0;
nocache->signaled = 0;
me_startproc((u32) me_function, 0);
return(1);
}
me_test(int i)
{
nocache->k1 = 777;
}
void me_start(int func, int param)
{
//#if 0
nocache->end = 0;
nocache->func = (void (*)(int)) func;
// nocache->func = (void (*)(int)) ((int)me_test | 0x80000000);
nocache->param = param;
nocache->start = 1;
//#endif
fprintf(stdout,"me.c: me_start() func = 0x%8X, k1=0x%8X\n", nocache->func, nocache->k1);
}
void me_wait()
{
while (nocache->end == 0);
}
int me_unused()
{
return(nocache->end);
}
void me_signal_reset()
{
nocache->signaled = 0;
}
void me_signal()
{
nocache->signaled = 1;
}
int me_signaled()
{
return(nocache->signaled);
}
void me_sceKernelDcacheWritebackInvalidateAll()
{
asm __volatile__
(
"cache 20, 0($0)\n"
"cache 20, 0($0)\n"
"cache 20, 64($0)\n"
"cache 20, 64($0)\n"
"cache 20, 128($0)\n"
"cache 20, 128($0)\n"
"cache 20, 192($0)\n"
"cache 20, 192($0)\n"
"cache 20, 256($0)\n"
"cache 20, 256($0)\n"
"cache 20, 320($0)\n"
"cache 20, 320($0)\n"
"cache 20, 384($0)\n"
"cache 20, 384($0)\n"
"cache 20, 448($0)\n"
"cache 20, 448($0)\n"
"cache 20, 512($0)\n"
"cache 20, 512($0)\n"
"cache 20, 576($0)\n"
"cache 20, 576($0)\n"
"cache 20, 640($0)\n"
"cache 20, 640($0)\n"
"cache 20, 704($0)\n"
"cache 20, 704($0)\n"
"cache 20, 768($0)\n"
"cache 20, 768($0)\n"
"cache 20, 832($0)\n"
"cache 20, 832($0)\n"
"cache 20, 896($0)\n"
"cache 20, 896($0)\n"
"cache 20, 960($0)\n"
"cache 20, 960($0)\n"
"cache 20, 1024($0)\n"
"cache 20, 1024($0)\n"
"cache 20, 1088($0)\n"
"cache 20, 1088($0)\n"
"cache 20, 1152($0)\n"
"cache 20, 1152($0)\n"
"cache 20, 1216($0)\n"
"cache 20, 1216($0)\n"
"cache 20, 1280($0)\n"
"cache 20, 1280($0)\n"
"cache 20, 1344($0)\n"
"cache 20, 1344($0)\n"
"cache 20, 1408($0)\n"
"cache 20, 1408($0)\n"
"cache 20, 1472($0)\n"
"cache 20, 1472($0)\n"
"cache 20, 1536($0)\n"
"cache 20, 1536($0)\n"
"cache 20, 1600($0)\n"
"cache 20, 1600($0)\n"
"cache 20, 1664($0)\n"
"cache 20, 1664($0)\n"
"cache 20, 1728($0)\n"
"cache 20, 1728($0)\n"
"cache 20, 1792($0)\n"
"cache 20, 1792($0)\n"
"cache 20, 1856($0)\n"
"cache 20, 1856($0)\n"
"cache 20, 1920($0)\n"
"cache 20, 1920($0)\n"
"cache 20, 1984($0)\n"
"cache 20, 1984($0)\n"
"cache 20, 2048($0)\n"
"cache 20, 2048($0)\n"
"cache 20, 2112($0)\n"
"cache 20, 2112($0)\n"
"cache 20, 2176($0)\n"
"cache 20, 2176($0)\n"
"cache 20, 2240($0)\n"
"cache 20, 2240($0)\n"
"cache 20, 2304($0)\n"
"cache 20, 2304($0)\n"
"cache 20, 2368($0)\n"
"cache 20, 2368($0)\n"
"cache 20, 2432($0)\n"
"cache 20, 2432($0)\n"
"cache 20, 2496($0)\n"
"cache 20, 2496($0)\n"
"cache 20, 2560($0)\n"
"cache 20, 2560($0)\n"
"cache 20, 2624($0)\n"
"cache 20, 2624($0)\n"
"cache 20, 2688($0)\n"
"cache 20, 2688($0)\n"
"cache 20, 2752($0)\n"
"cache 20, 2752($0)\n"
"cache 20, 2816($0)\n"
"cache 20, 2816($0)\n"
"cache 20, 2880($0)\n"
"cache 20, 2880($0)\n"
"cache 20, 2944($0)\n"
"cache 20, 2944($0)\n"
"cache 20, 3008($0)\n"
"cache 20, 3008($0)\n"
"cache 20, 3072($0)\n"
"cache 20, 3072($0)\n"
"cache 20, 3136($0)\n"
"cache 20, 3136($0)\n"
"cache 20, 3200($0)\n"
"cache 20, 3200($0)\n"
"cache 20, 3264($0)\n"
"cache 20, 3264($0)\n"
"cache 20, 3328($0)\n"
"cache 20, 3328($0)\n"
"cache 20, 3392($0)\n"
"cache 20, 3392($0)\n"
"cache 20, 3456($0)\n"
"cache 20, 3456($0)\n"
"cache 20, 3520($0)\n"
"cache 20, 3520($0)\n"
"cache 20, 3584($0)\n"
"cache 20, 3584($0)\n"
"cache 20, 3648($0)\n"
"cache 20, 3648($0)\n"
"cache 20, 3712($0)\n"
"cache 20, 3712($0)\n"
"cache 20, 3776($0)\n"
"cache 20, 3776($0)\n"
"cache 20, 3840($0)\n"
"cache 20, 3840($0)\n"
"cache 20, 3904($0)\n"
"cache 20, 3904($0)\n"
"cache 20, 3968($0)\n"
"cache 20, 3968($0)\n"
"cache 20, 4032($0)\n"
"cache 20, 4032($0)\n"
"cache 20, 4096($0)\n"
"cache 20, 4096($0)\n"
"cache 20, 4160($0)\n"
"cache 20, 4160($0)\n"
"cache 20, 4224($0)\n"
"cache 20, 4224($0)\n"
"cache 20, 4288($0)\n"
"cache 20, 4288($0)\n"
"cache 20, 4352($0)\n"
"cache 20, 4352($0)\n"
"cache 20, 4416($0)\n"
"cache 20, 4416($0)\n"
"cache 20, 4480($0)\n"
"cache 20, 4480($0)\n"
"cache 20, 4544($0)\n"
"cache 20, 4544($0)\n"
"cache 20, 4608($0)\n"
"cache 20, 4608($0)\n"
"cache 20, 4672($0)\n"
"cache 20, 4672($0)\n"
"cache 20, 4736($0)\n"
"cache 20, 4736($0)\n"
"cache 20, 4800($0)\n"
"cache 20, 4800($0)\n"
"cache 20, 4864($0)\n"
"cache 20, 4864($0)\n"
"cache 20, 4928($0)\n"
"cache 20, 4928($0)\n"
"cache 20, 4992($0)\n"
"cache 20, 4992($0)\n"
"cache 20, 5056($0)\n"
"cache 20, 5056($0)\n"
"cache 20, 5120($0)\n"
"cache 20, 5120($0)\n"
"cache 20, 5184($0)\n"
"cache 20, 5184($0)\n"
"cache 20, 5248($0)\n"
"cache 20, 5248($0)\n"
"cache 20, 5312($0)\n"
"cache 20, 5312($0)\n"
"cache 20, 5376($0)\n"
"cache 20, 5376($0)\n"
"cache 20, 5440($0)\n"
"cache 20, 5440($0)\n"
"cache 20, 5504($0)\n"
"cache 20, 5504($0)\n"
"cache 20, 5568($0)\n"
"cache 20, 5568($0)\n"
"cache 20, 5632($0)\n"
"cache 20, 5632($0)\n"
"cache 20, 5696($0)\n"
"cache 20, 5696($0)\n"
"cache 20, 5760($0)\n"
"cache 20, 5760($0)\n"
"cache 20, 5824($0)\n"
"cache 20, 5824($0)\n"
"cache 20, 5888($0)\n"
"cache 20, 5888($0)\n"
"cache 20, 5952($0)\n"
"cache 20, 5952($0)\n"
"cache 20, 6016($0)\n"
"cache 20, 6016($0)\n"
"cache 20, 6080($0)\n"
"cache 20, 6080($0)\n"
"cache 20, 6144($0)\n"
"cache 20, 6144($0)\n"
"cache 20, 6208($0)\n"
"cache 20, 6208($0)\n"
"cache 20, 6272($0)\n"
"cache 20, 6272($0)\n"
"cache 20, 6336($0)\n"
"cache 20, 6336($0)\n"
"cache 20, 6400($0)\n"
"cache 20, 6400($0)\n"
"cache 20, 6464($0)\n"
"cache 20, 6464($0)\n"
"cache 20, 6528($0)\n"
"cache 20, 6528($0)\n"
"cache 20, 6592($0)\n"
"cache 20, 6592($0)\n"
"cache 20, 6656($0)\n"
"cache 20, 6656($0)\n"
"cache 20, 6720($0)\n"
"cache 20, 6720($0)\n"
"cache 20, 6784($0)\n"
"cache 20, 6784($0)\n"
"cache 20, 6848($0)\n"
"cache 20, 6848($0)\n"
"cache 20, 6912($0)\n"
"cache 20, 6912($0)\n"
"cache 20, 6976($0)\n"
"cache 20, 6976($0)\n"
"cache 20, 7040($0)\n"
"cache 20, 7040($0)\n"
"cache 20, 7104($0)\n"
"cache 20, 7104($0)\n"
"cache 20, 7168($0)\n"
"cache 20, 7168($0)\n"
"cache 20, 7232($0)\n"
"cache 20, 7232($0)\n"
"cache 20, 7296($0)\n"
"cache 20, 7296($0)\n"
"cache 20, 7360($0)\n"
"cache 20, 7360($0)\n"
"cache 20, 7424($0)\n"
"cache 20, 7424($0)\n"
"cache 20, 7488($0)\n"
"cache 20, 7488($0)\n"
"cache 20, 7552($0)\n"
"cache 20, 7552($0)\n"
"cache 20, 7616($0)\n"
"cache 20, 7616($0)\n"
"cache 20, 7680($0)\n"
"cache 20, 7680($0)\n"
"cache 20, 7744($0)\n"
"cache 20, 7744($0)\n"
"cache 20, 7808($0)\n"
"cache 20, 7808($0)\n"
"cache 20, 7872($0)\n"
"cache 20, 7872($0)\n"
"cache 20, 7936($0)\n"
"cache 20, 7936($0)\n"
"cache 20, 8000($0)\n"
"cache 20, 8000($0)\n"
"cache 20, 8064($0)\n"
"cache 20, 8064($0)\n"
"cache 20, 8128($0)\n"
"cache 20, 8128($0)\n"
);
}
/* Exported function returns the address of module_info */
void* getModuleInfo(void)
{
fprintf(stdout,"me.c: getModuleInfo()\n");
//printf("me.c: getModuleInfo()\n");
return (void *) &module_info;
} |
and mestub.S:
| Code: | // this stub is from the melib package, (c)mrbrown
#include <regdef.h>
#define STATUS $12
#define CAUSE $13
#define CONFIG $16
#define TAGLO $28
#define TAGHI $29
#define IXIST 0x01
#define DXIST 0x11
.global me_stub
.global me_stub_end
.set noreorder
.set noat
me_stub:
li k0, 0xbc100000
li t0, 7
sw t0, 80(k0)
mtc0 zero, TAGLO
mtc0 zero, TAGHI
li k1, 8192
a:
addi k1, k1, -64
bne k1, zero, a
cache IXIST, 0(k1)
li k1, 8192
b:
addi k1, k1, -64
bne k1, zero, b
cache DXIST, 0(k1)
mtc0 zero, CAUSE
li t0, 0xbc00002c
li t1, 0xbc000000
li t2, -1
c:
sw t2, 0(t1)
bne t1, t0, c
addiu t1, t1, 4
li k0, 0x20000000
mtc0 k0, STATUS
sync
li t0, 0xbfc00000
lw a0, 0x604(t0)
lw k0, 0x600(t0)
li sp, 0x80200000
jr k0
nop
me_stub_end: |
Makefile:
| Code: | TARGET = memodule
OBJS = mestub.o me.o ../../../libavcodec/mod/me_idct.o ../../../libavcodec/mod/simple_idct.o ../mem64.o
# Define to build this as a prx (instead of a static elf)
BUILD_PRX=1
# Define the name of our custom exports (minus the .exp extension)
PRX_EXPORTS=exports.exp
USE_PSPSDK_LIBC = 1
#USE_KERNEL_LIBC = 1
#USE_KERNEL_LIBS = 1
INCDIR = . .. ../../../libavcodec/mod ../../../libavcodec ../../../libavformat ../../../libavutil
CFLAGS = -O2 -G0 -Wall
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)
LIBDIR =
PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak |
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|