mem_map_funcs.cpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. // Copyright 2014 Citra Emulator Project
  2. // Licensed under GPLv2
  3. // Refer to the license.txt file included.
  4. #include <map>
  5. #include "common/common.h"
  6. #include "core/mem_map.h"
  7. #include "core/hw/hw.h"
  8. #include "hle/hle.h"
  9. #include "hle/config_mem.h"
  10. namespace Memory {
  11. std::map<u32, MemoryBlock> g_heap_map;
  12. std::map<u32, MemoryBlock> g_heap_gsp_map;
  13. std::map<u32, MemoryBlock> g_shared_map;
  14. /// Convert a physical address (or firmware-specific virtual address) to primary virtual address
  15. u32 _VirtualAddress(const u32 addr) {
  16. // Our memory interface read/write functions assume virtual addresses. Put any physical address
  17. // to virtual address translations here. This is obviously quite hacky... But we're not doing
  18. // any MMU emulation yet or anything
  19. if ((addr >= FCRAM_PADDR) && (addr < FCRAM_PADDR_END)) {
  20. return VirtualAddressFromPhysical_FCRAM(addr);
  21. // Virtual address mapping FW0B
  22. } else if ((addr >= FCRAM_VADDR_FW0B) && (addr < FCRAM_VADDR_FW0B_END)) {
  23. return VirtualAddressFromPhysical_FCRAM(addr);
  24. // Hardware IO
  25. // TODO(bunnei): FixMe
  26. // This isn't going to work... The physical address of HARDWARE_IO conflicts with the virtual
  27. // address of shared memory.
  28. //} else if ((addr >= HARDWARE_IO_PADDR) && (addr < HARDWARE_IO_PADDR_END)) {
  29. // return (addr + 0x0EB00000);
  30. }
  31. return addr;
  32. }
  33. template <typename T>
  34. inline void _Read(T &var, const u32 addr) {
  35. // TODO: Figure out the fastest order of tests for both read and write (they are probably different).
  36. // TODO: Make sure this represents the mirrors in a correct way.
  37. // Could just do a base-relative read, too.... TODO
  38. const u32 vaddr = _VirtualAddress(addr);
  39. // Kernel memory command buffer
  40. if (vaddr >= KERNEL_MEMORY_VADDR && vaddr < KERNEL_MEMORY_VADDR_END) {
  41. var = *((const T*)&g_kernel_mem[vaddr & KERNEL_MEMORY_MASK]);
  42. // Hardware I/O register reads
  43. // 0x10XXXXXX- is physical address space, 0x1EXXXXXX is virtual address space
  44. } else if ((vaddr >= HARDWARE_IO_VADDR) && (vaddr < HARDWARE_IO_VADDR_END)) {
  45. HW::Read<T>(var, vaddr);
  46. // ExeFS:/.code is loaded here
  47. } else if ((vaddr >= EXEFS_CODE_VADDR) && (vaddr < EXEFS_CODE_VADDR_END)) {
  48. var = *((const T*)&g_exefs_code[vaddr & EXEFS_CODE_MASK]);
  49. // FCRAM - GSP heap
  50. } else if ((vaddr >= HEAP_GSP_VADDR) && (vaddr < HEAP_GSP_VADDR_END)) {
  51. var = *((const T*)&g_heap_gsp[vaddr & HEAP_GSP_MASK]);
  52. // FCRAM - application heap
  53. } else if ((vaddr >= HEAP_VADDR) && (vaddr < HEAP_VADDR_END)) {
  54. var = *((const T*)&g_heap[vaddr & HEAP_MASK]);
  55. // Shared memory
  56. } else if ((vaddr >= SHARED_MEMORY_VADDR) && (vaddr < SHARED_MEMORY_VADDR_END)) {
  57. var = *((const T*)&g_shared_mem[vaddr & SHARED_MEMORY_MASK]);
  58. // Config memory
  59. } else if ((vaddr >= CONFIG_MEMORY_VADDR) && (vaddr < CONFIG_MEMORY_VADDR_END)) {
  60. ConfigMem::Read<T>(var, vaddr);
  61. // VRAM
  62. } else if ((vaddr >= VRAM_VADDR) && (vaddr < VRAM_VADDR_END)) {
  63. var = *((const T*)&g_vram[vaddr & VRAM_MASK]);
  64. } else {
  65. //_assert_msg_(MEMMAP, false, "unknown Read%d @ 0x%08X", sizeof(var) * 8, vaddr);
  66. }
  67. }
  68. template <typename T>
  69. inline void _Write(u32 addr, const T data) {
  70. u32 vaddr = _VirtualAddress(addr);
  71. // Kernel memory command buffer
  72. if (vaddr >= KERNEL_MEMORY_VADDR && vaddr < KERNEL_MEMORY_VADDR_END) {
  73. *(T*)&g_kernel_mem[vaddr & KERNEL_MEMORY_MASK] = data;
  74. // Hardware I/O register writes
  75. // 0x10XXXXXX- is physical address space, 0x1EXXXXXX is virtual address space
  76. } else if ((vaddr >= HARDWARE_IO_VADDR) && (vaddr < HARDWARE_IO_VADDR_END)) {
  77. HW::Write<T>(vaddr, data);
  78. // ExeFS:/.code is loaded here
  79. } else if ((vaddr >= EXEFS_CODE_VADDR) && (vaddr < EXEFS_CODE_VADDR_END)) {
  80. *(T*)&g_exefs_code[vaddr & EXEFS_CODE_MASK] = data;
  81. // FCRAM - GSP heap
  82. } else if ((vaddr >= HEAP_GSP_VADDR) && (vaddr < HEAP_GSP_VADDR_END)) {
  83. *(T*)&g_heap_gsp[vaddr & HEAP_GSP_MASK] = data;
  84. // FCRAM - application heap
  85. } else if ((vaddr >= HEAP_VADDR) && (vaddr < HEAP_VADDR_END)) {
  86. *(T*)&g_heap[vaddr & HEAP_MASK] = data;
  87. // Shared memory
  88. } else if ((vaddr >= SHARED_MEMORY_VADDR) && (vaddr < SHARED_MEMORY_VADDR_END)) {
  89. *(T*)&g_shared_mem[vaddr & SHARED_MEMORY_MASK] = data;
  90. // VRAM
  91. } else if ((vaddr >= VRAM_VADDR) && (vaddr < VRAM_VADDR_END)) {
  92. *(T*)&g_vram[vaddr & VRAM_MASK] = data;
  93. //} else if ((vaddr & 0xFFF00000) == 0x1FF00000) {
  94. // _assert_msg_(MEMMAP, false, "umimplemented write to DSP memory");
  95. //} else if ((vaddr & 0xFFFF0000) == 0x1FF80000) {
  96. // _assert_msg_(MEMMAP, false, "umimplemented write to Configuration Memory");
  97. //} else if ((vaddr & 0xFFFFF000) == 0x1FF81000) {
  98. // _assert_msg_(MEMMAP, false, "umimplemented write to shared page");
  99. // Error out...
  100. } else {
  101. _assert_msg_(MEMMAP, false, "unknown Write%d 0x%08X @ 0x%08X", sizeof(data) * 8,
  102. data, vaddr);
  103. }
  104. }
  105. u8 *GetPointer(const u32 addr) {
  106. const u32 vaddr = _VirtualAddress(addr);
  107. // Kernel memory command buffer
  108. if (vaddr >= KERNEL_MEMORY_VADDR && vaddr < KERNEL_MEMORY_VADDR_END) {
  109. return g_kernel_mem + (vaddr & KERNEL_MEMORY_MASK);
  110. // ExeFS:/.code is loaded here
  111. } else if ((vaddr >= EXEFS_CODE_VADDR) && (vaddr < EXEFS_CODE_VADDR_END)) {
  112. return g_exefs_code + (vaddr & EXEFS_CODE_MASK);
  113. // FCRAM - GSP heap
  114. } else if ((vaddr >= HEAP_GSP_VADDR) && (vaddr < HEAP_GSP_VADDR_END)) {
  115. return g_heap_gsp + (vaddr & HEAP_GSP_MASK);
  116. // FCRAM - application heap
  117. } else if ((vaddr >= HEAP_VADDR) && (vaddr < HEAP_VADDR_END)) {
  118. return g_heap + (vaddr & HEAP_MASK);
  119. // Shared memory
  120. } else if ((vaddr > SHARED_MEMORY_VADDR) && (vaddr < SHARED_MEMORY_VADDR_END)) {
  121. return g_shared_mem + (vaddr & SHARED_MEMORY_MASK);
  122. // VRAM
  123. } else if ((vaddr > VRAM_VADDR) && (vaddr < VRAM_VADDR_END)) {
  124. return g_vram + (vaddr & VRAM_MASK);
  125. } else {
  126. ERROR_LOG(MEMMAP, "unknown GetPointer @ 0x%08x", vaddr);
  127. return 0;
  128. }
  129. }
  130. /**
  131. * Maps a block of memory in shared memory
  132. * @param handle Handle to map memory block for
  133. * @param addr Address to map memory block to
  134. * @param permissions Memory map permissions
  135. */
  136. u32 MapBlock_Shared(u32 handle, u32 addr,u32 permissions) {
  137. MemoryBlock block;
  138. block.handle = handle;
  139. block.base_address = addr;
  140. block.permissions = permissions;
  141. if (g_shared_map.size() > 0) {
  142. const MemoryBlock last_block = g_shared_map.rbegin()->second;
  143. block.address = last_block.address + last_block.size;
  144. }
  145. g_shared_map[block.GetVirtualAddress()] = block;
  146. return block.GetVirtualAddress();
  147. }
  148. /**
  149. * Maps a block of memory on the heap
  150. * @param size Size of block in bytes
  151. * @param operation Memory map operation type
  152. * @param flags Memory allocation flags
  153. */
  154. u32 MapBlock_Heap(u32 size, u32 operation, u32 permissions) {
  155. MemoryBlock block;
  156. block.base_address = HEAP_VADDR;
  157. block.size = size;
  158. block.operation = operation;
  159. block.permissions = permissions;
  160. if (g_heap_map.size() > 0) {
  161. const MemoryBlock last_block = g_heap_map.rbegin()->second;
  162. block.address = last_block.address + last_block.size;
  163. }
  164. g_heap_map[block.GetVirtualAddress()] = block;
  165. return block.GetVirtualAddress();
  166. }
  167. /**
  168. * Maps a block of memory on the GSP heap
  169. * @param size Size of block in bytes
  170. * @param operation Memory map operation type
  171. * @param flags Memory allocation flags
  172. */
  173. u32 MapBlock_HeapGSP(u32 size, u32 operation, u32 permissions) {
  174. MemoryBlock block;
  175. block.base_address = HEAP_GSP_VADDR;
  176. block.size = size;
  177. block.operation = operation;
  178. block.permissions = permissions;
  179. if (g_heap_gsp_map.size() > 0) {
  180. const MemoryBlock last_block = g_heap_gsp_map.rbegin()->second;
  181. block.address = last_block.address + last_block.size;
  182. }
  183. g_heap_gsp_map[block.GetVirtualAddress()] = block;
  184. return block.GetVirtualAddress();
  185. }
  186. u8 Read8(const u32 addr) {
  187. u8 _var = 0;
  188. _Read<u8>(_var, addr);
  189. return (u8)_var;
  190. }
  191. u16 Read16(const u32 addr) {
  192. u16_le _var = 0;
  193. _Read<u16_le>(_var, addr);
  194. return (u16)_var;
  195. }
  196. u32 Read32(const u32 addr) {
  197. u32_le _var = 0;
  198. _Read<u32_le>(_var, addr);
  199. return _var;
  200. }
  201. u64 Read64(const u32 addr) {
  202. u64_le _var = 0;
  203. _Read<u64_le>(_var, addr);
  204. return _var;
  205. }
  206. u32 Read8_ZX(const u32 addr) {
  207. return (u32)Read8(addr);
  208. }
  209. u32 Read16_ZX(const u32 addr) {
  210. return (u32)Read16(addr);
  211. }
  212. void Write8(const u32 addr, const u8 data) {
  213. _Write<u8>(addr, data);
  214. }
  215. void Write16(const u32 addr, const u16 data) {
  216. _Write<u16_le>(addr, data);
  217. }
  218. void Write32(const u32 addr, const u32 data) {
  219. _Write<u32_le>(addr, data);
  220. }
  221. void Write64(const u32 addr, const u64 data) {
  222. _Write<u64_le>(addr, data);
  223. }
  224. } // namespace