0
0
Fork 0

Rename ARegisters to AThreadState

This commit is contained in:
gdkchan 2018-02-18 16:28:07 -03:00
parent 5a0396efaf
commit f35d286c8d
25 changed files with 303 additions and 301 deletions

View file

@ -33,7 +33,7 @@ namespace Ryujinx.Tests.Cpu
private void Execute(AThread Thread) private void Execute(AThread Thread)
{ {
AutoResetEvent Wait = new AutoResetEvent(false); AutoResetEvent Wait = new AutoResetEvent(false);
Thread.Registers.Break += (sender, e) => Thread.StopExecution(); Thread.ThreadState.Break += (sender, e) => Thread.StopExecution();
Thread.WorkFinished += (sender, e) => Wait.Set(); Thread.WorkFinished += (sender, e) => Wait.Set();
Wait.Reset(); Wait.Reset();
@ -41,23 +41,23 @@ namespace Ryujinx.Tests.Cpu
Wait.WaitOne(); Wait.WaitOne();
} }
private ARegisters SingleOpcode(uint Opcode, private AThreadState SingleOpcode(uint Opcode,
ulong X0 = 0, ulong X1 = 0, ulong X2 = 0, ulong X0 = 0, ulong X1 = 0, ulong X2 = 0,
AVec V0 = new AVec(), AVec V1 = new AVec(), AVec V2 = new AVec()) AVec V0 = new AVec(), AVec V1 = new AVec(), AVec V2 = new AVec())
{ {
Memory.WriteUInt32(0x1000, Opcode); Memory.WriteUInt32(0x1000, Opcode);
Memory.WriteUInt32(0x1004, 0xD4200000); // BRK #0 Memory.WriteUInt32(0x1004, 0xD4200000); // BRK #0
Memory.WriteUInt32(0x1008, 0xD65F03C0); // RET Memory.WriteUInt32(0x1008, 0xD65F03C0); // RET
AThread Thread = new AThread(Memory, ThreadPriority.Normal, 0x1000); AThread Thread = new AThread(Memory, ThreadPriority.Normal, 0x1000);
Thread.Registers.X0 = X0; Thread.ThreadState.X0 = X0;
Thread.Registers.X1 = X1; Thread.ThreadState.X1 = X1;
Thread.Registers.X2 = X2; Thread.ThreadState.X2 = X2;
Thread.Registers.V0 = V0; Thread.ThreadState.V0 = V0;
Thread.Registers.V1 = V1; Thread.ThreadState.V1 = V1;
Thread.Registers.V2 = V2; Thread.ThreadState.V2 = V2;
Execute(Thread); Execute(Thread);
return Thread.Registers; return Thread.ThreadState;
} }
[Test] [Test]

View file

@ -10,8 +10,8 @@ namespace Ryujinx.Tests.Cpu
public void Add() public void Add()
{ {
// ADD X0, X1, X2 // ADD X0, X1, X2
ARegisters Registers = SingleOpcode(0x8B020020, X1: 1, X2: 2); AThreadState ThreadState = SingleOpcode(0x8B020020, X1: 1, X2: 2);
Assert.AreEqual(3, Registers.X0); Assert.AreEqual(3, ThreadState.X0);
} }
[Test] [Test]
@ -28,10 +28,10 @@ namespace Ryujinx.Tests.Cpu
foreach (var test in tests) foreach (var test in tests)
{ {
ARegisters Registers = SingleOpcode(Opcode, X1: test.W1, X2: test.W2); AThreadState ThreadState = SingleOpcode(Opcode, X1: test.W1, X2: test.W2);
Assert.AreEqual(test.Result, Registers.X0); Assert.AreEqual(test.Result, ThreadState.X0);
Assert.AreEqual(test.Negative, Registers.Negative); Assert.AreEqual(test.Negative, ThreadState.Negative);
Assert.AreEqual(test.Zero, Registers.Zero); Assert.AreEqual(test.Zero, ThreadState.Zero);
} }
} }
@ -50,16 +50,16 @@ namespace Ryujinx.Tests.Cpu
public void RevX0X0() public void RevX0X0()
{ {
// REV X0, X0 // REV X0, X0
ARegisters Registers = SingleOpcode(0xDAC00C00, X0: 0xAABBCCDDEEFF1100); AThreadState ThreadState = SingleOpcode(0xDAC00C00, X0: 0xAABBCCDDEEFF1100);
Assert.AreEqual(0x0011FFEEDDCCBBAA, Registers.X0); Assert.AreEqual(0x0011FFEEDDCCBBAA, ThreadState.X0);
} }
[Test] [Test]
public void RevW1W1() public void RevW1W1()
{ {
// REV W1, W1 // REV W1, W1
ARegisters Registers = SingleOpcode(0x5AC00821, X1: 0x12345678); AThreadState ThreadState = SingleOpcode(0x5AC00821, X1: 0x12345678);
Assert.AreEqual(0x78563412, Registers.X1); Assert.AreEqual(0x78563412, ThreadState.X1);
} }
} }
} }

View file

@ -7,7 +7,7 @@ namespace ChocolArm64
{ {
public class AThread public class AThread
{ {
public ARegisters Registers { get; private set; } public AThreadState ThreadState { get; private set; }
public AMemory Memory { get; private set; } public AMemory Memory { get; private set; }
public long EntryPoint { get; private set; } public long EntryPoint { get; private set; }
@ -20,7 +20,7 @@ namespace ChocolArm64
public event EventHandler WorkFinished; public event EventHandler WorkFinished;
public int ThreadId => Registers.ThreadId; public int ThreadId => ThreadState.ThreadId;
public bool IsAlive => Work.IsAlive; public bool IsAlive => Work.IsAlive;
@ -34,7 +34,7 @@ namespace ChocolArm64
this.Priority = Priority; this.Priority = Priority;
this.EntryPoint = EntryPoint; this.EntryPoint = EntryPoint;
Registers = new ARegisters(); ThreadState = new AThreadState();
Translator = new ATranslator(this); Translator = new ATranslator(this);
ExecuteLock = new object(); ExecuteLock = new object();
} }

View file

@ -9,7 +9,7 @@ namespace ChocolArm64
{ {
class ATranslatedSub class ATranslatedSub
{ {
private delegate long AA64Subroutine(ARegisters Register, AMemory Memory); private delegate long AA64Subroutine(AThreadState Register, AMemory Memory);
private AA64Subroutine ExecDelegate; private AA64Subroutine ExecDelegate;
@ -17,8 +17,8 @@ namespace ChocolArm64
public static Type[] FixedArgTypes { get; private set; } public static Type[] FixedArgTypes { get; private set; }
public static int RegistersArgIdx { get; private set; } public static int StateArgIdx { get; private set; }
public static int MemoryArgIdx { get; private set; } public static int MemoryArgIdx { get; private set; }
public DynamicMethod Method { get; private set; } public DynamicMethod Method { get; private set; }
@ -58,9 +58,9 @@ namespace ChocolArm64
FixedArgTypes[Index] = ParamType; FixedArgTypes[Index] = ParamType;
if (ParamType == typeof(ARegisters)) if (ParamType == typeof(AThreadState))
{ {
RegistersArgIdx = Index; StateArgIdx = Index;
} }
else if (ParamType == typeof(AMemory)) else if (ParamType == typeof(AMemory))
{ {
@ -69,7 +69,7 @@ namespace ChocolArm64
} }
} }
public long Execute(ARegisters Registers, AMemory Memory) public long Execute(AThreadState ThreadState, AMemory Memory)
{ {
if (!HasDelegate) if (!HasDelegate)
{ {
@ -83,7 +83,7 @@ namespace ChocolArm64
foreach (ARegister Reg in Params) foreach (ARegister Reg in Params)
{ {
Generator.EmitLdarg(RegistersArgIdx); Generator.EmitLdarg(StateArgIdx);
Generator.Emit(OpCodes.Ldfld, Reg.GetField()); Generator.Emit(OpCodes.Ldfld, Reg.GetField());
} }
@ -96,7 +96,7 @@ namespace ChocolArm64
HasDelegate = true; HasDelegate = true;
} }
return ExecDelegate(Registers, Memory); return ExecDelegate(ThreadState, Memory);
} }
public void MarkForReJit() => NeedsReJit = true; public void MarkForReJit() => NeedsReJit = true;

View file

@ -31,11 +31,11 @@ namespace ChocolArm64
{ {
if (CachedSubs.TryGetValue(Position, out ATranslatedSub Sub) && !Sub.NeedsReJit) if (CachedSubs.TryGetValue(Position, out ATranslatedSub Sub) && !Sub.NeedsReJit)
{ {
Position = Sub.Execute(Thread.Registers, Thread.Memory); Position = Sub.Execute(Thread.ThreadState, Thread.Memory);
} }
else else
{ {
Position = TranslateSubroutine(Position).Execute(Thread.Registers, Thread.Memory); Position = TranslateSubroutine(Position).Execute(Thread.ThreadState, Thread.Memory);
} }
} }
while (Position != 0 && KeepRunning); while (Position != 0 && KeepRunning);

View file

@ -25,7 +25,7 @@ namespace ChocolArm64.Decoder
Cond = (ACond)((OpCode >> 12) & 0xf); Cond = (ACond)((OpCode >> 12) & 0xf);
RmImm = (OpCode >> 16) & 0x1f; RmImm = (OpCode >> 16) & 0x1f;
Rd = ARegisters.ZRIndex; Rd = AThreadState.ZRIndex;
} }
} }
} }

