mirror of
https://github.com/fail0verflow/mini.git
synced 2024-11-24 20:26:55 +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) {
|
for (i = 0x40; i < 0x140; i++, ptr += 2048) {
|
||||||
nand_read_page(i, ptr, ecc);
|
nand_read_page(i, ptr, ecc);
|
||||||
nand_wait();
|
nand_wait();
|
||||||
|
if(nand_correct(i, ptr, ecc) < 0) {
|
||||||
|
gecko_printf("boot2 is corrupted, cannot load!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hdr->len != sizeof(struct wadheader))
|
if (hdr->len != sizeof(struct wadheader))
|
||||||
@ -75,6 +79,7 @@ void boot2_init() {
|
|||||||
|
|
||||||
memcpy(boot2, cntptr, datalen);
|
memcpy(boot2, cntptr, datalen);
|
||||||
boot2_initialized = 1;
|
boot2_initialized = 1;
|
||||||
|
gecko_printf("boot2 loaded\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 match[] = {
|
static u32 match[] = {
|
||||||
|
1
main.c
1
main.c
@ -178,7 +178,6 @@ void *_main(void *base)
|
|||||||
gecko_puts("NAND initialized.\n");
|
gecko_puts("NAND initialized.\n");
|
||||||
|
|
||||||
boot2_init();
|
boot2_init();
|
||||||
gecko_puts("Boot2 loaded to memory.\n");
|
|
||||||
|
|
||||||
gecko_puts("Initializing IPC...\n");
|
gecko_puts("Initializing IPC...\n");
|
||||||
ipc_initialize();
|
ipc_initialize();
|
||||||
|
42
nand.c
42
nand.c
@ -200,6 +200,48 @@ void nand_initialize(void)
|
|||||||
irq_enable(IRQ_NAND);
|
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)
|
void nand_ipc(volatile ipc_request *req)
|
||||||
{
|
{
|
||||||
if (ipc_code != 0 || ipc_tag != 0) {
|
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);
|
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_initialize();
|
||||||
|
|
||||||
void nand_ipc(volatile ipc_request *req);
|
void nand_ipc(volatile ipc_request *req);
|
||||||
|
Loading…
Reference in New Issue
Block a user