summaryrefslogtreecommitdiff
path: root/src/core/memory.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/memory.cpp')
-rw-r--r--src/core/memory.cpp199
1 files changed, 110 insertions, 89 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 {
225 return string; 225 return string;
226 } 226 }
227 227
228 void ZeroBlock(const Kernel::Process& process, const VAddr dest_addr, const std::size_t size) {
229 const auto& page_table = process.VMManager().page_table;
230 std::size_t remaining_size = size;
231 std::size_t page_index = dest_addr >> PAGE_BITS;
232 std::size_t page_offset = dest_addr & PAGE_MASK;
233
234 while (remaining_size > 0) {
235 const std::size_t copy_amount =
236 std::min(static_cast<std::size_t>(PAGE_SIZE) - page_offset, remaining_size);
237 const auto current_vaddr = static_cast<VAddr>((page_index << PAGE_BITS) + page_offset);
238
239 switch (page_table.attributes[page_index]) {
240 case Common::PageType::Unmapped: {
241 LOG_ERROR(HW_Memory,
242 "Unmapped ZeroBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
243 current_vaddr, dest_addr, size);
244 break;
245 }
246 case Common::PageType::Memory: {
247 DEBUG_ASSERT(page_table.pointers[page_index]);
248
249 u8* dest_ptr = page_table.pointers[page_index] + page_offset;
250 std::memset(dest_ptr, 0, copy_amount);
251 break;
252 }
253 case Common::PageType::RasterizerCachedMemory: {
254 u8* const host_ptr = GetPointerFromVMA(process, current_vaddr);
255 system.GPU().InvalidateRegion(ToCacheAddr(host_ptr), copy_amount);
256 std::memset(host_ptr, 0, copy_amount);
257 break;
258 }
259 default:
260 UNREACHABLE();
261 }
262
263 page_index++;
264 page_offset = 0;
265 remaining_size -= copy_amount;
266 }
267 }
268
269 void ZeroBlock(const VAddr dest_addr, const std::size_t size) {
270 ZeroBlock(*system.CurrentProcess(), dest_addr, size);
271 }
272
273 void CopyBlock(const Kernel::Process& process, VAddr dest_addr, VAddr src_addr,
274 const std::size_t size) {
275 const auto& page_table = process.VMManager().page_table;
276 std::size_t remaining_size = size;
277 std::size_t page_index = src_addr >> PAGE_BITS;
278 std::size_t page_offset = src_addr & PAGE_MASK;
279
280 while (remaining_size > 0) {
281 const std::size_t copy_amount =
282 std::min(static_cast<std::size_t>(PAGE_SIZE) - page_offset, remaining_size);
283 const auto current_vaddr = static_cast<VAddr>((page_index << PAGE_BITS) + page_offset);
284
285 switch (page_table.attributes[page_index]) {
286 case Common::PageType::Unmapped: {
287 LOG_ERROR(HW_Memory,
288 "Unmapped CopyBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
289 current_vaddr, src_addr, size);
290 ZeroBlock(process, dest_addr, copy_amount);
291 break;
292 }
293 case Common::PageType::Memory: {
294 DEBUG_ASSERT(page_table.pointers[page_index]);
295 const u8* src_ptr = page_table.pointers[page_index] + page_offset;
296 WriteBlock(process, dest_addr, src_ptr, copy_amount);
297 break;
298 }
299 case Common::PageType::RasterizerCachedMemory: {
300 const u8* const host_ptr = GetPointerFromVMA(process, current_vaddr);
301 system.GPU().FlushRegion(ToCacheAddr(host_ptr), copy_amount);
302 WriteBlock(process, dest_addr, host_ptr, copy_amount);
303 break;
304 }
305 default:
306 UNREACHABLE();
307 }
308
309 page_index++;
310 page_offset = 0;
311 dest_addr += static_cast<VAddr>(copy_amount);
312 src_addr += static_cast<VAddr>(copy_amount);
313 remaining_size -= copy_amount;
314 }
315 }
316
317 void CopyBlock(VAddr dest_addr, VAddr src_addr, std::size_t size) {
318 return CopyBlock(*system.CurrentProcess(), dest_addr, src_addr, size);
319 }
320
228 void RasterizerMarkRegionCached(VAddr vaddr, u64 size, bool cached) { 321 void RasterizerMarkRegionCached(VAddr vaddr, u64 size, bool cached) {
229 if (vaddr == 0) { 322 if (vaddr == 0) {
230 return; 323 return;
@@ -381,6 +474,23 @@ std::string Memory::ReadCString(VAddr vaddr, std::size_t max_length) {
381 return impl->ReadCString(vaddr, max_length); 474 return impl->ReadCString(vaddr, max_length);
382} 475}
383 476
477void Memory::ZeroBlock(const Kernel::Process& process, VAddr dest_addr, std::size_t size) {
478 impl->ZeroBlock(process, dest_addr, size);
479}
480
481void Memory::ZeroBlock(VAddr dest_addr, std::size_t size) {
482 impl->ZeroBlock(dest_addr, size);
483}
484
485void Memory::CopyBlock(const Kernel::Process& process, VAddr dest_addr, VAddr src_addr,
486 const std::size_t size) {
487 impl->CopyBlock(process, dest_addr, src_addr, size);
488}
489
490void Memory::CopyBlock(VAddr dest_addr, VAddr src_addr, std::size_t size) {
491 impl->CopyBlock(dest_addr, src_addr, size);
492}
493
384void Memory::RasterizerMarkRegionCached(VAddr vaddr, u64 size, bool cached) { 494void Memory::RasterizerMarkRegionCached(VAddr vaddr, u64 size, bool cached) {
385 impl->RasterizerMarkRegionCached(vaddr, size, cached); 495 impl->RasterizerMarkRegionCached(vaddr, size, cached);
386} 496}
@@ -529,93 +639,4 @@ void WriteBlock(const VAddr dest_addr, const void* src_buffer, const std::size_t
529 WriteBlock(*Core::System::GetInstance().CurrentProcess(), dest_addr, src_buffer, size); 639 WriteBlock(*Core::System::GetInstance().CurrentProcess(), dest_addr, src_buffer, size);
530} 640}
531 641
532void ZeroBlock(const Kernel::Process& process, const VAddr dest_addr, const std::size_t size) {
533 const auto& page_table = process.VMManager().page_table;
534 std::size_t remaining_size = size;
535 std::size_t page_index = dest_addr >> PAGE_BITS;
536 std::size_t page_offset = dest_addr & PAGE_MASK;
537
538 while (remaining_size > 0) {
539 const std::size_t copy_amount =
540 std::min(static_cast<std::size_t>(PAGE_SIZE) - page_offset, remaining_size);
541 const VAddr current_vaddr = static_cast<VAddr>((page_index << PAGE_BITS) + page_offset);
542
543 switch (page_table.attributes[page_index]) {
544 case Common::PageType::Unmapped: {
545 LOG_ERROR(HW_Memory,
546 "Unmapped ZeroBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
547 current_vaddr, dest_addr, size);
548 break;
549 }
550 case Common::PageType::Memory: {
551 DEBUG_ASSERT(page_table.pointers[page_index]);
552
553 u8* dest_ptr = page_table.pointers[page_index] + page_offset;
554 std::memset(dest_ptr, 0, copy_amount);
555 break;
556 }
557 case Common::PageType::RasterizerCachedMemory: {
558 const auto& host_ptr{GetPointerFromVMA(process, current_vaddr)};
559 Core::System::GetInstance().GPU().InvalidateRegion(ToCacheAddr(host_ptr), copy_amount);
560 std::memset(host_ptr, 0, copy_amount);
561 break;
562 }
563 default:
564 UNREACHABLE();
565 }
566
567 page_index++;
568 page_offset = 0;
569 remaining_size -= copy_amount;
570 }
571}
572
573void CopyBlock(const Kernel::Process& process, VAddr dest_addr, VAddr src_addr,
574 const std::size_t size) {
575 const auto& page_table = process.VMManager().page_table;
576 std::size_t remaining_size = size;
577 std::size_t page_index = src_addr >> PAGE_BITS;
578 std::size_t page_offset = src_addr & PAGE_MASK;
579
580 while (remaining_size > 0) {
581 const std::size_t copy_amount =
582 std::min(static_cast<std::size_t>(PAGE_SIZE) - page_offset, remaining_size);
583 const VAddr current_vaddr = static_cast<VAddr>((page_index << PAGE_BITS) + page_offset);
584
585 switch (page_table.attributes[page_index]) {
586 case Common::PageType::Unmapped: {
587 LOG_ERROR(HW_Memory,
588 "Unmapped CopyBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
589 current_vaddr, src_addr, size);
590 ZeroBlock(process, dest_addr, copy_amount);
591 break;
592 }
593 case Common::PageType::Memory: {
594 DEBUG_ASSERT(page_table.pointers[page_index]);
595 const u8* src_ptr = page_table.pointers[page_index] + page_offset;
596 WriteBlock(process, dest_addr, src_ptr, copy_amount);
597 break;
598 }
599 case Common::PageType::RasterizerCachedMemory: {
600 const auto& host_ptr{GetPointerFromVMA(process, current_vaddr)};
601 Core::System::GetInstance().GPU().FlushRegion(ToCacheAddr(host_ptr), copy_amount);
602 WriteBlock(process, dest_addr, host_ptr, copy_amount);
603 break;
604 }
605 default:
606 UNREACHABLE();
607 }
608
609 page_index++;
610 page_offset = 0;
611 dest_addr += static_cast<VAddr>(copy_amount);
612 src_addr += static_cast<VAddr>(copy_amount);
613 remaining_size -= copy_amount;
614 }
615}
616
617void CopyBlock(VAddr dest_addr, VAddr src_addr, std::size_t size) {
618 CopyBlock(*Core::System::GetInstance().CurrentProcess(), dest_addr, src_addr, size);
619}
620
621} // namespace Memory 642} // namespace Memory