From c084fc824cf4e076bb83e41af64f5cfaa9204dcb Mon Sep 17 00:00:00 2001 From: MerryMage Date: Sat, 16 Apr 2016 08:46:11 +0100 Subject: Memory: IsValidVirtualAddress/IsValidPhysicalAddress --- src/core/memory.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'src/core/memory.cpp') diff --git a/src/core/memory.cpp b/src/core/memory.cpp index ee9b69f81..68a29b154 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -246,6 +246,26 @@ void Write(const VAddr vaddr, const T data) { } } +bool IsValidVirtualAddress(const VAddr vaddr) { + const u8* page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS]; + if (page_pointer) + return true; + + if (current_page_table->attributes[vaddr >> PAGE_BITS] != PageType::Special) + return false; + + MMIORegionPointer mmio_region = GetMMIOHandler(vaddr); + if (mmio_region) { + return mmio_region->IsValidAddress(vaddr); + } + + return false; +} + +bool IsValidPhysicalAddress(const PAddr paddr) { + return IsValidVirtualAddress(PhysicalToVirtualAddress(paddr)); +} + u8* GetPointer(const VAddr vaddr) { u8* page_pointer = current_page_table->pointers[vaddr >> PAGE_BITS]; if (page_pointer) { @@ -261,6 +281,7 @@ u8* GetPointer(const VAddr vaddr) { } u8* GetPhysicalPointer(PAddr address) { + // TODO(Subv): This call should not go through the application's memory mapping. return GetPointer(PhysicalToVirtualAddress(address)); } -- cgit v1.2.3 From 3873b36db333547152280b741e85aa54c69d8199 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Sat, 16 Apr 2016 09:14:18 +0100 Subject: Memory: ReadBlock/WriteBlock --- src/core/memory.cpp | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 74 insertions(+), 3 deletions(-) (limited to 'src/core/memory.cpp') diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 68a29b154..c7b99a467 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -364,6 +364,45 @@ u64 Read64(const VAddr addr) { return Read(addr); } +void ReadBlock(const VAddr src_addr, u8* dest_buffer, const size_t size) { + size_t remaining_size = size; + size_t page_index = src_addr >> PAGE_BITS; + size_t page_offset = src_addr & PAGE_MASK; + + while (remaining_size > 0) { + const size_t copy_amount = std::min(PAGE_SIZE - page_offset, remaining_size); + const VAddr current_vaddr = (page_index << PAGE_BITS) + page_offset; + + switch (current_page_table->attributes[page_index]) { + case PageType::Unmapped: { + LOG_ERROR(HW_Memory, "unmapped ReadBlock @ 0x%08X (start address = 0x%08X, size = %zu)", current_vaddr, src_addr, size); + std::memset(dest_buffer, 0, copy_amount); + break; + } + case PageType::Memory: { + DEBUG_ASSERT(current_page_table->pointers[page_index]); + + const u8* src_ptr = current_page_table->pointers[page_index] + page_offset; + std::memcpy(dest_buffer, src_ptr, copy_amount); + break; + } + case PageType::Special: { + DEBUG_ASSERT(GetMMIOHandler(current_vaddr)); + + GetMMIOHandler(current_vaddr)->ReadBlock(current_vaddr, dest_buffer, copy_amount); + break; + } + default: + UNREACHABLE(); + } + + page_index++; + page_offset = 0; + dest_buffer += copy_amount; + remaining_size -= copy_amount; + } +} + void Write8(const VAddr addr, const u8 data) { Write(addr, data); } @@ -380,9 +419,41 @@ void Write64(const VAddr addr, const u64 data) { Write(addr, data); } -void WriteBlock(const VAddr addr, const u8* data, const size_t size) { - for (u32 offset = 0; offset < size; offset++) { - Write8(addr + offset, data[offset]); +void WriteBlock(const VAddr dest_addr, const u8* src_buffer, const size_t size) { + size_t remaining_size = size; + size_t page_index = dest_addr >> PAGE_BITS; + size_t page_offset = dest_addr & PAGE_MASK; + + while (remaining_size > 0) { + const size_t copy_amount = std::min(PAGE_SIZE - page_offset, remaining_size); + const VAddr current_vaddr = (page_index << PAGE_BITS) + page_offset; + + switch (current_page_table->attributes[page_index]) { + case PageType::Unmapped: { + LOG_ERROR(HW_Memory, "unmapped WriteBlock @ 0x%08X (start address = 0x%08X, size = %zu)", current_vaddr, dest_addr, size); + break; + } + case PageType::Memory: { + DEBUG_ASSERT(current_page_table->pointers[page_index]); + + u8* dest_ptr = current_page_table->pointers[page_index] + page_offset; + std::memcpy(dest_ptr, src_buffer, copy_amount); + break; + } + case PageType::Special: { + DEBUG_ASSERT(GetMMIOHandler(current_vaddr)); + + GetMMIOHandler(current_vaddr)->WriteBlock(current_vaddr, src_buffer, copy_amount); + break; + } + default: + UNREACHABLE(); + } + + page_index++; + page_offset = 0; + src_buffer += copy_amount; + remaining_size -= copy_amount; } } -- cgit v1.2.3 From ca17df5757f08c7bb673aec19e0fdd4698dd904f Mon Sep 17 00:00:00 2001 From: MerryMage Date: Sat, 16 Apr 2016 10:21:41 +0100 Subject: Memory: ZeroBlock --- src/core/memory.cpp | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'src/core/memory.cpp') diff --git a/src/core/memory.cpp b/src/core/memory.cpp index c7b99a467..1604a7da5 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -457,6 +457,44 @@ void WriteBlock(const VAddr dest_addr, const u8* src_buffer, const size_t size) } } +void ZeroBlock(const VAddr dest_addr, const size_t size) { + size_t remaining_size = size; + size_t page_index = dest_addr >> PAGE_BITS; + size_t page_offset = dest_addr & PAGE_MASK; + + while (remaining_size > 0) { + const size_t copy_amount = std::min(PAGE_SIZE - page_offset, remaining_size); + const VAddr current_vaddr = (page_index << PAGE_BITS) + page_offset; + + switch (current_page_table->attributes[page_index]) { + case PageType::Unmapped: { + LOG_ERROR(HW_Memory, "unmapped ZeroBlock @ 0x%08X (start address = 0x%08X, size = %zu)", current_vaddr, dest_addr, size); + break; + } + case PageType::Memory: { + DEBUG_ASSERT(current_page_table->pointers[page_index]); + + u8* dest_ptr = current_page_table->pointers[page_index] + page_offset; + std::memset(dest_ptr, 0, copy_amount); + break; + } + case PageType::Special: { + DEBUG_ASSERT(GetMMIOHandler(current_vaddr)); + + static const std::array zeros = {}; + GetMMIOHandler(current_vaddr)->WriteBlock(current_vaddr, zeros.data(), copy_amount); + break; + } + default: + UNREACHABLE(); + } + + page_index++; + page_offset = 0; + remaining_size -= copy_amount; + } +} + template<> u8 ReadMMIO(MMIORegionPointer mmio_handler, VAddr addr) { return mmio_handler->Read8(addr); -- cgit v1.2.3 From 31d49e01094068519850bbfa414f314fdb27beee Mon Sep 17 00:00:00 2001 From: MerryMage Date: Sat, 16 Apr 2016 15:22:45 +0100 Subject: Memory: CopyBlock --- src/core/memory.cpp | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'src/core/memory.cpp') diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 1604a7da5..bf2493270 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -495,6 +495,47 @@ void ZeroBlock(const VAddr dest_addr, const size_t size) { } } +void CopyBlock(VAddr dest_addr, VAddr src_addr, const size_t size) { + size_t remaining_size = size; + size_t page_index = src_addr >> PAGE_BITS; + size_t page_offset = src_addr & PAGE_MASK; + + while (remaining_size > 0) { + const size_t copy_amount = std::min(PAGE_SIZE - page_offset, remaining_size); + const VAddr current_vaddr = (page_index << PAGE_BITS) + page_offset; + + switch (current_page_table->attributes[page_index]) { + case PageType::Unmapped: { + LOG_ERROR(HW_Memory, "unmapped CopyBlock @ 0x%08X (start address = 0x%08X, size = %zu)", current_vaddr, src_addr, size); + ZeroBlock(dest_addr, copy_amount); + break; + } + case PageType::Memory: { + DEBUG_ASSERT(current_page_table->pointers[page_index]); + const u8* src_ptr = current_page_table->pointers[page_index] + page_offset; + WriteBlock(dest_addr, src_ptr, copy_amount); + break; + } + case PageType::Special: { + DEBUG_ASSERT(GetMMIOHandler(current_vaddr)); + + std::vector buffer(copy_amount); + GetMMIOHandler(current_vaddr)->ReadBlock(current_vaddr, buffer.data(), buffer.size()); + WriteBlock(dest_addr, buffer.data(), buffer.size()); + break; + } + default: + UNREACHABLE(); + } + + page_index++; + page_offset = 0; + dest_addr += copy_amount; + src_addr += copy_amount; + remaining_size -= copy_amount; + } +} + template<> u8 ReadMMIO(MMIORegionPointer mmio_handler, VAddr addr) { return mmio_handler->Read8(addr); -- cgit v1.2.3 From 660499ac01b9244301a0642f4a0209ef8309ace4 Mon Sep 17 00:00:00 2001 From: Subv Date: Tue, 19 Apr 2016 14:08:02 -0500 Subject: Memory: Make ReadBlock and WriteBlock accept void pointers. --- src/core/memory.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/core/memory.cpp') diff --git a/src/core/memory.cpp b/src/core/memory.cpp index bf2493270..2ac3e7de4 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -364,7 +364,7 @@ u64 Read64(const VAddr addr) { return Read(addr); } -void ReadBlock(const VAddr src_addr, u8* dest_buffer, const size_t size) { +void ReadBlock(const VAddr src_addr, void* dest_buffer, const size_t size) { size_t remaining_size = size; size_t page_index = src_addr >> PAGE_BITS; size_t page_offset = src_addr & PAGE_MASK; @@ -398,7 +398,7 @@ void ReadBlock(const VAddr src_addr, u8* dest_buffer, const size_t size) { page_index++; page_offset = 0; - dest_buffer += copy_amount; + dest_buffer = static_cast(dest_buffer) + copy_amount; remaining_size -= copy_amount; } } @@ -419,7 +419,7 @@ void Write64(const VAddr addr, const u64 data) { Write(addr, data); } -void WriteBlock(const VAddr dest_addr, const u8* src_buffer, const size_t size) { +void WriteBlock(const VAddr dest_addr, const void* src_buffer, const size_t size) { size_t remaining_size = size; size_t page_index = dest_addr >> PAGE_BITS; size_t page_offset = dest_addr & PAGE_MASK; @@ -452,7 +452,7 @@ void WriteBlock(const VAddr dest_addr, const u8* src_buffer, const size_t size) page_index++; page_offset = 0; - src_buffer += copy_amount; + src_buffer = static_cast(src_buffer) + copy_amount; remaining_size -= copy_amount; } } -- cgit v1.2.3 From 0aef634a54f786c49241c24b8d0c7aa3555b0fa1 Mon Sep 17 00:00:00 2001 From: Subv Date: Sun, 15 May 2016 12:43:52 -0500 Subject: Memory: Handle RasterizerCachedMemory and RasterizerCachedSpecial page types in the memory block manipulation functions. --- src/core/memory.cpp | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) (limited to 'src/core/memory.cpp') diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 2ac3e7de4..8c9e5d46d 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -392,6 +392,20 @@ void ReadBlock(const VAddr src_addr, void* dest_buffer, const size_t size) { GetMMIOHandler(current_vaddr)->ReadBlock(current_vaddr, dest_buffer, copy_amount); break; } + case PageType::RasterizerCachedMemory: { + RasterizerFlushRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount); + + std::memcpy(dest_buffer, GetPointerFromVMA(current_vaddr), copy_amount); + break; + } + case PageType::RasterizerCachedSpecial: { + DEBUG_ASSERT(GetMMIOHandler(current_vaddr)); + + RasterizerFlushRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount); + + GetMMIOHandler(current_vaddr)->ReadBlock(current_vaddr, dest_buffer, copy_amount); + break; + } default: UNREACHABLE(); } @@ -446,6 +460,20 @@ void WriteBlock(const VAddr dest_addr, const void* src_buffer, const size_t size GetMMIOHandler(current_vaddr)->WriteBlock(current_vaddr, src_buffer, copy_amount); break; } + case PageType::RasterizerCachedMemory: { + RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount); + + std::memcpy(GetPointerFromVMA(current_vaddr), src_buffer, copy_amount); + break; + } + case PageType::RasterizerCachedSpecial: { + DEBUG_ASSERT(GetMMIOHandler(current_vaddr)); + + RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount); + + GetMMIOHandler(current_vaddr)->WriteBlock(current_vaddr, src_buffer, copy_amount); + break; + } default: UNREACHABLE(); } @@ -462,6 +490,8 @@ void ZeroBlock(const VAddr dest_addr, const size_t size) { size_t page_index = dest_addr >> PAGE_BITS; size_t page_offset = dest_addr & PAGE_MASK; + static const std::array zeros = {}; + while (remaining_size > 0) { const size_t copy_amount = std::min(PAGE_SIZE - page_offset, remaining_size); const VAddr current_vaddr = (page_index << PAGE_BITS) + page_offset; @@ -481,7 +511,20 @@ void ZeroBlock(const VAddr dest_addr, const size_t size) { case PageType::Special: { DEBUG_ASSERT(GetMMIOHandler(current_vaddr)); - static const std::array zeros = {}; + GetMMIOHandler(current_vaddr)->WriteBlock(current_vaddr, zeros.data(), copy_amount); + break; + } + case PageType::RasterizerCachedMemory: { + RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount); + + std::memset(GetPointerFromVMA(current_vaddr), 0, copy_amount); + break; + } + case PageType::RasterizerCachedSpecial: { + DEBUG_ASSERT(GetMMIOHandler(current_vaddr)); + + RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount); + GetMMIOHandler(current_vaddr)->WriteBlock(current_vaddr, zeros.data(), copy_amount); break; } @@ -524,6 +567,22 @@ void CopyBlock(VAddr dest_addr, VAddr src_addr, const size_t size) { WriteBlock(dest_addr, buffer.data(), buffer.size()); break; } + case PageType::RasterizerCachedMemory: { + RasterizerFlushRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount); + + WriteBlock(dest_addr, GetPointerFromVMA(current_vaddr), copy_amount); + break; + } + case PageType::RasterizerCachedSpecial: { + DEBUG_ASSERT(GetMMIOHandler(current_vaddr)); + + RasterizerFlushRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount); + + std::vector buffer(copy_amount); + GetMMIOHandler(current_vaddr)->ReadBlock(current_vaddr, buffer.data(), buffer.size()); + WriteBlock(dest_addr, buffer.data(), buffer.size()); + break; + } default: UNREACHABLE(); } -- cgit v1.2.3