sceNand function declarations

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

Moderators: cheriff, TyRaNiD

Post Reply
User avatar
ryoko_no_usagi
Posts: 65
Joined: Tue Nov 29, 2005 4:47 pm

sceNand function declarations

Post by ryoko_no_usagi »

Here are most declarations for exported sceNand functions together with short explanations:

Code: Select all

/* Initializes the nand-module */
int sceNandInit();


/* Enables/disables write protection for the nand
 * protect = TRUE, write protect nand
 * protect = FALSE, enable writing to nand
*/
int sceNandProtect(bool_t protect);


/* Gains exclusive access to nand
 * write = TRUE enables writing to nand
*/
int sceNandLock(bool_t write);


/* Releases exclusive access to nand */
int sceNandUnlock(void);


/* Issues a RESET command to the nand
 * buf = buffer to hold status byte or NULL
*/
int sceNandReset(u8 *status);


/* Issues an ID command to the nand
 * id = buffer to hold id codes
 * len = size of id buffer
*/
int sceNandReadId(u8 *id, s32 len);


/* USER_ECC_IN_SPARE means that the spare page buffer contains four bytes at the beginning, reserved for user page ECC.
 * NO_AUTO_USER_ECC disables automatic ECC calculations for user pages.
 * NO_AUTO_SPARE_ECC disables automatic ECC calculations for spare pages.
*/
typedef enum {
    USER_ECC_IN_SPARE = 0x01,
    NO_AUTO_USER_ECC = 0x10,
    NO_AUTO_SPARE_ECC = 0x20
} SceNandEccMode_t;


/* Read physical pages from nand
 * ppn = physical page number
 * user = buffer for user pages or NULL
 * spare = buffer for spare pages or NULL
 * len = number of pages to read, max. 32
 * mode = how ECC is to be handled and the size of the spare page buffer
*/
int sceNandReadAccess(u32 ppn, u8 *user, u8 *spare, u32 len, SceNandEccMode_t mode);


/* Write physical pages to nand
 * ppn = physical page number
 * user = buffer for user pages or NULL
 * spare = buffer for spare pages or NULL
 * len = number of pages to write, max 32
 * mode = how ECC is to be handled and the size of the spare page buffer
*/
int sceNandWriteAccess(u32 ppn, u8 *user, u8 *spare, u32 len, SceNandEccMode_t mode);


/* Issues an ERASE BLOCK command to the nand controller
 * ppn = physical page number
*/
int sceNandEraseBlock(u32 ppn);


/* Reads spare pages without auto ECC from nand through serial interface
 * ppn = physical page number
 * spare = buffer for spare pages (16 bytes per page, user ECC stored)
 * len = number of spare pages to read, max 32.
*/
int sceNandReadExtraOnly(u32 ppn, u8 *spare, u32 len);


/* Releases the nand module */
int sceNandEnd(void);


/* Suspends nand module (NOP atm) */
int sceNandSuspend(void);


/* Reinitializes the nand module */
int sceNandResume(void);


/* Issues a STATUS command to the nand and returns the result */
int sceNandReadStatus(void);


/* Reads user and spare pages from nand with automatic ECC
 * ppn = physical page number
 * user = buffer for user pages or NULL
 * spare = buffer for spare pages (12 bytes, no user ECC stored)
 * len = number of pages to read, max 32
*/
int sceNandReadPages(u32 ppn, u8 *user, u8 *spare, u32 len);


/* Writes user and spare pages to nand with automatic ECC
 * ppn = physical page number
 * user = buffer for user pages or NULL
 * spare = buffer for spare pages or NULL (12 bytes, no user ECC provided)
 * len = number of pages to write, max 32
*/
int sceNandWritePages(u32 ppn, u8 *user, u8 *spare, u32 len);


