summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/core/memory.cpp199
-rw-r--r--src/core/memory.h53
2 files changed, 161 insertions, 91 deletions
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index 8c3489ed3..c939e980d 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -225,6 +225,99 @@ struct Memory::Impl {
return string;
}
+ 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;
+ std::size_t page_index = dest_addr >> PAGE_BITS;
+ std::size_t page_offset = dest_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 ZeroBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
+ current_vaddr, dest_addr, size);
+ break;
+ }
+ case Common::PageType::Memory: {
+ DEBUG_ASSERT(page_table.pointers[page_index]);
+
+ u8* dest_ptr = page_table.pointers[page_index] + page_offset;
+ std::memset(dest_ptr, 0, copy_amount);
+ break;
+ }
+ case Common::PageType::RasterizerCachedMemory: {
+ u8* const host_ptr = GetPointerFromVMA(process, current_vaddr);
+ system.GPU().InvalidateRegion(ToCacheAddr(host_ptr), copy_amount);
+ std::memset(host_ptr, 0, copy_amount);
+ break;
+ }
+ default:
+ UNREACHABLE();
+ }
+
+ page_index++;
+ page_offset = 0;
+ remaining_size -= copy_amount;
+ }
+ }
+
+ void ZeroBlock(const VAddr dest_addr, const std::size_t size) {
+ ZeroBlock(*system.CurrentProcess(), dest_addr, size);
+ }
+
+ void CopyBlock(const Kernel::Process& process, VAddr dest_addr, VAddr src_addr,
+ 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 CopyBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
+ current_vaddr, src_addr, size);
+ ZeroBlock(process, dest_addr, 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;
+ WriteBlock(process, dest_addr, 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);
+ WriteBlock(process, dest_addr, host_ptr, copy_amount);
+ break;
+ }
+ default:
+ UNREACHABLE();
+ }
+
+ page_index++;
+ page_offset = 0;
+ dest_addr += static_cast<VAddr>(copy_amount);
+ src_addr += static_cast<VAddr>(copy_amount);
+ remaining_size -= copy_amount;
+ }
+ }
+
+ void CopyBlock(VAddr dest_addr, VAddr src_addr, std::size_t size) {
+ return CopyBlock(*system.CurrentProcess(), dest_addr, src_addr, size);
+ }
+
void RasterizerMarkRegionCached(VAddr vaddr, u64 size, bool cached) {
if (vaddr == 0) {
return;
@@ -381,6 +474,23 @@ std::string Memory::ReadCString(VAddr vaddr, std::size_t max_length) {
return impl->ReadCString(vaddr, max_length);
}
+void Memory::ZeroBlock(const Kernel::Process& process, VAddr dest_addr, std::size_t size) {
+ impl->ZeroBlock(process, dest_addr, size);
+}
+
+void Memory::ZeroBlock(VAddr dest_addr, std::size_t size) {
+ impl->ZeroBlock(dest_addr, size);
+}
+
+void Memory::CopyBlock(const Kernel::Process& process, VAddr dest_addr, VAddr src_addr,
+ const std::size_t size) {
+ impl->CopyBlock(process, dest_addr, src_addr, size);
+}
+
+void Memory::CopyBlock(VAddr dest_addr, VAddr src_addr, std::size_t size) {
+ impl->CopyBlock(dest_addr, src_addr, size);
+}
+
void Memory::RasterizerMarkRegionCached(VAddr vaddr, u64 size, bool cached) {
impl->RasterizerMarkRegionCached(vaddr, size, cached);
}
@@ -529,93 +639,4 @@ void WriteBlock(const VAddr dest_addr, const void* src_buffer, const std::size_t
WriteBlock(*Core::System::GetInstance().CurrentProcess(), dest_addr, src_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;
- std::size_t page_index = dest_addr >> PAGE_BITS;
- std::size_t page_offset = dest_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 ZeroBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
- current_vaddr, dest_addr, size);
- break;
- }
- case Common::PageType::Memory: {
- DEBUG_ASSERT(page_table.pointers[page_index]);
-
- u8* dest_ptr = page_table.pointers[page_index] + page_offset;
- std::memset(dest_ptr, 0, copy_amount);
- break;
- }
- case Common::PageType::RasterizerCachedMemory: {
- const auto& host_ptr{GetPointerFromVMA(process, current_vaddr)};
- Core::System::GetInstance().GPU().InvalidateRegion(ToCacheAddr(host_ptr), copy_amount);
- std::memset(host_ptr, 0, copy_amount);
- break;
- }
- default:
- UNREACHABLE();
- }
-
- page_index++;
- page_offset = 0;
- remaining_size -= copy_amount;
- }
-}
-
-void CopyBlock(const Kernel::Process& process, VAddr dest_addr, VAddr src_addr,
- 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 CopyBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
- current_vaddr, src_addr, size);
- ZeroBlock(process, dest_addr, 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;
- WriteBlock(process, dest_addr, 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);
- WriteBlock(process, dest_addr, host_ptr, copy_amount);
- break;
- }
- default:
- UNREACHABLE();
- }
-
- page_index++;
- page_offset = 0;
- dest_addr += static_cast<VAddr>(copy_amount);
- src_addr += static_cast<VAddr>(copy_amount);
- remaining_size -= copy_amount;
- }
-}
-
-void CopyBlock(VAddr dest_addr, VAddr src_addr, std::size_t size) {
- CopyBlock(*Core::System::GetInstance().CurrentProcess(), dest_addr, src_addr, size);
-}
-
} // namespace Memory
diff --git a/src/core/memory.h b/src/core/memory.h
index 7cd348b49..fc0013a96 100644
--- a/src/core/memory.h
+++ b/src/core/memory.h
@@ -170,6 +170,57 @@ public:
std::string ReadCString(VAddr vaddr, std::size_t max_length);
/**
+ * Fills the specified address range within a process' address space with zeroes.
+ *
+ * @param process The process that will have a portion of its memory zeroed out.
+ * @param dest_addr The starting virtual address of the range to zero out.
+ * @param size The size of the address range to zero out, in bytes.
+ *
+ * @post The range [dest_addr, size) within the process' address space is
+ * filled with zeroes.
+ */
+ void ZeroBlock(const Kernel::Process& process, VAddr dest_addr, std::size_t size);
+
+ /**
+ * Fills the specified address range within the current process' address space with zeroes.
+ *
+ * @param dest_addr The starting virtual address of the range to zero out.
+ * @param size The size of the address range to zero out, in bytes.
+ *
+ * @post The range [dest_addr, size) within the current process' address space is
+ * filled with zeroes.
+ */
+ void ZeroBlock(VAddr dest_addr, std::size_t size);
+
+ /**
+ * Copies data within a process' address space to another location within the
+ * same address space.
+ *
+ * @param process The process that will have data copied within its address space.
+ * @param dest_addr The destination virtual address to begin copying the data into.
+ * @param src_addr The source virtual address to begin copying the data from.
+ * @param size The size of the data to copy, in bytes.
+ *
+ * @post The range [dest_addr, size) within the process' address space contains the
+ * same data within the range [src_addr, size).
+ */
+ void CopyBlock(const Kernel::Process& process, VAddr dest_addr, VAddr src_addr,
+ std::size_t size);
+
+ /**
+ * Copies data within the current process' address space to another location within the
+ * same address space.
+ *
+ * @param dest_addr The destination virtual address to begin copying the data into.
+ * @param src_addr The source virtual address to begin copying the data from.
+ * @param size The size of the data to copy, in bytes.
+ *
+ * @post The range [dest_addr, size) within the current process' address space
+ * contains the same data within the range [src_addr, size).
+ */
+ void CopyBlock(VAddr dest_addr, VAddr src_addr, std::size_t size);
+
+ /**
* Marks each page within the specified address range as cached or uncached.
*
* @param vaddr The virtual address indicating the start of the address range.
@@ -206,7 +257,5 @@ void ReadBlock(VAddr src_addr, void* dest_buffer, std::size_t size);
void WriteBlock(const Kernel::Process& process, VAddr dest_addr, const void* src_buffer,
std::size_t size);
void WriteBlock(VAddr dest_addr, const void* src_buffer, std::size_t size);
-void ZeroBlock(const Kernel::Process& process, VAddr dest_addr, std::size_t size);
-void CopyBlock(VAddr dest_addr, VAddr src_addr, std::size_t size);
} // namespace Memory