|
|
@ -225,6 +225,99 @@ struct Memory::Impl { |
|
|
return string; |
|
|
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) { |
|
|
void RasterizerMarkRegionCached(VAddr vaddr, u64 size, bool cached) { |
|
|
if (vaddr == 0) { |
|
|
if (vaddr == 0) { |
|
|
return; |
|
|
return; |
|
|
@ -381,6 +474,23 @@ std::string Memory::ReadCString(VAddr vaddr, std::size_t max_length) { |
|
|
return impl->ReadCString(vaddr, 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) { |
|
|
void Memory::RasterizerMarkRegionCached(VAddr vaddr, u64 size, bool cached) { |
|
|
impl->RasterizerMarkRegionCached(vaddr, size, 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); |
|
|
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
|
|
|
} // namespace Memory
|