summaryrefslogtreecommitdiff
path: root/src/video_core
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core')
-rw-r--r--src/video_core/memory_manager.cpp50
-rw-r--r--src/video_core/memory_manager.h15
2 files changed, 43 insertions, 22 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
90 return std::max(base, vma_handle->second.base); 90 return std::max(base, vma_handle->second.base);
91} 91}
92 92
93std::optional<VAddr> MemoryManager::GpuToCpuAddress(GPUVAddr gpu_addr) { 93bool MemoryManager::IsAddressValid(GPUVAddr addr) const {
94 VAddr cpu_addr = page_table.backing_addr[gpu_addr >> page_bits]; 94 return (addr >> page_bits) < page_table.pointers.size();
95}
96
97std::optional<VAddr> MemoryManager::GpuToCpuAddress(GPUVAddr addr) {
98 if (!IsAddressValid(addr)) {
99 return {};
100 }
101
102 VAddr cpu_addr = page_table.backing_addr[addr >> page_bits];
95 if (cpu_addr) { 103 if (cpu_addr) {
96 return cpu_addr + (gpu_addr & page_mask); 104 return cpu_addr + (addr & page_mask);
97 } 105 }
98 106
99 return {}; 107 return {};
100} 108}
101 109
102template <typename T> 110template <typename T>
103T MemoryManager::Read(GPUVAddr vaddr) { 111T MemoryManager::Read(GPUVAddr addr) {
104 const u8* page_pointer = page_table.pointers[vaddr >> page_bits]; 112 if (!IsAddressValid(addr)) {
113 return {};
114 }
115
116 const u8* page_pointer = page_table.pointers[addr >> page_bits];
105 if (page_pointer) { 117 if (page_pointer) {
106 // NOTE: Avoid adding any extra logic to this fast-path block 118 // NOTE: Avoid adding any extra logic to this fast-path block
107 T value; 119 T value;
108 std::memcpy(&value, &page_pointer[vaddr & page_mask], sizeof(T)); 120 std::memcpy(&value, &page_pointer[addr & page_mask], sizeof(T));
109 return value; 121 return value;
110 } 122 }
111 123
112 Common::PageType type = page_table.attributes[vaddr >> page_bits]; 124 Common::PageType type = page_table.attributes[addr >> page_bits];
113 switch (type) { 125 switch (type) {
114 case Common::PageType::Unmapped: 126 case Common::PageType::Unmapped:
115 LOG_ERROR(HW_GPU, "Unmapped Read{} @ 0x{:08X}", sizeof(T) * 8, vaddr); 127 LOG_ERROR(HW_GPU, "Unmapped Read{} @ 0x{:08X}", sizeof(T) * 8, addr);
116 return 0; 128 return 0;
117 case Common::PageType::Memory: 129 case Common::PageType::Memory:
118 ASSERT_MSG(false, "Mapped memory page without a pointer @ {:016X}", vaddr); 130 ASSERT_MSG(false, "Mapped memory page without a pointer @ {:016X}", addr);
119 break; 131 break;
120 default: 132 default:
121 UNREACHABLE(); 133 UNREACHABLE();
@@ -124,22 +136,26 @@ T MemoryManager::Read(GPUVAddr vaddr) {
124} 136}
125 137
126template <typename T> 138template <typename T>
127void MemoryManager::Write(GPUVAddr vaddr, T data) { 139void MemoryManager::Write(GPUVAddr addr, T data) {
128 u8* page_pointer = page_table.pointers[vaddr >> page_bits]; 140 if (!IsAddressValid(addr)) {
141 return;
142 }
143
144 u8* page_pointer = page_table.pointers[addr >> page_bits];
129 if (page_pointer) { 145 if (page_pointer) {
130 // NOTE: Avoid adding any extra logic to this fast-path block 146 // NOTE: Avoid adding any extra logic to this fast-path block
131 std::memcpy(&page_pointer[vaddr & page_mask], &data, sizeof(T)); 147 std::memcpy(&page_pointer[addr & page_mask], &data, sizeof(T));
132 return; 148 return;
133 } 149 }
134 150
135 Common::PageType type = page_table.attributes[vaddr >> page_bits]; 151 Common::PageType type = page_table.attributes[addr >> page_bits];
136 switch (type) { 152 switch (type) {
137 case Common::PageType::Unmapped: 153 case Common::PageType::Unmapped:
138 LOG_ERROR(HW_GPU, "Unmapped Write{} 0x{:08X} @ 0x{:016X}", sizeof(data) * 8, 154 LOG_ERROR(HW_GPU, "Unmapped Write{} 0x{:08X} @ 0x{:016X}", sizeof(data) * 8,
139 static_cast<u32>(data), vaddr); 155 static_cast<u32>(data), addr);
140 return; 156 return;
141 case Common::PageType::Memory: 157 case Common::PageType::Memory:
142 ASSERT_MSG(false, "Mapped memory page without a pointer @ {:016X}", vaddr); 158 ASSERT_MSG(false, "Mapped memory page without a pointer @ {:016X}", addr);
143 break; 159 break;
144 default: 160 default:
145 UNREACHABLE(); 161 UNREACHABLE();
@@ -156,6 +172,10 @@ template void MemoryManager::Write<u32>(GPUVAddr addr, u32 data);
156template void MemoryManager::Write<u64>(GPUVAddr addr, u64 data); 172template void MemoryManager::Write<u64>(GPUVAddr addr, u64 data);
157 173
158u8* MemoryManager::GetPointer(GPUVAddr addr) { 174u8* MemoryManager::GetPointer(GPUVAddr addr) {
175 if (!IsAddressValid(addr)) {
176 return {};
177 }
178
159 u8* page_pointer = page_table.pointers[addr >> page_bits]; 179 u8* page_pointer = page_table.pointers[addr >> page_bits];
160 if (page_pointer) { 180 if (page_pointer) {
161 return page_pointer + (addr & page_mask); 181 return page_pointer + (addr & page_mask);
diff --git a/src/video_core/memory_manager.h b/src/video_core/memory_manager.h
index ac1b42936..76fa3d916 100644
--- a/src/video_core/memory_manager.h
+++ b/src/video_core/memory_manager.h
@@ -46,19 +46,19 @@ public:
46 MemoryManager(); 46 MemoryManager();
47 47
48 GPUVAddr AllocateSpace(u64 size, u64 align); 48 GPUVAddr AllocateSpace(u64 size, u64 align);
49 GPUVAddr AllocateSpace(GPUVAddr gpu_addr, u64 size, u64 align); 49 GPUVAddr AllocateSpace(GPUVAddr addr, u64 size, u64 align);
50 GPUVAddr MapBufferEx(GPUVAddr cpu_addr, u64 size); 50 GPUVAddr MapBufferEx(GPUVAddr cpu_addr, u64 size);
51 GPUVAddr MapBufferEx(GPUVAddr cpu_addr, GPUVAddr gpu_addr, u64 size); 51 GPUVAddr MapBufferEx(GPUVAddr cpu_addr, GPUVAddr addr, u64 size);
52 GPUVAddr UnmapBuffer(GPUVAddr gpu_addr, u64 size); 52 GPUVAddr UnmapBuffer(GPUVAddr addr, u64 size);
53 std::optional<VAddr> GpuToCpuAddress(GPUVAddr gpu_addr); 53 std::optional<VAddr> GpuToCpuAddress(GPUVAddr addr);
54 54
55 template <typename T> 55 template <typename T>
56 T Read(GPUVAddr vaddr); 56 T Read(GPUVAddr addr);
57 57
58 template <typename T> 58 template <typename T>
59 void Write(GPUVAddr vaddr, T data); 59 void Write(GPUVAddr addr, T data);
60 60
61 u8* GetPointer(GPUVAddr vaddr); 61 u8* GetPointer(GPUVAddr addr);
62 62
63 void ReadBlock(GPUVAddr src_addr, void* dest_buffer, std::size_t size); 63 void ReadBlock(GPUVAddr src_addr, void* dest_buffer, std::size_t size);
64 void WriteBlock(GPUVAddr dest_addr, const void* src_buffer, std::size_t size); 64 void WriteBlock(GPUVAddr dest_addr, const void* src_buffer, std::size_t size);
@@ -69,6 +69,7 @@ private:
69 using VMAHandle = VMAMap::const_iterator; 69 using VMAHandle = VMAMap::const_iterator;
70 using VMAIter = VMAMap::iterator; 70 using VMAIter = VMAMap::iterator;
71 71
72 bool IsAddressValid(GPUVAddr addr) const;
72 void MapPages(GPUVAddr base, u64 size, u8* memory, Common::PageType type, 73 void MapPages(GPUVAddr base, u64 size, u8* memory, Common::PageType type,
73 VAddr backing_addr = 0); 74 VAddr backing_addr = 0);
74 void MapMemoryRegion(GPUVAddr base, u64 size, u8* target, VAddr backing_addr); 75 void MapMemoryRegion(GPUVAddr base, u64 size, u8* target, VAddr backing_addr);