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.cpp91
1 files changed, 52 insertions, 39 deletions
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index 42ca69e00..38fe9e231 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -83,19 +83,13 @@ static void MapPages(u32 base, u32 size, u8* memory, PageType type) {
83 LOG_DEBUG(HW_Memory, "Mapping %p onto %08X-%08X", memory, base * PAGE_SIZE, 83 LOG_DEBUG(HW_Memory, "Mapping %p onto %08X-%08X", memory, base * PAGE_SIZE,
84 (base + size) * PAGE_SIZE); 84 (base + size) * PAGE_SIZE);
85 85
86 u32 end = base + size; 86 RasterizerFlushVirtualRegion(base << PAGE_BITS, size * PAGE_SIZE,
87 FlushMode::FlushAndInvalidate);
87 88
89 u32 end = base + size;
88 while (base != end) { 90 while (base != end) {
89 ASSERT_MSG(base < PAGE_TABLE_NUM_ENTRIES, "out of range mapping at %08X", base); 91 ASSERT_MSG(base < PAGE_TABLE_NUM_ENTRIES, "out of range mapping at %08X", base);
90 92
91 // Since pages are unmapped on shutdown after video core is shutdown, the renderer may be
92 // null here
93 if (current_page_table->attributes[base] == PageType::RasterizerCachedMemory ||
94 current_page_table->attributes[base] == PageType::RasterizerCachedSpecial) {
95 RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(base << PAGE_BITS),
96 PAGE_SIZE);
97 }
98
99 current_page_table->attributes[base] = type; 93 current_page_table->attributes[base] = type;
100 current_page_table->pointers[base] = memory; 94 current_page_table->pointers[base] = memory;
101 current_page_table->cached_res_count[base] = 0; 95 current_page_table->cached_res_count[base] = 0;
@@ -189,7 +183,7 @@ T Read(const VAddr vaddr) {
189 ASSERT_MSG(false, "Mapped memory page without a pointer @ %08X", vaddr); 183 ASSERT_MSG(false, "Mapped memory page without a pointer @ %08X", vaddr);
190 break; 184 break;
191 case PageType::RasterizerCachedMemory: { 185 case PageType::RasterizerCachedMemory: {
192 RasterizerFlushRegion(VirtualToPhysicalAddress(vaddr), sizeof(T)); 186 RasterizerFlushVirtualRegion(vaddr, sizeof(T), FlushMode::Flush);
193 187
194 T value; 188 T value;
195 std::memcpy(&value, GetPointerFromVMA(vaddr), sizeof(T)); 189 std::memcpy(&value, GetPointerFromVMA(vaddr), sizeof(T));
@@ -198,8 +192,7 @@ T Read(const VAddr vaddr) {
198 case PageType::Special: 192 case PageType::Special:
199 return ReadMMIO<T>(GetMMIOHandler(vaddr), vaddr); 193 return ReadMMIO<T>(GetMMIOHandler(vaddr), vaddr);
200 case PageType::RasterizerCachedSpecial: { 194 case PageType::RasterizerCachedSpecial: {
201 RasterizerFlushRegion(VirtualToPhysicalAddress(vaddr), sizeof(T)); 195 RasterizerFlushVirtualRegion(vaddr, sizeof(T), FlushMode::Flush);
202
203 return ReadMMIO<T>(GetMMIOHandler(vaddr), vaddr); 196 return ReadMMIO<T>(GetMMIOHandler(vaddr), vaddr);
204 } 197 }
205 default: 198 default:
@@ -229,8 +222,7 @@ void Write(const VAddr vaddr, const T data) {
229 ASSERT_MSG(false, "Mapped memory page without a pointer @ %08X", vaddr); 222 ASSERT_MSG(false, "Mapped memory page without a pointer @ %08X", vaddr);
230 break; 223 break;
231 case PageType::RasterizerCachedMemory: { 224 case PageType::RasterizerCachedMemory: {
232 RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(vaddr), sizeof(T)); 225 RasterizerFlushVirtualRegion(vaddr, sizeof(T), FlushMode::FlushAndInvalidate);
233
234 std::memcpy(GetPointerFromVMA(vaddr), &data, sizeof(T)); 226 std::memcpy(GetPointerFromVMA(vaddr), &data, sizeof(T));
235 break; 227 break;
236 } 228 }
@@ -238,8 +230,7 @@ void Write(const VAddr vaddr, const T data) {
238 WriteMMIO<T>(GetMMIOHandler(vaddr), vaddr, data); 230 WriteMMIO<T>(GetMMIOHandler(vaddr), vaddr, data);
239 break; 231 break;
240 case PageType::RasterizerCachedSpecial: { 232 case PageType::RasterizerCachedSpecial: {
241 RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(vaddr), sizeof(T)); 233 RasterizerFlushVirtualRegion(vaddr, sizeof(T), FlushMode::FlushAndInvalidate);
242
243 WriteMMIO<T>(GetMMIOHandler(vaddr), vaddr, data); 234 WriteMMIO<T>(GetMMIOHandler(vaddr), vaddr, data);
244 break; 235 break;
245 } 236 }
@@ -369,11 +360,48 @@ void RasterizerFlushRegion(PAddr start, u32 size) {
369} 360}
370 361
371void RasterizerFlushAndInvalidateRegion(PAddr start, u32 size) { 362void RasterizerFlushAndInvalidateRegion(PAddr start, u32 size) {
363 // Since pages are unmapped on shutdown after video core is shutdown, the renderer may be
364 // null here
372 if (VideoCore::g_renderer != nullptr) { 365 if (VideoCore::g_renderer != nullptr) {
373 VideoCore::g_renderer->Rasterizer()->FlushAndInvalidateRegion(start, size); 366 VideoCore::g_renderer->Rasterizer()->FlushAndInvalidateRegion(start, size);
374 } 367 }
375} 368}
376 369
370void RasterizerFlushVirtualRegion(VAddr start, u32 size, FlushMode mode) {
371 // Since pages are unmapped on shutdown after video core is shutdown, the renderer may be
372 // null here
373 if (VideoCore::g_renderer != nullptr) {
374 VAddr end = start + size;
375
376 auto CheckRegion = [&](VAddr region_start, VAddr region_end) {
377 if (start >= region_end || end <= region_start) {
378 // No overlap with region
379 return;
380 }
381
382 VAddr overlap_start = std::max(start, region_start);
383 VAddr overlap_end = std::min(end, region_end);
384
385 PAddr physical_start = TryVirtualToPhysicalAddress(overlap_start).value();
386 u32 overlap_size = overlap_end - overlap_start;
387
388 auto* rasterizer = VideoCore::g_renderer->Rasterizer();
389 switch (mode) {
390 case FlushMode::Flush:
391 rasterizer->FlushRegion(physical_start, overlap_size);
392 break;
393 case FlushMode::FlushAndInvalidate:
394 rasterizer->FlushAndInvalidateRegion(physical_start, overlap_size);
395 break;
396 }
397 };
398
399 CheckRegion(LINEAR_HEAP_VADDR, LINEAR_HEAP_VADDR_END);
400 CheckRegion(NEW_LINEAR_HEAP_VADDR, NEW_LINEAR_HEAP_VADDR_END);
401 CheckRegion(VRAM_VADDR, VRAM_VADDR_END);
402 }
403}
404
377u8 Read8(const VAddr addr) { 405u8 Read8(const VAddr addr) {
378 return Read<u8>(addr); 406 return Read<u8>(addr);
379} 407}
@@ -420,16 +448,13 @@ void ReadBlock(const VAddr src_addr, void* dest_buffer, const size_t size) {
420 break; 448 break;
421 } 449 }
422 case PageType::RasterizerCachedMemory: { 450 case PageType::RasterizerCachedMemory: {
423 RasterizerFlushRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount); 451 RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::Flush);
424
425 std::memcpy(dest_buffer, GetPointerFromVMA(current_vaddr), copy_amount); 452 std::memcpy(dest_buffer, GetPointerFromVMA(current_vaddr), copy_amount);
426 break; 453 break;
427 } 454 }
428 case PageType::RasterizerCachedSpecial: { 455 case PageType::RasterizerCachedSpecial: {
429 DEBUG_ASSERT(GetMMIOHandler(current_vaddr)); 456 DEBUG_ASSERT(GetMMIOHandler(current_vaddr));
430 457 RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::Flush);
431 RasterizerFlushRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount);
432
433 GetMMIOHandler(current_vaddr)->ReadBlock(current_vaddr, dest_buffer, copy_amount); 458 GetMMIOHandler(current_vaddr)->ReadBlock(current_vaddr, dest_buffer, copy_amount);
434 break; 459 break;
435 } 460 }
@@ -490,18 +515,13 @@ void WriteBlock(const VAddr dest_addr, const void* src_buffer, const size_t size
490 break; 515 break;
491 } 516 }
492 case PageType::RasterizerCachedMemory: { 517 case PageType::RasterizerCachedMemory: {
493 RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(current_vaddr), 518 RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::FlushAndInvalidate);
494 copy_amount);
495
496 std::memcpy(GetPointerFromVMA(current_vaddr), src_buffer, copy_amount); 519 std::memcpy(GetPointerFromVMA(current_vaddr), src_buffer, copy_amount);
497 break; 520 break;
498 } 521 }
499 case PageType::RasterizerCachedSpecial: { 522 case PageType::RasterizerCachedSpecial: {
500 DEBUG_ASSERT(GetMMIOHandler(current_vaddr)); 523 DEBUG_ASSERT(GetMMIOHandler(current_vaddr));
501 524 RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::FlushAndInvalidate);
502 RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(current_vaddr),
503 copy_amount);
504
505 GetMMIOHandler(current_vaddr)->WriteBlock(current_vaddr, src_buffer, copy_amount); 525 GetMMIOHandler(current_vaddr)->WriteBlock(current_vaddr, src_buffer, copy_amount);
506 break; 526 break;
507 } 527 }
@@ -547,18 +567,13 @@ void ZeroBlock(const VAddr dest_addr, const size_t size) {
547 break; 567 break;
548 } 568 }
549 case PageType::RasterizerCachedMemory: { 569 case PageType::RasterizerCachedMemory: {
550 RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(current_vaddr), 570 RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::FlushAndInvalidate);
551 copy_amount);
552
553 std::memset(GetPointerFromVMA(current_vaddr), 0, copy_amount); 571 std::memset(GetPointerFromVMA(current_vaddr), 0, copy_amount);
554 break; 572 break;
555 } 573 }
556 case PageType::RasterizerCachedSpecial: { 574 case PageType::RasterizerCachedSpecial: {
557 DEBUG_ASSERT(GetMMIOHandler(current_vaddr)); 575 DEBUG_ASSERT(GetMMIOHandler(current_vaddr));
558 576 RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::FlushAndInvalidate);
559 RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(current_vaddr),
560 copy_amount);
561
562 GetMMIOHandler(current_vaddr)->WriteBlock(current_vaddr, zeros.data(), copy_amount); 577 GetMMIOHandler(current_vaddr)->WriteBlock(current_vaddr, zeros.data(), copy_amount);
563 break; 578 break;
564 } 579 }
@@ -603,15 +618,13 @@ void CopyBlock(VAddr dest_addr, VAddr src_addr, const size_t size) {
603 break; 618 break;
604 } 619 }
605 case PageType::RasterizerCachedMemory: { 620 case PageType::RasterizerCachedMemory: {
606 RasterizerFlushRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount); 621 RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::Flush);
607
608 WriteBlock(dest_addr, GetPointerFromVMA(current_vaddr), copy_amount); 622 WriteBlock(dest_addr, GetPointerFromVMA(current_vaddr), copy_amount);
609 break; 623 break;
610 } 624 }
611 case PageType::RasterizerCachedSpecial: { 625 case PageType::RasterizerCachedSpecial: {
612 DEBUG_ASSERT(GetMMIOHandler(current_vaddr)); 626 DEBUG_ASSERT(GetMMIOHandler(current_vaddr));
613 627 RasterizerFlushVirtualRegion(current_vaddr, copy_amount, FlushMode::Flush);
614 RasterizerFlushRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount);
615 628
616 std::vector<u8> buffer(copy_amount); 629 std::vector<u8> buffer(copy_amount);
617 GetMMIOHandler(current_vaddr)->ReadBlock(current_vaddr, buffer.data(), buffer.size()); 630 GetMMIOHandler(current_vaddr)->ReadBlock(current_vaddr, buffer.data(), buffer.size());