View file

@ -343,8 +343,11 @@ namespace ChocolArm64.Instruction
private static void EmitZeroCVFlags(AILEmitterCtx Context) private static void EmitZeroCVFlags(AILEmitterCtx Context)
{ {
Context.EmitLdc_I4(0); Context.EmitLdc_I4(0);
Context.EmitLdc_I4(0);
Context.EmitStflg((int)APState.VBit); Context.EmitStflg((int)APState.VBit);
Context.EmitLdc_I4(0);
Context.EmitStflg((int)APState.CBit); Context.EmitStflg((int)APState.CBit);
} }
} }

View file

@ -11,12 +11,12 @@ namespace ChocolArm64.Instruction
public static void Brk(AILEmitterCtx Context) public static void Brk(AILEmitterCtx Context)
{ {
EmitExceptionCall(Context, nameof(ARegisters.OnBreak)); EmitExceptionCall(Context, nameof(AThreadState.OnBreak));
} }
public static void Svc(AILEmitterCtx Context) public static void Svc(AILEmitterCtx Context)
{ {
EmitExceptionCall(Context, nameof(ARegisters.OnSvcCall)); EmitExceptionCall(Context, nameof(AThreadState.OnSvcCall));
} }
private static void EmitExceptionCall(AILEmitterCtx Context, string MthdName) private static void EmitExceptionCall(AILEmitterCtx Context, string MthdName)
@ -25,11 +25,11 @@ namespace ChocolArm64.Instruction
Context.EmitStoreState(); Context.EmitStoreState();
Context.EmitLdarg(ATranslatedSub.RegistersArgIdx); Context.EmitLdarg(ATranslatedSub.StateArgIdx);
Context.EmitLdc_I4(Op.Id); Context.EmitLdc_I4(Op.Id);
MethodInfo MthdInfo = typeof(ARegisters).GetMethod(MthdName, Binding); MethodInfo MthdInfo = typeof(AThreadState).GetMethod(MthdName, Binding);
Context.EmitCall(MthdInfo); Context.EmitCall(MthdInfo);
@ -45,14 +45,14 @@ namespace ChocolArm64.Instruction
Context.EmitStoreState(); Context.EmitStoreState();
Context.EmitLdarg(ATranslatedSub.RegistersArgIdx); Context.EmitLdarg(ATranslatedSub.StateArgIdx);
Context.EmitLdc_I8(Op.Position); Context.EmitLdc_I8(Op.Position);
Context.EmitLdc_I4(Op.RawOpCode); Context.EmitLdc_I4(Op.RawOpCode);
string MthdName = nameof(ARegisters.OnUndefined); string MthdName = nameof(AThreadState.OnUndefined);
MethodInfo MthdInfo = typeof(ARegisters).GetMethod(MthdName, Binding); MethodInfo MthdInfo = typeof(AThreadState).GetMethod(MthdName, Binding);
Context.EmitCall(MthdInfo); Context.EmitCall(MthdInfo);

View file

@ -26,7 +26,7 @@ namespace ChocolArm64.Instruction
AOpCodeBImmAl Op = (AOpCodeBImmAl)Context.CurrOp; AOpCodeBImmAl Op = (AOpCodeBImmAl)Context.CurrOp;
Context.EmitLdc_I(Op.Position + 4); Context.EmitLdc_I(Op.Position + 4);
Context.EmitStint(ARegisters.LRIndex); Context.EmitStint(AThreadState.LRIndex);
Context.EmitStoreState(); Context.EmitStoreState();
if (Context.TryOptEmitSubroutineCall()) if (Context.TryOptEmitSubroutineCall())
@ -66,7 +66,7 @@ namespace ChocolArm64.Instruction
AOpCodeBReg Op = (AOpCodeBReg)Context.CurrOp; AOpCodeBReg Op = (AOpCodeBReg)Context.CurrOp;
Context.EmitLdc_I(Op.Position + 4); Context.EmitLdc_I(Op.Position + 4);
Context.EmitStint(ARegisters.LRIndex); Context.EmitStint(AThreadState.LRIndex);
Context.EmitStoreState(); Context.EmitStoreState();
Context.EmitLdintzr(Op.Rn); Context.EmitLdintzr(Op.Rn);
@ -99,7 +99,7 @@ namespace ChocolArm64.Instruction
public static void Ret(AILEmitterCtx Context) public static void Ret(AILEmitterCtx Context)
{ {
Context.EmitStoreState(); Context.EmitStoreState();
Context.EmitLdint(ARegisters.LRIndex); Context.EmitLdint(AThreadState.LRIndex);
Context.Emit(OpCodes.Ret); Context.Emit(OpCodes.Ret);
} }

View file

