From 5d2fc0147ea0f998c34c85d9ef058fe98fef75ec Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Thu, 30 Nov 2023 22:17:10 +0100 Subject: [PATCH 1/4] MMU: Mark IsOpcodeFlag() and IsNoExceptionFlag() as constexpr. --- Source/Core/Core/PowerPC/MMU.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Core/Core/PowerPC/MMU.cpp b/Source/Core/Core/PowerPC/MMU.cpp index aa305fe0ab..db5d4a4b31 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; } From 0d6a0724fd946e6f9e25dc2f965d409eab3db741 Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Thu, 30 Nov 2023 22:15:50 +0100 Subject: [PATCH 2/4] MMU: Always use data read for the PTE lookup in TranslatePageAddress. --- Source/Core/Core/PowerPC/MMU.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Source/Core/Core/PowerPC/MMU.cpp b/Source/Core/Core/PowerPC/MMU.cpp index db5d4a4b31..6c85fc54ee 100644 --- a/Source/Core/Core/PowerPC/MMU.cpp +++ b/Source/Core/Core/PowerPC/MMU.cpp @@ -1464,11 +1464,13 @@ MMU::TranslateAddressResult MMU::TranslatePageAddress(const EffectiveAddress add for (int i = 0; i < 8; i++, pteg_addr += 8) { - const u32 pteg = ReadFromHardware(pteg_addr); + constexpr XCheckTLBFlag pte_read_flag = + IsNoExceptionFlag(flag) ? XCheckTLBFlag::NoException : XCheckTLBFlag::Read; + const u32 pteg = ReadFromHardware(pteg_addr); if (pte1.Hex == pteg) { - UPTE_Hi pte2(ReadFromHardware(pteg_addr + 4)); + UPTE_Hi pte2(ReadFromHardware(pteg_addr + 4)); // set the access bits switch (flag) From c12725c916caac69d33e1d5c040930eed9e9cb70 Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Thu, 30 Nov 2023 22:17:26 +0100 Subject: [PATCH 3/4] MMU: Assert that the given XCheckTLBFlag is valid for the operation. --- Source/Core/Core/PowerPC/MMU.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Source/Core/Core/PowerPC/MMU.cpp b/Source/Core/Core/PowerPC/MMU.cpp index 6c85fc54ee..a069d14073 100644 --- a/Source/Core/Core/PowerPC/MMU.cpp +++ b/Source/Core/Core/PowerPC/MMU.cpp @@ -148,6 +148,12 @@ static void EFB_Write(u32 data, u32 addr) template 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) @@ -258,6 +264,8 @@ T MMU::ReadFromHardware(u32 em_address) template 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; From a0da6788a36399f3e42a28dc6f1d5c28f549955c Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Sat, 19 Nov 2022 02:29:04 +0100 Subject: [PATCH 4/4] MMU: Use MSR.IR for instruction reads. --- Source/Core/Core/PowerPC/MMU.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Source/Core/Core/PowerPC/MMU.cpp b/Source/Core/Core/PowerPC/MMU.cpp index a069d14073..fdd370acc4 100644 --- a/Source/Core/Core/PowerPC/MMU.cpp +++ b/Source/Core/Core/PowerPC/MMU.cpp @@ -172,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(em_address); if (!translated_addr.Success()) @@ -516,7 +517,7 @@ std::optional> MMU::HostTryReadInstruction(const Core::CPUThread case RequestedAddressSpace::Effective: { const u32 value = mmu.ReadFromHardware(address); - return ReadResult(!!mmu.m_ppc_state.msr.DR, value); + return ReadResult(!!mmu.m_ppc_state.msr.IR, value); } case RequestedAddressSpace::Physical: { @@ -525,7 +526,7 @@ std::optional> 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(address); return ReadResult(true, value);