|
|
@ -44,8 +44,7 @@ bool AddressSpaceContains(const Common::PageTable& table, const Common::ProcessA |
|
|
// from outside classes. This also allows modification to the internals of the memory
|
|
|
// from outside classes. This also allows modification to the internals of the memory
|
|
|
// subsystem without needing to rebuild all files that make use of the memory interface.
|
|
|
// subsystem without needing to rebuild all files that make use of the memory interface.
|
|
|
struct Memory::Impl { |
|
|
struct Memory::Impl { |
|
|
explicit Impl(Core::System& system_) |
|
|
|
|
|
: system{system_} {} |
|
|
|
|
|
|
|
|
explicit Impl(Core::System& system_) : system{system_} {} |
|
|
|
|
|
|
|
|
void SetCurrentPageTable(Kernel::KProcess& process) { |
|
|
void SetCurrentPageTable(Kernel::KProcess& process) { |
|
|
current_page_table = &process.GetPageTable().GetImpl(); |
|
|
current_page_table = &process.GetPageTable().GetImpl(); |
|
|
@ -640,18 +639,6 @@ struct Memory::Impl { |
|
|
LOG_DEBUG(HW_Memory, "Mapping {:016X} onto {:016X}-{:016X}", GetInteger(target), |
|
|
LOG_DEBUG(HW_Memory, "Mapping {:016X} onto {:016X}-{:016X}", GetInteger(target), |
|
|
base * YUZU_PAGESIZE, (base + size) * YUZU_PAGESIZE); |
|
|
base * YUZU_PAGESIZE, (base + size) * YUZU_PAGESIZE); |
|
|
|
|
|
|
|
|
// During boot, current_page_table might not be set yet, in which case we need not flush
|
|
|
|
|
|
/*if (system.IsPoweredOn()) {
|
|
|
|
|
|
auto& gpu = system.GPU(); |
|
|
|
|
|
for (u64 i = 0; i < size; i++) { |
|
|
|
|
|
const auto page = base + i; |
|
|
|
|
|
if (page_table.pointers[page].Type() == Common::PageType::RasterizerCachedMemory) { |
|
|
|
|
|
|
|
|
|
|
|
gpu.FlushAndInvalidateRegion(page << YUZU_PAGEBITS, YUZU_PAGESIZE); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
}*/ |
|
|
|
|
|
|
|
|
|
|
|
const auto end = base + size; |
|
|
const auto end = base + size; |
|
|
ASSERT_MSG(end <= page_table.pointers.size(), "out of range mapping at {:016X}", |
|
|
ASSERT_MSG(end <= page_table.pointers.size(), "out of range mapping at {:016X}", |
|
|
base + page_table.pointers.size()); |
|
|
base + page_table.pointers.size()); |
|
|
@ -823,8 +810,7 @@ struct Memory::Impl { |
|
|
} |
|
|
} |
|
|
const size_t core = system.GetCurrentHostThreadID(); |
|
|
const size_t core = system.GetCurrentHostThreadID(); |
|
|
auto& current_area = rasterizer_read_areas[core]; |
|
|
auto& current_area = rasterizer_read_areas[core]; |
|
|
gpu_device_memory->ApplyOpOnPointer( |
|
|
|
|
|
p, scratch_buffers[core], [&](DAddr address) { |
|
|
|
|
|
|
|
|
gpu_device_memory->ApplyOpOnPointer(p, scratch_buffers[core], [&](DAddr address) { |
|
|
const DAddr end_address = address + size; |
|
|
const DAddr end_address = address + size; |
|
|
if (current_area.start_address <= address && end_address <= current_area.end_address) |
|
|
if (current_area.start_address <= address && end_address <= current_area.end_address) |
|
|
[[likely]] { |
|
|
[[likely]] { |
|
|
@ -852,8 +838,7 @@ struct Memory::Impl { |
|
|
sys_core_guard.unlock(); |
|
|
sys_core_guard.unlock(); |
|
|
} |
|
|
} |
|
|
}); |
|
|
}); |
|
|
gpu_device_memory->ApplyOpOnPointer( |
|
|
|
|
|
p, scratch_buffers[core], [&](DAddr address) { |
|
|
|
|
|
|
|
|
gpu_device_memory->ApplyOpOnPointer(p, scratch_buffers[core], [&](DAddr address) { |
|
|
auto& current_area = rasterizer_write_areas[core]; |
|
|
auto& current_area = rasterizer_write_areas[core]; |
|
|
PAddr subaddress = address >> YUZU_PAGEBITS; |
|
|
PAddr subaddress = address >> YUZU_PAGEBITS; |
|
|
bool do_collection = current_area.last_address == subaddress; |
|
|
bool do_collection = current_area.last_address == subaddress; |
|
|
@ -872,12 +857,25 @@ struct Memory::Impl { |
|
|
PAddr last_address; |
|
|
PAddr last_address; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
void InvalidateRegion(Common::ProcessAddress dest_addr, size_t size) { |
|
|
|
|
|
system.GPU().InvalidateRegion(GetInteger(dest_addr), size); |
|
|
|
|
|
|
|
|
void InvalidateGPUMemory(u8* p, size_t size) { |
|
|
|
|
|
constexpr size_t sys_core = Core::Hardware::NUM_CPU_CORES - 1; |
|
|
|
|
|
const size_t core = std::min(system.GetCurrentHostThreadID(), |
|
|
|
|
|
sys_core); // any other calls threads go to syscore.
|
|
|
|
|
|
if (!gpu_device_memory) [[unlikely]] { |
|
|
|
|
|
gpu_device_memory = &system.Host1x().MemoryManager(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void FlushRegion(Common::ProcessAddress dest_addr, size_t size) { |
|
|
|
|
|
system.GPU().FlushRegion(GetInteger(dest_addr), size); |
|
|
|
|
|
|
|
|
// Guard on sys_core;
|
|
|
|
|
|
if (core == sys_core) [[unlikely]] { |
|
|
|
|
|
sys_core_guard.lock(); |
|
|
|
|
|
} |
|
|
|
|
|
SCOPE_EXIT({ |
|
|
|
|
|
if (core == sys_core) [[unlikely]] { |
|
|
|
|
|
sys_core_guard.unlock(); |
|
|
|
|
|
} |
|
|
|
|
|
}); |
|
|
|
|
|
auto& gpu = system.GPU(); |
|
|
|
|
|
gpu_device_memory->ApplyOpOnPointer( |
|
|
|
|
|
p, scratch_buffers[core], [&](DAddr address) { gpu.InvalidateRegion(address, size); }); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Core::System& system; |
|
|
Core::System& system; |
|
|
@ -1081,14 +1079,6 @@ void Memory::MarkRegionDebug(Common::ProcessAddress vaddr, u64 size, bool debug) |
|
|
impl->MarkRegionDebug(GetInteger(vaddr), size, debug); |
|
|
impl->MarkRegionDebug(GetInteger(vaddr), size, debug); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void Memory::InvalidateRegion(Common::ProcessAddress dest_addr, size_t size) { |
|
|
|
|
|
impl->InvalidateRegion(dest_addr, size); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void Memory::FlushRegion(Common::ProcessAddress dest_addr, size_t size) { |
|
|
|
|
|
impl->FlushRegion(dest_addr, size); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool Memory::InvalidateNCE(Common::ProcessAddress vaddr, size_t size) { |
|
|
bool Memory::InvalidateNCE(Common::ProcessAddress vaddr, size_t size) { |
|
|
[[maybe_unused]] bool mapped = true; |
|
|
[[maybe_unused]] bool mapped = true; |
|
|
[[maybe_unused]] bool rasterizer = false; |
|
|
[[maybe_unused]] bool rasterizer = false; |
|
|
@ -1100,10 +1090,10 @@ bool Memory::InvalidateNCE(Common::ProcessAddress vaddr, size_t size) { |
|
|
GetInteger(vaddr)); |
|
|
GetInteger(vaddr)); |
|
|
mapped = false; |
|
|
mapped = false; |
|
|
}, |
|
|
}, |
|
|
[&] { |
|
|
|
|
|
impl->system.GPU().InvalidateRegion(GetInteger(vaddr), size); |
|
|
|
|
|
rasterizer = true; |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
[&] { rasterizer = true; }); |
|
|
|
|
|
if (rasterizer) { |
|
|
|
|
|
impl->InvalidateGPUMemory(ptr, size); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
#ifdef __linux__
|
|
|
#ifdef __linux__
|
|
|
if (!rasterizer && mapped) { |
|
|
if (!rasterizer && mapped) { |
|
|
|