mirror of
https://github.com/stenzek/duckstation.git
synced 2025-06-28 06:10:12 +00:00
DMA: Invalidate code pages on CD-ROM DMA write
Avoids page faulting by invalidating the pages in advance. Might help with frame time spikes on super low-spec devices.
This commit is contained in:
parent
fa0a926133
commit
6c6cc910e6
@ -699,11 +699,6 @@ bool Bus::CanUseFastmemForAddress(VirtualMemoryAddress address)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Bus::IsRAMCodePage(u32 index)
|
|
||||||
{
|
|
||||||
return g_ram_code_bits[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
void Bus::SetRAMCodePage(u32 index)
|
void Bus::SetRAMCodePage(u32 index)
|
||||||
{
|
{
|
||||||
if (g_ram_code_bits[index])
|
if (g_ram_code_bits[index])
|
||||||
|
@ -170,7 +170,10 @@ ALWAYS_INLINE static u32 GetRAMCodePageIndex(PhysicalMemoryAddress address)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the specified page contains code.
|
/// Returns true if the specified page contains code.
|
||||||
bool IsRAMCodePage(u32 index);
|
ALWAYS_INLINE static bool IsRAMCodePage(u32 index)
|
||||||
|
{
|
||||||
|
return g_ram_code_bits[index];
|
||||||
|
}
|
||||||
|
|
||||||
/// Flags a RAM region as code, so we know when to invalidate blocks.
|
/// Flags a RAM region as code, so we know when to invalidate blocks.
|
||||||
void SetRAMCodePage(u32 index);
|
void SetRAMCodePage(u32 index);
|
||||||
@ -188,7 +191,7 @@ bool IsCodePageAddress(PhysicalMemoryAddress address);
|
|||||||
bool HasCodePagesInRange(PhysicalMemoryAddress start_address, u32 size);
|
bool HasCodePagesInRange(PhysicalMemoryAddress start_address, u32 size);
|
||||||
|
|
||||||
/// Returns the number of cycles stolen by DMA RAM access.
|
/// Returns the number of cycles stolen by DMA RAM access.
|
||||||
ALWAYS_INLINE TickCount GetDMARAMTickCount(u32 word_count)
|
ALWAYS_INLINE static TickCount GetDMARAMTickCount(u32 word_count)
|
||||||
{
|
{
|
||||||
// DMA is using DRAM Hyper Page mode, allowing it to access DRAM rows at 1 clock cycle per word (effectively around
|
// DMA is using DRAM Hyper Page mode, allowing it to access DRAM rows at 1 clock cycle per word (effectively around
|
||||||
// 17 clks per 16 words, due to required row address loading, probably plus some further minimal overload due to
|
// 17 clks per 16 words, due to required row address loading, probably plus some further minimal overload due to
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "dma.h"
|
#include "dma.h"
|
||||||
#include "bus.h"
|
#include "bus.h"
|
||||||
#include "cdrom.h"
|
#include "cdrom.h"
|
||||||
|
#include "cpu_code_cache.h"
|
||||||
#include "cpu_core.h"
|
#include "cpu_core.h"
|
||||||
#include "gpu.h"
|
#include "gpu.h"
|
||||||
#include "gpu_dump.h"
|
#include "gpu_dump.h"
|
||||||
@ -895,6 +896,15 @@ TickCount DMA::TransferDeviceToMemory(u32 address, u32 increment, u32 word_count
|
|||||||
s_state.transfer_buffer.resize(word_count);
|
s_state.transfer_buffer.resize(word_count);
|
||||||
dest_pointer = s_state.transfer_buffer.data();
|
dest_pointer = s_state.transfer_buffer.data();
|
||||||
}
|
}
|
||||||
|
else if constexpr (channel == Channel::CDROM)
|
||||||
|
{
|
||||||
|
const u32 end_page = (address + (increment * word_count) - 1) >> HOST_PAGE_SHIFT;
|
||||||
|
for (u32 page = address >> HOST_PAGE_SHIFT; page <= end_page; page++)
|
||||||
|
{
|
||||||
|
if (Bus::IsRAMCodePage(page))
|
||||||
|
CPU::CodeCache::InvalidateBlocksWithPageIndex(page);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Read from device.
|
// Read from device.
|
||||||
switch (channel)
|
switch (channel)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user