summaryrefslogtreecommitdiffstats
path: root/src/core/hle/kernel/transfer_memory.cpp
diff options
context:
space:
mode:
authorbunnei <bunneidev@gmail.com>2020-01-31 04:39:07 +0100
committerbunnei <bunneidev@gmail.com>2020-02-06 05:06:54 +0100
commitba53543da6126b5fe7b3f26e2688272cf11024a3 (patch)
tree6056b75468249a9841a0e521d7a381efd087e0f2 /src/core/hle/kernel/transfer_memory.cpp
parentwait_object: Make wait behavior only require one object to signal. (diff)
downloadyuzu-ba53543da6126b5fe7b3f26e2688272cf11024a3.tar
yuzu-ba53543da6126b5fe7b3f26e2688272cf11024a3.tar.gz
yuzu-ba53543da6126b5fe7b3f26e2688272cf11024a3.tar.bz2
yuzu-ba53543da6126b5fe7b3f26e2688272cf11024a3.tar.lz
yuzu-ba53543da6126b5fe7b3f26e2688272cf11024a3.tar.xz
yuzu-ba53543da6126b5fe7b3f26e2688272cf11024a3.tar.zst
yuzu-ba53543da6126b5fe7b3f26e2688272cf11024a3.zip
Diffstat (limited to 'src/core/hle/kernel/transfer_memory.cpp')
-rw-r--r--src/core/hle/kernel/transfer_memory.cpp66
1 files changed, 60 insertions, 6 deletions
diff --git a/src/core/hle/kernel/transfer_memory.cpp b/src/core/hle/kernel/transfer_memory.cpp
index f0e73f57b..f2d3f8b49 100644
--- a/src/core/hle/kernel/transfer_memory.cpp
+++ b/src/core/hle/kernel/transfer_memory.cpp
@@ -8,15 +8,23 @@
#include "core/hle/kernel/shared_memory.h"
#include "core/hle/kernel/transfer_memory.h"
#include "core/hle/result.h"
+#include "core/memory.h"
namespace Kernel {
-TransferMemory::TransferMemory(KernelCore& kernel) : Object{kernel} {}
-TransferMemory::~TransferMemory() = default;
+TransferMemory::TransferMemory(KernelCore& kernel, Memory::Memory& memory)
+ : Object{kernel}, memory{memory} {}
-std::shared_ptr<TransferMemory> TransferMemory::Create(KernelCore& kernel, VAddr base_address,
- u64 size, MemoryPermission permissions) {
- std::shared_ptr<TransferMemory> transfer_memory{std::make_shared<TransferMemory>(kernel)};
+TransferMemory::~TransferMemory() {
+ // Release memory region when transfer memory is destroyed
+ Reset();
+}
+
+std::shared_ptr<TransferMemory> TransferMemory::Create(KernelCore& kernel, Memory::Memory& memory,
+ VAddr base_address, u64 size,
+ MemoryPermission permissions) {
+ std::shared_ptr<TransferMemory> transfer_memory{
+ std::make_shared<TransferMemory>(kernel, memory)};
transfer_memory->base_address = base_address;
transfer_memory->memory_size = size;
@@ -27,7 +35,7 @@ std::shared_ptr<TransferMemory> TransferMemory::Create(KernelCore& kernel, VAddr
}
const u8* TransferMemory::GetPointer() const {
- return backing_block.get()->data();
+ return memory.GetPointer(base_address);
}
u64 TransferMemory::GetSize() const {
@@ -62,6 +70,52 @@ ResultCode TransferMemory::MapMemory(VAddr address, u64 size, MemoryPermission p
return RESULT_SUCCESS;
}
+ResultCode TransferMemory::Reserve() {
+ auto& vm_manager{owner_process->VMManager()};
+ const auto check_range_result{vm_manager.CheckRangeState(
+ base_address, memory_size, MemoryState::FlagTransfer | MemoryState::FlagMemoryPoolAllocated,
+ MemoryState::FlagTransfer | MemoryState::FlagMemoryPoolAllocated, VMAPermission::All,
+ VMAPermission::ReadWrite, MemoryAttribute::Mask, MemoryAttribute::None,
+ MemoryAttribute::IpcAndDeviceMapped)};
+
+ if (check_range_result.Failed()) {
+ return check_range_result.Code();
+ }
+
+ auto [state_, permissions_, attribute] = *check_range_result;
+
+ if (const auto result{vm_manager.ReprotectRange(
+ base_address, memory_size, SharedMemory::ConvertPermissions(owner_permissions))};
+ result.IsError()) {
+ return result;
+ }
+
+ return vm_manager.SetMemoryAttribute(base_address, memory_size, MemoryAttribute::Mask,
+ attribute | MemoryAttribute::Locked);
+}
+
+ResultCode TransferMemory::Reset() {
+ auto& vm_manager{owner_process->VMManager()};
+ if (const auto result{vm_manager.CheckRangeState(
+ base_address, memory_size,
+ MemoryState::FlagTransfer | MemoryState::FlagMemoryPoolAllocated,
+ MemoryState::FlagTransfer | MemoryState::FlagMemoryPoolAllocated, VMAPermission::None,
+ VMAPermission::None, MemoryAttribute::Mask, MemoryAttribute::Locked,
+ MemoryAttribute::IpcAndDeviceMapped)};
+ result.Failed()) {
+ return result.Code();
+ }
+
+ if (const auto result{
+ vm_manager.ReprotectRange(base_address, memory_size, VMAPermission::ReadWrite)};
+ result.IsError()) {
+ return result;
+ }
+
+ return vm_manager.SetMemoryAttribute(base_address, memory_size, MemoryAttribute::Mask,
+ MemoryAttribute::None);
+}
+
ResultCode TransferMemory::UnmapMemory(VAddr address, u64 size) {
if (memory_size != size) {
return ERR_INVALID_SIZE;