aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.HLE/HOS/Kernel
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.HLE/HOS/Kernel')
-rw-r--r--Ryujinx.HLE/HOS/Kernel/KernelConstants.cs2
-rw-r--r--Ryujinx.HLE/HOS/Kernel/KernelContext.cs6
-rw-r--r--Ryujinx.HLE/HOS/Kernel/Process/HleProcessDebugger.cs2
-rw-r--r--Ryujinx.HLE/HOS/Kernel/Process/IProcessContext.cs5
-rw-r--r--Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs17
-rw-r--r--Ryujinx.HLE/HOS/Kernel/Process/ProcessContext.cs9
-rw-r--r--Ryujinx.HLE/HOS/Kernel/Process/ProcessExecutionContext.cs44
-rw-r--r--Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs2
-rw-r--r--Ryujinx.HLE/HOS/Kernel/SupervisorCall/SyscallHandler.cs14
-rw-r--r--Ryujinx.HLE/HOS/Kernel/SupervisorCall/SyscallTable.cs40
-rw-r--r--Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs30
11 files changed, 112 insertions, 59 deletions
diff --git a/Ryujinx.HLE/HOS/Kernel/KernelConstants.cs b/Ryujinx.HLE/HOS/Kernel/KernelConstants.cs
index 5a1dbef2..3817b0aa 100644
--- a/Ryujinx.HLE/HOS/Kernel/KernelConstants.cs
+++ b/Ryujinx.HLE/HOS/Kernel/KernelConstants.cs
@@ -12,5 +12,7 @@ namespace Ryujinx.HLE.HOS.Kernel
public const ulong UserSlabHeapBase = DramMemoryMap.SlabHeapBase;
public const ulong UserSlabHeapItemSize = KPageTableBase.PageSize;
public const ulong UserSlabHeapSize = 0x3de000;
+
+ public const ulong CounterFrequency = 19200000;
}
}
diff --git a/Ryujinx.HLE/HOS/Kernel/KernelContext.cs b/Ryujinx.HLE/HOS/Kernel/KernelContext.cs
index 4b8e4d15..6c58e197 100644
--- a/Ryujinx.HLE/HOS/Kernel/KernelContext.cs
+++ b/Ryujinx.HLE/HOS/Kernel/KernelContext.cs
@@ -1,4 +1,5 @@
-using Ryujinx.HLE.HOS.Kernel.Common;
+using Ryujinx.Cpu;
+using Ryujinx.HLE.HOS.Kernel.Common;
using Ryujinx.HLE.HOS.Kernel.Memory;
using Ryujinx.HLE.HOS.Kernel.Process;
using Ryujinx.HLE.HOS.Kernel.SupervisorCall;
@@ -23,6 +24,7 @@ namespace Ryujinx.HLE.HOS.Kernel
public Switch Device { get; }
public MemoryBlock Memory { get; }
+ public ITickSource TickSource { get; }
public Syscall Syscall { get; }
public SyscallHandler SyscallHandler { get; }
@@ -52,11 +54,13 @@ namespace Ryujinx.HLE.HOS.Kernel
private ulong _threadUid;
public KernelContext(
+ ITickSource tickSource,
Switch device,
MemoryBlock memory,
MemorySize memorySize,
MemoryArrange memoryArrange)
{
+ TickSource = tickSource;
Device = device;
Memory = memory;
diff --git a/Ryujinx.HLE/HOS/Kernel/Process/HleProcessDebugger.cs b/Ryujinx.HLE/HOS/Kernel/Process/HleProcessDebugger.cs
index e0cd4fbf..0a78a26d 100644
--- a/Ryujinx.HLE/HOS/Kernel/Process/HleProcessDebugger.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Process/HleProcessDebugger.cs
@@ -115,7 +115,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
string GetReg(int x)
{
- var v = x == 32 ? (ulong)thread.LastPc : context.GetX(x);
+ var v = x == 32 ? context.Pc : context.GetX(x);
if (!AnalyzePointer(out PointerInfo info, v, thread))
{
return $"0x{v:x16}";
diff --git a/Ryujinx.HLE/HOS/Kernel/Process/IProcessContext.cs b/Ryujinx.HLE/HOS/Kernel/Process/IProcessContext.cs
index 707e6d98..c8063a62 100644
--- a/Ryujinx.HLE/HOS/Kernel/Process/IProcessContext.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Process/IProcessContext.cs
@@ -1,4 +1,4 @@
-using ARMeilleure.State;
+using Ryujinx.Cpu;
using Ryujinx.Memory;
using System;
@@ -8,7 +8,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
{
IVirtualMemoryManager AddressSpace { get; }
- void Execute(ExecutionContext context, ulong codeAddress);
+ IExecutionContext CreateExecutionContext(ExceptionCallbacks exceptionCallbacks);
+ void Execute(IExecutionContext context, ulong codeAddress);
void InvalidateCacheRegion(ulong address, ulong size);
}
}
diff --git a/Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs b/Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs
index b10737b4..0caeacad 100644
--- a/Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs
@@ -1,4 +1,3 @@
-using ARMeilleure.State;
using Ryujinx.Common;
using Ryujinx.Common.Logging;
using Ryujinx.Cpu;
@@ -744,14 +743,16 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
}
}
- public void SubscribeThreadEventHandlers(ARMeilleure.State.ExecutionContext context)
+ public IExecutionContext CreateExecutionContext()
{
- context.Interrupt += InterruptHandler;
- context.SupervisorCall += KernelContext.SyscallHandler.SvcCall;
- context.Undefined += UndefinedInstructionHandler;
+ return Context?.CreateExecutionContext(new ExceptionCallbacks(
+ InterruptHandler,
+ null,
+ KernelContext.SyscallHandler.SvcCall,
+ UndefinedInstructionHandler));
}
- private void InterruptHandler(object sender, EventArgs e)
+ private void InterruptHandler(IExecutionContext context)
{
KThread currentThread = KernelStatic.GetCurrentThread();
@@ -1093,12 +1094,12 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
return false;
}
- private void UndefinedInstructionHandler(object sender, InstUndefinedEventArgs e)
+ private void UndefinedInstructionHandler(IExecutionContext context, ulong address, int opCode)
{
KernelStatic.GetCurrentThread().PrintGuestStackTrace();
KernelStatic.GetCurrentThread()?.PrintGuestRegisterPrintout();
- throw new UndefinedInstructionException(e.Address, e.OpCode);
+ throw new UndefinedInstructionException(address, opCode);
}
protected override void Destroy() => Context.Dispose();
diff --git a/Ryujinx.HLE/HOS/Kernel/Process/ProcessContext.cs b/Ryujinx.HLE/HOS/Kernel/Process/ProcessContext.cs
index bb3a1557..87296830 100644
--- a/Ryujinx.HLE/HOS/Kernel/Process/ProcessContext.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Process/ProcessContext.cs
@@ -1,4 +1,4 @@
-using ARMeilleure.State;
+using Ryujinx.Cpu;
using Ryujinx.Memory;
using System;
@@ -13,7 +13,12 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
AddressSpace = asManager;
}
- public void Execute(ExecutionContext context, ulong codeAddress)
+ public IExecutionContext CreateExecutionContext(ExceptionCallbacks exceptionCallbacks)
+ {
+ return new ProcessExecutionContext();
+ }
+
+ public void Execute(IExecutionContext context, ulong codeAddress)
{
throw new NotSupportedException();
}
diff --git a/Ryujinx.HLE/HOS/Kernel/Process/ProcessExecutionContext.cs b/Ryujinx.HLE/HOS/Kernel/Process/ProcessExecutionContext.cs
new file mode 100644
index 00000000..a0841252
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Kernel/Process/ProcessExecutionContext.cs
@@ -0,0 +1,44 @@
+using ARMeilleure.State;
+using Ryujinx.Cpu;
+
+namespace Ryujinx.HLE.HOS.Kernel.Process
+{
+ class ProcessExecutionContext : IExecutionContext
+ {
+ public ulong Pc => 0UL;
+
+ public ulong CntfrqEl0 { get => 0; set { } }
+ public ulong CntpctEl0 => 0UL;
+
+ public long TpidrEl0 { get => 0; set { } }
+ public long TpidrroEl0 { get => 0; set { } }
+
+ public uint Pstate { get => 0; set { } }
+
+ public uint Fpcr { get => 0; set { } }
+ public uint Fpsr { get => 0; set { } }
+
+ public bool IsAarch32 { get => false; set { } }
+
+ public bool Running { get; private set; } = true;
+
+ public ulong GetX(int index) => 0UL;
+ public void SetX(int index, ulong value) { }
+
+ public V128 GetV(int index) => default;
+ public void SetV(int index, V128 value) { }
+
+ public void RequestInterrupt()
+ {
+ }
+
+ public void StopRunning()
+ {
+ Running = false;
+ }
+
+ public void Dispose()
+ {
+ }
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs
index d9d492a5..571699d9 100644
--- a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs
+++ b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs
@@ -1755,7 +1755,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
public ulong GetSystemTick()
{
- return KernelStatic.GetCurrentThread().Context.CntpctEl0;
+ return _context.TickSource.Counter;
}
public void Break(ulong reason)
diff --git a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SyscallHandler.cs b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SyscallHandler.cs
index 5e795d35..cb693f59 100644
--- a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SyscallHandler.cs
+++ b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SyscallHandler.cs
@@ -1,4 +1,4 @@
-using ARMeilleure.State;
+using Ryujinx.Cpu;
using Ryujinx.HLE.HOS.Kernel.Threading;
using System;
@@ -17,7 +17,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
_syscall64 = new Syscall64(context.Syscall);
}
- public void SvcCall(object sender, InstExceptionEventArgs e)
+ public void SvcCall(IExecutionContext context, ulong address, int id)
{
KThread currentThread = KernelStatic.GetCurrentThread();
@@ -34,26 +34,24 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
_context.CriticalSection.Leave();
}
- ExecutionContext context = (ExecutionContext)sender;
-
if (context.IsAarch32)
{
- var svcFunc = SyscallTable.SvcTable32[e.Id];
+ var svcFunc = SyscallTable.SvcTable32[id];
if (svcFunc == null)
{
- throw new NotImplementedException($"SVC 0x{e.Id:X4} is not implemented.");
+ throw new NotImplementedException($"SVC 0x{id:X4} is not implemented.");
}
svcFunc(_syscall32, context);
}
else
{
- var svcFunc = SyscallTable.SvcTable64[e.Id];
+ var svcFunc = SyscallTable.SvcTable64[id];
if (svcFunc == null)
{
- throw new NotImplementedException($"SVC 0x{e.Id:X4} is not implemented.");
+ throw new NotImplementedException($"SVC 0x{id:X4} is not implemented.");
}
svcFunc(_syscall64, context);
diff --git a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SyscallTable.cs b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SyscallTable.cs
index 6e0b7010..8b7e7fb8 100644
--- a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SyscallTable.cs
+++ b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SyscallTable.cs
@@ -1,5 +1,5 @@
-using ARMeilleure.State;
using Ryujinx.Common.Logging;
+using Ryujinx.Cpu;
using Ryujinx.HLE.HOS.Kernel.Common;
using System;
using System.Collections.Generic;
@@ -14,13 +14,13 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
private const int SvcFuncMaxArguments32 = 4;
private const int SvcMax = 0x80;
- public static Action<Syscall32, ExecutionContext>[] SvcTable32 { get; }
- public static Action<Syscall64, ExecutionContext>[] SvcTable64 { get; }
+ public static Action<Syscall32, IExecutionContext>[] SvcTable32 { get; }
+ public static Action<Syscall64, IExecutionContext>[] SvcTable64 { get; }
static SyscallTable()
{
- SvcTable32 = new Action<Syscall32, ExecutionContext>[SvcMax];
- SvcTable64 = new Action<Syscall64, ExecutionContext>[SvcMax];
+ SvcTable32 = new Action<Syscall32, IExecutionContext>[SvcMax];
+ SvcTable64 = new Action<Syscall64, IExecutionContext>[SvcMax];
Dictionary<int, string> svcFuncs64 = new Dictionary<int, string>
{
@@ -182,9 +182,9 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
}
}
- private static Action<T, ExecutionContext> GenerateMethod<T>(string svcName, int registerCleanCount)
+ private static Action<T, IExecutionContext> GenerateMethod<T>(string svcName, int registerCleanCount)
{
- Type[] argTypes = new Type[] { typeof(T), typeof(ExecutionContext) };
+ Type[] argTypes = new Type[] { typeof(T), typeof(IExecutionContext) };
DynamicMethod method = new DynamicMethod(svcName, null, argTypes);
@@ -292,9 +292,9 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
generator.Emit(OpCodes.Ldarg_1);
generator.Emit(OpCodes.Ldc_I4, registerAttribute.Index);
- MethodInfo info = typeof(ExecutionContext).GetMethod(nameof(ExecutionContext.GetX));
+ MethodInfo info = typeof(IExecutionContext).GetMethod(nameof(IExecutionContext.GetX));
- generator.Emit(OpCodes.Call, info);
+ generator.Emit(OpCodes.Callvirt, info);
generator.Emit(OpCodes.Box, typeof(ulong));
@@ -339,9 +339,9 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
generator.Emit(OpCodes.Ldarg_1);
generator.Emit(OpCodes.Ldc_I4, registerAttribute.Index);
- MethodInfo info = typeof(ExecutionContext).GetMethod(nameof(ExecutionContext.GetX));
+ MethodInfo info = typeof(IExecutionContext).GetMethod(nameof(IExecutionContext.GetX));
- generator.Emit(OpCodes.Call, info);
+ generator.Emit(OpCodes.Callvirt, info);
ConvertToArgType(argType);
@@ -355,9 +355,9 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
generator.Emit(OpCodes.Ldarg_1);
generator.Emit(OpCodes.Ldc_I4, registerAttribute.Index);
- MethodInfo info = typeof(ExecutionContext).GetMethod(nameof(ExecutionContext.GetX));
+ MethodInfo info = typeof(IExecutionContext).GetMethod(nameof(IExecutionContext.GetX));
- generator.Emit(OpCodes.Call, info);
+ generator.Emit(OpCodes.Callvirt, info);
ConvertToArgType(argType);
}
@@ -393,9 +393,9 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
ConvertToFieldType(retType);
- MethodInfo info = typeof(ExecutionContext).GetMethod(nameof(ExecutionContext.SetX));
+ MethodInfo info = typeof(IExecutionContext).GetMethod(nameof(IExecutionContext.SetX));
- generator.Emit(OpCodes.Call, info);
+ generator.Emit(OpCodes.Callvirt, info);
registerInUse |= 1u << 0;
}
@@ -415,9 +415,9 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
ConvertToFieldType(local.LocalType);
- MethodInfo info = typeof(ExecutionContext).GetMethod(nameof(ExecutionContext.SetX));
+ MethodInfo info = typeof(IExecutionContext).GetMethod(nameof(IExecutionContext.SetX));
- generator.Emit(OpCodes.Call, info);
+ generator.Emit(OpCodes.Callvirt, info);
registerInUse |= 1u << attribute.Index;
}
@@ -434,14 +434,14 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
generator.Emit(OpCodes.Ldc_I4, i);
generator.Emit(OpCodes.Ldc_I8, 0L);
- MethodInfo info = typeof(ExecutionContext).GetMethod(nameof(ExecutionContext.SetX));
+ MethodInfo info = typeof(IExecutionContext).GetMethod(nameof(IExecutionContext.SetX));
- generator.Emit(OpCodes.Call, info);
+ generator.Emit(OpCodes.Callvirt, info);
}
generator.Emit(OpCodes.Ret);
- return method.CreateDelegate<Action<T, ExecutionContext>>();
+ return method.CreateDelegate<Action<T, IExecutionContext>>();
}
private static void CheckIfTypeIsSupported(Type type, string svcName)
diff --git a/Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs b/Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs
index ee701a69..b9dd91ef 100644
--- a/Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs
@@ -23,7 +23,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
public Thread HostThread { get; private set; }
- public ARMeilleure.State.ExecutionContext Context { get; private set; }
+ public IExecutionContext Context { get; private set; }
public KThreadContext ThreadContext { get; private set; }
@@ -115,9 +115,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
public bool WaitingInArbitration { get; set; }
- public long LastPc { get; set; }
-
- private object ActivityOperationLock = new object();
+ private object _activityOperationLock;
public KThread(KernelContext context) : base(context)
{
@@ -128,6 +126,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
_mutexWaiters = new LinkedList<KThread>();
_pinnedWaiters = new LinkedList<KThread>();
+
+ _activityOperationLock = new object();
}
public KernelResult Initialize(
@@ -192,7 +192,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
HostThread = new Thread(ThreadStart);
- Context = CpuContext.CreateExecutionContext();
+ Context = owner?.CreateExecutionContext() ?? new ProcessExecutionContext();
Context.IsAarch32 = !is64Bits;
@@ -208,8 +208,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
Context.SetX(13, (uint)stackTop);
}
- Context.CntfrqEl0 = 19200000;
- Context.Tpidr = (long)_tlsAddress;
+ Context.TpidrroEl0 = (long)_tlsAddress;
ThreadUid = KernelContext.NewThreadUid();
@@ -221,7 +220,6 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
if (owner != null)
{
- owner.SubscribeThreadEventHandlers(Context);
owner.AddThread(this);
if (owner.IsPaused)
@@ -538,7 +536,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
public KernelResult SetActivity(bool pause)
{
- lock (ActivityOperationLock)
+ lock (_activityOperationLock)
{
KernelResult result = KernelResult.Success;
@@ -634,7 +632,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
{
context = default;
- lock (ActivityOperationLock)
+ lock (_activityOperationLock)
{
KernelContext.CriticalSection.Enter();
@@ -656,7 +654,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
return KernelResult.Success;
}
- private static uint GetPsr(ARMeilleure.State.ExecutionContext context)
+ private static uint GetPsr(IExecutionContext context)
{
return context.Pstate & 0xFF0FFE20;
}
@@ -683,9 +681,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
context.Fp = Context.GetX(29);
context.Lr = Context.GetX(30);
context.Sp = Context.GetX(31);
- context.Pc = (ulong)LastPc;
+ context.Pc = Context.Pc;
context.Pstate = GetPsr(Context);
- context.Tpidr = (ulong)Context.Tpidr;
+ context.Tpidr = (ulong)Context.TpidrroEl0;
}
else
{
@@ -699,9 +697,9 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
context.FpuRegisters[i] = Context.GetV(i);
}
- context.Pc = (uint)LastPc;
+ context.Pc = (uint)Context.Pc;
context.Pstate = GetPsr(Context);
- context.Tpidr = (uint)Context.Tpidr;
+ context.Tpidr = (uint)Context.TpidrroEl0;
}
context.Fpcr = (uint)Context.Fpcr;
@@ -743,7 +741,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
public KernelResult SetCoreAndAffinityMask(int newCore, ulong newAffinityMask)
{
- lock (ActivityOperationLock)
+ lock (_activityOperationLock)
{
KernelContext.CriticalSection.Enter();