summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/core/CMakeLists.txt2
-rw-r--r--src/core/hle/kernel/object.cpp1
-rw-r--r--src/core/hle/kernel/object.h1
-rw-r--r--src/core/hle/kernel/svc.cpp13
-rw-r--r--src/core/hle/kernel/transfer_memory.cpp73
-rw-r--r--src/core/hle/kernel/transfer_memory.h91
6 files changed, 177 insertions, 4 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 8ccb2d5f0..e8aefb6b4 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -140,6 +140,8 @@ add_library(core STATIC
140 hle/kernel/svc_wrap.h 140 hle/kernel/svc_wrap.h
141 hle/kernel/thread.cpp 141 hle/kernel/thread.cpp
142 hle/kernel/thread.h 142 hle/kernel/thread.h
143 hle/kernel/transfer_memory.cpp
144 hle/kernel/transfer_memory.h
143 hle/kernel/vm_manager.cpp 145 hle/kernel/vm_manager.cpp
144 hle/kernel/vm_manager.h 146 hle/kernel/vm_manager.h
145 hle/kernel/wait_object.cpp 147 hle/kernel/wait_object.cpp
diff --git a/src/core/hle/kernel/object.cpp b/src/core/hle/kernel/object.cpp
index 8870463d0..217144efc 100644
--- a/src/core/hle/kernel/object.cpp
+++ b/src/core/hle/kernel/object.cpp
@@ -23,6 +23,7 @@ bool Object::IsWaitable() const {
23 case HandleType::Unknown: 23 case HandleType::Unknown:
24 case HandleType::WritableEvent: 24 case HandleType::WritableEvent:
25 case HandleType::SharedMemory: 25 case HandleType::SharedMemory:
26 case HandleType::TransferMemory:
26 case HandleType::AddressArbiter: 27 case HandleType::AddressArbiter:
27 case HandleType::ResourceLimit: 28 case HandleType::ResourceLimit:
28 case HandleType::ClientPort: 29 case HandleType::ClientPort:
diff --git a/src/core/hle/kernel/object.h b/src/core/hle/kernel/object.h
index 4c2505908..3f6baa094 100644
--- a/src/core/hle/kernel/object.h
+++ b/src/core/hle/kernel/object.h
@@ -22,6 +22,7 @@ enum class HandleType : u32 {
22 WritableEvent, 22 WritableEvent,
23 ReadableEvent, 23 ReadableEvent,
24 SharedMemory, 24 SharedMemory,
25 TransferMemory,
25 Thread, 26 Thread,
26 Process, 27 Process,
27 AddressArbiter, 28 AddressArbiter,
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 77d0e3d96..c8b9e8aeb 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -32,6 +32,7 @@
32#include "core/hle/kernel/svc.h" 32#include "core/hle/kernel/svc.h"
33#include "core/hle/kernel/svc_wrap.h" 33#include "core/hle/kernel/svc_wrap.h"
34#include "core/hle/kernel/thread.h" 34#include "core/hle/kernel/thread.h"
35#include "core/hle/kernel/transfer_memory.h"
35#include "core/hle/kernel/writable_event.h" 36#include "core/hle/kernel/writable_event.h"
36#include "core/hle/lock.h" 37#include "core/hle/lock.h"
37#include "core/hle/result.h" 38#include "core/hle/result.h"
@@ -1577,11 +1578,15 @@ static ResultCode CreateTransferMemory(Handle* handle, VAddr addr, u64 size, u32
1577 } 1578 }
1578 1579
1579 auto& kernel = Core::System::GetInstance().Kernel(); 1580 auto& kernel = Core::System::GetInstance().Kernel();
1580 auto process = kernel.CurrentProcess(); 1581 auto transfer_mem_handle = TransferMemory::Create(kernel, addr, size, perms);
1581 auto& handle_table = process->GetHandleTable();
1582 const auto shared_mem_handle = SharedMemory::Create(kernel, process, size, perms, perms, addr);
1583 1582
1584 CASCADE_RESULT(*handle, handle_table.Create(shared_mem_handle)); 1583 auto& handle_table = kernel.CurrentProcess()->GetHandleTable();
1584 const auto result = handle_table.Create(std::move(transfer_mem_handle));
1585 if (result.Failed()) {
1586 return result.Code();
1587 }
1588
1589 *handle = *result;
1585 return RESULT_SUCCESS; 1590 return RESULT_SUCCESS;
1586} 1591}
1587 1592
diff --git a/src/core/hle/kernel/transfer_memory.cpp b/src/core/hle/kernel/transfer_memory.cpp
new file mode 100644
index 000000000..23228e1b5
--- /dev/null
+++ b/src/core/hle/kernel/transfer_memory.cpp
@@ -0,0 +1,73 @@
1// Copyright 2019 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/kernel/errors.h"
6#include "core/hle/kernel/kernel.h"
7#include "core/hle/kernel/process.h"
8#include "core/hle/kernel/shared_memory.h"
9#include "core/hle/kernel/transfer_memory.h"
10#include "core/hle/result.h"
11
12namespace Kernel {
13
14TransferMemory::TransferMemory(KernelCore& kernel) : Object{kernel} {}
15TransferMemory::~TransferMemory() = default;
16
17SharedPtr<TransferMemory> TransferMemory::Create(KernelCore& kernel, VAddr base_address,
18 size_t size, MemoryPermission permissions) {
19 SharedPtr<TransferMemory> transfer_memory{new TransferMemory(kernel)};
20
21 transfer_memory->base_address = base_address;
22 transfer_memory->memory_size = size;
23 transfer_memory->owner_permissions = permissions;
24 transfer_memory->owner_process = kernel.CurrentProcess();
25
26 return transfer_memory;
27}
28
29ResultCode TransferMemory::MapMemory(VAddr address, size_t size, MemoryPermission permissions) {
30 if (memory_size != size) {
31 return ERR_INVALID_SIZE;
32 }
33
34 if (owner_permissions != permissions) {
35 return ERR_INVALID_STATE;
36 }
37
38 if (is_mapped) {
39 return ERR_INVALID_STATE;
40 }
41
42 const auto map_state = owner_permissions == MemoryPermission::None
43 ? MemoryState::TransferMemoryIsolated
44 : MemoryState::TransferMemory;
45 auto& vm_manager = owner_process->VMManager();
46 const auto map_result = vm_manager.MapMemoryBlock(
47 address, std::make_shared<std::vector<u8>>(size), 0, size, map_state);
48
49 if (map_result.Failed()) {
50 return map_result.Code();
51 }
52
53 is_mapped = true;
54 return RESULT_SUCCESS;
55}
56
57ResultCode TransferMemory::UnmapMemory(VAddr address, size_t size) {
58 if (memory_size != size) {
59 return ERR_INVALID_SIZE;
60 }
61
62 auto& vm_manager = owner_process->VMManager();
63 const auto result = vm_manager.UnmapRange(address, size);
64
65 if (result.IsError()) {
66 return result;
67 }
68
69 is_mapped = false;
70 return RESULT_SUCCESS;
71}
72
73} // namespace Kernel
diff --git a/src/core/hle/kernel/transfer_memory.h b/src/core/hle/kernel/transfer_memory.h
new file mode 100644
index 000000000..ec294951e
--- /dev/null
+++ b/src/core/hle/kernel/transfer_memory.h
@@ -0,0 +1,91 @@
1// Copyright 2019 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "core/hle/kernel/object.h"
8
9union ResultCode;
10
11namespace Kernel {
12
13class KernelCore;
14class Process;
15
16enum class MemoryPermission : u32;
17
18/// Defines the interface for transfer memory objects.
19///
20/// Transfer memory is typically used for the purpose of
21/// transferring memory between separate process instances,
22/// thus the name.
23///
24class TransferMemory final : public Object {
25public:
26 static constexpr HandleType HANDLE_TYPE = HandleType::TransferMemory;
27
28 static SharedPtr<TransferMemory> Create(KernelCore& kernel, VAddr base_address, size_t size,
29 MemoryPermission permissions);
30
31 TransferMemory(const TransferMemory&) = delete;
32 TransferMemory& operator=(const TransferMemory&) = delete;
33
34 TransferMemory(TransferMemory&&) = delete;
35 TransferMemory& operator=(TransferMemory&&) = delete;
36
37 std::string GetTypeName() const override {
38 return "TransferMemory";
39 }
40
41 std::string GetName() const override {
42 return GetTypeName();
43 }
44
45 HandleType GetHandleType() const override {
46 return HANDLE_TYPE;
47 }
48
49 /// Attempts to map transfer memory with the given range and memory permissions.
50 ///
51 /// @param address The base address to being mapping memory at.
52 /// @param size The size of the memory to map, in bytes.
53 /// @param permissions The memory permissions to check against when mapping memory.
54 ///
55 /// @pre The given address, size, and memory permissions must all match
56 /// the same values that were given when creating the transfer memory
57 /// instance.
58 ///
59 ResultCode MapMemory(VAddr address, size_t size, MemoryPermission permissions);
60
61 /// Unmaps the transfer memory with the given range
62 ///
63 /// @param address The base address to begin unmapping memory at.
64 /// @param size The size of the memory to unmap, in bytes.
65 ///
66 /// @pre The given address and size must be the same as the ones used
67 /// to create the transfer memory instance.
68 ///
69 ResultCode UnmapMemory(VAddr address, size_t size);
70
71private:
72 explicit TransferMemory(KernelCore& kernel);
73 ~TransferMemory() override;
74
75 /// The base address for the memory managed by this instance.
76 VAddr base_address = 0;
77
78 /// Size of the memory, in bytes, that this instance manages.
79 size_t memory_size = 0;
80
81 /// The memory permissions that are applied to this instance.
82 MemoryPermission owner_permissions{};
83
84 /// The process that this transfer memory instance was created under.
85 Process* owner_process = nullptr;
86
87 /// Whether or not this transfer memory instance has mapped memory.
88 bool is_mapped = false;
89};
90
91} // namespace Kernel