| ... | ... |
@@ -24,7 +24,7 @@ armcp15_t cp15; |
| 24 | 24 |
|
| 25 | 25 |
bool armcp15_t::reset(armcpu_t *c) |
| 26 | 26 |
{
|
| 27 |
- //printf("CP15 Reset\n");
|
|
| 27 |
+ //fprintf(stderr, "CP15 Reset\n"); |
|
| 28 | 28 |
this->cpu = c; |
| 29 | 29 |
this->IDCode = 0x41059461; |
| 30 | 30 |
this->cacheType = 0x0F0D2112; |
| ... | ... |
@@ -225,7 +225,7 @@ bool armcp15_t::moveCP2ARM(uint32_t *R, uint8_t CRn, uint8_t CRm, uint8_t opcode |
| 225 | 225 |
{
|
| 226 | 226 |
if (!this->cpu) |
| 227 | 227 |
{
|
| 228 |
- printf("ERROR: cp15 don\'t allocated\n");
|
|
| 228 |
+ fprintf(stderr, "ERROR: cp15 don\'t allocated\n"); |
|
| 229 | 229 |
return false; |
| 230 | 230 |
} |
| 231 | 231 |
if (this->cpu->CPSR.bits.mode == USR) |
| ... | ... |
@@ -371,7 +371,7 @@ bool armcp15_t::moveARM2CP(uint32_t val, uint8_t CRn, uint8_t CRm, uint8_t opcod |
| 371 | 371 |
{
|
| 372 | 372 |
if (!this->cpu) |
| 373 | 373 |
{
|
| 374 |
- printf("ERROR: cp15 don\'t allocated\n");
|
|
| 374 |
+ fprintf(stderr, "ERROR: cp15 don\'t allocated\n"); |
|
| 375 | 375 |
return false; |
| 376 | 376 |
} |
| 377 | 377 |
if (this->cpu->CPSR.bits.mode == USR) |
* [2SF] Used more up-to-date asmjit, despite the ugly looking code.
| ... | ... |
@@ -274,7 +274,7 @@ bool armcp15_t::moveCP2ARM(uint32_t *R, uint8_t CRn, uint8_t CRm, uint8_t opcode |
| 274 | 274 |
} |
| 275 | 275 |
return false; |
| 276 | 276 |
case 3: |
| 277 |
- if (!opcode1 && ~opcode2 && !CRm) |
|
| 277 |
+ if (!opcode1 && ~static_cast<int8_t>(opcode2) && !CRm) |
|
| 278 | 278 |
{
|
| 279 | 279 |
*R = this->writeBuffCtrl; |
| 280 | 280 |
return true; |
| ... | ... |
@@ -384,7 +384,7 @@ bool armcp15_t::moveARM2CP(uint32_t val, uint8_t CRn, uint8_t CRm, uint8_t opcod |
| 384 | 384 |
{
|
| 385 | 385 |
// On the NDS bit0,2,7,12..19 are R/W, Bit3..6 are always set, all other bits are always zero. |
| 386 | 386 |
this->ctrl = (val & 0x000FF085) | 0x00000078; |
| 387 |
- MMU.ARM9_RW_MODE = static_cast<uint8_t>(BIT7(val)); |
|
| 387 |
+ MMU.ARM9_RW_MODE = BIT7(val); |
|
| 388 | 388 |
// zero 31-jan-2010: change from 0x0FFF0000 to 0xFFFF0000 per gbatek |
| 389 | 389 |
this->cpu->intVector = 0xFFFF0000 * BIT13(val); |
| 390 | 390 |
this->cpu->LDTBit = !BIT15(val); // TBit |
| ... | ... |
@@ -17,81 +17,75 @@ |
| 17 | 17 |
*/ |
| 18 | 18 |
|
| 19 | 19 |
#include <cstdlib> |
| 20 |
- |
|
| 21 | 20 |
#include "cp15.h" |
| 22 |
-//#include "debug.h" |
|
| 23 | 21 |
#include "MMU.h" |
| 24 | 22 |
|
| 25 |
-armcp15_t *armcp15_new(armcpu_t * c) |
|
| 26 |
-{
|
|
| 27 |
- int i; |
|
| 28 |
- armcp15_t *armcp15 = (armcp15_t*)malloc(sizeof(armcp15_t)); |
|
| 29 |
- if(!armcp15) return NULL; |
|
| 30 |
- |
|
| 23 |
+armcp15_t cp15; |
|
| 31 | 24 |
|
| 32 |
- armcp15->cpu = c; |
|
| 33 |
- armcp15->IDCode = 0x41059461; |
|
| 34 |
- armcp15->cacheType = 0x0F0D2112; |
|
| 35 |
- armcp15->TCMSize = 0x00140180; |
|
| 36 |
- armcp15->ctrl = 0x00012078; |
|
| 37 |
- armcp15->DCConfig = 0x0; |
|
| 38 |
- armcp15->ICConfig = 0x0; |
|
| 39 |
- armcp15->writeBuffCtrl = 0x0; |
|
| 40 |
- armcp15->und = 0x0; |
|
| 41 |
- armcp15->DaccessPerm = 0x22222222; |
|
| 42 |
- armcp15->IaccessPerm = 0x22222222; |
|
| 43 |
- armcp15->protectBaseSize0 = 0x0; |
|
| 44 |
- armcp15->protectBaseSize1 = 0x0; |
|
| 45 |
- armcp15->protectBaseSize2 = 0x0; |
|
| 46 |
- armcp15->protectBaseSize3 = 0x0; |
|
| 47 |
- armcp15->protectBaseSize4 = 0x0; |
|
| 48 |
- armcp15->protectBaseSize5 = 0x0; |
|
| 49 |
- armcp15->protectBaseSize6 = 0x0; |
|
| 50 |
- armcp15->protectBaseSize7 = 0x0; |
|
| 51 |
- armcp15->cacheOp = 0x0; |
|
| 52 |
- armcp15->DcacheLock = 0x0; |
|
| 53 |
- armcp15->IcacheLock = 0x0; |
|
| 54 |
- armcp15->ITCMRegion = 0x0C; |
|
| 55 |
- armcp15->DTCMRegion = 0x0080000A; |
|
| 56 |
- armcp15->processID = 0; |
|
| 25 |
+bool armcp15_t::reset(armcpu_t *c) |
|
| 26 |
+{
|
|
| 27 |
+ //printf("CP15 Reset\n");
|
|
| 28 |
+ this->cpu = c; |
|
| 29 |
+ this->IDCode = 0x41059461; |
|
| 30 |
+ this->cacheType = 0x0F0D2112; |
|
| 31 |
+ this->TCMSize = 0x00140180; |
|
| 32 |
+ this->ctrl = 0x00012078; |
|
| 33 |
+ this->DCConfig = 0x0; |
|
| 34 |
+ this->ICConfig = 0x0; |
|
| 35 |
+ this->writeBuffCtrl = 0x0; |
|
| 36 |
+ this->und = 0x0; |
|
| 37 |
+ this->DaccessPerm = 0x22222222; |
|
| 38 |
+ this->IaccessPerm = 0x22222222; |
|
| 39 |
+ this->protectBaseSize0 = 0x0; |
|
| 40 |
+ this->protectBaseSize1 = 0x0; |
|
| 41 |
+ this->protectBaseSize2 = 0x0; |
|
| 42 |
+ this->protectBaseSize3 = 0x0; |
|
| 43 |
+ this->protectBaseSize4 = 0x0; |
|
| 44 |
+ this->protectBaseSize5 = 0x0; |
|
| 45 |
+ this->protectBaseSize6 = 0x0; |
|
| 46 |
+ this->protectBaseSize7 = 0x0; |
|
| 47 |
+ this->cacheOp = 0x0; |
|
| 48 |
+ this->DcacheLock = 0x0; |
|
| 49 |
+ this->IcacheLock = 0x0; |
|
| 50 |
+ this->ITCMRegion = 0x0C; |
|
| 51 |
+ this->DTCMRegion = 0x0080000A; |
|
| 52 |
+ this->processID = 0; |
|
| 57 | 53 |
|
| 58 |
- MMU.ARM9_RW_MODE = static_cast<uint8_t>(BIT7(armcp15->ctrl)); |
|
| 59 |
- armcp15->cpu->intVector = 0xFFFF0000 * (BIT13(armcp15->ctrl)); |
|
| 60 |
- armcp15->cpu->LDTBit = !BIT15(armcp15->ctrl); //TBit |
|
| 54 |
+ MMU.ARM9_RW_MODE = BIT7(this->ctrl); |
|
| 55 |
+ this->cpu->intVector = 0xFFFF0000 * BIT13(this->ctrl); |
|
| 56 |
+ this->cpu->LDTBit = !BIT15(this->ctrl); // TBit |
|
| 61 | 57 |
|
| 62 | 58 |
/* preset calculated regionmasks */ |
| 63 |
- for (i=0;i<8;i++) {
|
|
| 64 |
- armcp15->regionWriteMask_USR[i] = 0 ; |
|
| 65 |
- armcp15->regionWriteMask_SYS[i] = 0 ; |
|
| 66 |
- armcp15->regionReadMask_USR[i] = 0 ; |
|
| 67 |
- armcp15->regionReadMask_SYS[i] = 0 ; |
|
| 68 |
- armcp15->regionExecuteMask_USR[i] = 0 ; |
|
| 69 |
- armcp15->regionExecuteMask_SYS[i] = 0 ; |
|
| 70 |
- armcp15->regionWriteSet_USR[i] = 0 ; |
|
| 71 |
- armcp15->regionWriteSet_SYS[i] = 0 ; |
|
| 72 |
- armcp15->regionReadSet_USR[i] = 0 ; |
|
| 73 |
- armcp15->regionReadSet_SYS[i] = 0 ; |
|
| 74 |
- armcp15->regionExecuteSet_USR[i] = 0 ; |
|
| 75 |
- armcp15->regionExecuteSet_SYS[i] = 0 ; |
|
| 76 |
- } ; |
|
| 59 |
+ for (uint8_t i = 0; i < 8; ++i) |
|
| 60 |
+ {
|
|
| 61 |
+ this->regionWriteMask_USR[i] = 0; |
|
| 62 |
+ this->regionWriteMask_SYS[i] = 0; |
|
| 63 |
+ this->regionReadMask_USR[i] = 0; |
|
| 64 |
+ this->regionReadMask_SYS[i] = 0; |
|
| 65 |
+ this->regionExecuteMask_USR[i] = 0; |
|
| 66 |
+ this->regionExecuteMask_SYS[i] = 0; |
|
| 67 |
+ this->regionWriteSet_USR[i] = 0; |
|
| 68 |
+ this->regionWriteSet_SYS[i] = 0; |
|
| 69 |
+ this->regionReadSet_USR[i] = 0; |
|
| 70 |
+ this->regionReadSet_SYS[i] = 0; |
|
| 71 |
+ this->regionExecuteSet_USR[i] = 0; |
|
| 72 |
+ this->regionExecuteSet_SYS[i] = 0; |
|
| 73 |
+ } |
|
| 77 | 74 |
|
| 78 |
- return armcp15; |
|
| 75 |
+ return true; |
|
| 79 | 76 |
} |
| 80 | 77 |
|
| 81 |
-//#define ACCESSTYPE(val,n) (((val) >> (4*n)) & 0x0F) |
|
| 82 | 78 |
static inline uint32_t ACCESSTYPE(uint32_t val, unsigned char n) { return (val >> (4 * n)) & 0x0F; }
|
| 83 |
-//#define SIZEIDENTIFIER(val) ((((val) >> 1) & 0x1F)) |
|
| 84 | 79 |
static inline uint32_t SIZEIDENTIFIER(uint32_t val) { return (val >> 1) & 0x1F; }
|
| 85 |
-//#define SIZEBINARY(val) (1 << (SIZEIDENTIFIER(val)+1)) |
|
| 86 | 80 |
static inline uint32_t SIZEBINARY(uint32_t val) { return 1 << (SIZEIDENTIFIER(val) + 1); }
|
| 87 |
-//#define MASKFROMREG(val) (~((SIZEBINARY(val)-1) | 0x3F)) |
|
| 88 | 81 |
static inline uint32_t MASKFROMREG(uint32_t val) { return ~((SIZEBINARY(val) - 1) | 0x3F); }
|
| 89 |
-//#define SETFROMREG(val) ((val) & MASKFROMREG(val)) |
|
| 90 | 82 |
static inline uint32_t SETFROMREG(uint32_t val) { return val & MASKFROMREG(val); }
|
| 91 | 83 |
/* sets the precalculated regions to mask,set for the affected accesstypes */ |
| 92 |
-static void armcp15_setSingleRegionAccess(armcp15_t *armcp15,uint32_t dAccess,uint32_t iAccess,unsigned char num, uint32_t mask,uint32_t set) {
|
|
| 84 |
+void armcp15_t::setSingleRegionAccess(uint32_t dAccess, uint32_t iAccess, unsigned char num, uint32_t mask, uint32_t set) |
|
| 85 |
+{
|
|
| 93 | 86 |
|
| 94 |
- switch (ACCESSTYPE(dAccess,num)) {
|
|
| 87 |
+ switch (ACCESSTYPE(dAccess, num)) |
|
| 88 |
+ {
|
|
| 95 | 89 |
case 4: /* UNP */ |
| 96 | 90 |
case 7: /* UNP */ |
| 97 | 91 |
case 8: /* UNP */ |
| ... | ... |
@@ -103,67 +97,67 @@ static void armcp15_setSingleRegionAccess(armcp15_t *armcp15,uint32_t dAccess,ui |
| 103 | 97 |
case 14: /* UNP */ |
| 104 | 98 |
case 15: /* UNP */ |
| 105 | 99 |
case 0: /* no access at all */ |
| 106 |
- armcp15->regionWriteMask_USR[num] = 0 ; |
|
| 107 |
- armcp15->regionWriteSet_USR[num] = 0xFFFFFFFF ; |
|
| 108 |
- armcp15->regionReadMask_USR[num] = 0 ; |
|
| 109 |
- armcp15->regionReadSet_USR[num] = 0xFFFFFFFF ; |
|
| 110 |
- armcp15->regionWriteMask_SYS[num] = 0 ; |
|
| 111 |
- armcp15->regionWriteSet_SYS[num] = 0xFFFFFFFF ; |
|
| 112 |
- armcp15->regionReadMask_SYS[num] = 0 ; |
|
| 113 |
- armcp15->regionReadSet_SYS[num] = 0xFFFFFFFF ; |
|
| 114 |
- break ; |
|
| 100 |
+ this->regionWriteMask_USR[num] = 0; |
|
| 101 |
+ this->regionWriteSet_USR[num] = 0xFFFFFFFF; |
|
| 102 |
+ this->regionReadMask_USR[num] = 0; |
|
| 103 |
+ this->regionReadSet_USR[num] = 0xFFFFFFFF; |
|
| 104 |
+ this->regionWriteMask_SYS[num] = 0; |
|
| 105 |
+ this->regionWriteSet_SYS[num] = 0xFFFFFFFF; |
|
| 106 |
+ this->regionReadMask_SYS[num] = 0; |
|
| 107 |
+ this->regionReadSet_SYS[num] = 0xFFFFFFFF; |
|
| 108 |
+ break; |
|
| 115 | 109 |
case 1: /* no access at USR, all to sys */ |
| 116 |
- armcp15->regionWriteMask_USR[num] = 0 ; |
|
| 117 |
- armcp15->regionWriteSet_USR[num] = 0xFFFFFFFF ; |
|
| 118 |
- armcp15->regionReadMask_USR[num] = 0 ; |
|
| 119 |
- armcp15->regionReadSet_USR[num] = 0xFFFFFFFF ; |
|
| 120 |
- armcp15->regionWriteMask_SYS[num] = mask ; |
|
| 121 |
- armcp15->regionWriteSet_SYS[num] = set ; |
|
| 122 |
- armcp15->regionReadMask_SYS[num] = mask ; |
|
| 123 |
- armcp15->regionReadSet_SYS[num] = set ; |
|
| 124 |
- break ; |
|
| 110 |
+ this->regionWriteMask_USR[num] = 0; |
|
| 111 |
+ this->regionWriteSet_USR[num] = 0xFFFFFFFF; |
|
| 112 |
+ this->regionReadMask_USR[num] = 0; |
|
| 113 |
+ this->regionReadSet_USR[num] = 0xFFFFFFFF; |
|
| 114 |
+ this->regionWriteMask_SYS[num] = mask; |
|
| 115 |
+ this->regionWriteSet_SYS[num] = set; |
|
| 116 |
+ this->regionReadMask_SYS[num] = mask; |
|
| 117 |
+ this->regionReadSet_SYS[num] = set; |
|
| 118 |
+ break; |
|
| 125 | 119 |
case 2: /* read at USR, all to sys */ |
| 126 |
- armcp15->regionWriteMask_USR[num] = 0 ; |
|
| 127 |
- armcp15->regionWriteSet_USR[num] = 0xFFFFFFFF ; |
|
| 128 |
- armcp15->regionReadMask_USR[num] = mask ; |
|
| 129 |
- armcp15->regionReadSet_USR[num] = set ; |
|
| 130 |
- armcp15->regionWriteMask_SYS[num] = mask ; |
|
| 131 |
- armcp15->regionWriteSet_SYS[num] = set ; |
|
| 132 |
- armcp15->regionReadMask_SYS[num] = mask ; |
|
| 133 |
- armcp15->regionReadSet_SYS[num] = set ; |
|
| 134 |
- break ; |
|
| 120 |
+ this->regionWriteMask_USR[num] = 0; |
|
| 121 |
+ this->regionWriteSet_USR[num] = 0xFFFFFFFF; |
|
| 122 |
+ this->regionReadMask_USR[num] = mask; |
|
| 123 |
+ this->regionReadSet_USR[num] = set; |
|
| 124 |
+ this->regionWriteMask_SYS[num] = mask; |
|
| 125 |
+ this->regionWriteSet_SYS[num] = set; |
|
| 126 |
+ this->regionReadMask_SYS[num] = mask; |
|
| 127 |
+ this->regionReadSet_SYS[num] = set; |
|
| 128 |
+ break; |
|
| 135 | 129 |
case 3: /* all to USR, all to sys */ |
| 136 |
- armcp15->regionWriteMask_USR[num] = mask ; |
|
| 137 |
- armcp15->regionWriteSet_USR[num] = set ; |
|
| 138 |
- armcp15->regionReadMask_USR[num] = mask ; |
|
| 139 |
- armcp15->regionReadSet_USR[num] = set ; |
|
| 140 |
- armcp15->regionWriteMask_SYS[num] = mask ; |
|
| 141 |
- armcp15->regionWriteSet_SYS[num] = set ; |
|
| 142 |
- armcp15->regionReadMask_SYS[num] = mask ; |
|
| 143 |
- armcp15->regionReadSet_SYS[num] = set ; |
|
| 144 |
- break ; |
|
| 130 |
+ this->regionWriteMask_USR[num] = mask; |
|
| 131 |
+ this->regionWriteSet_USR[num] = set; |
|
| 132 |
+ this->regionReadMask_USR[num] = mask; |
|
| 133 |
+ this->regionReadSet_USR[num] = set; |
|
| 134 |
+ this->regionWriteMask_SYS[num] = mask; |
|
| 135 |
+ this->regionWriteSet_SYS[num] = set; |
|
| 136 |
+ this->regionReadMask_SYS[num] = mask; |
|
| 137 |
+ this->regionReadSet_SYS[num] = set; |
|
| 138 |
+ break; |
|
| 145 | 139 |
case 5: /* no access at USR, read to sys */ |
| 146 |
- armcp15->regionWriteMask_USR[num] = 0 ; |
|
| 147 |
- armcp15->regionWriteSet_USR[num] = 0xFFFFFFFF ; |
|
| 148 |
- armcp15->regionReadMask_USR[num] = 0 ; |
|
| 149 |
- armcp15->regionReadSet_USR[num] = 0xFFFFFFFF ; |
|
| 150 |
- armcp15->regionWriteMask_SYS[num] = 0 ; |
|
| 151 |
- armcp15->regionWriteSet_SYS[num] = 0xFFFFFFFF ; |
|
| 152 |
- armcp15->regionReadMask_SYS[num] = mask ; |
|
| 153 |
- armcp15->regionReadSet_SYS[num] = set ; |
|
| 154 |
- break ; |
|
| 140 |
+ this->regionWriteMask_USR[num] = 0; |
|
| 141 |
+ this->regionWriteSet_USR[num] = 0xFFFFFFFF; |
|
| 142 |
+ this->regionReadMask_USR[num] = 0; |
|
| 143 |
+ this->regionReadSet_USR[num] = 0xFFFFFFFF; |
|
| 144 |
+ this->regionWriteMask_SYS[num] = 0; |
|
| 145 |
+ this->regionWriteSet_SYS[num] = 0xFFFFFFFF; |
|
| 146 |
+ this->regionReadMask_SYS[num] = mask; |
|
| 147 |
+ this->regionReadSet_SYS[num] = set; |
|
| 148 |
+ break; |
|
| 155 | 149 |
case 6: /* read at USR, read to sys */ |
| 156 |
- armcp15->regionWriteMask_USR[num] = 0 ; |
|
| 157 |
- armcp15->regionWriteSet_USR[num] = 0xFFFFFFFF ; |
|
| 158 |
- armcp15->regionReadMask_USR[num] = mask ; |
|
| 159 |
- armcp15->regionReadSet_USR[num] = set ; |
|
| 160 |
- armcp15->regionWriteMask_SYS[num] = 0 ; |
|
| 161 |
- armcp15->regionWriteSet_SYS[num] = 0xFFFFFFFF ; |
|
| 162 |
- armcp15->regionReadMask_SYS[num] = mask ; |
|
| 163 |
- armcp15->regionReadSet_SYS[num] = set ; |
|
| 164 |
- break ; |
|
| 150 |
+ this->regionWriteMask_USR[num] = 0; |
|
| 151 |
+ this->regionWriteSet_USR[num] = 0xFFFFFFFF; |
|
| 152 |
+ this->regionReadMask_USR[num] = mask; |
|
| 153 |
+ this->regionReadSet_USR[num] = set; |
|
| 154 |
+ this->regionWriteMask_SYS[num] = 0; |
|
| 155 |
+ this->regionWriteSet_SYS[num] = 0xFFFFFFFF; |
|
| 156 |
+ this->regionReadMask_SYS[num] = mask; |
|
| 157 |
+ this->regionReadSet_SYS[num] = set; |
|
| 165 | 158 |
} |
| 166 |
- switch (ACCESSTYPE(iAccess,num)) {
|
|
| 159 |
+ switch (ACCESSTYPE(iAccess, num)) |
|
| 160 |
+ {
|
|
| 167 | 161 |
case 4: /* UNP */ |
| 168 | 162 |
case 7: /* UNP */ |
| 169 | 163 |
case 8: /* UNP */ |
| ... | ... |
@@ -175,400 +169,386 @@ static void armcp15_setSingleRegionAccess(armcp15_t *armcp15,uint32_t dAccess,ui |
| 175 | 169 |
case 14: /* UNP */ |
| 176 | 170 |
case 15: /* UNP */ |
| 177 | 171 |
case 0: /* no access at all */ |
| 178 |
- armcp15->regionExecuteMask_USR[num] = 0 ; |
|
| 179 |
- armcp15->regionExecuteSet_USR[num] = 0xFFFFFFFF ; |
|
| 180 |
- armcp15->regionExecuteMask_SYS[num] = 0 ; |
|
| 181 |
- armcp15->regionExecuteSet_SYS[num] = 0xFFFFFFFF ; |
|
| 182 |
- break ; |
|
| 172 |
+ this->regionExecuteMask_USR[num] = 0; |
|
| 173 |
+ this->regionExecuteSet_USR[num] = 0xFFFFFFFF; |
|
| 174 |
+ this->regionExecuteMask_SYS[num] = 0; |
|
| 175 |
+ this->regionExecuteSet_SYS[num] = 0xFFFFFFFF; |
|
| 176 |
+ break; |
|
| 183 | 177 |
case 1: |
| 184 |
- armcp15->regionExecuteMask_USR[num] = 0 ; |
|
| 185 |
- armcp15->regionExecuteSet_USR[num] = 0xFFFFFFFF ; |
|
| 186 |
- armcp15->regionExecuteMask_SYS[num] = mask ; |
|
| 187 |
- armcp15->regionExecuteSet_SYS[num] = set ; |
|
| 188 |
- break ; |
|
| 178 |
+ this->regionExecuteMask_USR[num] = 0; |
|
| 179 |
+ this->regionExecuteSet_USR[num] = 0xFFFFFFFF; |
|
| 180 |
+ this->regionExecuteMask_SYS[num] = mask; |
|
| 181 |
+ this->regionExecuteSet_SYS[num] = set; |
|
| 182 |
+ break; |
|
| 189 | 183 |
case 2: |
| 190 | 184 |
case 3: |
| 191 | 185 |
case 6: |
| 192 |
- armcp15->regionExecuteMask_USR[num] = mask ; |
|
| 193 |
- armcp15->regionExecuteSet_USR[num] = set ; |
|
| 194 |
- armcp15->regionExecuteMask_SYS[num] = mask ; |
|
| 195 |
- armcp15->regionExecuteSet_SYS[num] = set ; |
|
| 196 |
- break ; |
|
| 186 |
+ this->regionExecuteMask_USR[num] = mask; |
|
| 187 |
+ this->regionExecuteSet_USR[num] = set; |
|
| 188 |
+ this->regionExecuteMask_SYS[num] = mask; |
|
| 189 |
+ this->regionExecuteSet_SYS[num] = set; |
|
| 197 | 190 |
} |
| 198 | 191 |
} |
| 199 | 192 |
|
| 200 | 193 |
/* precalculate region masks/sets from cp15 register */ |
| 201 |
-static void armcp15_maskPrecalc(armcp15_t *armcp15) |
|
| 194 |
+void armcp15_t::maskPrecalc() |
|
| 202 | 195 |
{
|
| 203 |
-#define precalc(num) { \
|
|
| 204 |
- uint32_t mask = 0, set = 0xFFFFFFFF ; /* (x & 0) == 0xFF..FF is allways false (disabled) */ \ |
|
| 205 |
- if (BIT_N(armcp15->protectBaseSize##num,0)) /* if region is enabled */ \ |
|
| 206 |
- { /* reason for this define: naming includes var */ \
|
|
| 207 |
- mask = MASKFROMREG(armcp15->protectBaseSize##num) ; \ |
|
| 208 |
- set = SETFROMREG(armcp15->protectBaseSize##num) ; \ |
|
| 209 |
- if (SIZEIDENTIFIER(armcp15->protectBaseSize##num)==0x1F) \ |
|
| 210 |
- { /* for the 4GB region, uint32_t suffers wraparound */ \
|
|
| 211 |
- mask = 0 ; set = 0 ; /* (x & 0) == 0 is allways true (enabled) */ \ |
|
| 212 |
-} \ |
|
| 213 |
-} \ |
|
| 214 |
- armcp15_setSingleRegionAccess(armcp15,armcp15->DaccessPerm,armcp15->IaccessPerm,num,mask,set) ; \ |
|
| 196 |
+#define precalc(num) \ |
|
| 197 |
+{ \
|
|
| 198 |
+ uint32_t mask = 0, set = 0xFFFFFFFF; /* (x & 0) == 0xFF..FF is allways false (disabled) */ \ |
|
| 199 |
+ if (BIT_N(this->protectBaseSize##num, 0)) /* if region is enabled */ \ |
|
| 200 |
+ { \
|
|
| 201 |
+ /* reason for this define: naming includes var */ \ |
|
| 202 |
+ mask = MASKFROMREG(this->protectBaseSize##num); \ |
|
| 203 |
+ set = SETFROMREG(this->protectBaseSize##num); \ |
|
| 204 |
+ if (SIZEIDENTIFIER(this->protectBaseSize##num) == 0x1F) \ |
|
| 205 |
+ { \
|
|
| 206 |
+ /* for the 4GB region, u32 suffers wraparound */ \ |
|
| 207 |
+ mask = 0; \ |
|
| 208 |
+ set = 0; /* (x & 0) == 0 is allways true (enabled) */ \ |
|
| 209 |
+ } \ |
|
| 210 |
+ } \ |
|
| 211 |
+ this->setSingleRegionAccess(this->DaccessPerm, this->IaccessPerm, num, mask, set); \ |
|
| 215 | 212 |
} |
| 216 |
- precalc(0) ; |
|
| 217 |
- precalc(1) ; |
|
| 218 |
- precalc(2) ; |
|
| 219 |
- precalc(3) ; |
|
| 220 |
- precalc(4) ; |
|
| 221 |
- precalc(5) ; |
|
| 222 |
- precalc(6) ; |
|
| 223 |
- precalc(7) ; |
|
| 213 |
+ precalc(0); |
|
| 214 |
+ precalc(1); |
|
| 215 |
+ precalc(2); |
|
| 216 |
+ precalc(3); |
|
| 217 |
+ precalc(4); |
|
| 218 |
+ precalc(5); |
|
| 219 |
+ precalc(6); |
|
| 220 |
+ precalc(7); |
|
| 221 |
+#undef precalc |
|
| 224 | 222 |
} |
| 225 | 223 |
|
| 226 |
-/*bool armcp15_isAccessAllowed(armcp15_t *armcp15,uint32_t address,uint32_t access) |
|
| 227 |
-{
|
|
| 228 |
- int i ; |
|
| 229 |
- if (!(armcp15->ctrl & 1)) return true ;*/ /* protection checking is not enabled */ |
|
| 230 |
- /*for (i=0;i<8;i++) {
|
|
| 231 |
- switch (access) {
|
|
| 232 |
- case CP15_ACCESS_WRITEUSR: |
|
| 233 |
- if ((address & armcp15->regionWriteMask_USR[i]) == armcp15->regionWriteSet_USR[i]) return true ; |
|
| 234 |
- break ; |
|
| 235 |
- case CP15_ACCESS_WRITESYS: |
|
| 236 |
- if ((address & armcp15->regionWriteMask_SYS[i]) == armcp15->regionWriteSet_SYS[i]) return true ; |
|
| 237 |
- break ; |
|
| 238 |
- case CP15_ACCESS_READUSR: |
|
| 239 |
- if ((address & armcp15->regionReadMask_USR[i]) == armcp15->regionReadSet_USR[i]) return true ; |
|
| 240 |
- break ; |
|
| 241 |
- case CP15_ACCESS_READSYS: |
|
| 242 |
- if ((address & armcp15->regionReadMask_SYS[i]) == armcp15->regionReadSet_SYS[i]) return true ; |
|
| 243 |
- break ; |
|
| 244 |
- case CP15_ACCESS_EXECUSR: |
|
| 245 |
- if ((address & armcp15->regionExecuteMask_USR[i]) == armcp15->regionExecuteSet_USR[i]) return true ; |
|
| 246 |
- break ; |
|
| 247 |
- case CP15_ACCESS_EXECSYS: |
|
| 248 |
- if ((address & armcp15->regionExecuteMask_SYS[i]) == armcp15->regionExecuteSet_SYS[i]) return true ; |
|
| 249 |
- break ; |
|
| 250 |
- } |
|
| 251 |
- }*/ |
|
| 252 |
- /* when protections are enabled, but no region allows access, deny access */ |
|
| 253 |
- /*return false ; |
|
| 254 |
-}*/ |
|
| 255 |
- |
|
| 256 |
-/*bool armcp15_dataProcess(armcp15_t *, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t) |
|
| 257 |
-{
|
|
| 258 |
- //LOG("Unsupported CP15 operation : DataProcess\n");
|
|
| 259 |
- return false; |
|
| 260 |
-}*/ |
|
| 261 |
- |
|
| 262 |
-/*bool armcp15_load(armcp15_t *, uint8_t, uint8_t) |
|
| 224 |
+bool armcp15_t::moveCP2ARM(uint32_t *R, uint8_t CRn, uint8_t CRm, uint8_t opcode1, uint8_t opcode2) |
|
| 263 | 225 |
{
|
| 264 |
- //LOG("Unsupported CP15 operation : Load\n");
|
|
| 265 |
- return false; |
|
| 266 |
-}*/ |
|
| 267 |
- |
|
| 268 |
-/*bool armcp15_store(armcp15_t *, uint8_t, uint8_t) |
|
| 269 |
-{
|
|
| 270 |
- //LOG("Unsupported CP15 operation : Store\n");
|
|
| 271 |
- return false; |
|
| 272 |
-}*/ |
|
| 273 |
- |
|
| 274 |
-bool armcp15_moveCP2ARM(armcp15_t *armcp15, uint32_t * R, uint8_t CRn, uint8_t CRm, uint8_t opcode1, uint8_t opcode2) |
|
| 275 |
-{
|
|
| 276 |
- if(armcp15->cpu->CPSR.bits.mode == USR) return false; |
|
| 277 |
- |
|
| 278 |
- switch(CRn) |
|
| 226 |
+ if (!this->cpu) |
|
| 279 | 227 |
{
|
| 280 |
- case 0: |
|
| 281 |
- if((opcode1 == 0)&&(CRm==0)) |
|
| 282 |
- {
|
|
| 283 |
- switch(opcode2) |
|
| 284 |
- {
|
|
| 285 |
- case 1: |
|
| 286 |
- *R = armcp15->cacheType; |
|
| 287 |
- return true; |
|
| 288 |
- case 2: |
|
| 289 |
- *R = armcp15->TCMSize; |
|
| 290 |
- return true; |
|
| 291 |
- default: |
|
| 292 |
- *R = armcp15->IDCode; |
|
| 293 |
- return true; |
|
| 294 |
- } |
|
| 295 |
- } |
|
| 228 |
+ printf("ERROR: cp15 don\'t allocated\n");
|
|
| 296 | 229 |
return false; |
| 297 |
- case 1: |
|
| 298 |
- if((opcode1==0) && (opcode2==0) && (CRm==0)) |
|
| 299 |
- {
|
|
| 300 |
- *R = armcp15->ctrl; |
|
| 301 |
- //LOG("CP15: CPtoARM ctrl %08X\n", armcp15->ctrl);
|
|
| 302 |
- return true; |
|
| 303 |
- } |
|
| 230 |
+ } |
|
| 231 |
+ if (this->cpu->CPSR.bits.mode == USR) |
|
| 304 | 232 |
return false; |
| 305 | 233 |
|
| 306 |
- case 2: |
|
| 307 |
- if((opcode1==0) && (CRm==0)) |
|
| 308 |
- {
|
|
| 309 |
- switch(opcode2) |
|
| 234 |
+ switch (CRn) |
|
| 235 |
+ {
|
|
| 236 |
+ case 0: |
|
| 237 |
+ if (!opcode1 && !CRm) |
|
| 310 | 238 |
{
|
| 311 |
- case 0: |
|
| 312 |
- *R = armcp15->DCConfig; |
|
| 313 |
- return true; |
|
| 314 |
- case 1: |
|
| 315 |
- *R = armcp15->ICConfig; |
|
| 316 |
- return true; |
|
| 317 |
- default: |
|
| 318 |
- return false; |
|
| 239 |
+ switch (opcode2) |
|
| 240 |
+ {
|
|
| 241 |
+ case 1: |
|
| 242 |
+ *R = this->cacheType; |
|
| 243 |
+ return true; |
|
| 244 |
+ case 2: |
|
| 245 |
+ *R = this->TCMSize; |
|
| 246 |
+ return true; |
|
| 247 |
+ default: |
|
| 248 |
+ *R = this->IDCode; |
|
| 249 |
+ return true; |
|
| 250 |
+ } |
|
| 319 | 251 |
} |
| 320 |
- } |
|
| 321 |
- return false; |
|
| 322 |
- case 3: |
|
| 323 |
- if((opcode1==0) && (opcode2==0) && (CRm==0)) |
|
| 324 |
- {
|
|
| 325 |
- *R = armcp15->writeBuffCtrl; |
|
| 326 |
- //LOG("CP15: CPtoARM writeBuffer ctrl %08X\n", armcp15->writeBuffCtrl);
|
|
| 327 |
- return true; |
|
| 328 |
- } |
|
| 329 |
- return false; |
|
| 330 |
- case 5: |
|
| 331 |
- if((opcode1==0) && (CRm==0)) |
|
| 332 |
- {
|
|
| 333 |
- switch(opcode2) |
|
| 252 |
+ return false; |
|
| 253 |
+ case 1: |
|
| 254 |
+ if (!opcode1 && !opcode2 && !CRm) |
|
| 334 | 255 |
{
|
| 335 |
- case 2: |
|
| 336 |
- *R = armcp15->DaccessPerm; |
|
| 337 |
- return true; |
|
| 338 |
- case 3: |
|
| 339 |
- *R = armcp15->IaccessPerm; |
|
| 256 |
+ *R = this->ctrl; |
|
| 340 | 257 |
return true; |
| 341 |
- default: |
|
| 342 |
- return false; |
|
| 343 | 258 |
} |
| 344 |
- } |
|
| 345 |
- return false; |
|
| 346 |
- case 6: |
|
| 347 |
- if((opcode1==0) && (opcode2==0)) |
|
| 348 |
- {
|
|
| 349 |
- switch(CRm) |
|
| 259 |
+ return false; |
|
| 260 |
+ case 2: |
|
| 261 |
+ if (!opcode1 && !CRm) |
|
| 350 | 262 |
{
|
| 351 |
- case 0: |
|
| 352 |
- *R = armcp15->protectBaseSize0; |
|
| 353 |
- return true; |
|
| 354 |
- case 1: |
|
| 355 |
- *R = armcp15->protectBaseSize1; |
|
| 356 |
- return true; |
|
| 357 |
- case 2: |
|
| 358 |
- *R = armcp15->protectBaseSize2; |
|
| 359 |
- return true; |
|
| 360 |
- case 3: |
|
| 361 |
- *R = armcp15->protectBaseSize3; |
|
| 362 |
- return true; |
|
| 363 |
- case 4: |
|
| 364 |
- *R = armcp15->protectBaseSize4; |
|
| 365 |
- return true; |
|
| 366 |
- case 5: |
|
| 367 |
- *R = armcp15->protectBaseSize5; |
|
| 368 |
- return true; |
|
| 369 |
- case 6: |
|
| 370 |
- *R = armcp15->protectBaseSize6; |
|
| 371 |
- return true; |
|
| 372 |
- case 7: |
|
| 373 |
- *R = armcp15->protectBaseSize7; |
|
| 263 |
+ switch (opcode2) |
|
| 264 |
+ {
|
|
| 265 |
+ case 0: |
|
| 266 |
+ *R = this->DCConfig; |
|
| 267 |
+ return true; |
|
| 268 |
+ case 1: |
|
| 269 |
+ *R = this->ICConfig; |
|
| 270 |
+ return true; |
|
| 271 |
+ default: |
|
| 272 |
+ return false; |
|
| 273 |
+ } |
|
| 274 |
+ } |
|
| 275 |
+ return false; |
|
| 276 |
+ case 3: |
|
| 277 |
+ if (!opcode1 && ~opcode2 && !CRm) |
|
| 278 |
+ {
|
|
| 279 |
+ *R = this->writeBuffCtrl; |
|
| 374 | 280 |
return true; |
| 375 |
- default: |
|
| 376 |
- return false; |
|
| 377 | 281 |
} |
| 378 |
- } |
|
| 379 |
- return false; |
|
| 380 |
- case 9: |
|
| 381 |
- if((opcode1==0)) |
|
| 382 |
- {
|
|
| 383 |
- switch(CRm) |
|
| 282 |
+ return false; |
|
| 283 |
+ case 5: |
|
| 284 |
+ if (!opcode1 && !CRm) |
|
| 285 |
+ {
|
|
| 286 |
+ switch (opcode2) |
|
| 287 |
+ {
|
|
| 288 |
+ case 2: |
|
| 289 |
+ *R = this->DaccessPerm; |
|
| 290 |
+ return true; |
|
| 291 |
+ case 3: |
|
| 292 |
+ *R = this->IaccessPerm; |
|
| 293 |
+ return true; |
|
| 294 |
+ default: |
|
| 295 |
+ return false; |
|
| 296 |
+ } |
|
| 297 |
+ } |
|
| 298 |
+ return false; |
|
| 299 |
+ case 6: |
|
| 300 |
+ if (!opcode1 && !opcode2) |
|
| 384 | 301 |
{
|
| 385 |
- case 0: |
|
| 386 |
- switch(opcode2) |
|
| 302 |
+ switch (CRm) |
|
| 387 | 303 |
{
|
| 388 |
- case 0: |
|
| 389 |
- *R = armcp15->DcacheLock; |
|
| 390 |
- return true; |
|
| 391 |
- case 1: |
|
| 392 |
- *R = armcp15->IcacheLock; |
|
| 393 |
- return true; |
|
| 394 |
- default: |
|
| 395 |
- return false; |
|
| 304 |
+ case 0: |
|
| 305 |
+ *R = this->protectBaseSize0; |
|
| 306 |
+ return true; |
|
| 307 |
+ case 1: |
|
| 308 |
+ *R = this->protectBaseSize1; |
|
| 309 |
+ return true; |
|
| 310 |
+ case 2: |
|
| 311 |
+ *R = this->protectBaseSize2; |
|
| 312 |
+ return true; |
|
| 313 |
+ case 3: |
|
| 314 |
+ *R = this->protectBaseSize3; |
|
| 315 |
+ return true; |
|
| 316 |
+ case 4: |
|
| 317 |
+ *R = this->protectBaseSize4; |
|
| 318 |
+ return true; |
|
| 319 |
+ case 5: |
|
| 320 |
+ *R = this->protectBaseSize5; |
|
| 321 |
+ return true; |
|
| 322 |
+ case 6: |
|
| 323 |
+ *R = this->protectBaseSize6; |
|
| 324 |
+ return true; |
|
| 325 |
+ case 7: |
|
| 326 |
+ *R = this->protectBaseSize7; |
|
| 327 |
+ return true; |
|
| 328 |
+ default: |
|
| 329 |
+ return false; |
|
| 396 | 330 |
} |
| 397 |
- case 1: |
|
| 398 |
- switch(opcode2) |
|
| 331 |
+ } |
|
| 332 |
+ return false; |
|
| 333 |
+ case 9: |
|
| 334 |
+ if (!opcode1) |
|
| 335 |
+ {
|
|
| 336 |
+ switch (CRm) |
|
| 399 | 337 |
{
|
| 400 |
- case 0: |
|
| 401 |
- *R = armcp15->DTCMRegion; |
|
| 402 |
- return true; |
|
| 403 |
- case 1: |
|
| 404 |
- *R = armcp15->ITCMRegion; |
|
| 405 |
- return true; |
|
| 406 |
- default: |
|
| 407 |
- return false; |
|
| 338 |
+ case 0: |
|
| 339 |
+ switch (opcode2) |
|
| 340 |
+ {
|
|
| 341 |
+ case 0: |
|
| 342 |
+ *R = this->DcacheLock; |
|
| 343 |
+ return true; |
|
| 344 |
+ case 1: |
|
| 345 |
+ *R = this->IcacheLock; |
|
| 346 |
+ return true; |
|
| 347 |
+ default: |
|
| 348 |
+ return false; |
|
| 349 |
+ } |
|
| 350 |
+ case 1: |
|
| 351 |
+ switch (opcode2) |
|
| 352 |
+ {
|
|
| 353 |
+ case 0: |
|
| 354 |
+ *R = this->DTCMRegion; |
|
| 355 |
+ return true; |
|
| 356 |
+ case 1: |
|
| 357 |
+ *R = this->ITCMRegion; |
|
| 358 |
+ return true; |
|
| 359 |
+ default: |
|
| 360 |
+ return false; |
|
| 361 |
+ } |
|
| 408 | 362 |
} |
| 409 | 363 |
} |
| 410 |
- } |
|
| 411 |
- return false; |
|
| 412 |
- default: |
|
| 413 |
- //LOG("Unsupported CP15 operation : MRC\n");
|
|
| 414 |
- return false; |
|
| 364 |
+ return false; |
|
| 365 |
+ default: |
|
| 366 |
+ return false; |
|
| 415 | 367 |
} |
| 416 | 368 |
} |
| 417 | 369 |
|
| 418 |
-static uint32_t CP15wait4IRQ(armcpu_t *cpu) |
|
| 370 |
+bool armcp15_t::moveARM2CP(uint32_t val, uint8_t CRn, uint8_t CRm, uint8_t opcode1, uint8_t opcode2) |
|
| 419 | 371 |
{
|
| 420 |
- cpu->waitIRQ = true; |
|
| 421 |
- cpu->halt_IE_and_IF = true; |
|
| 422 |
- //IME set deliberately omitted: only SWI sets IME to 1 |
|
| 423 |
- return 1; |
|
| 424 |
-} |
|
| 425 |
- |
|
| 426 |
-bool armcp15_moveARM2CP(armcp15_t *armcp15, uint32_t val, uint8_t CRn, uint8_t CRm, uint8_t opcode1, uint8_t opcode2) |
|
| 427 |
-{
|
|
| 428 |
- if(armcp15->cpu->CPSR.bits.mode == USR) return false; |
|
| 429 |
- |
|
| 430 |
- switch(CRn) |
|
| 372 |
+ if (!this->cpu) |
|
| 431 | 373 |
{
|
| 432 |
- case 1: |
|
| 433 |
- if((opcode1==0) && (opcode2==0) && (CRm==0)) |
|
| 434 |
- {
|
|
| 435 |
- |
|
| 436 |
- //On the NDS bit0,2,7,12..19 are R/W, Bit3..6 are always set, all other bits are always zero. |
|
| 437 |
- armcp15->ctrl = (val & 0x000FF085) | 0x00000078; |
|
| 438 |
- MMU.ARM9_RW_MODE = static_cast<uint8_t>(BIT7(val)); |
|
| 439 |
- //zero 31-jan-2010: change from 0x0FFF0000 to 0xFFFF0000 per gbatek |
|
| 440 |
- armcp15->cpu->intVector = 0xFFFF0000 * (BIT13(val)); |
|
| 441 |
- armcp15->cpu->LDTBit = !BIT15(val); //TBit |
|
| 442 |
- //LOG("CP15: ARMtoCP ctrl %08X (val %08X)\n", armcp15->ctrl, val);
|
|
| 443 |
- return true; |
|
| 444 |
- } |
|
| 374 |
+ printf("ERROR: cp15 don\'t allocated\n");
|
|
| 375 |
+ return false; |
|
| 376 |
+ } |
|
| 377 |
+ if (this->cpu->CPSR.bits.mode == USR) |
|
| 445 | 378 |
return false; |
| 446 |
- case 2: |
|
| 447 |
- if((opcode1==0) && (CRm==0)) |
|
| 448 |
- {
|
|
| 449 |
- switch(opcode2) |
|
| 379 |
+ |
|
| 380 |
+ switch (CRn) |
|
| 381 |
+ {
|
|
| 382 |
+ case 1: |
|
| 383 |
+ if (!opcode1 && !opcode2 && !CRm) |
|
| 450 | 384 |
{
|
| 451 |
- case 0: |
|
| 452 |
- armcp15->DCConfig = val; |
|
| 453 |
- return true; |
|
| 454 |
- case 1: |
|
| 455 |
- armcp15->ICConfig = val; |
|
| 385 |
+ // On the NDS bit0,2,7,12..19 are R/W, Bit3..6 are always set, all other bits are always zero. |
|
| 386 |
+ this->ctrl = (val & 0x000FF085) | 0x00000078; |
|
| 387 |
+ MMU.ARM9_RW_MODE = static_cast<uint8_t>(BIT7(val)); |
|
| 388 |
+ // zero 31-jan-2010: change from 0x0FFF0000 to 0xFFFF0000 per gbatek |
|
| 389 |
+ this->cpu->intVector = 0xFFFF0000 * BIT13(val); |
|
| 390 |
+ this->cpu->LDTBit = !BIT15(val); // TBit |
|
| 456 | 391 |
return true; |
| 457 |
- default: |
|
| 458 |
- return false; |
|
| 459 | 392 |
} |
| 460 |
- } |
|
| 461 |
- return false; |
|
| 462 |
- case 3: |
|
| 463 |
- if((opcode1==0) && (opcode2==0) && (CRm==0)) |
|
| 464 |
- {
|
|
| 465 |
- armcp15->writeBuffCtrl = val; |
|
| 466 |
- //LOG("CP15: ARMtoCP writeBuffer ctrl %08X\n", armcp15->writeBuffCtrl);
|
|
| 467 |
- return true; |
|
| 468 |
- } |
|
| 469 |
- return false; |
|
| 470 |
- case 5: |
|
| 471 |
- if((opcode1==0) && (CRm==0)) |
|
| 472 |
- {
|
|
| 473 |
- switch(opcode2) |
|
| 393 |
+ return false; |
|
| 394 |
+ case 2: |
|
| 395 |
+ if (!opcode1 && !CRm) |
|
| 474 | 396 |
{
|
| 475 |
- case 2: |
|
| 476 |
- armcp15->DaccessPerm = val; |
|
| 477 |
- armcp15_maskPrecalc(armcp15); |
|
| 478 |
- return true; |
|
| 479 |
- case 3: |
|
| 480 |
- armcp15->IaccessPerm = val; |
|
| 481 |
- armcp15_maskPrecalc(armcp15); |
|
| 482 |
- return true; |
|
| 483 |
- default: |
|
| 484 |
- return false; |
|
| 397 |
+ switch (opcode2) |
|
| 398 |
+ {
|
|
| 399 |
+ case 0: |
|
| 400 |
+ this->DCConfig = val; |
|
| 401 |
+ return true; |
|
| 402 |
+ case 1: |
|
| 403 |
+ this->ICConfig = val; |
|
| 404 |
+ return true; |
|
| 405 |
+ default: |
|
| 406 |
+ return false; |
|
| 407 |
+ } |
|
| 485 | 408 |
} |
| 486 |
- } |
|
| 487 |
- return false; |
|
| 488 |
- case 6: |
|
| 489 |
- if((opcode1==0) && (opcode2==0)) |
|
| 490 |
- {
|
|
| 491 |
- switch(CRm) |
|
| 409 |
+ return false; |
|
| 410 |
+ case 3: |
|
| 411 |
+ if (!opcode1 && !opcode2 && !CRm) |
|
| 492 | 412 |
{
|
| 493 |
- case 0: |
|
| 494 |
- armcp15->protectBaseSize0 = val; |
|
| 495 |
- armcp15_maskPrecalc(armcp15) ; |
|
| 413 |
+ this->writeBuffCtrl = val; |
|
| 496 | 414 |
return true; |
| 497 |
- case 1: |
|
| 498 |
- armcp15->protectBaseSize1 = val; |
|
| 499 |
- armcp15_maskPrecalc(armcp15) ; |
|
| 500 |
- return true; |
|
| 501 |
- case 2: |
|
| 502 |
- armcp15->protectBaseSize2 = val; |
|
| 503 |
- armcp15_maskPrecalc(armcp15) ; |
|
| 504 |
- return true; |
|
| 505 |
- case 3: |
|
| 506 |
- armcp15->protectBaseSize3 = val; |
|
| 507 |
- armcp15_maskPrecalc(armcp15) ; |
|
| 508 |
- return true; |
|
| 509 |
- case 4: |
|
| 510 |
- armcp15->protectBaseSize4 = val; |
|
| 511 |
- armcp15_maskPrecalc(armcp15) ; |
|
| 512 |
- return true; |
|
| 513 |
- case 5: |
|
| 514 |
- armcp15->protectBaseSize5 = val; |
|
| 515 |
- armcp15_maskPrecalc(armcp15) ; |
|
| 516 |
- return true; |
|
| 517 |
- case 6: |
|
| 518 |
- armcp15->protectBaseSize6 = val; |
|
| 519 |
- armcp15_maskPrecalc(armcp15) ; |
|
| 520 |
- return true; |
|
| 521 |
- case 7: |
|
| 522 |
- armcp15->protectBaseSize7 = val; |
|
| 523 |
- armcp15_maskPrecalc(armcp15) ; |
|
| 524 |
- return true; |
|
| 525 |
- default: |
|
| 526 |
- return false; |
|
| 527 | 415 |
} |
| 528 |
- } |
|
| 529 |
- return false; |
|
| 530 |
- case 7: |
|
| 531 |
- if((CRm==0)&&(opcode1==0)&&((opcode2==4))) |
|
| 532 |
- {
|
|
| 533 |
- CP15wait4IRQ(armcp15->cpu); |
|
| 534 |
- return true; |
|
| 535 |
- } |
|
| 536 |
- return false; |
|
| 537 |
- case 9: |
|
| 538 |
- if((opcode1==0)) |
|
| 539 |
- {
|
|
| 540 |
- switch(CRm) |
|
| 416 |
+ return false; |
|
| 417 |
+ case 5: |
|
| 418 |
+ if (!opcode1 && !CRm) |
|
| 541 | 419 |
{
|
| 542 |
- case 0: |
|
| 543 |
- switch(opcode2) |
|
| 420 |
+ switch (opcode2) |
|
| 544 | 421 |
{
|
| 545 |
- case 0: |
|
| 546 |
- armcp15->DcacheLock = val; |
|
| 547 |
- return true; |
|
| 548 |
- case 1: |
|
| 549 |
- armcp15->IcacheLock = val; |
|
| 550 |
- return true; |
|
| 551 |
- default: |
|
| 552 |
- return false; |
|
| 422 |
+ case 2: |
|
| 423 |
+ this->DaccessPerm = val; |
|
| 424 |
+ this->maskPrecalc(); |
|
| 425 |
+ return true; |
|
| 426 |
+ case 3: |
|
| 427 |
+ this->IaccessPerm = val; |
|
| 428 |
+ this->maskPrecalc(); |
|
| 429 |
+ return true; |
|
| 430 |
+ default: |
|
| 431 |
+ return false; |
|
| 553 | 432 |
} |
| 554 |
- case 1: |
|
| 555 |
- switch(opcode2) |
|
| 433 |
+ } |
|
| 434 |
+ return false; |
|
| 435 |
+ case 6: |
|
| 436 |
+ if (!opcode1 && !opcode2) |
|
| 437 |
+ {
|
|
| 438 |
+ switch (CRm) |
|
| 556 | 439 |
{
|
| 557 |
- case 0: |
|
| 558 |
- MMU.DTCMRegion = armcp15->DTCMRegion = val & 0x0FFFF000; |
|
| 559 |
- return true; |
|
| 560 |
- case 1: |
|
| 561 |
- armcp15->ITCMRegion = val; |
|
| 562 |
- //ITCM base is not writeable! |
|
| 563 |
- MMU.ITCMRegion = 0; |
|
| 564 |
- return true; |
|
| 565 |
- default: |
|
| 566 |
- return false; |
|
| 440 |
+ case 0: |
|
| 441 |
+ this->protectBaseSize0 = val; |
|
| 442 |
+ this->maskPrecalc(); |
|
| 443 |
+ return true; |
|
| 444 |
+ case 1: |
|
| 445 |
+ this->protectBaseSize1 = val; |
|
| 446 |
+ this->maskPrecalc(); |
|
| 447 |
+ return true; |
|
| 448 |
+ case 2: |
|
| 449 |
+ this->protectBaseSize2 = val; |
|
| 450 |
+ this->maskPrecalc(); |
|
| 451 |
+ return true; |
|
| 452 |
+ case 3: |
|
| 453 |
+ this->protectBaseSize3 = val; |
|
| 454 |
+ this->maskPrecalc(); |
|
| 455 |
+ return true; |
|
| 456 |
+ case 4: |
|
| 457 |
+ this->protectBaseSize4 = val; |
|
| 458 |
+ this->maskPrecalc(); |
|
| 459 |
+ return true; |
|
| 460 |
+ case 5: |
|
| 461 |
+ this->protectBaseSize5 = val; |
|
| 462 |
+ this->maskPrecalc(); |
|
| 463 |
+ return true; |
|
| 464 |
+ case 6: |
|
| 465 |
+ this->protectBaseSize6 = val; |
|
| 466 |
+ this->maskPrecalc(); |
|
| 467 |
+ return true; |
|
| 468 |
+ case 7: |
|
| 469 |
+ this->protectBaseSize7 = val; |
|
| 470 |
+ this->maskPrecalc(); |
|
| 471 |
+ return true; |
|
| 472 |
+ default: |
|
| 473 |
+ return false; |
|
| 567 | 474 |
} |
| 568 | 475 |
} |
| 569 |
- } |
|
| 570 |
- return false; |
|
| 571 |
- default: |
|
| 572 |
- return false; |
|
| 476 |
+ return false; |
|
| 477 |
+ case 7: |
|
| 478 |
+ if (!CRm && !opcode1 && opcode2 == 4) |
|
| 479 |
+ {
|
|
| 480 |
+ this->cpu->waitIRQ = true; |
|
| 481 |
+ this->cpu->halt_IE_and_IF = true; |
|
| 482 |
+ // IME set deliberately omitted: only SWI sets IME to 1 |
|
| 483 |
+ return true; |
|
| 484 |
+ } |
|
| 485 |
+ return false; |
|
| 486 |
+ case 9: |
|
| 487 |
+ if (!opcode1) |
|
| 488 |
+ {
|
|
| 489 |
+ switch (CRm) |
|
| 490 |
+ {
|
|
| 491 |
+ case 0: |
|
| 492 |
+ switch (opcode2) |
|
| 493 |
+ {
|
|
| 494 |
+ case 0: |
|
| 495 |
+ this->DcacheLock = val; |
|
| 496 |
+ return true; |
|
| 497 |
+ case 1: |
|
| 498 |
+ this->IcacheLock = val; |
|
| 499 |
+ return true; |
|
| 500 |
+ default: |
|
| 501 |
+ return false; |
|
| 502 |
+ } |
|
| 503 |
+ case 1: |
|
| 504 |
+ switch (opcode2) |
|
| 505 |
+ {
|
|
| 506 |
+ case 0: |
|
| 507 |
+ MMU.DTCMRegion = this->DTCMRegion = val & 0x0FFFF000; |
|
| 508 |
+ return true; |
|
| 509 |
+ case 1: |
|
| 510 |
+ this->ITCMRegion = val; |
|
| 511 |
+ // ITCM base is not writeable! |
|
| 512 |
+ MMU.ITCMRegion = 0; |
|
| 513 |
+ return true; |
|
| 514 |
+ default: |
|
| 515 |
+ return false; |
|
| 516 |
+ } |
|
| 517 |
+ } |
|
| 518 |
+ } |
|
| 519 |
+ return false; |
|
| 520 |
+ default: |
|
| 521 |
+ return false; |
|
| 573 | 522 |
} |
| 574 | 523 |
} |
| 524 |
+ |
|
| 525 |
+/* precalculate region masks/sets from cp15 register ----- JIT */ |
|
| 526 |
+void maskPrecalc() |
|
| 527 |
+{
|
|
| 528 |
+#define precalc(num) \ |
|
| 529 |
+{ \
|
|
| 530 |
+ uint32_t mask = 0, set = 0xFFFFFFFF; /* (x & 0) == 0xFF..FF is allways false (disabled) */ \ |
|
| 531 |
+ if (BIT_N(cp15.protectBaseSize##num, 0)) /* if region is enabled */ \ |
|
| 532 |
+ { \
|
|
| 533 |
+ /* reason for this define: naming includes var */ \ |
|
| 534 |
+ mask = MASKFROMREG(cp15.protectBaseSize##num); \ |
|
| 535 |
+ set = SETFROMREG(cp15.protectBaseSize##num); \ |
|
| 536 |
+ if (SIZEIDENTIFIER(cp15.protectBaseSize##num) == 0x1F) \ |
|
| 537 |
+ { \
|
|
| 538 |
+ /* for the 4GB region, u32 suffers wraparound */ \ |
|
| 539 |
+ mask = 0; \ |
|
| 540 |
+ set = 0; /* (x & 0) == 0 is allways true (enabled) */ \ |
|
| 541 |
+ } \ |
|
| 542 |
+ } \ |
|
| 543 |
+ cp15.setSingleRegionAccess(cp15.DaccessPerm, cp15.IaccessPerm, num, mask, set); \ |
|
| 544 |
+} |
|
| 545 |
+ precalc(0); |
|
| 546 |
+ precalc(1); |
|
| 547 |
+ precalc(2); |
|
| 548 |
+ precalc(3); |
|
| 549 |
+ precalc(4); |
|
| 550 |
+ precalc(5); |
|
| 551 |
+ precalc(6); |
|
| 552 |
+ precalc(7); |
|
| 553 |
+#undef precalc |
|
| 554 |
+} |
| 1 | 1 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,574 @@ |
| 1 |
+/* |
|
| 2 |
+ Copyright (C) 2006 yopyop |
|
| 3 |
+ Copyright (C) 2006-2011 DeSmuME team |
|
| 4 |
+ |
|
| 5 |
+ This file is free software: you can redistribute it and/or modify |
|
| 6 |
+ it under the terms of the GNU General Public License as published by |
|
| 7 |
+ the Free Software Foundation, either version 2 of the License, or |
|
| 8 |
+ (at your option) any later version. |
|
| 9 |
+ |
|
| 10 |
+ This file is distributed in the hope that it will be useful, |
|
| 11 |
+ but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 12 |
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 13 |
+ GNU General Public License for more details. |
|
| 14 |
+ |
|
| 15 |
+ You should have received a copy of the GNU General Public License |
|
| 16 |
+ along with the this software. If not, see <http://www.gnu.org/licenses/>. |
|
| 17 |
+*/ |
|
| 18 |
+ |
|
| 19 |
+#include <cstdlib> |
|
| 20 |
+ |
|
| 21 |
+#include "cp15.h" |
|
| 22 |
+//#include "debug.h" |
|
| 23 |
+#include "MMU.h" |
|
| 24 |
+ |
|
| 25 |
+armcp15_t *armcp15_new(armcpu_t * c) |
|
| 26 |
+{
|
|
| 27 |
+ int i; |
|
| 28 |
+ armcp15_t *armcp15 = (armcp15_t*)malloc(sizeof(armcp15_t)); |
|
| 29 |
+ if(!armcp15) return NULL; |
|
| 30 |
+ |
|
| 31 |
+ |
|
| 32 |
+ armcp15->cpu = c; |
|
| 33 |
+ armcp15->IDCode = 0x41059461; |
|
| 34 |
+ armcp15->cacheType = 0x0F0D2112; |
|
| 35 |
+ armcp15->TCMSize = 0x00140180; |
|
| 36 |
+ armcp15->ctrl = 0x00012078; |
|
| 37 |
+ armcp15->DCConfig = 0x0; |
|
| 38 |
+ armcp15->ICConfig = 0x0; |
|
| 39 |
+ armcp15->writeBuffCtrl = 0x0; |
|
| 40 |
+ armcp15->und = 0x0; |
|
| 41 |
+ armcp15->DaccessPerm = 0x22222222; |
|
| 42 |
+ armcp15->IaccessPerm = 0x22222222; |
|
| 43 |
+ armcp15->protectBaseSize0 = 0x0; |
|
| 44 |
+ armcp15->protectBaseSize1 = 0x0; |
|
| 45 |
+ armcp15->protectBaseSize2 = 0x0; |
|
| 46 |
+ armcp15->protectBaseSize3 = 0x0; |
|
| 47 |
+ armcp15->protectBaseSize4 = 0x0; |
|
| 48 |
+ armcp15->protectBaseSize5 = 0x0; |
|
| 49 |
+ armcp15->protectBaseSize6 = 0x0; |
|
| 50 |
+ armcp15->protectBaseSize7 = 0x0; |
|
| 51 |
+ armcp15->cacheOp = 0x0; |
|
| 52 |
+ armcp15->DcacheLock = 0x0; |
|
| 53 |
+ armcp15->IcacheLock = 0x0; |
|
| 54 |
+ armcp15->ITCMRegion = 0x0C; |
|
| 55 |
+ armcp15->DTCMRegion = 0x0080000A; |
|
| 56 |
+ armcp15->processID = 0; |
|
| 57 |
+ |
|
| 58 |
+ MMU.ARM9_RW_MODE = static_cast<uint8_t>(BIT7(armcp15->ctrl)); |
|
| 59 |
+ armcp15->cpu->intVector = 0xFFFF0000 * (BIT13(armcp15->ctrl)); |
|
| 60 |
+ armcp15->cpu->LDTBit = !BIT15(armcp15->ctrl); //TBit |
|
| 61 |
+ |
|
| 62 |
+ /* preset calculated regionmasks */ |
|
| 63 |
+ for (i=0;i<8;i++) {
|
|
| 64 |
+ armcp15->regionWriteMask_USR[i] = 0 ; |
|
| 65 |
+ armcp15->regionWriteMask_SYS[i] = 0 ; |
|
| 66 |
+ armcp15->regionReadMask_USR[i] = 0 ; |
|
| 67 |
+ armcp15->regionReadMask_SYS[i] = 0 ; |
|
| 68 |
+ armcp15->regionExecuteMask_USR[i] = 0 ; |
|
| 69 |
+ armcp15->regionExecuteMask_SYS[i] = 0 ; |
|
| 70 |
+ armcp15->regionWriteSet_USR[i] = 0 ; |
|
| 71 |
+ armcp15->regionWriteSet_SYS[i] = 0 ; |
|
| 72 |
+ armcp15->regionReadSet_USR[i] = 0 ; |
|
| 73 |
+ armcp15->regionReadSet_SYS[i] = 0 ; |
|
| 74 |
+ armcp15->regionExecuteSet_USR[i] = 0 ; |
|
| 75 |
+ armcp15->regionExecuteSet_SYS[i] = 0 ; |
|
| 76 |
+ } ; |
|
| 77 |
+ |
|
| 78 |
+ return armcp15; |
|
| 79 |
+} |
|
| 80 |
+ |
|
| 81 |
+//#define ACCESSTYPE(val,n) (((val) >> (4*n)) & 0x0F) |
|
| 82 |
+static inline uint32_t ACCESSTYPE(uint32_t val, unsigned char n) { return (val >> (4 * n)) & 0x0F; }
|
|
| 83 |
+//#define SIZEIDENTIFIER(val) ((((val) >> 1) & 0x1F)) |
|
| 84 |
+static inline uint32_t SIZEIDENTIFIER(uint32_t val) { return (val >> 1) & 0x1F; }
|
|
| 85 |
+//#define SIZEBINARY(val) (1 << (SIZEIDENTIFIER(val)+1)) |
|
| 86 |
+static inline uint32_t SIZEBINARY(uint32_t val) { return 1 << (SIZEIDENTIFIER(val) + 1); }
|
|
| 87 |
+//#define MASKFROMREG(val) (~((SIZEBINARY(val)-1) | 0x3F)) |
|
| 88 |
+static inline uint32_t MASKFROMREG(uint32_t val) { return ~((SIZEBINARY(val) - 1) | 0x3F); }
|
|
| 89 |
+//#define SETFROMREG(val) ((val) & MASKFROMREG(val)) |
|
| 90 |
+static inline uint32_t SETFROMREG(uint32_t val) { return val & MASKFROMREG(val); }
|
|
| 91 |
+/* sets the precalculated regions to mask,set for the affected accesstypes */ |
|
| 92 |
+static void armcp15_setSingleRegionAccess(armcp15_t *armcp15,uint32_t dAccess,uint32_t iAccess,unsigned char num, uint32_t mask,uint32_t set) {
|
|
| 93 |
+ |
|
| 94 |
+ switch (ACCESSTYPE(dAccess,num)) {
|
|
| 95 |
+ case 4: /* UNP */ |
|
| 96 |
+ case 7: /* UNP */ |
|
| 97 |
+ case 8: /* UNP */ |
|
| 98 |
+ case 9: /* UNP */ |
|
| 99 |
+ case 10: /* UNP */ |
|
| 100 |
+ case 11: /* UNP */ |
|
| 101 |
+ case 12: /* UNP */ |
|
| 102 |
+ case 13: /* UNP */ |
|
| 103 |
+ case 14: /* UNP */ |
|
| 104 |
+ case 15: /* UNP */ |
|
| 105 |
+ case 0: /* no access at all */ |
|
| 106 |
+ armcp15->regionWriteMask_USR[num] = 0 ; |
|
| 107 |
+ armcp15->regionWriteSet_USR[num] = 0xFFFFFFFF ; |
|
| 108 |
+ armcp15->regionReadMask_USR[num] = 0 ; |
|
| 109 |
+ armcp15->regionReadSet_USR[num] = 0xFFFFFFFF ; |
|
| 110 |
+ armcp15->regionWriteMask_SYS[num] = 0 ; |
|
| 111 |
+ armcp15->regionWriteSet_SYS[num] = 0xFFFFFFFF ; |
|
| 112 |
+ armcp15->regionReadMask_SYS[num] = 0 ; |
|
| 113 |
+ armcp15->regionReadSet_SYS[num] = 0xFFFFFFFF ; |
|
| 114 |
+ break ; |
|
| 115 |
+ case 1: /* no access at USR, all to sys */ |
|
| 116 |
+ armcp15->regionWriteMask_USR[num] = 0 ; |
|
| 117 |
+ armcp15->regionWriteSet_USR[num] = 0xFFFFFFFF ; |
|
| 118 |
+ armcp15->regionReadMask_USR[num] = 0 ; |
|
| 119 |
+ armcp15->regionReadSet_USR[num] = 0xFFFFFFFF ; |
|
| 120 |
+ armcp15->regionWriteMask_SYS[num] = mask ; |
|
| 121 |
+ armcp15->regionWriteSet_SYS[num] = set ; |
|
| 122 |
+ armcp15->regionReadMask_SYS[num] = mask ; |
|
| 123 |
+ armcp15->regionReadSet_SYS[num] = set ; |
|
| 124 |
+ break ; |
|
| 125 |
+ case 2: /* read at USR, all to sys */ |
|
| 126 |
+ armcp15->regionWriteMask_USR[num] = 0 ; |
|
| 127 |
+ armcp15->regionWriteSet_USR[num] = 0xFFFFFFFF ; |
|
| 128 |
+ armcp15->regionReadMask_USR[num] = mask ; |
|
| 129 |
+ armcp15->regionReadSet_USR[num] = set ; |
|
| 130 |
+ armcp15->regionWriteMask_SYS[num] = mask ; |
|
| 131 |
+ armcp15->regionWriteSet_SYS[num] = set ; |
|
| 132 |
+ armcp15->regionReadMask_SYS[num] = mask ; |
|
| 133 |
+ armcp15->regionReadSet_SYS[num] = set ; |
|
| 134 |
+ break ; |
|
| 135 |
+ case 3: /* all to USR, all to sys */ |
|
| 136 |
+ armcp15->regionWriteMask_USR[num] = mask ; |
|
| 137 |
+ armcp15->regionWriteSet_USR[num] = set ; |
|
| 138 |
+ armcp15->regionReadMask_USR[num] = mask ; |
|
| 139 |
+ armcp15->regionReadSet_USR[num] = set ; |
|
| 140 |
+ armcp15->regionWriteMask_SYS[num] = mask ; |
|
| 141 |
+ armcp15->regionWriteSet_SYS[num] = set ; |
|
| 142 |
+ armcp15->regionReadMask_SYS[num] = mask ; |
|
| 143 |
+ armcp15->regionReadSet_SYS[num] = set ; |
|
| 144 |
+ break ; |
|
| 145 |
+ case 5: /* no access at USR, read to sys */ |
|
| 146 |
+ armcp15->regionWriteMask_USR[num] = 0 ; |
|
| 147 |
+ armcp15->regionWriteSet_USR[num] = 0xFFFFFFFF ; |
|
| 148 |
+ armcp15->regionReadMask_USR[num] = 0 ; |
|
| 149 |
+ armcp15->regionReadSet_USR[num] = 0xFFFFFFFF ; |
|
| 150 |
+ armcp15->regionWriteMask_SYS[num] = 0 ; |
|
| 151 |
+ armcp15->regionWriteSet_SYS[num] = 0xFFFFFFFF ; |
|
| 152 |
+ armcp15->regionReadMask_SYS[num] = mask ; |
|
| 153 |
+ armcp15->regionReadSet_SYS[num] = set ; |
|
| 154 |
+ break ; |
|
| 155 |
+ case 6: /* read at USR, read to sys */ |
|
| 156 |
+ armcp15->regionWriteMask_USR[num] = 0 ; |
|
| 157 |
+ armcp15->regionWriteSet_USR[num] = 0xFFFFFFFF ; |
|
| 158 |
+ armcp15->regionReadMask_USR[num] = mask ; |
|
| 159 |
+ armcp15->regionReadSet_USR[num] = set ; |
|
| 160 |
+ armcp15->regionWriteMask_SYS[num] = 0 ; |
|
| 161 |
+ armcp15->regionWriteSet_SYS[num] = 0xFFFFFFFF ; |
|
| 162 |
+ armcp15->regionReadMask_SYS[num] = mask ; |
|
| 163 |
+ armcp15->regionReadSet_SYS[num] = set ; |
|
| 164 |
+ break ; |
|
| 165 |
+ } |
|
| 166 |
+ switch (ACCESSTYPE(iAccess,num)) {
|
|
| 167 |
+ case 4: /* UNP */ |
|
| 168 |
+ case 7: /* UNP */ |
|
| 169 |
+ case 8: /* UNP */ |
|
| 170 |
+ case 9: /* UNP */ |
|
| 171 |
+ case 10: /* UNP */ |
|
| 172 |
+ case 11: /* UNP */ |
|
| 173 |
+ case 12: /* UNP */ |
|
| 174 |
+ case 13: /* UNP */ |
|
| 175 |
+ case 14: /* UNP */ |
|
| 176 |
+ case 15: /* UNP */ |
|
| 177 |
+ case 0: /* no access at all */ |
|
| 178 |
+ armcp15->regionExecuteMask_USR[num] = 0 ; |
|
| 179 |
+ armcp15->regionExecuteSet_USR[num] = 0xFFFFFFFF ; |
|
| 180 |
+ armcp15->regionExecuteMask_SYS[num] = 0 ; |
|
| 181 |
+ armcp15->regionExecuteSet_SYS[num] = 0xFFFFFFFF ; |
|
| 182 |
+ break ; |
|
| 183 |
+ case 1: |
|
| 184 |
+ armcp15->regionExecuteMask_USR[num] = 0 ; |
|
| 185 |
+ armcp15->regionExecuteSet_USR[num] = 0xFFFFFFFF ; |
|
| 186 |
+ armcp15->regionExecuteMask_SYS[num] = mask ; |
|
| 187 |
+ armcp15->regionExecuteSet_SYS[num] = set ; |
|
| 188 |
+ break ; |
|
| 189 |
+ case 2: |
|
| 190 |
+ case 3: |
|
| 191 |
+ case 6: |
|
| 192 |
+ armcp15->regionExecuteMask_USR[num] = mask ; |
|
| 193 |
+ armcp15->regionExecuteSet_USR[num] = set ; |
|
| 194 |
+ armcp15->regionExecuteMask_SYS[num] = mask ; |
|
| 195 |
+ armcp15->regionExecuteSet_SYS[num] = set ; |
|
| 196 |
+ break ; |
|
| 197 |
+ } |
|
| 198 |
+} |
|
| 199 |
+ |
|
| 200 |
+/* precalculate region masks/sets from cp15 register */ |
|
| 201 |
+static void armcp15_maskPrecalc(armcp15_t *armcp15) |
|
| 202 |
+{
|
|
| 203 |
+#define precalc(num) { \
|
|
| 204 |
+ uint32_t mask = 0, set = 0xFFFFFFFF ; /* (x & 0) == 0xFF..FF is allways false (disabled) */ \ |
|
| 205 |
+ if (BIT_N(armcp15->protectBaseSize##num,0)) /* if region is enabled */ \ |
|
| 206 |
+ { /* reason for this define: naming includes var */ \
|
|
| 207 |
+ mask = MASKFROMREG(armcp15->protectBaseSize##num) ; \ |
|
| 208 |
+ set = SETFROMREG(armcp15->protectBaseSize##num) ; \ |
|
| 209 |
+ if (SIZEIDENTIFIER(armcp15->protectBaseSize##num)==0x1F) \ |
|
| 210 |
+ { /* for the 4GB region, uint32_t suffers wraparound */ \
|
|
| 211 |
+ mask = 0 ; set = 0 ; /* (x & 0) == 0 is allways true (enabled) */ \ |
|
| 212 |
+} \ |
|
| 213 |
+} \ |
|
| 214 |
+ armcp15_setSingleRegionAccess(armcp15,armcp15->DaccessPerm,armcp15->IaccessPerm,num,mask,set) ; \ |
|
| 215 |
+} |
|
| 216 |
+ precalc(0) ; |
|
| 217 |
+ precalc(1) ; |
|
| 218 |
+ precalc(2) ; |
|
| 219 |
+ precalc(3) ; |
|
| 220 |
+ precalc(4) ; |
|
| 221 |
+ precalc(5) ; |
|
| 222 |
+ precalc(6) ; |
|
| 223 |
+ precalc(7) ; |
|
| 224 |
+} |
|
| 225 |
+ |
|
| 226 |
+/*bool armcp15_isAccessAllowed(armcp15_t *armcp15,uint32_t address,uint32_t access) |
|
| 227 |
+{
|
|
| 228 |
+ int i ; |
|
| 229 |
+ if (!(armcp15->ctrl & 1)) return true ;*/ /* protection checking is not enabled */ |
|
| 230 |
+ /*for (i=0;i<8;i++) {
|
|
| 231 |
+ switch (access) {
|
|
| 232 |
+ case CP15_ACCESS_WRITEUSR: |
|
| 233 |
+ if ((address & armcp15->regionWriteMask_USR[i]) == armcp15->regionWriteSet_USR[i]) return true ; |
|
| 234 |
+ break ; |
|
| 235 |
+ case CP15_ACCESS_WRITESYS: |
|
| 236 |
+ if ((address & armcp15->regionWriteMask_SYS[i]) == armcp15->regionWriteSet_SYS[i]) return true ; |
|
| 237 |
+ break ; |
|
| 238 |
+ case CP15_ACCESS_READUSR: |
|
| 239 |
+ if ((address & armcp15->regionReadMask_USR[i]) == armcp15->regionReadSet_USR[i]) return true ; |
|
| 240 |
+ break ; |
|
| 241 |
+ case CP15_ACCESS_READSYS: |
|
| 242 |
+ if ((address & armcp15->regionReadMask_SYS[i]) == armcp15->regionReadSet_SYS[i]) return true ; |
|
| 243 |
+ break ; |
|
| 244 |
+ case CP15_ACCESS_EXECUSR: |
|
| 245 |
+ if ((address & armcp15->regionExecuteMask_USR[i]) == armcp15->regionExecuteSet_USR[i]) return true ; |
|
| 246 |
+ break ; |
|
| 247 |
+ case CP15_ACCESS_EXECSYS: |
|
| 248 |
+ if ((address & armcp15->regionExecuteMask_SYS[i]) == armcp15->regionExecuteSet_SYS[i]) return true ; |
|
| 249 |
+ break ; |
|
| 250 |
+ } |
|
| 251 |
+ }*/ |
|
| 252 |
+ /* when protections are enabled, but no region allows access, deny access */ |
|
| 253 |
+ /*return false ; |
|
| 254 |
+}*/ |
|
| 255 |
+ |
|
| 256 |
+/*bool armcp15_dataProcess(armcp15_t *, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t) |
|
| 257 |
+{
|
|
| 258 |
+ //LOG("Unsupported CP15 operation : DataProcess\n");
|
|
| 259 |
+ return false; |
|
| 260 |
+}*/ |
|
| 261 |
+ |
|
| 262 |
+/*bool armcp15_load(armcp15_t *, uint8_t, uint8_t) |
|
| 263 |
+{
|
|
| 264 |
+ //LOG("Unsupported CP15 operation : Load\n");
|
|
| 265 |
+ return false; |
|
| 266 |
+}*/ |
|
| 267 |
+ |
|
| 268 |
+/*bool armcp15_store(armcp15_t *, uint8_t, uint8_t) |
|
| 269 |
+{
|
|
| 270 |
+ //LOG("Unsupported CP15 operation : Store\n");
|
|
| 271 |
+ return false; |
|
| 272 |
+}*/ |
|
| 273 |
+ |
|
| 274 |
+bool armcp15_moveCP2ARM(armcp15_t *armcp15, uint32_t * R, uint8_t CRn, uint8_t CRm, uint8_t opcode1, uint8_t opcode2) |
|
| 275 |
+{
|
|
| 276 |
+ if(armcp15->cpu->CPSR.bits.mode == USR) return false; |
|
| 277 |
+ |
|
| 278 |
+ switch(CRn) |
|
| 279 |
+ {
|
|
| 280 |
+ case 0: |
|
| 281 |
+ if((opcode1 == 0)&&(CRm==0)) |
|
| 282 |
+ {
|
|
| 283 |
+ switch(opcode2) |
|
| 284 |
+ {
|
|
| 285 |
+ case 1: |
|
| 286 |
+ *R = armcp15->cacheType; |
|
| 287 |
+ return true; |
|
| 288 |
+ case 2: |
|
| 289 |
+ *R = armcp15->TCMSize; |
|
| 290 |
+ return true; |
|
| 291 |
+ default: |
|
| 292 |
+ *R = armcp15->IDCode; |
|
| 293 |
+ return true; |
|
| 294 |
+ } |
|
| 295 |
+ } |
|
| 296 |
+ return false; |
|
| 297 |
+ case 1: |
|
| 298 |
+ if((opcode1==0) && (opcode2==0) && (CRm==0)) |
|
| 299 |
+ {
|
|
| 300 |
+ *R = armcp15->ctrl; |
|
| 301 |
+ //LOG("CP15: CPtoARM ctrl %08X\n", armcp15->ctrl);
|
|
| 302 |
+ return true; |
|
| 303 |
+ } |
|
| 304 |
+ return false; |
|
| 305 |
+ |
|
| 306 |
+ case 2: |
|
| 307 |
+ if((opcode1==0) && (CRm==0)) |
|
| 308 |
+ {
|
|
| 309 |
+ switch(opcode2) |
|
| 310 |
+ {
|
|
| 311 |
+ case 0: |
|
| 312 |
+ *R = armcp15->DCConfig; |
|
| 313 |
+ return true; |
|
| 314 |
+ case 1: |
|
| 315 |
+ *R = armcp15->ICConfig; |
|
| 316 |
+ return true; |
|
| 317 |
+ default: |
|
| 318 |
+ return false; |
|
| 319 |
+ } |
|
| 320 |
+ } |
|
| 321 |
+ return false; |
|
| 322 |
+ case 3: |
|
| 323 |
+ if((opcode1==0) && (opcode2==0) && (CRm==0)) |
|
| 324 |
+ {
|
|
| 325 |
+ *R = armcp15->writeBuffCtrl; |
|
| 326 |
+ //LOG("CP15: CPtoARM writeBuffer ctrl %08X\n", armcp15->writeBuffCtrl);
|
|
| 327 |
+ return true; |
|
| 328 |
+ } |
|
| 329 |
+ return false; |
|
| 330 |
+ case 5: |
|
| 331 |
+ if((opcode1==0) && (CRm==0)) |
|
| 332 |
+ {
|
|
| 333 |
+ switch(opcode2) |
|
| 334 |
+ {
|
|
| 335 |
+ case 2: |
|
| 336 |
+ *R = armcp15->DaccessPerm; |
|
| 337 |
+ return true; |
|
| 338 |
+ case 3: |
|
| 339 |
+ *R = armcp15->IaccessPerm; |
|
| 340 |
+ return true; |
|
| 341 |
+ default: |
|
| 342 |
+ return false; |
|
| 343 |
+ } |
|
| 344 |
+ } |
|
| 345 |
+ return false; |
|
| 346 |
+ case 6: |
|
| 347 |
+ if((opcode1==0) && (opcode2==0)) |
|
| 348 |
+ {
|
|
| 349 |
+ switch(CRm) |
|
| 350 |
+ {
|
|
| 351 |
+ case 0: |
|
| 352 |
+ *R = armcp15->protectBaseSize0; |
|
| 353 |
+ return true; |
|
| 354 |
+ case 1: |
|
| 355 |
+ *R = armcp15->protectBaseSize1; |
|
| 356 |
+ return true; |
|
| 357 |
+ case 2: |
|
| 358 |
+ *R = armcp15->protectBaseSize2; |
|
| 359 |
+ return true; |
|
| 360 |
+ case 3: |
|
| 361 |
+ *R = armcp15->protectBaseSize3; |
|
| 362 |
+ return true; |
|
| 363 |
+ case 4: |
|
| 364 |
+ *R = armcp15->protectBaseSize4; |
|
| 365 |
+ return true; |
|
| 366 |
+ case 5: |
|
| 367 |
+ *R = armcp15->protectBaseSize5; |
|
| 368 |
+ return true; |
|
| 369 |
+ case 6: |
|
| 370 |
+ *R = armcp15->protectBaseSize6; |
|
| 371 |
+ return true; |
|
| 372 |
+ case 7: |
|
| 373 |
+ *R = armcp15->protectBaseSize7; |
|
| 374 |
+ return true; |
|
| 375 |
+ default: |
|
| 376 |
+ return false; |
|
| 377 |
+ } |
|
| 378 |
+ } |
|
| 379 |
+ return false; |
|
| 380 |
+ case 9: |
|
| 381 |
+ if((opcode1==0)) |
|
| 382 |
+ {
|
|
| 383 |
+ switch(CRm) |
|
| 384 |
+ {
|
|
| 385 |
+ case 0: |
|
| 386 |
+ switch(opcode2) |
|
| 387 |
+ {
|
|
| 388 |
+ case 0: |
|
| 389 |
+ *R = armcp15->DcacheLock; |
|
| 390 |
+ return true; |
|
| 391 |
+ case 1: |
|
| 392 |
+ *R = armcp15->IcacheLock; |
|
| 393 |
+ return true; |
|
| 394 |
+ default: |
|
| 395 |
+ return false; |
|
| 396 |
+ } |
|
| 397 |
+ case 1: |
|
| 398 |
+ switch(opcode2) |
|
| 399 |
+ {
|
|
| 400 |
+ case 0: |
|
| 401 |
+ *R = armcp15->DTCMRegion; |
|
| 402 |
+ return true; |
|
| 403 |
+ case 1: |
|
| 404 |
+ *R = armcp15->ITCMRegion; |
|
| 405 |
+ return true; |
|
| 406 |
+ default: |
|
| 407 |
+ return false; |
|
| 408 |
+ } |
|
| 409 |
+ } |
|
| 410 |
+ } |
|
| 411 |
+ return false; |
|
| 412 |
+ default: |
|
| 413 |
+ //LOG("Unsupported CP15 operation : MRC\n");
|
|
| 414 |
+ return false; |
|
| 415 |
+ } |
|
| 416 |
+} |
|
| 417 |
+ |
|
| 418 |
+static uint32_t CP15wait4IRQ(armcpu_t *cpu) |
|
| 419 |
+{
|
|
| 420 |
+ cpu->waitIRQ = true; |
|
| 421 |
+ cpu->halt_IE_and_IF = true; |
|
| 422 |
+ //IME set deliberately omitted: only SWI sets IME to 1 |
|
| 423 |
+ return 1; |
|
| 424 |
+} |
|
| 425 |
+ |
|
| 426 |
+bool armcp15_moveARM2CP(armcp15_t *armcp15, uint32_t val, uint8_t CRn, uint8_t CRm, uint8_t opcode1, uint8_t opcode2) |
|
| 427 |
+{
|
|
| 428 |
+ if(armcp15->cpu->CPSR.bits.mode == USR) return false; |
|
| 429 |
+ |
|
| 430 |
+ switch(CRn) |
|
| 431 |
+ {
|
|
| 432 |
+ case 1: |
|
| 433 |
+ if((opcode1==0) && (opcode2==0) && (CRm==0)) |
|
| 434 |
+ {
|
|
| 435 |
+ |
|
| 436 |
+ //On the NDS bit0,2,7,12..19 are R/W, Bit3..6 are always set, all other bits are always zero. |
|
| 437 |
+ armcp15->ctrl = (val & 0x000FF085) | 0x00000078; |
|
| 438 |
+ MMU.ARM9_RW_MODE = static_cast<uint8_t>(BIT7(val)); |
|
| 439 |
+ //zero 31-jan-2010: change from 0x0FFF0000 to 0xFFFF0000 per gbatek |
|
| 440 |
+ armcp15->cpu->intVector = 0xFFFF0000 * (BIT13(val)); |
|
| 441 |
+ armcp15->cpu->LDTBit = !BIT15(val); //TBit |
|
| 442 |
+ //LOG("CP15: ARMtoCP ctrl %08X (val %08X)\n", armcp15->ctrl, val);
|
|
| 443 |
+ return true; |
|
| 444 |
+ } |
|
| 445 |
+ return false; |
|
| 446 |
+ case 2: |
|
| 447 |
+ if((opcode1==0) && (CRm==0)) |
|
| 448 |
+ {
|
|
| 449 |
+ switch(opcode2) |
|
| 450 |
+ {
|
|
| 451 |
+ case 0: |
|
| 452 |
+ armcp15->DCConfig = val; |
|
| 453 |
+ return true; |
|
| 454 |
+ case 1: |
|
| 455 |
+ armcp15->ICConfig = val; |
|
| 456 |
+ return true; |
|
| 457 |
+ default: |
|
| 458 |
+ return false; |
|
| 459 |
+ } |
|
| 460 |
+ } |
|
| 461 |
+ return false; |
|
| 462 |
+ case 3: |
|
| 463 |
+ if((opcode1==0) && (opcode2==0) && (CRm==0)) |
|
| 464 |
+ {
|
|
| 465 |
+ armcp15->writeBuffCtrl = val; |
|
| 466 |
+ //LOG("CP15: ARMtoCP writeBuffer ctrl %08X\n", armcp15->writeBuffCtrl);
|
|
| 467 |
+ return true; |
|
| 468 |
+ } |
|
| 469 |
+ return false; |
|
| 470 |
+ case 5: |
|
| 471 |
+ if((opcode1==0) && (CRm==0)) |
|
| 472 |
+ {
|
|
| 473 |
+ switch(opcode2) |
|
| 474 |
+ {
|
|
| 475 |
+ case 2: |
|
| 476 |
+ armcp15->DaccessPerm = val; |
|
| 477 |
+ armcp15_maskPrecalc(armcp15); |
|
| 478 |
+ return true; |
|
| 479 |
+ case 3: |
|
| 480 |
+ armcp15->IaccessPerm = val; |
|
| 481 |
+ armcp15_maskPrecalc(armcp15); |
|
| 482 |
+ return true; |
|
| 483 |
+ default: |
|
| 484 |
+ return false; |
|
| 485 |
+ } |
|
| 486 |
+ } |
|
| 487 |
+ return false; |
|
| 488 |
+ case 6: |
|
| 489 |
+ if((opcode1==0) && (opcode2==0)) |
|
| 490 |
+ {
|
|
| 491 |
+ switch(CRm) |
|
| 492 |
+ {
|
|
| 493 |
+ case 0: |
|
| 494 |
+ armcp15->protectBaseSize0 = val; |
|
| 495 |
+ armcp15_maskPrecalc(armcp15) ; |
|
| 496 |
+ return true; |
|
| 497 |
+ case 1: |
|
| 498 |
+ armcp15->protectBaseSize1 = val; |
|
| 499 |
+ armcp15_maskPrecalc(armcp15) ; |
|
| 500 |
+ return true; |
|
| 501 |
+ case 2: |
|
| 502 |
+ armcp15->protectBaseSize2 = val; |
|
| 503 |
+ armcp15_maskPrecalc(armcp15) ; |
|
| 504 |
+ return true; |
|
| 505 |
+ case 3: |
|
| 506 |
+ armcp15->protectBaseSize3 = val; |
|
| 507 |
+ armcp15_maskPrecalc(armcp15) ; |
|
| 508 |
+ return true; |
|
| 509 |
+ case 4: |
|
| 510 |
+ armcp15->protectBaseSize4 = val; |
|
| 511 |
+ armcp15_maskPrecalc(armcp15) ; |
|
| 512 |
+ return true; |
|
| 513 |
+ case 5: |
|
| 514 |
+ armcp15->protectBaseSize5 = val; |
|
| 515 |
+ armcp15_maskPrecalc(armcp15) ; |
|
| 516 |
+ return true; |
|
| 517 |
+ case 6: |
|
| 518 |
+ armcp15->protectBaseSize6 = val; |
|
| 519 |
+ armcp15_maskPrecalc(armcp15) ; |
|
| 520 |
+ return true; |
|
| 521 |
+ case 7: |
|
| 522 |
+ armcp15->protectBaseSize7 = val; |
|
| 523 |
+ armcp15_maskPrecalc(armcp15) ; |
|
| 524 |
+ return true; |
|
| 525 |
+ default: |
|
| 526 |
+ return false; |
|
| 527 |
+ } |
|
| 528 |
+ } |
|
| 529 |
+ return false; |
|
| 530 |
+ case 7: |
|
| 531 |
+ if((CRm==0)&&(opcode1==0)&&((opcode2==4))) |
|
| 532 |
+ {
|
|
| 533 |
+ CP15wait4IRQ(armcp15->cpu); |
|
| 534 |
+ return true; |
|
| 535 |
+ } |
|
| 536 |
+ return false; |
|
| 537 |
+ case 9: |
|
| 538 |
+ if((opcode1==0)) |
|
| 539 |
+ {
|
|
| 540 |
+ switch(CRm) |
|
| 541 |
+ {
|
|
| 542 |
+ case 0: |
|
| 543 |
+ switch(opcode2) |
|
| 544 |
+ {
|
|
| 545 |
+ case 0: |
|
| 546 |
+ armcp15->DcacheLock = val; |
|
| 547 |
+ return true; |
|
| 548 |
+ case 1: |
|
| 549 |
+ armcp15->IcacheLock = val; |
|
| 550 |
+ return true; |
|
| 551 |
+ default: |
|
| 552 |
+ return false; |
|
| 553 |
+ } |
|
| 554 |
+ case 1: |
|
| 555 |
+ switch(opcode2) |
|
| 556 |
+ {
|
|
| 557 |
+ case 0: |
|
| 558 |
+ MMU.DTCMRegion = armcp15->DTCMRegion = val & 0x0FFFF000; |
|
| 559 |
+ return true; |
|
| 560 |
+ case 1: |
|
| 561 |
+ armcp15->ITCMRegion = val; |
|
| 562 |
+ //ITCM base is not writeable! |
|
| 563 |
+ MMU.ITCMRegion = 0; |
|
| 564 |
+ return true; |
|
| 565 |
+ default: |
|
| 566 |
+ return false; |
|
| 567 |
+ } |
|
| 568 |
+ } |
|
| 569 |
+ } |
|
| 570 |
+ return false; |
|
| 571 |
+ default: |
|
| 572 |
+ return false; |
|
| 573 |
+ } |
|
| 574 |
+} |