Bus: Protect main RAM buffer
Get rid of write-time checks.
This commit is contained in:
parent
79e1ae3e54
commit
a062b00c1a
|
@ -3009,7 +3009,7 @@ unsigned int Achievements::RAIntegration::RACallbackReadMemoryBlock(unsigned int
|
|||
return 0;
|
||||
|
||||
const u32 copy_size = std::min<u32>(Bus::g_ram_size - nAddress, nBytes);
|
||||
std::memcpy(pBuffer, Bus::g_ram + nAddress, copy_size);
|
||||
std::memcpy(pBuffer, Bus::g_unprotected_ram + nAddress, copy_size);
|
||||
return copy_size;
|
||||
}
|
||||
|
||||
|
|
102
src/core/bus.cpp
102
src/core/bus.cpp
|
@ -37,6 +37,7 @@ Log_SetChannel(Bus);
|
|||
// TODO: Get rid of page code bits, instead use page faults to track SMC.
|
||||
|
||||
// Exports for external debugger access
|
||||
#ifndef __ANDROID__
|
||||
namespace Exports {
|
||||
|
||||
extern "C" {
|
||||
|
@ -50,6 +51,7 @@ __attribute__((visibility("default"), used)) u32 RAM_SIZE, RAM_MASK;
|
|||
}
|
||||
|
||||
} // namespace Exports
|
||||
#endif
|
||||
|
||||
namespace Bus {
|
||||
|
||||
|
@ -105,6 +107,7 @@ static void* s_shmem_handle = nullptr;
|
|||
|
||||
std::bitset<RAM_8MB_CODE_PAGE_COUNT> g_ram_code_bits{};
|
||||
u8* g_ram = nullptr;
|
||||
u8* g_unprotected_ram = nullptr;
|
||||
u32 g_ram_size = 0;
|
||||
u32 g_ram_mask = 0;
|
||||
u8* g_bios = nullptr;
|
||||
|
@ -132,16 +135,13 @@ static std::vector<std::pair<u8*, size_t>> s_fastmem_ram_views;
|
|||
#endif
|
||||
|
||||
static u8** s_fastmem_lut = nullptr;
|
||||
static constexpr const std::array s_fastmem_ram_mirrors = {0x00000000u, 0x00200000u, 0x00400000u, 0x00600000u,
|
||||
0x80000000u, 0x80200000u, 0x80400000u, 0x80600000u,
|
||||
0xA0000000u, 0xA0200000u, 0xA0400000u, 0xA0600000u};
|
||||
|
||||
static void SetRAMSize(bool enable_8mb_ram);
|
||||
|
||||
static std::tuple<TickCount, TickCount, TickCount> CalculateMemoryTiming(MEMDELAY mem_delay, COMDELAY common_delay);
|
||||
static void RecalculateMemoryTimings();
|
||||
|
||||
static void SetCodePageFastmemProtection(u32 page_index, bool writable);
|
||||
static void SetRAMPageWritable(u32 page_index, bool writable);
|
||||
|
||||
static void SetHandlers();
|
||||
|
||||
|
@ -182,7 +182,9 @@ bool Bus::AllocateMemory()
|
|||
|
||||
g_ram = static_cast<u8*>(MemMap::MapSharedMemory(s_shmem_handle, MemoryMap::RAM_OFFSET, nullptr, MemoryMap::RAM_SIZE,
|
||||
PageProtect::ReadWrite));
|
||||
if (!g_ram)
|
||||
g_unprotected_ram = static_cast<u8*>(MemMap::MapSharedMemory(s_shmem_handle, MemoryMap::RAM_OFFSET, nullptr,
|
||||
MemoryMap::RAM_SIZE, PageProtect::ReadWrite));
|
||||
if (!g_ram || !g_unprotected_ram)
|
||||
{
|
||||
Host::ReportErrorAsync("Error", "Failed to map memory for RAM");
|
||||
ReleaseMemory();
|
||||
|
@ -227,11 +229,21 @@ bool Bus::AllocateMemory()
|
|||
Log_InfoPrintf("Fastmem base: %p", s_fastmem_arena.BasePointer());
|
||||
#endif
|
||||
|
||||
#ifndef __ANDROID__
|
||||
Exports::RAM = reinterpret_cast<uintptr_t>(g_unprotected_ram);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Bus::ReleaseMemory()
|
||||
{
|
||||
#ifndef __ANDROID__
|
||||
Exports::RAM = 0;
|
||||
Exports::RAM_SIZE = 0;
|
||||
Exports::RAM_MASK = 0;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_MMAP_FASTMEM
|
||||
DebugAssert(s_fastmem_ram_views.empty());
|
||||
s_fastmem_arena.Destroy();
|
||||
|
@ -253,6 +265,12 @@ void Bus::ReleaseMemory()
|
|||
g_bios = nullptr;
|
||||
}
|
||||
|
||||
if (g_unprotected_ram)
|
||||
{
|
||||
MemMap::UnmapSharedMemory(g_unprotected_ram, MemoryMap::RAM_SIZE);
|
||||
g_unprotected_ram = nullptr;
|
||||
}
|
||||
|
||||
if (g_ram)
|
||||
{
|
||||
MemMap::UnmapSharedMemory(g_ram, MemoryMap::RAM_SIZE);
|
||||
|
@ -278,9 +296,10 @@ void Bus::SetRAMSize(bool enable_8mb_ram)
|
|||
g_ram_size = enable_8mb_ram ? RAM_8MB_SIZE : RAM_2MB_SIZE;
|
||||
g_ram_mask = enable_8mb_ram ? RAM_8MB_MASK : RAM_2MB_MASK;
|
||||
|
||||
Exports::RAM = reinterpret_cast<uintptr_t>(g_ram);
|
||||
#ifndef __ANDROID__
|
||||
Exports::RAM_SIZE = g_ram_size;
|
||||
Exports::RAM_MASK = g_ram_mask;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Bus::Shutdown()
|
||||
|
@ -291,9 +310,11 @@ void Bus::Shutdown()
|
|||
g_ram_mask = 0;
|
||||
g_ram_size = 0;
|
||||
|
||||
#ifndef __ANDROID__
|
||||
Exports::RAM = 0;
|
||||
Exports::RAM_SIZE = 0;
|
||||
Exports::RAM_MASK = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Bus::Reset()
|
||||
|
@ -509,13 +530,13 @@ void Bus::UpdateFastmemViews(CPUFastmemMode mode)
|
|||
|
||||
if (!s_fastmem_lut)
|
||||
{
|
||||
s_fastmem_lut = static_cast<u8**>(std::malloc(sizeof(u8*) * FASTMEM_LUT_NUM_SLOTS));
|
||||
s_fastmem_lut = static_cast<u8**>(std::malloc(sizeof(u8*) * FASTMEM_LUT_SIZE));
|
||||
Assert(s_fastmem_lut);
|
||||
|
||||
Log_InfoPrintf("Fastmem base (software): %p", s_fastmem_lut);
|
||||
}
|
||||
|
||||
std::memset(s_fastmem_lut, 0, sizeof(u8*) * FASTMEM_LUT_NUM_SLOTS);
|
||||
std::memset(s_fastmem_lut, 0, sizeof(u8*) * FASTMEM_LUT_SIZE);
|
||||
|
||||
auto MapRAM = [](u32 base_address) {
|
||||
u8* ram_ptr = g_ram + (base_address & g_ram_mask);
|
||||
|
@ -523,8 +544,6 @@ void Bus::UpdateFastmemViews(CPUFastmemMode mode)
|
|||
{
|
||||
const u32 lut_index = (base_address + address) >> FASTMEM_LUT_PAGE_SHIFT;
|
||||
s_fastmem_lut[lut_index] = ram_ptr;
|
||||
s_fastmem_lut[FASTMEM_LUT_NUM_PAGES + lut_index] =
|
||||
g_ram_code_bits[address >> HOST_PAGE_SHIFT] ? nullptr : ram_ptr;
|
||||
ram_ptr += FASTMEM_LUT_PAGE_SIZE;
|
||||
}
|
||||
};
|
||||
|
@ -584,7 +603,7 @@ void Bus::SetRAMCodePage(u32 index)
|
|||
|
||||
// protect fastmem pages
|
||||
g_ram_code_bits[index] = true;
|
||||
SetCodePageFastmemProtection(index, false);
|
||||
SetRAMPageWritable(index, false);
|
||||
}
|
||||
|
||||
void Bus::ClearRAMCodePage(u32 index)
|
||||
|
@ -594,11 +613,19 @@ void Bus::ClearRAMCodePage(u32 index)
|
|||
|
||||
// unprotect fastmem pages
|
||||
g_ram_code_bits[index] = false;
|
||||
SetCodePageFastmemProtection(index, true);
|
||||
SetRAMPageWritable(index, true);
|
||||
}
|
||||
|
||||
void Bus::SetCodePageFastmemProtection(u32 page_index, bool writable)
|
||||
void Bus::SetRAMPageWritable(u32 page_index, bool writable)
|
||||
{
|
||||
if (!MemMap::MemProtect(&g_ram[page_index * HOST_PAGE_SIZE], HOST_PAGE_SIZE,
|
||||
writable ? PageProtect::ReadWrite : PageProtect::ReadOnly)) [[unlikely]]
|
||||
{
|
||||
Log_ErrorFmt("Failed to set RAM host page {} ({}) to {}", page_index,
|
||||
reinterpret_cast<const void*>(&g_ram[page_index * HOST_PAGE_SIZE]),
|
||||
writable ? "read-write" : "read-only");
|
||||
}
|
||||
|
||||
#ifdef ENABLE_MMAP_FASTMEM
|
||||
if (s_fastmem_mode == CPUFastmemMode::MMap)
|
||||
{
|
||||
|
@ -608,7 +635,7 @@ void Bus::SetCodePageFastmemProtection(u32 page_index, bool writable)
|
|||
for (const auto& it : s_fastmem_ram_views)
|
||||
{
|
||||
u8* page_address = it.first + (page_index * HOST_PAGE_SIZE);
|
||||
if (!MemMap::MemProtect(page_address, HOST_PAGE_SIZE, protect))
|
||||
if (!MemMap::MemProtect(page_address, HOST_PAGE_SIZE, protect)) [[unlikely]]
|
||||
{
|
||||
Log_ErrorPrintf("Failed to %s code page %u (0x%08X) @ %p", writable ? "unprotect" : "protect", page_index,
|
||||
page_index * static_cast<u32>(HOST_PAGE_SIZE), page_address);
|
||||
|
@ -618,30 +645,15 @@ void Bus::SetCodePageFastmemProtection(u32 page_index, bool writable)
|
|||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (s_fastmem_mode == CPUFastmemMode::LUT)
|
||||
{
|
||||
// mirrors...
|
||||
const u32 code_addr = page_index << HOST_PAGE_SHIFT;
|
||||
for (u32 mirror_start : s_fastmem_ram_mirrors)
|
||||
{
|
||||
u32 lut_addr = mirror_start + code_addr;
|
||||
u32 ram_offset = (lut_addr & g_ram_mask);
|
||||
for (u32 j = 0; j < FASTMEM_LUT_PAGES_PER_CODE_PAGE; j++)
|
||||
{
|
||||
s_fastmem_lut[FASTMEM_LUT_NUM_PAGES + (lut_addr >> FASTMEM_LUT_PAGE_SHIFT)] =
|
||||
writable ? &g_ram[ram_offset] : nullptr;
|
||||
lut_addr += FASTMEM_LUT_PAGE_SIZE;
|
||||
ram_offset += FASTMEM_LUT_PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Bus::ClearRAMCodePageFlags()
|
||||
{
|
||||
g_ram_code_bits.reset();
|
||||
|
||||
if (!MemMap::MemProtect(g_ram, RAM_8MB_SIZE, PageProtect::ReadWrite))
|
||||
Log_ErrorPrint("Failed to restore RAM protection to read-write.");
|
||||
|
||||
#ifdef ENABLE_MMAP_FASTMEM
|
||||
if (s_fastmem_mode == CPUFastmemMode::MMap)
|
||||
{
|
||||
|
@ -655,21 +667,6 @@ void Bus::ClearRAMCodePageFlags()
|
|||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (s_fastmem_mode == CPUFastmemMode::LUT)
|
||||
{
|
||||
for (u32 i = 0; i < static_cast<u32>(g_ram_code_bits.size()); i++)
|
||||
{
|
||||
u32 lut_addr = (i * HOST_PAGE_SIZE);
|
||||
u32 ram_offset = (lut_addr & g_ram_mask);
|
||||
for (u32 j = 0; j < FASTMEM_LUT_PAGES_PER_CODE_PAGE; j++)
|
||||
{
|
||||
s_fastmem_lut[FASTMEM_LUT_NUM_PAGES + (lut_addr >> FASTMEM_LUT_PAGE_SHIFT)] = &g_ram[ram_offset];
|
||||
lut_addr += FASTMEM_LUT_PAGE_SIZE;
|
||||
ram_offset += FASTMEM_LUT_PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Bus::IsCodePageAddress(PhysicalMemoryAddress address)
|
||||
|
@ -740,16 +737,16 @@ u8* Bus::GetMemoryRegionPointer(MemoryRegion region)
|
|||
switch (region)
|
||||
{
|
||||
case MemoryRegion::RAM:
|
||||
return g_ram;
|
||||
return g_unprotected_ram;
|
||||
|
||||
case MemoryRegion::RAMMirror1:
|
||||
return (g_ram + (RAM_2MB_SIZE & g_ram_mask));
|
||||
return (g_unprotected_ram + (RAM_2MB_SIZE & g_ram_mask));
|
||||
|
||||
case MemoryRegion::RAMMirror2:
|
||||
return (g_ram + ((RAM_2MB_SIZE * 2) & g_ram_mask));
|
||||
return (g_unprotected_ram + ((RAM_2MB_SIZE * 2) & g_ram_mask));
|
||||
|
||||
case MemoryRegion::RAMMirror3:
|
||||
return (g_ram + ((RAM_8MB_SIZE * 3) & g_ram_mask));
|
||||
return (g_unprotected_ram + ((RAM_8MB_SIZE * 3) & g_ram_mask));
|
||||
|
||||
case MemoryRegion::EXP1:
|
||||
return nullptr;
|
||||
|
@ -932,9 +929,6 @@ template<MemoryAccessSize size>
|
|||
void Bus::RAMWriteHandler(VirtualMemoryAddress address, u32 value)
|
||||
{
|
||||
const u32 offset = address & g_ram_mask;
|
||||
const u32 page_index = offset / HOST_PAGE_SIZE;
|
||||
if (g_ram_code_bits[page_index])
|
||||
CPU::CodeCache::InvalidateBlocksWithPageIndex(page_index);
|
||||
|
||||
if constexpr (size == MemoryAccessSize::Byte)
|
||||
{
|
||||
|
|
|
@ -96,10 +96,7 @@ enum : u32
|
|||
FASTMEM_LUT_PAGE_SIZE = 4096,
|
||||
FASTMEM_LUT_PAGE_MASK = FASTMEM_LUT_PAGE_SIZE - 1,
|
||||
FASTMEM_LUT_PAGE_SHIFT = 12,
|
||||
FASTMEM_LUT_PAGES_PER_CODE_PAGE = HOST_PAGE_SIZE / FASTMEM_LUT_PAGE_SIZE,
|
||||
|
||||
FASTMEM_LUT_NUM_PAGES = 0x100000, // 0x100000000 >> 12
|
||||
FASTMEM_LUT_NUM_SLOTS = FASTMEM_LUT_NUM_PAGES * 2,
|
||||
FASTMEM_LUT_SIZE = 0x100000, // 0x100000000 >> 12
|
||||
};
|
||||
|
||||
#ifdef ENABLE_MMAP_FASTMEM
|
||||
|
@ -135,10 +132,11 @@ bool CanUseFastmemForAddress(VirtualMemoryAddress address);
|
|||
void SetExpansionROM(std::vector<u8> data);
|
||||
|
||||
extern std::bitset<RAM_8MB_CODE_PAGE_COUNT> g_ram_code_bits;
|
||||
extern u8* g_ram; // 2MB-8MB RAM
|
||||
extern u32 g_ram_size; // Active size of RAM.
|
||||
extern u32 g_ram_mask; // Active address bits for RAM.
|
||||
extern u8* g_bios; // 512K BIOS ROM
|
||||
extern u8* g_ram; // 2MB-8MB RAM
|
||||
extern u8* g_unprotected_ram; // RAM without page protection, use for debugger access.
|
||||
extern u32 g_ram_size; // Active size of RAM.
|
||||
extern u32 g_ram_mask; // Active address bits for RAM.
|
||||
extern u8* g_bios; // 512K BIOS ROM
|
||||
extern std::array<TickCount, 3> g_exp1_access_time;
|
||||
extern std::array<TickCount, 3> g_exp2_access_time;
|
||||
extern std::array<TickCount, 3> g_bios_access_time;
|
||||
|
|
|
@ -672,7 +672,19 @@ void CPU::CodeCache::ClearBlocks()
|
|||
Common::PageFaultHandler::HandlerResult CPU::CodeCache::ExceptionHandler(void* exception_pc, void* fault_address,
|
||||
bool is_write)
|
||||
{
|
||||
// TODO: Catch general RAM writes, not just fastmem
|
||||
if (static_cast<const u8*>(fault_address) >= Bus::g_ram &&
|
||||
static_cast<const u8*>(fault_address) < (Bus::g_ram + Bus::RAM_8MB_SIZE))
|
||||
{
|
||||
// Writing to protected RAM.
|
||||
DebugAssert(is_write);
|
||||
const u32 guest_address = static_cast<u32>(static_cast<const u8*>(fault_address) - Bus::g_ram);
|
||||
const u32 page_index = Bus::GetRAMCodePageIndex(guest_address);
|
||||
Log_DevFmt("Page fault on protected RAM @ 0x{:08X} (page #{}), invalidating code cache.", guest_address,
|
||||
page_index);
|
||||
InvalidateBlocksWithPageIndex(page_index);
|
||||
return Common::PageFaultHandler::HandlerResult::ContinueExecution;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_RECOMPILER_SUPPORT
|
||||
return HandleFastmemException(exception_pc, fault_address, is_write);
|
||||
#else
|
||||
|
|
|
@ -38,16 +38,4 @@ void InvalidateBlocksWithPageIndex(u32 page_index);
|
|||
/// Invalidates all blocks in the cache.
|
||||
void InvalidateAllRAMBlocks();
|
||||
|
||||
/// Invalidates any code pages which overlap the specified range.
|
||||
ALWAYS_INLINE void InvalidateCodePages(PhysicalMemoryAddress address, u32 word_count)
|
||||
{
|
||||
const u32 start_page = address / HOST_PAGE_SIZE;
|
||||
const u32 end_page = (address + word_count * sizeof(u32) - sizeof(u32)) / HOST_PAGE_SIZE;
|
||||
for (u32 page = start_page; page <= end_page; page++)
|
||||
{
|
||||
if (Bus::g_ram_code_bits[page])
|
||||
CPU::CodeCache::InvalidateBlocksWithPageIndex(page);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace CPU::CodeCache
|
||||
|
|
|
@ -2740,17 +2740,17 @@ ALWAYS_INLINE bool CPU::DoSafeMemoryAccess(VirtualMemoryAddress address, u32& va
|
|||
{
|
||||
if constexpr (size == MemoryAccessSize::Byte)
|
||||
{
|
||||
value = g_ram[offset];
|
||||
value = g_unprotected_ram[offset];
|
||||
}
|
||||
else if constexpr (size == MemoryAccessSize::HalfWord)
|
||||
{
|
||||
u16 temp;
|
||||
std::memcpy(&temp, &g_ram[offset], sizeof(temp));
|
||||
std::memcpy(&temp, &g_unprotected_ram[offset], sizeof(temp));
|
||||
value = ZeroExtend32(temp);
|
||||
}
|
||||
else if constexpr (size == MemoryAccessSize::Word)
|
||||
{
|
||||
std::memcpy(&value, &g_ram[offset], sizeof(u32));
|
||||
std::memcpy(&value, &g_unprotected_ram[offset], sizeof(u32));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -2759,9 +2759,9 @@ ALWAYS_INLINE bool CPU::DoSafeMemoryAccess(VirtualMemoryAddress address, u32& va
|
|||
|
||||
if constexpr (size == MemoryAccessSize::Byte)
|
||||
{
|
||||
if (g_ram[offset] != Truncate8(value))
|
||||
if (g_unprotected_ram[offset] != Truncate8(value))
|
||||
{
|
||||
g_ram[offset] = Truncate8(value);
|
||||
g_unprotected_ram[offset] = Truncate8(value);
|
||||
if (g_ram_code_bits[page_index])
|
||||
CPU::CodeCache::InvalidateBlocksWithPageIndex(page_index);
|
||||
}
|
||||
|
@ -2770,10 +2770,10 @@ ALWAYS_INLINE bool CPU::DoSafeMemoryAccess(VirtualMemoryAddress address, u32& va
|
|||
{
|
||||
const u16 new_value = Truncate16(value);
|
||||
u16 old_value;
|
||||
std::memcpy(&old_value, &g_ram[offset], sizeof(old_value));
|
||||
std::memcpy(&old_value, &g_unprotected_ram[offset], sizeof(old_value));
|
||||
if (old_value != new_value)
|
||||
{
|
||||
std::memcpy(&g_ram[offset], &new_value, sizeof(u16));
|
||||
std::memcpy(&g_unprotected_ram[offset], &new_value, sizeof(u16));
|
||||
if (g_ram_code_bits[page_index])
|
||||
CPU::CodeCache::InvalidateBlocksWithPageIndex(page_index);
|
||||
}
|
||||
|
@ -2781,10 +2781,10 @@ ALWAYS_INLINE bool CPU::DoSafeMemoryAccess(VirtualMemoryAddress address, u32& va
|
|||
else if constexpr (size == MemoryAccessSize::Word)
|
||||
{
|
||||
u32 old_value;
|
||||
std::memcpy(&old_value, &g_ram[offset], sizeof(u32));
|
||||
std::memcpy(&old_value, &g_unprotected_ram[offset], sizeof(u32));
|
||||
if (old_value != value)
|
||||
{
|
||||
std::memcpy(&g_ram[offset], &value, sizeof(u32));
|
||||
std::memcpy(&g_unprotected_ram[offset], &value, sizeof(u32));
|
||||
if (g_ram_code_bits[page_index])
|
||||
CPU::CodeCache::InvalidateBlocksWithPageIndex(page_index);
|
||||
}
|
||||
|
@ -2955,11 +2955,8 @@ void* CPU::GetDirectWriteMemoryPointer(VirtualMemoryAddress address, MemoryAcces
|
|||
|
||||
const PhysicalMemoryAddress paddr = address & PHYSICAL_MEMORY_ADDRESS_MASK;
|
||||
|
||||
#if 0
|
||||
// Not enabled until we can protect code regions.
|
||||
if (paddr < RAM_MIRROR_END)
|
||||
return &g_ram[paddr & RAM_MASK];
|
||||
#endif
|
||||
return &g_ram[paddr & g_ram_mask];
|
||||
|
||||
if ((paddr & DCACHE_LOCATION_MASK) == DCACHE_LOCATION)
|
||||
return &g_state.dcache[paddr & DCACHE_OFFSET_MASK];
|
||||
|
|
|
@ -109,8 +109,6 @@ public:
|
|||
void EmitLoadGlobalAddress(HostReg host_reg, const void* ptr);
|
||||
|
||||
// Automatically generates an exception handler.
|
||||
Value GetFastmemLoadBase();
|
||||
Value GetFastmemStoreBase();
|
||||
Value EmitLoadGuestMemory(Instruction instruction, const CodeCache::InstructionInfo& info, const Value& address,
|
||||
const SpeculativeValue& address_spec, RegSize size);
|
||||
void EmitLoadGuestRAMFastmem(const Value& address, RegSize size, Value& result);
|
||||
|
|
|
@ -1999,7 +1999,6 @@ void CodeGenerator::EmitStoreGuestMemoryFastmem(Instruction instruction, const C
|
|||
{
|
||||
m_emit->lsr(GetHostReg32(RARG1), GetHostReg32(address_reg), Bus::FASTMEM_LUT_PAGE_SHIFT);
|
||||
m_emit->and_(GetHostReg32(RARG2), GetHostReg32(address_reg), Bus::FASTMEM_LUT_PAGE_MASK);
|
||||
m_emit->add(GetHostReg64(RARG3), GetFastmemBasePtrReg(), Bus::FASTMEM_LUT_NUM_PAGES * sizeof(u32*));
|
||||
m_emit->ldr(GetHostReg64(RARG1), a64::MemOperand(GetHostReg64(RARG3), GetHostReg32(RARG1), a64::LSL, 3));
|
||||
|
||||
host_pc = GetCurrentNearCodePointer();
|
||||
|
|
|
@ -63,7 +63,7 @@ Value CodeGenerator::EmitLoadGuestMemory(Instruction instruction, const CodeCach
|
|||
|
||||
Value result = m_register_cache.AllocateScratch(HostPointerSize);
|
||||
|
||||
const bool use_fastmem =
|
||||
const bool use_fastmem = !g_settings.cpu_recompiler_memory_exceptions &&
|
||||
(address_spec ? Bus::CanUseFastmemForAddress(*address_spec) : true) && !SpeculativeIsCacheIsolated();
|
||||
if (address_spec)
|
||||
{
|
||||
|
@ -137,7 +137,7 @@ void CodeGenerator::EmitStoreGuestMemory(Instruction instruction, const CodeCach
|
|||
}
|
||||
}
|
||||
|
||||
const bool use_fastmem =
|
||||
const bool use_fastmem = !g_settings.cpu_recompiler_memory_exceptions &&
|
||||
(address_spec ? Bus::CanUseFastmemForAddress(*address_spec) : true) && !SpeculativeIsCacheIsolated();
|
||||
if (address_spec)
|
||||
{
|
||||
|
|
|
@ -2524,8 +2524,7 @@ void CodeGenerator::EmitStoreGuestMemoryFastmem(Instruction instruction, const C
|
|||
m_emit->mov(GetHostReg32(RARG2), GetHostReg32(RARG1));
|
||||
m_emit->shr(GetHostReg32(RARG1), Bus::FASTMEM_LUT_PAGE_SHIFT);
|
||||
m_emit->and_(GetHostReg32(RARG2), Bus::FASTMEM_LUT_PAGE_MASK);
|
||||
m_emit->mov(GetHostReg64(RARG1),
|
||||
m_emit->qword[GetFastmemBasePtrReg() + GetHostReg64(RARG1) * 8 + (Bus::FASTMEM_LUT_NUM_PAGES * 8)]);
|
||||
m_emit->mov(GetHostReg64(RARG1), m_emit->qword[GetFastmemBasePtrReg() + GetHostReg64(RARG1) * 8]);
|
||||
host_pc = GetCurrentNearCodePointer();
|
||||
|
||||
switch (size)
|
||||
|
|
|
@ -739,7 +739,6 @@ TickCount DMA::TransferDeviceToMemory(Channel channel, u32 address, u32 incremen
|
|||
|
||||
const u32 terminator = UINT32_C(0xFFFFFF);
|
||||
std::memcpy(&ram_pointer[address], &terminator, sizeof(terminator));
|
||||
CPU::CodeCache::InvalidateCodePages(address, word_count);
|
||||
return Bus::GetDMARAMTickCount(word_count);
|
||||
}
|
||||
|
||||
|
@ -787,7 +786,6 @@ TickCount DMA::TransferDeviceToMemory(Channel channel, u32 address, u32 incremen
|
|||
}
|
||||
}
|
||||
|
||||
CPU::CodeCache::InvalidateCodePages(address, word_count);
|
||||
return Bus::GetDMARAMTickCount(word_count);
|
||||
}
|
||||
|
||||
|
|
|
@ -3191,7 +3191,7 @@ bool System::DumpRAM(const char* filename)
|
|||
if (!IsValid())
|
||||
return false;
|
||||
|
||||
return FileSystem::WriteBinaryFile(filename, Bus::g_ram, Bus::g_ram_size);
|
||||
return FileSystem::WriteBinaryFile(filename, Bus::g_unprotected_ram, Bus::g_ram_size);
|
||||
}
|
||||
|
||||
bool System::DumpVRAM(const char* filename)
|
||||
|
|
Loading…
Reference in New Issue