From 08831eecf77cedd3c4192ebab5a9c485fb15d51e Mon Sep 17 00:00:00 2001
From: gdkchan <gab.dark.100@gmail.com>
Date: Wed, 4 Jan 2023 19:15:45 -0300
Subject: IPC refactor part 3+4: New server HIPC message processor (#4188)

* IPC refactor part 3 + 4: New server HIPC message processor with source generator based serialization

* Make types match on calls to AlignUp/AlignDown

* Formatting

* Address some PR feedback

* Move BitfieldExtensions to Ryujinx.Common.Utilities and consolidate implementations

* Rename Reader/Writer to SpanReader/SpanWriter and move to Ryujinx.Common.Memory

* Implement EventType

* Address more PR feedback

* Log request processing errors since they are not normal

* Rename waitable to multiwait and add missing lock

* PR feedback

* Ac_K PR feedback
---
 Ryujinx.HLE/HOS/ProgramLoader.cs | 69 +++++++++++++++++++++++++---------------
 1 file changed, 43 insertions(+), 26 deletions(-)

(limited to 'Ryujinx.HLE/HOS/ProgramLoader.cs')

diff --git a/Ryujinx.HLE/HOS/ProgramLoader.cs b/Ryujinx.HLE/HOS/ProgramLoader.cs
index beeb5ad6..b422fef7 100644
--- a/Ryujinx.HLE/HOS/ProgramLoader.cs
+++ b/Ryujinx.HLE/HOS/ProgramLoader.cs
@@ -9,6 +9,7 @@ using Ryujinx.HLE.HOS.Kernel.Common;
 using Ryujinx.HLE.HOS.Kernel.Memory;
 using Ryujinx.HLE.HOS.Kernel.Process;
 using Ryujinx.HLE.Loaders.Executables;
+using Ryujinx.Horizon.Common;
 using System;
 using System.Linq;
 using System.Runtime.InteropServices;
@@ -90,9 +91,9 @@ namespace Ryujinx.HLE.HOS
 
             KMemoryRegionManager region = context.MemoryManager.MemoryRegions[(int)memoryRegion];
 
-            KernelResult result = region.AllocatePages(out KPageList pageList, (ulong)codePagesCount);
+            Result result = region.AllocatePages(out KPageList pageList, (ulong)codePagesCount);
 
-            if (result != KernelResult.Success)
+            if (result != Result.Success)
             {
                 Logger.Error?.Print(LogClass.Loader, $"Process initialization returned error \"{result}\".");
 
@@ -111,7 +112,7 @@ namespace Ryujinx.HLE.HOS
                 memoryRegion,
                 processContextFactory);
 
-            if (result != KernelResult.Success)
+            if (result != Result.Success)
             {
                 Logger.Error?.Print(LogClass.Loader, $"Process initialization returned error \"{result}\".");
 
@@ -120,7 +121,7 @@ namespace Ryujinx.HLE.HOS
 
             result = LoadIntoMemory(process, kip, codeBaseAddress);
 
-            if (result != KernelResult.Success)
+            if (result != Result.Success)
             {
                 Logger.Error?.Print(LogClass.Loader, $"Process initialization returned error \"{result}\".");
 
@@ -131,7 +132,7 @@ namespace Ryujinx.HLE.HOS
 
             result = process.Start(kip.Priority, (ulong)kip.StackSize);
 
-            if (result != KernelResult.Success)
+            if (result != Result.Success)
             {
                 Logger.Error?.Print(LogClass.Loader, $"Process start returned error \"{result}\".");
 
@@ -230,19 +231,35 @@ namespace Ryujinx.HLE.HOS
 
             context.Device.System.LibHacHorizonManager.InitializeApplicationClient(new ProgramId(programInfo.ProgramId), in npdm);
 
-            KernelResult result;
+            Result result;
 
             KResourceLimit resourceLimit = new KResourceLimit(context);
 
             long applicationRgSize = (long)context.MemoryManager.MemoryRegions[(int)MemoryRegion.Application].Size;
 
-            result  = resourceLimit.SetLimitValue(LimitableResource.Memory,         applicationRgSize);
-            result |= resourceLimit.SetLimitValue(LimitableResource.Thread,         608);
-            result |= resourceLimit.SetLimitValue(LimitableResource.Event,          700);
-            result |= resourceLimit.SetLimitValue(LimitableResource.TransferMemory, 128);
-            result |= resourceLimit.SetLimitValue(LimitableResource.Session,        894);
+            result = resourceLimit.SetLimitValue(LimitableResource.Memory, applicationRgSize);
 
-            if (result != KernelResult.Success)
+            if (result.IsSuccess)
+            {
+                result = resourceLimit.SetLimitValue(LimitableResource.Thread, 608);
+            }
+
+            if (result.IsSuccess)
+            {
+                result = resourceLimit.SetLimitValue(LimitableResource.Event, 700);
+            }
+
+            if (result.IsSuccess)
+            {
+                result = resourceLimit.SetLimitValue(LimitableResource.TransferMemory, 128);
+            }
+
+            if (result.IsSuccess)
+            {
+                result = resourceLimit.SetLimitValue(LimitableResource.Session, 894);
+            }
+
+            if (result != Result.Success)
             {
                 Logger.Error?.Print(LogClass.Loader, $"Process initialization failed setting resource limit values.");
 
@@ -273,7 +290,7 @@ namespace Ryujinx.HLE.HOS
                 memoryRegion,
                 processContextFactory);
 
-            if (result != KernelResult.Success)
+            if (result != Result.Success)
             {
                 Logger.Error?.Print(LogClass.Loader, $"Process initialization returned error \"{result}\".");
 
@@ -288,7 +305,7 @@ namespace Ryujinx.HLE.HOS
 
                 result = LoadIntoMemory(process, executables[index], nsoBase[index]);
 
-                if (result != KernelResult.Success)
+                if (result != Result.Success)
                 {
                     Logger.Error?.Print(LogClass.Loader, $"Process initialization returned error \"{result}\".");
 
@@ -302,7 +319,7 @@ namespace Ryujinx.HLE.HOS
 
             result = process.Start(meta.MainThreadPriority, meta.MainThreadStackSize);
 
-            if (result != KernelResult.Success)
+            if (result != Result.Success)
             {
                 Logger.Error?.Print(LogClass.Loader, $"Process start returned error \"{result}\".");
 
@@ -322,18 +339,18 @@ namespace Ryujinx.HLE.HOS
             return true;
         }
 
-        private static KernelResult LoadIntoMemory(KProcess process, IExecutable image, ulong baseAddress)
+        private static Result LoadIntoMemory(KProcess process, IExecutable image, ulong baseAddress)
         {
-            ulong textStart = baseAddress + (ulong)image.TextOffset;
-            ulong roStart   = baseAddress + (ulong)image.RoOffset;
-            ulong dataStart = baseAddress + (ulong)image.DataOffset;
-            ulong bssStart  = baseAddress + (ulong)image.BssOffset;
+            ulong textStart = baseAddress + image.TextOffset;
+            ulong roStart   = baseAddress + image.RoOffset;
+            ulong dataStart = baseAddress + image.DataOffset;
+            ulong bssStart  = baseAddress + image.BssOffset;
 
             ulong end = dataStart + (ulong)image.Data.Length;
 
             if (image.BssSize != 0)
             {
-                end = bssStart + (ulong)image.BssSize;
+                end = bssStart + image.BssSize;
             }
 
             process.CpuMemory.Write(textStart, image.Text);
@@ -342,11 +359,11 @@ namespace Ryujinx.HLE.HOS
 
             process.CpuMemory.Fill(bssStart, image.BssSize, 0);
 
-            KernelResult SetProcessMemoryPermission(ulong address, ulong size, KMemoryPermission permission)
+            Result SetProcessMemoryPermission(ulong address, ulong size, KMemoryPermission permission)
             {
                 if (size == 0)
                 {
-                    return KernelResult.Success;
+                    return Result.Success;
                 }
 
                 size = BitUtils.AlignUp<ulong>(size, KPageTableBase.PageSize);
@@ -354,16 +371,16 @@ namespace Ryujinx.HLE.HOS
                 return process.MemoryManager.SetProcessMemoryPermission(address, size, permission);
             }
 
-            KernelResult result = SetProcessMemoryPermission(textStart, (ulong)image.Text.Length, KMemoryPermission.ReadAndExecute);
+            Result result = SetProcessMemoryPermission(textStart, (ulong)image.Text.Length, KMemoryPermission.ReadAndExecute);
 
-            if (result != KernelResult.Success)
+            if (result != Result.Success)
             {
                 return result;
             }
 
             result = SetProcessMemoryPermission(roStart, (ulong)image.Ro.Length, KMemoryPermission.Read);
 
-            if (result != KernelResult.Success)
+            if (result != Result.Success)
             {
                 return result;
             }
-- 
cgit v1.2.3-70-g09d2