Accessing the extra 4Megs of RAM on 1.5+

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
TyRaNiD
Posts: 907
Joined: Sun Jan 18, 2004 12:23 am

Accessing the extra 4Megs of RAM on 1.5+

Post by TyRaNiD »

As some will know on 1.0 there was an extra 4megs of RAM from 0x8400000 which you could access, on 1.5 if you access it you get an exception, what is going on here?

Well I just added the functions to the SDK to allow access to these areas, there are in sceSuspendForUser for usermode calls and scePower_driver for kernel mode.

For user mode they are defined in pspsuspend.h as:

Code: Select all

sceSuspendForUser_3E0271D3(int unk, void **ptr, int *size);
int sceSuspendForUser_A14F40B2(int unk, void **ptr, int *size);
int sceSuspendForUser_A569E425(void);
The first is a allocate function, pass in a pointer and a size integer and if you can allocate it it will return the appropriate info. The second is a try allocate, it polls a semaphore and if it is already alloced will return an error. The final one is the deallocate.

For kernel mode they are:

Code: Select all

scePower_driver_23C31FFE
scePower_driver_FA97A599
scePower_driver_B3EDD801
Same prototypes as the suspend ones. The suspend ones just call the power ones anyway through a callback (which then proceeds to call back into sysmem anyway, why Sony why :P).

Now as these are in a suspend library it is a fair chance that the kernel uses them for something, I haven't tested it but it might be used when suspending or sommit therefore you might not be able to use it as a general purpose area :( Still worth a try and see how far you get ;P

Now for the techy minded this is an explanation of how they work :) The core function is sceKernelSetDdrMemoryProtection(void *addr, int size, int prot). By calling this you can set the memory protection bits on certain memory blocks (well only in the first 8Mb of DDR). Addr is obvious, size is a value up to 2 megs in 256KByte blocks, prot is a 4 bit mask which determines the protection.

The prot mask is thus:

Bit 3 - Kernel Write Enable
Bit 2 - Kernel Read Enable
Bit 1 - User Write Enable
Bit 0 - User Read Enable

The first four megs are all set to 0xC prot mask which means kernel only read/write, this is interesting cause you can therefore "unprotect" the kernel only address space and access it in user mode :)

e.g.

Code: Select all

sceKernelSetDdrMemoryProtection((void*) 0x08000000, 2*1024*1024, 0xF);
Will allow the first 2 megs of kernel memory to be accessed from user space.

Now for the real techy minded (i.e. groepaz) this is what that function is doing.

The memory protection registers are 8 32bit words stating at 0xbc000000. Each 32bit is split into 8 4bit protection masks starting LSB first, i.e. bits 0 to 3 are the first 256KBytes of that chunk, bits 4 to 7 are the next etc. And as each register can address 8 256KByte blocks then the address space is split into 2Mbyte chunks.

Do for example 0xbc000000 sets protection on 0x08000000 -> 0x081FFFFFF, 0xbc000004 sets on 0x08200000 -> 0x083FFFFF and so on.

There doesn't seem to be any registers for any addresses greater than this so Sony only protected the first 8Megs.
User avatar
harleyg
Posts: 123
Joined: Wed Oct 05, 2005 6:15 am

Post by harleyg »

Nice find tyranid.
jimparis
Posts: 1145
Joined: Fri Jun 10, 2005 4:21 am
Location: Boston

Post by jimparis »

Nice work as always :)
User avatar
Raphael
Posts: 646
Joined: Tue Jan 17, 2006 4:54 pm
Location: Germany
Contact:

Post by Raphael »

Very nice finding and good documentation of the finding :) Thanks Tyranid!
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki

Alexander Berl
zshadow
Posts: 42
Joined: Mon Dec 26, 2005 5:36 am

Post by zshadow »

Very nice work.
Fanjita
Posts: 217
Joined: Wed Sep 28, 2005 9:31 am

Post by Fanjita »

Great stuff.

I'm puzzled though - I've never had any problems accessing 0x08400000 - 0x08800000 from a user-mode thread, on 2.0 - 2.8.

Perhaps this is normally accessible from VSH threads, but not plain user threads, which would explain why I've never seen an access exception?

Then again, I'm relatively sure that I've dumped that memory space from GTA, too...
Got a v2.0-v2.80 firmware PSP? Download the eLoader here to run homebrew on it!
The PSP Homebrew Database needs you!
SamuraiX
Posts: 76
Joined: Tue Jan 31, 2006 6:28 am
Location: USA
Contact:

Post by SamuraiX »

Hmmm, perhaps I'm doing something wrong but I keep getting an exception. I'm using 1.5 firmware and I've tried user and kernel mode.

sceSuspendAllocExtraMem sceSuspendForUser_3E0271D3 gives me an exception

