summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2020-04-08 19:05:31 -0400
committerGravatar bunnei2020-04-17 00:59:32 -0400
commit3fcc4cab4fcc7a3496e98fb699a96d21df90e512 (patch)
treefae88975e2e00c5514c348d851a13fc46a6045b9 /src
parentcore: Construct/Destruct DeviceMemory on Init/Shutdown. (diff)
downloadyuzu-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.cpp99
-rw-r--r--src/core/hle/kernel/transfer_memory.h47
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
23std::shared_ptr<TransferMemory> TransferMemory::Create(KernelCore& kernel, 22std::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
42u64 TransferMemory::GetSize() const {
43 return memory_size;
44}
45
46ResultCode 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
74ResultCode TransferMemory::Reserve() { 41ResultCode 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
98ResultCode TransferMemory::Reset() { 45ResultCode 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
120ResultCode 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 {
20class KernelCore; 21class KernelCore;
21class Process; 22class Process;
22 23
23enum 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
96private: 75private:
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};