summaryrefslogtreecommitdiff
path: root/src/core/memory.cpp
diff options
context:
space:
mode:
authorGravatar bunnei2016-05-29 21:57:07 -0400
committerGravatar bunnei2016-05-29 21:57:07 -0400
commitab4b27f0f5760c7f378f29756d3ce631bafca1b2 (patch)
tree6340ca66710e9603db24c051da0b8173b796d3c6 /src/core/memory.cpp
parentMerge pull request #1756 from wwylele/config-cleanup (diff)
parentMemory: Handle RasterizerCachedMemory and RasterizerCachedSpecial page types ... (diff)
downloadyuzu-ab4b27f0f5760c7f378f29756d3ce631bafca1b2.tar.gz
yuzu-ab4b27f0f5760c7f378f29756d3ce631bafca1b2.tar.xz
yuzu-ab4b27f0f5760c7f378f29756d3ce631bafca1b2.zip
Merge pull request #1692 from Subv/rm_getpointer2
Memory: Remove most usages of GetPointer
Diffstat (limited to 'src/core/memory.cpp')
-rw-r--r--src/core/memory.cpp236
1 files changed, 233 insertions, 3 deletions
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index ee9b69f81..8c9e5d46d 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -246,6 +246,26 @@ void Write(const VAddr vaddr, const T data) {
246 } 246 }
247} 247}
248 248
249bool IsValidVirtualAddress(const VAddr vaddr) {
250 const u8* page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS];
251 if (page_pointer)
252 return true;
253
254 if (current_page_table->attributes[vaddr >> PAGE_BITS] != PageType::Special)
255 return false;
256
257 MMIORegionPointer mmio_region = GetMMIOHandler(vaddr);
258 if (mmio_region) {
259 return mmio_region->IsValidAddress(vaddr);
260 }
261
262 return false;
263}
264
265bool IsValidPhysicalAddress(const PAddr paddr) {
266 return IsValidVirtualAddress(PhysicalToVirtualAddress(paddr));
267}
268
249u8* GetPointer(const VAddr vaddr) { 269u8* GetPointer(const VAddr vaddr) {
250 u8* page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS]; 270 u8* page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS];
251 if (page_pointer) { 271 if (page_pointer) {
@@ -261,6 +281,7 @@ u8* GetPointer(const VAddr vaddr) {
261} 281}
262 282
263u8* GetPhysicalPointer(PAddr address) { 283u8* GetPhysicalPointer(PAddr address) {
284 // TODO(Subv): This call should not go through the application's memory mapping.
264 return GetPointer(PhysicalToVirtualAddress(address)); 285 return GetPointer(PhysicalToVirtualAddress(address));
265} 286}
266 287
@@ -343,6 +364,59 @@ u64 Read64(const VAddr addr) {
343 return Read<u64_le>(addr); 364 return Read<u64_le>(addr);
344} 365}
345 366
367void ReadBlock(const VAddr src_addr, void* dest_buffer, const size_t size) {
368 size_t remaining_size = size;
369 size_t page_index = src_addr >> PAGE_BITS;
370 size_t page_offset = src_addr & PAGE_MASK;
371
372 while (remaining_size > 0) {
373 const size_t copy_amount = std::min(PAGE_SIZE - page_offset, remaining_size);
374 const VAddr current_vaddr = (page_index << PAGE_BITS) + page_offset;
375
376 switch (current_page_table->attributes[page_index]) {
377 case PageType::Unmapped: {
378 LOG_ERROR(HW_Memory, "unmapped ReadBlock @ 0x%08X (start address = 0x%08X, size = %zu)", current_vaddr, src_addr, size);
379 std::memset(dest_buffer, 0, copy_amount);
380 break;
381 }
382 case PageType::Memory: {
383 DEBUG_ASSERT(current_page_table->pointers[page_index]);
384
385 const u8* src_ptr = current_page_table->pointers[page_index] + page_offset;
386 std::memcpy(dest_buffer, src_ptr, copy_amount);
387 break;
388 }
389 case PageType::Special: {
390 DEBUG_ASSERT(GetMMIOHandler(current_vaddr));
391
392 GetMMIOHandler(current_vaddr)->ReadBlock(current_vaddr, dest_buffer, copy_amount);
393 break;
394 }
395 case PageType::RasterizerCachedMemory: {
396 RasterizerFlushRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount);
397
398 std::memcpy(dest_buffer, GetPointerFromVMA(current_vaddr), copy_amount);
399 break;
400 }
401 case PageType::RasterizerCachedSpecial: {
402 DEBUG_ASSERT(GetMMIOHandler(current_vaddr));
403
404 RasterizerFlushRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount);
405
406 GetMMIOHandler(current_vaddr)->ReadBlock(current_vaddr, dest_buffer, copy_amount);
407 break;
408 }
409 default:
410 UNREACHABLE();
411 }
412
413 page_index++;
414 page_offset = 0;
415 dest_buffer = static_cast<u8*>(dest_buffer) + copy_amount;
416 remaining_size -= copy_amount;
417 }
418}
419
346void Write8(const VAddr addr, const u8 data) { 420void Write8(const VAddr addr, const u8 data) {
347 Write<u8>(addr, data); 421 Write<u8>(addr, data);
348} 422}
@@ -359,9 +433,165 @@ void Write64(const VAddr addr, const u64 data) {
359 Write<u64_le>(addr, data); 433 Write<u64_le>(addr, data);
360} 434}
361 435
362void WriteBlock(const VAddr addr, const u8* data, const size_t size) { 436void WriteBlock(const VAddr dest_addr, const void* src_buffer, const size_t size) {
363 for (u32 offset = 0; offset < size; offset++) { 437 size_t remaining_size = size;
364 Write8(addr + offset, data[offset]); 438 size_t page_index = dest_addr >> PAGE_BITS;
439 size_t page_offset = dest_addr & PAGE_MASK;
440
441 while (remaining_size > 0) {
442 const size_t copy_amount = std::min(PAGE_SIZE - page_offset, remaining_size);
443 const VAddr current_vaddr = (page_index << PAGE_BITS) + page_offset;
444
445 switch (current_page_table->attributes[page_index]) {
446 case PageType::Unmapped: {
447 LOG_ERROR(HW_Memory, "unmapped WriteBlock @ 0x%08X (start address = 0x%08X, size = %zu)", current_vaddr, dest_addr, size);
448 break;
449 }
450 case PageType::Memory: {
451 DEBUG_ASSERT(current_page_table->pointers[page_index]);
452
453 u8* dest_ptr = current_page_table->pointers[page_index] + page_offset;
454 std::memcpy(dest_ptr, src_buffer, copy_amount);
455 break;
456 }
457 case PageType::Special: {
458 DEBUG_ASSERT(GetMMIOHandler(current_vaddr));
459
460 GetMMIOHandler(current_vaddr)->WriteBlock(current_vaddr, src_buffer, copy_amount);
461 break;
462 }
463 case PageType::RasterizerCachedMemory: {
464 RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount);
465
466 std::memcpy(GetPointerFromVMA(current_vaddr), src_buffer, copy_amount);
467 break;
468 }
469 case PageType::RasterizerCachedSpecial: {
470 DEBUG_ASSERT(GetMMIOHandler(current_vaddr));
471
472 RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount);
473
474 GetMMIOHandler(current_vaddr)->WriteBlock(current_vaddr, src_buffer, copy_amount);
475 break;
476 }
477 default:
478 UNREACHABLE();
479 }
480
481 page_index++;
482 page_offset = 0;
483 src_buffer = static_cast<const u8*>(src_buffer) + copy_amount;
484 remaining_size -= copy_amount;
485 }
486}
487
488void ZeroBlock(const VAddr dest_addr, const size_t size) {
489 size_t remaining_size = size;
490 size_t page_index = dest_addr >> PAGE_BITS;
491 size_t page_offset = dest_addr & PAGE_MASK;
492
493 static const std::array<u8, PAGE_SIZE> zeros = {};
494
495 while (remaining_size > 0) {
496 const size_t copy_amount = std::min(PAGE_SIZE - page_offset, remaining_size);
497 const VAddr current_vaddr = (page_index << PAGE_BITS) + page_offset;
498
499 switch (current_page_table->attributes[page_index]) {
500 case PageType::Unmapped: {
501 LOG_ERROR(HW_Memory, "unmapped ZeroBlock @ 0x%08X (start address = 0x%08X, size = %zu)", current_vaddr, dest_addr, size);
502 break;
503 }
504 case PageType::Memory: {
505 DEBUG_ASSERT(current_page_table->pointers[page_index]);
506
507 u8* dest_ptr = current_page_table->pointers[page_index] + page_offset;
508 std::memset(dest_ptr, 0, copy_amount);
509 break;
510 }
511 case PageType::Special: {
512 DEBUG_ASSERT(GetMMIOHandler(current_vaddr));
513
514 GetMMIOHandler(current_vaddr)->WriteBlock(current_vaddr, zeros.data(), copy_amount);
515 break;
516 }
517 case PageType::RasterizerCachedMemory: {
518 RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount);
519
520 std::memset(GetPointerFromVMA(current_vaddr), 0, copy_amount);
521 break;
522 }
523 case PageType::RasterizerCachedSpecial: {
524 DEBUG_ASSERT(GetMMIOHandler(current_vaddr));
525
526 RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount);
527
528 GetMMIOHandler(current_vaddr)->WriteBlock(current_vaddr, zeros.data(), copy_amount);
529 break;
530 }
531 default:
532 UNREACHABLE();
533 }
534
535 page_index++;
536 page_offset = 0;
537 remaining_size -= copy_amount;
538 }
539}
540
541void CopyBlock(VAddr dest_addr, VAddr src_addr, const size_t size) {
542 size_t remaining_size = size;
543 size_t page_index = src_addr >> PAGE_BITS;
544 size_t page_offset = src_addr & PAGE_MASK;
545
546 while (remaining_size > 0) {
547 const size_t copy_amount = std::min(PAGE_SIZE - page_offset, remaining_size);
548 const VAddr current_vaddr = (page_index << PAGE_BITS) + page_offset;
549
550 switch (current_page_table->attributes[page_index]) {
551 case PageType::Unmapped: {
552 LOG_ERROR(HW_Memory, "unmapped CopyBlock @ 0x%08X (start address = 0x%08X, size = %zu)", current_vaddr, src_addr, size);
553 ZeroBlock(dest_addr, copy_amount);
554 break;
555 }
556 case PageType::Memory: {
557 DEBUG_ASSERT(current_page_table->pointers[page_index]);
558 const u8* src_ptr = current_page_table->pointers[page_index] + page_offset;
559 WriteBlock(dest_addr, src_ptr, copy_amount);
560 break;
561 }
562 case PageType::Special: {
563 DEBUG_ASSERT(GetMMIOHandler(current_vaddr));
564
565 std::vector<u8> buffer(copy_amount);
566 GetMMIOHandler(current_vaddr)->ReadBlock(current_vaddr, buffer.data(), buffer.size());
567 WriteBlock(dest_addr, buffer.data(), buffer.size());
568 break;
569 }
570 case PageType::RasterizerCachedMemory: {
571 RasterizerFlushRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount);
572
573 WriteBlock(dest_addr, GetPointerFromVMA(current_vaddr), copy_amount);
574 break;
575 }
576 case PageType::RasterizerCachedSpecial: {
577 DEBUG_ASSERT(GetMMIOHandler(current_vaddr));
578
579 RasterizerFlushRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount);
580
581 std::vector<u8> buffer(copy_amount);
582 GetMMIOHandler(current_vaddr)->ReadBlock(current_vaddr, buffer.data(), buffer.size());
583 WriteBlock(dest_addr, buffer.data(), buffer.size());
584 break;
585 }
586 default:
587 UNREACHABLE();
588 }
589
590 page_index++;
591 page_offset = 0;
592 dest_addr += copy_amount;
593 src_addr += copy_amount;
594 remaining_size -= copy_amount;
365 } 595 }
366} 596}
367 597