sceSuspendTryAllocExtraMem sceSuspendForUser_A14F40B2 is reported as undefined reference to `sceSuspendForUser_A14F40B2' when linking


as for the usuage....

Code: Select all

static void **filecache;
int *size = &#40;int*&#41;&#40;16384*255+64&#41;;   // 4177984 Bytes &#40;sceSuspendAllocExtraMem up to 4194304 Bytes&#41;

sceSuspendAllocExtraMem&#40;0, filecache, size&#41;;
This keeps causing an exception within the function.

Any help would be much appreciated. Thank You in Advance!
TyRaNiD
Posts: 907
Joined: Sun Jan 18, 2004 12:23 am

Post by TyRaNiD »

Fanjita, well perhaps it is just available on 2.0 and greater, it is possible Sony realised noone had used it on 1.5x games and just reverted the change. I Dont do any 2.x development so it wasn't tested by me :)

SamuraiX, ill check on the undefined reference problem, perhaps I have just made a typo somewhere. As for why it is crasing it is cause you are not using it correctly. You are passing in uninitalised pointers, you need to change it to something like.

Code: Select all

static void *filecache;
int size;   // No need to set to anything, its value isn't used

sceSuspendAllocExtraMem&#40;0, &filecache, &size&#41;; 
// filecache is now 0x08400000 and size 4Megs
moonlight
Posts: 567
Joined: Wed Oct 26, 2005 7:46 pm

Post by moonlight »

Fanjita wrote:Great stuff.

I'm puzzled though - I've never had any problems accessing 0x08400000 - 0x08800000 from a user-mode thread, on 2.0 - 2.8.

Perhaps this is normally accessible from VSH threads, but not plain user threads, which would explain why I've never seen an access exception?

Then again, I'm relatively sure that I've dumped that memory space from GTA, too...
I never tested read to that memory in gta, but i tested writing and my test app crashed. In that space of memory is loaded pafmini, common_gui, etc that are loaded by utility.prx whenever a system dialog is created, so it would have sense to have that area not accesible to a user thread.
moonlight
Posts: 567
Joined: Wed Oct 26, 2005 7:46 pm

Post by moonlight »

Btw, tyranid, the true names of those three functions are known and they are in my prx doc.

sceSuspendForUser_3E0271D3 -> sceKernelVolatileMemLock
sceSuspendForUser_A14F40B2 -> sceKernelVolatileMemTryLock
sceSuspendForUser_A569E425 -> sceKernelVolatileMemUnlock
SamuraiX
Posts: 76
Joined: Tue Jan 31, 2006 6:28 am
Location: USA
Contact:

Post by SamuraiX »

What a great find TyRaNiD!!! Works like a charm. The extra memory does come handy...:)

It also works great in 2.71SE-A
TyRaNiD
Posts: 907
Joined: Sun Jan 18, 2004 12:23 am

Post by TyRaNiD »

moonlight, oh okay you should have said :P Ill change svn just to break everyones stuff, hehe ;)

And perhaps unsurprisingly the corresponding power functions are called scePowerVolatileMemLock etc. Might be worth updating your doc :P
User avatar
groepaz
Posts: 305
Joined: Thu Sep 01, 2005 7:44 am
Contact:

Post by groepaz »

very nice....finally something lowlevel again =)

about 2.x... 1.5 seems to be the _only_ firmware that actually protects the second 4mb (besides implied protection beeing kernelmode only).
weltall
Posts: 310
Joined: Fri Feb 20, 2004 1:56 am
Contact:

Post by weltall »

from a kernel prx point of virew i've noticed that the 4mb volatile ram under 2.71 is enabled only when the browser is opened (and the browser itself allocates ~ 2mb of ram) and during the bootup process (at least during the game bootup) then tries to access to that area makes the psp shout down.
plus when the area is enabled partition functions works fine :)
be2003
Posts: 144
Joined: Thu Apr 20, 2006 2:46 pm

Re: Accessing the extra 4Megs of RAM on 1.5+

Post by be2003 »

TyRaNiD wrote:As some will know on 1.0 there was an extra 4megs of RAM from 0x8400000 which you could access, on 1.5 if you access it you get an exception, what is going on here?

Well I just added the functions to the SDK to allow access to these areas, there are in sceSuspendForUser for usermode calls and scePower_driver for kernel mode.

For user mode they are defined in pspsuspend.h as:

Code: Select all

sceSuspendForUser_3E0271D3&#40;int unk, void **ptr, int *size&#41;;
int sceSuspendForUser_A14F40B2&#40;int unk, void **ptr, int *size&#41;;
int sceSuspendForUser_A569E425&#40;void&#41;;
The first is a allocate function, pass in a pointer and a size integer and if you can allocate it it will return the appropriate info. The second is a try allocate, it polls a semaphore and if it is already alloced will return an error. The final one is the deallocate.

For kernel mode they are:

Code: Select all

scePower_driver_23C31FFE
scePower_driver_FA97A599
scePower_driver_B3EDD801
Same prototypes as the suspend ones. The suspend ones just call the power ones anyway through a callback (which then proceeds to call back into sysmem anyway, why Sony why :P).

Now as these are in a suspend library it is a fair chance that the kernel uses them for something, I haven't tested it but it might be used when suspending or sommit therefore you might not be able to use it as a general purpose area :( Still worth a try and see how far you get ;P

Now for the techy minded this is an explanation of how they work :) The core function is sceKernelSetDdrMemoryProtection(void *addr, int size, int prot). By calling this you can set the memory protection bits on certain memory blocks (well only in the first 8Mb of DDR). Addr is obvious, size is a value up to 2 megs in 256KByte blocks, prot is a 4 bit mask which determines the protection.

The prot mask is thus:

Bit 3 - Kernel Write Enable
Bit 2 - Kernel Read Enable
Bit 1 - User Write Enable
Bit 0 - User Read Enable

The first four megs are all set to 0xC prot mask which means kernel only read/write, this is interesting cause you can therefore "unprotect" the kernel only address space and access it in user mode :)

e.g.

Code: Select all

sceKernelSetDdrMemoryProtection&#40;&#40;void*&#41; 0x08000000, 2*1024*1024, 0xF&#41;;
Will allow the first 2 megs of kernel memory to be accessed from user space.

Now for the real techy minded (i.e. groepaz) this is what that function is doing.

The memory protection registers are 8 32bit words stating at 0xbc000000. Each 32bit is split into 8 4bit protection masks starting LSB first, i.e. bits 0 to 3 are the first 256KBytes of that chunk, bits 4 to 7 are the next etc. And as each register can address 8 256KByte blocks then the address space is split into 2Mbyte chunks.

Do for example 0xbc000000 sets protection on 0x08000000 -> 0x081FFFFFF, 0xbc000004 sets on 0x08200000 -> 0x083FFFFF and so on.

There doesn't seem to be any registers for any addresses greater than this so Sony only protected the first 8Megs.
eh...
my computer gives me an "undefined reference to..." when i try and call sceKernelVolatileMemTryLock(int unk, void **ptr, int *size);
so i think the toolchain might be bugged, lol

so i did a quick prxtool to sysmem.prx (1.50) and built a makeshift libpspsuspend.a and i came up with a few theories about those functions and i need someone to clear them up for me

when i call sceSuspendForUser_3E0271D3 (sceKernelVolatileMemLock) it works just fine until i attempt to call it again after the memory is already allocated. i dont think it causes an exception, it just seems to hang and all other threads seem to be working perfectly fine.
1st call: returns 0
2nd call: hang, doesnt return squat

also when i call sceSuspendForUser_A14F40B2 (sceKernelVolatileMemTryLock) before i call sceKernelVolatileMemLock it returns 0 like it should, but then it makes the psp hang again... letting all other threads run
but if i call sceKernelVolatileMemTryLock after sceKernelVolatileMemLock it returns some random negative int (which is normal i guess), and the psp doesnt hang

so im trying to write a function that will check to see if that 4 mb of memory has been allocated and if it hasnt then allocate it and i need some help. i have:

Code: Select all

#define sceSuspendAllocateExtraMemory 	sceSuspendForUser_3E0271D3
#define sceSuspendTryExtraMemory 		sceSuspendForUser_A14F40B2
#define sceSuspendFreeExtraMemory 		sceSuspendForUser_A569E425
if&#40;sceSuspendTryExtraMemory&#40;0, &temp_loc, &temp_size&#41; == 0&#41; //ram not allocated
	&#123;
		sceSuspendAllocateExtraMemory&#40;0, &temp_loc, &temp_size&#41;; //so lets allocate it
	&#125; 
but like i said before it hangs if sceSuspendTryExtraMemory is called before sceSuspendAllocateExtraMemory
- be2003
blog
Pit0711
Posts: 54
Joined: Thu Mar 24, 2005 5:45 am
Location: Old Europe -Germany-

Post by Pit0711 »

PSP2 has 64 Megs RAM :-)
Anti-QJ
Posts: 16
Joined: Thu May 03, 2007 2:34 pm

Post by Anti-QJ »

Link?
Please...
kururin
Posts: 36
Joined: Wed Jul 05, 2006 7:19 am

Post by kururin »

Anti-QJ wrote:Link?
Please...
I saw these images in some forums, i don't know original source though.
http://i202.photobucket.com/albums/aa11 ... SPSPEC.jpg

Nothing is said about the flash, but maybe it will have 64 (well, 66) MB too.
User avatar
dot_blank
Posts: 498
Joined: Wed Sep 28, 2005 8:47 am
Location: Brasil

Post by dot_blank »

well since 64MB RAM is used and 64MB NAND PIN
assignments change ..its a pretty save bet that the
psp200x will use the same 528byte pages
10011011 00101010 11010111 10001001 10111010
Post Reply