aboutsummaryrefslogtreecommitdiff
path: root/src/core/memory.cpp
diff options
context:
space:
mode:
authorLioncash <mathew1800@gmail.com>2019-11-26 16:29:34 -0500
committerLioncash <mathew1800@gmail.com>2019-11-26 21:55:39 -0500
commitb05bfc603689419dc515a656b9fc711d79994f13 (patch)
treebc0937d11bbe31458785a69478edbf11a720b0ae /src/core/memory.cpp
parent89ef3ef5752e42d0eb0bdfa23cc72d391db74216 (diff)
core/memory: Migrate over Read{8, 16, 32, 64, Block} to the Memory class
With all of the trivial parts of the memory interface moved over, we can get right into moving over the bits that are used. Note that this does require the use of GetInstance from the global system instance to be used within hle_ipc.cpp and the gdbstub. This is fine for the time being, as they both already rely on the global system instance in other functions. These will be removed in a change directed at both of these respectively. For now, it's sufficient, as it still accomplishes the goal of de-globalizing the memory code.
Diffstat (limited to 'src/core/memory.cpp')
-rw-r--r--src/core/memory.cpp228
1 files changed, 132 insertions, 96 deletions
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index c939e980d2..699c481071 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -60,37 +60,6 @@ u8* GetPointerFromVMA(VAddr vaddr) {
}
template <typename T>
-T Read(const VAddr vaddr) {
- const u8* const page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS];
- if (page_pointer != nullptr) {
- // NOTE: Avoid adding any extra logic to this fast-path block
- T value;
- std::memcpy(&value, &page_pointer[vaddr & PAGE_MASK], sizeof(T));
- return value;
- }
-
- const Common::PageType type = current_page_table->attributes[vaddr >> PAGE_BITS];
- switch (type) {
- case Common::PageType::Unmapped:
- LOG_ERROR(HW_Memory, "Unmapped Read{} @ 0x{:08X}", sizeof(T) * 8, vaddr);
- return 0;
- case Common::PageType::Memory:
- ASSERT_MSG(false, "Mapped memory page without a pointer @ {:016X}", vaddr);
- break;
- case Common::PageType::RasterizerCachedMemory: {
- const u8* const host_ptr{GetPointerFromVMA(vaddr)};
- Core::System::GetInstance().GPU().FlushRegion(ToCacheAddr(host_ptr), sizeof(T));
- T value;
- std::memcpy(&value, host_ptr, sizeof(T));
- return value;
- }
- default:
- UNREACHABLE();
- }
- return {};
-}
-
-template <typename T>
void Write(const VAddr vaddr, const T data) {
u8* const page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS];
if (page_pointer != nullptr) {
@@ -210,6 +179,22 @@ struct Memory::Impl {
return nullptr;
}
+ u8 Read8(const VAddr addr) {
+ return Read<u8>(addr);
+ }
+
+ u16 Read16(const VAddr addr) {
+ return Read<u16_le>(addr);
+ }
+
+ u32 Read32(const VAddr addr) {
+ return Read<u32_le>(addr);
+ }
+
+ u64 Read64(const VAddr addr) {
+ return Read<u64_le>(addr);
+ }
+
std::string ReadCString(VAddr vaddr, std::size_t max_length) {
std::string string;
string.reserve(max_length);
@@ -225,6 +210,55 @@ struct Memory::Impl {
return string;
}
+ void ReadBlock(const Kernel::Process& process, const VAddr src_addr, void* dest_buffer,
+ const std::size_t size) {
+ const auto& page_table = process.VMManager().page_table;
+
+ std::size_t remaining_size = size;
+ std::size_t page_index = src_addr >> PAGE_BITS;
+ std::size_t page_offset = src_addr & PAGE_MASK;
+
+ while (remaining_size > 0) {
+ const std::size_t copy_amount =
+ std::min(static_cast<std::size_t>(PAGE_SIZE) - page_offset, remaining_size);
+ const auto current_vaddr = static_cast<VAddr>((page_index << PAGE_BITS) + page_offset);
+
+ switch (page_table.attributes[page_index]) {
+ case Common::PageType::Unmapped: {
+ LOG_ERROR(HW_Memory,
+ "Unmapped ReadBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
+ current_vaddr, src_addr, size);
+ std::memset(dest_buffer, 0, copy_amount);
+ break;
+ }
+ case Common::PageType::Memory: {
+ DEBUG_ASSERT(page_table.pointers[page_index]);
+
+ const u8* const src_ptr = page_table.pointers[page_index] + page_offset;
+ std::memcpy(dest_buffer, src_ptr, copy_amount);
+ break;
+ }
+ case Common::PageType::RasterizerCachedMemory: {
+ const u8* const host_ptr = GetPointerFromVMA(process, current_vaddr);
+ system.GPU().FlushRegion(ToCacheAddr(host_ptr), copy_amount);
+ std::memcpy(dest_buffer, host_ptr, copy_amount);
+ break;
+ }
+ default:
+ UNREACHABLE();
+ }
+
+ page_index++;
+ page_offset = 0;
+ dest_buffer = static_cast<u8*>(dest_buffer) + copy_amount;
+ remaining_size -= copy_amount;
+ }
+ }
+
+ void ReadBlock(const VAddr src_addr, void* dest_buffer, const std::size_t size) {
+ ReadBlock(*system.CurrentProcess(), src_addr, dest_buffer, size);
+ }
+
void ZeroBlock(const Kernel::Process& process, const VAddr dest_addr, const std::size_t size) {
const auto& page_table = process.VMManager().page_table;
std::size_t remaining_size = size;
@@ -425,6 +459,48 @@ struct Memory::Impl {
}
}
+ /**
+ * Reads a particular data type out of memory at the given virtual address.
+ *
+ * @param vaddr The virtual address to read the data type from.
+ *
+ * @tparam T The data type to read out of memory. This type *must* be
+ * trivially copyable, otherwise the behavior of this function
+ * is undefined.
+ *
+ * @returns The instance of T read from the specified virtual address.
+ */
+ template <typename T>
+ T Read(const VAddr vaddr) {
+ const u8* const page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS];
+ if (page_pointer != nullptr) {
+ // NOTE: Avoid adding any extra logic to this fast-path block
+ T value;
+ std::memcpy(&value, &page_pointer[vaddr & PAGE_MASK], sizeof(T));
+ return value;
+ }
+
+ const Common::PageType type = current_page_table->attributes[vaddr >> PAGE_BITS];
+ switch (type) {
+ case Common::PageType::Unmapped:
+ LOG_ERROR(HW_Memory, "Unmapped Read{} @ 0x{:08X}", sizeof(T) * 8, vaddr);
+ return 0;
+ case Common::PageType::Memory:
+ ASSERT_MSG(false, "Mapped memory page without a pointer @ {:016X}", vaddr);
+ break;
+ case Common::PageType::RasterizerCachedMemory: {
+ const u8* const host_ptr = GetPointerFromVMA(vaddr);
+ system.GPU().FlushRegion(ToCacheAddr(host_ptr), sizeof(T));
+ T value;
+ std::memcpy(&value, host_ptr, sizeof(T));
+ return value;
+ }
+ default:
+ UNREACHABLE();
+ }
+ return {};
+ }
+
Core::System& system;
};
@@ -470,10 +546,35 @@ const u8* Memory::GetPointer(VAddr vaddr) const {
return impl->GetPointer(vaddr);
}
+u8 Memory::Read8(const VAddr addr) {
+ return impl->Read8(addr);
+}
+
+u16 Memory::Read16(const VAddr addr) {
+ return impl->Read16(addr);
+}
+
+u32 Memory::Read32(const VAddr addr) {
+ return impl->Read32(addr);
+}
+
+u64 Memory::Read64(const VAddr addr) {
+ return impl->Read64(addr);
+}
+
std::string Memory::ReadCString(VAddr vaddr, std::size_t max_length) {
return impl->ReadCString(vaddr, max_length);
}
+void Memory::ReadBlock(const Kernel::Process& process, const VAddr src_addr, void* dest_buffer,
+ const std::size_t size) {
+ impl->ReadBlock(process, src_addr, dest_buffer, size);
+}
+
+void Memory::ReadBlock(const VAddr src_addr, void* dest_buffer, const std::size_t size) {
+ impl->ReadBlock(src_addr, dest_buffer, size);
+}
+
void Memory::ZeroBlock(const Kernel::Process& process, VAddr dest_addr, std::size_t size) {
impl->ZeroBlock(process, dest_addr, size);
}
@@ -511,71 +612,6 @@ bool IsKernelVirtualAddress(const VAddr vaddr) {
return KERNEL_REGION_VADDR <= vaddr && vaddr < KERNEL_REGION_END;
}
-u8 Read8(const VAddr addr) {
- return Read<u8>(addr);
-}
-
-u16 Read16(const VAddr addr) {
- return Read<u16_le>(addr);
-}
-
-u32 Read32(const VAddr addr) {
- return Read<u32_le>(addr);
-}
-
-u64 Read64(const VAddr addr) {
- return Read<u64_le>(addr);
-}
-
-void ReadBlock(const Kernel::Process& process, const VAddr src_addr, void* dest_buffer,
- const std::size_t size) {
- const auto& page_table = process.VMManager().page_table;
-
- std::size_t remaining_size = size;
- std::size_t page_index = src_addr >> PAGE_BITS;
- std::size_t page_offset = src_addr & PAGE_MASK;
-
- while (remaining_size > 0) {
- const std::size_t copy_amount =
- std::min(static_cast<std::size_t>(PAGE_SIZE) - page_offset, remaining_size);
- const VAddr current_vaddr = static_cast<VAddr>((page_index << PAGE_BITS) + page_offset);
-
- switch (page_table.attributes[page_index]) {
- case Common::PageType::Unmapped: {
- LOG_ERROR(HW_Memory,
- "Unmapped ReadBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
- current_vaddr, src_addr, size);
- std::memset(dest_buffer, 0, copy_amount);
- break;
- }
- case Common::PageType::Memory: {
- DEBUG_ASSERT(page_table.pointers[page_index]);
-
- const u8* src_ptr = page_table.pointers[page_index] + page_offset;
- std::memcpy(dest_buffer, src_ptr, copy_amount);
- break;
- }
- case Common::PageType::RasterizerCachedMemory: {
- const auto& host_ptr{GetPointerFromVMA(process, current_vaddr)};
- Core::System::GetInstance().GPU().FlushRegion(ToCacheAddr(host_ptr), copy_amount);
- std::memcpy(dest_buffer, host_ptr, copy_amount);
- break;
- }
- default:
- UNREACHABLE();
- }
-
- page_index++;
- page_offset = 0;
- dest_buffer = static_cast<u8*>(dest_buffer) + copy_amount;
- remaining_size -= copy_amount;
- }
-}
-
-void ReadBlock(const VAddr src_addr, void* dest_buffer, const std::size_t size) {
- ReadBlock(*Core::System::GetInstance().CurrentProcess(), src_addr, dest_buffer, size);
-}
-
void Write8(const VAddr addr, const u8 data) {
Write<u8>(addr, data);
}