/* Reads user pages with automatic ECC and spare pages without automatic ECC from nand
 * ppn = physical page number
 * user = buffer for user pages or NULL
 * spare = buffer for spare pages or NULL (12 bytes, no user ECC stored)
 * len = number of pages to read, max 32
*/
int sceNandReadPagesRawExtra(u32 ppn, u8 *user, u8 *spare, u32 len);


/* Writes user pages with automatic ECC and spare pages without automatic ECC to nand
 * ppn = physical page number
 * user = buffer for user pages or NULL
 * page = buffer for spare pages or NULL (12 bytes, no user ECC provided)
 * len = number of pages to write, max 32
*/
int sceNandWritePagesRawExtra(u32 ppn, u8 *user, u8 *spare, u32 len);


/* Reads user and spare pages from nand without automatic ECC
 * ppn = physical page number
 * user = buffer for user pages
 * spare = buffer for spare pages (16 bytes, user ECC stored)
 * len = number of pages to read, max 32
*/
int sceNandReadPagesRawAll(u32 ppn, u8 *user, u8 *spare, u32 len);


/* Writes user and spare pages to nand without automatic ECC
 * ppn = physical page number
 * user = buffer for user pages
 * spare = buffer for spare pages (16 bytes, user ECC stored)
 * len = number of pages to write, max 32
*/
int sceNandWritePagesRawAll(u32 ppn, u8 *user, u8 *spare, u32 len);


/* Reads the device and manufacturer code and looks up nand properties in internal db */
int sceNandDetectChip();


/* Erases the block, writes (with automatic ECC) and verifies it, retrying up to four times in case of failure
 * ppn = physical page number
 * user = buffer for user block
 * spare = buffer for spare block (12 bytes per page, no user ECC provided)
*/
int sceNandWriteBlockWithVerify(u32 ppn, u8 *user, u8 *spare);


/* Reads the block (with automatic ECC), retrying up to four times in case of failure
 * ppn = physical page number
 * user = buffer for user block
 * spare = buffer for spare block (12 bytes, no user ECC stored)
*/
int sceNandReadBlockWithRetry(u32 ppn, u8 *user, u8 *spare);


/* Verifies the block
 * ppn = physical page number
 * user = buffer for user block
 * spare = buffer for spare block (12 bytes per page, no user ECC stored)
*/
int sceNandVerifyBlockWithRetry(u32 ppn, u8 *user, u8 *spare);


/* Erases the block, retrying up to four times in case of failure
 * ppn = physical page number
*/
int sceNandEraseBlockWithRetry(u32 ppn);


/* Checks if the block is bad (check the block_status byte in the spare area)
 * ppn = physical page number
*/
int sceNandIsBadBlock(u32 ppn);


/* Erases all blocks on the nand */
int sceNandEraseAllBlock(void);


/* Returns the page size of the nand */
int sceNandGetPageSize(void);


/* Returns the number of pages per block of the nand */
int sceNandGetPagesPerBlock(void);


/* Returns the total number of blocks of the nand */
int sceNandGetTotalBlocks(void);


/* Erases the block and then writes it to nand with automatic ECC
 * ppn = physical page number
 * user = buffer for user block
 * spare = buffer for spare block (12 bytes per page, no user ECC provided)
*/
int sceNandWriteBlock(u32 ppn, u8 *user, u8 *spare);


/* Calculates and returns a 12-bit ECC value suitable for the spare area
 * buf = eight bytes of data on which to calculate
*/
int sceNandCalcEcc(u8 *buf);


/* Calculates and compares 12-bit ECC values and returns status
 * buf = eight bytes of data on which to calculate
 * ecc = 12-bit ECC value to compare against
 * Returns:  0 = ECC correct
 *          -1 = ECC incorrect, correctable single-bit error
 *          -2 = ECC incorrect, single-bit error in ECC itself
 *          -3 = ECC incorrect, multiple bit errors
*/
int sceNandVerifyEcc(u8 *buf, u16 ecc);


