forums.ps2dev.org Forum Index forums.ps2dev.org
Homebrew PS2, PSP & PS3 Development Discussions
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

SC/ME processors : memory mappings

 
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development
View previous topic :: View next topic  
Author Message
hlide



Joined: 10 Sep 2006
Posts: 750

PostPosted: Wed Dec 06, 2006 11:24 am    Post subject: SC/ME processors : memory mappings Reply with quote

SC and ME have the same revision code (PRId) "31040125", so we can expect a lot of similarities between them indeed.

Code:

COP0 registers :
       [    SC   ]   [    ME    ]   
15 - 31040125 - 31040125 - PRId
16 - 00000480 - 00000480 - Config


I suspect both CPUs using a FM (Fix Mapped) MMU which could explain the current mapping and the lack of a TLB MMU.

COP0.Config is the same so they almost share the same memory mapping :

0x00000000-0x3fffffff : KUSEG0 -> kernel/user mapped.
0x40000000-0x7fffffff : KUSEG1 -> kernel/user mapped.
0x80000000-0x9fffffff : KSEG0 -> kernel unmapped cached
0xA0000000-0xbfffffff : KSEG1 -> kernel unmapped uncached

SC Processor :
Code:

0x04000000 - 2MB   : cached VRAM
0x08000000 - 32MB : cached main memory

0x44000000 - 2MB   : uncached VRAM
0x48000000 - 32MB : uncached main memory

0x84000000 - 2MB   : cached VRAM
0x88000000 - 32MB : cached main memory

0xA4000000 - 2MB   : uncached VRAM
0xA8000000 - 32MB : uncached main memory


ME processor :
Code:

0x04000000 - 2MB   : cached ???, mirror of 0x84000000
0x08000000 - 32MB : cached main memory, mirror of 0x88000000

0x44000000 - 2MB   : uncached ???, mirror of 0xA4000000
0x48000000 - 32MB : uncached main memory, mirror of 0xA8000000

0x80000000 - 2MB   : cached eDRAM
0x84000000 - 2MB   : cached ??? (can modify contents only in cache)
0x88000000 - 32MB : cached main memory

0xA0000000 - 2MB   : uncached eDRAM
0xA4000000 - 2MB   : uncached ??? (unmodifiable contents)
0xA8000000 - 32MB : uncached main memory


ME processor has a weird memory starting at 0x?4000000. I dunno if it is for VRAM. If so, we probably need to enable its access through an unknown setting of a controller.


Last edited by hlide on Thu Dec 07, 2006 8:24 am; edited 3 times in total
Back to top
View user's profile Send private message
hlide



Joined: 10 Sep 2006
Posts: 750

PostPosted: Thu Dec 07, 2006 7:29 am    Post subject: Reply with quote

if someone has more details about how to raise an interrupt from ME into SC and vice versa, I'm very interested.

Anyway, it would be interesting to check if ME processor can use the same exceptions than SC processor. They are necessary for creating a small kernel for ME processor that would be more robuste that the actual code we have. If we can figure the way how to signal the other processor to give an order or a result, it would be cool.

EDIT : I don't mean running SC exceptions code into ME processor but to have the same way to handle the exceptions with ME processor
Back to top
View user's profile Send private message
TyRaNiD



Joined: 18 Jan 2004
Posts: 918

PostPosted: Thu Dec 07, 2006 7:53 am    Post subject: Reply with quote

Code:
asm("sync\n");
_sw(1, 0xBC100044);
asm("sync\n");


Should raise interrupt 31 on the ME and vice versa.
Back to top
View user's profile Send private message
hlide



Joined: 10 Sep 2006
Posts: 750

PostPosted: Thu Dec 07, 2006 8:21 am    Post subject: Reply with quote

TyRaNiD wrote:
Code:
asm("sync\n");
_sw(1, 0xBC100044);
asm("sync\n");


Should raise interrupt 31 on the ME and vice versa.


cool !!!! thanx very much !

EDIT: it doesn't seem to work. I probably miss something :/

According to yad4psp :

interrupt 31 : SYS_REG ME Codec. So this is not an exception but an interrupt. Maybe this interrupt is by default a "nop" so it may explain why i cannot receive anything (or this interrupt is masked ?)
Back to top
View user's profile Send private message
hlide



Joined: 10 Sep 2006
Posts: 750

PostPosted: Thu Dec 07, 2006 9:19 am    Post subject: Reply with quote

hummm SYSREG_driver (FW 1.5) gives us :

Code:

// sceSysregInterruptToOther ???
int 880790ac(void)
{
  _sync();
  _writew(1, 0xbc100044);
  _sync();
  return 0;
}

// sceSysregSemaTryLock ???
int 880790cc(void)
{
  _sync();
  v0 = _mfc0(22); // CPUId (0 -> SC / 1 -> ME)
  a2 = v0 + 1; // 1 -> SC / 2 -> ME
  _writew(a2, 0xbc100048); // try to acquire semaphore
  a3 = _readw(0xbc100048) & 3; // who owns semaphore ?
  return -((a2 ^ a3) != 0); // 0 if successful or -1 if not
}

