information regarding the PSP nand controller, and below I present
some info on the nand hardware registers. The information is probably
not 100% correct, obviously. I simply looked over my reversed source
code and tried to dechipher the meaning of the registers from that. No
testing or experimentation was performed. Besides the clear danger of
me misinterpretting something, there is also the possibility that the
controller has changed with different revisions. The information
presented here was obtained from a 1.5 fw PSP.
Code: Select all
bd101000: Nand Control Reg (rw)
+---------------------------------+
|31 - 18 | 17 | 16 | 15 - 0 |
| ??? | ECCWR | ECCRD | ??? |
+---------------------------------+
ECCWR: Calculate ECC for user page during writing
ECCRD: Calculate ECC for user page during reading
-----------------------------------------------------------------
bd101004: Nand Status Reg (rw)
+-----------------------------+
| 31 - 8 | 7 | 6 - 1 | 0 |
| ??? | PROT | ??? | RDY |
+-----------------------------+
PROT: 0: NAND is not write-protected
1: NAND is write-protected
RDY: 0: NAND is busy
1: NAND is ready
-----------------------------------------------------------------
bd101008: Nand Command Reg (w)
+---------------+
|31 - 8 | 7 - 0 |
| ??? | CMD |
+---------------+
CMD: 0x50 - Read Spare Page
0x60 - Erase block1
0x70 - Read Status
0x90 - Read ID
0xd0 - Erase block2
0xff - Reset
Maybe all commands are supported?
-----------------------------------------------------------------
bd10100c: Nand Address Reg (w)
+--------------------------+
|31 - 27 | 26 - 10 | 9 - 0 |
| ??? | ADDR | ??? |
+--------------------------+
ADDR: Physical page to access
-----------------------------------------------------------------
bd101014: Nand Reset Reg (w)
+-------------+
|31 - 1 | 0 |
| ??? | RST |
+-------------+
RST: Reset NAND controller to default state?
-----------------------------------------------------------------
bd101020: Nand DMA Address Reg (w)
+--------------------------+
|31 - 27 | 26 - 10 | 9 - 0 |
| ??? | ADDR | ??? |
+--------------------------+
ADDR: Physical page to access
-----------------------------------------------------------------
bd101024: Nand DMA Control Reg (w)
+----------------------------------------+
|31 - 19 | 9 | 8 | 7 - 2 | 1 | 0 |
| ??? | EN1 | EN2 | ??? | DIR | EN0 |
+----------------------------------------+
EN1: Set to enable DMA transfer? (ECC?) Or set to clear previous status?
EN2: Set to enable DMA transfer? (USER?) Or set to clear previous status?
DIR: 0 -> Transfer from Nand to Nand Data Buffer
1 -> Transfer from Nand Data Buffer to Nand
EN0: Set to enable DMA transfer
-----------------------------------------------------------------
bd101028: Nand DMA Status Reg (r)
+-------+
|31 - 0 |
| STAT |
+-------+
STAT: Maybe != 0 -> write failed?
-----------------------------------------------------------------
bd101038: Nand DMA Intr Reg (rw)
+----------------------------------------+
|31 - 19 | 9 | 8 | 7 - 2 | 1 | 0 |
| ??? | IN1 | IN2 | ??? | IN3 | IN4 |
+----------------------------------------+
Probably the same bits as bd101024
-----------------------------------------------------------------
bd101200: Nand Resume Reg (write 0x0b040205 to resume?) (w)
+-------+
|31 - 0 |
| RES |
+-------+
RES: write 0x0b040205 to resume?
-----------------------------------------------------------------
bd101300: Nand Serial Data Reg (rw?)
+------------------------------------+
|31 - 24 | 23 - 16 | 15 - 8 | 7 - 0 |
| byte 3 | byte 2 | byte 1 | byte 0 |
+------------------------------------+
Serial Data register
-----------------------------------------------------------------
bff00000: Nand DMA User Data Buf start (rw)
bff00200: Nand DMA USer Data Buf end
512 bytes buffer to hold DMA data for a user page.
-----------------------------------------------------------------
bff00800: Nand User ECC Reg (rw)
+-------+
|31 - 0 |
| ECC |
+-------+
Hardware calculated ECC for a user page
-----------------------------------------------------------------
bff00900: Nand DMA Spare Data Buf start (rw)
bff00910: Nand DMA Spare Data Buf end
16 bytes buffer to hold DMA data for a spare page.
Moonlight:
How to write to NAND using hardware register poking:
1) Copy user data to Nand User Data buf (bff00000 - bff00200) (careful with cache!)
2) Write ECC value to Nand User ECC buf (bff00800) (Alternatively, the hw might be able to generate it)
3) Write appropriate flags to Nand Control reg (bd1010000)
4) Write spare data to Nand Spare Data buf (bff00900 - bff00910)
5) Write page number to Nand DMA Addr reg (bd101020)
6) Clear appropriate flags in the Nand DMA Intr reg (bd101038)
7) Start DMA transfer by writing the appropriate flags to Nand DMA control reg (bd101024)
8) Wait for interrupt and process accordingly
Maybe it's possible to write data using the serial data register too, but I haven't seen anything
in the firmware that utilizes that.
How to read from NAND:
1) Write appropriate flags to Nand Control reg (bd1010000)
2) Write page number to Nand DMA Addr reg (bd101020)
3) Clear appropriate flags in the Nand DMA Intr reg (bd101038)
4) Start DMA transfer by writing the appropriate flags to the Nand DMA control reg (bd101024)
5) Wait for interrupt
6) Copy user data from Nand User Data buf (bff00000 - bff00200) (careful with cache!)
7) Check User ECC status (?) (bff00800)
8) Copy ECC value from from Nand User ECC buf (bff00800)
9) Copy spare data from Nand Spare Data buf (bff00900)
10) Check Spare ECC manually
EDIT: corrected some register info