| View previous topic :: View next topic |
| Author |
Message |
adrahil
Joined: 16 Mar 2006 Posts: 277
|
Posted: Fri Sep 22, 2006 7:35 am Post subject: sceNandReadId and sceNandLock |
|
|
Hello everybody!
I might be asking a stupid question, but I didn't find the answer in any of the posts in here... I've been fiddling around emc_sm.prx, and this is what I found out about sceNandReadId and sceNandLock:
(not standard ANSI C syntax...)
| Code: | int sceNandLock(int state){
//Lock the Nand for writing.
// argument state:
// 1 = write-protect
// 0 = write-enable
#define nand_semaphore *(0x00000040)
#define nand_clock_enabled *(0x00000048)
#define nand_hw_lock_addr 0xbd101004
#define FLAG_LOCK 0x0080
#define FLAG_UNLOCK -0x81
int sema;
sema = sceKernelWaitSema(nand_semaphore, 1, 0);
if (sema < 0) return sema;
if (!nand_clock_enabled){
sceSysregEmcsmBusClockEnable();
}
if (state == 0){
*nand_hw_lock_addr = *nand_hw_lock_addr & FLAG_UNLOCK;
} else {
*nand_hw_lock_addr = *nand_hw_lock_addr | FLAG_LOCK;
}
return 0;
} |
| Code: | int sceNandReadId(int *id, int len){
//probably the command to send. reading ID?
#define nand_hw_addr1 0xbd101008
//maybe the position to start from.
#define nand_hw_addr2 0xbd10100c
//this might be the reset of the buffer, or anything else...
#define nand_hw_addr3 0xbd101014
//the buffer to read from.
#define nand_hw_addr4 0xbd101300
*nand_hw_addr1 = 0x90;
*nand_hw_addr2 = 0;
if (len <= 0){
*nand_hw_addr3 = 1;
return 0;
}
i = 0;
do{
if(&id == 0) continue;
//read only one byte at a time and store to given buffer.
id[i] = *0xbd101300 & 0xff;
i++;
}while (i<len);
*nand_hw_addr3 = 1;
return 0;
} |
Well, my question is, does anyone know what these addresses are for: 0xbd101008, 0xbd10100c, 0xbd101014, 0xbd101300 ? I have made rough guesses as you can see in the comments of the code, but I'm still unsure... :(
Last edited by adrahil on Fri Sep 22, 2006 5:17 pm; edited 1 time in total |
|
| Back to top |
|
 |
adrahil
Joined: 16 Mar 2006 Posts: 277
|
Posted: Fri Sep 22, 2006 7:44 am Post subject: |
|
|
Hmm, I'm really blind... I found three of the addresses in groepaz's doc...
0xbd101008 = Command
0xbd10100c(*) = Address
0xbd101300 = Data (read)
However, there is one which is not inside: 0xbd101014(*).
Does anybody know what it is for?
Last edited by adrahil on Fri Sep 22, 2006 5:32 pm; edited 1 time in total |
|
| Back to top |
|
 |