// sceSysregSemaUnlock ???
void 880790fc(void)
{
  _sync();
  _writew(0, 0xbc100048); // owner releases semaphore
  _sync();
  return;
}


Last edited by hlide on Thu Dec 07, 2006 11:48 pm; edited 2 times in total
Back to top
View user's profile Send private message
J.F.



Joined: 22 Feb 2004
Posts: 2906

PostPosted: Thu Dec 07, 2006 9:43 am    Post subject: Reply with quote

We appreciate the work you're doing on the ME, hlide. This could really improve a variety of programs, being able to run some things on the ME.
Back to top
View user's profile Send private message AIM Address
hlide



Joined: 10 Sep 2006
Posts: 750

PostPosted: Fri Dec 08, 2006 7:13 pm    Post subject: Reply with quote

ok, semaphore is working. I am able to sync SC and ME with 0xBC100048.

now, i want to use int 31. Running PSPINSIDE, i can see it is activated and calls a function which sets an event flag.

pspsdk really lacks of functions on interrupts. I'm wondering how to proceed. I can see several interesting functions in http://pspdev.ofcode.com/api2.0/index.php?type=2&id=34 but i have no detail about them (i'm under FW1.5).

There could be one solution, to access the interrupt table and set our own interrupt for int 31... but it is very dirty. :/

EDIT: talking about semaphore, it is much more like a mutex indeed.
Back to top
View user's profile Send private message
rapso



Joined: 28 Mar 2005
Posts: 147

PostPosted: Fri Dec 08, 2006 8:25 pm    Post subject: Re: SC/ME processors : memory mappings Reply with quote

hlide wrote:
ME processor has a weird memory starting at 0x?4000000. I dunno if it is for VRAM. If so, we probably need to enable its access through an unknown setting of a controller.
afaik, before the psp was released, there were rumors talkin about 4MB VRam. maybe it's the upper or lower 2MB of that VRam, so maybe u cannot access it by the main cpu, but maybe set it as frontbuffer/display?

[edit]
I searched it and found the description on this side: http://www.hartware.de/review_492_3.html

Quote:

Neben den 32 MB besitzen die CPUs, wie schon gesagt, rund 4 MB eDRAM. Diese 4 MB verteilen sich auf die Media Engine und den Grafikkern.
except of the 32MB main memory, 4MB eDRAM are available, splited to the ME and GU.

Quote:

Wie bei der Haupt-CPU ist der Takt der Media Engine von 1 bis 333 MHz regelbar. Diese verfügt aber über 2 MB der insgesamt 4 MB eDRAM. Diese 2 MB hängen dabei an einem Bus, der mit der halben Taktfrequenz der Media Engine läuft, das heißt maximal 166 Mhz.

As the main CPU, the ME can be set from 1 to 333MHz, it has access to 2MB of the whole 4MB eDRAM. Those 2MB are running with the same speed as the bus of the ME, 166MHz.

[/edit]
maybe it's just for movie playing, but maybe we could even use it as 2MB additional texture memory (maybe even motion-textures)
Back to top
View user's profile Send private message
hlide



Joined: 10 Sep 2006
Posts: 750

PostPosted: Sat Dec 09, 2006 3:07 am    Post subject: Reply with quote

I managed to set my own exceptions but i would like to be able to use the one already provided if possible.
This is the function set by default into cop0 status register EBASE :
Code:

ctc0 $v0, $4
ctc0 $v1, $5
lui $v1, 0xBC200000
lui $v0, 0x1FF0000
ori $v0, 0x1FF
sw $v0, ($v1)
mfc0 $v0, $13
ctc0 $v0, $3
andi $v0, 0x7C
mfc0 $v1, $14
ctc0 $v1, $0
cfc0 $v1, $8
add $v1, $v0
lw $v1, ($v1)
mfc0 $v0, $12
jr $v1
ctc0 $v0, $2


I cannot find what 0xBC200000 is (not documented in yad4psp). Any idea ? is it something usable only for ME ?

cop0 control register 8 doesn't seem to contain a valid address on a 32-entry exception table, but we can set ours here.
Back to top
View user's profile Send private message
hlide



Joined: 10 Sep 2006
Posts: 750

PostPosted: Sat Dec 09, 2006 9:27 am    Post subject: Reply with quote

okay, now SC processor can display exception details coming from ME using 'pspDebugDumpException'. At least it should be a help to develop on ME processor.

I'm still clueless about how to deroute int 31 in SC processor so ME can signal an exception for instance. :/

Next task : SC signaling ME via int 31.

I'll plan to release a ME library which should allow ME and SC to communicate to each other and catch ME exceptions too when evrything is okay.

Maybe a small RPC-like mechanism can be added to allow ME processor to "borrow" SC ressources.
Back to top
View user's profile Send private message
Chrighton