/* Calculates and compares 12-bit ECC values, corrects if possible, returns status
 * buf = eight bytes of data on which to calculate
 * ecc = 12-bit ECC value to compare against
 * Returns:  0 = ECC correct
 *          -1 = ECC incorrect, single-bit error corrected
 *          -2 = ECC incorrect, single-bit error in ECC itself
 *          -3 = ECC incorrect, multiple bit errors
 * Notes: this function appears to be broken. If a single bit error occurs, the ECC
 * can be used to identify the offending bit, but this function appears to implement an incorrect
 * correction routine. Instead of inverting the offending bit, the MSB of byte 7 is always
 * inverted. This looks like a mistake. Also, the name of the function should obviously be
 * sceNandCorrectEcc. The Japanese language does not make a distinction between 'r' and 'l'
 * so these spelling mistakes are quite common.
*/
int sceNandCollectEcc(u8 *buf, u16);
adrahil
Posts: 274
Joined: Thu Mar 16, 2006 1:55 am

Post by adrahil »

nice work :)
User avatar
harleyg
Posts: 123
Joined: Wed Oct 05, 2005 6:15 am

Post by harleyg »

Nice, thanks for this.
User avatar
dot_blank
Posts: 498
Joined: Wed Sep 28, 2005 8:47 am
Location: Brasil

Post by dot_blank »

thanx but there is one thing that stands out to me

/* Calculates and compares 12-bit ECC values and returns status
* buf = eight bytes of data on which to calculate
* ecc = 12-bit ECC value to compare against
* Returns: 0 = ECC correct
* -1 = ECC incorrect, correctable single-bit error
* -2 = ECC incorrect, single-bit error in ECC itself
* -3 = ECC incorrect, multiple bit errors
*/
int sceNandVerifyEcc(u8 *buf, u16 ecc);

...so is it unsigned char or unsigned long long ?

very important to make this clear for users
cheers
10011011 00101010 11010111 10001001 10111010
ufoz
Posts: 86
Joined: Thu Nov 10, 2005 2:36 am
Location: Tokyo
Contact:

Post by ufoz »

dot_blank wrote: ...so is it unsigned char or unsigned long long ?

very important to make this clear for users
cheers
Um, a pointer is a pointer. It points to the 8 bytes of data to check. I think that's pretty straightforward.
User avatar
ryoko_no_usagi
Posts: 65
Joined: Tue Nov 29, 2005 4:47 pm

Post by ryoko_no_usagi »

I don't know if that's a dig, dot_blank :) but I admit that my use of datatypes could be better. When I start to reverse I usually put void* for pointers and u32 for integers in declarations, and only go back and fix to proper types when it seems necessary, after I've got the definitions worked out. For the declarations I posted, I changed types on the fly to what I thought would be clear, but maybe it would have been better to retain void*...
moonlight
Posts: 567
Joined: Wed Oct 26, 2005 7:46 pm

Post by moonlight »

good work. I'll add the new nids to my prx doc that i have to update one of these days :P
User avatar
ryoko_no_usagi
Posts: 65
Joined: Tue Nov 29, 2005 4:47 pm

Post by ryoko_no_usagi »

Um, what new nids? :)
Wer mit Ungeheuern kämpft, mag zusehn, dass er nicht dabei zum Ungeheuer wird.
Und wenn du lange in einen Abgrund blickst, blickt der Abgrund auch in dich hinein.
moonlight
Posts: 567
Joined: Wed Oct 26, 2005 7:46 pm

Post by moonlight »

ryoko_no_usagi wrote:Um, what new nids? :)
Ups sorry, i saw sceNandProtect and i thought it was a new nid. I guess you meant sceNandSetWriteProtect.
User avatar
ryoko_no_usagi
Posts: 65
Joined: Tue Nov 29, 2005 4:47 pm

Post by ryoko_no_usagi »

Heh, that's funny! In my reversed source I accidentally called it sceNandWriteProtect, and above I mistakenly typed sceNandProtect! Sloppy me...I hope I didn't make more serious mistakes...
Post Reply