summaryrefslogtreecommitdiffstats
path: root/src/video_core/memory_manager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/memory_manager.cpp')
-rw-r--r--src/video_core/memory_manager.cpp50
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);