mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-30 21:30:04 +00:00 
			
		
		
		
	Remove memory ref from tests
This commit is contained in:
		
							parent
							
								
									e00a49e1e5
								
							
						
					
					
						commit
						af82841622
					
				
					 9 changed files with 88 additions and 247 deletions
				
			
		|  | @ -100,8 +100,6 @@ add_library(citra_common STATIC | ||||||
|     math_util.h |     math_util.h | ||||||
|     memory_detect.cpp |     memory_detect.cpp | ||||||
|     memory_detect.h |     memory_detect.h | ||||||
|     memory_ref.h |  | ||||||
|     memory_ref.cpp |  | ||||||
|     microprofile.cpp |     microprofile.cpp | ||||||
|     microprofile.h |     microprofile.h | ||||||
|     microprofileui.h |     microprofileui.h | ||||||
|  |  | ||||||
|  | @ -1,5 +0,0 @@ | ||||||
| // Copyright 2020 Citra Emulator Project
 |  | ||||||
| // Licensed under GPLv2 or any later version
 |  | ||||||
| // Refer to the license.txt file included.
 |  | ||||||
| 
 |  | ||||||
| #include "common/memory_ref.h" |  | ||||||
|  | @ -1,134 +0,0 @@ | ||||||
| // Copyright 2020 Citra Emulator Project
 |  | ||||||
| // Licensed under GPLv2 or any later version
 |  | ||||||
| // Refer to the license.txt file included.
 |  | ||||||
| 
 |  | ||||||
| #pragma once |  | ||||||
| 
 |  | ||||||
| #include <memory> |  | ||||||
| #include <span> |  | ||||||
| #include <vector> |  | ||||||
| #include "common/assert.h" |  | ||||||
| #include "common/common_types.h" |  | ||||||
| 
 |  | ||||||
| /// Abstract host-side memory - for example a static buffer, or local vector
 |  | ||||||
| class BackingMem { |  | ||||||
| public: |  | ||||||
|     virtual ~BackingMem() = default; |  | ||||||
|     virtual u8* GetPtr() = 0; |  | ||||||
|     virtual const u8* GetPtr() const = 0; |  | ||||||
|     virtual std::size_t GetSize() const = 0; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| /// Backing memory implemented by a local buffer
 |  | ||||||
| class BufferMem : public BackingMem { |  | ||||||
| public: |  | ||||||
|     BufferMem() = default; |  | ||||||
|     explicit BufferMem(std::size_t size) : data(size) {} |  | ||||||
| 
 |  | ||||||
|     u8* GetPtr() override { |  | ||||||
|         return data.data(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     const u8* GetPtr() const override { |  | ||||||
|         return data.data(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     std::size_t GetSize() const override { |  | ||||||
|         return data.size(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     std::vector<u8>& Vector() { |  | ||||||
|         return data; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     const std::vector<u8>& Vector() const { |  | ||||||
|         return data; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| private: |  | ||||||
|     std::vector<u8> data; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * A managed reference to host-side memory. |  | ||||||
|  * Fast enough to be used everywhere instead of u8* |  | ||||||
|  * Supports serialization. |  | ||||||
|  */ |  | ||||||
| class MemoryRef { |  | ||||||
| public: |  | ||||||
|     MemoryRef() = default; |  | ||||||
|     MemoryRef(std::nullptr_t) {} |  | ||||||
| 
 |  | ||||||
|     MemoryRef(std::shared_ptr<BackingMem> backing_mem_) |  | ||||||
|         : backing_mem(std::move(backing_mem_)), offset(0) { |  | ||||||
|         Init(); |  | ||||||
|     } |  | ||||||
|     MemoryRef(std::shared_ptr<BackingMem> backing_mem_, u64 offset_) |  | ||||||
|         : backing_mem(std::move(backing_mem_)), offset(offset_) { |  | ||||||
|         ASSERT(offset <= backing_mem->GetSize()); |  | ||||||
|         Init(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     explicit operator bool() const { |  | ||||||
|         return cptr != nullptr; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     operator u8*() { |  | ||||||
|         return cptr; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     u8* GetPtr() { |  | ||||||
|         return cptr; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     operator const u8*() const { |  | ||||||
|         return cptr; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     const u8* GetPtr() const { |  | ||||||
|         return cptr; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     std::span<u8> GetWriteBytes(std::size_t size) { |  | ||||||
|         return std::span{cptr, std::min(size, csize)}; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     template <typename T> |  | ||||||
|     std::span<const T> GetReadBytes(std::size_t size) const { |  | ||||||
|         const auto* cptr_t = reinterpret_cast<T*>(cptr); |  | ||||||
|         return std::span{cptr_t, std::min(size, csize) / sizeof(T)}; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     std::size_t GetSize() const { |  | ||||||
|         return csize; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     MemoryRef& operator+=(u32 offset_by) { |  | ||||||
|         ASSERT(offset_by < csize); |  | ||||||
|         offset += offset_by; |  | ||||||
|         Init(); |  | ||||||
|         return *this; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     MemoryRef operator+(u32 offset_by) const { |  | ||||||
|         ASSERT(offset_by < csize); |  | ||||||
|         return MemoryRef(backing_mem, offset + offset_by); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| private: |  | ||||||
|     std::shared_ptr<BackingMem> backing_mem{}; |  | ||||||
|     u64 offset{}; |  | ||||||
|     // Cached values for speed
 |  | ||||||
|     u8* cptr{}; |  | ||||||
|     std::size_t csize{}; |  | ||||||
| 
 |  | ||||||
|     void Init() { |  | ||||||
|         if (backing_mem) { |  | ||||||
|             cptr = backing_mem->GetPtr() + offset; |  | ||||||
|             csize = static_cast<std::size_t>(backing_mem->GetSize() - offset); |  | ||||||
|         } else { |  | ||||||
|             cptr = nullptr; |  | ||||||
|             csize = 0; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| }; |  | ||||||
|  | @ -4,19 +4,19 @@ | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| // Configuration memory stores various hardware/kernel configuration settings. This memory page is
 |  | ||||||
| // read-only for ARM11 processes. I'm guessing this would normally be written to by the firmware/
 |  | ||||||
| // bootrom. Because we're not emulating this, and essentially just "stubbing" the functionality, I'm
 |  | ||||||
| // putting this as a subset of HLE for now.
 |  | ||||||
| 
 |  | ||||||
| #include "common/common_funcs.h" | #include "common/common_funcs.h" | ||||||
| #include "common/common_types.h" | #include "common/common_types.h" | ||||||
| #include "common/memory_ref.h" |  | ||||||
| #include "common/swap.h" | #include "common/swap.h" | ||||||
| #include "core/memory.h" | #include "core/memory.h" | ||||||
| 
 | 
 | ||||||
| namespace ConfigMem { | namespace ConfigMem { | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * Configuration memory stores various hardware/kernel configuration settings. This memory page is | ||||||
|  |  * read-only for ARM11 processes. I'm guessing this would normally be written to by the firmware/ | ||||||
|  |  * bootrom. Because we're not emulating this, and essentially just "stubbing" the functionality, I'm | ||||||
|  |  * putting this as a subset of HLE for now. | ||||||
|  |  */ | ||||||
| struct ConfigMemDef { | struct ConfigMemDef { | ||||||
|     u8 kernel_unk;                       // 0
 |     u8 kernel_unk;                       // 0
 | ||||||
|     u8 kernel_version_rev;               // 1
 |     u8 kernel_version_rev;               // 1
 | ||||||
|  | @ -48,20 +48,20 @@ struct ConfigMemDef { | ||||||
| static_assert(sizeof(ConfigMemDef) == Memory::CONFIG_MEMORY_SIZE, | static_assert(sizeof(ConfigMemDef) == Memory::CONFIG_MEMORY_SIZE, | ||||||
|               "Config Memory structure size is wrong"); |               "Config Memory structure size is wrong"); | ||||||
| 
 | 
 | ||||||
| class Handler : public BackingMem { | class Handler { | ||||||
| public: | public: | ||||||
|     Handler(); |     Handler(); | ||||||
|     ConfigMemDef& GetConfigMem(); |     ConfigMemDef& GetConfigMem(); | ||||||
| 
 | 
 | ||||||
|     u8* GetPtr() override { |     u8* GetPtr() { | ||||||
|         return reinterpret_cast<u8*>(&config_mem); |         return reinterpret_cast<u8*>(&config_mem); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     const u8* GetPtr() const override { |     const u8* GetPtr() const { | ||||||
|         return reinterpret_cast<const u8*>(&config_mem); |         return reinterpret_cast<const u8*>(&config_mem); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     std::size_t GetSize() const override { |     std::size_t GetSize() const { | ||||||
|         return sizeof(config_mem); |         return sizeof(config_mem); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -11,7 +11,6 @@ | ||||||
| #include "core/core_timing.h" | #include "core/core_timing.h" | ||||||
| #include "core/hle/kernel/shared_page.h" | #include "core/hle/kernel/shared_page.h" | ||||||
| #include "core/hle/service/ptm/ptm.h" | #include "core/hle/service/ptm/ptm.h" | ||||||
| #include "core/movie.h" |  | ||||||
| 
 | 
 | ||||||
| namespace SharedPage { | namespace SharedPage { | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -4,19 +4,11 @@ | ||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| /**
 |  | ||||||
|  * The shared page stores various runtime configuration settings. This memory page is |  | ||||||
|  * read-only for user processes (there is a bit in the header that grants the process |  | ||||||
|  * write access, according to 3dbrew; this is not emulated) |  | ||||||
|  */ |  | ||||||
| 
 |  | ||||||
| #include <chrono> | #include <chrono> | ||||||
| #include <ctime> | #include <ctime> | ||||||
| #include <memory> |  | ||||||
| #include "common/bit_field.h" | #include "common/bit_field.h" | ||||||
| #include "common/common_funcs.h" | #include "common/common_funcs.h" | ||||||
| #include "common/common_types.h" | #include "common/common_types.h" | ||||||
| #include "common/memory_ref.h" |  | ||||||
| #include "common/swap.h" | #include "common/swap.h" | ||||||
| #include "core/memory.h" | #include "core/memory.h" | ||||||
| 
 | 
 | ||||||
|  | @ -66,6 +58,11 @@ enum class WifiState : u8 { | ||||||
|     Disabled = 7, |     Disabled = 7, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * The shared page stores various runtime configuration settings. This memory page is | ||||||
|  |  * read-only for user processes (there is a bit in the header that grants the process | ||||||
|  |  * write access, according to 3dbrew; this is not emulated) | ||||||
|  |  */ | ||||||
| struct SharedPageDef { | struct SharedPageDef { | ||||||
|     // Most of these names are taken from the 3dbrew page linked above.
 |     // Most of these names are taken from the 3dbrew page linked above.
 | ||||||
|     u32_le date_time_counter; // 0
 |     u32_le date_time_counter; // 0
 | ||||||
|  | @ -91,7 +88,7 @@ struct SharedPageDef { | ||||||
| static_assert(sizeof(SharedPageDef) == Memory::SHARED_PAGE_SIZE, | static_assert(sizeof(SharedPageDef) == Memory::SHARED_PAGE_SIZE, | ||||||
|               "Shared page structure size is wrong"); |               "Shared page structure size is wrong"); | ||||||
| 
 | 
 | ||||||
| class Handler : public BackingMem { | class Handler { | ||||||
| public: | public: | ||||||
|     Handler(Core::Timing& timing, u64 override_init_time); |     Handler(Core::Timing& timing, u64 override_init_time); | ||||||
| 
 | 
 | ||||||
|  | @ -111,15 +108,15 @@ public: | ||||||
| 
 | 
 | ||||||
|     SharedPageDef& GetSharedPage(); |     SharedPageDef& GetSharedPage(); | ||||||
| 
 | 
 | ||||||
|     u8* GetPtr() override { |     u8* GetPtr() { | ||||||
|         return reinterpret_cast<u8*>(&shared_page); |         return reinterpret_cast<u8*>(&shared_page); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     const u8* GetPtr() const override { |     const u8* GetPtr() const { | ||||||
|         return reinterpret_cast<const u8*>(&shared_page); |         return reinterpret_cast<const u8*>(&shared_page); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     std::size_t GetSize() const override { |     std::size_t GetSize() const { | ||||||
|         return sizeof(shared_page); |         return sizeof(shared_page); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -7,7 +7,6 @@ | ||||||
| #include <map> | #include <map> | ||||||
| #include <memory> | #include <memory> | ||||||
| #include "common/common_types.h" | #include "common/common_types.h" | ||||||
| #include "common/memory_ref.h" |  | ||||||
| #include "core/hle/kernel/memory.h" | #include "core/hle/kernel/memory.h" | ||||||
| #include "core/hle/result.h" | #include "core/hle/result.h" | ||||||
| #include "core/memory.h" | #include "core/memory.h" | ||||||
|  |  | ||||||
|  | @ -143,74 +143,70 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     SECTION("translates StaticBuffer descriptors") { |     SECTION("translates StaticBuffer descriptors") { | ||||||
|         auto mem = std::make_shared<BufferMem>(Memory::CITRA_PAGE_SIZE); |         auto mem = std::vector<u8>(Memory::CITRA_PAGE_SIZE); | ||||||
|         MemoryRef buffer{mem}; |         std::fill(mem.begin(), mem.end(), 0xAB); | ||||||
|         std::fill(buffer.GetPtr(), buffer.GetPtr() + buffer.GetSize(), 0xAB); |  | ||||||
| 
 | 
 | ||||||
|         VAddr target_address = 0x10000000; |         VAddr target_address = 0x10000000; | ||||||
|         auto result = process->vm_manager.MapBackingMemory( |         auto result = process->vm_manager.MapBackingMemory( | ||||||
|             target_address, buffer, static_cast<u32>(buffer.GetSize()), MemoryState::Private); |             target_address, mem.data(), static_cast<u32>(mem.size()), MemoryState::Private); | ||||||
|         REQUIRE(result.Code() == ResultSuccess); |         REQUIRE(result.Code() == ResultSuccess); | ||||||
| 
 | 
 | ||||||
|         const u32_le input[]{ |         const u32_le input[]{ | ||||||
|             IPC::MakeHeader(0, 0, 2), |             IPC::MakeHeader(0, 0, 2), | ||||||
|             IPC::StaticBufferDesc(buffer.GetSize(), 0), |             IPC::StaticBufferDesc(mem.size(), 0), | ||||||
|             target_address, |             target_address, | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|         context.PopulateFromIncomingCommandBuffer(input, process); |         context.PopulateFromIncomingCommandBuffer(input, process); | ||||||
| 
 | 
 | ||||||
|         CHECK(context.GetStaticBuffer(0) == mem->Vector()); |         CHECK(context.GetStaticBuffer(0) == mem); | ||||||
| 
 | 
 | ||||||
|         REQUIRE(process->vm_manager.UnmapRange( |         REQUIRE(process->vm_manager.UnmapRange(target_address, static_cast<u32>(mem.size())) == | ||||||
|                     target_address, static_cast<u32>(buffer.GetSize())) == ResultSuccess); |                 ResultSuccess); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     SECTION("translates MappedBuffer descriptors") { |     SECTION("translates MappedBuffer descriptors") { | ||||||
|         auto mem = std::make_shared<BufferMem>(Memory::CITRA_PAGE_SIZE); |         std::vector<u8> mem(Memory::CITRA_PAGE_SIZE); | ||||||
|         MemoryRef buffer{mem}; |         std::fill(mem.begin(), mem.end(), 0xCD); | ||||||
|         std::fill(buffer.GetPtr(), buffer.GetPtr() + buffer.GetSize(), 0xCD); |  | ||||||
| 
 | 
 | ||||||
|         VAddr target_address = 0x10000000; |         VAddr target_address = 0x10000000; | ||||||
|         auto result = process->vm_manager.MapBackingMemory( |         auto result = process->vm_manager.MapBackingMemory( | ||||||
|             target_address, buffer, static_cast<u32>(buffer.GetSize()), MemoryState::Private); |             target_address, mem.data(), static_cast<u32>(mem.size()), MemoryState::Private); | ||||||
|         REQUIRE(result.Code() == ResultSuccess); |         REQUIRE(result.Code() == ResultSuccess); | ||||||
| 
 | 
 | ||||||
|         const u32_le input[]{ |         const u32_le input[]{ | ||||||
|             IPC::MakeHeader(0, 0, 2), |             IPC::MakeHeader(0, 0, 2), | ||||||
|             IPC::MappedBufferDesc(buffer.GetSize(), IPC::R), |             IPC::MappedBufferDesc(mem.size(), IPC::R), | ||||||
|             target_address, |             target_address, | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|         context.PopulateFromIncomingCommandBuffer(input, process); |         context.PopulateFromIncomingCommandBuffer(input, process); | ||||||
| 
 | 
 | ||||||
|         std::vector<u8> other_buffer(buffer.GetSize()); |         std::vector<u8> other_buffer(mem.size()); | ||||||
|         context.GetMappedBuffer(0).Read(other_buffer.data(), 0, buffer.GetSize()); |         context.GetMappedBuffer(0).Read(other_buffer.data(), 0, mem.size()); | ||||||
| 
 | 
 | ||||||
|         CHECK(other_buffer == mem->Vector()); |         CHECK(other_buffer == mem); | ||||||
| 
 | 
 | ||||||
|         REQUIRE(process->vm_manager.UnmapRange( |         REQUIRE(process->vm_manager.UnmapRange(target_address, static_cast<u32>(mem.size())) == | ||||||
|                     target_address, static_cast<u32>(buffer.GetSize())) == ResultSuccess); |                 ResultSuccess); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     SECTION("translates mixed params") { |     SECTION("translates mixed params") { | ||||||
|         auto mem_static = std::make_shared<BufferMem>(Memory::CITRA_PAGE_SIZE); |         std::vector<u8> buffer_static(Memory::CITRA_PAGE_SIZE); | ||||||
|         MemoryRef buffer_static{mem_static}; |         std::fill(buffer_static.begin(), buffer_static.end(), 0xCE); | ||||||
|         std::fill(buffer_static.GetPtr(), buffer_static.GetPtr() + buffer_static.GetSize(), 0xCE); |  | ||||||
| 
 | 
 | ||||||
|         auto mem_mapped = std::make_shared<BufferMem>(Memory::CITRA_PAGE_SIZE); |         std::vector<u8> buffer_mapped(Memory::CITRA_PAGE_SIZE); | ||||||
|         MemoryRef buffer_mapped{mem_mapped}; |         std::fill(buffer_mapped.begin(), buffer_mapped.end(), 0xDF); | ||||||
|         std::fill(buffer_mapped.GetPtr(), buffer_mapped.GetPtr() + buffer_mapped.GetSize(), 0xDF); |  | ||||||
| 
 | 
 | ||||||
|         VAddr target_address_static = 0x10000000; |         VAddr target_address_static = 0x10000000; | ||||||
|         auto result = process->vm_manager.MapBackingMemory( |         auto result = process->vm_manager.MapBackingMemory( | ||||||
|             target_address_static, buffer_static, static_cast<u32>(buffer_static.GetSize()), |             target_address_static, buffer_static.data(), static_cast<u32>(buffer_static.size()), | ||||||
|             MemoryState::Private); |             MemoryState::Private); | ||||||
|         REQUIRE(result.Code() == ResultSuccess); |         REQUIRE(result.Code() == ResultSuccess); | ||||||
| 
 | 
 | ||||||
|         VAddr target_address_mapped = 0x20000000; |         VAddr target_address_mapped = 0x20000000; | ||||||
|         result = process->vm_manager.MapBackingMemory(target_address_mapped, buffer_mapped, |         result = process->vm_manager.MapBackingMemory(target_address_mapped, buffer_mapped.data(), | ||||||
|                                                       static_cast<u32>(buffer_mapped.GetSize()), |                                                       static_cast<u32>(buffer_mapped.size()), | ||||||
|                                                       MemoryState::Private); |                                                       MemoryState::Private); | ||||||
|         REQUIRE(result.Code() == ResultSuccess); |         REQUIRE(result.Code() == ResultSuccess); | ||||||
| 
 | 
 | ||||||
|  | @ -225,9 +221,9 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel | ||||||
|             a_handle, |             a_handle, | ||||||
|             IPC::CallingPidDesc(), |             IPC::CallingPidDesc(), | ||||||
|             0, |             0, | ||||||
|             IPC::StaticBufferDesc(buffer_static.GetSize(), 0), |             IPC::StaticBufferDesc(buffer_static.size(), 0), | ||||||
|             target_address_static, |             target_address_static, | ||||||
|             IPC::MappedBufferDesc(buffer_mapped.GetSize(), IPC::R), |             IPC::MappedBufferDesc(buffer_mapped.size(), IPC::R), | ||||||
|             target_address_mapped, |             target_address_mapped, | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|  | @ -238,16 +234,16 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel | ||||||
|         CHECK(output[2] == 0xABCDEF00); |         CHECK(output[2] == 0xABCDEF00); | ||||||
|         CHECK(context.GetIncomingHandle(output[4]) == a); |         CHECK(context.GetIncomingHandle(output[4]) == a); | ||||||
|         CHECK(output[6] == process->process_id); |         CHECK(output[6] == process->process_id); | ||||||
|         CHECK(context.GetStaticBuffer(0) == mem_static->Vector()); |         CHECK(context.GetStaticBuffer(0) == buffer_static); | ||||||
|         std::vector<u8> other_buffer(buffer_mapped.GetSize()); |         std::vector<u8> other_buffer(buffer_mapped.size()); | ||||||
|         context.GetMappedBuffer(0).Read(other_buffer.data(), 0, buffer_mapped.GetSize()); |         context.GetMappedBuffer(0).Read(other_buffer.data(), 0, buffer_mapped.size()); | ||||||
|         CHECK(other_buffer == mem_mapped->Vector()); |         CHECK(other_buffer == buffer_mapped); | ||||||
| 
 | 
 | ||||||
|         REQUIRE(process->vm_manager.UnmapRange(target_address_static, |         REQUIRE(process->vm_manager.UnmapRange(target_address_static, | ||||||
|                                                static_cast<u32>(buffer_static.GetSize())) == |                                                static_cast<u32>(buffer_static.size())) == | ||||||
|                 ResultSuccess); |                 ResultSuccess); | ||||||
|         REQUIRE(process->vm_manager.UnmapRange(target_address_mapped, |         REQUIRE(process->vm_manager.UnmapRange(target_address_mapped, | ||||||
|                                                static_cast<u32>(buffer_mapped.GetSize())) == |                                                static_cast<u32>(buffer_mapped.size())) == | ||||||
|                 ResultSuccess); |                 ResultSuccess); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | @ -337,12 +333,11 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { | ||||||
| 
 | 
 | ||||||
|         context.AddStaticBuffer(0, input_buffer); |         context.AddStaticBuffer(0, input_buffer); | ||||||
| 
 | 
 | ||||||
|         auto output_mem = std::make_shared<BufferMem>(Memory::CITRA_PAGE_SIZE); |         std::vector<u8> output_buffer(Memory::CITRA_PAGE_SIZE); | ||||||
|         MemoryRef output_buffer{output_mem}; |  | ||||||
| 
 | 
 | ||||||
|         VAddr target_address = 0x10000000; |         VAddr target_address = 0x10000000; | ||||||
|         auto result = process->vm_manager.MapBackingMemory( |         auto result = process->vm_manager.MapBackingMemory(target_address, output_buffer.data(), | ||||||
|             target_address, output_buffer, static_cast<u32>(output_buffer.GetSize()), |                                                            static_cast<u32>(output_buffer.size()), | ||||||
|                                                            MemoryState::Private); |                                                            MemoryState::Private); | ||||||
|         REQUIRE(result.Code() == ResultSuccess); |         REQUIRE(result.Code() == ResultSuccess); | ||||||
| 
 | 
 | ||||||
|  | @ -354,33 +349,31 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { | ||||||
|         // target address
 |         // target address
 | ||||||
|         std::array<u32_le, IPC::COMMAND_BUFFER_LENGTH + 2> output_cmdbuff; |         std::array<u32_le, IPC::COMMAND_BUFFER_LENGTH + 2> output_cmdbuff; | ||||||
|         // Set up the output StaticBuffer
 |         // Set up the output StaticBuffer
 | ||||||
|         output_cmdbuff[IPC::COMMAND_BUFFER_LENGTH] = |         output_cmdbuff[IPC::COMMAND_BUFFER_LENGTH] = IPC::StaticBufferDesc(output_buffer.size(), 0); | ||||||
|             IPC::StaticBufferDesc(output_buffer.GetSize(), 0); |  | ||||||
|         output_cmdbuff[IPC::COMMAND_BUFFER_LENGTH + 1] = target_address; |         output_cmdbuff[IPC::COMMAND_BUFFER_LENGTH + 1] = target_address; | ||||||
| 
 | 
 | ||||||
|         context.WriteToOutgoingCommandBuffer(output_cmdbuff.data(), *process); |         context.WriteToOutgoingCommandBuffer(output_cmdbuff.data(), *process); | ||||||
| 
 | 
 | ||||||
|         CHECK(output_mem->Vector() == input_buffer); |         CHECK(output_buffer == input_buffer); | ||||||
|         REQUIRE(process->vm_manager.UnmapRange( |         REQUIRE(process->vm_manager.UnmapRange( | ||||||
|                     target_address, static_cast<u32>(output_buffer.GetSize())) == ResultSuccess); |                     target_address, static_cast<u32>(output_buffer.size())) == ResultSuccess); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     SECTION("translates StaticBuffer descriptors") { |     SECTION("translates StaticBuffer descriptors") { | ||||||
|         std::vector<u8> input_buffer(Memory::CITRA_PAGE_SIZE); |         std::vector<u8> input_buffer(Memory::CITRA_PAGE_SIZE); | ||||||
|         std::fill(input_buffer.begin(), input_buffer.end(), 0xAB); |         std::fill(input_buffer.begin(), input_buffer.end(), 0xAB); | ||||||
| 
 | 
 | ||||||
|         auto output_mem = std::make_shared<BufferMem>(Memory::CITRA_PAGE_SIZE); |         std::vector<u8> output_buffer(Memory::CITRA_PAGE_SIZE); | ||||||
|         MemoryRef output_buffer{output_mem}; |  | ||||||
| 
 | 
 | ||||||
|         VAddr target_address = 0x10000000; |         VAddr target_address = 0x10000000; | ||||||
|         auto result = process->vm_manager.MapBackingMemory( |         auto result = process->vm_manager.MapBackingMemory(target_address, output_buffer.data(), | ||||||
|             target_address, output_buffer, static_cast<u32>(output_buffer.GetSize()), |                                                            static_cast<u32>(output_buffer.size()), | ||||||
|                                                            MemoryState::Private); |                                                            MemoryState::Private); | ||||||
|         REQUIRE(result.Code() == ResultSuccess); |         REQUIRE(result.Code() == ResultSuccess); | ||||||
| 
 | 
 | ||||||
|         const u32_le input_cmdbuff[]{ |         const u32_le input_cmdbuff[]{ | ||||||
|             IPC::MakeHeader(0, 0, 2), |             IPC::MakeHeader(0, 0, 2), | ||||||
|             IPC::MappedBufferDesc(output_buffer.GetSize(), IPC::W), |             IPC::MappedBufferDesc(output_buffer.size(), IPC::W), | ||||||
|             target_address, |             target_address, | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|  | @ -389,16 +382,16 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { | ||||||
|         context.GetMappedBuffer(0).Write(input_buffer.data(), 0, input_buffer.size()); |         context.GetMappedBuffer(0).Write(input_buffer.data(), 0, input_buffer.size()); | ||||||
| 
 | 
 | ||||||
|         input[0] = IPC::MakeHeader(0, 0, 2); |         input[0] = IPC::MakeHeader(0, 0, 2); | ||||||
|         input[1] = IPC::MappedBufferDesc(output_buffer.GetSize(), IPC::W); |         input[1] = IPC::MappedBufferDesc(output_buffer.size(), IPC::W); | ||||||
|         input[2] = 0; |         input[2] = 0; | ||||||
| 
 | 
 | ||||||
|         context.WriteToOutgoingCommandBuffer(output, *process); |         context.WriteToOutgoingCommandBuffer(output, *process); | ||||||
| 
 | 
 | ||||||
|         CHECK(output[1] == IPC::MappedBufferDesc(output_buffer.GetSize(), IPC::W)); |         CHECK(output[1] == IPC::MappedBufferDesc(output_buffer.size(), IPC::W)); | ||||||
|         CHECK(output[2] == target_address); |         CHECK(output[2] == target_address); | ||||||
|         CHECK(output_mem->Vector() == input_buffer); |         CHECK(output_buffer == input_buffer); | ||||||
|         REQUIRE(process->vm_manager.UnmapRange( |         REQUIRE(process->vm_manager.UnmapRange( | ||||||
|                     target_address, static_cast<u32>(output_buffer.GetSize())) == ResultSuccess); |                     target_address, static_cast<u32>(output_buffer.size())) == ResultSuccess); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -11,8 +11,7 @@ | ||||||
| #include "core/memory.h" | #include "core/memory.h" | ||||||
| 
 | 
 | ||||||
| TEST_CASE("Memory Basics", "[kernel][memory]") { | TEST_CASE("Memory Basics", "[kernel][memory]") { | ||||||
|     auto mem = std::make_shared<BufferMem>(Memory::CITRA_PAGE_SIZE); |     auto mem = std::make_unique<u8[]>(Memory::CITRA_PAGE_SIZE); | ||||||
|     MemoryRef block{mem}; |  | ||||||
|     Core::Timing timing(1, 100); |     Core::Timing timing(1, 100); | ||||||
|     Core::System system; |     Core::System system; | ||||||
|     Memory::MemorySystem memory{system}; |     Memory::MemorySystem memory{system}; | ||||||
|  | @ -23,28 +22,26 @@ TEST_CASE("Memory Basics", "[kernel][memory]") { | ||||||
|     SECTION("mapping memory") { |     SECTION("mapping memory") { | ||||||
|         // Because of the PageTable, Kernel::VMManager is too big to be created on the stack.
 |         // Because of the PageTable, Kernel::VMManager is too big to be created on the stack.
 | ||||||
|         auto manager = std::make_unique<Kernel::VMManager>(memory, process); |         auto manager = std::make_unique<Kernel::VMManager>(memory, process); | ||||||
|         auto result = |         auto result = manager->MapBackingMemory( | ||||||
|             manager->MapBackingMemory(Memory::HEAP_VADDR, block, static_cast<u32>(block.GetSize()), |             Memory::HEAP_VADDR, mem.get(), Memory::CITRA_PAGE_SIZE, Kernel::MemoryState::Private); | ||||||
|                                       Kernel::MemoryState::Private); |  | ||||||
|         REQUIRE(result.Code() == ResultSuccess); |         REQUIRE(result.Code() == ResultSuccess); | ||||||
| 
 | 
 | ||||||
|         auto vma = manager->FindVMA(Memory::HEAP_VADDR); |         auto vma = manager->FindVMA(Memory::HEAP_VADDR); | ||||||
|         CHECK(vma != manager->vma_map.end()); |         CHECK(vma != manager->vma_map.end()); | ||||||
|         CHECK(vma->second.size == static_cast<u32>(block.GetSize())); |         CHECK(vma->second.size == Memory::CITRA_PAGE_SIZE); | ||||||
|         CHECK(vma->second.type == Kernel::VMAType::BackingMemory); |         CHECK(vma->second.type == Kernel::VMAType::BackingMemory); | ||||||
|         CHECK(vma->second.backing_memory == block.GetPtr()); |         CHECK(vma->second.backing_memory == mem.get()); | ||||||
|         CHECK(vma->second.meminfo_state == Kernel::MemoryState::Private); |         CHECK(vma->second.meminfo_state == Kernel::MemoryState::Private); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     SECTION("unmapping memory") { |     SECTION("unmapping memory") { | ||||||
|         // Because of the PageTable, Kernel::VMManager is too big to be created on the stack.
 |         // Because of the PageTable, Kernel::VMManager is too big to be created on the stack.
 | ||||||
|         auto manager = std::make_unique<Kernel::VMManager>(memory, process); |         auto manager = std::make_unique<Kernel::VMManager>(memory, process); | ||||||
|         auto result = |         auto result = manager->MapBackingMemory( | ||||||
|             manager->MapBackingMemory(Memory::HEAP_VADDR, block, static_cast<u32>(block.GetSize()), |             Memory::HEAP_VADDR, mem.get(), Memory::CITRA_PAGE_SIZE, Kernel::MemoryState::Private); | ||||||
|                                       Kernel::MemoryState::Private); |  | ||||||
|         REQUIRE(result.Code() == ResultSuccess); |         REQUIRE(result.Code() == ResultSuccess); | ||||||
| 
 | 
 | ||||||
|         Result code = manager->UnmapRange(Memory::HEAP_VADDR, static_cast<u32>(block.GetSize())); |         Result code = manager->UnmapRange(Memory::HEAP_VADDR, Memory::CITRA_PAGE_SIZE); | ||||||
|         REQUIRE(code == ResultSuccess); |         REQUIRE(code == ResultSuccess); | ||||||
| 
 | 
 | ||||||
|         auto vma = manager->FindVMA(Memory::HEAP_VADDR); |         auto vma = manager->FindVMA(Memory::HEAP_VADDR); | ||||||
|  | @ -56,12 +53,11 @@ TEST_CASE("Memory Basics", "[kernel][memory]") { | ||||||
|     SECTION("changing memory permissions") { |     SECTION("changing memory permissions") { | ||||||
|         // Because of the PageTable, Kernel::VMManager is too big to be created on the stack.
 |         // Because of the PageTable, Kernel::VMManager is too big to be created on the stack.
 | ||||||
|         auto manager = std::make_unique<Kernel::VMManager>(memory, process); |         auto manager = std::make_unique<Kernel::VMManager>(memory, process); | ||||||
|         auto result = |         auto result = manager->MapBackingMemory( | ||||||
|             manager->MapBackingMemory(Memory::HEAP_VADDR, block, static_cast<u32>(block.GetSize()), |             Memory::HEAP_VADDR, mem.get(), Memory::CITRA_PAGE_SIZE, Kernel::MemoryState::Private); | ||||||
|                                       Kernel::MemoryState::Private); |  | ||||||
|         REQUIRE(result.Code() == ResultSuccess); |         REQUIRE(result.Code() == ResultSuccess); | ||||||
| 
 | 
 | ||||||
|         Result code = manager->ReprotectRange(Memory::HEAP_VADDR, static_cast<u32>(block.GetSize()), |         Result code = manager->ReprotectRange(Memory::HEAP_VADDR, Memory::CITRA_PAGE_SIZE, | ||||||
|                                               Kernel::VMAPermission::Execute); |                                               Kernel::VMAPermission::Execute); | ||||||
|         CHECK(code == ResultSuccess); |         CHECK(code == ResultSuccess); | ||||||
| 
 | 
 | ||||||
|  | @ -69,28 +65,26 @@ TEST_CASE("Memory Basics", "[kernel][memory]") { | ||||||
|         CHECK(vma != manager->vma_map.end()); |         CHECK(vma != manager->vma_map.end()); | ||||||
|         CHECK(vma->second.permissions == Kernel::VMAPermission::Execute); |         CHECK(vma->second.permissions == Kernel::VMAPermission::Execute); | ||||||
| 
 | 
 | ||||||
|         code = manager->UnmapRange(Memory::HEAP_VADDR, static_cast<u32>(block.GetSize())); |         code = manager->UnmapRange(Memory::HEAP_VADDR, Memory::CITRA_PAGE_SIZE); | ||||||
|         REQUIRE(code == ResultSuccess); |         REQUIRE(code == ResultSuccess); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     SECTION("changing memory state") { |     SECTION("changing memory state") { | ||||||
|         // Because of the PageTable, Kernel::VMManager is too big to be created on the stack.
 |         // Because of the PageTable, Kernel::VMManager is too big to be created on the stack.
 | ||||||
|         auto manager = std::make_unique<Kernel::VMManager>(memory, process); |         auto manager = std::make_unique<Kernel::VMManager>(memory, process); | ||||||
|         auto result = |         auto result = manager->MapBackingMemory( | ||||||
|             manager->MapBackingMemory(Memory::HEAP_VADDR, block, static_cast<u32>(block.GetSize()), |             Memory::HEAP_VADDR, mem.get(), Memory::CITRA_PAGE_SIZE, Kernel::MemoryState::Private); | ||||||
|                                       Kernel::MemoryState::Private); |  | ||||||
|         REQUIRE(result.Code() == ResultSuccess); |         REQUIRE(result.Code() == ResultSuccess); | ||||||
| 
 | 
 | ||||||
|         SECTION("reprotect memory range") { |         SECTION("reprotect memory range") { | ||||||
|             Result code = |             Result code = manager->ReprotectRange(Memory::HEAP_VADDR, Memory::CITRA_PAGE_SIZE, | ||||||
|                 manager->ReprotectRange(Memory::HEAP_VADDR, static_cast<u32>(block.GetSize()), |  | ||||||
|                                                   Kernel::VMAPermission::ReadWrite); |                                                   Kernel::VMAPermission::ReadWrite); | ||||||
|             REQUIRE(code == ResultSuccess); |             REQUIRE(code == ResultSuccess); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         SECTION("with invalid address") { |         SECTION("with invalid address") { | ||||||
|             Result code = manager->ChangeMemoryState( |             Result code = manager->ChangeMemoryState( | ||||||
|                 0xFFFFFFFF, static_cast<u32>(block.GetSize()), Kernel::MemoryState::Locked, |                 0xFFFFFFFF, Memory::CITRA_PAGE_SIZE, Kernel::MemoryState::Locked, | ||||||
|                 Kernel::VMAPermission::ReadWrite, Kernel::MemoryState::Aliased, |                 Kernel::VMAPermission::ReadWrite, Kernel::MemoryState::Aliased, | ||||||
|                 Kernel::VMAPermission::Execute); |                 Kernel::VMAPermission::Execute); | ||||||
|             CHECK(code == Kernel::ResultInvalidAddress); |             CHECK(code == Kernel::ResultInvalidAddress); | ||||||
|  | @ -98,7 +92,7 @@ TEST_CASE("Memory Basics", "[kernel][memory]") { | ||||||
| 
 | 
 | ||||||
|         SECTION("ignoring the original permissions") { |         SECTION("ignoring the original permissions") { | ||||||
|             Result code = manager->ChangeMemoryState( |             Result code = manager->ChangeMemoryState( | ||||||
|                 Memory::HEAP_VADDR, static_cast<u32>(block.GetSize()), Kernel::MemoryState::Private, |                 Memory::HEAP_VADDR, Memory::CITRA_PAGE_SIZE, Kernel::MemoryState::Private, | ||||||
|                 Kernel::VMAPermission::None, Kernel::MemoryState::Locked, |                 Kernel::VMAPermission::None, Kernel::MemoryState::Locked, | ||||||
|                 Kernel::VMAPermission::Write); |                 Kernel::VMAPermission::Write); | ||||||
|             CHECK(code == ResultSuccess); |             CHECK(code == ResultSuccess); | ||||||
|  | @ -111,7 +105,7 @@ TEST_CASE("Memory Basics", "[kernel][memory]") { | ||||||
| 
 | 
 | ||||||
|         SECTION("enforcing the original permissions with correct expectations") { |         SECTION("enforcing the original permissions with correct expectations") { | ||||||
|             Result code = manager->ChangeMemoryState( |             Result code = manager->ChangeMemoryState( | ||||||
|                 Memory::HEAP_VADDR, static_cast<u32>(block.GetSize()), Kernel::MemoryState::Private, |                 Memory::HEAP_VADDR, Memory::CITRA_PAGE_SIZE, Kernel::MemoryState::Private, | ||||||
|                 Kernel::VMAPermission::ReadWrite, Kernel::MemoryState::Aliased, |                 Kernel::VMAPermission::ReadWrite, Kernel::MemoryState::Aliased, | ||||||
|                 Kernel::VMAPermission::Execute); |                 Kernel::VMAPermission::Execute); | ||||||
|             CHECK(code == ResultSuccess); |             CHECK(code == ResultSuccess); | ||||||
|  | @ -124,7 +118,7 @@ TEST_CASE("Memory Basics", "[kernel][memory]") { | ||||||
| 
 | 
 | ||||||
|         SECTION("with incorrect permission expectations") { |         SECTION("with incorrect permission expectations") { | ||||||
|             Result code = manager->ChangeMemoryState( |             Result code = manager->ChangeMemoryState( | ||||||
|                 Memory::HEAP_VADDR, static_cast<u32>(block.GetSize()), Kernel::MemoryState::Private, |                 Memory::HEAP_VADDR, Memory::CITRA_PAGE_SIZE, Kernel::MemoryState::Private, | ||||||
|                 Kernel::VMAPermission::Execute, Kernel::MemoryState::Aliased, |                 Kernel::VMAPermission::Execute, Kernel::MemoryState::Aliased, | ||||||
|                 Kernel::VMAPermission::Execute); |                 Kernel::VMAPermission::Execute); | ||||||
|             CHECK(code == Kernel::ResultInvalidAddressState); |             CHECK(code == Kernel::ResultInvalidAddressState); | ||||||
|  | @ -137,7 +131,7 @@ TEST_CASE("Memory Basics", "[kernel][memory]") { | ||||||
| 
 | 
 | ||||||
|         SECTION("with incorrect state expectations") { |         SECTION("with incorrect state expectations") { | ||||||
|             Result code = manager->ChangeMemoryState( |             Result code = manager->ChangeMemoryState( | ||||||
|                 Memory::HEAP_VADDR, static_cast<u32>(block.GetSize()), Kernel::MemoryState::Locked, |                 Memory::HEAP_VADDR, Memory::CITRA_PAGE_SIZE, Kernel::MemoryState::Locked, | ||||||
|                 Kernel::VMAPermission::ReadWrite, Kernel::MemoryState::Aliased, |                 Kernel::VMAPermission::ReadWrite, Kernel::MemoryState::Aliased, | ||||||
|                 Kernel::VMAPermission::Execute); |                 Kernel::VMAPermission::Execute); | ||||||
|             CHECK(code == Kernel::ResultInvalidAddressState); |             CHECK(code == Kernel::ResultInvalidAddressState); | ||||||
|  | @ -148,7 +142,7 @@ TEST_CASE("Memory Basics", "[kernel][memory]") { | ||||||
|             CHECK(vma->second.meminfo_state == Kernel::MemoryState::Private); |             CHECK(vma->second.meminfo_state == Kernel::MemoryState::Private); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         Result code = manager->UnmapRange(Memory::HEAP_VADDR, static_cast<u32>(block.GetSize())); |         Result code = manager->UnmapRange(Memory::HEAP_VADDR, Memory::CITRA_PAGE_SIZE); | ||||||
|         REQUIRE(code == ResultSuccess); |         REQUIRE(code == ResultSuccess); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue