diff options
Diffstat (limited to 'src/core/memory.cpp')
| -rw-r--r-- | src/core/memory.cpp | 51 |
1 files changed, 30 insertions, 21 deletions
diff --git a/src/core/memory.cpp b/src/core/memory.cpp index f658271a5..cc1ed16b6 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #include <algorithm> | 5 | #include <algorithm> |
| 6 | #include <array> | 6 | #include <array> |
| 7 | #include <cinttypes> | ||
| 7 | #include <cstring> | 8 | #include <cstring> |
| 8 | #include <boost/optional.hpp> | 9 | #include <boost/optional.hpp> |
| 9 | #include "common/assert.h" | 10 | #include "common/assert.h" |
| @@ -38,12 +39,12 @@ PageTable* GetCurrentPageTable() { | |||
| 38 | } | 39 | } |
| 39 | 40 | ||
| 40 | static void MapPages(PageTable& page_table, VAddr base, u64 size, u8* memory, PageType type) { | 41 | static void MapPages(PageTable& page_table, VAddr base, u64 size, u8* memory, PageType type) { |
| 41 | LOG_DEBUG(HW_Memory, "Mapping %p onto %08X-%08X", memory, base * PAGE_SIZE, | 42 | LOG_DEBUG(HW_Memory, "Mapping %p onto %016" PRIX64 "-%016" PRIX64, memory, base * PAGE_SIZE, |
| 42 | (base + size) * PAGE_SIZE); | 43 | (base + size) * PAGE_SIZE); |
| 43 | 44 | ||
| 44 | VAddr end = base + size; | 45 | VAddr end = base + size; |
| 45 | while (base != end) { | 46 | while (base != end) { |
| 46 | ASSERT_MSG(base < PAGE_TABLE_NUM_ENTRIES, "out of range mapping at %08X", base); | 47 | ASSERT_MSG(base < PAGE_TABLE_NUM_ENTRIES, "out of range mapping at %016" PRIX64, base); |
| 47 | 48 | ||
| 48 | page_table.attributes[base] = type; | 49 | page_table.attributes[base] = type; |
| 49 | page_table.pointers[base] = memory; | 50 | page_table.pointers[base] = memory; |
| @@ -55,14 +56,14 @@ static void MapPages(PageTable& page_table, VAddr base, u64 size, u8* memory, Pa | |||
| 55 | } | 56 | } |
| 56 | 57 | ||
| 57 | void MapMemoryRegion(PageTable& page_table, VAddr base, u64 size, u8* target) { | 58 | void MapMemoryRegion(PageTable& page_table, VAddr base, u64 size, u8* target) { |
| 58 | ASSERT_MSG((size & PAGE_MASK) == 0, "non-page aligned size: %08X", size); | 59 | ASSERT_MSG((size & PAGE_MASK) == 0, "non-page aligned size: %016" PRIX64, size); |
| 59 | ASSERT_MSG((base & PAGE_MASK) == 0, "non-page aligned base: %08X", base); | 60 | ASSERT_MSG((base & PAGE_MASK) == 0, "non-page aligned base: %016" PRIX64, base); |
| 60 | MapPages(page_table, base / PAGE_SIZE, size / PAGE_SIZE, target, PageType::Memory); | 61 | MapPages(page_table, base / PAGE_SIZE, size / PAGE_SIZE, target, PageType::Memory); |
| 61 | } | 62 | } |
| 62 | 63 | ||
| 63 | void MapIoRegion(PageTable& page_table, VAddr base, u64 size, MemoryHookPointer mmio_handler) { | 64 | void MapIoRegion(PageTable& page_table, VAddr base, u64 size, MemoryHookPointer mmio_handler) { |
| 64 | ASSERT_MSG((size & PAGE_MASK) == 0, "non-page aligned size: %08X", size); | 65 | ASSERT_MSG((size & PAGE_MASK) == 0, "non-page aligned size: %016" PRIX64, size); |
| 65 | ASSERT_MSG((base & PAGE_MASK) == 0, "non-page aligned base: %08X", base); | 66 | ASSERT_MSG((base & PAGE_MASK) == 0, "non-page aligned base: %016" PRIX64, base); |
| 66 | MapPages(page_table, base / PAGE_SIZE, size / PAGE_SIZE, nullptr, PageType::Special); | 67 | MapPages(page_table, base / PAGE_SIZE, size / PAGE_SIZE, nullptr, PageType::Special); |
| 67 | 68 | ||
| 68 | auto interval = boost::icl::discrete_interval<VAddr>::closed(base, base + size - 1); | 69 | auto interval = boost::icl::discrete_interval<VAddr>::closed(base, base + size - 1); |
| @@ -71,8 +72,8 @@ void MapIoRegion(PageTable& page_table, VAddr base, u64 size, MemoryHookPointer | |||
| 71 | } | 72 | } |
| 72 | 73 | ||
| 73 | void UnmapRegion(PageTable& page_table, VAddr base, u64 size) { | 74 | void UnmapRegion(PageTable& page_table, VAddr base, u64 size) { |
| 74 | ASSERT_MSG((size & PAGE_MASK) == 0, "non-page aligned size: %08X", size); | 75 | ASSERT_MSG((size & PAGE_MASK) == 0, "non-page aligned size: %016" PRIX64, size); |
| 75 | ASSERT_MSG((base & PAGE_MASK) == 0, "non-page aligned base: %08X", base); | 76 | ASSERT_MSG((base & PAGE_MASK) == 0, "non-page aligned base: %016" PRIX64, base); |
| 76 | MapPages(page_table, base / PAGE_SIZE, size / PAGE_SIZE, nullptr, PageType::Unmapped); | 77 | MapPages(page_table, base / PAGE_SIZE, size / PAGE_SIZE, nullptr, PageType::Unmapped); |
| 77 | 78 | ||
| 78 | auto interval = boost::icl::discrete_interval<VAddr>::closed(base, base + size - 1); | 79 | auto interval = boost::icl::discrete_interval<VAddr>::closed(base, base + size - 1); |
| @@ -120,7 +121,7 @@ T Read(const VAddr vaddr) { | |||
| 120 | const PageType type = current_page_table->attributes[vaddr >> PAGE_BITS]; | 121 | const PageType type = current_page_table->attributes[vaddr >> PAGE_BITS]; |
| 121 | switch (type) { | 122 | switch (type) { |
| 122 | case PageType::Unmapped: | 123 | case PageType::Unmapped: |
| 123 | LOG_ERROR(HW_Memory, "unmapped Read%lu @ 0x%016llX", sizeof(T) * 8, vaddr); | 124 | LOG_ERROR(HW_Memory, "unmapped Read%zu @ 0x%016" PRIX64, sizeof(T) * 8, vaddr); |
| 124 | return 0; | 125 | return 0; |
| 125 | case PageType::Special: { | 126 | case PageType::Special: { |
| 126 | if (auto result = ReadSpecial<T>(vaddr)) | 127 | if (auto result = ReadSpecial<T>(vaddr)) |
| @@ -129,7 +130,7 @@ T Read(const VAddr vaddr) { | |||
| 129 | } | 130 | } |
| 130 | case PageType::Memory: { | 131 | case PageType::Memory: { |
| 131 | const u8* page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS]; | 132 | const u8* page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS]; |
| 132 | ASSERT_MSG(page_pointer, "Mapped memory page without a pointer @ %08X", vaddr); | 133 | ASSERT_MSG(page_pointer, "Mapped memory page without a pointer @ %016" PRIX64, vaddr); |
| 133 | 134 | ||
| 134 | T value; | 135 | T value; |
| 135 | std::memcpy(&value, &page_pointer[vaddr & PAGE_MASK], sizeof(T)); | 136 | std::memcpy(&value, &page_pointer[vaddr & PAGE_MASK], sizeof(T)); |
| @@ -148,8 +149,8 @@ void Write(const VAddr vaddr, const T data) { | |||
| 148 | const PageType type = current_page_table->attributes[vaddr >> PAGE_BITS]; | 149 | const PageType type = current_page_table->attributes[vaddr >> PAGE_BITS]; |
| 149 | switch (type) { | 150 | switch (type) { |
| 150 | case PageType::Unmapped: | 151 | case PageType::Unmapped: |
| 151 | LOG_ERROR(HW_Memory, "unmapped Write%lu 0x%08X @ 0x%08X", sizeof(data) * 8, (u32)data, | 152 | LOG_ERROR(HW_Memory, "unmapped Write%zu 0x%08X @ 0x%016" PRIX64, sizeof(data) * 8, |
| 152 | vaddr); | 153 | static_cast<u32>(data), vaddr); |
| 153 | return; | 154 | return; |
| 154 | case PageType::Special: { | 155 | case PageType::Special: { |
| 155 | if (WriteSpecial<T>(vaddr, data)) | 156 | if (WriteSpecial<T>(vaddr, data)) |
| @@ -158,7 +159,7 @@ void Write(const VAddr vaddr, const T data) { | |||
| 158 | } | 159 | } |
| 159 | case PageType::Memory: { | 160 | case PageType::Memory: { |
| 160 | u8* page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS]; | 161 | u8* page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS]; |
| 161 | ASSERT_MSG(page_pointer, "Mapped memory page without a pointer @ %08X", vaddr); | 162 | ASSERT_MSG(page_pointer, "Mapped memory page without a pointer @ %016" PRIX64, vaddr); |
| 162 | std::memcpy(&page_pointer[vaddr & PAGE_MASK], &data, sizeof(T)); | 163 | std::memcpy(&page_pointer[vaddr & PAGE_MASK], &data, sizeof(T)); |
| 163 | return; | 164 | return; |
| 164 | } | 165 | } |
| @@ -203,7 +204,7 @@ u8* GetPointer(const VAddr vaddr) { | |||
| 203 | return page_pointer + (vaddr & PAGE_MASK); | 204 | return page_pointer + (vaddr & PAGE_MASK); |
| 204 | } | 205 | } |
| 205 | 206 | ||
| 206 | LOG_ERROR(HW_Memory, "unknown GetPointer @ 0x%08x", vaddr); | 207 | LOG_ERROR(HW_Memory, "unknown GetPointer @ 0x%016" PRIx64, vaddr); |
| 207 | return nullptr; | 208 | return nullptr; |
| 208 | } | 209 | } |
| 209 | 210 | ||
| @@ -241,12 +242,13 @@ u8* GetPhysicalPointer(PAddr address) { | |||
| 241 | }); | 242 | }); |
| 242 | 243 | ||
| 243 | if (area == std::end(memory_areas)) { | 244 | if (area == std::end(memory_areas)) { |
| 244 | LOG_ERROR(HW_Memory, "unknown GetPhysicalPointer @ 0x%08X", address); | 245 | LOG_ERROR(HW_Memory, "unknown GetPhysicalPointer @ 0x%016" PRIX64, address); |
| 245 | return nullptr; | 246 | return nullptr; |
| 246 | } | 247 | } |
| 247 | 248 | ||
| 248 | if (area->paddr_base == IO_AREA_PADDR) { | 249 | if (area->paddr_base == IO_AREA_PADDR) { |
| 249 | LOG_ERROR(HW_Memory, "MMIO mappings are not supported yet. phys_addr=0x%08X", address); | 250 | LOG_ERROR(HW_Memory, "MMIO mappings are not supported yet. phys_addr=0x%016" PRIX64, |
| 251 | address); | ||
| 250 | return nullptr; | 252 | return nullptr; |
| 251 | } | 253 | } |
| 252 | 254 | ||
| @@ -321,7 +323,9 @@ void ReadBlock(const Kernel::Process& process, const VAddr src_addr, void* dest_ | |||
| 321 | 323 | ||
| 322 | switch (page_table.attributes[page_index]) { | 324 | switch (page_table.attributes[page_index]) { |
| 323 | case PageType::Unmapped: | 325 | case PageType::Unmapped: |
| 324 | LOG_ERROR(HW_Memory, "unmapped ReadBlock @ 0x%08X (start address = 0xllx, size = %zu)", | 326 | LOG_ERROR(HW_Memory, |
| 327 | "unmapped ReadBlock @ 0x%016" PRIX64 " (start address = 0x%" PRIx64 | ||
| 328 | ", size = %zu)", | ||
| 325 | current_vaddr, src_addr, size); | 329 | current_vaddr, src_addr, size); |
| 326 | std::memset(dest_buffer, 0, copy_amount); | 330 | std::memset(dest_buffer, 0, copy_amount); |
| 327 | break; | 331 | break; |
| @@ -393,7 +397,8 @@ void WriteBlock(const Kernel::Process& process, const VAddr dest_addr, const voi | |||
| 393 | switch (page_table.attributes[page_index]) { | 397 | switch (page_table.attributes[page_index]) { |
| 394 | case PageType::Unmapped: | 398 | case PageType::Unmapped: |
| 395 | LOG_ERROR(HW_Memory, | 399 | LOG_ERROR(HW_Memory, |
| 396 | "unmapped WriteBlock @ 0x%08X (start address = 0x%08X, size = %zu)", | 400 | "unmapped WriteBlock @ 0x%016" PRIX64 " (start address = 0x%016" PRIX64 |
| 401 | ", size = %zu)", | ||
| 397 | current_vaddr, dest_addr, size); | 402 | current_vaddr, dest_addr, size); |
| 398 | break; | 403 | break; |
| 399 | case PageType::Special: | 404 | case PageType::Special: |
| @@ -437,7 +442,9 @@ void ZeroBlock(const VAddr dest_addr, const size_t size) { | |||
| 437 | 442 | ||
| 438 | switch (current_page_table->attributes[page_index]) { | 443 | switch (current_page_table->attributes[page_index]) { |
| 439 | case PageType::Unmapped: | 444 | case PageType::Unmapped: |
| 440 | LOG_ERROR(HW_Memory, "unmapped ZeroBlock @ 0x%08X (start address = 0x%08X, size = %zu)", | 445 | LOG_ERROR(HW_Memory, |
| 446 | "unmapped ZeroBlock @ 0x%016" PRIX64 " (start address = 0x%016" PRIX64 | ||
| 447 | ", size = %zu)", | ||
| 441 | current_vaddr, dest_addr, size); | 448 | current_vaddr, dest_addr, size); |
| 442 | break; | 449 | break; |
| 443 | case PageType::Special: | 450 | case PageType::Special: |
| @@ -474,7 +481,9 @@ void CopyBlock(VAddr dest_addr, VAddr src_addr, const size_t size) { | |||
| 474 | 481 | ||
| 475 | switch (current_page_table->attributes[page_index]) { | 482 | switch (current_page_table->attributes[page_index]) { |
| 476 | case PageType::Unmapped: | 483 | case PageType::Unmapped: |
| 477 | LOG_ERROR(HW_Memory, "unmapped CopyBlock @ 0x%08X (start address = 0x%08X, size = %zu)", | 484 | LOG_ERROR(HW_Memory, |
| 485 | "unmapped CopyBlock @ 0x%016" PRIX64 " (start address = 0x%016" PRIX64 | ||
| 486 | ", size = %zu)", | ||
| 478 | current_vaddr, src_addr, size); | 487 | current_vaddr, src_addr, size); |
| 479 | ZeroBlock(dest_addr, copy_amount); | 488 | ZeroBlock(dest_addr, copy_amount); |
| 480 | break; | 489 | break; |
| @@ -599,7 +608,7 @@ boost::optional<PAddr> TryVirtualToPhysicalAddress(const VAddr addr) { | |||
| 599 | PAddr VirtualToPhysicalAddress(const VAddr addr) { | 608 | PAddr VirtualToPhysicalAddress(const VAddr addr) { |
| 600 | auto paddr = TryVirtualToPhysicalAddress(addr); | 609 | auto paddr = TryVirtualToPhysicalAddress(addr); |
| 601 | if (!paddr) { | 610 | if (!paddr) { |
| 602 | LOG_ERROR(HW_Memory, "Unknown virtual address @ 0x%08X", addr); | 611 | LOG_ERROR(HW_Memory, "Unknown virtual address @ 0x%016" PRIX64, addr); |
| 603 | // To help with debugging, set bit on address so that it's obviously invalid. | 612 | // To help with debugging, set bit on address so that it's obviously invalid. |
| 604 | return addr | 0x80000000; | 613 | return addr | 0x80000000; |
| 605 | } | 614 | } |