/* * Make the table local in * linux-2.6.27.y/drivers/mtd/nand/nand_ecc.c */ void mkECCtbl(void) { unsigned char i; unsigned cp0, cp1, cp2, cp3, cp4, cp5; unsigned rp; cp0 = 0, cp1 = 0, cp2 = 0, cp3 = 0, cp4 = 0, cp5 = 0; rp = 0; /* * cp0 = bit6 ^ bit4 ^ bit2 ^ bit0; * cp1 = bit7 ^ bit5 ^ bit3 ^ bit1; * cp2 = bit5 ^ bit4 ^ bit1 ^ bit0; * cp3 = bit7 ^ bit6 ^ bit3 ^ bit2; * cp4 = bit3 ^ bit2 ^ bit1 ^ bit0; * cp5 = bit7 ^ bit6 ^ bit5 ^ bit4; * * rp = xor all bits; */ for (i = 0; i < 0xff; i++) { unsigned char xdata = 0; cp0 = BIT0(i) ^ BIT2(i) ^ BIT4(i) ^ BIT6(i); if (cp0) xdata |= 0x1; cp1 = BIT1(i) ^ BIT3(i) ^ BIT5(i) ^ BIT7(i); if (cp1) xdata |= 0x2; cp2 = BIT0(i) ^ BIT1(i) ^ BIT4(i) ^ BIT5(i); if (cp2) xdata |= 0x4; cp3 = BIT2(i) ^ BIT3(i) ^ BIT6(i) ^ BIT7(i); if (cp3) xdata |= 0x8; cp4 = BIT0(i) ^ BIT1(i) ^ BIT2(i) ^ BIT3(i); if (cp4) xdata |= 0x10; cp5 = BIT4(i) ^ BIT5(i) ^ BIT6(i) ^ BIT7(i); if (cp5) xdata |= 0x20; rp = BIT0(i) ^ BIT1(i) ^ BIT2(i) ^ BIT3(i) ^ BIT4(i) ^ BIT5(i) ^ BIT6(i) ^ BIT7(i); if (rp) xdata |= 0x40; ecc_tbl[i] = xdata; } }
static void calculate_ecc(const uint8_t *buf, uint8_t *ecc) { uint8_t p8, byte; int i; memset(ecc, 0, 3); for (i = 0; i < 256; i++) { byte = buf[i]; ecc[0] ^= (BIT0(byte) ^ BIT2(byte) ^ BIT4(byte) ^ BIT6(byte)) << 2; ecc[0] ^= (BIT1(byte) ^ BIT3(byte) ^ BIT5(byte) ^ BIT7(byte)) << 3; ecc[0] ^= (BIT0(byte) ^ BIT1(byte) ^ BIT4(byte) ^ BIT5(byte)) << 4; ecc[0] ^= (BIT2(byte) ^ BIT3(byte) ^ BIT6(byte) ^ BIT7(byte)) << 5; ecc[0] ^= (BIT0(byte) ^ BIT1(byte) ^ BIT2(byte) ^ BIT3(byte)) << 6; ecc[0] ^= (BIT4(byte) ^ BIT5(byte) ^ BIT6(byte) ^ BIT7(byte)) << 7; p8 = BIT0(byte) ^ BIT1(byte) ^ BIT2(byte) ^ BIT3(byte) ^ BIT4(byte) ^ BIT5(byte) ^ BIT6(byte) ^ BIT7(byte); if (p8) { ecc[2] ^= (0x1 << BIT0(i)); ecc[2] ^= (0x4 << BIT1(i)); ecc[2] ^= (0x10 << BIT2(i)); ecc[2] ^= (0x40 << BIT3(i)); ecc[1] ^= (0x1 << BIT4(i)); ecc[1] ^= (0x4 << BIT5(i)); ecc[1] ^= (0x10 << BIT6(i)); ecc[1] ^= (0x40 << BIT7(i)); } } ecc[0] = ~ecc[0]; ecc[1] = ~ecc[1]; ecc[2] = ~ecc[2]; ecc[0] |= 3; }
armcp15_t *armcp15_new(armcpu_t * c) { int i; armcp15_t *armcp15 = (armcp15_t*)malloc(sizeof(armcp15_t)); if(!armcp15) return NULL; armcp15->cpu = c; armcp15->IDCode = 0x41059461; armcp15->cacheType = 0x0F0D2112; armcp15->TCMSize = 0x00140180; armcp15->ctrl = 0x00012078; armcp15->DCConfig = 0x0; armcp15->ICConfig = 0x0; armcp15->writeBuffCtrl = 0x0; armcp15->und = 0x0; armcp15->DaccessPerm = 0x22222222; armcp15->IaccessPerm = 0x22222222; armcp15->protectBaseSize0 = 0x0; armcp15->protectBaseSize1 = 0x0; armcp15->protectBaseSize2 = 0x0; armcp15->protectBaseSize3 = 0x0; armcp15->protectBaseSize4 = 0x0; armcp15->protectBaseSize5 = 0x0; armcp15->protectBaseSize6 = 0x0; armcp15->protectBaseSize7 = 0x0; armcp15->cacheOp = 0x0; armcp15->DcacheLock = 0x0; armcp15->IcacheLock = 0x0; armcp15->ITCMRegion = 0x0C; armcp15->DTCMRegion = 0x0080000A; armcp15->processID = 0; MMU.ARM9_RW_MODE = BIT7(armcp15->ctrl); armcp15->cpu->intVector = 0xFFFF0000 * (BIT13(armcp15->ctrl)); armcp15->cpu->LDTBit = !BIT15(armcp15->ctrl); //TBit /* preset calculated regionmasks */ for (i=0;i<8;i++) { armcp15->regionWriteMask_USR[i] = 0 ; armcp15->regionWriteMask_SYS[i] = 0 ; armcp15->regionReadMask_USR[i] = 0 ; armcp15->regionReadMask_SYS[i] = 0 ; armcp15->regionExecuteMask_USR[i] = 0 ; armcp15->regionExecuteMask_SYS[i] = 0 ; armcp15->regionWriteSet_USR[i] = 0 ; armcp15->regionWriteSet_SYS[i] = 0 ; armcp15->regionReadSet_USR[i] = 0 ; armcp15->regionReadSet_SYS[i] = 0 ; armcp15->regionExecuteSet_USR[i] = 0 ; armcp15->regionExecuteSet_SYS[i] = 0 ; } ; return armcp15; }
static int correct_ecc(uint8_t *buf, uint8_t *calc_ecc, uint8_t *read_ecc) { uint8_t ecc0, ecc1, ecc2, onesnum, bit, byte; uint16_t addr = 0; ecc0 = calc_ecc[0] ^ read_ecc[0]; ecc1 = calc_ecc[1] ^ read_ecc[1]; ecc2 = calc_ecc[2] ^ read_ecc[2]; if (!ecc0 && !ecc1 && !ecc2) return (ECC_OK); addr = BIT3(ecc0) | (BIT5(ecc0) << 1) | (BIT7(ecc0) << 2); addr |= (BIT1(ecc2) << 3) | (BIT3(ecc2) << 4) | (BIT5(ecc2) << 5) | (BIT7(ecc2) << 6); addr |= (BIT1(ecc1) << 7) | (BIT3(ecc1) << 8) | (BIT5(ecc1) << 9) | (BIT7(ecc1) << 10); onesnum = 0; while (ecc0 || ecc1 || ecc2) { if (ecc0 & 1) onesnum++; if (ecc1 & 1) onesnum++; if (ecc2 & 1) onesnum++; ecc0 >>= 1; ecc1 >>= 1; ecc2 >>= 1; } if (onesnum == 11) { /* Correctable error */ bit = addr & 7; byte = addr >> 3; buf[byte] ^= (1 << bit); return (ECC_CORRECTABLE); } else if (onesnum == 1) {
BOOL armcp15_t::moveARM2CP(u32 val, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2) { if(NDS_ARM9.CPSR.bits.mode == USR) return FALSE; switch(CRn) { case 1: if((opcode1==0) && (opcode2==0) && (CRm==0)) { //On the NDS bit0,2,7,12..19 are R/W, Bit3..6 are always set, all other bits are always zero. ctrl = (val & 0x000FF085) | 0x00000078; MMU.ARM9_RW_MODE = BIT7(val); //zero 31-jan-2010: change from 0x0FFF0000 to 0xFFFF0000 per gbatek NDS_ARM9.intVector = 0xFFFF0000 * (BIT13(val)); NDS_ARM9.LDTBit = !BIT15(val); //TBit //LOG("CP15: ARMtoCP ctrl %08X (val %08X)\n", ctrl, val); return TRUE; } return FALSE; case 2: if((opcode1==0) && (CRm==0)) { switch(opcode2) { case 0: DCConfig = val; return TRUE; case 1: ICConfig = val; return TRUE; default: return FALSE; } } return FALSE; case 3: if((opcode1==0) && (opcode2==0) && (CRm==0)) { writeBuffCtrl = val; //LOG("CP15: ARMtoCP writeBuffer ctrl %08X\n", writeBuffCtrl); return TRUE; } return FALSE; case 5: if((opcode1==0) && (CRm==0)) { switch(opcode2) { case 2: DaccessPerm = val; maskPrecalc(); return TRUE; case 3: IaccessPerm = val; maskPrecalc(); return TRUE; default: return FALSE; } } return FALSE; case 6: if((opcode1==0) && (opcode2==0)) { if (CRm < 8) { protectBaseSize[CRm] = val; maskPrecalc(); return TRUE; } } return FALSE; case 7: if((CRm==0)&&(opcode1==0)&&((opcode2==4))) { //CP15wait4IRQ; NDS_ARM9.waitIRQ = TRUE; NDS_ARM9.halt_IE_and_IF = TRUE; //IME set deliberately omitted: only SWI sets IME to 1 return TRUE; } return FALSE; case 9: if((opcode1==0)) { switch(CRm) { case 0: switch(opcode2) { case 0: DcacheLock = val; return TRUE; case 1: IcacheLock = val; return TRUE; default: return FALSE; } case 1: switch(opcode2) { case 0: MMU.DTCMRegion = DTCMRegion = val & 0x0FFFF000; return TRUE; case 1: ITCMRegion = val; //ITCM base is not writeable! MMU.ITCMRegion = 0; return TRUE; default: return FALSE; } } } return FALSE; default: return FALSE; } }
BOOL armcp15_moveARM2CP(armcp15_t *armcp15, u32 val, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2) { if(armcp15->cpu->CPSR.bits.mode == USR) return FALSE; switch(CRn) { case 1: if((opcode1==0) && (opcode2==0) && (CRm==0)) { //On the NDS bit0,2,7,12..19 are R/W, Bit3..6 are always set, all other bits are always zero. armcp15->ctrl = (val & 0x000FF085) | 0x00000078; MMU.ARM9_RW_MODE = BIT7(val); //zero 31-jan-2010: change from 0x0FFF0000 to 0xFFFF0000 per gbatek armcp15->cpu->intVector = 0xFFFF0000 * (BIT13(val)); armcp15->cpu->LDTBit = !BIT15(val); //TBit //LOG("CP15: ARMtoCP ctrl %08X (val %08X)\n", armcp15->ctrl, val); return TRUE; } return FALSE; case 2: if((opcode1==0) && (CRm==0)) { switch(opcode2) { case 0: armcp15->DCConfig = val; return TRUE; case 1: armcp15->ICConfig = val; return TRUE; default: return FALSE; } } return FALSE; case 3: if((opcode1==0) && (opcode2==0) && (CRm==0)) { armcp15->writeBuffCtrl = val; //LOG("CP15: ARMtoCP writeBuffer ctrl %08X\n", armcp15->writeBuffCtrl); return TRUE; } return FALSE; case 5: if((opcode1==0) && (CRm==0)) { switch(opcode2) { case 2: armcp15->DaccessPerm = val; armcp15_maskPrecalc(armcp15); return TRUE; case 3: armcp15->IaccessPerm = val; armcp15_maskPrecalc(armcp15); return TRUE; default: return FALSE; } } return FALSE; case 6: if((opcode1==0) && (opcode2==0)) { switch(CRm) { case 0: armcp15->protectBaseSize0 = val; armcp15_maskPrecalc(armcp15) ; return TRUE; case 1: armcp15->protectBaseSize1 = val; armcp15_maskPrecalc(armcp15) ; return TRUE; case 2: armcp15->protectBaseSize2 = val; armcp15_maskPrecalc(armcp15) ; return TRUE; case 3: armcp15->protectBaseSize3 = val; armcp15_maskPrecalc(armcp15) ; return TRUE; case 4: armcp15->protectBaseSize4 = val; armcp15_maskPrecalc(armcp15) ; return TRUE; case 5: armcp15->protectBaseSize5 = val; armcp15_maskPrecalc(armcp15) ; return TRUE; case 6: armcp15->protectBaseSize6 = val; armcp15_maskPrecalc(armcp15) ; return TRUE; case 7: armcp15->protectBaseSize7 = val; armcp15_maskPrecalc(armcp15) ; return TRUE; default: return FALSE; } } return FALSE; case 7: if((CRm==0)&&(opcode1==0)&&((opcode2==4))) { CP15wait4IRQ(armcp15->cpu); return TRUE; } return FALSE; case 9: if((opcode1==0)) { switch(CRm) { case 0: switch(opcode2) { case 0: armcp15->DcacheLock = val; return TRUE; case 1: armcp15->IcacheLock = val; return TRUE; default: return FALSE; } case 1: switch(opcode2) { case 0: MMU.DTCMRegion = armcp15->DTCMRegion = val & 0x0FFFF000; return TRUE; case 1: armcp15->ITCMRegion = val; //ITCM base is not writeable! MMU.ITCMRegion = 0; return TRUE; default: return FALSE; } } } return FALSE; default: return FALSE; } }
BOOL armcp15_moveARM2CP(armcp15_t *armcp15, u32 val, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2) { if(armcp15->cpu->CPSR.bits.mode == USR) return FALSE; switch(CRn) { case 1 : if((opcode1==0) && (opcode2==0) && (CRm==0)) { armcp15->ctrl = val; armcp15->cpu->state->MMU->ARM9_RW_MODE = BIT7(val); armcp15->cpu->intVector = 0x0FFF0000 * (BIT13(val)); armcp15->cpu->LDTBit = !BIT15(val); //TBit /*if(BIT17(val)) { log::ajouter("outch !!!!!!!"); } if(BIT19(val)) { log::ajouter("outch !!!!!!!"); }*/ return TRUE; } return FALSE; case 2 : if((opcode1==0) && (CRm==0)) { switch(opcode2) { case 0 : armcp15->DCConfig = val; return TRUE; case 1 : armcp15->ICConfig = val; return TRUE; default : return FALSE; } } return FALSE; case 3 : if((opcode1==0) && (opcode2==0) && (CRm==0)) { armcp15->writeBuffCtrl = val; return TRUE; } return FALSE; if((opcode1==0) && (CRm==0)) { switch(opcode2) { case 2 : armcp15->DaccessPerm = val; armcp15_maskPrecalc(armcp15); return TRUE; case 3 : armcp15->IaccessPerm = val; armcp15_maskPrecalc(armcp15); return TRUE; default : return FALSE; } } return FALSE; case 6 : if((opcode1==0) && (opcode2==0)) { switch(CRm) { case 0 : armcp15->protectBaseSize0 = val; armcp15_maskPrecalc(armcp15) ; return TRUE; case 1 : armcp15->protectBaseSize1 = val; armcp15_maskPrecalc(armcp15) ; return TRUE; case 2 : armcp15->protectBaseSize2 = val; armcp15_maskPrecalc(armcp15) ; return TRUE; case 3 : armcp15->protectBaseSize3 = val; armcp15_maskPrecalc(armcp15) ; return TRUE; case 4 : armcp15->protectBaseSize4 = val; armcp15_maskPrecalc(armcp15) ; return TRUE; case 5 : armcp15->protectBaseSize5 = val; armcp15_maskPrecalc(armcp15) ; return TRUE; case 6 : armcp15->protectBaseSize6 = val; armcp15_maskPrecalc(armcp15) ; return TRUE; case 7 : armcp15->protectBaseSize7 = val; armcp15_maskPrecalc(armcp15) ; return TRUE; default : return FALSE; } } return FALSE; case 7 : if((CRm==0)&&(opcode1==0)&&((opcode2==4))) { CP15wait4IRQ(armcp15->cpu); return TRUE; } return FALSE; case 9 : if(opcode1==0) { switch(CRm) { case 0 : switch(opcode2) { case 0 : armcp15->DcacheLock = val; return TRUE; case 1 : armcp15->IcacheLock = val; return TRUE; default : return FALSE; } case 1 : switch(opcode2) { case 0 : armcp15->DTCMRegion = val; armcp15->cpu->state->MMU->DTCMRegion = val & 0x0FFFFFFC0; /*sprintf(logbuf, "%08X", val); log::ajouter(logbuf);*/ return TRUE; case 1 : armcp15->ITCMRegion = val; /* ITCM base is not writeable! */ armcp15->cpu->state->MMU->ITCMRegion = 0; return TRUE; default : return FALSE; } } } return FALSE; default : return FALSE; } }