From 0644db02ad5d800fee4a3f7caad3cd0c8f5fbcdc Mon Sep 17 00:00:00 2001 From: Mary Date: Wed, 23 Jun 2021 21:52:11 +0200 Subject: kernel: Implement MapTransferMemory and UnmapTransferMemory (#2386) Based on my reversing of kernel 12.0.0 --- Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs | 86 ++++++++++++++++++++++++ 1 file changed, 86 insertions(+) (limited to 'Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs') diff --git a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs index b3e202b3..d65a373d 100644 --- a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs +++ b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs @@ -1095,6 +1095,92 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall return result; } + public KernelResult MapTransferMemory(int handle, ulong address, ulong size, KMemoryPermission permission) + { + if (!PageAligned(address)) + { + return KernelResult.InvalidAddress; + } + + if (!PageAligned(size) || size == 0) + { + return KernelResult.InvalidSize; + } + + if (address + size <= address) + { + return KernelResult.InvalidMemState; + } + + if (permission > KMemoryPermission.ReadAndWrite || permission == KMemoryPermission.Write) + { + return KernelResult.InvalidPermission; + } + + KProcess currentProcess = KernelStatic.GetCurrentProcess(); + + KTransferMemory transferMemory = currentProcess.HandleTable.GetObject(handle); + + if (transferMemory == null) + { + return KernelResult.InvalidHandle; + } + + if (currentProcess.MemoryManager.IsInvalidRegion(address, size) || + currentProcess.MemoryManager.InsideHeapRegion(address, size) || + currentProcess.MemoryManager.InsideAliasRegion(address, size)) + { + return KernelResult.InvalidMemRange; + } + + return transferMemory.MapIntoProcess( + currentProcess.MemoryManager, + address, + size, + currentProcess, + permission); + } + + public KernelResult UnmapTransferMemory(int handle, ulong address, ulong size) + { + if (!PageAligned(address)) + { + return KernelResult.InvalidAddress; + } + + if (!PageAligned(size) || size == 0) + { + return KernelResult.InvalidSize; + } + + if (address + size <= address) + { + return KernelResult.InvalidMemState; + } + + KProcess currentProcess = KernelStatic.GetCurrentProcess(); + + KTransferMemory transferMemory = currentProcess.HandleTable.GetObject(handle); + + if (transferMemory == null) + { + return KernelResult.InvalidHandle; + } + + if (currentProcess.MemoryManager.IsInvalidRegion(address, size) || + currentProcess.MemoryManager.InsideHeapRegion(address, size) || + currentProcess.MemoryManager.InsideAliasRegion(address, size)) + { + return KernelResult.InvalidMemRange; + } + + return transferMemory.UnmapFromProcess( + currentProcess.MemoryManager, + address, + size, + currentProcess); + } + public KernelResult MapPhysicalMemory(ulong address, ulong size) { if (!PageAligned(address)) -- cgit v1.2.3