summaryrefslogtreecommitdiff
path: root/src/core/mem_map_funcs.cpp
diff options
context:
space:
mode:
authorGravatar bunnei2014-04-17 18:40:42 -0400
committerGravatar bunnei2014-04-17 18:40:42 -0400
commitae99574b6dd2f21960bd42e0bb9a1978e18413d4 (patch)
treeb3b03484e87c67ed6008eb142706f2b126f75197 /src/core/mem_map_funcs.cpp
parentfixed framebuffer color order (diff)
downloadyuzu-ae99574b6dd2f21960bd42e0bb9a1978e18413d4.tar.gz
yuzu-ae99574b6dd2f21960bd42e0bb9a1978e18413d4.tar.xz
yuzu-ae99574b6dd2f21960bd42e0bb9a1978e18413d4.zip
cleaned up memory interfaces a lot, removed some hackish stuff
Diffstat (limited to 'src/core/mem_map_funcs.cpp')
-rw-r--r--src/core/mem_map_funcs.cpp144
1 files changed, 48 insertions, 96 deletions
diff --git a/src/core/mem_map_funcs.cpp b/src/core/mem_map_funcs.cpp
index 3e85a119f..bb83855fe 100644
--- a/src/core/mem_map_funcs.cpp
+++ b/src/core/mem_map_funcs.cpp
@@ -10,154 +10,106 @@
10 10
11namespace Memory { 11namespace Memory {
12 12
13/// Convert a physical address to virtual address
14u32 _AddressPhysicalToVirtual(const u32 addr) {
15 // Our memory interface read/write functions assume virtual addresses. Put any physical address
16 // to virtual address translations here. This is obviously quite hacky... But we're not doing
17 // any MMU emulation yet or anything
18 if (((addr & 0xF0000000) == MEM_FCRAM_PADDR) && (addr < (MEM_FCRAM_PADDR_END))) {
19 return (addr & MEM_FCRAM_MASK) | MEM_FCRAM_VADDR;
20 }
21 return addr;
22}
23
13template <typename T> 24template <typename T>
14inline void _Read(T &var, const u32 addr) { 25inline void _Read(T &var, const u32 addr) {
15 // TODO: Figure out the fastest order of tests for both read and write (they are probably different). 26 // TODO: Figure out the fastest order of tests for both read and write (they are probably different).
16 // TODO: Make sure this represents the mirrors in a correct way. 27 // TODO: Make sure this represents the mirrors in a correct way.
17 // Could just do a base-relative read, too.... TODO 28 // Could just do a base-relative read, too.... TODO
18 29
30 const u32 vaddr = _AddressPhysicalToVirtual(addr);
19 31
20 // Memory allocated for HLE use that can be addressed from the emulated application 32 // Memory allocated for HLE use that can be addressed from the emulated application
21 // The primary use of this is sharing a commandbuffer between the HLE OS (syscore) and the LLE 33 // The primary use of this is sharing a commandbuffer between the HLE OS (syscore) and the LLE
22 // core running the user application (appcore) 34 // core running the user application (appcore)
23 if (addr >= HLE::CMD_BUFFER_ADDR && addr < HLE::CMD_BUFFER_ADDR_END) { 35 if (vaddr >= HLE::CMD_BUFFER_ADDR && vaddr < HLE::CMD_BUFFER_ADDR_END) {
24 HLE::Read<T>(var, addr); 36 HLE::Read<T>(var, vaddr);
25 37
26 // Hardware I/O register reads 38 // Hardware I/O register reads
27 // 0x10XXXXXX- is physical address space, 0x1EXXXXXX is virtual address space 39 // 0x10XXXXXX- is physical address space, 0x1EXXXXXX is virtual address space
28 } else if ((addr & 0xFF000000) == 0x10000000 || (addr & 0xFF000000) == 0x1E000000) { 40 } else if ((vaddr & 0xFF000000) == 0x10000000 || (vaddr & 0xFF000000) == 0x1E000000) {
29 HW::Read<T>(var, addr); 41 HW::Read<T>(var, vaddr);
30 42
31 // FCRAM virtual address reads 43 // FCRAM
32 } else if ((addr & 0x3E000000) == 0x08000000) { 44 } else if ((vaddr > MEM_FCRAM_VADDR) && (vaddr < MEM_FCRAM_VADDR_END)) {
33 var = *((const T*)&g_fcram[addr & MEM_FCRAM_MASK]); 45 var = *((const T*)&g_fcram[vaddr & MEM_FCRAM_MASK]);
34 46
35 // Scratchpad memory 47 /*else if ((vaddr & 0x3F800000) == 0x04000000) {
36 } else if (addr > MEM_SCRATCHPAD_VADDR && addr <= (MEM_SCRATCHPAD_VADDR + MEM_SCRATCHPAD_SIZE)) { 48 var = *((const T*)&m_pVRAM[vaddr & VRAM_MASK]);*/
37 var = *((const T*)&g_scratchpad[addr & MEM_SCRATCHPAD_MASK]);
38
39 /*else if ((addr & 0x3F800000) == 0x04000000) {
40 var = *((const T*)&m_pVRAM[addr & VRAM_MASK]);
41 }*/
42
43 // HACK(bunnei): There is no layer yet to translate virtual addresses to physical addresses.
44 // Until we progress far enough along, we'll accept all physical address reads here. I think
45 // that this is typically a corner-case from usermode software unless they are trying to do
46 // bare-metal things (e.g. early 3DS homebrew writes directly to the FB @ 0x20184E60, etc.
47 } else if (((addr & 0xF0000000) == MEM_FCRAM_PADDR) && (addr < (MEM_FCRAM_PADDR_END))) {
48 var = *((const T*)&g_fcram[addr & MEM_FCRAM_MASK]);
49 49
50 } else { 50 } else {
51 _assert_msg_(MEMMAP, false, "unknown Read%d @ 0x%08X", sizeof(var) * 8, addr); 51 _assert_msg_(MEMMAP, false, "unknown Read%d @ 0x%08X", sizeof(var) * 8, vaddr);
52 } 52 }
53} 53}
54 54
55template <typename T> 55template <typename T>
56inline void _Write(u32 addr, const T data) { 56inline void _Write(u32 addr, const T data) {
57 u32 vaddr = _AddressPhysicalToVirtual(addr);
57 58
58 // Memory allocated for HLE use that can be addressed from the emulated application 59 // Memory allocated for HLE use that can be addressed from the emulated application
59 // The primary use of this is sharing a commandbuffer between the HLE OS (syscore) and the LLE 60 // The primary use of this is sharing a commandbuffer between the HLE OS (syscore) and the LLE
60 // core running the user application (appcore) 61 // core running the user application (appcore)
61 if (addr >= HLE::CMD_BUFFER_ADDR && addr < HLE::CMD_BUFFER_ADDR_END) { 62 if (vaddr >= HLE::CMD_BUFFER_ADDR && vaddr < HLE::CMD_BUFFER_ADDR_END) {
62 HLE::Write<T>(addr, data); 63 HLE::Write<T>(vaddr, data);
63 64
64 // Hardware I/O register writes 65 // Hardware I/O register writes
65 // 0x10XXXXXX- is physical address space, 0x1EXXXXXX is virtual address space 66 // 0x10XXXXXX- is physical address space, 0x1EXXXXXX is virtual address space
66 } else if ((addr & 0xFF000000) == 0x10000000 || (addr & 0xFF000000) == 0x1E000000) { 67 } else if ((vaddr & 0xFF000000) == 0x10000000 || (vaddr & 0xFF000000) == 0x1E000000) {
67 HW::Write<T>(addr, data); 68 HW::Write<T>(vaddr, data);
68 69
69 // ExeFS:/.code is loaded here: 70 // ExeFS:/.code is loaded here:
70 } else if ((addr & 0xFFF00000) == 0x00100000) { 71 } else if ((vaddr & 0xFFF00000) == 0x00100000) {
71 // TODO(ShizZy): This is dumb... handle correctly. From 3DBrew: 72 // TODO(ShizZy): This is dumb... handle correctly. From 3DBrew:
72 // http://3dbrew.org/wiki/Memory_layout#ARM11_User-land_memory_regions 73 // http://3dbrew.org/wiki/Memory_layout#ARM11_User-land_memory_regions
73 // The ExeFS:/.code is loaded here, executables must be loaded to the 0x00100000 region when 74 // The ExeFS:/.code is loaded here, executables must be loaded to the 0x00100000 region when
74 // the exheader "special memory" flag is clear. The 0x03F00000-byte size restriction only 75 // the exheader "special memory" flag is clear. The 0x03F00000-byte size restriction only
75 // applies when this flag is clear. Executables are usually loaded to 0x14000000 when the 76 // applies when this flag is clear. Executables are usually loaded to 0x14000000 when the
76 // exheader "special memory" flag is set, however this address can be arbitrary. 77 // exheader "special memory" flag is set, however this address can be arbitrary.
77 *(T*)&g_fcram[addr & MEM_FCRAM_MASK] = data; 78 *(T*)&g_fcram[vaddr & MEM_FCRAM_MASK] = data;
78
79 // Scratchpad memory
80 } else if (addr > MEM_SCRATCHPAD_VADDR && addr <= (MEM_SCRATCHPAD_VADDR + MEM_SCRATCHPAD_SIZE)) {
81 *(T*)&g_scratchpad[addr & MEM_SCRATCHPAD_MASK] = data;
82 79
83 // Heap mapped by ControlMemory: 80 // FCRAM
84 } else if ((addr & 0x3E000000) == 0x08000000) { 81 } else if ((vaddr > MEM_FCRAM_VADDR) && (vaddr < MEM_FCRAM_VADDR_END)) {
85 // TODO(ShizZy): Writes to this virtual address should be put in physical memory at FCRAM + GSP 82 *(T*)&g_fcram[vaddr & MEM_FCRAM_MASK] = data;
86 // heap size... the following is writing to FCRAM + 0, which is actually supposed to be the
87 // application's GSP heap
88 *(T*)&g_fcram[addr & MEM_FCRAM_MASK] = data;
89 83
90 } else if ((addr & 0xFF000000) == 0x14000000) { 84 } else if ((vaddr & 0xFF000000) == 0x14000000) {
91 _assert_msg_(MEMMAP, false, "umimplemented write to GSP heap"); 85 _assert_msg_(MEMMAP, false, "umimplemented write to GSP heap");
92 } else if ((addr & 0xFFF00000) == 0x1EC00000) { 86 } else if ((vaddr & 0xFFF00000) == 0x1EC00000) {
93 _assert_msg_(MEMMAP, false, "umimplemented write to IO registers"); 87 _assert_msg_(MEMMAP, false, "umimplemented write to IO registers");
94 } else if ((addr & 0xFF000000) == 0x1F000000) { 88 } else if ((vaddr & 0xFF000000) == 0x1F000000) {
95 _assert_msg_(MEMMAP, false, "umimplemented write to VRAM"); 89 _assert_msg_(MEMMAP, false, "umimplemented write to VRAM");
96 } else if ((addr & 0xFFF00000) == 0x1FF00000) { 90 } else if ((vaddr & 0xFFF00000) == 0x1FF00000) {
97 _assert_msg_(MEMMAP, false, "umimplemented write to DSP memory"); 91 _assert_msg_(MEMMAP, false, "umimplemented write to DSP memory");
98 } else if ((addr & 0xFFFF0000) == 0x1FF80000) { 92 } else if ((vaddr & 0xFFFF0000) == 0x1FF80000) {
99 _assert_msg_(MEMMAP, false, "umimplemented write to Configuration Memory"); 93 _assert_msg_(MEMMAP, false, "umimplemented write to Configuration Memory");
100 } else if ((addr & 0xFFFFF000) == 0x1FF81000) { 94 } else if ((vaddr & 0xFFFFF000) == 0x1FF81000) {
101 _assert_msg_(MEMMAP, false, "umimplemented write to shared page"); 95 _assert_msg_(MEMMAP, false, "umimplemented write to shared page");
102 96
103 // HACK(bunnei): There is no layer yet to translate virtual addresses to physical addresses.
104 // Until we progress far enough along, we'll accept all physical address writes here. I think
105 // that this is typically a corner-case from usermode software unless they are trying to do
106 // bare-metal things (e.g. early 3DS homebrew writes directly to the FB @ 0x20184E60, etc.
107 } else if (((addr & 0xF0000000) == MEM_FCRAM_PADDR) && (addr < (MEM_FCRAM_PADDR_END))) {
108 *(T*)&g_fcram[addr & MEM_FCRAM_MASK] = data;
109
110 // Error out... 97 // Error out...
111 } else { 98 } else {
112 _assert_msg_(MEMMAP, false, "unknown Write%d 0x%08X @ 0x%08X", sizeof(data) * 8, 99 _assert_msg_(MEMMAP, false, "unknown Write%d 0x%08X @ 0x%08X", sizeof(data) * 8,
113 data, addr); 100 data, vaddr);
114 }
115}
116
117bool IsValidAddress(const u32 addr) {
118 if ((addr & 0x3E000000) == 0x08000000) {
119 return true;
120 } else if ((addr & 0x3F800000) == 0x04000000) {
121 return true;
122 } else if ((addr & 0xBFFF0000) == 0x00010000) {
123 return true;
124 } else if ((addr & 0x3F000000) >= 0x08000000 && (addr & 0x3F000000) < 0x08000000 + MEM_FCRAM_MASK) {
125 return true;
126 } else {
127 return false;
128 } 101 }
129} 102}
130 103
131u8 *GetPointer(const u32 addr) { 104u8 *GetPointer(const u32 addr) {
132 // TODO(bunnei): Just a stub for now... ImplementMe! 105 const u32 vaddr = _AddressPhysicalToVirtual(addr);
133 if ((addr & 0x3E000000) == 0x08000000) { 106
134 return g_fcram + (addr & MEM_FCRAM_MASK); 107 // FCRAM
135 108 if ((vaddr > MEM_FCRAM_VADDR) && (vaddr < MEM_FCRAM_VADDR_END)) {
136 // HACK(bunnei): There is no layer yet to translate virtual addresses to physical addresses. 109 return g_fcram + (vaddr & MEM_FCRAM_MASK);
137 // Until we progress far enough along, we'll accept all physical address reads here. I think 110
138 // that this is typically a corner-case from usermode software unless they are trying to do
139 // bare-metal things (e.g. early 3DS homebrew writes directly to the FB @ 0x20184E60, etc.
140 } else if (((addr & 0xF0000000) == MEM_FCRAM_PADDR) && (addr < (MEM_FCRAM_PADDR_END))) {
141 return g_fcram + (addr & MEM_FCRAM_MASK);
142
143 //else if ((addr & 0x3F800000) == 0x04000000) {
144 // return g_vram + (addr & MEM_VRAM_MASK);
145 //}
146 //else if ((addr & 0x3F000000) >= 0x08000000 && (addr & 0x3F000000) < 0x08000000 + g_MemorySize) {
147 // return m_pRAM + (addr & g_MemoryMask);
148 //}
149 } else { 111 } else {
150 //ERROR_LOG(MEMMAP, "Unknown GetPointer %08x PC %08x LR %08x", addr, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]); 112 ERROR_LOG(MEMMAP, "Unknown GetPointer @ 0x%08x", vaddr);
151 ERROR_LOG(MEMMAP, "Unknown GetPointer %08x", addr);
152 static bool reported = false;
153 //if (!reported) {
154 // Reporting::ReportMessage("Unknown GetPointer %08x PC %08x LR %08x", addr, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]);
155 // reported = true;
156 //}
157 //if (!g_Config.bIgnoreBadMemAccess) {
158 // Core_EnableStepping(true);
159 // host->SetDebugMode(true);
160 //}
161 return 0; 113 return 0;
162 } 114 }
163} 115}