From 7b6a7d7dfb92d7a6d3537ea8b0339c2170d7eb84 Mon Sep 17 00:00:00 2001
From: Tony Wasserka <NeoBrainX@gmail.com>
Date: Sun, 3 Aug 2014 01:46:47 +0200
Subject: Pica/GPU: Change hardware registers to use physical addresses rather
 than virtual ones.

This cleans up the mess that address reading/writing had become and makes the code a *lot* more sensible.
This adds a physical<->virtual address converter to mem_map.h. For further accuracy, we will want to properly extend this to support a wider range of address regions. For now, this makes simply homebrew applications work in a good manner though.
---
 src/core/mem_map_funcs.cpp | 68 ++++++++++++++++++++++++----------------------
 1 file changed, 36 insertions(+), 32 deletions(-)

(limited to 'src/core/mem_map_funcs.cpp')

diff --git a/src/core/mem_map_funcs.cpp b/src/core/mem_map_funcs.cpp
index 305be84683..5772cca523 100644
--- a/src/core/mem_map_funcs.cpp
+++ b/src/core/mem_map_funcs.cpp
@@ -17,37 +17,44 @@ std::map<u32, MemoryBlock> g_heap_map;
 std::map<u32, MemoryBlock> g_heap_gsp_map;
 std::map<u32, MemoryBlock> g_shared_map;
 
-/// Convert a physical address (or firmware-specific virtual address) to primary virtual address
-u32 _VirtualAddress(const u32 addr) {
-    // Our memory interface read/write functions assume virtual addresses. Put any physical address 
-    // to virtual address translations here. This is obviously quite hacky... But we're not doing 
-    // any MMU emulation yet or anything
-    if ((addr >= FCRAM_PADDR) && (addr < FCRAM_PADDR_END)) {
-        return VirtualAddressFromPhysical_FCRAM(addr);
-
-    // Virtual address mapping FW0B
-    } else if ((addr >= FCRAM_VADDR_FW0B) && (addr < FCRAM_VADDR_FW0B_END)) {
-        return VirtualAddressFromPhysical_FCRAM(addr);
-
-    // Hardware IO
-    // TODO(bunnei): FixMe
-    // This isn't going to work... The physical address of HARDWARE_IO conflicts with the virtual 
-    // address of shared memory.
-    //} else if ((addr >= HARDWARE_IO_PADDR) && (addr < HARDWARE_IO_PADDR_END)) {
-    //    return (addr + 0x0EB00000);
+/// Convert a physical address to virtual address
+u32 PhysicalToVirtualAddress(const u32 addr) {
+    // Our memory interface read/write functions assume virtual addresses. Put any physical address
+    // to virtual address translations here. This is quite hacky, but necessary until we implement
+    // proper MMU emulation.
+    // TODO: Screw it, I'll let bunnei figure out how to do this properly.
+    if ((addr >= VRAM_PADDR) && (addr < VRAM_PADDR_END)) {
+        return addr - VRAM_PADDR + VRAM_VADDR;
+    }else if ((addr >= FCRAM_PADDR) && (addr < FCRAM_PADDR_END)) {
+        return addr - FCRAM_PADDR + FCRAM_VADDR;
+    }
+
+    ERROR_LOG(MEMMAP, "Unknown physical address @ 0x%08x", addr);
+    return addr;
+}
 
+/// Convert a physical address to virtual address
+u32 VirtualToPhysicalAddress(const u32 addr) {
+    // Our memory interface read/write functions assume virtual addresses. Put any physical address
+    // to virtual address translations here. This is quite hacky, but necessary until we implement
+    // proper MMU emulation.
+    // TODO: Screw it, I'll let bunnei figure out how to do this properly.
+    if ((addr >= VRAM_VADDR) && (addr < VRAM_VADDR_END)) {
+        return addr - 0x07000000;
+    } else if ((addr >= FCRAM_VADDR) && (addr < FCRAM_VADDR_END)) {
+        return addr - FCRAM_VADDR + FCRAM_PADDR;
     }
+
+    ERROR_LOG(MEMMAP, "Unknown virtual address @ 0x%08x", addr);
     return addr;
 }
 
 template <typename T>
-inline void Read(T &var, const u32 addr) {
+inline void Read(T &var, const u32 vaddr) {
     // TODO: Figure out the fastest order of tests for both read and write (they are probably different).
     // TODO: Make sure this represents the mirrors in a correct way.
     // Could just do a base-relative read, too.... TODO
 
-    const u32 vaddr = _VirtualAddress(addr);
-
     // Kernel memory command buffer
     if (vaddr >= KERNEL_MEMORY_VADDR && vaddr < KERNEL_MEMORY_VADDR_END) {
         var = *((const T*)&g_kernel_mem[vaddr & KERNEL_MEMORY_MASK]);
@@ -91,9 +98,8 @@ inline void Read(T &var, const u32 addr) {
 }
 
 template <typename T>
-inline void Write(u32 addr, const T data) {
-    u32 vaddr = _VirtualAddress(addr);
-    
+inline void Write(u32 vaddr, const T data) {
+
     // Kernel memory command buffer
     if (vaddr >= KERNEL_MEMORY_VADDR && vaddr < KERNEL_MEMORY_VADDR_END) {
         *(T*)&g_kernel_mem[vaddr & KERNEL_MEMORY_MASK] = data;
@@ -133,16 +139,14 @@ inline void Write(u32 addr, const T data) {
     //    _assert_msg_(MEMMAP, false, "umimplemented write to Configuration Memory");
     //} else if ((vaddr & 0xFFFFF000) == 0x1FF81000) {
     //    _assert_msg_(MEMMAP, false, "umimplemented write to shared page");
-    
+
     // Error out...
     } else {
         ERROR_LOG(MEMMAP, "unknown Write%d 0x%08X @ 0x%08X", sizeof(data) * 8, data, vaddr);
     }
 }
 
-u8 *GetPointer(const u32 addr) {
-    const u32 vaddr = _VirtualAddress(addr);
-
+u8 *GetPointer(const u32 vaddr) {
     // Kernel memory command buffer
     if (vaddr >= KERNEL_MEMORY_VADDR && vaddr < KERNEL_MEMORY_VADDR_END) {
         return g_kernel_mem + (vaddr & KERNEL_MEMORY_MASK);
@@ -185,12 +189,12 @@ u8 *GetPointer(const u32 addr) {
  */
 u32 MapBlock_Heap(u32 size, u32 operation, u32 permissions) {
     MemoryBlock block;
-    
+
     block.base_address  = HEAP_VADDR;
     block.size          = size;
     block.operation     = operation;
     block.permissions   = permissions;
-    
+
     if (g_heap_map.size() > 0) {
         const MemoryBlock last_block = g_heap_map.rbegin()->second;
         block.address = last_block.address + last_block.size;
@@ -208,12 +212,12 @@ u32 MapBlock_Heap(u32 size, u32 operation, u32 permissions) {
  */
 u32 MapBlock_HeapGSP(u32 size, u32 operation, u32 permissions) {
     MemoryBlock block;
-    
+
     block.base_address  = HEAP_GSP_VADDR;
     block.size          = size;
     block.operation     = operation;
     block.permissions   = permissions;
-    
+
     if (g_heap_gsp_map.size() > 0) {
         const MemoryBlock last_block = g_heap_gsp_map.rbegin()->second;
         block.address = last_block.address + last_block.size;
-- 
cgit v1.2.3-70-g09d2