diff options
Diffstat (limited to 'src/core/memory.cpp')
| -rw-r--r-- | src/core/memory.cpp | 199 |
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 | ||
| 477 | void Memory::ZeroBlock(const Kernel::Process& process, VAddr dest_addr, std::size_t size) { | ||
| 478 | impl->ZeroBlock(process, dest_addr, size); | ||
| 479 | } | ||
| 480 | |||
| 481 | void Memory::ZeroBlock(VAddr dest_addr, std::size_t size) { | ||
| 482 | impl->ZeroBlock(dest_addr, size); | ||
| 483 | } | ||
| 484 | |||
| 485 | void 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 | |||
| 490 | void Memory::CopyBlock(VAddr dest_addr, VAddr src_addr, std::size_t size) { | ||
| 491 | impl->CopyBlock(dest_addr, src_addr, size); | ||
| 492 | } | ||
| 493 | |||
| 384 | void Memory::RasterizerMarkRegionCached(VAddr vaddr, u64 size, bool cached) { | 494 | void 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 | ||
| 532 | void 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 | |||
| 573 | void 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 | |||
| 617 | void 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 |