summaryrefslogtreecommitdiffstats
path: root/src/core/hle/kernel/k_shared_memory.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/core/hle/kernel/k_shared_memory.cpp86
1 files changed, 60 insertions, 26 deletions
diff --git a/src/core/hle/kernel/k_shared_memory.cpp b/src/core/hle/kernel/k_shared_memory.cpp
index 9b14f42b5..7770b1868 100644
--- a/src/core/hle/kernel/k_shared_memory.cpp
+++ b/src/core/hle/kernel/k_shared_memory.cpp
@@ -8,50 +8,74 @@
#include "core/hle/kernel/k_scoped_resource_reservation.h"
#include "core/hle/kernel/k_shared_memory.h"
#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/svc_results.h"
namespace Kernel {
-KSharedMemory::KSharedMemory(KernelCore& kernel, Core::DeviceMemory& device_memory)
- : Object{kernel}, device_memory{device_memory} {}
+KSharedMemory::KSharedMemory(KernelCore& kernel_) : KAutoObjectWithSlabHeapAndContainer{kernel_} {}
KSharedMemory::~KSharedMemory() {
kernel.GetSystemResourceLimit()->Release(LimitableResource::PhysicalMemory, size);
}
-std::shared_ptr<KSharedMemory> KSharedMemory::Create(
- KernelCore& kernel, Core::DeviceMemory& device_memory, Process* owner_process,
- KPageLinkedList&& page_list, KMemoryPermission owner_permission,
- KMemoryPermission user_permission, PAddr physical_address, std::size_t size, std::string name) {
+ResultCode KSharedMemory::Initialize(Core::DeviceMemory& device_memory_, KProcess* owner_process_,
+ KPageLinkedList&& page_list_,
+ Svc::MemoryPermission owner_permission_,
+ Svc::MemoryPermission user_permission_,
+ PAddr physical_address_, std::size_t size_,
+ std::string name_) {
+ // Set members.
+ owner_process = owner_process_;
+ device_memory = &device_memory_;
+ page_list = std::move(page_list_);
+ owner_permission = owner_permission_;
+ user_permission = user_permission_;
+ physical_address = physical_address_;
+ size = size_;
+ name = std::move(name_);
- const auto resource_limit = kernel.GetSystemResourceLimit();
- KScopedResourceReservation memory_reservation(resource_limit, LimitableResource::PhysicalMemory,
- size);
- ASSERT(memory_reservation.Succeeded());
+ // Get the resource limit.
+ KResourceLimit* reslimit = kernel.GetSystemResourceLimit();
- std::shared_ptr<KSharedMemory> shared_memory{
- std::make_shared<KSharedMemory>(kernel, device_memory)};
-
- shared_memory->owner_process = owner_process;
- shared_memory->page_list = std::move(page_list);
- shared_memory->owner_permission = owner_permission;
- shared_memory->user_permission = user_permission;
- shared_memory->physical_address = physical_address;
- shared_memory->size = size;
- shared_memory->name = name;
+ // Reserve memory for ourselves.
+ KScopedResourceReservation memory_reservation(reslimit, LimitableResource::PhysicalMemory,
+ size_);
+ R_UNLESS(memory_reservation.Succeeded(), ResultLimitReached);
+ // Commit our reservation.
memory_reservation.Commit();
- return shared_memory;
+
+ // Set our resource limit.
+ resource_limit = reslimit;
+ resource_limit->Open();
+
+ // Mark initialized.
+ is_initialized = true;
+
+ // Clear all pages in the memory.
+ std::memset(device_memory_.GetPointer(physical_address_), 0, size_);
+
+ return RESULT_SUCCESS;
+}
+
+void KSharedMemory::Finalize() {
+ // Release the memory reservation.
+ resource_limit->Release(LimitableResource::PhysicalMemory, size);
+ resource_limit->Close();
+
+ // Perform inherited finalization.
+ KAutoObjectWithSlabHeapAndContainer<KSharedMemory, KAutoObjectWithList>::Finalize();
}
-ResultCode KSharedMemory::Map(Process& target_process, VAddr address, std::size_t size,
- KMemoryPermission permissions) {
- const u64 page_count{(size + PageSize - 1) / PageSize};
+ResultCode KSharedMemory::Map(KProcess& target_process, VAddr address, std::size_t map_size,
+ Svc::MemoryPermission permissions) {
+ const u64 page_count{(map_size + PageSize - 1) / PageSize};
if (page_list.GetNumPages() != page_count) {
UNIMPLEMENTED_MSG("Page count does not match");
}
- const KMemoryPermission expected =
+ const Svc::MemoryPermission expected =
&target_process == owner_process ? owner_permission : user_permission;
if (permissions != expected) {
@@ -59,7 +83,17 @@ ResultCode KSharedMemory::Map(Process& target_process, VAddr address, std::size_
}
return target_process.PageTable().MapPages(address, page_list, KMemoryState::Shared,
- permissions);
+ ConvertToKMemoryPermission(permissions));
+}
+
+ResultCode KSharedMemory::Unmap(KProcess& target_process, VAddr address, std::size_t unmap_size) {
+ const u64 page_count{(unmap_size + PageSize - 1) / PageSize};
+
+ if (page_list.GetNumPages() != page_count) {
+ UNIMPLEMENTED_MSG("Page count does not match");
+ }
+
+ return target_process.PageTable().UnmapPages(address, page_list, KMemoryState::Shared);
}
} // namespace Kernel