From 243cadb4cd03e190c37df4fe35bf8a491c9b32e6 Mon Sep 17 00:00:00 2001 From: mtabachenko Date: Fri, 9 Aug 2013 23:08:13 +0000 Subject: [PATCH] JIT: - fix OP_MCR (fix a delay boot M&L:PiT and SPP on x64 PGO build); --- desmume/src/NDSSystem.cpp | 4 +- desmume/src/cp15.cpp | 207 ++++---------------------------------- desmume/src/cp15.h | 51 ++++------ 3 files changed, 44 insertions(+), 218 deletions(-) diff --git a/desmume/src/NDSSystem.cpp b/desmume/src/NDSSystem.cpp index 7e18e3dde..583606ea5 100644 --- a/desmume/src/NDSSystem.cpp +++ b/desmume/src/NDSSystem.cpp @@ -2513,7 +2513,9 @@ void NDS_Reset() // only ARM9 have co-processor reconstruct(&cp15); - cp15.reset(&NDS_ARM9); + MMU.ARM9_RW_MODE = BIT7(cp15.ctrl); + NDS_ARM9.intVector = 0xFFFF0000 * (BIT13(cp15.ctrl)); + NDS_ARM9.LDTBit = !BIT15(cp15.ctrl); //TBit resetUserInput(); diff --git a/desmume/src/cp15.cpp b/desmume/src/cp15.cpp index c047b9769..fb130b60f 100644 --- a/desmume/src/cp15.cpp +++ b/desmume/src/cp15.cpp @@ -1,6 +1,6 @@ /* Copyright (C) 2006 yopyop - Copyright (C) 2006-2011 DeSmuME team + Copyright (C) 2006-2013 DeSmuME team This file is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -24,67 +24,11 @@ armcp15_t cp15; -bool armcp15_t::reset(armcpu_t * c) -{ - //printf("CP15 Reset\n"); - cpu = c; - IDCode = 0x41059461; - cacheType = 0x0F0D2112; - TCMSize = 0x00140180; - ctrl = 0x00012078; - DCConfig = 0x0; - ICConfig = 0x0; - writeBuffCtrl = 0x0; - und = 0x0; - DaccessPerm = 0x22222222; - IaccessPerm = 0x22222222; - protectBaseSize0 = 0x0; - protectBaseSize1 = 0x0; - protectBaseSize2 = 0x0; - protectBaseSize3 = 0x0; - protectBaseSize4 = 0x0; - protectBaseSize5 = 0x0; - protectBaseSize6 = 0x0; - protectBaseSize7 = 0x0; - cacheOp = 0x0; - DcacheLock = 0x0; - IcacheLock = 0x0; - ITCMRegion = 0x0C; - DTCMRegion = 0x0080000A; - processID = 0; - - MMU.ARM9_RW_MODE = BIT7(ctrl); - cpu->intVector = 0xFFFF0000 * (BIT13(ctrl)); - cpu->LDTBit = !BIT15(ctrl); //TBit - - /* preset calculated regionmasks */ - for (u8 i=0;i<8;i++) { - regionWriteMask_USR[i] = 0 ; - regionWriteMask_SYS[i] = 0 ; - regionReadMask_USR[i] = 0 ; - regionReadMask_SYS[i] = 0 ; - regionExecuteMask_USR[i] = 0 ; - regionExecuteMask_SYS[i] = 0 ; - regionWriteSet_USR[i] = 0 ; - regionWriteSet_SYS[i] = 0 ; - regionReadSet_USR[i] = 0 ; - regionReadSet_SYS[i] = 0 ; - regionExecuteSet_USR[i] = 0 ; - regionExecuteSet_SYS[i] = 0 ; - } ; - - return true; -} - -#define ACCESSTYPE(val,n) (((val) >> (4*n)) & 0x0F) -#define SIZEIDENTIFIER(val) ((((val) >> 1) & 0x1F)) -#define SIZEBINARY(val) (1 << (SIZEIDENTIFIER(val)+1)) -#define MASKFROMREG(val) (~((SIZEBINARY(val)-1) | 0x3F)) -#define SETFROMREG(val) ((val) & MASKFROMREG(val)) +#define CP15_ACCESSTYPE(val, n) (((val) >> (4*n)) & 0x0F) /* sets the precalculated regions to mask,set for the affected accesstypes */ -void armcp15_t::setSingleRegionAccess(u32 dAccess,u32 iAccess,unsigned char num, u32 mask,u32 set) { +void armcp15_t::setSingleRegionAccess(u8 num, u32 mask, u32 set) { - switch (ACCESSTYPE(dAccess,num)) { + switch (CP15_ACCESSTYPE(DaccessPerm, num)) { case 4: /* UNP */ case 7: /* UNP */ case 8: /* UNP */ @@ -156,7 +100,7 @@ void armcp15_t::setSingleRegionAccess(u32 dAccess,u32 iAccess,unsigned char num, regionReadSet_SYS[num] = set ; break ; } - switch (ACCESSTYPE(iAccess,num)) { + switch (CP15_ACCESSTYPE(IaccessPerm, num)) { case 4: /* UNP */ case 7: /* UNP */ case 8: /* UNP */ @@ -195,16 +139,16 @@ void armcp15_t::maskPrecalc() { #define precalc(num) { \ u32 mask = 0, set = 0xFFFFFFFF ; /* (x & 0) == 0xFF..FF is allways false (disabled) */ \ - if (BIT_N(protectBaseSize##num,0)) /* if region is enabled */ \ + if (BIT_N(protectBaseSize[num],0)) /* if region is enabled */ \ { /* reason for this define: naming includes var */ \ - mask = MASKFROMREG(protectBaseSize##num) ; \ - set = SETFROMREG(protectBaseSize##num) ; \ - if (SIZEIDENTIFIER(protectBaseSize##num)==0x1F) \ + mask = CP15_MASKFROMREG(protectBaseSize[num]) ; \ + set = CP15_SETFROMREG(protectBaseSize[num]) ; \ + if (CP15_SIZEIDENTIFIER(protectBaseSize[num])==0x1F) \ { /* for the 4GB region, u32 suffers wraparound */ \ mask = 0 ; set = 0 ; /* (x & 0) == 0 is allways true (enabled) */ \ } \ } \ - setSingleRegionAccess(DaccessPerm,IaccessPerm,num,mask,set) ; \ + setSingleRegionAccess(num, mask, set) ; \ } precalc(0) ; precalc(1) ; @@ -267,12 +211,7 @@ BOOL armcp15_t::store(u8 CRd, u8 adr) BOOL armcp15_t::moveCP2ARM(u32 * R, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2) { - if (!cpu) - { - printf("ERROR: cp15 don\'t allocated\n"); - return FALSE; - } - if(cpu->CPSR.bits.mode == USR) return FALSE; + if(NDS_ARM9.CPSR.bits.mode == USR) return FALSE; switch(CRn) { @@ -345,34 +284,10 @@ BOOL armcp15_t::moveCP2ARM(u32 * R, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2) case 6: if((opcode1==0) && (opcode2==0)) { - switch(CRm) + if (CRm < 8) { - case 0: - *R = protectBaseSize0; + *R = protectBaseSize[CRm]; return TRUE; - case 1: - *R = protectBaseSize1; - return TRUE; - case 2: - *R = protectBaseSize2; - return TRUE; - case 3: - *R = protectBaseSize3; - return TRUE; - case 4: - *R = protectBaseSize4; - return TRUE; - case 5: - *R = protectBaseSize5; - return TRUE; - case 6: - *R = protectBaseSize6; - return TRUE; - case 7: - *R = protectBaseSize7; - return TRUE; - default: - return FALSE; } } return FALSE; @@ -416,12 +331,7 @@ BOOL armcp15_t::moveCP2ARM(u32 * R, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2) BOOL armcp15_t::moveARM2CP(u32 val, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2) { - if (!cpu) - { - printf("ERROR: cp15 don\'t allocated\n"); - return FALSE; - } - if(cpu->CPSR.bits.mode == USR) return FALSE; + if(NDS_ARM9.CPSR.bits.mode == USR) return FALSE; switch(CRn) { @@ -433,8 +343,8 @@ BOOL armcp15_t::moveARM2CP(u32 val, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2) ctrl = (val & 0x000FF085) | 0x00000078; MMU.ARM9_RW_MODE = BIT7(val); //zero 31-jan-2010: change from 0x0FFF0000 to 0xFFFF0000 per gbatek - cpu->intVector = 0xFFFF0000 * (BIT13(val)); - cpu->LDTBit = !BIT15(val); //TBit + NDS_ARM9.intVector = 0xFFFF0000 * (BIT13(val)); + NDS_ARM9.LDTBit = !BIT15(val); //TBit //LOG("CP15: ARMtoCP ctrl %08X (val %08X)\n", ctrl, val); return TRUE; } @@ -484,42 +394,11 @@ BOOL armcp15_t::moveARM2CP(u32 val, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2) case 6: if((opcode1==0) && (opcode2==0)) { - switch(CRm) + if (CRm < 8) { - case 0: - protectBaseSize0 = val; + protectBaseSize[CRm] = val; maskPrecalc(); return TRUE; - case 1: - protectBaseSize1 = val; - maskPrecalc(); - return TRUE; - case 2: - protectBaseSize2 = val; - maskPrecalc(); - return TRUE; - case 3: - protectBaseSize3 = val; - maskPrecalc(); - return TRUE; - case 4: - protectBaseSize4 = val; - maskPrecalc(); - return TRUE; - case 5: - protectBaseSize5 = val; - maskPrecalc(); - return TRUE; - case 6: - protectBaseSize6 = val; - maskPrecalc(); - return TRUE; - case 7: - protectBaseSize7 = val; - maskPrecalc(); - return TRUE; - default: - return FALSE; } } return FALSE; @@ -527,8 +406,8 @@ BOOL armcp15_t::moveARM2CP(u32 val, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2) if((CRm==0)&&(opcode1==0)&&((opcode2==4))) { //CP15wait4IRQ; - cpu->waitIRQ = TRUE; - cpu->halt_IE_and_IF = TRUE; + NDS_ARM9.waitIRQ = TRUE; + NDS_ARM9.halt_IE_and_IF = TRUE; //IME set deliberately omitted: only SWI sets IME to 1 return TRUE; } @@ -585,14 +464,7 @@ void armcp15_t::saveone(EMUFILE* os) write32le(und,os); write32le(DaccessPerm,os); write32le(IaccessPerm,os); - write32le(protectBaseSize0,os); - write32le(protectBaseSize1,os); - write32le(protectBaseSize2,os); - write32le(protectBaseSize3,os); - write32le(protectBaseSize4,os); - write32le(protectBaseSize5,os); - write32le(protectBaseSize6,os); - write32le(protectBaseSize7,os); + for(int i=0;i<8;i++) write32le(protectBaseSize[i],os); write32le(cacheOp,os); write32le(DcacheLock,os); write32le(IcacheLock,os); @@ -628,14 +500,7 @@ bool armcp15_t::loadone(EMUFILE* is) if(!read32le(&und,is)) return false; if(!read32le(&DaccessPerm,is)) return false; if(!read32le(&IaccessPerm,is)) return false; - if(!read32le(&protectBaseSize0,is)) return false; - if(!read32le(&protectBaseSize1,is)) return false; - if(!read32le(&protectBaseSize2,is)) return false; - if(!read32le(&protectBaseSize3,is)) return false; - if(!read32le(&protectBaseSize4,is)) return false; - if(!read32le(&protectBaseSize5,is)) return false; - if(!read32le(&protectBaseSize6,is)) return false; - if(!read32le(&protectBaseSize7,is)) return false; + for(int i=0;i<8;i++) if(!read32le(&protectBaseSize[i],is)) return false; if(!read32le(&cacheOp,is)) return false; if(!read32le(&DcacheLock,is)) return false; if(!read32le(&IcacheLock,is)) return false; @@ -660,31 +525,3 @@ bool armcp15_t::loadone(EMUFILE* is) return true; } - -/* precalculate region masks/sets from cp15 register ----- JIT */ -void maskPrecalc() -{ -#define precalc(num) { \ - u32 mask = 0, set = 0xFFFFFFFF ; /* (x & 0) == 0xFF..FF is allways false (disabled) */ \ - if (BIT_N(cp15.protectBaseSize##num,0)) /* if region is enabled */ \ - { /* reason for this define: naming includes var */ \ - mask = MASKFROMREG(cp15.protectBaseSize##num) ; \ - set = SETFROMREG(cp15.protectBaseSize##num) ; \ - if (SIZEIDENTIFIER(cp15.protectBaseSize##num)==0x1F) \ - { /* for the 4GB region, u32 suffers wraparound */ \ - mask = 0 ; set = 0 ; /* (x & 0) == 0 is allways true (enabled) */ \ -} \ -} \ - cp15.setSingleRegionAccess(cp15.DaccessPerm,cp15.IaccessPerm,num,mask,set) ; \ -} - precalc(0) ; - precalc(1) ; - precalc(2) ; - precalc(3) ; - precalc(4) ; - precalc(5) ; - precalc(6) ; - precalc(7) ; -#undef precalc -} - diff --git a/desmume/src/cp15.h b/desmume/src/cp15.h index 1dc7bc379..488850ce3 100644 --- a/desmume/src/cp15.h +++ b/desmume/src/cp15.h @@ -1,6 +1,6 @@ /* Copyright (C) 2006 yopyop - Copyright (C) 2006-2010 DeSmuME team + Copyright (C) 2006-2013 DeSmuME team This file is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -32,6 +32,11 @@ #define CP15_ACCESS_EXECUSR CP15_ACCESS_EXECUTE #define CP15_ACCESS_EXECSYS 5 +#define CP15_SIZEBINARY(val) (1 << (CP15_SIZEIDENTIFIER(val)+1)) +#define CP15_SIZEIDENTIFIER(val) ((((val) >> 1) & 0x1F)) +#define CP15_MASKFROMREG(val) (~((CP15_SIZEBINARY(val)-1) | 0x3F)) +#define CP15_SETFROMREG(val) ((val) & CP15_MASKFROMREG(val)) + struct armcp15_t { public: @@ -45,14 +50,7 @@ public: u32 und; u32 DaccessPerm; u32 IaccessPerm; - u32 protectBaseSize0; - u32 protectBaseSize1; - u32 protectBaseSize2; - u32 protectBaseSize3; - u32 protectBaseSize4; - u32 protectBaseSize5; - u32 protectBaseSize6; - u32 protectBaseSize7; + u32 protectBaseSize[8]; u32 cacheOp; u32 DcacheLock; u32 IcacheLock; @@ -77,41 +75,32 @@ public: u32 regionExecuteSet_USR[8] ; u32 regionExecuteSet_SYS[8] ; - armcpu_t *cpu; - - void setSingleRegionAccess(u32 dAccess,u32 iAccess,unsigned char num, u32 mask,u32 set); + void setSingleRegionAccess(u8 num, u32 mask, u32 set); void maskPrecalc(); public: - armcp15_t() : IDCode(0), - cacheType(0), - TCMSize(0), - ctrl(0), + armcp15_t() : IDCode(0x41059461), + cacheType(0x0F0D2112), + TCMSize(0x00140180), + ctrl(0x00012078), DCConfig(0), ICConfig(0), writeBuffCtrl(0), und(0), - DaccessPerm(0), - IaccessPerm(0), - protectBaseSize0(0), - protectBaseSize1(0), - protectBaseSize2(0), - protectBaseSize3(0), - protectBaseSize4(0), - protectBaseSize5(0), - protectBaseSize6(0), - protectBaseSize7(0), + DaccessPerm(0x22222222), + IaccessPerm(0x22222222), cacheOp(0), DcacheLock(0), IcacheLock(0), - ITCMRegion(0), - DTCMRegion(0), + ITCMRegion(0x0C), + DTCMRegion(0x0080000A), processID(0), RAM_TAG(0), testState(0), - cacheDbg(0), - cpu(NULL) + cacheDbg(0) { + //printf("CP15 Reset\n"); + memset(&protectBaseSize[0], 0, sizeof(protectBaseSize)); memset(®ionWriteMask_USR[0], 0, sizeof(regionWriteMask_USR)); memset(®ionWriteMask_SYS[0], 0, sizeof(regionWriteMask_SYS)); memset(®ionReadMask_USR[0], 0, sizeof(regionReadMask_USR)); @@ -125,7 +114,6 @@ public: memset(®ionExecuteSet_USR[0], 0, sizeof(regionExecuteSet_USR)); memset(®ionExecuteSet_SYS[0], 0, sizeof(regionExecuteSet_SYS)); } - bool reset(armcpu_t * c); BOOL dataProcess(u8 CRd, u8 CRn, u8 CRm, u8 opcode1, u8 opcode2); BOOL load(u8 CRd, u8 adr); BOOL store(u8 CRd, u8 adr); @@ -138,5 +126,4 @@ public: }; extern armcp15_t cp15; -void maskPrecalc(); #endif /* __CP15_H__*/