sceNandReadId and sceNandLock

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

Moderators: cheriff, TyRaNiD

Post Reply
adrahil
Posts: 274
Joined: Thu Mar 16, 2006 1:55 am

sceNandReadId and sceNandLock

Post by adrahil »

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: Select all

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 &#40;sema < 0&#41; return sema;

  if &#40;!nand_clock_enabled&#41;&#123;
    sceSysregEmcsmBusClockEnable&#40;&#41;;
  &#125;

  if &#40;state == 0&#41;&#123;
    *nand_hw_lock_addr = *nand_hw_lock_addr & FLAG_UNLOCK;
  &#125; else &#123;
    *nand_hw_lock_addr = *nand_hw_lock_addr | FLAG_LOCK;
  &#125;

  return 0;
&#125;

Code: Select all

int sceNandReadId&#40;int *id, int len&#41;&#123;
  //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 &#40;len <= 0&#41;&#123;
    *nand_hw_addr3 = 1;
    return 0;
  &#125;

  i = 0;
  do&#123;
    if&#40;&id == 0&#41; continue;
    //read only one byte at a time and store to given buffer.
    id&#91;i&#93; = *0xbd101300 & 0xff;
    i++;
  &#125;while &#40;i<len&#41;;

  *nand_hw_addr3 = 1;

  return 0;
&#125;
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.
adrahil
Posts: 274
Joined: Thu Mar 16, 2006 1:55 am

Post by adrahil »

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.
moonlight
Posts: 567
Joined: Wed Oct 26, 2005 7:46 pm

Post by moonlight »

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)
adrahil
Posts: 274
Joined: Thu Mar 16, 2006 1:55 am

Post by adrahil »

I had inverted the addresses :P
What is exactly the end transition?
hlide
Posts: 739
Joined: Sun Sep 10, 2006 2:31 am

Post by hlide »

well I suppose it means EOC (End Of Command) or EOT (End of Transfer), etc.

Code: Select all

  do&#123;
    if &#40;id&#91;0&#93; == 0&#41; continue;
    //read only one byte at a time and store to given buffer.
    id&#91;i&#93; = *0xbd101300 & 0xff;
    i++;
  &#125;while &#40;i<len&#41;;
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: Select all

  int i = 0;
  while &#40;i<len&#41;
    if &#40;id&#91;i&#93; = &#40;*0xbd101300&#41; & 255&#41;
      i++;
    else
      break;
or if you prefer :

Code: Select all

  for &#40;int i = 0; i<len; ++i&#41;
    if &#40;&#40;id&#91;i&#93; = &#40;&#40;*0xbd101300&#41; & 255&#41;&#41; == 0&#41;
      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.
adrahil
Posts: 274
Joined: Thu Mar 16, 2006 1:55 am

Post by adrahil »

Code: Select all

  beq    r4,0,$00000704                     ;000006F8&#91;10800002,'....'&#93;
  andi   r2,r8,$00ff                        ;000006FC&#91;310200FF,'...1'&#93;
  sb     r2,$0&#40;r7&#41;                          ;00000700&#91;A0E20000,'....'&#93;
well I probably mixed up address and value :P it's more like:

Code: Select all

if&#40;&id == 0&#41; continue;
It's not an if-imbricked-assignment, and r4 doesnt vary :)
User avatar
ryoko_no_usagi
Posts: 65
Joined: Tue Nov 29, 2005 4:47 pm

Post by ryoko_no_usagi »

Here's the relevant code from my reversed source :)

Code: Select all

s32
sceNandReadId&#40;void *buf, s32 len&#41;
&#123;
        char *p = &#40;char *&#41;buf;
        int i;

        *&#40;u32 *&#41;0xbd101008 = 0x0000090;
        *&#40;u32 *&#41;0xbd10100c = 0x0000000;

        for &#40;i = 0; i < len; i++&#41; &#123;
                if &#40;p&#41; p&#91;i&#93; = &#40;char&#41;&#40;&#40;*&#40;volatile u32 *&#41;0xbd101300&#41; & 0xff&#41;;
        &#125;
        *&#40;u32 *&#41;0xbd101014 = 0x00000001;
        return 0;
&#125;
I have a lot (most?) of emc_sm.prx in "pseudo" C code if anyone wants to know something...
User avatar
groepaz
Posts: 305
Joined: Thu Sep 01, 2005 7:44 am
Contact:

Post by groepaz »

i would definetly like to have a look at it so i can update my doc...
hlide
Posts: 739
Joined: Sun Sep 10, 2006 2:31 am

Post by hlide »

adrahil wrote:

Code: Select all

  beq    r4,0,$00000704                     ;000006F8&#91;10800002,'....'&#93;
  andi   r2,r8,$00ff                        ;000006FC&#91;310200FF,'...1'&#93;
  sb     r2,$0&#40;r7&#41;                          ;00000700&#91;A0E20000,'....'&#93;
well I probably mixed up address and value :P it's more like:

Code: Select all

if&#40;&id == 0&#41; 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 ;).
moonlight
Posts: 567
Joined: Wed Oct 26, 2005 7:46 pm

Post by moonlight »

ryoko, do you know how to use the commands to write to the nand?
User avatar
ryoko_no_usagi
Posts: 65
Joined: Tue Nov 29, 2005 4:47 pm

Post by ryoko_no_usagi »

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
moonlight
Posts: 567
Joined: Wed Oct 26, 2005 7:46 pm

Post by moonlight »

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 :)
Post Reply