@ -159,7 +159,7 @@ namespace ChocolArm64.Instruction
private static void EmitMemoryCall(AILEmitterCtx Context, string Name, int Rn = -1) private static void EmitMemoryCall(AILEmitterCtx Context, string Name, int Rn = -1)
{ {
Context.EmitLdarg(ATranslatedSub.MemoryArgIdx); Context.EmitLdarg(ATranslatedSub.MemoryArgIdx);
Context.EmitLdarg(ATranslatedSub.RegistersArgIdx); Context.EmitLdarg(ATranslatedSub.StateArgIdx);
if (Rn != -1) if (Rn != -1)
{ {

View file

@ -167,7 +167,7 @@ namespace ChocolArm64.Instruction
Context.EmitLdint(Op.Rn); Context.EmitLdint(Op.Rn);
if (Op.Rm != ARegisters.ZRIndex) if (Op.Rm != AThreadState.ZRIndex)
{ {
Context.EmitLdint(Op.Rm); Context.EmitLdint(Op.Rm);
} }

View file

@ -13,26 +13,26 @@ namespace ChocolArm64.Instruction
{ {
AOpCodeSystem Op = (AOpCodeSystem)Context.CurrOp; AOpCodeSystem Op = (AOpCodeSystem)Context.CurrOp;
Context.EmitLdarg(ATranslatedSub.RegistersArgIdx); Context.EmitLdarg(ATranslatedSub.StateArgIdx);
string PropName; string PropName;
switch (GetPackedId(Op)) switch (GetPackedId(Op))
{ {
case 0b11_011_0000_0000_001: PropName = nameof(ARegisters.CtrEl0); break; case 0b11_011_0000_0000_001: PropName = nameof(AThreadState.CtrEl0); break;
case 0b11_011_0000_0000_111: PropName = nameof(ARegisters.DczidEl0); break; case 0b11_011_0000_0000_111: PropName = nameof(AThreadState.DczidEl0); break;
case 0b11_011_0100_0100_000: PropName = nameof(ARegisters.Fpcr); break; case 0b11_011_0100_0100_000: PropName = nameof(AThreadState.Fpcr); break;
case 0b11_011_0100_0100_001: PropName = nameof(ARegisters.Fpsr); break; case 0b11_011_0100_0100_001: PropName = nameof(AThreadState.Fpsr); break;
case 0b11_011_1101_0000_010: PropName = nameof(ARegisters.TpidrEl0); break; case 0b11_011_1101_0000_010: PropName = nameof(AThreadState.TpidrEl0); break;
case 0b11_011_1101_0000_011: PropName = nameof(ARegisters.Tpidr); break; case 0b11_011_1101_0000_011: PropName = nameof(AThreadState.Tpidr); break;
case 0b11_011_1110_0000_001: PropName = nameof(ARegisters.CntpctEl0); break; case 0b11_011_1110_0000_001: PropName = nameof(AThreadState.CntpctEl0); break;
default: throw new NotImplementedException($"Unknown MRS at {Op.Position:x16}"); default: throw new NotImplementedException($"Unknown MRS at {Op.Position:x16}");
} }
Context.EmitCallPropGet(typeof(ARegisters), PropName); Context.EmitCallPropGet(typeof(AThreadState), PropName);
PropertyInfo PropInfo = typeof(ARegisters).GetProperty(PropName); PropertyInfo PropInfo = typeof(AThreadState).GetProperty(PropName);
if (PropInfo.PropertyType != typeof(long) && if (PropInfo.PropertyType != typeof(long) &&
PropInfo.PropertyType != typeof(ulong)) PropInfo.PropertyType != typeof(ulong))
@ -47,21 +47,21 @@ namespace ChocolArm64.Instruction
{ {
AOpCodeSystem Op = (AOpCodeSystem)Context.CurrOp; AOpCodeSystem Op = (AOpCodeSystem)Context.CurrOp;
Context.EmitLdarg(ATranslatedSub.RegistersArgIdx); Context.EmitLdarg(ATranslatedSub.StateArgIdx);
Context.EmitLdintzr(Op.Rt); Context.EmitLdintzr(Op.Rt);
string PropName; string PropName;
switch (GetPackedId(Op)) switch (GetPackedId(Op))
{ {
case 0b11_011_0100_0100_000: PropName = nameof(ARegisters.Fpcr); break; case 0b11_011_0100_0100_000: PropName = nameof(AThreadState.Fpcr); break;
case 0b11_011_0100_0100_001: PropName = nameof(ARegisters.Fpsr); break; case 0b11_011_0100_0100_001: PropName = nameof(AThreadState.Fpsr); break;
case 0b11_011_1101_0000_010: PropName = nameof(ARegisters.TpidrEl0); break; case 0b11_011_1101_0000_010: PropName = nameof(AThreadState.TpidrEl0); break;
default: throw new NotImplementedException($"Unknown MSR at {Op.Position:x16}"); default: throw new NotImplementedException($"Unknown MSR at {Op.Position:x16}");
} }
PropertyInfo PropInfo = typeof(ARegisters).GetProperty(PropName); PropertyInfo PropInfo = typeof(AThreadState).GetProperty(PropName);
if (PropInfo.PropertyType != typeof(long) && if (PropInfo.PropertyType != typeof(long) &&
PropInfo.PropertyType != typeof(ulong)) PropInfo.PropertyType != typeof(ulong))
@ -69,7 +69,7 @@ namespace ChocolArm64.Instruction
Context.Emit(OpCodes.Conv_U4); Context.Emit(OpCodes.Conv_U4);
} }
Context.EmitCallPropSet(typeof(ARegisters), PropName); Context.EmitCallPropSet(typeof(AThreadState), PropName);
} }
public static void Nop(AILEmitterCtx Context) public static void Nop(AILEmitterCtx Context)
@ -89,7 +89,7 @@ namespace ChocolArm64.Instruction
case 0b11_011_0111_0100_001: case 0b11_011_0111_0100_001:
{ {
//DC ZVA //DC ZVA
for (int Offs = 0; Offs < (4 << ARegisters.DczSizeLog2); Offs += 8) for (int Offs = 0; Offs < (4 << AThreadState.DczSizeLog2); Offs += 8)
{ {
Context.EmitLdarg(ATranslatedSub.MemoryArgIdx); Context.EmitLdarg(ATranslatedSub.MemoryArgIdx);
Context.EmitLdint(Op.Rt); Context.EmitLdint(Op.Rt);

View file

@ -8,7 +8,7 @@ namespace ChocolArm64.Memory
{ {
public unsafe class AMemory public unsafe class AMemory
{ {
private const long ErgMask = (4 << ARegisters.ErgSizeLog2) - 1; private const long ErgMask = (4 << AThreadState.ErgSizeLog2) - 1;
public AMemoryMgr Manager { get; private set; } public AMemoryMgr Manager { get; private set; }
@ -65,13 +65,13 @@ namespace ChocolArm64.Memory
} }
} }
public void SetExclusive(ARegisters Registers, long Position) public void SetExclusive(AThreadState ThreadState, long Position)
{ {
Position &= ~ErgMask; Position &= ~ErgMask;
lock (Monitors) lock (Monitors)
{ {
if (Monitors.TryGetValue(Registers.ThreadId, out ExMonitor Monitor)) if (Monitors.TryGetValue(ThreadState.ThreadId, out ExMonitor Monitor))
{ {
ExAddrs.Remove(Monitor.Position); ExAddrs.Remove(Monitor.Position);
} }
@ -80,20 +80,20 @@ namespace ChocolArm64.Memory
Monitor = new ExMonitor(Position, ExState); Monitor = new ExMonitor(Position, ExState);
if (!Monitors.TryAdd(Registers.ThreadId, Monitor)) if (!Monitors.TryAdd(ThreadState.ThreadId, Monitor))
{ {
Monitors[Registers.ThreadId] = Monitor; Monitors[ThreadState.ThreadId] = Monitor;
} }
} }
} }
public bool TestExclusive(ARegisters Registers, long Position) public bool TestExclusive(AThreadState ThreadState, long Position)
{ {
Position &= ~ErgMask; Position &= ~ErgMask;
lock (Monitors) lock (Monitors)
{ {
if (!Monitors.TryGetValue(Registers.ThreadId, out ExMonitor Monitor)) if (!Monitors.TryGetValue(ThreadState.ThreadId, out ExMonitor Monitor))
{ {
return false; return false;
} }
@ -102,11 +102,11 @@ namespace ChocolArm64.Memory
} }
} }
public void ClearExclusive(ARegisters Registers) public void ClearExclusive(AThreadState ThreadState)
{ {
lock (Monitors) lock (Monitors)
{ {
if (Monitors.TryGetValue(Registers.ThreadId, out ExMonitor Monitor)) if (Monitors.TryGetValue(ThreadState.ThreadId, out ExMonitor Monitor))
{ {
Monitor.Reset(); Monitor.Reset();
ExAddrs.Remove(Monitor.Position); ExAddrs.Remove(Monitor.Position);

View file

@ -43,10 +43,10 @@ namespace ChocolArm64.State
{ {
switch ((APState)Index) switch ((APState)Index)
{ {
case APState.VBit: return GetField(nameof(ARegisters.Overflow)); case APState.VBit: return GetField(nameof(AThreadState.Overflow));
case APState.CBit: return GetField(nameof(ARegisters.Carry)); case APState.CBit: return GetField(nameof(AThreadState.Carry));
case APState.ZBit: return GetField(nameof(ARegisters.Zero)); case APState.ZBit: return GetField(nameof(AThreadState.Zero));
case APState.NBit: return GetField(nameof(ARegisters.Negative)); case APState.NBit: return GetField(nameof(AThreadState.Negative));
} }
throw new InvalidOperationException(); throw new InvalidOperationException();
@ -56,38 +56,38 @@ namespace ChocolArm64.State
{ {
switch (Index) switch (Index)
{ {
case 0: return GetField(nameof(ARegisters.X0)); case 0: return GetField(nameof(AThreadState.X0));
case 1: return GetField(nameof(ARegisters.X1)); case 1: return GetField(nameof(AThreadState.X1));
case 2: return GetField(nameof(ARegisters.X2)); case 2: return GetField(nameof(AThreadState.X2));
case 3: return GetField(nameof(ARegisters.X3)); case 3: return GetField(nameof(AThreadState.X3));
case 4: return GetField(nameof(ARegisters.X4)); case 4: return GetField(nameof(AThreadState.X4));
case 5: return GetField(nameof(ARegisters.X5)); case 5: return GetField(nameof(AThreadState.X5));
case 6: return GetField(nameof(ARegisters.X6)); case 6: return GetField(nameof(AThreadState.X6));
case 7: return GetField(nameof(ARegisters.X7)); case 7: return GetField(nameof(AThreadState.X7));
case 8: return GetField(nameof(ARegisters.X8)); case 8: return GetField(nameof(AThreadState.X8));
case 9: return GetField(nameof(ARegisters.X9)); case 9: return GetField(nameof(AThreadState.X9));
case 10: return GetField(nameof(ARegisters.X10)); case 10: return GetField(nameof(AThreadState.X10));
case 11: return GetField(nameof(ARegisters.X11)); case 11: return GetField(nameof(AThreadState.X11));
case 12: return GetField(nameof(ARegisters.X12)); case 12: return GetField(nameof(AThreadState.X12));
case 13: return GetField(nameof(ARegisters.X13)); case 13: return GetField(nameof(AThreadState.X13));
case 14: return GetField(nameof(ARegisters.X14)); case 14: return GetField(nameof(AThreadState.X14));
case 15: return GetField(nameof(ARegisters.X15)); case 15: return GetField(nameof(AThreadState.X15));
case 16: return GetField(nameof(ARegisters.X16)); case 16: return GetField(nameof(AThreadState.X16));
case 17: return GetField(nameof(ARegisters.X17)); case 17: return GetField(nameof(AThreadState.X17));
case 18: return GetField(nameof(ARegisters.X18)); case 18: return GetField(nameof(AThreadState.X18));
case 19: return GetField(nameof(ARegisters.X19)); case 19: return GetField(nameof(AThreadState.X19));
case 20: return GetField(nameof(ARegisters.X20)); case 20: return GetField(nameof(AThreadState.X20));
case 21: return GetField(nameof(ARegisters.X21)); case 21: return GetField(nameof(AThreadState.X21));
case 22: return GetField(nameof(ARegisters.X22)); case 22: return GetField(nameof(AThreadState.X22));
case 23: return GetField(nameof(ARegisters.X23)); case 23: return GetField(nameof(AThreadState.X23));
case 24: return GetField(nameof(ARegisters.X24)); case 24: return GetField(nameof(AThreadState.X24));
case 25: return GetField(nameof(ARegisters.X25)); case 25: return GetField(nameof(AThreadState.X25));
case 26: return GetField(nameof(ARegisters.X26)); case 26: return GetField(nameof(AThreadState.X26));
case 27: return GetField(nameof(ARegisters.X27)); case 27: return GetField(nameof(AThreadState.X27));
case 28: return GetField(nameof(ARegisters.X28)); case 28: return GetField(nameof(AThreadState.X28));
case 29: return GetField(nameof(ARegisters.X29)); case 29: return GetField(nameof(AThreadState.X29));
case 30: return GetField(nameof(ARegisters.X30)); case 30: return GetField(nameof(AThreadState.X30));
case 31: return GetField(nameof(ARegisters.X31)); case 31: return GetField(nameof(AThreadState.X31));
} }
throw new InvalidOperationException(); throw new InvalidOperationException();
@ -97,38 +97,38 @@ namespace ChocolArm64.State
{ {
switch (Index) switch (Index)
{ {
case 0: return GetField(nameof(ARegisters.V0)); case 0: return GetField(nameof(AThreadState.V0));
case 1: return GetField(nameof(ARegisters.V1)); case 1: return GetField(nameof(AThreadState.V1));
case 2: return GetField(nameof(ARegisters.V2)); case 2: return GetField(nameof(AThreadState.V2));
case 3: return GetField(nameof(ARegisters.V3)); case 3: return GetField(nameof(AThreadState.V3));
case 4: return GetField(nameof(ARegisters.V4)); case 4: return GetField(nameof(AThreadState.V4));
case 5: return GetField(nameof(ARegisters.V5)); case 5: return GetField(nameof(AThreadState.V5));
case 6: return GetField(nameof(ARegisters.V6)); case 6: return GetField(nameof(AThreadState.V6));
case 7: return GetField(nameof(ARegisters.V7)); case 7: return GetField(nameof(AThreadState.V7));
case 8: return GetField(nameof(ARegisters.V8)); case 8: return GetField(nameof(AThreadState.V8));
case 9: return GetField(nameof(ARegisters.V9)); case 9: return GetField(nameof(AThreadState.V9));
case 10: return GetField(nameof(ARegisters.V10)); case 10: return GetField(nameof(AThreadState.V10));
case 11: return GetField(nameof(ARegisters.V11)); case 11: return GetField(nameof(AThreadState.V11));
case 12: return GetField(nameof(ARegisters.V12)); case 12: return GetField(nameof(AThreadState.V12));
case 13: return GetField(nameof(ARegisters.V13)); case 13: return GetField(nameof(AThreadState.V13));
case 14: return GetField(nameof(ARegisters.V14)); case 14: return GetField(nameof(AThreadState.V14));
case 15: return GetField(nameof(ARegisters.V15)); case 15: return GetField(nameof(AThreadState.V15));
case 16: return GetField(nameof(ARegisters.V16)); case 16: return GetField(nameof(AThreadState.V16));
case 17: return GetField(nameof(ARegisters.V17)); case 17: return GetField(nameof(AThreadState.V17));
case 18: return GetField(nameof(ARegisters.V18)); case 18: return GetField(nameof(AThreadState.V18));
case 19: return GetField(nameof(ARegisters.V19)); case 19: return GetField(nameof(AThreadState.V19));
case 20: return GetField(nameof(ARegisters.V20)); case 20: return GetField(nameof(AThreadState.V20));
case 21: return GetField(nameof(ARegisters.V21)); case 21: return GetField(nameof(AThreadState.V21));
case 22: return GetField(nameof(ARegisters.V22)); case 22: return GetField(nameof(AThreadState.V22));
case 23: return GetField(nameof(ARegisters.V23)); case 23: return GetField(nameof(AThreadState.V23));
case 24: return GetField(nameof(ARegisters.V24)); case 24: return GetField(nameof(AThreadState.V24));
case 25: return GetField(nameof(ARegisters.V25)); case 25: return GetField(nameof(AThreadState.V25));
case 26: return GetField(nameof(ARegisters.V26)); case 26: return GetField(nameof(AThreadState.V26));
case 27: return GetField(nameof(ARegisters.V27)); case 27: return GetField(nameof(AThreadState.V27));
case 28: return GetField(nameof(ARegisters.V28)); case 28: return GetField(nameof(AThreadState.V28));
case 29: return GetField(nameof(ARegisters.V29)); case 29: return GetField(nameof(AThreadState.V29));
case 30: return GetField(nameof(ARegisters.V30)); case 30: return GetField(nameof(AThreadState.V30));
case 31: return GetField(nameof(ARegisters.V31)); case 31: return GetField(nameof(AThreadState.V31));
} }
throw new InvalidOperationException(); throw new InvalidOperationException();
@ -136,7 +136,7 @@ namespace ChocolArm64.State
private FieldInfo GetField(string Name) private FieldInfo GetField(string Name)
{ {
return typeof(ARegisters).GetField(Name); return typeof(AThreadState).GetField(Name);
} }
} }
} }

View file

@ -2,7 +2,7 @@ using System;
namespace ChocolArm64.State namespace ChocolArm64.State
{ {
public class ARegisters public class AThreadState
{ {
internal const int LRIndex = 30; internal const int LRIndex = 30;
internal const int ZRIndex = 31; internal const int ZRIndex = 31;

View file

@ -309,7 +309,7 @@ namespace ChocolArm64.Translation
public void EmitLdintzr(int Index) public void EmitLdintzr(int Index)
{ {
if (Index != ARegisters.ZRIndex) if (Index != AThreadState.ZRIndex)
{ {
EmitLdint(Index); EmitLdint(Index);
} }
@ -321,7 +321,7 @@ namespace ChocolArm64.Translation
public void EmitStintzr(int Index) public void EmitStintzr(int Index)
{ {
if (Index != ARegisters.ZRIndex) if (Index != AThreadState.ZRIndex)
{ {
EmitStint(Index); EmitStint(Index);
} }

View file

@ -53,7 +53,7 @@ namespace ChocolArm64.Translation
{ {
ARegister Reg = AILEmitter.GetRegFromBit(Bit, BaseType); ARegister Reg = AILEmitter.GetRegFromBit(Bit, BaseType);
Context.Generator.EmitLdarg(ATranslatedSub.RegistersArgIdx); Context.Generator.EmitLdarg(ATranslatedSub.StateArgIdx);
Context.Generator.Emit(OpCodes.Ldfld, Reg.GetField()); Context.Generator.Emit(OpCodes.Ldfld, Reg.GetField());
Context.Generator.EmitStloc(Context.GetLocalIndex(Reg)); Context.Generator.EmitStloc(Context.GetLocalIndex(Reg));

View file

@ -53,7 +53,7 @@ namespace ChocolArm64.Translation
{ {
ARegister Reg = AILEmitter.GetRegFromBit(Bit, BaseType); ARegister Reg = AILEmitter.GetRegFromBit(Bit, BaseType);
Context.Generator.EmitLdarg(ATranslatedSub.RegistersArgIdx); Context.Generator.EmitLdarg(ATranslatedSub.StateArgIdx);
Context.Generator.EmitLdloc(Context.GetLocalIndex(Reg)); Context.Generator.EmitLdloc(Context.GetLocalIndex(Reg));
Context.Generator.Emit(OpCodes.Stfld, Reg.GetField()); Context.Generator.Emit(OpCodes.Stfld, Reg.GetField());

View file

@ -176,19 +176,19 @@ namespace Ryujinx.OsHle
return -1; return -1;
} }
Thread.Registers.Break += BreakHandler; Thread.ThreadState.Break += BreakHandler;
Thread.Registers.SvcCall += SvcHandler.SvcCall; Thread.ThreadState.SvcCall += SvcHandler.SvcCall;
Thread.Registers.Undefined += UndefinedHandler; Thread.ThreadState.Undefined += UndefinedHandler;
Thread.Registers.ProcessId = ProcessId; Thread.ThreadState.ProcessId = ProcessId;
Thread.Registers.ThreadId = Ns.Os.IdGen.GenerateId(); Thread.ThreadState.ThreadId = Ns.Os.IdGen.GenerateId();
Thread.Registers.Tpidr = TlsPageAddr + TlsSlot * TlsSize; Thread.ThreadState.Tpidr = TlsPageAddr + TlsSlot * TlsSize;
Thread.Registers.X0 = (ulong)ArgsPtr; Thread.ThreadState.X0 = (ulong)ArgsPtr;
Thread.Registers.X1 = (ulong)Handle; Thread.ThreadState.X1 = (ulong)Handle;
Thread.Registers.X31 = (ulong)StackTop; Thread.ThreadState.X31 = (ulong)StackTop;
Thread.WorkFinished += ThreadFinished; Thread.WorkFinished += ThreadFinished;
ThreadsByTpidr.TryAdd(Thread.Registers.Tpidr, ThreadHnd); ThreadsByTpidr.TryAdd(Thread.ThreadState.Tpidr, ThreadHnd);
return Handle; return Handle;
} }
@ -220,7 +220,7 @@ namespace Ryujinx.OsHle
{ {
if (sender is AThread Thread) if (sender is AThread Thread)
{ {
TlsSlots.TryRemove(GetTlsSlot(Thread.Registers.Tpidr), out _); TlsSlots.TryRemove(GetTlsSlot(Thread.ThreadState.Tpidr), out _);
Ns.Os.IdGen.DeleteId(Thread.ThreadId); Ns.Os.IdGen.DeleteId(Thread.ThreadId);
} }

View file

@ -7,7 +7,7 @@ namespace Ryujinx.OsHle.Svc
{ {
partial class SvcHandler partial class SvcHandler
{ {
private delegate void SvcFunc(ARegisters Registers); private delegate void SvcFunc(AThreadState ThreadState);
private Dictionary<int, SvcFunc> SvcFuncs; private Dictionary<int, SvcFunc> SvcFuncs;
@ -61,15 +61,15 @@ namespace Ryujinx.OsHle.Svc
public void SvcCall(object sender, AInstExceptEventArgs e) public void SvcCall(object sender, AInstExceptEventArgs e)
{ {
ARegisters Registers = (ARegisters)sender; AThreadState ThreadState = (AThreadState)sender;
if (SvcFuncs.TryGetValue(e.Id, out SvcFunc Func)) if (SvcFuncs.TryGetValue(e.Id, out SvcFunc Func))
{ {
Logging.Trace($"(Thread {Registers.ThreadId}) {Func.Method.Name} called."); Logging.Trace($"(Thread {ThreadState.ThreadId}) {Func.Method.Name} called.");
Func(Registers); Func(ThreadState);
Logging.Trace($"(Thread {Registers.ThreadId}) {Func.Method.Name} ended."); Logging.Trace($"(Thread {ThreadState.ThreadId}) {Func.Method.Name} ended.");
} }
else else
{ {

View file

@ -6,43 +6,43 @@ namespace Ryujinx.OsHle.Svc
{ {
partial class SvcHandler partial class SvcHandler
{ {
private void SvcSetHeapSize(ARegisters Registers) private void SvcSetHeapSize(AThreadState ThreadState)
{ {
uint Size = (uint)Registers.X1; uint Size = (uint)ThreadState.X1;
Memory.Manager.SetHeapSize(Size, (int)MemoryType.Heap); Memory.Manager.SetHeapSize(Size, (int)MemoryType.Heap);
Registers.X0 = (int)SvcResult.Success; ThreadState.X0 = (int)SvcResult.Success;
Registers.X1 = (ulong)Memory.Manager.HeapAddr; ThreadState.X1 = (ulong)Memory.Manager.HeapAddr;
} }
private void SvcSetMemoryAttribute(ARegisters Registers) private void SvcSetMemoryAttribute(AThreadState ThreadState)
{ {
long Position = (long)Registers.X0; long Position = (long)ThreadState.X0;
long Size = (long)Registers.X1; long Size = (long)ThreadState.X1;
int State0 = (int)Registers.X2; int State0 = (int)ThreadState.X2;
int State1 = (int)Registers.X3; int State1 = (int)ThreadState.X3;
//TODO //TODO
Registers.X0 = (int)SvcResult.Success; ThreadState.X0 = (int)SvcResult.Success;
} }
private void SvcMapMemory(ARegisters Registers) private void SvcMapMemory(AThreadState ThreadState)
{ {
long Dst = (long)Registers.X0; long Dst = (long)ThreadState.X0;
long Src = (long)Registers.X1; long Src = (long)ThreadState.X1;
long Size = (long)Registers.X2; long Size = (long)ThreadState.X2;
Memory.Manager.MapMirror(Src, Dst, Size, (int)MemoryType.MappedMemory); Memory.Manager.MapMirror(Src, Dst, Size, (int)MemoryType.MappedMemory);
Registers.X0 = (int)SvcResult.Success; ThreadState.X0 = (int)SvcResult.Success;
} }
private void SvcQueryMemory(ARegisters Registers) private void SvcQueryMemory(AThreadState ThreadState)
{ {
long InfoPtr = (long)Registers.X0; long InfoPtr = (long)ThreadState.X0;
long Position = (long)Registers.X2; long Position = (long)ThreadState.X2;
AMemoryMapInfo MapInfo = Memory.Manager.GetMapInfo(Position); AMemoryMapInfo MapInfo = Memory.Manager.GetMapInfo(Position);
@ -59,16 +59,16 @@ namespace Ryujinx.OsHle.Svc
//TODO: X1. //TODO: X1.
Registers.X0 = (int)SvcResult.Success; ThreadState.X0 = (int)SvcResult.Success;
Registers.X1 = 0; ThreadState.X1 = 0;
} }
private void SvcMapSharedMemory(ARegisters Registers) private void SvcMapSharedMemory(AThreadState ThreadState)
{ {
int Handle = (int)Registers.X0; int Handle = (int)ThreadState.X0;
long Src = (long)Registers.X1; long Src = (long)ThreadState.X1;
long Size = (long)Registers.X2; long Size = (long)ThreadState.X2;
int Perm = (int)Registers.X3; int Perm = (int)ThreadState.X3;
HSharedMem SharedMem = Ns.Os.Handles.GetData<HSharedMem>(Handle); HSharedMem SharedMem = Ns.Os.Handles.GetData<HSharedMem>(Handle);
@ -78,33 +78,33 @@ namespace Ryujinx.OsHle.Svc
Memory.Manager.MapPhys(Src, Size, (int)MemoryType.SharedMemory, (AMemoryPerm)Perm); Memory.Manager.MapPhys(Src, Size, (int)MemoryType.SharedMemory, (AMemoryPerm)Perm);
Registers.X0 = (int)SvcResult.Success; ThreadState.X0 = (int)SvcResult.Success;
} }
//TODO: Error codes. //TODO: Error codes.
} }
private void SvcUnmapSharedMemory(ARegisters Registers) private void SvcUnmapSharedMemory(AThreadState ThreadState)
{ {
int Handle = (int)Registers.X0; int Handle = (int)ThreadState.X0;
long Position = (long)Registers.X1; long Position = (long)ThreadState.X1;
long Size = (long)Registers.X2; long Size = (long)ThreadState.X2;
HSharedMem HndData = Ns.Os.Handles.GetData<HSharedMem>(Handle); HSharedMem HndData = Ns.Os.Handles.GetData<HSharedMem>(Handle);
if (HndData != null) if (HndData != null)
{ {
Registers.X0 = (int)SvcResult.Success; ThreadState.X0 = (int)SvcResult.Success;
} }
//TODO: Error codes. //TODO: Error codes.
} }
private void SvcCreateTransferMemory(ARegisters Registers) private void SvcCreateTransferMemory(AThreadState ThreadState)
{ {
long Position = (long)Registers.X1; long Position = (long)ThreadState.X1;
long Size = (long)Registers.X2; long Size = (long)ThreadState.X2;
int Perm = (int)Registers.X3; int Perm = (int)ThreadState.X3;
AMemoryMapInfo MapInfo = Memory.Manager.GetMapInfo(Position); AMemoryMapInfo MapInfo = Memory.Manager.GetMapInfo(Position);
@ -114,8 +114,8 @@ namespace Ryujinx.OsHle.Svc
int Handle = Ns.Os.Handles.GenerateId(HndData); int Handle = Ns.Os.Handles.GenerateId(HndData);
Registers.X1 = (ulong)Handle; ThreadState.X1 = (ulong)Handle;
Registers.X0 = (int)SvcResult.Success; ThreadState.X0 = (int)SvcResult.Success;
} }
} }
} }

View file

@ -9,57 +9,57 @@ namespace Ryujinx.OsHle.Svc
{ {
partial class SvcHandler partial class SvcHandler
{ {
private void SvcExitProcess(ARegisters Registers) => Ns.Os.ExitProcess(Registers.ProcessId); private void SvcExitProcess(AThreadState ThreadState) => Ns.Os.ExitProcess(ThreadState.ProcessId);
private void SvcCloseHandle(ARegisters Registers) private void SvcCloseHandle(AThreadState ThreadState)
{ {
int Handle = (int)Registers.X0; int Handle = (int)ThreadState.X0;
Ns.Os.CloseHandle(Handle); Ns.Os.CloseHandle(Handle);
Registers.X0 = (int)SvcResult.Success; ThreadState.X0 = (int)SvcResult.Success;
} }
private void SvcResetSignal(ARegisters Registers) private void SvcResetSignal(AThreadState ThreadState)
{ {
int Handle = (int)Registers.X0; int Handle = (int)ThreadState.X0;
//TODO: Implement events. //TODO: Implement events.
Registers.X0 = (int)SvcResult.Success; ThreadState.X0 = (int)SvcResult.Success;
} }
private void SvcWaitSynchronization(ARegisters Registers) private void SvcWaitSynchronization(AThreadState ThreadState)
{ {
long HandlesPtr = (long)Registers.X0; long HandlesPtr = (long)ThreadState.X0;
int HandlesCount = (int)Registers.X2; int HandlesCount = (int)ThreadState.X2;
long Timeout = (long)Registers.X3; long Timeout = (long)ThreadState.X3;
//TODO: Implement events. //TODO: Implement events.
//Logging.Info($"SvcWaitSynchronization Thread {Registers.ThreadId}"); //Logging.Info($"SvcWaitSynchronization Thread {ThreadState.ThreadId}");
if (Process.TryGetThread(Registers.Tpidr, out HThread Thread)) if (Process.TryGetThread(ThreadState.Tpidr, out HThread Thread))
{ {
Process.Scheduler.Yield(Thread); Process.Scheduler.Yield(Thread);
} }
else else
{ {
Logging.Error($"Thread with TPIDR_EL0 0x{Registers.Tpidr:x16} not found!"); Logging.Error($"Thread with TPIDR_EL0 0x{ThreadState.Tpidr:x16} not found!");
} }
Registers.X0 = (int)SvcResult.Success; ThreadState.X0 = (int)SvcResult.Success;
} }
private void SvcGetSystemTick(ARegisters Registers) private void SvcGetSystemTick(AThreadState ThreadState)
{ {
Registers.X0 = (ulong)Registers.CntpctEl0; ThreadState.X0 = (ulong)ThreadState.CntpctEl0;
} }
private void SvcConnectToNamedPort(ARegisters Registers) private void SvcConnectToNamedPort(AThreadState ThreadState)
{ {
long StackPtr = (long)Registers.X0; long StackPtr = (long)ThreadState.X0;
long NamePtr = (long)Registers.X1; long NamePtr = (long)ThreadState.X1;
string Name = AMemoryHelper.ReadAsciiString(Memory, NamePtr, 8); string Name = AMemoryHelper.ReadAsciiString(Memory, NamePtr, 8);
@ -68,35 +68,35 @@ namespace Ryujinx.OsHle.Svc
HSession Session = new HSession(Name); HSession Session = new HSession(Name);
Registers.X1 = (ulong)Ns.Os.Handles.GenerateId(Session); ThreadState.X1 = (ulong)Ns.Os.Handles.GenerateId(Session);
Registers.X0 = (int)SvcResult.Success; ThreadState.X0 = (int)SvcResult.Success;
} }
private void SvcSendSyncRequest(ARegisters Registers) private void SvcSendSyncRequest(AThreadState ThreadState)
{ {
SendSyncRequest(Registers, false); SendSyncRequest(ThreadState, false);
} }
private void SvcSendSyncRequestWithUserBuffer(ARegisters Registers) private void SvcSendSyncRequestWithUserBuffer(AThreadState ThreadState)
{ {
SendSyncRequest(Registers, true); SendSyncRequest(ThreadState, true);
} }
private void SendSyncRequest(ARegisters Registers, bool UserBuffer) private void SendSyncRequest(AThreadState ThreadState, bool UserBuffer)
{ {
long CmdPtr = Registers.Tpidr; long CmdPtr = ThreadState.Tpidr;
long Size = 0x100; long Size = 0x100;
int Handle = 0; int Handle = 0;
if (UserBuffer) if (UserBuffer)
{ {
CmdPtr = (long)Registers.X0; CmdPtr = (long)ThreadState.X0;
Size = (long)Registers.X1; Size = (long)ThreadState.X1;
Handle = (int)Registers.X2; Handle = (int)ThreadState.X2;
} }
else else
{ {
Handle = (int)Registers.X0; Handle = (int)ThreadState.X0;
} }
byte[] CmdData = AMemoryHelper.ReadBytes(Memory, CmdPtr, (int)Size); byte[] CmdData = AMemoryHelper.ReadBytes(Memory, CmdPtr, (int)Size);
@ -111,69 +111,69 @@ namespace Ryujinx.OsHle.Svc
byte[] Response = AMemoryHelper.ReadBytes(Memory, CmdPtr, (int)Size); byte[] Response = AMemoryHelper.ReadBytes(Memory, CmdPtr, (int)Size);
Registers.X0 = (int)SvcResult.Success; ThreadState.X0 = (int)SvcResult.Success;
} }
else else
{ {
Registers.X0 = (int)SvcResult.ErrBadIpcReq; ThreadState.X0 = (int)SvcResult.ErrBadIpcReq;
} }
} }
private void SvcBreak(ARegisters Registers) private void SvcBreak(AThreadState ThreadState)
{ {
long Reason = (long)Registers.X0; long Reason = (long)ThreadState.X0;
long Unknown = (long)Registers.X1; long Unknown = (long)ThreadState.X1;
long Info = (long)Registers.X2; long Info = (long)ThreadState.X2;
throw new GuestBrokeExecutionException(); throw new GuestBrokeExecutionException();
} }
private void SvcOutputDebugString(ARegisters Registers) private void SvcOutputDebugString(AThreadState ThreadState)
{ {
long Position = (long)Registers.X0; long Position = (long)ThreadState.X0;
long Size = (long)Registers.X1; long Size = (long)ThreadState.X1;
string Str = AMemoryHelper.ReadAsciiString(Memory, Position, (int)Size); string Str = AMemoryHelper.ReadAsciiString(Memory, Position, (int)Size);
Logging.Info($"SvcOutputDebugString: {Str}"); Logging.Info($"SvcOutputDebugString: {Str}");
Registers.X0 = (int)SvcResult.Success; ThreadState.X0 = (int)SvcResult.Success;
} }
private void SvcGetInfo(ARegisters Registers) private void SvcGetInfo(AThreadState ThreadState)
{ {
long StackPtr = (long)Registers.X0; long StackPtr = (long)ThreadState.X0;
int InfoType = (int)Registers.X1; int InfoType = (int)ThreadState.X1;
long Handle = (long)Registers.X2; long Handle = (long)ThreadState.X2;
int InfoId = (int)Registers.X3; int InfoId = (int)ThreadState.X3;
//Fail for info not available on older Kernel versions. //Fail for info not available on older Kernel versions.
if (InfoType == 18 || if (InfoType == 18 ||
InfoType == 19) InfoType == 19)
{ {
Registers.X0 = (int)SvcResult.ErrBadInfo; ThreadState.X0 = (int)SvcResult.ErrBadInfo;
return; return;
} }
switch (InfoType) switch (InfoType)
{ {
case 2: Registers.X1 = GetMapRegionBaseAddr(); break; case 2: ThreadState.X1 = GetMapRegionBaseAddr(); break;
case 3: Registers.X1 = GetMapRegionSize(); break; case 3: ThreadState.X1 = GetMapRegionSize(); break;
case 4: Registers.X1 = GetHeapRegionBaseAddr(); break; case 4: ThreadState.X1 = GetHeapRegionBaseAddr(); break;
case 5: Registers.X1 = GetHeapRegionSize(); break; case 5: ThreadState.X1 = GetHeapRegionSize(); break;
case 6: Registers.X1 = GetTotalMem(); break; case 6: ThreadState.X1 = GetTotalMem(); break;
case 7: Registers.X1 = GetUsedMem(); break; case 7: ThreadState.X1 = GetUsedMem(); break;
case 11: Registers.X1 = GetRnd64(); break; case 11: ThreadState.X1 = GetRnd64(); break;
case 12: Registers.X1 = GetAddrSpaceBaseAddr(); break; case 12: ThreadState.X1 = GetAddrSpaceBaseAddr(); break;
case 13: Registers.X1 = GetAddrSpaceSize(); break; case 13: ThreadState.X1 = GetAddrSpaceSize(); break;
case 14: Registers.X1 = GetMapRegionBaseAddr(); break; case 14: ThreadState.X1 = GetMapRegionBaseAddr(); break;
case 15: Registers.X1 = GetMapRegionSize(); break; case 15: ThreadState.X1 = GetMapRegionSize(); break;
default: throw new NotImplementedException($"SvcGetInfo: {InfoType} {Handle} {InfoId}"); default: throw new NotImplementedException($"SvcGetInfo: {InfoType} {Handle} {InfoId}");
} }
Registers.X0 = (int)SvcResult.Success; ThreadState.X0 = (int)SvcResult.Success;
} }
private ulong GetTotalMem() private ulong GetTotalMem()

View file

@ -6,15 +6,15 @@ namespace Ryujinx.OsHle.Svc
{ {
partial class SvcHandler partial class SvcHandler
{ {
private void SvcCreateThread(ARegisters Registers) private void SvcCreateThread(AThreadState ThreadState)
{ {
long EntryPoint = (long)Registers.X1; long EntryPoint = (long)ThreadState.X1;
long ArgsPtr = (long)Registers.X2; long ArgsPtr = (long)ThreadState.X2;
long StackTop = (long)Registers.X3; long StackTop = (long)ThreadState.X3;
int Priority = (int)Registers.X4; int Priority = (int)ThreadState.X4;
int ProcessorId = (int)Registers.X5; int ProcessorId = (int)ThreadState.X5;
if (Ns.Os.TryGetProcess(Registers.ProcessId, out Process Process)) if (Ns.Os.TryGetProcess(ThreadState.ProcessId, out Process Process))
{ {
if (ProcessorId == -2) if (ProcessorId == -2)
{ {
@ -28,16 +28,16 @@ namespace Ryujinx.OsHle.Svc
Priority, Priority,
ProcessorId); ProcessorId);
Registers.X0 = (int)SvcResult.Success; ThreadState.X0 = (int)SvcResult.Success;
Registers.X1 = (ulong)Handle; ThreadState.X1 = (ulong)Handle;
} }
//TODO: Error codes. //TODO: Error codes.
} }
private void SvcStartThread(ARegisters Registers) private void SvcStartThread(AThreadState ThreadState)
{ {
int Handle = (int)Registers.X0; int Handle = (int)ThreadState.X0;
HThread Thread = Ns.Os.Handles.GetData<HThread>(Handle); HThread Thread = Ns.Os.Handles.GetData<HThread>(Handle);
@ -45,38 +45,38 @@ namespace Ryujinx.OsHle.Svc
{ {
Process.Scheduler.StartThread(Thread); Process.Scheduler.StartThread(Thread);
Registers.X0 = (int)SvcResult.Success; ThreadState.X0 = (int)SvcResult.Success;
} }
//TODO: Error codes. //TODO: Error codes.
} }
private void SvcSleepThread(ARegisters Registers) private void SvcSleepThread(AThreadState ThreadState)
{ {
ulong NanoSecs = Registers.X0; ulong NanoSecs = ThreadState.X0;
if (Process.TryGetThread(Registers.Tpidr, out HThread CurrThread)) if (Process.TryGetThread(ThreadState.Tpidr, out HThread CurrThread))
{ {
Process.Scheduler.Yield(CurrThread); Process.Scheduler.Yield(CurrThread);
} }
else else
{ {
Logging.Error($"Thread with TPIDR_EL0 0x{Registers.Tpidr:x16} not found!"); Logging.Error($"Thread with TPIDR_EL0 0x{ThreadState.Tpidr:x16} not found!");
} }
Thread.Sleep((int)(NanoSecs / 1000000)); Thread.Sleep((int)(NanoSecs / 1000000));
} }
private void SvcGetThreadPriority(ARegisters Registers) private void SvcGetThreadPriority(AThreadState ThreadState)
{ {
int Handle = (int)Registers.X1; int Handle = (int)ThreadState.X1;
HThread Thread = Ns.Os.Handles.GetData<HThread>(Handle); HThread Thread = Ns.Os.Handles.GetData<HThread>(Handle);
if (Thread != null) if (Thread != null)
{ {
Registers.X1 = (ulong)Thread.Priority; ThreadState.X1 = (ulong)Thread.Priority;
Registers.X0 = (int)SvcResult.Success; ThreadState.X0 = (int)SvcResult.Success;
} }
//TODO: Error codes. //TODO: Error codes.

View file

@ -5,11 +5,11 @@ namespace Ryujinx.OsHle.Svc
{ {
partial class SvcHandler partial class SvcHandler
{ {
private void SvcArbitrateLock(ARegisters Registers) private void SvcArbitrateLock(AThreadState ThreadState)
{ {
int OwnerThreadHandle = (int)Registers.X0; int OwnerThreadHandle = (int)ThreadState.X0;
long MutexAddress = (long)Registers.X1; long MutexAddress = (long)ThreadState.X1;
int RequestingThreadHandle = (int)Registers.X2; int RequestingThreadHandle = (int)ThreadState.X2;
HThread RequestingThread = Ns.Os.Handles.GetData<HThread>(RequestingThreadHandle); HThread RequestingThread = Ns.Os.Handles.GetData<HThread>(RequestingThreadHandle);
@ -19,27 +19,27 @@ namespace Ryujinx.OsHle.Svc
M.WaitForLock(RequestingThread, RequestingThreadHandle); M.WaitForLock(RequestingThread, RequestingThreadHandle);
Registers.X0 = (int)SvcResult.Success; ThreadState.X0 = (int)SvcResult.Success;
} }
private void SvcArbitrateUnlock(ARegisters Registers) private void SvcArbitrateUnlock(AThreadState ThreadState)
{ {
long MutexAddress = (long)Registers.X0; long MutexAddress = (long)ThreadState.X0;
if (Ns.Os.Mutexes.TryGetValue(MutexAddress, out Mutex M)) if (Ns.Os.Mutexes.TryGetValue(MutexAddress, out Mutex M))
{ {
M.Unlock(); M.Unlock();
} }
Registers.X0 = (int)SvcResult.Success; ThreadState.X0 = (int)SvcResult.Success;
} }
private void SvcWaitProcessWideKeyAtomic(ARegisters Registers) private void SvcWaitProcessWideKeyAtomic(AThreadState ThreadState)
{ {
long MutexAddress = (long)Registers.X0; long MutexAddress = (long)ThreadState.X0;
long CondVarAddress = (long)Registers.X1; long CondVarAddress = (long)ThreadState.X1;
int ThreadHandle = (int)Registers.X2; int ThreadHandle = (int)ThreadState.X2;
long Timeout = (long)Registers.X3; long Timeout = (long)ThreadState.X3;
HThread Thread = Ns.Os.Handles.GetData<HThread>(ThreadHandle); HThread Thread = Ns.Os.Handles.GetData<HThread>(ThreadHandle);
@ -60,20 +60,20 @@ namespace Ryujinx.OsHle.Svc
M.WaitForLock(Thread, ThreadHandle); M.WaitForLock(Thread, ThreadHandle);
Registers.X0 = (int)SvcResult.Success; ThreadState.X0 = (int)SvcResult.Success;
} }
private void SvcSignalProcessWideKey(ARegisters Registers) private void SvcSignalProcessWideKey(AThreadState ThreadState)
{ {
long CondVarAddress = (long)Registers.X0; long CondVarAddress = (long)ThreadState.X0;
int Count = (int)Registers.X1; int Count = (int)ThreadState.X1;
if (Ns.Os.CondVars.TryGetValue(CondVarAddress, out CondVar Cv)) if (Ns.Os.CondVars.TryGetValue(CondVarAddress, out CondVar Cv))
{ {
Cv.SetSignal(Count); Cv.SetSignal(Count);
} }
Registers.X0 = (int)SvcResult.Success; ThreadState.X0 = (int)SvcResult.Success;
} }
} }
} }

View file

@ -2,7 +2,6 @@
using Gal.OpenGL; using Gal.OpenGL;
using System; using System;
using System.IO; using System.IO;
using ChocolArm64;
namespace Ryujinx namespace Ryujinx
{ {