Joined: 15 Jun 2005
Posts: 58

PostPosted: Sat Dec 09, 2006 12:00 pm    Post subject: Reply with quote

Nice work, hlide. Thanks for keeping us up to date on your findings.
Back to top
View user's profile Send private message
hlide



Joined: 10 Sep 2006
Posts: 750

PostPosted: Mon Dec 11, 2006 4:17 am    Post subject: Reply with quote

since i'm unsuccessful with int 31, i tried to discover much about SYSREG functions :

Code:

int sceSysregIntrInit(void)
{
  sceKernelRegisterIntrHandler(31, 1, 0x88080118, 0, 0x88089DF0);
  sceKernelEnableIntr(a0 = 31);
  return 0;
}

NOTE :    0x88080118 seems to be in the .text section of module sceDMACPLUS_Driver.
 
int sceSysregIntrEnd(void)
{
  sceKernelReleaseIntrHandler(31);
  return 0;
}

int sceSysregInterruptToOther(void)
{
  _sync();
  _sw(0xbc100044) = 1;
  _sync();
  return 0;
}

int sceSysregSemaTryLock(void)
{
  _sync();
  v0 = _mfc0(22); // CPUId (0 -> SC / 1 -> ME)
  a2 = v0 + 1; // 1 -> SC / 2 -> ME
  _sw(0xbc100048) = a2; // try to acquire semaphore
  a3 = _lw(0xbc100048) & 3; // who owns semaphore ?
  return -(a2 != a3); // 0 if successful or -1 if not
}

void sceSysregSemaUnlock(void)
{
  _sync();
  _sw(0xbc100048) = 0; // owner releases semaphore
  _sync();
  return;
}
 
bool sceSysregEnableIntr(int no)
{
  if (no > 31) return 0x80000102;
  v0 = sceKernelCpuSuspendIntr();
  t0 = _lw(0x880089E04);
  _sw(0x880089E04) = t0 | (1 << no)
  sceKernelCpuResumeIntr(v0);
  return (t0 >> no) & 1;
}

bool sceSysregDisableIntr(int no)
{
  if (no > 31) return 0x80000102;
  v0 = sceKernelCpuSuspendIntr();
  t0 = _lw(0x880089E04);
  _sw(0x880089E04) = t0 & ~(1 << no)
  sceKernelCpuResumeIntr(v0);
  return (t0 >> no) & 1;
}

int sceSysregRequestIntr(int cpu, int no)
{
  if ((no > 31) || (cpu > 1)) return 0x80000102;
  s0 = cpu;
  s1 = no;
  while (sceSysregSemaTryLock() < 0);
  t0 = 0xBFC00400 + (cpu << 2);
  _sw(t0) = _lw(t0) | (1 << no);
  sceSysregSemaUnlock();
  if (_mfc0(22) != cpu) sceSysregInterruptToOther();
  return 0;
}



those functions are definitely weird... it seems to imply the interrupt can be "shared" between SC and ME. SYSREG seems to be used in such way that ME and SC can know what is in charge of such interrupt. I guess we should have a look on meAudio or meCodec instead.
Back to top
View user's profile Send private message
J.F.



Joined: 22 Feb 2004
Posts: 2906

PostPosted: Mon Dec 11, 2006 4:35 am    Post subject: Reply with quote

Well, it makes sense that they would share the int. Think about how you would communicate with one int and one semaphore...

Both CPUs watch the same int.
CPU 1 decides it needs CPU 2 to do something for it.
CPU 1 tries to acquire the semaphore and is successful.
CPU 1 generates the int.
CPU 1's int handler sees it has the semaphore and exits.
CPU 2's int handler sees that CPU 1 has the semaphore and does what is needed to respond to CPU 1.
CPU 1 sees CPU 2 responding and releases the semaphore.
CPU 2 finishes and tries for the semaphore and is (maybe eventually) successful.
CPU 2 generates the int to show it finished.
CPU 2's int handler sees it has the semaphore and exits.
CPU 1's int handler sees CPU 2 has the semaphore and does what is needed to acknowledge CPU 2 is done.
CPU 2 releases the semaphore.

Something like that...
Back to top
View user's profile Send private message AIM Address
hlide



Joined: 10 Sep 2006
Posts: 750

PostPosted: Mon Dec 11, 2006 5:39 am    Post subject: Reply with quote

I prefer to say mutex instead of semaphore, for mutex is more appropriate according to what I saw. In fact, there are uses as "enter_critical_session" and "leave_critical_session".

This mutex protects access to 0xBFC00400/0xBFC00404 (i don't think they are part of interrupt controller but a "shared" data between SC and ME) and doesn't last very long indeed.

This mutex is not held when generating an int.

Those functions don't act really on interrupt controller. So I suppose you cannot use them solely but probably must be used along with functions having a real effect on interrupt controler.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development All times are GMT + 10 Hours
Page 1 of 1

 
Jump to:  
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