sceKernelIcacheInvalidateRange on v1.0 firmware

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

Moderators: cheriff, TyRaNiD

Post Reply
RustyFunkNut
Posts: 17
Joined: Mon Sep 26, 2005 5:10 am
Location: London, UK

sceKernelIcacheInvalidateRange on v1.0 firmware

Post by RustyFunkNut »

I've been working on dynamic code generation for an emulator, and I've been strugging with a few odd bugs which I believe I've tracked down to the incorrect flushing of the instruction cache.

I am calling sceKernelIcacheInvalidateRange to invalidate the instructions I've written (and I'm writing through an uncached pointer so I don't think the dcache is an issue here), but I'm not convinced it's working correctly (at least on the v1.0 firmware I'm developing on).

When I look at the disassembly for the various sceKernel* stubs in my image (at runtime, after they've been patched), this is what I see:

Code: Select all

sceKernelDcacheWritebackAll:
0x08994A28: 03E00008 - jr         $ra
0x08994A2C: 0008310C - syscall    0x20C4

sceKernelDcacheWritebackRange:
0x08994A30: 03E00008 - jr         $ra
0x08994A34: 0008318C - syscall    0x20C6

sceKernelExitGame:
0x08994A38: 03E00008 - jr         $ra
0x08994A3C: 0008384C - syscall    0x20E1

sceKernelRegisterExitCallback:
0x08994A40: 03E00008 - jr         $ra
0x08994A44: 0008388C - syscall    0x20E2

sceKernelIcacheInvalidateRange:
0x08994A48: 0000054C - syscall    0x15
0x08994A4C: 00000000 - nop
The syscall for sceKernelIcacheInvalidateRange looks a little suspicious here (I guess the syscall 0x15 just performs some kind of no-op??) I did a little more digging, and found this list of syscalls for the various firmware revisions:

http://hitmen.c02.at/files/releases/psp/syscalls.txt

These rows show the syscall for v1.0, 1.5, 1.52 and 2.0 firmware:

Code: Select all

sceKernelIcacheInvalidateAll             |0x920f104a|      |0x20cc|0x20cc|0x20cd| *** differences ***
sceKernelIcacheInvalidateRange           |0xc2df770e|      |0x20b6|0x20b6|0x20b8| *** differences ***
As far as I can tell, it looks like the calls to sceKernelIcacheInvalidateAll/sceKernelIcacheInvalidateRange are undetermined for v1.0 firmware (hence the blank slot in the rows)?

So I guess my question is, are these now known/available for v1.0 (and hence I need to update my pspsdk installaton)?

If they're not known the alternative is to flush the cache manually. I'm familiar with MIPS assembly, but I have no idea if the cache management instructions are the same on the PSP. If I need to take this route, can anyone supply any references that I can chase up?

Cheers,
Paul
TyRaNiD
Posts: 907
Joined: Sun Jan 18, 2004 12:23 am

Post by TyRaNiD »

For what ever reason the icache operations are only available in kernel mode on a v1.0, as you can tell there is no syscall available for them. Either make your app a kernel mode application (not a great idea) or write a quick and dirty export prx and load that (not exactly clean either).

You _might_ be able to use the cache operations in MIPS assembly but I would expect they are classed as privileged instructions and so will cause your app to crash. I think opcode 8 is instruction cache invalidate, so do

Code: Select all

cache 8, 0($v0)
where $v0 is the 64byte aligned address, and that invalidates a cache line (i.e. 64bytes). But I could be wrong :P
RustyFunkNut
Posts: 17
Joined: Mon Sep 26, 2005 5:10 am
Location: London, UK

Post by RustyFunkNut »

Hi TyRaNid,

I've just knocked up a quick test, and it looks like

Code: Select all

cache 8, 0($v0)
works perfectly - many thanks!
Post Reply