Merge pull request #677 from lioncash/cp15
dyncom: Isolate CP15 register reading and writing
This commit is contained in:
		
						commit
						e25ffaba86
					
				@ -3690,10 +3690,6 @@ static int clz(unsigned int x) {
 | 
			
		||||
    return n;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool InAPrivilegedMode(ARMul_State* core) {
 | 
			
		||||
    return (core->Mode != USER32MODE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned InterpreterMainLoop(ARMul_State* state) {
 | 
			
		||||
    Common::Profiling::ScopeTimer timer_execute(profile_execute);
 | 
			
		||||
 | 
			
		||||
@ -3701,6 +3697,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
 | 
			
		||||
    #undef RS
 | 
			
		||||
 | 
			
		||||
    #define CRn             inst_cream->crn
 | 
			
		||||
    #define OPCODE_1        inst_cream->opcode_1
 | 
			
		||||
    #define OPCODE_2        inst_cream->opcode_2
 | 
			
		||||
    #define CRm             inst_cream->crm
 | 
			
		||||
    #define CP15_REG(n)     cpu->CP15[CP15(n)]
 | 
			
		||||
@ -4764,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);
 | 
			
		||||
@ -4926,50 +4837,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
 | 
			
		||||
                CITRA_IGNORE_EXIT(-1);
 | 
			
		||||
                goto END;
 | 
			
		||||
            } else {
 | 
			
		||||
                if (inst_cream->cp_num == 15) {
 | 
			
		||||
                    if(CRn == 0 && OPCODE_2 == 0 && CRm == 0) {
 | 
			
		||||
                        RD = cpu->CP15[CP15(CP15_MAIN_ID)];
 | 
			
		||||
                    } else if (CRn == 0 && CRm == 0 && OPCODE_2 == 1) {
 | 
			
		||||
                        RD = cpu->CP15[CP15(CP15_CACHE_TYPE)];
 | 
			
		||||
                    } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 0) {
 | 
			
		||||
                        RD = cpu->CP15[CP15(CP15_CONTROL)];
 | 
			
		||||
                    } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 1) {
 | 
			
		||||
                        RD = cpu->CP15[CP15(CP15_AUXILIARY_CONTROL)];
 | 
			
		||||
                    } else if (CRn == 1 && CRm == 0 && OPCODE_2 == 2) {
 | 
			
		||||
                        RD = cpu->CP15[CP15(CP15_COPROCESSOR_ACCESS_CONTROL)];
 | 
			
		||||
                    } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 0) {
 | 
			
		||||
                        RD = cpu->CP15[CP15(CP15_TRANSLATION_BASE_TABLE_0)];
 | 
			
		||||
                    } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 1) {
 | 
			
		||||
                        RD = cpu->CP15[CP15(CP15_TRANSLATION_BASE_TABLE_1)];
 | 
			
		||||
                    } else if (CRn == 2 && CRm == 0 && OPCODE_2 == 2) {
 | 
			
		||||
                        RD = cpu->CP15[CP15(CP15_TRANSLATION_BASE_CONTROL)];
 | 
			
		||||
                    } else if (CRn == 3 && CRm == 0 && OPCODE_2 == 0) {
 | 
			
		||||
                        RD = cpu->CP15[CP15(CP15_DOMAIN_ACCESS_CONTROL)];
 | 
			
		||||
                    } else if (CRn == 5 && CRm == 0 && OPCODE_2 == 0) {
 | 
			
		||||
                        RD = cpu->CP15[CP15(CP15_FAULT_STATUS)];
 | 
			
		||||
                    } else if (CRn == 5 && CRm == 0 && OPCODE_2 == 1) {
 | 
			
		||||
                        RD = cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)];
 | 
			
		||||
                    } else if (CRn == 6 && CRm == 0 && OPCODE_2 == 0) {
 | 
			
		||||
                        RD = cpu->CP15[CP15(CP15_FAULT_ADDRESS)];
 | 
			
		||||
                    } else if (CRn == 13) {
 | 
			
		||||
                        if(OPCODE_2 == 0) {
 | 
			
		||||
                            RD = CP15_REG(CP15_PID);
 | 
			
		||||
                        } else if(OPCODE_2 == 1) {
 | 
			
		||||
                            RD = CP15_REG(CP15_CONTEXT_ID);
 | 
			
		||||
                        } else if (OPCODE_2 == 2) {
 | 
			
		||||
                            RD = CP15_REG(CP15_THREAD_UPRW);
 | 
			
		||||
                        } else if(OPCODE_2 == 3) {
 | 
			
		||||
                            RD = Memory::KERNEL_MEMORY_VADDR;
 | 
			
		||||
                        } else if (OPCODE_2 == 4) {
 | 
			
		||||
                            if (InAPrivilegedMode(cpu))
 | 
			
		||||
                                RD = CP15_REG(CP15_THREAD_PRW);
 | 
			
		||||
                        } else {
 | 
			
		||||
                            LOG_ERROR(Core_ARM11, "mmu_mrr wrote UNKNOWN - reg %d", CRn);
 | 
			
		||||
                        }
 | 
			
		||||
                    } else {
 | 
			
		||||
                        LOG_ERROR(Core_ARM11, "mrc CRn=%d, CRm=%d, OP2=%d is not implemented", CRn, CRm, OPCODE_2);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                if (inst_cream->cp_num == 15)
 | 
			
		||||
                     RD = ReadCP15Register(cpu, CRn, OPCODE_1, CRm, OPCODE_2);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        cpu->Reg[15] += GET_INST_SIZE(cpu);
 | 
			
		||||
 | 
			
		||||
@ -15,7 +15,9 @@
 | 
			
		||||
    along with this program; if not, write to the Free Software
 | 
			
		||||
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
 | 
			
		||||
 | 
			
		||||
#include "core/mem_map.h"
 | 
			
		||||
#include "core/arm/skyeye_common/armdefs.h"
 | 
			
		||||
#include "core/arm/skyeye_common/arm_regformat.h"
 | 
			
		||||
 | 
			
		||||
// Unsigned sum of absolute difference
 | 
			
		||||
u8 ARMul_UnsignedAbsoluteDifference(u8 left, u8 right)
 | 
			
		||||
@ -207,3 +209,432 @@ bool InBigEndianMode(ARMul_State* cpu)
 | 
			
		||||
{
 | 
			
		||||
    return (cpu->Cpsr & (1 << 9)) != 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Whether or not the given CPU is in a mode other than user mode.
 | 
			
		||||
bool InAPrivilegedMode(ARMul_State* cpu)
 | 
			
		||||
{
 | 
			
		||||
    return (cpu->Mode != USER32MODE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Reads from the CP15 registers. Used with implementation of the MRC instruction.
 | 
			
		||||
// Note that since the 3DS does not have the hypervisor extensions, these registers
 | 
			
		||||
// are not implemented.
 | 
			
		||||
u32 ReadCP15Register(ARMul_State* cpu, u32 crn, u32 opcode_1, u32 crm, u32 opcode_2)
 | 
			
		||||
{
 | 
			
		||||
    // Unprivileged registers
 | 
			
		||||
    if (crn == 13 && opcode_1 == 0 && crm == 0)
 | 
			
		||||
    {
 | 
			
		||||
        if (opcode_2 == 2)
 | 
			
		||||
            return cpu->CP15[CP15(CP15_THREAD_UPRW)];
 | 
			
		||||
 | 
			
		||||
        // TODO: Whenever TLS is implemented, this should return
 | 
			
		||||
        // "cpu->CP15[CP15(CP15_THREAD_URO)];"
 | 
			
		||||
        // which contains the address of the 0x200-byte TLS
 | 
			
		||||
        if (opcode_2 == 3)
 | 
			
		||||
            return Memory::KERNEL_MEMORY_VADDR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (InAPrivilegedMode(cpu))
 | 
			
		||||
    {
 | 
			
		||||
        if (crn == 0 && opcode_1 == 0)
 | 
			
		||||
        {
 | 
			
		||||
            if (crm == 0)
 | 
			
		||||
            {
 | 
			
		||||
                if (opcode_2 == 0)
 | 
			
		||||
                    return cpu->CP15[CP15(CP15_MAIN_ID)];
 | 
			
		||||
 | 
			
		||||
                if (opcode_2 == 1)
 | 
			
		||||
                    return cpu->CP15[CP15(CP15_CACHE_TYPE)];
 | 
			
		||||
 | 
			
		||||
                if (opcode_2 == 3)
 | 
			
		||||
                    return cpu->CP15[CP15(CP15_TLB_TYPE)];
 | 
			
		||||
 | 
			
		||||
                if (opcode_2 == 5)
 | 
			
		||||
                    return cpu->CP15[CP15(CP15_CPU_ID)];
 | 
			
		||||
            }
 | 
			
		||||
            else if (crm == 1)
 | 
			
		||||
            {
 | 
			
		||||
                if (opcode_2 == 0)
 | 
			
		||||
                    return cpu->CP15[CP15(CP15_PROCESSOR_FEATURE_0)];
 | 
			
		||||
 | 
			
		||||
                if (opcode_2 == 1)
 | 
			
		||||
                    return cpu->CP15[CP15(CP15_PROCESSOR_FEATURE_1)];
 | 
			
		||||
 | 
			
		||||
                if (opcode_2 == 2)
 | 
			
		||||
                    return cpu->CP15[CP15(CP15_DEBUG_FEATURE_0)];
 | 
			
		||||
 | 
			
		||||
                if (opcode_2 == 4)
 | 
			
		||||
                    return cpu->CP15[CP15(CP15_MEMORY_MODEL_FEATURE_0)];
 | 
			
		||||
 | 
			
		||||
                if (opcode_2 == 5)
 | 
			
		||||
                    return cpu->CP15[CP15(CP15_MEMORY_MODEL_FEATURE_1)];
 | 
			
		||||
 | 
			
		||||
                if (opcode_2 == 6)
 | 
			
		||||
                    return cpu->CP15[CP15(CP15_MEMORY_MODEL_FEATURE_2)];
 | 
			
		||||
 | 
			
		||||
                if (opcode_2 == 7)
 | 
			
		||||
                    return cpu->CP15[CP15(CP15_MEMORY_MODEL_FEATURE_3)];
 | 
			
		||||
            }
 | 
			
		||||
            else if (crm == 2)
 | 
			
		||||
            {
 | 
			
		||||
                if (opcode_2 == 0)
 | 
			
		||||
                    return cpu->CP15[CP15(CP15_ISA_FEATURE_0)];
 | 
			
		||||
 | 
			
		||||
                if (opcode_2 == 1)
 | 
			
		||||
                    return cpu->CP15[CP15(CP15_ISA_FEATURE_1)];
 | 
			
		||||
 | 
			
		||||
                if (opcode_2 == 2)
 | 
			
		||||
                    return cpu->CP15[CP15(CP15_ISA_FEATURE_2)];
 | 
			
		||||
 | 
			
		||||
                if (opcode_2 == 3)
 | 
			
		||||
                    return cpu->CP15[CP15(CP15_ISA_FEATURE_3)];
 | 
			
		||||
 | 
			
		||||
                if (opcode_2 == 4)
 | 
			
		||||
                    return cpu->CP15[CP15(CP15_ISA_FEATURE_4)];
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (crn == 1 && opcode_1 == 0 && crm == 0)
 | 
			
		||||
        {
 | 
			
		||||
            if (opcode_2 == 0)
 | 
			
		||||
                return cpu->CP15[CP15(CP15_CONTROL)];
 | 
			
		||||
 | 
			
		||||
            if (opcode_2 == 1)
 | 
			
		||||
                return cpu->CP15[CP15(CP15_AUXILIARY_CONTROL)];
 | 
			
		||||
 | 
			
		||||
            if (opcode_2 == 2)
 | 
			
		||||
                return cpu->CP15[CP15(CP15_COPROCESSOR_ACCESS_CONTROL)];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (crn == 2 && opcode_1 == 0 && crm == 0)
 | 
			
		||||
        {
 | 
			
		||||
            if (opcode_2 == 0)
 | 
			
		||||
                return cpu->CP15[CP15(CP15_TRANSLATION_BASE_TABLE_0)];
 | 
			
		||||
 | 
			
		||||
            if (opcode_2 == 1)
 | 
			
		||||
                return cpu->CP15[CP15(CP15_TRANSLATION_BASE_TABLE_1)];
 | 
			
		||||
 | 
			
		||||
            if (opcode_2 == 2)
 | 
			
		||||
                return cpu->CP15[CP15(CP15_TRANSLATION_BASE_CONTROL)];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (crn == 3 && opcode_1 == 0 && crm == 0 && opcode_2 == 0)
 | 
			
		||||
            return cpu->CP15[CP15(CP15_DOMAIN_ACCESS_CONTROL)];
 | 
			
		||||
 | 
			
		||||
        if (crn == 5 && opcode_1 == 0 && crm == 0)
 | 
			
		||||
        {
 | 
			
		||||
            if (opcode_2 == 0)
 | 
			
		||||
                return cpu->CP15[CP15(CP15_FAULT_STATUS)];
 | 
			
		||||
 | 
			
		||||
            if (opcode_2 == 1)
 | 
			
		||||
                return cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (crn == 6 && opcode_1 == 0 && crm == 0)
 | 
			
		||||
        {
 | 
			
		||||
            if (opcode_2 == 0)
 | 
			
		||||
                return cpu->CP15[CP15(CP15_FAULT_ADDRESS)];
 | 
			
		||||
 | 
			
		||||
            if (opcode_2 == 1)
 | 
			
		||||
                return cpu->CP15[CP15(CP15_WFAR)];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (crn == 7 && opcode_1 == 0 && crm == 4 && opcode_2 == 0)
 | 
			
		||||
            return cpu->CP15[CP15(CP15_PHYS_ADDRESS)];
 | 
			
		||||
 | 
			
		||||
        if (crn == 9 && opcode_1 == 0 && crm == 0 && opcode_2 == 0)
 | 
			
		||||
            return cpu->CP15[CP15(CP15_DATA_CACHE_LOCKDOWN)];
 | 
			
		||||
 | 
			
		||||
        if (crn == 10 && opcode_1 == 0)
 | 
			
		||||
        {
 | 
			
		||||
            if (crm == 0 && opcode_2 == 0)
 | 
			
		||||
                return cpu->CP15[CP15(CP15_TLB_LOCKDOWN)];
 | 
			
		||||
 | 
			
		||||
            if (crm == 2)
 | 
			
		||||
            {
 | 
			
		||||
                if (opcode_2 == 0)
 | 
			
		||||
                    return cpu->CP15[CP15(CP15_PRIMARY_REGION_REMAP)];
 | 
			
		||||
 | 
			
		||||
                if (opcode_2 == 1)
 | 
			
		||||
                    return cpu->CP15[CP15(CP15_NORMAL_REGION_REMAP)];
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (crn == 13 && crm == 0)
 | 
			
		||||
        {
 | 
			
		||||
            if (opcode_2 == 0)
 | 
			
		||||
                return cpu->CP15[CP15(CP15_PID)];
 | 
			
		||||
 | 
			
		||||
            if (opcode_2 == 1)
 | 
			
		||||
                return cpu->CP15[CP15(CP15_CONTEXT_ID)];
 | 
			
		||||
 | 
			
		||||
            if (opcode_2 == 4)
 | 
			
		||||
                return cpu->CP15[CP15(CP15_THREAD_PRW)];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (crn == 15)
 | 
			
		||||
        {
 | 
			
		||||
            if (opcode_1 == 0 && crm == 12)
 | 
			
		||||
            {
 | 
			
		||||
                if (opcode_2 == 0)
 | 
			
		||||
                    return cpu->CP15[CP15(CP15_PERFORMANCE_MONITOR_CONTROL)];
 | 
			
		||||
 | 
			
		||||
                if (opcode_2 == 1)
 | 
			
		||||
                    return cpu->CP15[CP15(CP15_CYCLE_COUNTER)];
 | 
			
		||||
 | 
			
		||||
                if (opcode_2 == 2)
 | 
			
		||||
                    return cpu->CP15[CP15(CP15_COUNT_0)];
 | 
			
		||||
 | 
			
		||||
                if (opcode_2 == 3)
 | 
			
		||||
                    return cpu->CP15[CP15(CP15_COUNT_1)];
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (opcode_1 == 5 && opcode_2 == 2)
 | 
			
		||||
            {
 | 
			
		||||
                if (crm == 5)
 | 
			
		||||
                    return cpu->CP15[CP15(CP15_MAIN_TLB_LOCKDOWN_VIRT_ADDRESS)];
 | 
			
		||||
 | 
			
		||||
                if (crm == 6)
 | 
			
		||||
                    return cpu->CP15[CP15(CP15_MAIN_TLB_LOCKDOWN_PHYS_ADDRESS)];
 | 
			
		||||
 | 
			
		||||
                if (crm == 7)
 | 
			
		||||
                    return cpu->CP15[CP15(CP15_MAIN_TLB_LOCKDOWN_ATTRIBUTE)];
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (opcode_1 == 7 && crm == 1 && opcode_2 == 0)
 | 
			
		||||
                return cpu->CP15[CP15(CP15_TLB_DEBUG_CONTROL)];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    LOG_ERROR(Core_ARM11, "MRC CRn=%u, CRm=%u, OP1=%u OP2=%u is not implemented. Returning zero.", crn, crm, opcode_1, opcode_2);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Write to the CP15 registers. Used with implementation of the MCR instruction.
 | 
			
		||||
// Note that since the 3DS does not have the hypervisor extensions, these registers
 | 
			
		||||
// are not implemented.
 | 
			
		||||
void WriteCP15Register(ARMul_State* cpu, u32 value, u32 crn, u32 opcode_1, u32 crm, u32 opcode_2)
 | 
			
		||||
{
 | 
			
		||||
    if (InAPrivilegedMode(cpu))
 | 
			
		||||
    {
 | 
			
		||||
        if (crn == 1 && opcode_1 == 0 && crm == 0)
 | 
			
		||||
        {
 | 
			
		||||
            if (opcode_2 == 0)
 | 
			
		||||
                cpu->CP15[CP15(CP15_CONTROL)] = value;
 | 
			
		||||
            else if (opcode_2 == 1)
 | 
			
		||||
                cpu->CP15[CP15(CP15_AUXILIARY_CONTROL)] = value;
 | 
			
		||||
            else if (opcode_2 == 2)
 | 
			
		||||
                cpu->CP15[CP15(CP15_COPROCESSOR_ACCESS_CONTROL)] = value;
 | 
			
		||||
        }
 | 
			
		||||
        else if (crn == 2 && opcode_1 == 0 && crm == 0)
 | 
			
		||||
        {
 | 
			
		||||
            if (opcode_2 == 0)
 | 
			
		||||
                cpu->CP15[CP15(CP15_TRANSLATION_BASE_TABLE_0)] = value;
 | 
			
		||||
            else if (opcode_2 == 1)
 | 
			
		||||
                cpu->CP15[CP15(CP15_TRANSLATION_BASE_TABLE_1)] = value;
 | 
			
		||||
            else if (opcode_2 == 2)
 | 
			
		||||
                cpu->CP15[CP15(CP15_TRANSLATION_BASE_CONTROL)] = value;
 | 
			
		||||
        }
 | 
			
		||||
        else if (crn == 3 && opcode_1 == 0 && crm == 0 && opcode_2 == 0)
 | 
			
		||||
        {
 | 
			
		||||
            cpu->CP15[CP15(CP15_DOMAIN_ACCESS_CONTROL)] = value;
 | 
			
		||||
        }
 | 
			
		||||
        else if (crn == 5 && opcode_1 == 0 && crm == 0)
 | 
			
		||||
        {
 | 
			
		||||
            if (opcode_2 == 0)
 | 
			
		||||
                cpu->CP15[CP15(CP15_FAULT_STATUS)] = value;
 | 
			
		||||
            else if (opcode_2 == 1)
 | 
			
		||||
                cpu->CP15[CP15(CP15_INSTR_FAULT_STATUS)] = value;
 | 
			
		||||
        }
 | 
			
		||||
        else if (crn == 6 && opcode_1 == 0 && crm == 0)
 | 
			
		||||
        {
 | 
			
		||||
            if (opcode_2 == 0)
 | 
			
		||||
                cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = value;
 | 
			
		||||
            else if (opcode_2 == 1)
 | 
			
		||||
                cpu->CP15[CP15(CP15_WFAR)] = value;
 | 
			
		||||
        }
 | 
			
		||||
        else if (crn == 7 && opcode_1 == 0)
 | 
			
		||||
        {
 | 
			
		||||
            LOG_WARNING(Core_ARM11, "Cache operations are not fully implemented.");
 | 
			
		||||
 | 
			
		||||
            if (crm == 0 && opcode_2 == 4)
 | 
			
		||||
            {
 | 
			
		||||
                cpu->CP15[CP15(CP15_WAIT_FOR_INTERRUPT)] = value;
 | 
			
		||||
            }
 | 
			
		||||
            else if (crm == 4 && opcode_2 == 0)
 | 
			
		||||
            {
 | 
			
		||||
                // NOTE: Not entirely accurate. This should do permission checks.
 | 
			
		||||
                cpu->CP15[CP15(CP15_PHYS_ADDRESS)] = Memory::VirtualToPhysicalAddress(value);
 | 
			
		||||
            }
 | 
			
		||||
            else if (crm == 5)
 | 
			
		||||
            {
 | 
			
		||||
                if (opcode_2 == 0)
 | 
			
		||||
                    cpu->CP15[CP15(CP15_INVALIDATE_INSTR_CACHE)] = value;
 | 
			
		||||
                else if (opcode_2 == 1)
 | 
			
		||||
                    cpu->CP15[CP15(CP15_INVALIDATE_INSTR_CACHE_USING_MVA)] = value;
 | 
			
		||||
                else if (opcode_2 == 2)
 | 
			
		||||
                    cpu->CP15[CP15(CP15_INVALIDATE_INSTR_CACHE_USING_INDEX)] = value;
 | 
			
		||||
                else if (opcode_2 == 6)
 | 
			
		||||
                    cpu->CP15[CP15(CP15_FLUSH_BRANCH_TARGET_CACHE)] = value;
 | 
			
		||||
                else if (opcode_2 == 7)
 | 
			
		||||
                    cpu->CP15[CP15(CP15_FLUSH_BRANCH_TARGET_CACHE_ENTRY)] = value;
 | 
			
		||||
            }
 | 
			
		||||
            else if (crm == 6)
 | 
			
		||||
            {
 | 
			
		||||
                if (opcode_2 == 0)
 | 
			
		||||
                    cpu->CP15[CP15(CP15_INVALIDATE_DATA_CACHE)] = value;
 | 
			
		||||
                else if (opcode_2 == 1)
 | 
			
		||||
                    cpu->CP15[CP15(CP15_INVALIDATE_DATA_CACHE_LINE_USING_MVA)] = value;
 | 
			
		||||
                else if (opcode_2 == 2)
 | 
			
		||||
                    cpu->CP15[CP15(CP15_INVALIDATE_DATA_CACHE_LINE_USING_INDEX)] = value;
 | 
			
		||||
            }
 | 
			
		||||
            else if (crm == 7 && opcode_2 == 0)
 | 
			
		||||
            {
 | 
			
		||||
                cpu->CP15[CP15(CP15_INVALIDATE_DATA_AND_INSTR_CACHE)] = value;
 | 
			
		||||
            }
 | 
			
		||||
            else if (crm == 10)
 | 
			
		||||
            {
 | 
			
		||||
                if (opcode_2 == 0)
 | 
			
		||||
                    cpu->CP15[CP15(CP15_CLEAN_DATA_CACHE)] = value;
 | 
			
		||||
                else if (opcode_2 == 1)
 | 
			
		||||
                    cpu->CP15[CP15(CP15_CLEAN_DATA_CACHE_LINE_USING_MVA)] = value;
 | 
			
		||||
                else if (opcode_2 == 2)
 | 
			
		||||
                    cpu->CP15[CP15(CP15_CLEAN_DATA_CACHE_LINE_USING_INDEX)] = value;
 | 
			
		||||
            }
 | 
			
		||||
            else if (crm == 14)
 | 
			
		||||
            {
 | 
			
		||||
                if (opcode_2 == 0)
 | 
			
		||||
                    cpu->CP15[CP15(CP15_CLEAN_AND_INVALIDATE_DATA_CACHE)] = value;
 | 
			
		||||
                else if (opcode_2 == 1)
 | 
			
		||||
                    cpu->CP15[CP15(CP15_CLEAN_AND_INVALIDATE_DATA_CACHE_LINE_USING_MVA)] = value;
 | 
			
		||||
                else if (opcode_2 == 2)
 | 
			
		||||
                    cpu->CP15[CP15(CP15_CLEAN_AND_INVALIDATE_DATA_CACHE_LINE_USING_INDEX)] = value;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else if (crn == 8 && opcode_1 == 0)
 | 
			
		||||
        {
 | 
			
		||||
            LOG_WARNING(Core_ARM11, "TLB operations not fully implemented.");
 | 
			
		||||
 | 
			
		||||
            if (crm == 5)
 | 
			
		||||
            {
 | 
			
		||||
                if (opcode_2 == 0)
 | 
			
		||||
                    cpu->CP15[CP15(CP15_INVALIDATE_ITLB)] = value;
 | 
			
		||||
                else if (opcode_2 == 1)
 | 
			
		||||
                    cpu->CP15[CP15(CP15_INVALIDATE_ITLB_SINGLE_ENTRY)] = value;
 | 
			
		||||
                else if (opcode_2 == 2)
 | 
			
		||||
                    cpu->CP15[CP15(CP15_INVALIDATE_ITLB_ENTRY_ON_ASID_MATCH)] = value;
 | 
			
		||||
                else if (opcode_2 == 3)
 | 
			
		||||
                    cpu->CP15[CP15(CP15_INVALIDATE_ITLB_ENTRY_ON_MVA)] = value;
 | 
			
		||||
            }
 | 
			
		||||
            else if (crm == 6)
 | 
			
		||||
            {
 | 
			
		||||
                if (opcode_2 == 0)
 | 
			
		||||
                    cpu->CP15[CP15(CP15_INVALIDATE_DTLB)] = value;
 | 
			
		||||
                else if (opcode_2 == 1)
 | 
			
		||||
                    cpu->CP15[CP15(CP15_INVALIDATE_DTLB_SINGLE_ENTRY)] = value;
 | 
			
		||||
                else if (opcode_2 == 2)
 | 
			
		||||
                    cpu->CP15[CP15(CP15_INVALIDATE_DTLB_ENTRY_ON_ASID_MATCH)] = value;
 | 
			
		||||
                else if (opcode_2 == 3)
 | 
			
		||||
                    cpu->CP15[CP15(CP15_INVALIDATE_DTLB_ENTRY_ON_MVA)] = value;
 | 
			
		||||
            }
 | 
			
		||||
            else if (crm == 7)
 | 
			
		||||
            {
 | 
			
		||||
                if (opcode_2 == 0)
 | 
			
		||||
                    cpu->CP15[CP15(CP15_INVALIDATE_UTLB)] = value;
 | 
			
		||||
                else if (opcode_2 == 1)
 | 
			
		||||
                    cpu->CP15[CP15(CP15_INVALIDATE_UTLB_SINGLE_ENTRY)] = value;
 | 
			
		||||
                else if (opcode_2 == 2)
 | 
			
		||||
                    cpu->CP15[CP15(CP15_INVALIDATE_UTLB_ENTRY_ON_ASID_MATCH)] = value;
 | 
			
		||||
                else if (opcode_2 == 3)
 | 
			
		||||
                    cpu->CP15[CP15(CP15_INVALIDATE_UTLB_ENTRY_ON_MVA)] = value;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else if (crn == 9 && opcode_1 == 0 && crm == 0 && opcode_2 == 0)
 | 
			
		||||
        {
 | 
			
		||||
            cpu->CP15[CP15(CP15_DATA_CACHE_LOCKDOWN)] = value;
 | 
			
		||||
        }
 | 
			
		||||
        else if (crn == 10 && opcode_1 == 0)
 | 
			
		||||
        {
 | 
			
		||||
            if (crm == 0 && opcode_2 == 0)
 | 
			
		||||
            {
 | 
			
		||||
                cpu->CP15[CP15(CP15_TLB_LOCKDOWN)] = value;
 | 
			
		||||
            }
 | 
			
		||||
            else if (crm == 2)
 | 
			
		||||
            {
 | 
			
		||||
                if (opcode_2 == 0)
 | 
			
		||||
                    cpu->CP15[CP15(CP15_PRIMARY_REGION_REMAP)] = value;
 | 
			
		||||
                else if (opcode_2 == 1)
 | 
			
		||||
                    cpu->CP15[CP15(CP15_NORMAL_REGION_REMAP)] = value;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else if (crn == 13 && opcode_1 == 0 && crm == 0)
 | 
			
		||||
        {
 | 
			
		||||
            if (opcode_2 == 0)
 | 
			
		||||
                cpu->CP15[CP15(CP15_PID)] = value;
 | 
			
		||||
            else if (opcode_2 == 1)
 | 
			
		||||
                cpu->CP15[CP15(CP15_CONTEXT_ID)] = value;
 | 
			
		||||
            else if (opcode_2 == 3)
 | 
			
		||||
                cpu->CP15[CP15(CP15_THREAD_URO)] = value;
 | 
			
		||||
            else if (opcode_2 == 4)
 | 
			
		||||
                cpu->CP15[CP15(CP15_THREAD_PRW)] = value;
 | 
			
		||||
        }
 | 
			
		||||
        else if (crn == 15)
 | 
			
		||||
        {
 | 
			
		||||
            if (opcode_1 == 0 && crm == 12)
 | 
			
		||||
            {
 | 
			
		||||
                if (opcode_2 == 0)
 | 
			
		||||
                    cpu->CP15[CP15(CP15_PERFORMANCE_MONITOR_CONTROL)] = value;
 | 
			
		||||
                else if (opcode_2 == 1)
 | 
			
		||||
                    cpu->CP15[CP15(CP15_CYCLE_COUNTER)] = value;
 | 
			
		||||
                else if (opcode_2 == 2)
 | 
			
		||||
                    cpu->CP15[CP15(CP15_COUNT_0)] = value;
 | 
			
		||||
                else if (opcode_2 == 3)
 | 
			
		||||
                    cpu->CP15[CP15(CP15_COUNT_1)] = value;
 | 
			
		||||
            }
 | 
			
		||||
            else if (opcode_1 == 5)
 | 
			
		||||
            {
 | 
			
		||||
                if (crm == 4)
 | 
			
		||||
                {
 | 
			
		||||
                    if (opcode_2 == 2)
 | 
			
		||||
                        cpu->CP15[CP15(CP15_READ_MAIN_TLB_LOCKDOWN_ENTRY)] = value;
 | 
			
		||||
                    else if (opcode_2 == 4)
 | 
			
		||||
                        cpu->CP15[CP15(CP15_WRITE_MAIN_TLB_LOCKDOWN_ENTRY)] = value;
 | 
			
		||||
                }
 | 
			
		||||
                else if (crm == 5 && opcode_2 == 2)
 | 
			
		||||
                {
 | 
			
		||||
                    cpu->CP15[CP15(CP15_MAIN_TLB_LOCKDOWN_VIRT_ADDRESS)] = value;
 | 
			
		||||
                }
 | 
			
		||||
                else if (crm == 6 && opcode_2 == 2)
 | 
			
		||||
                {
 | 
			
		||||
                    cpu->CP15[CP15(CP15_MAIN_TLB_LOCKDOWN_PHYS_ADDRESS)] = value;
 | 
			
		||||
                }
 | 
			
		||||
                else if (crm == 7 && opcode_2 == 2)
 | 
			
		||||
                {
 | 
			
		||||
                    cpu->CP15[CP15(CP15_MAIN_TLB_LOCKDOWN_ATTRIBUTE)] = value;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else if (opcode_1 == 7 && crm == 1 && opcode_2 == 0)
 | 
			
		||||
            {
 | 
			
		||||
                cpu->CP15[CP15(CP15_TLB_DEBUG_CONTROL)] = value;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Unprivileged registers
 | 
			
		||||
    if (crn == 7 && opcode_1 == 0 && crm == 5 && opcode_2 == 4)
 | 
			
		||||
    {
 | 
			
		||||
        cpu->CP15[CP15(CP15_FLUSH_PREFETCH_BUFFER)] = value;
 | 
			
		||||
    }
 | 
			
		||||
    else if (crn == 7 && opcode_1 == 0 && crm == 10)
 | 
			
		||||
    {
 | 
			
		||||
       if (opcode_2 == 4)
 | 
			
		||||
           cpu->CP15[CP15(CP15_DATA_SYNC_BARRIER)] = value;
 | 
			
		||||
       else if (opcode_2 == 5)
 | 
			
		||||
           cpu->CP15[CP15(CP15_DATA_MEMORY_BARRIER)] = value;
 | 
			
		||||
           
 | 
			
		||||
    }
 | 
			
		||||
    else if (crn == 13 && opcode_1 == 0 && crm == 0 && opcode_2 == 2)
 | 
			
		||||
    {
 | 
			
		||||
        cpu->CP15[CP15(CP15_THREAD_UPRW)] = value;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -50,6 +50,8 @@ enum {
 | 
			
		||||
    EXCLUSIVE_TAG,
 | 
			
		||||
    EXCLUSIVE_STATE,
 | 
			
		||||
    EXCLUSIVE_RESULT,
 | 
			
		||||
 | 
			
		||||
    // c0 - Information registers
 | 
			
		||||
    CP15_BASE,
 | 
			
		||||
    CP15_C0 = CP15_BASE,
 | 
			
		||||
    CP15_C0_C0 = CP15_C0,
 | 
			
		||||
@ -57,15 +59,30 @@ enum {
 | 
			
		||||
    CP15_CACHE_TYPE,
 | 
			
		||||
    CP15_TCM_STATUS,
 | 
			
		||||
    CP15_TLB_TYPE,
 | 
			
		||||
    CP15_CPU_ID,
 | 
			
		||||
    CP15_C0_C1,
 | 
			
		||||
    CP15_PROCESSOR_FEATURE_0 = CP15_C0_C1,
 | 
			
		||||
    CP15_PROCESSOR_FEATURE_1,
 | 
			
		||||
    CP15_DEBUG_FEATURE_0,
 | 
			
		||||
    CP15_AUXILIARY_FEATURE_0,
 | 
			
		||||
    CP15_MEMORY_MODEL_FEATURE_0,
 | 
			
		||||
    CP15_MEMORY_MODEL_FEATURE_1,
 | 
			
		||||
    CP15_MEMORY_MODEL_FEATURE_2,
 | 
			
		||||
    CP15_MEMORY_MODEL_FEATURE_3,
 | 
			
		||||
    CP15_C0_C2,
 | 
			
		||||
    CP15_ISA_FEATURE_0 = CP15_C0_C2,
 | 
			
		||||
    CP15_ISA_FEATURE_1,
 | 
			
		||||
    CP15_ISA_FEATURE_2,
 | 
			
		||||
    CP15_ISA_FEATURE_3,
 | 
			
		||||
    CP15_ISA_FEATURE_4,
 | 
			
		||||
 | 
			
		||||
    // c1 - Control registers
 | 
			
		||||
    CP15_C1_C0,
 | 
			
		||||
    CP15_CONTROL = CP15_C1_C0,
 | 
			
		||||
    CP15_AUXILIARY_CONTROL,
 | 
			
		||||
    CP15_COPROCESSOR_ACCESS_CONTROL,
 | 
			
		||||
 | 
			
		||||
    // c2 - Translation table registers
 | 
			
		||||
    CP15_C2,
 | 
			
		||||
    CP15_C2_C0 = CP15_C2,
 | 
			
		||||
    CP15_TRANSLATION_BASE = CP15_C2_C0,
 | 
			
		||||
@ -74,24 +91,87 @@ enum {
 | 
			
		||||
    CP15_TRANSLATION_BASE_CONTROL,
 | 
			
		||||
    CP15_DOMAIN_ACCESS_CONTROL,
 | 
			
		||||
    CP15_RESERVED,
 | 
			
		||||
    /* Fault status */
 | 
			
		||||
 | 
			
		||||
    // c5 - Fault status registers
 | 
			
		||||
    CP15_FAULT_STATUS,
 | 
			
		||||
    CP15_INSTR_FAULT_STATUS,
 | 
			
		||||
    CP15_COMBINED_DATA_FSR = CP15_FAULT_STATUS,
 | 
			
		||||
    CP15_INST_FSR,
 | 
			
		||||
    /* Fault Address register */
 | 
			
		||||
 | 
			
		||||
    // c6 - Fault Address registers
 | 
			
		||||
    CP15_FAULT_ADDRESS,
 | 
			
		||||
    CP15_COMBINED_DATA_FAR = CP15_FAULT_ADDRESS,
 | 
			
		||||
    CP15_WFAR,
 | 
			
		||||
    CP15_IFAR,
 | 
			
		||||
 | 
			
		||||
    // c7 - Cache operation registers
 | 
			
		||||
    CP15_WAIT_FOR_INTERRUPT,
 | 
			
		||||
    CP15_PHYS_ADDRESS,
 | 
			
		||||
    CP15_INVALIDATE_INSTR_CACHE,
 | 
			
		||||
    CP15_INVALIDATE_INSTR_CACHE_USING_MVA,
 | 
			
		||||
    CP15_INVALIDATE_INSTR_CACHE_USING_INDEX,
 | 
			
		||||
    CP15_FLUSH_PREFETCH_BUFFER,
 | 
			
		||||
    CP15_FLUSH_BRANCH_TARGET_CACHE,
 | 
			
		||||
    CP15_FLUSH_BRANCH_TARGET_CACHE_ENTRY,
 | 
			
		||||
    CP15_INVALIDATE_DATA_CACHE,
 | 
			
		||||
    CP15_INVALIDATE_DATA_CACHE_LINE_USING_MVA,
 | 
			
		||||
    CP15_INVALIDATE_DATA_CACHE_LINE_USING_INDEX,
 | 
			
		||||
    CP15_INVALIDATE_DATA_AND_INSTR_CACHE,
 | 
			
		||||
    CP15_CLEAN_DATA_CACHE,
 | 
			
		||||
    CP15_CLEAN_DATA_CACHE_LINE_USING_MVA,
 | 
			
		||||
    CP15_CLEAN_DATA_CACHE_LINE_USING_INDEX,
 | 
			
		||||
    CP15_DATA_SYNC_BARRIER,
 | 
			
		||||
    CP15_DATA_MEMORY_BARRIER,
 | 
			
		||||
    CP15_CLEAN_AND_INVALIDATE_DATA_CACHE,
 | 
			
		||||
    CP15_CLEAN_AND_INVALIDATE_DATA_CACHE_LINE_USING_MVA,
 | 
			
		||||
    CP15_CLEAN_AND_INVALIDATE_DATA_CACHE_LINE_USING_INDEX,
 | 
			
		||||
 | 
			
		||||
    // c8 - TLB operations
 | 
			
		||||
    CP15_INVALIDATE_ITLB,
 | 
			
		||||
    CP15_INVALIDATE_ITLB_SINGLE_ENTRY,
 | 
			
		||||
    CP15_INVALIDATE_ITLB_ENTRY_ON_ASID_MATCH,
 | 
			
		||||
    CP15_INVALIDATE_ITLB_ENTRY_ON_MVA,
 | 
			
		||||
    CP15_INVALIDATE_DTLB,
 | 
			
		||||
    CP15_INVALIDATE_DTLB_SINGLE_ENTRY,
 | 
			
		||||
    CP15_INVALIDATE_DTLB_ENTRY_ON_ASID_MATCH,
 | 
			
		||||
    CP15_INVALIDATE_DTLB_ENTRY_ON_MVA,
 | 
			
		||||
    CP15_INVALIDATE_UTLB,
 | 
			
		||||
    CP15_INVALIDATE_UTLB_SINGLE_ENTRY,
 | 
			
		||||
    CP15_INVALIDATE_UTLB_ENTRY_ON_ASID_MATCH,
 | 
			
		||||
    CP15_INVALIDATE_UTLB_ENTRY_ON_MVA,
 | 
			
		||||
 | 
			
		||||
    // c9 - Data cache lockdown register
 | 
			
		||||
    CP15_DATA_CACHE_LOCKDOWN,
 | 
			
		||||
 | 
			
		||||
    // c10 - TLB/Memory map registers
 | 
			
		||||
    CP15_TLB_LOCKDOWN,
 | 
			
		||||
    CP15_PRIMARY_REGION_REMAP,
 | 
			
		||||
    CP15_NORMAL_REGION_REMAP,
 | 
			
		||||
 | 
			
		||||
    // c13 - Thread related registers
 | 
			
		||||
    CP15_PID,
 | 
			
		||||
    CP15_CONTEXT_ID,
 | 
			
		||||
    CP15_THREAD_UPRW, // Thread ID register - User/Privileged Read/Write
 | 
			
		||||
    CP15_THREAD_URO,  // Thread ID register - User Read Only (Privileged R/W)
 | 
			
		||||
    CP15_THREAD_PRW,  // Thread ID register - Privileged R/W only.
 | 
			
		||||
    CP15_TLB_FAULT_ADDR, /* defined by SkyEye */
 | 
			
		||||
    CP15_TLB_FAULT_STATUS, /* defined by SkyEye */
 | 
			
		||||
    /* VFP registers */
 | 
			
		||||
 | 
			
		||||
    // c15 - Performance and TLB lockdown registers
 | 
			
		||||
    CP15_PERFORMANCE_MONITOR_CONTROL,
 | 
			
		||||
    CP15_CYCLE_COUNTER,
 | 
			
		||||
    CP15_COUNT_0,
 | 
			
		||||
    CP15_COUNT_1,
 | 
			
		||||
    CP15_READ_MAIN_TLB_LOCKDOWN_ENTRY,
 | 
			
		||||
    CP15_WRITE_MAIN_TLB_LOCKDOWN_ENTRY,
 | 
			
		||||
    CP15_MAIN_TLB_LOCKDOWN_VIRT_ADDRESS,
 | 
			
		||||
    CP15_MAIN_TLB_LOCKDOWN_PHYS_ADDRESS,
 | 
			
		||||
    CP15_MAIN_TLB_LOCKDOWN_ATTRIBUTE,
 | 
			
		||||
    CP15_TLB_DEBUG_CONTROL,
 | 
			
		||||
 | 
			
		||||
    // Skyeye defined
 | 
			
		||||
    CP15_TLB_FAULT_ADDR,
 | 
			
		||||
    CP15_TLB_FAULT_STATUS,
 | 
			
		||||
 | 
			
		||||
    // VFP registers
 | 
			
		||||
    VFP_BASE,
 | 
			
		||||
    VFP_FPSID = VFP_BASE,
 | 
			
		||||
    VFP_FPSCR,
 | 
			
		||||
 | 
			
		||||
@ -357,3 +357,7 @@ extern u32 ARMul_SignedSatQ(s32, u8, bool*);
 | 
			
		||||
extern u32 ARMul_UnsignedSatQ(s32, u8, bool*);
 | 
			
		||||
 | 
			
		||||
extern bool InBigEndianMode(ARMul_State*);
 | 
			
		||||
extern bool InAPrivilegedMode(ARMul_State*);
 | 
			
		||||
 | 
			
		||||
extern u32 ReadCP15Register(ARMul_State* cpu, u32 crn, u32 opcode_1, u32 crm, u32 opcode_2);
 | 
			
		||||
extern void WriteCP15Register(ARMul_State* cpu, u32 value, u32 crn, u32 opcode_1, u32 crm, u32 opcode_2);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user