diff options
Diffstat (limited to 'Ryujinx.HLE/HOS/Kernel')
-rw-r--r-- | Ryujinx.HLE/HOS/Kernel/KernelConstants.cs | 2 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Kernel/KernelContext.cs | 6 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Kernel/Process/HleProcessDebugger.cs | 2 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Kernel/Process/IProcessContext.cs | 5 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs | 17 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Kernel/Process/ProcessContext.cs | 9 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Kernel/Process/ProcessExecutionContext.cs | 44 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs | 2 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Kernel/SupervisorCall/SyscallHandler.cs | 14 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Kernel/SupervisorCall/SyscallTable.cs | 40 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs | 30 |
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(); |