diff options
Diffstat (limited to 'src/video_core/memory_manager.cpp')
-rw-r--r-- | src/video_core/memory_manager.cpp | 50 |
1 files changed, 35 insertions, 15 deletions
diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp index 4c7faa067..e8edf9b14 100644 --- a/src/video_core/memory_manager.cpp +++ b/src/video_core/memory_manager.cpp @@ -90,32 +90,44 @@ GPUVAddr MemoryManager::FindFreeRegion(GPUVAddr region_start, u64 size, u64 alig return std::max(base, vma_handle->second.base); } -std::optional<VAddr> MemoryManager::GpuToCpuAddress(GPUVAddr gpu_addr) { - VAddr cpu_addr = page_table.backing_addr[gpu_addr >> page_bits]; +bool MemoryManager::IsAddressValid(GPUVAddr addr) const { + return (addr >> page_bits) < page_table.pointers.size(); +} + +std::optional<VAddr> MemoryManager::GpuToCpuAddress(GPUVAddr addr) { + if (!IsAddressValid(addr)) { + return {}; + } + + VAddr cpu_addr = page_table.backing_addr[addr >> page_bits]; if (cpu_addr) { - return cpu_addr + (gpu_addr & page_mask); + return cpu_addr + (addr & page_mask); } return {}; } template <typename T> -T MemoryManager::Read(GPUVAddr vaddr) { - const u8* page_pointer = page_table.pointers[vaddr >> page_bits]; +T MemoryManager::Read(GPUVAddr addr) { + if (!IsAddressValid(addr)) { + return {}; + } + + const u8* page_pointer = page_table.pointers[addr >> page_bits]; if (page_pointer) { // NOTE: Avoid adding any extra logic to this fast-path block T value; - std::memcpy(&value, &page_pointer[vaddr & page_mask], sizeof(T)); + std::memcpy(&value, &page_pointer[addr & page_mask], sizeof(T)); return value; } - Common::PageType type = page_table.attributes[vaddr >> page_bits]; + Common::PageType type = page_table.attributes[addr >> page_bits]; switch (type) { case Common::PageType::Unmapped: - LOG_ERROR(HW_GPU, "Unmapped Read{} @ 0x{:08X}", sizeof(T) * 8, vaddr); + LOG_ERROR(HW_GPU, "Unmapped Read{} @ 0x{:08X}", sizeof(T) * 8, addr); return 0; case Common::PageType::Memory: - ASSERT_MSG(false, "Mapped memory page without a pointer @ {:016X}", vaddr); + ASSERT_MSG(false, "Mapped memory page without a pointer @ {:016X}", addr); break; default: UNREACHABLE(); @@ -124,22 +136,26 @@ T MemoryManager::Read(GPUVAddr vaddr) { } template <typename T> -void MemoryManager::Write(GPUVAddr vaddr, T data) { - u8* page_pointer = page_table.pointers[vaddr >> page_bits]; +void MemoryManager::Write(GPUVAddr addr, T data) { + if (!IsAddressValid(addr)) { + return; + } + + u8* page_pointer = page_table.pointers[addr >> page_bits]; if (page_pointer) { // NOTE: Avoid adding any extra logic to this fast-path block - std::memcpy(&page_pointer[vaddr & page_mask], &data, sizeof(T)); + std::memcpy(&page_pointer[addr & page_mask], &data, sizeof(T)); return; } - Common::PageType type = page_table.attributes[vaddr >> page_bits]; + Common::PageType type = page_table.attributes[addr >> page_bits]; switch (type) { case Common::PageType::Unmapped: LOG_ERROR(HW_GPU, "Unmapped Write{} 0x{:08X} @ 0x{:016X}", sizeof(data) * 8, - static_cast<u32>(data), vaddr); + static_cast<u32>(data), addr); return; case Common::PageType::Memory: - ASSERT_MSG(false, "Mapped memory page without a pointer @ {:016X}", vaddr); + ASSERT_MSG(false, "Mapped memory page without a pointer @ {:016X}", addr); break; default: UNREACHABLE(); @@ -156,6 +172,10 @@ template void MemoryManager::Write<u32>(GPUVAddr addr, u32 data); template void MemoryManager::Write<u64>(GPUVAddr addr, u64 data); u8* MemoryManager::GetPointer(GPUVAddr addr) { + if (!IsAddressValid(addr)) { + return {}; + } + u8* page_pointer = page_table.pointers[addr >> page_bits]; if (page_pointer) { return page_pointer + (addr & page_mask); |