summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorMai <mai.iam2048@gmail.com>2023-12-10 09:06:05 -0500
committerGitHub <noreply@github.com>2023-12-10 09:06:05 -0500
commitfb0934de71fb525db3f06854a97eefb1b34aa735 (patch)
tree2d47afe1161068fe9e5dac4bc2be1df0a6830d02 /Source/Core
parentf284bfca4597ec7f648f3a244005e051ed25cfc5 (diff)
parenta0da6788a36399f3e42a28dc6f1d5c28f549955c (diff)
Merge pull request #11289 from AdmiralCurtiss/mmu-msi-ir
MMU: Use MSR.IR for Host instruction reads.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/PowerPC/MMU.cpp25
1 files changed, 18 insertions, 7 deletions
diff --git a/Source/Core/Core/PowerPC/MMU.cpp b/Source/Core/Core/PowerPC/MMU.cpp
index aa305fe0ab..fdd370acc4 100644
--- a/Source/Core/Core/PowerPC/MMU.cpp
+++ b/Source/Core/Core/PowerPC/MMU.cpp
@@ -85,12 +85,12 @@ MMU::~MMU() = default;
return Common::swap64(val);
}
-static bool IsOpcodeFlag(XCheckTLBFlag flag)
+static constexpr bool IsOpcodeFlag(XCheckTLBFlag flag)
{
return flag == XCheckTLBFlag::Opcode || flag == XCheckTLBFlag::OpcodeNoException;
}
-static bool IsNoExceptionFlag(XCheckTLBFlag flag)
+static constexpr bool IsNoExceptionFlag(XCheckTLBFlag flag)
{
return flag == XCheckTLBFlag::NoException || flag == XCheckTLBFlag::OpcodeNoException;
}
@@ -148,6 +148,12 @@ static void EFB_Write(u32 data, u32 addr)
template <XCheckTLBFlag flag, typename T, bool never_translate>
T MMU::ReadFromHardware(u32 em_address)
{
+ // ReadFromHardware is currently used with XCheckTLBFlag::OpcodeNoException by host instruction
+ // functions. Actual instruction decoding (which can raise exceptions and uses icache) is handled
+ // by TryReadInstruction.
+ static_assert(flag == XCheckTLBFlag::NoException || flag == XCheckTLBFlag::Read ||
+ flag == XCheckTLBFlag::OpcodeNoException);
+
const u32 em_address_start_page = em_address & ~HW_PAGE_MASK;
const u32 em_address_end_page = (em_address + sizeof(T) - 1) & ~HW_PAGE_MASK;
if (em_address_start_page != em_address_end_page)
@@ -166,7 +172,8 @@ T MMU::ReadFromHardware(u32 em_address)
bool wi = false;
- if (!never_translate && m_ppc_state.msr.DR)
+ if (!never_translate &&
+ (IsOpcodeFlag(flag) ? m_ppc_state.msr.IR.Value() : m_ppc_state.msr.DR.Value()))
{
auto translated_addr = TranslateAddress<flag>(em_address);
if (!translated_addr.Success())
@@ -258,6 +265,8 @@ T MMU::ReadFromHardware(u32 em_address)
template <XCheckTLBFlag flag, bool never_translate>
void MMU::WriteToHardware(u32 em_address, const u32 data, const u32 size)
{
+ static_assert(flag == XCheckTLBFlag::NoException || flag == XCheckTLBFlag::Write);
+
DEBUG_ASSERT(size <= 4);
const u32 em_address_start_page = em_address & ~HW_PAGE_MASK;
@@ -508,7 +517,7 @@ std::optional<ReadResult<u32>> MMU::HostTryReadInstruction(const Core::CPUThread
case RequestedAddressSpace::Effective:
{
const u32 value = mmu.ReadFromHardware<XCheckTLBFlag::OpcodeNoException, u32>(address);
- return ReadResult<u32>(!!mmu.m_ppc_state.msr.DR, value);
+ return ReadResult<u32>(!!mmu.m_ppc_state.msr.IR, value);
}
case RequestedAddressSpace::Physical:
{
@@ -517,7 +526,7 @@ std::optional<ReadResult<u32>> MMU::HostTryReadInstruction(const Core::CPUThread
}
case RequestedAddressSpace::Virtual:
{
- if (!mmu.m_ppc_state.msr.DR)
+ if (!mmu.m_ppc_state.msr.IR)
return std::nullopt;
const u32 value = mmu.ReadFromHardware<XCheckTLBFlag::OpcodeNoException, u32>(address);
return ReadResult<u32>(true, value);
@@ -1464,11 +1473,13 @@ MMU::TranslateAddressResult MMU::TranslatePageAddress(const EffectiveAddress add
for (int i = 0; i < 8; i++, pteg_addr += 8)
{
- const u32 pteg = ReadFromHardware<flag, u32, true>(pteg_addr);
+ constexpr XCheckTLBFlag pte_read_flag =
+ IsNoExceptionFlag(flag) ? XCheckTLBFlag::NoException : XCheckTLBFlag::Read;
+ const u32 pteg = ReadFromHardware<pte_read_flag, u32, true>(pteg_addr);
if (pte1.Hex == pteg)
{
- UPTE_Hi pte2(ReadFromHardware<flag, u32, true>(pteg_addr + 4));
+ UPTE_Hi pte2(ReadFromHardware<pte_read_flag, u32, true>(pteg_addr + 4));
// set the access bits
switch (flag)