mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-21 12:32:40 +02:00
Introducing shmem
This commit is contained in:
parent
96dc3a4ff0
commit
6280e1ba58
@ -15,6 +15,7 @@ extern "C" {
|
|||||||
#include <switch/os.h>
|
#include <switch/os.h>
|
||||||
|
|
||||||
#include <switch/kernel/tmem.h>
|
#include <switch/kernel/tmem.h>
|
||||||
|
#include <switch/kernel/shmem.h>
|
||||||
#include <switch/kernel/mutex.h>
|
#include <switch/kernel/mutex.h>
|
||||||
#include <switch/kernel/thread.h>
|
#include <switch/kernel/thread.h>
|
||||||
#include <switch/kernel/virtmem.h>
|
#include <switch/kernel/virtmem.h>
|
||||||
|
15
nx/include/switch/kernel/shmem.h
Normal file
15
nx/include/switch/kernel/shmem.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
typedef struct {
|
||||||
|
Handle MemHandle;
|
||||||
|
size_t Size;
|
||||||
|
Permission Perm;
|
||||||
|
void* MappedAddr;
|
||||||
|
} SharedMemory;
|
||||||
|
|
||||||
|
Result shmemCreate(SharedMemory* s, size_t size, Permission local_perm, Permission remote_perm);
|
||||||
|
void shmemLoadRemote(SharedMemory* t, Handle handle, size_t size, Permission perm);
|
||||||
|
|
||||||
|
Result shmemMap(SharedMemory* t);
|
||||||
|
Result shmemUnmap(SharedMemory* t);
|
||||||
|
void* shmemGetAddr(SharedMemory* t);
|
||||||
|
|
||||||
|
Result shmemClose(SharedMemory* t);
|
@ -19,25 +19,18 @@ static inline void* armGetTls(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u64 base_addr;
|
u64 base_addr;
|
||||||
u64 size;
|
u64 size;
|
||||||
u32 memorytype;
|
u32 memorytype;
|
||||||
u32 memoryattribute;
|
u32 memoryattribute;
|
||||||
u32 perm;
|
u32 perm;
|
||||||
u32 devicerefcount;
|
u32 devicerefcount;
|
||||||
u32 ipcrefcount;
|
u32 ipcrefcount;
|
||||||
u32 padding;
|
u32 padding;
|
||||||
} MemInfo;
|
} MemInfo;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u64 X0;
|
u64 X[8];
|
||||||
u64 X1;
|
|
||||||
u64 X2;
|
|
||||||
u64 X3;
|
|
||||||
u64 X4;
|
|
||||||
u64 X5;
|
|
||||||
u64 X6;
|
|
||||||
u64 X7;
|
|
||||||
} __attribute__((packed)) SecmonArgs;
|
} __attribute__((packed)) SecmonArgs;
|
||||||
|
|
||||||
Result svcSetHeapSize(void** out_addr, u64 size);
|
Result svcSetHeapSize(void** out_addr, u64 size);
|
||||||
@ -51,6 +44,8 @@ void NORETURN svcExitThread();
|
|||||||
Result svcSleepThread(u64 nano);
|
Result svcSleepThread(u64 nano);
|
||||||
Result svcClearEvent(Handle handle);
|
Result svcClearEvent(Handle handle);
|
||||||
Result svcCloseHandle(Handle handle);
|
Result svcCloseHandle(Handle handle);
|
||||||
|
Result svcMapSharedMemory(Handle handle, void* addr, size_t size, u32 perm);
|
||||||
|
Result svcUnmapSharedMemory(Handle handle, void* addr, size_t size);
|
||||||
Result svcCreateTransferMemory(Handle* out, void* addr, size_t size, u32 perm);
|
Result svcCreateTransferMemory(Handle* out, void* addr, size_t size, u32 perm);
|
||||||
Result svcWaitSynchronization(s32* index, const Handle* handles, s32 handleCount, u64 timeout);
|
Result svcWaitSynchronization(s32* index, const Handle* handles, s32 handleCount, u64 timeout);
|
||||||
Result svcArbitrateLock(u32 wait_tag, u32* tag_location, u32 self_tag);
|
Result svcArbitrateLock(u32 wait_tag, u32* tag_location, u32 self_tag);
|
||||||
@ -62,6 +57,7 @@ Result svcGetInfo(u64* out, u64 id0, Handle handle, u64 id1);
|
|||||||
Result svcCreateSession(Handle *server_handle, Handle *client_handle, u32 unk0, u64 unk1);//unk* are normally 0?
|
Result svcCreateSession(Handle *server_handle, Handle *client_handle, u32 unk0, u64 unk1);//unk* are normally 0?
|
||||||
Result svcAcceptSession(Handle *session_handle, Handle port_handle);
|
Result svcAcceptSession(Handle *session_handle, Handle port_handle);
|
||||||
Result svcReplyAndReceive(s32* index, const Handle* handles, s32 handleCount, Handle replyTarget, u64 timeout);
|
Result svcReplyAndReceive(s32* index, const Handle* handles, s32 handleCount, Handle replyTarget, u64 timeout);
|
||||||
|
Result svcCreateSharedMemory(Handle* out, size_t size, u32 local_perm, u32 other_perm);
|
||||||
Result svcMapTransferMemory(Handle tmem_handle, void* addr, size_t size, u32 perm);
|
Result svcMapTransferMemory(Handle tmem_handle, void* addr, size_t size, u32 perm);
|
||||||
Result svcUnmapTransferMemory(Handle tmem_handle, void* addr, size_t size);
|
Result svcUnmapTransferMemory(Handle tmem_handle, void* addr, size_t size);
|
||||||
Result svcQueryPhysicalAddress(u64 out[3], u64 virtaddr);
|
Result svcQueryPhysicalAddress(u64 out[3], u64 virtaddr);
|
||||||
|
85
nx/source/kernel/shmem.c
Normal file
85
nx/source/kernel/shmem.c
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
// Copyright 2017 plutoo
|
||||||
|
#include <switch.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
|
||||||
|
Result shmemCreate(SharedMemory* s, size_t size, Permission local_perm, Permission remote_perm)
|
||||||
|
{
|
||||||
|
Result rc;
|
||||||
|
|
||||||
|
s->MemHandle = INVALID_HANDLE;
|
||||||
|
s->Size = size;
|
||||||
|
s->MappedAddr = NULL;
|
||||||
|
s->Perm = local_perm;
|
||||||
|
|
||||||
|
rc = svcCreateSharedMemory(&s->MemHandle, size, local_perm, remote_perm);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void shmemLoadRemote(SharedMemory* s, Handle handle, size_t size, Permission perm)
|
||||||
|
{
|
||||||
|
s->MemHandle = handle;
|
||||||
|
s->Size = size;
|
||||||
|
s->MappedAddr = NULL;
|
||||||
|
s->Perm = perm;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result shmemMap(SharedMemory* s)
|
||||||
|
{
|
||||||
|
Result rc = 0;
|
||||||
|
|
||||||
|
if (s->MappedAddr == NULL)
|
||||||
|
{
|
||||||
|
void* addr = virtmemReserve(s->Size);
|
||||||
|
|
||||||
|
rc = svcMapSharedMemory(s->MemHandle, addr, s->Size, s->Perm);
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
s->MappedAddr = addr;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
virtmemFree(addr, s->Size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rc = LIBNX_ALREADYMAPPED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result shmemUnmap(SharedMemory* s)
|
||||||
|
{
|
||||||
|
Result rc;
|
||||||
|
|
||||||
|
rc = svcUnmapSharedMemory(s->MemHandle, s->MappedAddr, s->Size);
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
s->MappedAddr = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* shmemGetAddr(SharedMemory* s) {
|
||||||
|
return s->MappedAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result shmemClose(SharedMemory* s)
|
||||||
|
{
|
||||||
|
Result rc = 0;
|
||||||
|
|
||||||
|
if (s->MappedAddr != NULL) {
|
||||||
|
rc = shmemUnmap(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
if (s->MemHandle != INVALID_HANDLE) {
|
||||||
|
rc = svcCloseHandle(s->MemHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
s->MemHandle = INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
@ -71,8 +71,13 @@ SVC_BEGIN svcClearEvent
|
|||||||
ret
|
ret
|
||||||
SVC_END
|
SVC_END
|
||||||
|
|
||||||
SVC_BEGIN svcCloseHandle
|
SVC_BEGIN svcMapSharedMemory
|
||||||
svc 0x16
|
svc 0x13
|
||||||
|
ret
|
||||||
|
SVC_END
|
||||||
|
|
||||||
|
SVC_BEGIN svcUnmapSharedMemory
|
||||||
|
svc 0x14
|
||||||
ret
|
ret
|
||||||
SVC_END
|
SVC_END
|
||||||
|
|
||||||
@ -84,6 +89,11 @@ SVC_BEGIN svcCreateTransferMemory
|
|||||||
ret
|
ret
|
||||||
SVC_END
|
SVC_END
|
||||||
|
|
||||||
|
SVC_BEGIN svcCloseHandle
|
||||||
|
svc 0x16
|
||||||
|
ret
|
||||||
|
SVC_END
|
||||||
|
|
||||||
SVC_BEGIN svcWaitSynchronization
|
SVC_BEGIN svcWaitSynchronization
|
||||||
str x0, [sp, #-16]!
|
str x0, [sp, #-16]!
|
||||||
svc 0x18
|
svc 0x18
|
||||||
@ -152,6 +162,14 @@ SVC_BEGIN svcReplyAndReceive
|
|||||||
ret
|
ret
|
||||||
SVC_END
|
SVC_END
|
||||||
|
|
||||||
|
SVC_BEGIN svcCreateSharedMemory
|
||||||
|
str x0, [sp, #-16]!
|
||||||
|
svc 0x50
|
||||||
|
ldr x2, [sp], #16
|
||||||
|
str w1, [x2]
|
||||||
|
ret
|
||||||
|
SVC_END
|
||||||
|
|
||||||
SVC_BEGIN svcMapTransferMemory
|
SVC_BEGIN svcMapTransferMemory
|
||||||
svc 0x51
|
svc 0x51
|
||||||
ret
|
ret
|
||||||
|
Loading…
Reference in New Issue
Block a user