1 // 2 // Copyright (c) 2010-2024 Antmicro 3 // 4 // This file is licensed under the MIT License. 5 // Full license text is available in 'licenses/MIT.txt'. 6 // 7 using System; 8 using Antmicro.Renode.Core; 9 using Antmicro.Renode.Logging; 10 using Antmicro.Renode.Time; 11 using ELFSharp.ELF; 12 using Machine = Antmicro.Renode.Core.Machine; 13 14 namespace Antmicro.Renode.Peripherals.CPU 15 { 16 // parts of this class can be left unmodified; 17 // to integrate an external simulator you need to 18 // look for comments in the code below 19 public class ExternalCPU : BaseCPU, IGPIOReceiver, ITimeSink, IDisposable 20 { ExternalCPU(string cpuType, IMachine machine, Endianess endianness, CpuBitness bitness = CpuBitness.Bits32)21 public ExternalCPU(string cpuType, IMachine machine, Endianess endianness, CpuBitness bitness = CpuBitness.Bits32) 22 : base(0, cpuType, machine, endianness, bitness) 23 { 24 throw new Exception("This is only a stub class that should not be directly used in a platform"); 25 } 26 Start()27 public override void Start() 28 { 29 base.Start(); 30 31 // [Here goes an invocation enabling an external simulator (if needed)] 32 // [This can be used to initialize the simulator, but no actual instructions should be executed yet] 33 } 34 Reset()35 public override void Reset() 36 { 37 base.Reset(); 38 39 instructionsExecutedThisRound = 0; 40 totalExecutedInstructions = 0; 41 42 // [Here goes an invocation resetting the external simulator (if needed)] 43 // [This can be used to revert the internal state of the simulator to the initial form] 44 } 45 Dispose()46 public override void Dispose() 47 { 48 base.Dispose(); 49 // [Here goes an invocation disposing the external simulator (if needed)] 50 // [This can be used to clean all unmanaged resources used to communicate with the simulator] 51 } 52 OnGPIO(int number, bool value)53 public void OnGPIO(int number, bool value) 54 { 55 this.NoisyLog("IRQ {0}, value {1}", number, value); 56 if(!IsStarted) 57 { 58 return; 59 } 60 61 // [Here goes an invocation triggering an IRQ in the external simulator] 62 } 63 SetRegisterValue32(int register, uint value)64 public virtual void SetRegisterValue32(int register, uint value) 65 { 66 // [Here goes an invocation setting the register value in the external simulator] 67 } 68 GetRegisterValue32(int register)69 public virtual uint GetRegisterValue32(int register) 70 { 71 // [Here goes an invocation reading the register value from the external simulator] 72 return 0; 73 } 74 ExecuteInstructions(ulong numberOfInstructionsToExecute, out ulong numberOfExecutedInstructions)75 public override ExecutionResult ExecuteInstructions(ulong numberOfInstructionsToExecute, out ulong numberOfExecutedInstructions) 76 { 77 instructionsExecutedThisRound = 0UL; 78 79 try 80 { 81 // [Here comes the invocation of the external simulator for the given amount of instructions] 82 // [This is the place where simulation of acutal instructions is to be executed] 83 } 84 catch(Exception) 85 { 86 this.NoisyLog("CPU exception detected, halting."); 87 InvokeHalted(new HaltArguments(HaltReason.Abort, this)); 88 return ExecutionResult.Aborted; 89 } 90 finally 91 { 92 numberOfExecutedInstructions = instructionsExecutedThisRound; 93 totalExecutedInstructions += instructionsExecutedThisRound; 94 } 95 96 return ExecutionResult.Ok; 97 } 98 99 public override string Architecture => "Unknown"; 100 101 public override RegisterValue PC 102 { 103 get 104 { 105 return GetRegisterValue32(PCRegisterId); 106 } 107 108 set 109 { 110 SetRegisterValue32(PCRegisterId, value); 111 } 112 } 113 114 public override ulong ExecutedInstructions => totalExecutedInstructions; 115 116 private ulong instructionsExecutedThisRound; 117 private ulong totalExecutedInstructions; 118 119 // [This needs to be mapped to the id of the Program Counter register used by the simulator] 120 private const int PCRegisterId = 0; 121 } 122 } 123