public override void OnRead(IPlatformEngine engine, ulong address, uint size) { var ctx = engine.GetState <Ctx>(this); switch (address & 0xFFF) { case 0: // status engine.Write(address, BitConverter.GetBytes(ctx.Status)); if ((ctx.Status & 0x4) == 0x4) // is ready? { ctx.Data = ctx.WaitingData; ctx.Status ^= 0x4; } break; case 4: // cmd engine.Write(address, new byte[4]); break; case 8: // address engine.Write(address, BitConverter.GetBytes(ctx.Address)); break; case 12: // data engine.Write(address, BitConverter.GetBytes(ctx.Data)); break; default: throw new InvalidHwOperationException(engine, "Unknown register"); } }
public override void InitSimulator(IPlatformEngine sim) { if (FaultAddress % 2 == 1) { throw new NotSupportedException(); } uint hitCount = 0; sim.SetBreakPoint(FaultAddress, engine => { hitCount++; if (hitCount == BreakpointHitCount) // We hit the glitched instruction { engine.Write(FaultAddress, FaultedData); engine.RequestRestart(FaultAddress); } else if (hitCount == BreakpointHitCount + 1) // Execute glitched instruction { } else if (hitCount == BreakpointHitCount + 2) // Write back original instruction { engine.Write(FaultAddress, OriginalData); engine.RequestRestart(FaultAddress); } }); }
public override void InitSimulator(IPlatformEngine sim) { if (FaultAddress % 2 == 1) { throw new NotSupportedException(); } sim.Write(FaultAddress, FaultedData); }
FaultResult _runFaultSimulation(IFaultDefinition faultDefinition, IPlatformEngine sim) { sim.Init(); faultDefinition.InitSimulator(sim); var simResult = Result.Exception; SimulationException simException = null; try { simResult = sim.Run(); } catch (SimulationException e) { simException = e; } return(new FaultResult { Fault = faultDefinition, Result = simResult, Exception = simException }); }
public NotSupportedHwOperationException(IPlatformEngine engine, string message) : base($"{message} @ {engine.TracePC:X8}: {engine.CurrentInstruction}") { }
public NotSupportedHwOperationException(IPlatformEngine engine) : base($"Unknown exception in {new StackTrace()}.{new StackTrace().GetFrames()[1].GetMethod().Name} @ {engine.TracePC:X8}: {engine.CurrentInstruction}") { }
public InvalidHwOperationException(IPlatformEngine engine, string message, Exception innerException = null) : base($"{message} @ {engine.TracePC:X8}: {engine.CurrentInstruction}", innerException) { }
public PlatformEngineException(IPlatformEngine engine, string message, Exception innerException = null) : base(message, innerException) { Engine = engine; }
public virtual void OnWrite(IPlatformEngine engine, ulong address, uint size, ulong value) => throw new NotSupportedHwOperationException(engine, $"OnWrite({address:X16}, {size}, {value}) not implemented");
public override void OnWrite(IPlatformEngine engine, ulong address, uint size, ulong value) { var ctx = engine.GetState <Ctx>(this); switch (address & 0xFFF) { case 0: // status break; case 4: // cmd switch (value) { case 1: // OTP_CMD_INIT if (_otpOriginalData.Length == 0 && File.Exists(_otpBinPath)) { _otpOriginalData = File.ReadAllBytes(_otpBinPath); } else if (_otpOriginalData.Length == 0) { _otpOriginalData = new byte[4096]; } ctx.OTPData = _otpOriginalData; ctx.Status = 0x2; // ready break; case 2: // OTP_CMD_READ if ((ctx.Status & 0x2) == 0x2 && (ctx.Status & 0x4) == 0x0) // is ready and not working? { if (ctx.Address + 4 < (ulong)ctx.OTPData.Length) { ctx.WaitingData = (uint)(ctx.OTPData[ctx.Address] + (ctx.OTPData[ctx.Address + 1] << 8) + (ctx.OTPData[ctx.Address + 2] << 16) + (ctx.OTPData[ctx.Address + 3] << 24)); ctx.Status |= 0x4; // working } else { ctx.Status |= 0x1; // error } } break; case 3: // OTP_CMD_WRITE if ((ctx.Status & 0x2) == 0x2 && (ctx.Status & 0x4) == 0x0) // is ready and not working? { if (ctx.Address + 4 < (ulong)ctx.OTPData.Length) { ctx.OTPData[ctx.Address] = (byte)(ctx.OTPData[ctx.Address] | (byte)(ctx.Data & 0xFF)); ctx.OTPData[ctx.Address + 1] = (byte)(ctx.OTPData[ctx.Address + 1] | (byte)(ctx.Data >> 8 & 0xFF)); ctx.OTPData[ctx.Address + 2] = (byte)(ctx.OTPData[ctx.Address + 2] | (byte)(ctx.Data >> 16 & 0xFF)); ctx.OTPData[ctx.Address + 3] = (byte)(ctx.OTPData[ctx.Address + 3] | (byte)(ctx.Data >> 24 & 0xFF)); if (PersistentChanges) { _otpOriginalData = ctx.OTPData; File.WriteAllBytes(_otpBinPath, ctx.OTPData); } ctx.WaitingData = (uint)value; ctx.Status |= 0x4; // working } else { ctx.Status |= 0x1; // error } } break; default: throw new InvalidHwOperationException(engine, $"Unknown OTP command {value}"); } break; case 8: // address ctx.Address = (uint)value; break; case 12: // data ctx.Data = (uint)value; break; default: throw new InvalidHwOperationException(engine, "Unknown register"); } }
public abstract void InitSimulator(IPlatformEngine sim);
public void InitSimulator(IPlatformEngine sim) => throw new System.NotImplementedException();
public override void OnWrite(IPlatformEngine engine, ulong address, uint size, ulong value) { _onWrite?.Invoke(engine, address, size, value); }
public override void OnRead(IPlatformEngine engine, ulong address, uint size) { _onRead?.Invoke(engine, address, size); }