diff options
| author | 2020-04-08 19:05:31 -0400 | |
|---|---|---|
| committer | 2020-04-17 00:59:32 -0400 | |
| commit | 3fcc4cab4fcc7a3496e98fb699a96d21df90e512 (patch) | |
| tree | fae88975e2e00c5514c348d851a13fc46a6045b9 /src | |
| parent | core: Construct/Destruct DeviceMemory on Init/Shutdown. (diff) | |
| download | yuzu-3fcc4cab4fcc7a3496e98fb699a96d21df90e512.tar.gz yuzu-3fcc4cab4fcc7a3496e98fb699a96d21df90e512.tar.xz yuzu-3fcc4cab4fcc7a3496e98fb699a96d21df90e512.zip | |
kernel: transfer_memory: Refactor for new VMM.
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/kernel/transfer_memory.cpp | 99 | ||||
| -rw-r--r-- | src/core/hle/kernel/transfer_memory.h | 47 |
2 files changed, 16 insertions, 130 deletions
diff --git a/src/core/hle/kernel/transfer_memory.cpp b/src/core/hle/kernel/transfer_memory.cpp index 74514068e..765f408c3 100644 --- a/src/core/hle/kernel/transfer_memory.cpp +++ b/src/core/hle/kernel/transfer_memory.cpp | |||
| @@ -2,10 +2,9 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "core/hle/kernel/errors.h" | ||
| 6 | #include "core/hle/kernel/kernel.h" | 5 | #include "core/hle/kernel/kernel.h" |
| 6 | #include "core/hle/kernel/memory/page_table.h" | ||
| 7 | #include "core/hle/kernel/process.h" | 7 | #include "core/hle/kernel/process.h" |
| 8 | #include "core/hle/kernel/shared_memory.h" | ||
| 9 | #include "core/hle/kernel/transfer_memory.h" | 8 | #include "core/hle/kernel/transfer_memory.h" |
| 10 | #include "core/hle/result.h" | 9 | #include "core/hle/result.h" |
| 11 | #include "core/memory.h" | 10 | #include "core/memory.h" |
| @@ -22,13 +21,13 @@ TransferMemory::~TransferMemory() { | |||
| 22 | 21 | ||
| 23 | std::shared_ptr<TransferMemory> TransferMemory::Create(KernelCore& kernel, | 22 | std::shared_ptr<TransferMemory> TransferMemory::Create(KernelCore& kernel, |
| 24 | Core::Memory::Memory& memory, | 23 | Core::Memory::Memory& memory, |
| 25 | VAddr base_address, u64 size, | 24 | VAddr base_address, std::size_t size, |
| 26 | MemoryPermission permissions) { | 25 | Memory::MemoryPermission permissions) { |
| 27 | std::shared_ptr<TransferMemory> transfer_memory{ | 26 | std::shared_ptr<TransferMemory> transfer_memory{ |
| 28 | std::make_shared<TransferMemory>(kernel, memory)}; | 27 | std::make_shared<TransferMemory>(kernel, memory)}; |
| 29 | 28 | ||
| 30 | transfer_memory->base_address = base_address; | 29 | transfer_memory->base_address = base_address; |
| 31 | transfer_memory->memory_size = size; | 30 | transfer_memory->size = size; |
| 32 | transfer_memory->owner_permissions = permissions; | 31 | transfer_memory->owner_permissions = permissions; |
| 33 | transfer_memory->owner_process = kernel.CurrentProcess(); | 32 | transfer_memory->owner_process = kernel.CurrentProcess(); |
| 34 | 33 | ||
| @@ -39,98 +38,12 @@ const u8* TransferMemory::GetPointer() const { | |||
| 39 | return memory.GetPointer(base_address); | 38 | return memory.GetPointer(base_address); |
| 40 | } | 39 | } |
| 41 | 40 | ||
| 42 | u64 TransferMemory::GetSize() const { | ||
| 43 | return memory_size; | ||
| 44 | } | ||
| 45 | |||
| 46 | ResultCode TransferMemory::MapMemory(VAddr address, u64 size, MemoryPermission permissions) { | ||
| 47 | if (memory_size != size) { | ||
| 48 | return ERR_INVALID_SIZE; | ||
| 49 | } | ||
| 50 | |||
| 51 | if (owner_permissions != permissions) { | ||
| 52 | return ERR_INVALID_STATE; | ||
| 53 | } | ||
| 54 | |||
| 55 | if (is_mapped) { | ||
| 56 | return ERR_INVALID_STATE; | ||
| 57 | } | ||
| 58 | |||
| 59 | backing_block = std::make_shared<PhysicalMemory>(size); | ||
| 60 | |||
| 61 | const auto map_state = owner_permissions == MemoryPermission::None | ||
| 62 | ? MemoryState::TransferMemoryIsolated | ||
| 63 | : MemoryState::TransferMemory; | ||
| 64 | auto& vm_manager = owner_process->VMManager(); | ||
| 65 | const auto map_result = vm_manager.MapMemoryBlock(address, backing_block, 0, size, map_state); | ||
| 66 | if (map_result.Failed()) { | ||
| 67 | return map_result.Code(); | ||
| 68 | } | ||
| 69 | |||
| 70 | is_mapped = true; | ||
| 71 | return RESULT_SUCCESS; | ||
| 72 | } | ||
| 73 | |||
| 74 | ResultCode TransferMemory::Reserve() { | 41 | ResultCode TransferMemory::Reserve() { |
| 75 | auto& vm_manager{owner_process->VMManager()}; | 42 | return owner_process->PageTable().ReserveTransferMemory(base_address, size, owner_permissions); |
| 76 | const auto check_range_result{vm_manager.CheckRangeState( | ||
| 77 | base_address, memory_size, MemoryState::FlagTransfer | MemoryState::FlagMemoryPoolAllocated, | ||
| 78 | MemoryState::FlagTransfer | MemoryState::FlagMemoryPoolAllocated, VMAPermission::All, | ||
| 79 | VMAPermission::ReadWrite, MemoryAttribute::Mask, MemoryAttribute::None, | ||
| 80 | MemoryAttribute::IpcAndDeviceMapped)}; | ||
| 81 | |||
| 82 | if (check_range_result.Failed()) { | ||
| 83 | return check_range_result.Code(); | ||
| 84 | } | ||
| 85 | |||
| 86 | auto [state_, permissions_, attribute] = *check_range_result; | ||
| 87 | |||
| 88 | if (const auto result{vm_manager.ReprotectRange( | ||
| 89 | base_address, memory_size, SharedMemory::ConvertPermissions(owner_permissions))}; | ||
| 90 | result.IsError()) { | ||
| 91 | return result; | ||
| 92 | } | ||
| 93 | |||
| 94 | return vm_manager.SetMemoryAttribute(base_address, memory_size, MemoryAttribute::Mask, | ||
| 95 | attribute | MemoryAttribute::Locked); | ||
| 96 | } | 43 | } |
| 97 | 44 | ||
| 98 | ResultCode TransferMemory::Reset() { | 45 | ResultCode TransferMemory::Reset() { |
| 99 | auto& vm_manager{owner_process->VMManager()}; | 46 | return owner_process->PageTable().ResetTransferMemory(base_address, size); |
| 100 | if (const auto result{vm_manager.CheckRangeState( | ||
| 101 | base_address, memory_size, | ||
| 102 | MemoryState::FlagTransfer | MemoryState::FlagMemoryPoolAllocated, | ||
| 103 | MemoryState::FlagTransfer | MemoryState::FlagMemoryPoolAllocated, VMAPermission::None, | ||
| 104 | VMAPermission::None, MemoryAttribute::Mask, MemoryAttribute::Locked, | ||
| 105 | MemoryAttribute::IpcAndDeviceMapped)}; | ||
| 106 | result.Failed()) { | ||
| 107 | return result.Code(); | ||
| 108 | } | ||
| 109 | |||
| 110 | if (const auto result{ | ||
| 111 | vm_manager.ReprotectRange(base_address, memory_size, VMAPermission::ReadWrite)}; | ||
| 112 | result.IsError()) { | ||
| 113 | return result; | ||
| 114 | } | ||
| 115 | |||
| 116 | return vm_manager.SetMemoryAttribute(base_address, memory_size, MemoryAttribute::Mask, | ||
| 117 | MemoryAttribute::None); | ||
| 118 | } | ||
| 119 | |||
| 120 | ResultCode TransferMemory::UnmapMemory(VAddr address, u64 size) { | ||
| 121 | if (memory_size != size) { | ||
| 122 | return ERR_INVALID_SIZE; | ||
| 123 | } | ||
| 124 | |||
| 125 | auto& vm_manager = owner_process->VMManager(); | ||
| 126 | const auto result = vm_manager.UnmapRange(address, size); | ||
| 127 | |||
| 128 | if (result.IsError()) { | ||
| 129 | return result; | ||
| 130 | } | ||
| 131 | |||
| 132 | is_mapped = false; | ||
| 133 | return RESULT_SUCCESS; | ||
| 134 | } | 47 | } |
| 135 | 48 | ||
| 136 | } // namespace Kernel | 49 | } // namespace Kernel |
diff --git a/src/core/hle/kernel/transfer_memory.h b/src/core/hle/kernel/transfer_memory.h index a47f57714..05e9f7464 100644 --- a/src/core/hle/kernel/transfer_memory.h +++ b/src/core/hle/kernel/transfer_memory.h | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | #include <memory> | 7 | #include <memory> |
| 8 | 8 | ||
| 9 | #include "core/hle/kernel/memory/memory_block.h" | ||
| 9 | #include "core/hle/kernel/object.h" | 10 | #include "core/hle/kernel/object.h" |
| 10 | #include "core/hle/kernel/physical_memory.h" | 11 | #include "core/hle/kernel/physical_memory.h" |
| 11 | 12 | ||
| @@ -20,8 +21,6 @@ namespace Kernel { | |||
| 20 | class KernelCore; | 21 | class KernelCore; |
| 21 | class Process; | 22 | class Process; |
| 22 | 23 | ||
| 23 | enum class MemoryPermission : u32; | ||
| 24 | |||
| 25 | /// Defines the interface for transfer memory objects. | 24 | /// Defines the interface for transfer memory objects. |
| 26 | /// | 25 | /// |
| 27 | /// Transfer memory is typically used for the purpose of | 26 | /// Transfer memory is typically used for the purpose of |
| @@ -36,8 +35,8 @@ public: | |||
| 36 | static constexpr HandleType HANDLE_TYPE = HandleType::TransferMemory; | 35 | static constexpr HandleType HANDLE_TYPE = HandleType::TransferMemory; |
| 37 | 36 | ||
| 38 | static std::shared_ptr<TransferMemory> Create(KernelCore& kernel, Core::Memory::Memory& memory, | 37 | static std::shared_ptr<TransferMemory> Create(KernelCore& kernel, Core::Memory::Memory& memory, |
| 39 | VAddr base_address, u64 size, | 38 | VAddr base_address, std::size_t size, |
| 40 | MemoryPermission permissions); | 39 | Memory::MemoryPermission permissions); |
| 41 | 40 | ||
| 42 | TransferMemory(const TransferMemory&) = delete; | 41 | TransferMemory(const TransferMemory&) = delete; |
| 43 | TransferMemory& operator=(const TransferMemory&) = delete; | 42 | TransferMemory& operator=(const TransferMemory&) = delete; |
| @@ -61,29 +60,9 @@ public: | |||
| 61 | const u8* GetPointer() const; | 60 | const u8* GetPointer() const; |
| 62 | 61 | ||
| 63 | /// Gets the size of the memory backing this instance in bytes. | 62 | /// Gets the size of the memory backing this instance in bytes. |
| 64 | u64 GetSize() const; | 63 | constexpr std::size_t GetSize() const { |
| 65 | 64 | return size; | |
| 66 | /// Attempts to map transfer memory with the given range and memory permissions. | 65 | } |
| 67 | /// | ||
| 68 | /// @param address The base address to being mapping memory at. | ||
| 69 | /// @param size The size of the memory to map, in bytes. | ||
| 70 | /// @param permissions The memory permissions to check against when mapping memory. | ||
| 71 | /// | ||
| 72 | /// @pre The given address, size, and memory permissions must all match | ||
| 73 | /// the same values that were given when creating the transfer memory | ||
| 74 | /// instance. | ||
| 75 | /// | ||
| 76 | ResultCode MapMemory(VAddr address, u64 size, MemoryPermission permissions); | ||
| 77 | |||
| 78 | /// Unmaps the transfer memory with the given range | ||
| 79 | /// | ||
| 80 | /// @param address The base address to begin unmapping memory at. | ||
| 81 | /// @param size The size of the memory to unmap, in bytes. | ||
| 82 | /// | ||
| 83 | /// @pre The given address and size must be the same as the ones used | ||
| 84 | /// to create the transfer memory instance. | ||
| 85 | /// | ||
| 86 | ResultCode UnmapMemory(VAddr address, u64 size); | ||
| 87 | 66 | ||
| 88 | /// Reserves the region to be used for the transfer memory, called after the transfer memory is | 67 | /// Reserves the region to be used for the transfer memory, called after the transfer memory is |
| 89 | /// created. | 68 | /// created. |
| @@ -94,23 +73,17 @@ public: | |||
| 94 | ResultCode Reset(); | 73 | ResultCode Reset(); |
| 95 | 74 | ||
| 96 | private: | 75 | private: |
| 97 | /// Memory block backing this instance. | ||
| 98 | std::shared_ptr<PhysicalMemory> backing_block; | ||
| 99 | |||
| 100 | /// The base address for the memory managed by this instance. | 76 | /// The base address for the memory managed by this instance. |
| 101 | VAddr base_address = 0; | 77 | VAddr base_address{}; |
| 102 | 78 | ||
| 103 | /// Size of the memory, in bytes, that this instance manages. | 79 | /// Size of the memory, in bytes, that this instance manages. |
| 104 | u64 memory_size = 0; | 80 | std::size_t size{}; |
| 105 | 81 | ||
| 106 | /// The memory permissions that are applied to this instance. | 82 | /// The memory permissions that are applied to this instance. |
| 107 | MemoryPermission owner_permissions{}; | 83 | Memory::MemoryPermission owner_permissions{}; |
| 108 | 84 | ||
| 109 | /// The process that this transfer memory instance was created under. | 85 | /// The process that this transfer memory instance was created under. |
| 110 | Process* owner_process = nullptr; | 86 | Process* owner_process{}; |
| 111 | |||
| 112 | /// Whether or not this transfer memory instance has mapped memory. | ||
| 113 | bool is_mapped = false; | ||
| 114 | 87 | ||
| 115 | Core::Memory::Memory& memory; | 88 | Core::Memory::Memory& memory; |
| 116 | }; | 89 | }; |