all repos — mgba @ 290d5b77dd4f47e7f96981728eea5dc33bd29f1d

mGBA Game Boy Advance Emulator

ARM: Add basic CP15 information
Jeffrey Pfau jeffrey@endrift.com
Wed, 01 Jun 2016 19:13:31 -0700
commit

290d5b77dd4f47e7f96981728eea5dc33bd29f1d

parent

e75cb6f7b4cdea9ee94c9af590172acb33a02ae6

2 files changed, 64 insertions(+), 0 deletions(-)

jump to
M src/arm/arm.csrc/arm/arm.c

@@ -69,6 +69,7 @@ }

} void ARMInit(struct ARMCore* cpu) { + memset(&cpu->cp15, 0, sizeof(cpu->cp15)); cpu->master->init(cpu, cpu->master); size_t i; for (i = 0; i < cpu->numComponents; ++i) {

@@ -115,6 +116,10 @@ int i;

for (i = 0; i < 16; ++i) { cpu->gprs[i] = 0; } + if (ARMControlRegIsVE(cpu->cp15.r1.c0)) { + cpu->gprs[ARM_PC] = 0xFFFF0000; + } + for (i = 0; i < 6; ++i) { cpu->bankedRegisters[i][0] = 0; cpu->bankedRegisters[i][1] = 0;

@@ -161,6 +166,9 @@ ARMSetPrivilegeMode(cpu, MODE_IRQ);

cpu->cpsr.priv = MODE_IRQ; cpu->gprs[ARM_LR] = cpu->gprs[ARM_PC] - instructionWidth + WORD_SIZE_ARM; cpu->gprs[ARM_PC] = BASE_IRQ; + if (ARMControlRegIsVE(cpu->cp15.r1.c0)) { + cpu->gprs[ARM_PC] |= 0xFFFF0000; + } int currentCycles = 0; ARM_WRITE_PC; _ARMSetMode(cpu, MODE_ARM);

@@ -181,6 +189,9 @@ ARMSetPrivilegeMode(cpu, MODE_SUPERVISOR);

cpu->cpsr.priv = MODE_SUPERVISOR; cpu->gprs[ARM_LR] = cpu->gprs[ARM_PC] - instructionWidth; cpu->gprs[ARM_PC] = BASE_SWI; + if (ARMControlRegIsVE(cpu->cp15.r1.c0)) { + cpu->gprs[ARM_PC] |= 0xFFFF0000; + } int currentCycles = 0; ARM_WRITE_PC; _ARMSetMode(cpu, MODE_ARM);

@@ -201,6 +212,9 @@ ARMSetPrivilegeMode(cpu, MODE_UNDEFINED);

cpu->cpsr.priv = MODE_UNDEFINED; cpu->gprs[ARM_LR] = cpu->gprs[ARM_PC] - instructionWidth; cpu->gprs[ARM_PC] = BASE_UNDEF; + if (ARMControlRegIsVE(cpu->cp15.r1.c0)) { + cpu->gprs[ARM_PC] |= 0xFFFF0000; + } int currentCycles = 0; ARM_WRITE_PC; _ARMSetMode(cpu, MODE_ARM);
M src/arm/arm.hsrc/arm/arm.h

@@ -131,6 +131,55 @@

void (*hitStub)(struct ARMCore* cpu, uint32_t opcode); }; +DECL_BITFIELD(ARMCPUID, uint32_t); +DECL_BITFIELD(ARMCacheType, uint32_t); +DECL_BITFIELD(ARMTCMType, uint32_t); +DECL_BITFIELD(ARMTLBType, uint32_t); +DECL_BITFIELD(ARMMPUType, uint32_t); + +DECL_BITFIELD(ARMControlReg, uint32_t); +DECL_BIT(ARMControlReg, M, 0); +DECL_BIT(ARMControlReg, A, 1); +DECL_BIT(ARMControlReg, C, 2); +DECL_BIT(ARMControlReg, W, 3); +DECL_BIT(ARMControlReg, P, 4); +DECL_BIT(ARMControlReg, D, 5); +DECL_BIT(ARMControlReg, L, 6); +DECL_BIT(ARMControlReg, B, 7); +DECL_BIT(ARMControlReg, S, 8); +DECL_BIT(ARMControlReg, R, 9); +DECL_BIT(ARMControlReg, F, 10); +DECL_BIT(ARMControlReg, Z, 11); +DECL_BIT(ARMControlReg, I, 12); +DECL_BIT(ARMControlReg, V, 13); +DECL_BIT(ARMControlReg, RR, 14); +DECL_BIT(ARMControlReg, L4, 15); +DECL_BIT(ARMControlReg, FI, 21); +DECL_BIT(ARMControlReg, U, 22); +DECL_BIT(ARMControlReg, XP, 23); +DECL_BIT(ARMControlReg, VE, 24); +DECL_BIT(ARMControlReg, EE, 25); +DECL_BIT(ARMControlReg, L2, 26); + +DECL_BITFIELD(ARMCoprocessorAccess, uint32_t); + +struct ARMCP15 { + struct { + ARMCPUID cpuid; + ARMCacheType cachetype; + ARMTCMType tcmtype; + ARMTLBType tlbtype; + ARMMPUType mputype; + } r0; + struct { + ARMControlReg c0; + uint32_t c1; + ARMCoprocessorAccess cpAccess; + } r1; + + uint32_t (*write)(struct ARMCore*, int crn, int crm, int opcode2, uint32_t value); +}; + struct ARMCore { int32_t gprs[16]; union PSR cpsr;

@@ -152,6 +201,7 @@ enum PrivilegeMode privilegeMode;

struct ARMMemory memory; struct ARMInterruptHandler irqh; + struct ARMCP15 cp15; struct mCPUComponent* master;