1#include <memory/memory.h>
11#include <loader/xex.h>
16extern uint32_t mainThreadStackSize;
18std::vector<AllocInfo> allocInfo;
20uint8_t** readPages, **writePages;
21#define PAGE_SIZE (4*1024)
22#define MAX_ADDRESS_SPACE 0xFFFF0000
23std::bitset<MAX_ADDRESS_SPACE / PAGE_SIZE> usedPages;
25void Memory::Initialize()
27 readPages =
new uint8_t*[MAX_ADDRESS_SPACE / PAGE_SIZE];
28 writePages =
new uint8_t*[MAX_ADDRESS_SPACE / PAGE_SIZE];
31 for (
size_t i = 0; i < 64*1024; i += 4096)
32 usedPages[i / 4096] =
true;
37 std::ofstream file(
"mem.dump");
38 for (uint32_t i = mainXexBase; i < mainXexBase+mainXexSize; i += 4)
40 uint32_t data = bswap32(Read32(i));
41 file.write((
char*)&data, 4);
45 file.open(
"stack.dump");
46 for (uint32_t i = 0x70000000; i < 0x70000000+mainThreadStackSize; i += 4)
48 uint32_t data = bswap32(Read32(i));
49 file.write((
char*)&data, 4);
54void *Memory::AllocMemory(uint32_t baseAddress, uint32_t size)
56 void* ret = mmap((
void*)baseAddress, size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
58 if (ret == MAP_FAILED)
60 printf(
"Failed to allocate memory: %s\n", strerror(errno));
64 size = (size + PAGE_SIZE) & ~PAGE_SIZE;
66 for (
int i = 0; i < size; i += PAGE_SIZE)
68 readPages[(baseAddress + i) / PAGE_SIZE] = ((uint8_t*)ret+i);
69 writePages[(baseAddress + i) / PAGE_SIZE] = ((uint8_t*)ret+i);
75uint32_t Memory::VirtAllocMemoryRange(uint32_t beginAddr, uint32_t endAddr, uint32_t size)
77 uint32_t requiredPages = size / PAGE_SIZE;
80 uint32_t candidate = 0;
81 uint32_t freePages = 0;
82 for (uint32_t i = beginAddr; i < endAddr; i += PAGE_SIZE)
84 if (!candidate && !usedPages[i / PAGE_SIZE])
86 candidate = i / PAGE_SIZE;
89 else if (!usedPages[i / PAGE_SIZE])
92 if (freePages == requiredPages)
103 printf(
"ERROR: Failed to allocate virtual memory in range [0x%08x -> 0x%08x]\n", beginAddr, endAddr);
108 for (
int i = 0; i < requiredPages; i++)
109 usedPages.set(candidate+i,
true);
112 info.baseAddress = candidate*PAGE_SIZE;
113 info.regionSize = requiredPages*PAGE_SIZE;
114 allocInfo.push_back(info);
116 return candidate*PAGE_SIZE;
119uint8_t *Memory::GetRawPtrForAddr(uint32_t addr)
121 if (!readPages[addr / PAGE_SIZE])
123 printf(
"Read raw ptr from unmapped addr 0x%08x\n", addr);
127 return &readPages[addr / PAGE_SIZE][addr % PAGE_SIZE];
130bool Memory::GetAllocInfo(uint32_t addr,
AllocInfo& outInfo)
132 for (
auto& info : allocInfo)
134 if (info.baseAddress <= addr && info.baseAddress+info.regionSize > addr)
141 printf(
"Failed to get allocation info for region 0x%08x\n", addr);
145uint8_t Memory::Read8(uint32_t addr,
bool slow)
149 if (!readPages[addr / PAGE_SIZE])
151 return Read8(addr,
true);
154 return readPages[addr / PAGE_SIZE][addr % PAGE_SIZE];
163 printf(
"Read8 from unmapped addr 0x%08x\n", addr);
169uint16_t Memory::Read16(uint32_t addr,
bool slow)
173 if (!readPages[addr / PAGE_SIZE])
175 return Read16(addr,
true);
178 return bswap16(*(uint16_t*)&readPages[addr / PAGE_SIZE][addr % PAGE_SIZE]);
189 return bswap16(0x4f80);
198 printf(
"Read16 from unmapped address 0x%08x\n", addr);
204uint32_t Memory::Read32(uint32_t addr,
bool slow)
208 if (!readPages[addr / PAGE_SIZE])
210 return Read32(addr,
true);
213 return bswap32(*(uint32_t*)&readPages[addr / PAGE_SIZE][addr % PAGE_SIZE]);
217 static int system_ticks = 0;
223 return bswap32(system_ticks++);
225 return bswap32(0x20);
227 return bswap32(0x2000000);
229 printf(
"Read32 from unmapped address 0x%08x\n", addr);
235uint64_t Memory::Read64(uint32_t addr)
237 if (!readPages[addr / PAGE_SIZE])
239 printf(
"Read64 from unmapped addr 0x%08x\n", addr);
243 return bswap64(*(uint64_t*)&readPages[addr / PAGE_SIZE][addr % PAGE_SIZE]);
246unsigned __int128 swap(
unsigned __int128 n)
249 const uint64_t* src = (
const uint64_t*)(&n);
250 uint64_t* dest = (uint64_t*)(&m);
251 dest[1] = bswap64(src[0]);
252 dest[0] = bswap64(src[1]);
256__uint128_t Memory::Read128(uint32_t addr)
258 if (!readPages[addr / PAGE_SIZE])
260 printf(
"Read128 from unmapped addr 0x%08x\n", addr);
264 __uint128_t t = *(__uint128_t*)&readPages[addr / PAGE_SIZE][addr % PAGE_SIZE];
268void Memory::Write8(uint32_t addr, uint8_t data)
270 if (!writePages[addr / PAGE_SIZE])
272 printf(
"Write8 to unmapped addr 0x%08x\n", addr);
276 writePages[addr / PAGE_SIZE][addr % PAGE_SIZE] = data;
279void Memory::Write16(uint32_t addr, uint16_t data)
281 if (!writePages[addr / PAGE_SIZE])
283 printf(
"Write16 to unmapped addr 0x%08x\n", addr);
287 *(uint16_t*)&writePages[addr / PAGE_SIZE][addr % PAGE_SIZE] = bswap16(data);
290void Memory::Write32(uint32_t addr, uint32_t data)
292 if (!writePages[addr / PAGE_SIZE])
294 printf(
"Write32 to unmapped addr 0x%08x\n", addr);
298 *(uint32_t*)&writePages[addr / PAGE_SIZE][addr % PAGE_SIZE] = bswap32(data);
301void Memory::Write64(uint32_t addr, uint64_t data)
303 if (!writePages[addr / PAGE_SIZE])
305 printf(
"Write64 to unmapped addr 0x%08x\n", addr);
309 *(uint64_t*)&writePages[addr / PAGE_SIZE][addr % PAGE_SIZE] = bswap64(data);
312void Memory::Write128(uint32_t addr, __uint128_t data)
314 if (!writePages[addr / PAGE_SIZE])
316 printf(
"Write64 to unmapped addr 0x%08x\n", addr);
321 *(__uint128_t*)&writePages[addr / PAGE_SIZE][addr % PAGE_SIZE] = data;