aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs')
-rw-r--r--Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs86
1 files changed, 86 insertions, 0 deletions
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<KTransferMemory>(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<KTransferMemory>(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))