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