moonlight
Joined: 26 Oct 2005 Posts: 567
|
Posted: Fri Sep 22, 2006 11:36 am Post subject: |
|
|
| adrahil wrote: | Hmm, I'm really blind... I found three of the addresses in groepaz's doc...
0xbd101008 = Command
0xbd101014 = Address
0xbd101300 = Data (read)
However, there is one which is not inside: 0xbd10100c.
Does anybody know what it is for? |
0xbd10100c = address;
0xbd101014 != address; 0xbd101014 = end transition (if i don't remember bad) |
|
| Back to top |
|
 |
adrahil
Joined: 16 Mar 2006 Posts: 277
|
Posted: Fri Sep 22, 2006 3:05 pm Post subject: |
|
|
I had inverted the addresses :P
What is exactly the end transition? |
|
| Back to top |
|
 |
hlide
Joined: 10 Sep 2006 Posts: 750
|
Posted: Fri Sep 22, 2006 4:09 pm Post subject: |
|
|
well I suppose it means EOC (End Of Command) or EOT (End of Transfer), etc.
| Code: |
do{
if (id[0] == 0) continue;
//read only one byte at a time and store to given buffer.
id[i] = *0xbd101300 & 0xff;
i++;
}while (i<len);
|
Are you sure about id[0] == 0 ? that code must be wrong for it makes no sense to do so : if your id[0] is '\0' you will loop without reading any byte instead of breaking...
should not it be indeed :
| Code: |
int i = 0;
while (i<len)
if (id[i] = (*0xbd101300) & 255)
i++;
else
break;
|
or if you prefer :
| Code: |
for (int i = 0; i<len; ++i)
if ((id[i] = ((*0xbd101300) & 255)) == 0)
break;
|
Maybe you was not considering delay slot instruction (the instruction following an branch instruction is always executed BEFORE branching), reading that code the wrong way. |
|
| Back to top |
|
 |
adrahil
Joined: 16 Mar 2006 Posts: 277
|
Posted: Fri Sep 22, 2006 5:12 pm Post subject: |
|
|
| Code: | beq r4,0,$00000704 ;000006F8[10800002,'....']
andi r2,r8,$00ff ;000006FC[310200FF,'...1']
sb r2,$0(r7) ;00000700[A0E20000,'....'] |
well I probably mixed up address and value :P it's more like:
| Code: | | if(&id == 0) continue; |
It's not an if-imbricked-assignment, and r4 doesnt vary :) |
|
| Back to top |
|
 |
ryoko_no_usagi

Joined: 29 Nov 2005 Posts: 65
|
Posted: Fri Sep 22, 2006 7:41 pm Post subject: |
|
|
Here's the relevant code from my reversed source :)
| Code: |
s32
sceNandReadId(void *buf, s32 len)
{
char *p = (char *)buf;
int i;
*(u32 *)0xbd101008 = 0x0000090;
*(u32 *)0xbd10100c = 0x0000000;
for (i = 0; i < len; i++) {
if (p) p[i] = (char)((*(volatile u32 *)0xbd101300) & 0xff);
}
*(u32 *)0xbd101014 = 0x00000001;
return 0;
}
|
I have a lot (most?) of emc_sm.prx in "pseudo" C code if anyone wants to know something... |
|
| Back to top |
|
 |
groepaz

Joined: 01 Sep 2005 Posts: 305
|
|
| Back to top |
|
 |
hlide
Joined: 10 Sep 2006 Posts: 750
|
Posted: Sat Sep 23, 2006 3:34 am Post subject: |
|
|
| adrahil wrote: | | Code: | beq r4,0,$00000704 ;000006F8[10800002,'....']
andi r2,r8,$00ff ;000006FC[310200FF,'...1']
sb r2,$0(r7) ;00000700[A0E20000,'....'] |
well I probably mixed up address and value :P it's more like:
| Code: | | if(&id == 0) continue; |
It's not an if-imbricked-assignment, and r4 doesnt vary :) |
well, you're right. Me seems SONY developers drinks too much sake when they code this function ;). |
|
| Back to top |
|
 |
moonlight
Joined: 26 Oct 2005 Posts: 567
|
Posted: Sat Sep 23, 2006 5:01 am Post subject: |
|
|
| ryoko, do you know how to use the commands to write to the nand? |
|
| Back to top |
|
 |
ryoko_no_usagi

Joined: 29 Nov 2005 Posts: 65
|
Posted: Mon Sep 25, 2006 7:32 pm Post subject: |
|
|
Oops, I had a closer look on my source, and I realize I'm missing pretty significant chunks of the callback routine that handles the hardware access. I'll have a look at the psp-doc and see if I can add something though.
Moonlight: do you mean hardware register writing or just using the sceNandWrite syscalls? The latter should be known by know, isn't it?
For hardware way, the controller uses the same commands as descibed in the nand datasheet as far as I recall.
EDIT: Moonlight, here's a NID you seem to be missing for sceNand: 0x3f76bc21 sceNandDumpWearBBMSize |
|
| Back to top |
|
 |
moonlight
Joined: 26 Oct 2005 Posts: 567
|
Posted: Mon Sep 25, 2006 8:29 pm Post subject: |
|
|
| ryoko_no_usagi wrote: | Oops, I had a closer look on my source, and I realize I'm missing pretty significant chunks of the callback routine that handles the hardware access. I'll have a look at the psp-doc and see if I can add something though.
Moonlight: do you mean hardware register writing or just using the sceNandWrite syscalls? The latter should be known by know, isn't it?
For hardware way, the controller uses the same commands as descibed in the nand datasheet as far as I recall.
EDIT: Moonlight, here's a NID you seem to be missing for sceNand: 0x3f76bc21 sceNandDumpWearBBMSize |
Thanks ryoko. i will add it to the docs :).
I meant hardware register of course :) |
|
| Back to top |
|
 |
|