mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2025-01-05 11:58:00 +00:00
kern: fully implement KSharedMemory (and Svcs)
This commit is contained in:
parent
81db43932d
commit
7aa3120f60
7 changed files with 314 additions and 7 deletions
|
@ -195,6 +195,8 @@ namespace ams::kern::arch::arm64 {
|
||||||
|
|
||||||
size_t GetNormalMemorySize() const { return this->page_table.GetNormalMemorySize(); }
|
size_t GetNormalMemorySize() const { return this->page_table.GetNormalMemorySize(); }
|
||||||
|
|
||||||
|
u32 GetAllocateOption() const { return this->page_table.GetAllocateOption(); }
|
||||||
|
|
||||||
KPhysicalAddress GetHeapPhysicalAddress(KVirtualAddress address) const {
|
KPhysicalAddress GetHeapPhysicalAddress(KVirtualAddress address) const {
|
||||||
/* TODO: Better way to convert address type? */
|
/* TODO: Better way to convert address type? */
|
||||||
return this->page_table.GetHeapPhysicalAddress(address);
|
return this->page_table.GetHeapPhysicalAddress(address);
|
||||||
|
|
|
@ -345,6 +345,8 @@ namespace ams::kern {
|
||||||
|
|
||||||
return (this->current_heap_end - this->heap_region_start) + this->mapped_physical_memory_size;
|
return (this->current_heap_end - this->heap_region_start) + this->mapped_physical_memory_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 GetAllocateOption() const { return this->allocate_option; }
|
||||||
public:
|
public:
|
||||||
static ALWAYS_INLINE KVirtualAddress GetLinearMappedVirtualAddress(KPhysicalAddress addr) {
|
static ALWAYS_INLINE KVirtualAddress GetLinearMappedVirtualAddress(KPhysicalAddress addr) {
|
||||||
return KMemoryLayout::GetLinearVirtualAddress(addr);
|
return KMemoryLayout::GetLinearVirtualAddress(addr);
|
||||||
|
|
|
@ -151,7 +151,6 @@ namespace ams::kern {
|
||||||
constexpr KProcessAddress GetEntryPoint() const { return this->code_address; }
|
constexpr KProcessAddress GetEntryPoint() const { return this->code_address; }
|
||||||
|
|
||||||
constexpr u64 GetRandomEntropy(size_t i) const { return this->entropy[i]; }
|
constexpr u64 GetRandomEntropy(size_t i) const { return this->entropy[i]; }
|
||||||
|
|
||||||
constexpr bool IsSuspended() const {
|
constexpr bool IsSuspended() const {
|
||||||
return this->is_suspended;
|
return this->is_suspended;
|
||||||
}
|
}
|
||||||
|
@ -176,6 +175,8 @@ namespace ams::kern {
|
||||||
return this->capabilities.CanForceDebug();
|
return this->capabilities.CanForceDebug();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 GetAllocateOption() const { return this->page_table.GetAllocateOption(); }
|
||||||
|
|
||||||
ThreadList &GetThreadList() { return this->thread_list; }
|
ThreadList &GetThreadList() { return this->thread_list; }
|
||||||
const ThreadList &GetThreadList() const { return this->thread_list; }
|
const ThreadList &GetThreadList() const { return this->thread_list; }
|
||||||
|
|
||||||
|
@ -218,6 +219,9 @@ namespace ams::kern {
|
||||||
size_t GetUsedNonSystemUserPhysicalMemorySize() const;
|
size_t GetUsedNonSystemUserPhysicalMemorySize() const;
|
||||||
size_t GetTotalNonSystemUserPhysicalMemorySize() const;
|
size_t GetTotalNonSystemUserPhysicalMemorySize() const;
|
||||||
|
|
||||||
|
Result AddSharedMemory(KSharedMemory *shmem, KProcessAddress address, size_t size);
|
||||||
|
void RemoveSharedMemory(KSharedMemory *shmem, KProcessAddress address, size_t size);
|
||||||
|
|
||||||
Result CreateThreadLocalRegion(KProcessAddress *out);
|
Result CreateThreadLocalRegion(KProcessAddress *out);
|
||||||
Result DeleteThreadLocalRegion(KProcessAddress addr);
|
Result DeleteThreadLocalRegion(KProcessAddress addr);
|
||||||
void *GetThreadLocalRegionPointer(KProcessAddress addr);
|
void *GetThreadLocalRegionPointer(KProcessAddress addr);
|
||||||
|
|
|
@ -17,11 +17,43 @@
|
||||||
#include <mesosphere/kern_common.hpp>
|
#include <mesosphere/kern_common.hpp>
|
||||||
#include <mesosphere/kern_k_auto_object.hpp>
|
#include <mesosphere/kern_k_auto_object.hpp>
|
||||||
#include <mesosphere/kern_slab_helpers.hpp>
|
#include <mesosphere/kern_slab_helpers.hpp>
|
||||||
|
#include <mesosphere/kern_select_page_table.hpp>
|
||||||
|
|
||||||
namespace ams::kern {
|
namespace ams::kern {
|
||||||
|
|
||||||
|
class KProcess;
|
||||||
|
class KResourceLimit;
|
||||||
|
|
||||||
class KSharedMemory final : public KAutoObjectWithSlabHeapAndContainer<KSharedMemory, KAutoObjectWithList> {
|
class KSharedMemory final : public KAutoObjectWithSlabHeapAndContainer<KSharedMemory, KAutoObjectWithList> {
|
||||||
MESOSPHERE_AUTOOBJECT_TRAITS(KSharedMemory, KAutoObject);
|
MESOSPHERE_AUTOOBJECT_TRAITS(KSharedMemory, KAutoObject);
|
||||||
|
private:
|
||||||
|
KPageGroup page_group;
|
||||||
|
KResourceLimit *resource_limit;
|
||||||
|
u64 owner_process_id;
|
||||||
|
ams::svc::MemoryPermission owner_perm;
|
||||||
|
ams::svc::MemoryPermission remote_perm;
|
||||||
|
bool is_initialized;
|
||||||
|
public:
|
||||||
|
explicit KSharedMemory()
|
||||||
|
: page_group(std::addressof(Kernel::GetBlockInfoManager())), resource_limit(nullptr), owner_process_id(std::numeric_limits<u64>::max()),
|
||||||
|
owner_perm(ams::svc::MemoryPermission_None), remote_perm(ams::svc::MemoryPermission_None), is_initialized(false)
|
||||||
|
{
|
||||||
|
/* ... */
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~KSharedMemory() { /* ... */ }
|
||||||
|
|
||||||
|
Result Initialize(KProcess *owner, size_t size, ams::svc::MemoryPermission own_perm, ams::svc::MemoryPermission rem_perm);
|
||||||
|
virtual void Finalize() override;
|
||||||
|
|
||||||
|
virtual bool IsInitialized() const override { return this->is_initialized; }
|
||||||
|
static void PostDestroy(uintptr_t arg) { /* ... */ }
|
||||||
|
|
||||||
|
Result Map(KProcessPageTable *table, KProcessAddress address, size_t size, KProcess *process, ams::svc::MemoryPermission map_perm);
|
||||||
|
Result Unmap(KProcessPageTable *table, KProcessAddress address, size_t size, KProcess *process);
|
||||||
|
|
||||||
|
u64 GetOwnerProcessId() const { return this->owner_process_id; }
|
||||||
|
size_t GetSize() const { return this->page_group.GetNumPages() * PageSize; }
|
||||||
public:
|
public:
|
||||||
/* TODO: This is a placeholder definition. */
|
/* TODO: This is a placeholder definition. */
|
||||||
};
|
};
|
||||||
|
|
|
@ -277,6 +277,61 @@ namespace ams::kern {
|
||||||
MESOSPHERE_UNIMPLEMENTED();
|
MESOSPHERE_UNIMPLEMENTED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result KProcess::AddSharedMemory(KSharedMemory *shmem, KProcessAddress address, size_t size) {
|
||||||
|
/* Lock ourselves, to prevent concurrent access. */
|
||||||
|
KScopedLightLock lk(this->state_lock);
|
||||||
|
|
||||||
|
/* Try to find an existing info for the memory. */
|
||||||
|
KSharedMemoryInfo *info = nullptr;
|
||||||
|
for (auto it = this->shared_memory_list.begin(); it != this->shared_memory_list.end(); ++it) {
|
||||||
|
if (it->GetSharedMemory() == shmem) {
|
||||||
|
info = std::addressof(*it);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we didn't find an info, create one. */
|
||||||
|
if (info == nullptr) {
|
||||||
|
/* Allocate a new info. */
|
||||||
|
info = KSharedMemoryInfo::Allocate();
|
||||||
|
R_UNLESS(info != nullptr, svc::ResultOutOfResource());
|
||||||
|
|
||||||
|
/* Initialize the info and add it to our list. */
|
||||||
|
info->Initialize(shmem);
|
||||||
|
this->shared_memory_list.push_back(*info);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open a reference to the shared memory and its info. */
|
||||||
|
shmem->Open();
|
||||||
|
info->Open();
|
||||||
|
|
||||||
|
return ResultSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
void KProcess::RemoveSharedMemory(KSharedMemory *shmem, KProcessAddress address, size_t size) {
|
||||||
|
/* Lock ourselves, to prevent concurrent access. */
|
||||||
|
KScopedLightLock lk(this->state_lock);
|
||||||
|
|
||||||
|
/* Find an existing info for the memory. */
|
||||||
|
KSharedMemoryInfo *info = nullptr;
|
||||||
|
auto it = this->shared_memory_list.begin();
|
||||||
|
for (/* ... */; it != this->shared_memory_list.end(); ++it) {
|
||||||
|
if (it->GetSharedMemory() == shmem) {
|
||||||
|
info = std::addressof(*it);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MESOSPHERE_ABORT_UNLESS(info != nullptr);
|
||||||
|
|
||||||
|
/* Close a reference to the info and its memory. */
|
||||||
|
if (info->Close()) {
|
||||||
|
this->shared_memory_list.erase(it);
|
||||||
|
KSharedMemoryInfo::Free(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
shmem->Close();
|
||||||
|
}
|
||||||
|
|
||||||
Result KProcess::CreateThreadLocalRegion(KProcessAddress *out) {
|
Result KProcess::CreateThreadLocalRegion(KProcessAddress *out) {
|
||||||
KThreadLocalPage *tlp = nullptr;
|
KThreadLocalPage *tlp = nullptr;
|
||||||
KProcessAddress tlr = Null<KProcessAddress>;
|
KProcessAddress tlr = Null<KProcessAddress>;
|
||||||
|
|
110
libraries/libmesosphere/source/kern_k_shared_memory.cpp
Normal file
110
libraries/libmesosphere/source/kern_k_shared_memory.cpp
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include <mesosphere.hpp>
|
||||||
|
|
||||||
|
namespace ams::kern {
|
||||||
|
|
||||||
|
Result KSharedMemory::Initialize(KProcess *owner, size_t size, ams::svc::MemoryPermission own_perm, ams::svc::MemoryPermission rem_perm) {
|
||||||
|
MESOSPHERE_ASSERT_THIS();
|
||||||
|
|
||||||
|
/* Set members. */
|
||||||
|
this->owner_process_id = owner->GetId();
|
||||||
|
this->owner_perm = own_perm;
|
||||||
|
this->remote_perm = rem_perm;
|
||||||
|
|
||||||
|
/* Get the number of pages. */
|
||||||
|
const size_t num_pages = util::DivideUp(size, PageSize);
|
||||||
|
MESOSPHERE_ASSERT(num_pages > 0);
|
||||||
|
|
||||||
|
/* Get the resource limit. */
|
||||||
|
KResourceLimit *reslimit = owner->GetResourceLimit();
|
||||||
|
|
||||||
|
/* Reserve memory for ourselves. */
|
||||||
|
KScopedResourceReservation memory_reservation(reslimit, ams::svc::LimitableResource_PhysicalMemoryMax, size);
|
||||||
|
R_UNLESS(memory_reservation.Succeeded(), svc::ResultLimitReached());
|
||||||
|
|
||||||
|
/* Allocate the memory. */
|
||||||
|
R_TRY(Kernel::GetMemoryManager().Allocate(std::addressof(this->page_group), num_pages, owner->GetAllocateOption()));
|
||||||
|
|
||||||
|
/* Commit our reservation. */
|
||||||
|
memory_reservation.Commit();
|
||||||
|
|
||||||
|
/* Set our resource limit. */
|
||||||
|
this->resource_limit = reslimit;
|
||||||
|
this->resource_limit->Open();
|
||||||
|
|
||||||
|
/* Open the memory. */
|
||||||
|
this->page_group.Open();
|
||||||
|
|
||||||
|
/* Mark initialized. */
|
||||||
|
this->is_initialized = true;
|
||||||
|
|
||||||
|
/* Clear all pages in the memory. */
|
||||||
|
for (const auto &block : this->page_group) {
|
||||||
|
std::memset(GetVoidPointer(block.GetAddress()), 0, block.GetSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
return ResultSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
void KSharedMemory::Finalize() {
|
||||||
|
MESOSPHERE_ASSERT_THIS();
|
||||||
|
|
||||||
|
/* Get the number of pages. */
|
||||||
|
const size_t num_pages = this->page_group.GetNumPages();
|
||||||
|
const size_t size = num_pages * PageSize;
|
||||||
|
|
||||||
|
/* Close and finalize the page group. */
|
||||||
|
this->page_group.Close();
|
||||||
|
this->page_group.Finalize();
|
||||||
|
|
||||||
|
/* Release the memory reservation. */
|
||||||
|
this->resource_limit->Release(ams::svc::LimitableResource_PhysicalMemoryMax, size);
|
||||||
|
this->resource_limit->Close();
|
||||||
|
|
||||||
|
/* Perform inherited finalization. */
|
||||||
|
KAutoObjectWithSlabHeapAndContainer<KSharedMemory, KAutoObjectWithList>::Finalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result KSharedMemory::Map(KProcessPageTable *table, KProcessAddress address, size_t size, KProcess *process, ams::svc::MemoryPermission map_perm) {
|
||||||
|
MESOSPHERE_ASSERT_THIS();
|
||||||
|
|
||||||
|
/* Validate the size. */
|
||||||
|
R_UNLESS(this->page_group.GetNumPages() == util::DivideUp(size, PageSize), svc::ResultInvalidSize());
|
||||||
|
|
||||||
|
/* Validate the permission. */
|
||||||
|
const ams::svc::MemoryPermission test_perm = (process->GetId() == this->owner_process_id) ? this->owner_perm : this->remote_perm;
|
||||||
|
if (test_perm == ams::svc::MemoryPermission_DontCare) {
|
||||||
|
MESOSPHERE_ASSERT(map_perm == ams::svc::MemoryPermission_Read || map_perm == ams::svc::MemoryPermission_ReadWrite);
|
||||||
|
} else {
|
||||||
|
R_UNLESS(map_perm == test_perm, svc::ResultInvalidNewMemoryPermission());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Map the memory. */
|
||||||
|
return table->MapPageGroup(address, this->page_group, KMemoryState_Shared, ConvertToKMemoryPermission(map_perm));
|
||||||
|
}
|
||||||
|
|
||||||
|
Result KSharedMemory::Unmap(KProcessPageTable *table, KProcessAddress address, size_t size, KProcess *process) {
|
||||||
|
MESOSPHERE_ASSERT_THIS();
|
||||||
|
|
||||||
|
/* Validate the size. */
|
||||||
|
R_UNLESS(this->page_group.GetNumPages() == util::DivideUp(size, PageSize), svc::ResultInvalidSize());
|
||||||
|
|
||||||
|
/* Unmap the memory. */
|
||||||
|
return table->UnmapPageGroup(address, this->page_group, KMemoryState_Shared);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -21,36 +21,138 @@ namespace ams::kern::svc {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
constexpr bool IsValidSharedMemoryPermission(ams::svc::MemoryPermission perm) {
|
||||||
|
switch (perm) {
|
||||||
|
case ams::svc::MemoryPermission_Read:
|
||||||
|
case ams::svc::MemoryPermission_ReadWrite:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool IsValidRemoteSharedMemoryPermission(ams::svc::MemoryPermission perm) {
|
||||||
|
return IsValidSharedMemoryPermission(perm) || perm == ams::svc::MemoryPermission_DontCare;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result MapSharedMemory(ams::svc::Handle shmem_handle, uintptr_t address, size_t size, ams::svc::MemoryPermission map_perm) {
|
||||||
|
/* Validate the address/size. */
|
||||||
|
R_UNLESS(util::IsAligned(address, PageSize), svc::ResultInvalidAddress());
|
||||||
|
R_UNLESS(util::IsAligned(size, PageSize), svc::ResultInvalidSize());
|
||||||
|
R_UNLESS(size > 0, svc::ResultInvalidSize());
|
||||||
|
R_UNLESS((address < address + size), svc::ResultInvalidCurrentMemory());
|
||||||
|
|
||||||
|
/* Validate the permission. */
|
||||||
|
R_UNLESS(IsValidSharedMemoryPermission(map_perm), svc::ResultInvalidNewMemoryPermission());
|
||||||
|
|
||||||
|
/* Get the current process. */
|
||||||
|
auto &process = GetCurrentProcess();
|
||||||
|
auto &page_table = process.GetPageTable();
|
||||||
|
|
||||||
|
/* Get the shared memory. */
|
||||||
|
KScopedAutoObject shmem = process.GetHandleTable().GetObject<KSharedMemory>(shmem_handle);
|
||||||
|
R_UNLESS(shmem.IsNotNull(), svc::ResultInvalidHandle());
|
||||||
|
|
||||||
|
/* Verify that the mapping is in range. */
|
||||||
|
R_UNLESS(page_table.CanContain(address, size, KMemoryState_Shared), svc::ResultInvalidMemoryRegion());
|
||||||
|
|
||||||
|
/* Add the shared memory to the process. */
|
||||||
|
R_TRY(process.AddSharedMemory(shmem.GetPointerUnsafe(), address, size));
|
||||||
|
|
||||||
|
/* Ensure that we clean up the shared memory if we fail to map it. */
|
||||||
|
auto guard = SCOPE_GUARD { process.RemoveSharedMemory(shmem.GetPointerUnsafe(), address, size); };
|
||||||
|
|
||||||
|
/* Map the shared memory. */
|
||||||
|
R_TRY(shmem->Map(std::addressof(page_table), address, size, std::addressof(process), map_perm));
|
||||||
|
|
||||||
|
/* We succeeded. */
|
||||||
|
guard.Cancel();
|
||||||
|
return ResultSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result UnmapSharedMemory(ams::svc::Handle shmem_handle, uintptr_t address, size_t size) {
|
||||||
|
/* Validate the address/size. */
|
||||||
|
R_UNLESS(util::IsAligned(address, PageSize), svc::ResultInvalidAddress());
|
||||||
|
R_UNLESS(util::IsAligned(size, PageSize), svc::ResultInvalidSize());
|
||||||
|
R_UNLESS(size > 0, svc::ResultInvalidSize());
|
||||||
|
R_UNLESS((address < address + size), svc::ResultInvalidCurrentMemory());
|
||||||
|
|
||||||
|
/* Get the current process. */
|
||||||
|
auto &process = GetCurrentProcess();
|
||||||
|
auto &page_table = process.GetPageTable();
|
||||||
|
|
||||||
|
/* Get the shared memory. */
|
||||||
|
KScopedAutoObject shmem = process.GetHandleTable().GetObject<KSharedMemory>(shmem_handle);
|
||||||
|
R_UNLESS(shmem.IsNotNull(), svc::ResultInvalidHandle());
|
||||||
|
|
||||||
|
/* Verify that the mapping is in range. */
|
||||||
|
R_UNLESS(page_table.CanContain(address, size, KMemoryState_Shared), svc::ResultInvalidMemoryRegion());
|
||||||
|
|
||||||
|
/* Map the shared memory. */
|
||||||
|
R_TRY(shmem->Unmap(std::addressof(page_table), address, size, std::addressof(process)));
|
||||||
|
|
||||||
|
/* Remove the shared memory from the process. */
|
||||||
|
process.RemoveSharedMemory(shmem.GetPointerUnsafe(), address, size);
|
||||||
|
|
||||||
|
return ResultSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result CreateSharedMemory(ams::svc::Handle *out, size_t size, ams::svc::MemoryPermission owner_perm, ams::svc::MemoryPermission remote_perm) {
|
||||||
|
/* Validate the size. */
|
||||||
|
R_UNLESS(0 < size && size < kern::MainMemorySize, svc::ResultInvalidSize());
|
||||||
|
R_UNLESS(util::IsAligned(size, PageSize), svc::ResultInvalidSize());
|
||||||
|
|
||||||
|
/* Validate the permissions. */
|
||||||
|
R_UNLESS(IsValidSharedMemoryPermission(owner_perm), svc::ResultInvalidNewMemoryPermission());
|
||||||
|
R_UNLESS(IsValidRemoteSharedMemoryPermission(remote_perm), svc::ResultInvalidNewMemoryPermission());
|
||||||
|
|
||||||
|
/* Create the shared memory. */
|
||||||
|
KSharedMemory *shmem = KSharedMemory::Create();
|
||||||
|
R_UNLESS(shmem != nullptr, svc::ResultOutOfResource());
|
||||||
|
|
||||||
|
/* Ensure the only reference is in the handle table when we're done. */
|
||||||
|
ON_SCOPE_EXIT { shmem->Close(); };
|
||||||
|
|
||||||
|
/* Initialize the shared memory. */
|
||||||
|
R_TRY(shmem->Initialize(GetCurrentProcessPointer(), size, owner_perm, remote_perm));
|
||||||
|
|
||||||
|
/* Register the shared memory. */
|
||||||
|
R_TRY(KSharedMemory::Register(shmem));
|
||||||
|
|
||||||
|
/* Add the shared memory to the handle table. */
|
||||||
|
R_TRY(GetCurrentProcess().GetHandleTable().Add(out, shmem));
|
||||||
|
|
||||||
|
return ResultSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================= 64 ABI ============================= */
|
/* ============================= 64 ABI ============================= */
|
||||||
|
|
||||||
Result MapSharedMemory64(ams::svc::Handle shmem_handle, ams::svc::Address address, ams::svc::Size size, ams::svc::MemoryPermission map_perm) {
|
Result MapSharedMemory64(ams::svc::Handle shmem_handle, ams::svc::Address address, ams::svc::Size size, ams::svc::MemoryPermission map_perm) {
|
||||||
MESOSPHERE_PANIC("Stubbed SvcMapSharedMemory64 was called.");
|
return MapSharedMemory(shmem_handle, address, size, map_perm);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result UnmapSharedMemory64(ams::svc::Handle shmem_handle, ams::svc::Address address, ams::svc::Size size) {
|
Result UnmapSharedMemory64(ams::svc::Handle shmem_handle, ams::svc::Address address, ams::svc::Size size) {
|
||||||
MESOSPHERE_PANIC("Stubbed SvcUnmapSharedMemory64 was called.");
|
return UnmapSharedMemory(shmem_handle, address, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CreateSharedMemory64(ams::svc::Handle *out_handle, ams::svc::Size size, ams::svc::MemoryPermission owner_perm, ams::svc::MemoryPermission remote_perm) {
|
Result CreateSharedMemory64(ams::svc::Handle *out_handle, ams::svc::Size size, ams::svc::MemoryPermission owner_perm, ams::svc::MemoryPermission remote_perm) {
|
||||||
MESOSPHERE_PANIC("Stubbed SvcCreateSharedMemory64 was called.");
|
return CreateSharedMemory(out_handle, size, owner_perm, remote_perm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================= 64From32 ABI ============================= */
|
/* ============================= 64From32 ABI ============================= */
|
||||||
|
|
||||||
Result MapSharedMemory64From32(ams::svc::Handle shmem_handle, ams::svc::Address address, ams::svc::Size size, ams::svc::MemoryPermission map_perm) {
|
Result MapSharedMemory64From32(ams::svc::Handle shmem_handle, ams::svc::Address address, ams::svc::Size size, ams::svc::MemoryPermission map_perm) {
|
||||||
MESOSPHERE_PANIC("Stubbed SvcMapSharedMemory64From32 was called.");
|
return MapSharedMemory(shmem_handle, address, size, map_perm);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result UnmapSharedMemory64From32(ams::svc::Handle shmem_handle, ams::svc::Address address, ams::svc::Size size) {
|
Result UnmapSharedMemory64From32(ams::svc::Handle shmem_handle, ams::svc::Address address, ams::svc::Size size) {
|
||||||
MESOSPHERE_PANIC("Stubbed SvcUnmapSharedMemory64From32 was called.");
|
return UnmapSharedMemory(shmem_handle, address, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result CreateSharedMemory64From32(ams::svc::Handle *out_handle, ams::svc::Size size, ams::svc::MemoryPermission owner_perm, ams::svc::MemoryPermission remote_perm) {
|
Result CreateSharedMemory64From32(ams::svc::Handle *out_handle, ams::svc::Size size, ams::svc::MemoryPermission owner_perm, ams::svc::MemoryPermission remote_perm) {
|
||||||
MESOSPHERE_PANIC("Stubbed SvcCreateSharedMemory64From32 was called.");
|
return CreateSharedMemory(out_handle, size, owner_perm, remote_perm);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue