3 changed files with 234 additions and 0 deletions
-
2src/core/CMakeLists.txt
-
80src/core/arm/dynarmic/arm_dynarmic_cp15.cpp
-
152src/core/arm/dynarmic/arm_dynarmic_cp15.h
@ -0,0 +1,80 @@ |
|||
// Copyright 2017 Citra Emulator Project
|
|||
// Licensed under GPLv2 or any later version
|
|||
// Refer to the license.txt file included.
|
|||
|
|||
#include "core/arm/dynarmic/arm_dynarmic_cp15.h"
|
|||
|
|||
using Callback = Dynarmic::A32::Coprocessor::Callback; |
|||
using CallbackOrAccessOneWord = Dynarmic::A32::Coprocessor::CallbackOrAccessOneWord; |
|||
using CallbackOrAccessTwoWords = Dynarmic::A32::Coprocessor::CallbackOrAccessTwoWords; |
|||
|
|||
std::optional<Callback> DynarmicCP15::CompileInternalOperation(bool two, unsigned opc1, |
|||
CoprocReg CRd, CoprocReg CRn, |
|||
CoprocReg CRm, unsigned opc2) { |
|||
return {}; |
|||
} |
|||
|
|||
CallbackOrAccessOneWord DynarmicCP15::CompileSendOneWord(bool two, unsigned opc1, CoprocReg CRn, |
|||
CoprocReg CRm, unsigned opc2) { |
|||
// TODO(merry): Privileged CP15 registers
|
|||
|
|||
if (!two && CRn == CoprocReg::C7 && opc1 == 0 && CRm == CoprocReg::C5 && opc2 == 4) { |
|||
// This is a dummy write, we ignore the value written here.
|
|||
return &CP15[static_cast<std::size_t>(CP15Register::CP15_FLUSH_PREFETCH_BUFFER)]; |
|||
} |
|||
|
|||
if (!two && CRn == CoprocReg::C7 && opc1 == 0 && CRm == CoprocReg::C10) { |
|||
switch (opc2) { |
|||
case 4: |
|||
// This is a dummy write, we ignore the value written here.
|
|||
return &CP15[static_cast<std::size_t>(CP15Register::CP15_DATA_SYNC_BARRIER)]; |
|||
case 5: |
|||
// This is a dummy write, we ignore the value written here.
|
|||
return &CP15[static_cast<std::size_t>(CP15Register::CP15_DATA_MEMORY_BARRIER)]; |
|||
default: |
|||
return {}; |
|||
} |
|||
} |
|||
|
|||
if (!two && CRn == CoprocReg::C13 && opc1 == 0 && CRm == CoprocReg::C0 && opc2 == 2) { |
|||
return &CP15[static_cast<std::size_t>(CP15Register::CP15_THREAD_UPRW)]; |
|||
} |
|||
|
|||
return {}; |
|||
} |
|||
|
|||
CallbackOrAccessTwoWords DynarmicCP15::CompileSendTwoWords(bool two, unsigned opc, CoprocReg CRm) { |
|||
return {}; |
|||
} |
|||
|
|||
CallbackOrAccessOneWord DynarmicCP15::CompileGetOneWord(bool two, unsigned opc1, CoprocReg CRn, |
|||
CoprocReg CRm, unsigned opc2) { |
|||
// TODO(merry): Privileged CP15 registers
|
|||
|
|||
if (!two && CRn == CoprocReg::C13 && opc1 == 0 && CRm == CoprocReg::C0) { |
|||
switch (opc2) { |
|||
case 2: |
|||
return &CP15[static_cast<std::size_t>(CP15Register::CP15_THREAD_UPRW)]; |
|||
case 3: |
|||
return &CP15[static_cast<std::size_t>(CP15Register::CP15_THREAD_URO)]; |
|||
default: |
|||
return {}; |
|||
} |
|||
} |
|||
|
|||
return {}; |
|||
} |
|||
|
|||
CallbackOrAccessTwoWords DynarmicCP15::CompileGetTwoWords(bool two, unsigned opc, CoprocReg CRm) { |
|||
return {}; |
|||
} |
|||
|
|||
std::optional<Callback> DynarmicCP15::CompileLoadWords(bool two, bool long_transfer, CoprocReg CRd, |
|||
std::optional<u8> option) { |
|||
return {}; |
|||
} |
|||
|
|||
std::optional<Callback> DynarmicCP15::CompileStoreWords(bool two, bool long_transfer, CoprocReg CRd, |
|||
std::optional<u8> option) { |
|||
return {}; |
|||
} |
|||
@ -0,0 +1,152 @@ |
|||
// Copyright 2017 Citra Emulator Project |
|||
// Licensed under GPLv2 or any later version |
|||
// Refer to the license.txt file included. |
|||
|
|||
#pragma once |
|||
|
|||
#include <memory> |
|||
#include <optional> |
|||
|
|||
#include <dynarmic/A32/coprocessor.h> |
|||
#include "common/common_types.h" |
|||
|
|||
enum class CP15Register { |
|||
// c0 - Information registers |
|||
CP15_MAIN_ID, |
|||
CP15_CACHE_TYPE, |
|||
CP15_TCM_STATUS, |
|||
CP15_TLB_TYPE, |
|||
CP15_CPU_ID, |
|||
CP15_PROCESSOR_FEATURE_0, |
|||
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_ISA_FEATURE_0, |
|||
CP15_ISA_FEATURE_1, |
|||
CP15_ISA_FEATURE_2, |
|||
CP15_ISA_FEATURE_3, |
|||
CP15_ISA_FEATURE_4, |
|||
|
|||
// c1 - Control registers |
|||
CP15_CONTROL, |
|||
CP15_AUXILIARY_CONTROL, |
|||
CP15_COPROCESSOR_ACCESS_CONTROL, |
|||
|
|||
// c2 - Translation table registers |
|||
CP15_TRANSLATION_BASE_TABLE_0, |
|||
CP15_TRANSLATION_BASE_TABLE_1, |
|||
CP15_TRANSLATION_BASE_CONTROL, |
|||
CP15_DOMAIN_ACCESS_CONTROL, |
|||
CP15_RESERVED, |
|||
|
|||
// c5 - Fault status registers |
|||
CP15_FAULT_STATUS, |
|||
CP15_INSTR_FAULT_STATUS, |
|||
CP15_COMBINED_DATA_FSR = CP15_FAULT_STATUS, |
|||
CP15_INST_FSR, |
|||
|
|||
// 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. |
|||
|
|||
// 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, |
|||
|
|||
// Not an actual register. |
|||
// All registers should be defined above this. |
|||
CP15_REGISTER_COUNT, |
|||
}; |
|||
|
|||
class DynarmicCP15 final : public Dynarmic::A32::Coprocessor { |
|||
public: |
|||
using CoprocReg = Dynarmic::A32::CoprocReg; |
|||
|
|||
explicit DynarmicCP15(u32* cp15) : CP15(cp15){}; |
|||
|
|||
std::optional<Callback> CompileInternalOperation(bool two, unsigned opc1, CoprocReg CRd, |
|||
CoprocReg CRn, CoprocReg CRm, |
|||
unsigned opc2) override; |
|||
CallbackOrAccessOneWord CompileSendOneWord(bool two, unsigned opc1, CoprocReg CRn, |
|||
CoprocReg CRm, unsigned opc2) override; |
|||
CallbackOrAccessTwoWords CompileSendTwoWords(bool two, unsigned opc, CoprocReg CRm) override; |
|||
CallbackOrAccessOneWord CompileGetOneWord(bool two, unsigned opc1, CoprocReg CRn, CoprocReg CRm, |
|||
unsigned opc2) override; |
|||
CallbackOrAccessTwoWords CompileGetTwoWords(bool two, unsigned opc, CoprocReg CRm) override; |
|||
std::optional<Callback> CompileLoadWords(bool two, bool long_transfer, CoprocReg CRd, |
|||
std::optional<u8> option) override; |
|||
std::optional<Callback> CompileStoreWords(bool two, bool long_transfer, CoprocReg CRd, |
|||
std::optional<u8> option) override; |
|||
|
|||
private: |
|||
u32* CP15{}; |
|||
}; |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue