summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/hle/kernel/thread.cpp6
-rw-r--r--src/core/hle/kernel/thread.h6
-rw-r--r--src/core/memory.cpp67
-rw-r--r--src/core/memory.h4
4 files changed, 61 insertions, 22 deletions
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 2614a260c..0f7970ebe 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -541,6 +541,12 @@ s32 Thread::GetWaitObjectIndex(WaitObject* object) const {
541 return static_cast<s32>(std::distance(match, wait_objects.rend()) - 1); 541 return static_cast<s32>(std::distance(match, wait_objects.rend()) - 1);
542} 542}
543 543
544VAddr Thread::GetCommandBufferAddress() const {
545 // Offset from the start of TLS at which the IPC command buffer begins.
546 static constexpr int CommandHeaderOffset = 0x80;
547 return GetTLSAddress() + CommandHeaderOffset;
548}
549
544//////////////////////////////////////////////////////////////////////////////////////////////////// 550////////////////////////////////////////////////////////////////////////////////////////////////////
545 551
546void ThreadingInit() { 552void ThreadingInit() {
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index 4679c2022..314fba81f 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -164,6 +164,12 @@ public:
164 return tls_address; 164 return tls_address;
165 } 165 }
166 166
167 /*
168 * Returns the address of the current thread's command buffer, located in the TLS.
169 * @returns VAddr of the thread's command buffer.
170 */
171 VAddr GetCommandBufferAddress() const;
172
167 /** 173 /**
168 * Returns whether this thread is waiting for all the objects in 174 * Returns whether this thread is waiting for all the objects in
169 * its wait list to become ready, as a result of a WaitSynchronizationN call 175 * its wait list to become ready, as a result of a WaitSynchronizationN call
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index 847e69710..7f58be6de 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -82,10 +82,10 @@ void UnmapRegion(PageTable& page_table, VAddr base, u32 size) {
82 * Gets a pointer to the exact memory at the virtual address (i.e. not page aligned) 82 * Gets a pointer to the exact memory at the virtual address (i.e. not page aligned)
83 * using a VMA from the current process 83 * using a VMA from the current process
84 */ 84 */
85static u8* GetPointerFromVMA(VAddr vaddr) { 85static u8* GetPointerFromVMA(const Kernel::Process& process, VAddr vaddr) {
86 u8* direct_pointer = nullptr; 86 u8* direct_pointer = nullptr;
87 87
88 auto& vm_manager = Kernel::g_current_process->vm_manager; 88 auto& vm_manager = process.vm_manager;
89 89
90 auto it = vm_manager.FindVMA(vaddr); 90 auto it = vm_manager.FindVMA(vaddr);
91 ASSERT(it != vm_manager.vma_map.end()); 91 ASSERT(it != vm_manager.vma_map.end());
@@ -108,6 +108,14 @@ static u8* GetPointerFromVMA(VAddr vaddr) {
108} 108}
109 109
110/** 110/**
111 * Gets a pointer to the exact memory at the virtual address (i.e. not page aligned)
112 * using a VMA from the current process.
113 */
114static u8* GetPointerFromVMA(VAddr vaddr) {
115 return GetPointerFromVMA(*Kernel::g_current_process, vaddr);
116}
117
118/**
111 * This function should only be called for virtual addreses with attribute `PageType::Special`. 119 * This function should only be called for virtual addreses with attribute `PageType::Special`.
112 */ 120 */
113static MMIORegionPointer GetMMIOHandler(const PageTable& page_table, VAddr vaddr) { 121static MMIORegionPointer GetMMIOHandler(const PageTable& page_table, VAddr vaddr) {
@@ -470,7 +478,10 @@ u64 Read64(const VAddr addr) {
470 return Read<u64_le>(addr); 478 return Read<u64_le>(addr);
471} 479}
472 480
473void ReadBlock(const VAddr src_addr, void* dest_buffer, const size_t size) { 481void ReadBlock(const Kernel::Process& process, const VAddr src_addr, void* dest_buffer,
482 const size_t size) {
483 auto& page_table = process.vm_manager.page_table;
484
474 size_t remaining_size = size; 485 size_t remaining_size = size;
475 size_t page_index = src_addr >> PAGE_BITS; 486 size_t page_index = src_addr >> PAGE_BITS;
476 size_t page_offset = src_addr & PAGE_MASK; 487 size_t page_offset = src_addr & PAGE_MASK;
@@ -479,7 +490,7 @@ void ReadBlock(const VAddr src_addr, void* dest_buffer, const size_t size) {
479 const size_t copy_amount = std::min(PAGE_SIZE - page_offset, remaining_size); 490 const size_t copy_amount = std::min(PAGE_SIZE - page_offset, remaining_size);
480 const VAddr current_vaddr = static_cast<VAddr>((page_index << PAGE_BITS) + page_offset); 491 const VAddr current_vaddr = static_cast<VAddr>((page_index << PAGE_BITS) + page_offset);
481 492
482 switch (current_page_table->attributes[page_index]) { 493 switch (page_table.attributes[page_index]) {
483 case PageType::Unmapped: { 494 case PageType::Unmapped: {
484 LOG_ERROR(HW_Memory, "unmapped ReadBlock @ 0x%08X (start address = 0x%08X, size = %zu)", 495 LOG_ERROR(HW_Memory, "unmapped ReadBlock @ 0x%08X (start address = 0x%08X, size = %zu)",
485 current_vaddr, src_addr, size); 496 current_vaddr, src_addr, size);
@@ -487,29 +498,30 @@ void ReadBlock(const VAddr src_addr, void* dest_buffer, const size_t size) {
487 break; 498 break;
488 } 499 }
489 case PageType::Memory: { 500 case PageType::Memory: {
490 DEBUG_ASSERT(current_page_table->pointers[page_index]); 501 DEBUG_ASSERT(page_table.pointers[page_index]);
491 502
492 const u8* src_ptr = current_page_table->pointers[page_index] + page_offset; 503 const u8* src_ptr = page_table.pointers[page_index] + page_offset;
493 std::memcpy(dest_buffer, src_ptr, copy_amount); 504 std::memcpy(dest_buffer, src_ptr, copy_amount);
494 break; 505 break;
495 } 506 }
496 case PageType::Special: { 507 case PageType::Special: {
497 DEBUG_ASSERT(GetMMIOHandler(current_vaddr)); 508 MMIORegionPointer handler = GetMMIOHandler(page_table, current_vaddr);
498 509 DEBUG_ASSERT(handler);
499 GetMMIOHandler(current_vaddr)->ReadBlock(current_vaddr, dest_buffer, copy_amount); 510 handler->ReadBlock(current_vaddr, dest_buffer, copy_amount);
500 break; 511 break;
501 } 512 }
502 case PageType::RasterizerCachedMemory: { 513 case PageType::RasterizerCachedMemory: {
503 RasterizerFlushVirtualRegion(current_vaddr, static_cast<u32>(copy_amount), 514 RasterizerFlushVirtualRegion(current_vaddr, static_cast<u32>(copy_amount),
504 FlushMode::Flush); 515 FlushMode::Flush);
505 std::memcpy(dest_buffer, GetPointerFromVMA(current_vaddr), copy_amount); 516 std::memcpy(dest_buffer, GetPointerFromVMA(process, current_vaddr), copy_amount);
506 break; 517 break;
507 } 518 }
508 case PageType::RasterizerCachedSpecial: { 519 case PageType::RasterizerCachedSpecial: {
509 DEBUG_ASSERT(GetMMIOHandler(current_vaddr)); 520 MMIORegionPointer handler = GetMMIOHandler(page_table, current_vaddr);
521 DEBUG_ASSERT(handler);
510 RasterizerFlushVirtualRegion(current_vaddr, static_cast<u32>(copy_amount), 522 RasterizerFlushVirtualRegion(current_vaddr, static_cast<u32>(copy_amount),
511 FlushMode::Flush); 523 FlushMode::Flush);
512 GetMMIOHandler(current_vaddr)->ReadBlock(current_vaddr, dest_buffer, copy_amount); 524 handler->ReadBlock(current_vaddr, dest_buffer, copy_amount);
513 break; 525 break;
514 } 526 }
515 default: 527 default:
@@ -523,6 +535,10 @@ void ReadBlock(const VAddr src_addr, void* dest_buffer, const size_t size) {
523 } 535 }
524} 536}
525 537
538void ReadBlock(const VAddr src_addr, void* dest_buffer, const size_t size) {
539 ReadBlock(*Kernel::g_current_process, src_addr, dest_buffer, size);
540}
541
526void Write8(const VAddr addr, const u8 data) { 542void Write8(const VAddr addr, const u8 data) {
527 Write<u8>(addr, data); 543 Write<u8>(addr, data);
528} 544}
@@ -539,7 +555,9 @@ void Write64(const VAddr addr, const u64 data) {
539 Write<u64_le>(addr, data); 555 Write<u64_le>(addr, data);
540} 556}
541 557
542void WriteBlock(const VAddr dest_addr, const void* src_buffer, const size_t size) { 558void WriteBlock(const Kernel::Process& process, const VAddr dest_addr, const void* src_buffer,
559 const size_t size) {
560 auto& page_table = process.vm_manager.page_table;
543 size_t remaining_size = size; 561 size_t remaining_size = size;
544 size_t page_index = dest_addr >> PAGE_BITS; 562 size_t page_index = dest_addr >> PAGE_BITS;
545 size_t page_offset = dest_addr & PAGE_MASK; 563 size_t page_offset = dest_addr & PAGE_MASK;
@@ -548,7 +566,7 @@ void WriteBlock(const VAddr dest_addr, const void* src_buffer, const size_t size
548 const size_t copy_amount = std::min(PAGE_SIZE - page_offset, remaining_size); 566 const size_t copy_amount = std::min(PAGE_SIZE - page_offset, remaining_size);
549 const VAddr current_vaddr = static_cast<VAddr>((page_index << PAGE_BITS) + page_offset); 567 const VAddr current_vaddr = static_cast<VAddr>((page_index << PAGE_BITS) + page_offset);
550 568
551 switch (current_page_table->attributes[page_index]) { 569 switch (page_table.attributes[page_index]) {
552 case PageType::Unmapped: { 570 case PageType::Unmapped: {
553 LOG_ERROR(HW_Memory, 571 LOG_ERROR(HW_Memory,
554 "unmapped WriteBlock @ 0x%08X (start address = 0x%08X, size = %zu)", 572 "unmapped WriteBlock @ 0x%08X (start address = 0x%08X, size = %zu)",
@@ -556,29 +574,30 @@ void WriteBlock(const VAddr dest_addr, const void* src_buffer, const size_t size
556 break; 574 break;
557 } 575 }
558 case PageType::Memory: { 576 case PageType::Memory: {
559 DEBUG_ASSERT(current_page_table->pointers[page_index]); 577 DEBUG_ASSERT(page_table.pointers[page_index]);
560 578
561 u8* dest_ptr = current_page_table->pointers[page_index] + page_offset; 579 u8* dest_ptr = page_table.pointers[page_index] + page_offset;
562 std::memcpy(dest_ptr, src_buffer, copy_amount); 580 std::memcpy(dest_ptr, src_buffer, copy_amount);
563 break; 581 break;
564 } 582 }
565 case PageType::Special: { 583 case PageType::Special: {
566 DEBUG_ASSERT(GetMMIOHandler(current_vaddr)); 584 MMIORegionPointer handler = GetMMIOHandler(page_table, current_vaddr);
567 585 DEBUG_ASSERT(handler);
568 GetMMIOHandler(current_vaddr)->WriteBlock(current_vaddr, src_buffer, copy_amount); 586 handler->WriteBlock(current_vaddr, src_buffer, copy_amount);
569 break; 587 break;
570 } 588 }
571 case PageType::RasterizerCachedMemory: { 589 case PageType::RasterizerCachedMemory: {
572 RasterizerFlushVirtualRegion(current_vaddr, static_cast<u32>(copy_amount), 590 RasterizerFlushVirtualRegion(current_vaddr, static_cast<u32>(copy_amount),
573 FlushMode::FlushAndInvalidate); 591 FlushMode::FlushAndInvalidate);
574 std::memcpy(GetPointerFromVMA(current_vaddr), src_buffer, copy_amount); 592 std::memcpy(GetPointerFromVMA(process, current_vaddr), src_buffer, copy_amount);
575 break; 593 break;
576 } 594 }
577 case PageType::RasterizerCachedSpecial: { 595 case PageType::RasterizerCachedSpecial: {
578 DEBUG_ASSERT(GetMMIOHandler(current_vaddr)); 596 MMIORegionPointer handler = GetMMIOHandler(page_table, current_vaddr);
597 DEBUG_ASSERT(handler);
579 RasterizerFlushVirtualRegion(current_vaddr, static_cast<u32>(copy_amount), 598 RasterizerFlushVirtualRegion(current_vaddr, static_cast<u32>(copy_amount),
580 FlushMode::FlushAndInvalidate); 599 FlushMode::FlushAndInvalidate);
581 GetMMIOHandler(current_vaddr)->WriteBlock(current_vaddr, src_buffer, copy_amount); 600 handler->WriteBlock(current_vaddr, src_buffer, copy_amount);
582 break; 601 break;
583 } 602 }
584 default: 603 default:
@@ -592,6 +611,10 @@ void WriteBlock(const VAddr dest_addr, const void* src_buffer, const size_t size
592 } 611 }
593} 612}
594 613
614void WriteBlock(const VAddr dest_addr, const void* src_buffer, const size_t size) {
615 WriteBlock(*Kernel::g_current_process, dest_addr, src_buffer, size);
616}
617
595void ZeroBlock(const VAddr dest_addr, const size_t size) { 618void ZeroBlock(const VAddr dest_addr, const size_t size) {
596 size_t remaining_size = size; 619 size_t remaining_size = size;
597 size_t page_index = dest_addr >> PAGE_BITS; 620 size_t page_index = dest_addr >> PAGE_BITS;
diff --git a/src/core/memory.h b/src/core/memory.h
index 347c08c78..dd599f73e 100644
--- a/src/core/memory.h
+++ b/src/core/memory.h
@@ -205,7 +205,11 @@ void Write16(VAddr addr, u16 data);
205void Write32(VAddr addr, u32 data); 205void Write32(VAddr addr, u32 data);
206void Write64(VAddr addr, u64 data); 206void Write64(VAddr addr, u64 data);
207 207
208void ReadBlock(const Kernel::Process& process, const VAddr src_addr, void* dest_buffer,
209 size_t size);
208void ReadBlock(const VAddr src_addr, void* dest_buffer, size_t size); 210void ReadBlock(const VAddr src_addr, void* dest_buffer, size_t size);
211void WriteBlock(const Kernel::Process& process, const VAddr dest_addr, const void* src_buffer,
212 size_t size);
209void WriteBlock(const VAddr dest_addr, const void* src_buffer, size_t size); 213void WriteBlock(const VAddr dest_addr, const void* src_buffer, size_t size);
210void ZeroBlock(const VAddr dest_addr, const size_t size); 214void ZeroBlock(const VAddr dest_addr, const size_t size);
211void CopyBlock(VAddr dest_addr, VAddr src_addr, size_t size); 215void CopyBlock(VAddr dest_addr, VAddr src_addr, size_t size);