dyncom: Move CP15 register writing into its own function.

Also implements writing to the rest of the ARM11 MPCore CP15 register set.
This commit is contained in:
Lioncash 2015-03-26 15:25:04 -04:00
parent 5e5954c63b
commit 490df716f3
4 changed files with 265 additions and 88 deletions

View file

@ -4761,94 +4761,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
if (inst_cream->Rd == 15) {
DEBUG_MSG;
} else {
if (inst_cream->cp_num == 15) {
if (CRn == 1 && CRm == 0 && OPCODE_2 == 0) {
CP15_REG(CP15_CONTROL) = RD;
} else if (CRn == 1 && CRm == 0 && OPCODE_2 == 1) {
CP15_REG(CP15_AUXILIARY_CONTROL) = RD;
} else if (CRn == 1 && CRm == 0 && OPCODE_2 == 2) {
CP15_REG(CP15_COPROCESSOR_ACCESS_CONTROL) = RD;
} else if (CRn == 2 && CRm == 0 && OPCODE_2 == 0) {
CP15_REG(CP15_TRANSLATION_BASE_TABLE_0) = RD;
} else if (CRn == 2 && CRm == 0 && OPCODE_2 == 1) {
CP15_REG(CP15_TRANSLATION_BASE_TABLE_1) = RD;
} else if (CRn == 2 && CRm == 0 && OPCODE_2 == 2) {
CP15_REG(CP15_TRANSLATION_BASE_CONTROL) = RD;
} else if (CRn == 3 && CRm == 0 && OPCODE_2 == 0) {
CP15_REG(CP15_DOMAIN_ACCESS_CONTROL) = RD;
} else if(CRn == MMU_CACHE_OPS){
//LOG_WARNING(Core_ARM11, "cache operations have not implemented.");
} else if(CRn == MMU_TLB_OPS){
switch (CRm) {
case 5: // ITLB
switch(OPCODE_2) {
case 0: // Invalidate all
LOG_DEBUG(Core_ARM11, "{TLB} [INSN] invalidate all");
break;
case 1: // Invalidate by MVA
LOG_DEBUG(Core_ARM11, "{TLB} [INSN] invalidate by mva");
break;
case 2: // Invalidate by asid
LOG_DEBUG(Core_ARM11, "{TLB} [INSN] invalidate by asid");
break;
default:
break;
}
break;
case 6: // DTLB
switch(OPCODE_2){
case 0: // Invalidate all
LOG_DEBUG(Core_ARM11, "{TLB} [DATA] invalidate all");
break;
case 1: // Invalidate by MVA
LOG_DEBUG(Core_ARM11, "{TLB} [DATA] invalidate by mva");
break;
case 2: // Invalidate by asid
LOG_DEBUG(Core_ARM11, "{TLB} [DATA] invalidate by asid");
break;
default:
break;
}
break;
case 7: // UNIFILED TLB
switch(OPCODE_2){
case 0: // invalidate all
LOG_DEBUG(Core_ARM11, "{TLB} [UNIFILED] invalidate all");
break;
case 1: // Invalidate by MVA
LOG_DEBUG(Core_ARM11, "{TLB} [UNIFILED] invalidate by mva");
break;
case 2: // Invalidate by asid
LOG_DEBUG(Core_ARM11, "{TLB} [UNIFILED] invalidate by asid");
break;
default:
break;
}
break;
default:
break;
}
} else if(CRn == MMU_PID) {
if(OPCODE_2 == 0) {
CP15_REG(CP15_PID) = RD;
} else if(OPCODE_2 == 1) {
CP15_REG(CP15_CONTEXT_ID) = RD;
} else if (OPCODE_2 == 2) {
CP15_REG(CP15_THREAD_UPRW) = RD;
} else if(OPCODE_2 == 3) {
if (InAPrivilegedMode(cpu))
CP15_REG(CP15_THREAD_URO) = RD;
} else if (OPCODE_2 == 4) {
if (InAPrivilegedMode(cpu))
CP15_REG(CP15_THREAD_PRW) = RD;
} else {
LOG_ERROR(Core_ARM11, "mmu_mcr wrote UNKNOWN - reg %d", CRn);
}
} else {
LOG_ERROR(Core_ARM11, "mcr CRn=%d, CRm=%d OP2=%d is not implemented", CRn, CRm, OPCODE_2);
}
}
if (inst_cream->cp_num == 15)
WriteCP15Register(cpu, RD, CRn, OPCODE_1, CRm, OPCODE_2);
}
}
cpu->Reg[15] += GET_INST_SIZE(cpu);