diff options
author | Yuri Kunde Schlesner <yuriks@yuriks.net> | 2015-05-12 22:38:29 -0300 |
---|---|---|
committer | Yuri Kunde Schlesner <yuriks@yuriks.net> | 2015-05-15 00:04:38 -0300 |
commit | 7ada357b2d12cf616672425a8961804b865354d6 (patch) | |
tree | 983003c1efc0950605eca3aa7d135b7c8fe9edcf /src/core/memory.cpp | |
parent | a251721bf3a053ea012ac0b891826f3246273c82 (diff) |
Memmap: Re-organize memory function in two files
memory.cpp/h contains definitions related to acessing memory and
configuring the address space
mem_map.cpp/h contains higher-level definitions related to configuring
the address space accoording to the kernel and allocating memory.
Diffstat (limited to 'src/core/memory.cpp')
-rw-r--r-- | src/core/memory.cpp | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/src/core/memory.cpp b/src/core/memory.cpp new file mode 100644 index 0000000000..517167b0ad --- /dev/null +++ b/src/core/memory.cpp @@ -0,0 +1,197 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "common/common_types.h" +#include "common/logging/log.h" +#include "common/swap.h" + +#include "core/hle/config_mem.h" +#include "core/hle/shared_page.h" +#include "core/hw/hw.h" +#include "core/mem_map.h" +#include "core/memory.h" + +namespace Memory { + +template <typename T> +inline void Read(T &var, const VAddr 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 + + // Kernel memory command buffer + if (vaddr >= TLS_AREA_VADDR && vaddr < TLS_AREA_VADDR_END) { + var = *((const T*)&g_tls_mem[vaddr - TLS_AREA_VADDR]); + + // ExeFS:/.code is loaded here + } else if ((vaddr >= PROCESS_IMAGE_VADDR) && (vaddr < PROCESS_IMAGE_VADDR_END)) { + var = *((const T*)&g_exefs_code[vaddr - PROCESS_IMAGE_VADDR]); + + // FCRAM - linear heap + } else if ((vaddr >= LINEAR_HEAP_VADDR) && (vaddr < LINEAR_HEAP_VADDR_END)) { + var = *((const T*)&g_heap_linear[vaddr - LINEAR_HEAP_VADDR]); + + // FCRAM - application heap + } else if ((vaddr >= HEAP_VADDR) && (vaddr < HEAP_VADDR_END)) { + var = *((const T*)&g_heap[vaddr - HEAP_VADDR]); + + // Shared memory + } else if ((vaddr >= SHARED_MEMORY_VADDR) && (vaddr < SHARED_MEMORY_VADDR_END)) { + var = *((const T*)&g_shared_mem[vaddr - SHARED_MEMORY_VADDR]); + + // Config memory + } else if ((vaddr >= CONFIG_MEMORY_VADDR) && (vaddr < CONFIG_MEMORY_VADDR_END)) { + ConfigMem::Read<T>(var, vaddr); + + // Shared page + } else if ((vaddr >= SHARED_PAGE_VADDR) && (vaddr < SHARED_PAGE_VADDR_END)) { + SharedPage::Read<T>(var, vaddr); + + // DSP memory + } else if ((vaddr >= DSP_RAM_VADDR) && (vaddr < DSP_RAM_VADDR_END)) { + var = *((const T*)&g_dsp_mem[vaddr - DSP_RAM_VADDR]); + + // VRAM + } else if ((vaddr >= VRAM_VADDR) && (vaddr < VRAM_VADDR_END)) { + var = *((const T*)&g_vram[vaddr - VRAM_VADDR]); + + } else { + LOG_ERROR(HW_Memory, "unknown Read%lu @ 0x%08X", sizeof(var) * 8, vaddr); + } +} + +template <typename T> +inline void Write(const VAddr vaddr, const T data) { + + // Kernel memory command buffer + if (vaddr >= TLS_AREA_VADDR && vaddr < TLS_AREA_VADDR_END) { + *(T*)&g_tls_mem[vaddr - TLS_AREA_VADDR] = data; + + // ExeFS:/.code is loaded here + } else if ((vaddr >= PROCESS_IMAGE_VADDR) && (vaddr < PROCESS_IMAGE_VADDR_END)) { + *(T*)&g_exefs_code[vaddr - PROCESS_IMAGE_VADDR] = data; + + // FCRAM - linear heap + } else if ((vaddr >= LINEAR_HEAP_VADDR) && (vaddr < LINEAR_HEAP_VADDR_END)) { + *(T*)&g_heap_linear[vaddr - LINEAR_HEAP_VADDR] = data; + + // FCRAM - application heap + } else if ((vaddr >= HEAP_VADDR) && (vaddr < HEAP_VADDR_END)) { + *(T*)&g_heap[vaddr - HEAP_VADDR] = data; + + // Shared memory + } else if ((vaddr >= SHARED_MEMORY_VADDR) && (vaddr < SHARED_MEMORY_VADDR_END)) { + *(T*)&g_shared_mem[vaddr - SHARED_MEMORY_VADDR] = data; + + // VRAM + } else if ((vaddr >= VRAM_VADDR) && (vaddr < VRAM_VADDR_END)) { + *(T*)&g_vram[vaddr - VRAM_VADDR] = data; + + // DSP memory + } else if ((vaddr >= DSP_RAM_VADDR) && (vaddr < DSP_RAM_VADDR_END)) { + *(T*)&g_dsp_mem[vaddr - DSP_RAM_VADDR] = data; + + //} else if ((vaddr & 0xFFFF0000) == 0x1FF80000) { + // 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 { + LOG_ERROR(HW_Memory, "unknown Write%lu 0x%08X @ 0x%08X", sizeof(data) * 8, (u32)data, vaddr); + } +} + +u8 *GetPointer(const VAddr vaddr) { + // Kernel memory command buffer + if (vaddr >= TLS_AREA_VADDR && vaddr < TLS_AREA_VADDR_END) { + return g_tls_mem + (vaddr - TLS_AREA_VADDR); + + // ExeFS:/.code is loaded here + } else if ((vaddr >= PROCESS_IMAGE_VADDR) && (vaddr < PROCESS_IMAGE_VADDR_END)) { + return g_exefs_code + (vaddr - PROCESS_IMAGE_VADDR); + + // FCRAM - linear heap + } else if ((vaddr >= LINEAR_HEAP_VADDR) && (vaddr < LINEAR_HEAP_VADDR_END)) { + return g_heap_linear + (vaddr - LINEAR_HEAP_VADDR); + + // FCRAM - application heap + } else if ((vaddr >= HEAP_VADDR) && (vaddr < HEAP_VADDR_END)) { + return g_heap + (vaddr - HEAP_VADDR); + + // Shared memory + } else if ((vaddr >= SHARED_MEMORY_VADDR) && (vaddr < SHARED_MEMORY_VADDR_END)) { + return g_shared_mem + (vaddr - SHARED_MEMORY_VADDR); + + // VRAM + } else if ((vaddr >= VRAM_VADDR) && (vaddr < VRAM_VADDR_END)) { + return g_vram + (vaddr - VRAM_VADDR); + + } else { + LOG_ERROR(HW_Memory, "unknown GetPointer @ 0x%08x", vaddr); + return 0; + } +} + +u8* GetPhysicalPointer(PAddr address) { + return GetPointer(PhysicalToVirtualAddress(address)); +} + +u8 Read8(const VAddr addr) { + u8 data = 0; + Read<u8>(data, addr); + return data; +} + +u16 Read16(const VAddr addr) { + u16_le data = 0; + Read<u16_le>(data, addr); + return data; +} + +u32 Read32(const VAddr addr) { + u32_le data = 0; + Read<u32_le>(data, addr); + return data; +} + +u64 Read64(const VAddr addr) { + u64_le data = 0; + Read<u64_le>(data, addr); + return data; +} + +void Write8(const VAddr addr, const u8 data) { + Write<u8>(addr, data); +} + +void Write16(const VAddr addr, const u16 data) { + Write<u16_le>(addr, data); +} + +void Write32(const VAddr addr, const u32 data) { + Write<u32_le>(addr, data); +} + +void Write64(const VAddr addr, const u64 data) { + Write<u64_le>(addr, data); +} + +void WriteBlock(const VAddr addr, const u8* data, const size_t size) { + u32 offset = 0; + while (offset < (size & ~3)) { + Write32(addr + offset, *(u32*)&data[offset]); + offset += 4; + } + + if (size & 2) { + Write16(addr + offset, *(u16*)&data[offset]); + offset += 2; + } + + if (size & 1) + Write8(addr + offset, data[offset]); +} + +} // namespace |