Rename ARegisters to AThreadState
This commit is contained in:
parent
5a0396efaf
commit
f35d286c8d
25 changed files with 303 additions and 301 deletions
|
@ -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]
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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;
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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()
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
Reference in a new issue