aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.HLE/HOS/Kernel/KMemoryManager.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.HLE/HOS/Kernel/KMemoryManager.cs')
-rw-r--r--Ryujinx.HLE/HOS/Kernel/KMemoryManager.cs98
1 files changed, 98 insertions, 0 deletions
diff --git a/Ryujinx.HLE/HOS/Kernel/KMemoryManager.cs b/Ryujinx.HLE/HOS/Kernel/KMemoryManager.cs
index 3afdb570..8871cbe7 100644
--- a/Ryujinx.HLE/HOS/Kernel/KMemoryManager.cs
+++ b/Ryujinx.HLE/HOS/Kernel/KMemoryManager.cs
@@ -148,6 +148,92 @@ namespace Ryujinx.HLE.HOS.Kernel
}
}
+ public long MapProcessCodeMemory(long Dst, long Src, long Size)
+ {
+ lock (Blocks)
+ {
+ long PagesCount = Size / PageSize;
+
+ bool Success = IsUnmapped(Dst, Size);
+
+ Success &= CheckRange(
+ Src,
+ Size,
+ MemoryState.Mask,
+ MemoryState.Heap,
+ MemoryPermission.Mask,
+ MemoryPermission.ReadAndWrite,
+ MemoryAttribute.Mask,
+ MemoryAttribute.None,
+ MemoryAttribute.IpcAndDeviceMapped,
+ out _,
+ out _,
+ out _);
+
+ if (Success)
+ {
+ long PA = CpuMemory.GetPhysicalAddress(Src);
+
+ InsertBlock(Dst, PagesCount, MemoryState.CodeStatic, MemoryPermission.ReadAndExecute);
+ InsertBlock(Src, PagesCount, MemoryState.Heap, MemoryPermission.None);
+
+ CpuMemory.Map(Dst, PA, Size);
+
+ return 0;
+ }
+ }
+
+ return MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
+ }
+
+ public long UnmapProcessCodeMemory(long Dst, long Src, long Size)
+ {
+ lock (Blocks)
+ {
+ long PagesCount = Size / PageSize;
+
+ bool Success = CheckRange(
+ Dst,
+ Size,
+ MemoryState.Mask,
+ MemoryState.CodeStatic,
+ MemoryPermission.None,
+ MemoryPermission.None,
+ MemoryAttribute.Mask,
+ MemoryAttribute.None,
+ MemoryAttribute.IpcAndDeviceMapped,
+ out _,
+ out _,
+ out _);
+
+ Success &= CheckRange(
+ Src,
+ Size,
+ MemoryState.Mask,
+ MemoryState.Heap,
+ MemoryPermission.Mask,
+ MemoryPermission.None,
+ MemoryAttribute.Mask,
+ MemoryAttribute.None,
+ MemoryAttribute.IpcAndDeviceMapped,
+ out _,
+ out _,
+ out _);
+
+ if (Success)
+ {
+ InsertBlock(Dst, PagesCount, MemoryState.Unmapped);
+ InsertBlock(Src, PagesCount, MemoryState.Heap, MemoryPermission.ReadAndWrite);
+
+ CpuMemory.Unmap(Dst, Size);
+
+ return 0;
+ }
+ }
+
+ return MakeError(ErrorModule.Kernel, KernelErr.NoAccessPerm);
+ }
+
public void HleMapCustom(long Position, long Size, MemoryState State, MemoryPermission Permission)
{
long PagesCount = Size / PageSize;
@@ -755,6 +841,18 @@ namespace Ryujinx.HLE.HOS.Kernel
}
}
+ public bool HleIsUnmapped(long Position, long Size)
+ {
+ bool Result = false;
+
+ lock (Blocks)
+ {
+ Result = IsUnmapped(Position, Size);
+ }
+
+ return Result;
+ }
+
private bool IsUnmapped(long Position, long Size)
{
return CheckRange(