summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/memory.cpp115
-rw-r--r--src/core/memory.h10
2 files changed, 125 insertions, 0 deletions
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index 9ceb7fabc..6061d37ae 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -257,10 +257,59 @@ struct Memory::Impl {
}
}
+ void ReadBlockUnsafe(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 + (page_index << PAGE_BITS);
+ std::memcpy(dest_buffer, src_ptr, copy_amount);
+ break;
+ }
+ case Common::PageType::RasterizerCachedMemory: {
+ const u8* const host_ptr = GetPointerFromVMA(process, current_vaddr);
+ 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 ReadBlockUnsafe(const VAddr src_addr, void* dest_buffer, const std::size_t size) {
+ ReadBlockUnsafe(*system.CurrentProcess(), src_addr, dest_buffer, size);
+ }
+
void WriteBlock(const Kernel::Process& process, const VAddr dest_addr, const void* src_buffer,
const std::size_t size) {
const auto& page_table = process.VMManager().page_table;
@@ -305,10 +354,57 @@ struct Memory::Impl {
}
}
+ void WriteBlockUnsafe(const Kernel::Process& process, const VAddr dest_addr,
+ const void* src_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 = 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 WriteBlock @ 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* const dest_ptr =
+ page_table.pointers[page_index] + page_offset + (page_index << PAGE_BITS);
+ std::memcpy(dest_ptr, src_buffer, copy_amount);
+ break;
+ }
+ case Common::PageType::RasterizerCachedMemory: {
+ u8* const host_ptr = GetPointerFromVMA(process, current_vaddr);
+ std::memcpy(host_ptr, src_buffer, copy_amount);
+ break;
+ }
+ default:
+ UNREACHABLE();
+ }
+
+ page_index++;
+ page_offset = 0;
+ src_buffer = static_cast<const u8*>(src_buffer) + copy_amount;
+ remaining_size -= copy_amount;
+ }
+ }
+
void WriteBlock(const VAddr dest_addr, const void* src_buffer, const std::size_t size) {
WriteBlock(*system.CurrentProcess(), dest_addr, src_buffer, size);
}
+ void WriteBlockUnsafe(const VAddr dest_addr, const void* src_buffer, const std::size_t size) {
+ WriteBlockUnsafe(*system.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;
@@ -696,6 +792,15 @@ void Memory::ReadBlock(const VAddr src_addr, void* dest_buffer, const std::size_
impl->ReadBlock(src_addr, dest_buffer, size);
}
+void Memory::ReadBlockUnsafe(const Kernel::Process& process, const VAddr src_addr,
+ void* dest_buffer, const std::size_t size) {
+ impl->ReadBlockUnsafe(process, src_addr, dest_buffer, size);
+}
+
+void Memory::ReadBlockUnsafe(const VAddr src_addr, void* dest_buffer, const std::size_t size) {
+ impl->ReadBlockUnsafe(src_addr, dest_buffer, size);
+}
+
void Memory::WriteBlock(const Kernel::Process& process, VAddr dest_addr, const void* src_buffer,
std::size_t size) {
impl->WriteBlock(process, dest_addr, src_buffer, size);
@@ -705,6 +810,16 @@ void Memory::WriteBlock(const VAddr dest_addr, const void* src_buffer, const std
impl->WriteBlock(dest_addr, src_buffer, size);
}
+void Memory::WriteBlockUnsafe(const Kernel::Process& process, VAddr dest_addr,
+ const void* src_buffer, std::size_t size) {
+ impl->WriteBlockUnsafe(process, dest_addr, src_buffer, size);
+}
+
+void Memory::WriteBlockUnsafe(const VAddr dest_addr, const void* src_buffer,
+ const std::size_t size) {
+ impl->WriteBlockUnsafe(dest_addr, src_buffer, size);
+}
+
void Memory::ZeroBlock(const Kernel::Process& process, VAddr dest_addr, std::size_t size) {
impl->ZeroBlock(process, dest_addr, size);
}
diff --git a/src/core/memory.h b/src/core/memory.h
index 8913a9da4..97750f851 100644
--- a/src/core/memory.h
+++ b/src/core/memory.h
@@ -294,6 +294,9 @@ public:
void ReadBlock(const Kernel::Process& process, VAddr src_addr, void* dest_buffer,
std::size_t size);
+ void ReadBlockUnsafe(const Kernel::Process& process, VAddr src_addr, void* dest_buffer,
+ std::size_t size);
+
/**
* Reads a contiguous block of bytes from the current process' address space.
*
@@ -312,6 +315,8 @@ public:
*/
void ReadBlock(VAddr src_addr, void* dest_buffer, std::size_t size);
+ void ReadBlockUnsafe(VAddr src_addr, void* dest_buffer, std::size_t size);
+
/**
* Writes a range of bytes into a given process' address space at the specified
* virtual address.
@@ -335,6 +340,9 @@ public:
void WriteBlock(const Kernel::Process& process, VAddr dest_addr, const void* src_buffer,
std::size_t size);
+ void WriteBlockUnsafe(const Kernel::Process& process, VAddr dest_addr, const void* src_buffer,
+ std::size_t size);
+
/**
* Writes a range of bytes into the current process' address space at the specified
* virtual address.
@@ -356,6 +364,8 @@ public:
*/
void WriteBlock(VAddr dest_addr, const void* src_buffer, std::size_t size);
+ void WriteBlockUnsafe(VAddr dest_addr, const void* src_buffer, std::size_t size);
+
/**
* Fills the specified address range within a process' address space with zeroes.
*