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; }
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; } }