mirror of
https://github.com/fail0verflow/mini.git
synced 2024-11-28 06:04:19 +01:00
Add NAND ECC correction to miniios and use for boot2 loads
This commit is contained in:
parent
3310503c11
commit
d1f9fa8a3a
5
boot2.c
5
boot2.c
@ -42,6 +42,10 @@ void boot2_init() {
|
||||
for (i = 0x40; i < 0x140; i++, ptr += 2048) {
|
||||
nand_read_page(i, ptr, ecc);
|
||||
nand_wait();
|
||||
if(nand_correct(i, ptr, ecc) < 0) {
|
||||
gecko_printf("boot2 is corrupted, cannot load!\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (hdr->len != sizeof(struct wadheader))
|
||||
@ -75,6 +79,7 @@ void boot2_init() {
|
||||
|
||||
memcpy(boot2, cntptr, datalen);
|
||||
boot2_initialized = 1;
|
||||
gecko_printf("boot2 loaded\n");
|
||||
}
|
||||
|
||||
static u32 match[] = {
|
||||
|
1
main.c
1
main.c
@ -178,7 +178,6 @@ void *_main(void *base)
|
||||
gecko_puts("NAND initialized.\n");
|
||||
|
||||
boot2_init();
|
||||
gecko_puts("Boot2 loaded to memory.\n");
|
||||
|
||||
gecko_puts("Initializing IPC...\n");
|
||||
ipc_initialize();
|
||||
|
42
nand.c
42
nand.c
@ -200,6 +200,48 @@ void nand_initialize(void)
|
||||
irq_enable(IRQ_NAND);
|
||||
}
|
||||
|
||||
int nand_correct(u32 pageno, void *data, void *ecc)
|
||||
{
|
||||
u8 *dp = (u8*)data;
|
||||
u32 *ecc_read = (u32*)((u8*)ecc)+0x30;
|
||||
u32 *ecc_calc = (u32*)((u8*)ecc)+0x40;
|
||||
int i;
|
||||
int uncorrectable = 0;
|
||||
int corrected = 0;
|
||||
|
||||
for(i=0;i<4;i++) {
|
||||
u32 syndrome = *ecc_read ^ *ecc_calc; //calculate ECC syncrome
|
||||
if(syndrome) {
|
||||
if(!((syndrome-1)&syndrome)) {
|
||||
// single-bit error in ECC
|
||||
corrected++;
|
||||
} else {
|
||||
// byteswap and extract odd and even halves
|
||||
u16 even = (syndrome >> 24) | ((syndrome >> 8) & 0xf00);
|
||||
u16 odd = ((syndrome << 8) & 0xf00) | ((syndrome >> 8) & 0x0ff);
|
||||
if((even ^ odd) != 0xfff) {
|
||||
// oops, can't fix this one
|
||||
uncorrectable++;
|
||||
} else {
|
||||
// fix the bad bit
|
||||
dp[odd >> 3] ^= 1<<(odd&7);
|
||||
corrected++;
|
||||
}
|
||||
}
|
||||
}
|
||||
dp += 0x200;
|
||||
ecc_read++;
|
||||
ecc_calc++;
|
||||
}
|
||||
if(uncorrectable || corrected)
|
||||
gecko_printf("ECC stats for NAND page 0x%x: %d uncorrectable, %d corrected\n", uncorrectable, corrected);
|
||||
if(uncorrectable)
|
||||
return NAND_ECC_UNCORRECTABLE;
|
||||
if(corrected)
|
||||
return NAND_ECC_CORRECTED;
|
||||
return NAND_ECC_OK;
|
||||
}
|
||||
|
||||
void nand_ipc(volatile ipc_request *req)
|
||||
{
|
||||
if (ipc_code != 0 || ipc_tag != 0) {
|
||||
|
6
nand.h
6
nand.h
@ -17,6 +17,12 @@ void nand_wait(void);
|
||||
|
||||
void nand_read_cluster(u32 clusterno, void *data);
|
||||
|
||||
#define NAND_ECC_OK 0
|
||||
#define NAND_ECC_CORRECTED 1
|
||||
#define NAND_ECC_UNCORRECTABLE -1
|
||||
|
||||
int nand_correct(u32 pageno, void *data, void *ecc);
|
||||
|
||||
void nand_initialize();
|
||||
|
||||
void nand_ipc(volatile ipc_request *req);
|
||||
|
Loading…
Reference in New Issue
Block a user