|
|
@@ -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
|