mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-26 07:39:45 -06:00
Merge pull request #11289 from AdmiralCurtiss/mmu-msi-ir
MMU: Use MSR.IR for Host instruction reads.
This commit is contained in:
@ -85,12 +85,12 @@ MMU::~MMU() = default;
|
|||||||
return Common::swap64(val);
|
return Common::swap64(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsOpcodeFlag(XCheckTLBFlag flag)
|
static constexpr bool IsOpcodeFlag(XCheckTLBFlag flag)
|
||||||
{
|
{
|
||||||
return flag == XCheckTLBFlag::Opcode || flag == XCheckTLBFlag::OpcodeNoException;
|
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;
|
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>
|
template <XCheckTLBFlag flag, typename T, bool never_translate>
|
||||||
T MMU::ReadFromHardware(u32 em_address)
|
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_start_page = em_address & ~HW_PAGE_MASK;
|
||||||
const u32 em_address_end_page = (em_address + sizeof(T) - 1) & ~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)
|
if (em_address_start_page != em_address_end_page)
|
||||||
@ -166,7 +172,8 @@ T MMU::ReadFromHardware(u32 em_address)
|
|||||||
|
|
||||||
bool wi = false;
|
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);
|
auto translated_addr = TranslateAddress<flag>(em_address);
|
||||||
if (!translated_addr.Success())
|
if (!translated_addr.Success())
|
||||||
@ -258,6 +265,8 @@ T MMU::ReadFromHardware(u32 em_address)
|
|||||||
template <XCheckTLBFlag flag, bool never_translate>
|
template <XCheckTLBFlag flag, bool never_translate>
|
||||||
void MMU::WriteToHardware(u32 em_address, const u32 data, const u32 size)
|
void MMU::WriteToHardware(u32 em_address, const u32 data, const u32 size)
|
||||||
{
|
{
|
||||||
|
static_assert(flag == XCheckTLBFlag::NoException || flag == XCheckTLBFlag::Write);
|
||||||
|
|
||||||
DEBUG_ASSERT(size <= 4);
|
DEBUG_ASSERT(size <= 4);
|
||||||
|
|
||||||
const u32 em_address_start_page = em_address & ~HW_PAGE_MASK;
|
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:
|
case RequestedAddressSpace::Effective:
|
||||||
{
|
{
|
||||||
const u32 value = mmu.ReadFromHardware<XCheckTLBFlag::OpcodeNoException, u32>(address);
|
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:
|
case RequestedAddressSpace::Physical:
|
||||||
{
|
{
|
||||||
@ -517,7 +526,7 @@ std::optional<ReadResult<u32>> MMU::HostTryReadInstruction(const Core::CPUThread
|
|||||||
}
|
}
|
||||||
case RequestedAddressSpace::Virtual:
|
case RequestedAddressSpace::Virtual:
|
||||||
{
|
{
|
||||||
if (!mmu.m_ppc_state.msr.DR)
|
if (!mmu.m_ppc_state.msr.IR)
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
const u32 value = mmu.ReadFromHardware<XCheckTLBFlag::OpcodeNoException, u32>(address);
|
const u32 value = mmu.ReadFromHardware<XCheckTLBFlag::OpcodeNoException, u32>(address);
|
||||||
return ReadResult<u32>(true, value);
|
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)
|
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)
|
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
|
// set the access bits
|
||||||
switch (flag)
|
switch (flag)
|
||||||
|
Reference in New Issue
Block a user