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