sencha: track changes to MpactCheriotCPU.cs
- MpactCheriotPeripheral is now bundled with and bound to the
MpactCherioCPU class; this includes combining the code in one file
- no more need to setup ram_smc; mpact sim is not shared any more
- CliPort -> CLIPort and WaitForCli -> WaitForCLI
- renode LoadELF now works (LoadBinary should too but not tested)
- constructors changed; adjust the c# code to match
- massive style changes to MpactCheriotCPU.cs
NB: this requires an update cheriot toolchain
Change-Id: I9034e06c7ffecf78312b38b59ef971256f78107d
diff --git a/platforms/sencha_smc.repl b/platforms/sencha_smc.repl
index c457b35..94937c5 100644
--- a/platforms/sencha_smc.repl
+++ b/platforms/sencha_smc.repl
@@ -25,11 +25,11 @@
memoryBase: 0x80000000
memorySize: 0x04000000
revocationMemoryBase: 0x83000000 // Shadow bitmap
- clintMMRBase: 0 // NB: disables simulator built-in impl
-ram_smc: MpactPeripheral.MpactCheriotPeripheral @ sysbus 0x80000000
+ram_smc: MpactCPU.MpactCheriotPeripheral @ sysbus 0x80000000
size: 0x04000000
- id: 1 // NB: must match MpactCheriotCPU.id
+ baseAddress: 0x80000000
+ mpactCpu: cpu1
// Control block for the SMC, lets us pause/restart the core at an arbitrary PC.
smc_control: MpactCPU.SmcCheriot_ControlBlock @ sysbus 0x54020000
diff --git a/sencha.resc b/sencha.resc
index b77b779..ceae2c4 100644
--- a/sencha.resc
+++ b/sencha.resc
@@ -21,8 +21,7 @@
include @sim/config/shodan_infrastructure/MpactCheriotCPU.cs
EnsureTypeIsLoaded "Antmicro.Renode.Peripherals.MpactCPU.MpactCheriotCPU"
-include @sim/config/shodan_infrastructure/MpactCheriotPeripheral.cs
-EnsureTypeIsLoaded "Antmicro.Renode.Peripherals.MpactPeripheral.MpactCheriotPeripheral"
+EnsureTypeIsLoaded "Antmicro.Renode.Peripherals.MpactCPU.MpactCheriotPeripheral"
EnsureTypeIsLoaded "Antmicro.Renode.Peripherals.CPU.RiscV32"
include @sim/config/shodan_infrastructure/KelvinCPU.cs
EnsureTypeIsLoaded "Antmicro.Renode.Peripherals.CPU.KelvinCPU"
@@ -62,12 +61,8 @@
# Override cli_port to enable the command line interface on the specified port.
$cli_port?= -1
-sysbus.cpu1 CliPort $cli_port
-sysbus.cpu1 WaitForCli true
-
-# Setup ram_smc to coordinate with cpu1
-sysbus.ram_smc CpuLibraryPath $cheriotLibrary
-sysbus.ram_smc Start
+sysbus.cpu1 CLIPort $cli_port
+sysbus.cpu1 WaitForCLI true
$tar ?= @out/cantrip/shodan/release/ext_flash.tar
$spi_flash_load_address ?= 0x44000000
diff --git a/shodan_infrastructure/MpactCheriotCPU.cs b/shodan_infrastructure/MpactCheriotCPU.cs
index 072ddaa..b814cd6 100644
--- a/shodan_infrastructure/MpactCheriotCPU.cs
+++ b/shodan_infrastructure/MpactCheriotCPU.cs
@@ -38,518 +38,758 @@
namespace Antmicro.Renode.Peripherals.MpactCPU
{
- // Declare some additional function signatures.
- [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- public delegate Int32 FuncInt32Int32ActionInt32(Int32 param0, ActionInt32 param1);
- [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- public delegate Int32 FuncInt32Int32Int32FuncInt32UInt64IntPtrInt32FuncInt32UInt64IntPtrInt32(Int32 param0, Int32 param1, FuncInt32UInt64IntPtrInt32 param2,
- FuncInt32UInt64IntPtrInt32 param3);
- [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- public delegate Int32 FuncInt32Int32FuncInt32UInt64IntPtrInt32FuncInt32UInt64IntPtrInt32(Int32 param0, FuncInt32UInt64IntPtrInt32 param1,
- FuncInt32UInt64IntPtrInt32 param2);
- [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- public delegate Int32 FuncInt32Int32StringArrStringArrInt32(Int32 param0, string[] param1, string[] param2, Int32 param3);
- [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- public delegate Int32 FuncInt32Int32Int32Bool(Int32 param0, Int32 param1, bool param2);
- public class MpactCheriotCPU : BaseCPU, ICpuSupportingGdb, ICPUWithRegisters, ICPUWithHooks, IGPIOReceiver, ITimeSink, IDisposable {
- [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi, Pack = 1)]
- private struct RegInfo {
- [FieldOffset(0)]
- public Int32 index;
- [FieldOffset(4)]
- public Int32 width;
- [FieldOffset(8)]
- public bool isGeneral;
- [FieldOffset(9)]
- public bool isReadOnly;
- }
+// This interface is implemented by MpactCheriotCPU and used by
+// MpactCheriotPeripheral to access memory in mpact_cheriot simulator
+public interface IMpactPeripheral : IBytePeripheral, IWordPeripheral,
+ IDoubleWordPeripheral,
+ IQuadWordPeripheral,
+ IMultibyteWritePeripheral {}
- public MpactCheriotCPU(uint id, UInt64 memoryBase, UInt64 memorySize,
- UInt64 revocationMemoryBase, UInt64 clintMMRBase,
- string cpuType, IMachine machine, Endianess endianness,
- CpuBitness bitness = CpuBitness.Bits32)
- : base(id, cpuType, machine, endianness, bitness)
- {
- this.memoryBase = memoryBase;
- this.memorySize = memorySize;
- revocationMemBase = revocationMemoryBase;
- clintBase = clintMMRBase;
- error_ptr = Marshal.AllocHGlobal(4);
- value_ptr = Marshal.AllocHGlobal(8);
- reg_info_ptr = Marshal.AllocHGlobal(Marshal.SizeOf<RegInfo>());
- string_ptr = Marshal.AllocHGlobal(maxStringLen);
- read_sysmem_delegate = new FuncInt32UInt64IntPtrInt32(ReadSysMemory);
- write_sysmem_delegate = new FuncInt32UInt64IntPtrInt32(WriteSysMemory);
- cpuLibraryRegistered = false;
- }
- ~MpactCheriotCPU() {
- Marshal.FreeHGlobal(error_ptr);
- Marshal.FreeHGlobal(value_ptr);
- Marshal.FreeHGlobal(reg_info_ptr);
- Marshal.FreeHGlobal(string_ptr);
- }
+// Struct containing info for loading binary image files.
+public struct BinFileLoadInfo {
+ public string file_name;
+ public UInt64 load_address;
+ public UInt64 entry_point;
+}
- public override string Architecture { get { return "MpactCheriot";} }
+// The MpactCheriotCPU class. This class derives from BaseCPU, which implements
+// a CPU in ReNode. It is the interface between ReNode and the mpact_cheriot
+// simulator library.
+public class MpactCheriotCPU : BaseCPU, ICpuSupportingGdb, ICPUWithRegisters,
+ ICPUWithHooks, IGPIOReceiver, ITimeSink,
+ IDisposable, IMpactPeripheral {
- public override void Start()
- {
- if (!cpuLibraryRegistered)
- {
- LogAndThrowRE("Failed to register cpu library");
- return;
- }
- base.Start();
+ // Structure for ReNode register information that is obtained from the
+ // simulator.
+ [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi, Pack = 1)]
+ private struct RegInfo {
+ [FieldOffset(0)]
+ public Int32 index;
+ [FieldOffset(4)]
+ public Int32 width;
+ [FieldOffset(8)]
+ public bool isGeneral;
+ [FieldOffset(9)]
+ public bool isReadOnly;
+ }
- // Simulator initialization code goes here.
- mpact_id = connect_with_sysbus((Int32)Id, maxStringLen, read_sysmem_delegate, write_sysmem_delegate);
- if (mpact_id < 0) {
- LogAndThrowRE("Failed to create simulator instance");
- return;
- }
- // Set up configuration array.
- var config_names = new List<string>();
- var config_values = new List<string>();
- config_names.Add("memoryBase");
- config_names.Add("memorySize");
- config_names.Add("revocationMemoryBase");
- config_names.Add("clintMMRBase");
- config_values.Add("0x" + memoryBase.ToString("X"));
- config_values.Add("0x" + memorySize.ToString("X"));
- config_values.Add("0x" + revocationMemBase.ToString("X"));
- config_values.Add("0x" + clintBase.ToString("X"));
+ public MpactCheriotCPU(uint id, UInt64 memoryBase, UInt64 memorySize,
+ UInt64 revocationMemoryBase, string cpuType,
+ IMachine machine, Endianess endianness,
+ CpuBitness bitness = CpuBitness.Bits32)
+ : base(id, cpuType, machine, endianness, bitness) {
+ this.memoryBase = memoryBase;
+ this.memorySize = memorySize;
+ revocationMemBase = revocationMemoryBase;
+ // Allocate space for marshaling data to/from simulator.
+ error_ptr = Marshal.AllocHGlobal(4);
+ value_ptr = Marshal.AllocHGlobal(8);
+ reg_info_ptr = Marshal.AllocHGlobal(Marshal.SizeOf<RegInfo>());
+ string_ptr = Marshal.AllocHGlobal(maxStringLen);
+ }
- if (cli_port != -1) {
- config_names.Add("cliPort");
- config_values.Add("0x" + cli_port.ToString("X"));
- config_names.Add("waitForCLI");
- config_values.Add("0x" + Convert.ToInt32(wait_for_cli).ToString("X"));
- }
+ ~MpactCheriotCPU() {
+ Marshal.FreeHGlobal(error_ptr);
+ Marshal.FreeHGlobal(value_ptr);
+ Marshal.FreeHGlobal(reg_info_ptr);
+ Marshal.FreeHGlobal(string_ptr);
+ }
- Int32 cfg_res = set_config(mpact_id, config_names.ToArray(), config_values.ToArray(), config_names.Count);
- if (cfg_res < 0) {
- LogAndThrowRE("Failed to set configuration information");
- }
- }
- public override void Reset()
- {
- base.Reset();
- instructionsExecutedThisRound = 0;
- totalExecutedInstructions = 0;
- // Call simulator to reset.
- reset(mpact_id);
- }
+ public override string Architecture { get { return "MpactCheriot";} }
- public override void Dispose()
- {
- base.Dispose();
- destruct(mpact_id);
- }
+ public override void Start() {
+ base.Start();
- public string CpuLibraryPath
- {
- get
- {
- return cpuLibraryPath;
- }
- set
- {
- if (!String.IsNullOrWhiteSpace(value))
- {
- if (cpuLibraryRegistered)
- {
- this.WarningLog("cpu library already registerd and " +
- "should not be updated again.");
- return;
- }
- cpuLibraryPath = value;
- try
- {
- binder = new NativeBinder(this, cpuLibraryPath);
- }
- catch (System.Exception e)
- {
- LogAndThrowRE("Failed to load CPU library: " + e.Message);
- }
- cpuLibraryRegistered = true;
- }
- else
- {
- return;
- }
- }
- }
+ // Set up configuration array.
+ var config_names = new List<string>();
+ var config_values = new List<string>();
+ config_names.Add("memoryBase");
+ config_names.Add("memorySize");
+ config_names.Add("revocationMemoryBase");
+ config_values.Add("0x" + memoryBase.ToString("X"));
+ config_values.Add("0x" + memorySize.ToString("X"));
+ config_values.Add("0x" + revocationMemBase.ToString("X"));
+ if (cli_port > 0) {
+ this.Log(LogLevel.Info, "Adding cli port");
+ config_names.Add("cliPort");
+ config_values.Add("0x" + cli_port.ToString("X"));
+ config_names.Add("waitForCLI");
+ config_values.Add("0x" + (wait_for_cli ? 1 : 0).ToString("X"));
+ }
+ Int32 cfg_res = set_config(mpact_id, config_names.ToArray(),
+ config_values.ToArray(), config_names.Count);
+ if (cfg_res < 0) {
+ LogAndThrowRE("Failed to set configuration information");
+ }
+ if (mpact_id < 0) {
+ LogAndThrowRE("Failed to create simulator instance");
+ return;
+ }
+ // Load executable file or bin file if specified. Otherwise it is
+ // handled by the system.
+ if (!executable_file.Equals("")) {
+ var entry_point = load_executable(mpact_id, executable_file,
+ error_ptr);
+ Int32 result = Marshal.ReadInt32(error_ptr);
+ if (result < 0) {
+ LogAndThrowRE("Failed to load executable");
+ }
+ PC = entry_point;
+ } else if (!bin_file_info.file_name.Equals("")) {
+ Int32 res = load_image(mpact_id, bin_file_info.file_name,
+ bin_file_info.load_address);
+ if (res < 0) {
+ LogAndThrowRE("Failed to load binary image");
+ }
+ PC = bin_file_info.entry_point;
+ }
+ }
- public int CliPort { get => cli_port; set => cli_port = value; }
- public bool WaitForCli
- {
- get => wait_for_cli;
- set => wait_for_cli = value;
- }
+ public override void Reset() {
+ base.Reset();
+ instructionsExecutedThisRound = 0;
+ totalExecutedInstructions = 0;
+ // Call simulator to reset.
+ reset(mpact_id);
+ }
- public override ulong ExecutedInstructions => totalExecutedInstructions;
+ public override void Dispose() {
+ base.Dispose();
+ // Cleanup: simulator and any unmanaged resources.
+ this.Log(LogLevel.Info, "destruct mpact");
+ destruct(mpact_id);
+ this.Log(LogLevel.Info, "done");
+ }
- public override ExecutionMode ExecutionMode
- {
- get
- {
- return executionMode;
- }
- set
- {
- lock(singleStepSynchronizer.Guard)
- {
- if (executionMode == value)
- {
- return;
- }
-
- executionMode = value;
-
- singleStepSynchronizer.Enabled = IsSingleStepMode;
- UpdateHaltedState();
- }
- }
- }
-
- [Register]
- public override RegisterValue PC
- {
- get
- {
- Int32 error = read_register(mpact_id, PC_ID, value_ptr);
- // TODO(torerik): Check for error.
- if (error < 0) {
- this.Log(LogLevel.Error, "Failed to read PC");
- }
- Int64 value = Marshal.ReadInt64(value_ptr);
- return Convert.ToUInt64(value);
- }
-
- set
- {
- Int32 error = write_register(mpact_id, PC_ID, value);
- // TODO(torerik): Check for error.
- if (error < 0) {
- this.Log(LogLevel.Error, "Failed to write PC");
- }
- }
- }
-
- protected override ExecutionResult ExecuteInstructions(ulong numberOfInstructionsToExecute, out ulong numberOfExecutedInstructions)
- {
- UInt64 instructionsExecutedThisRound = 0UL;
- ExecutionResult result = ExecutionResult.Ok;
- try
- {
- // Invoke simulator for the number of instructions.
- instructionsExecutedThisRound = step(mpact_id, numberOfInstructionsToExecute, error_ptr);
- // Parse the result.
- Int32 step_result = Marshal.ReadInt32(error_ptr);
- switch (step_result) {
- case -1:
- result = ExecutionResult.Aborted;
- break;
- case 0:
- result = ExecutionResult.Ok;
- break;
- case 1:
- result = ExecutionResult.Interrupted;
- break;
- case 2:
- result = ExecutionResult.WaitingForInterrupt;
- break;
- case 3:
- result = ExecutionResult.StoppedAtBreakpoint;
- break;
- case 4:
- result = ExecutionResult.StoppedAtWatchpoint;
- break;
- case 5:
- result = ExecutionResult.ExternalMmuFault;
- break;
- default:
- LogAndThrowRE("Unknown return value from step - " + step_result);
- break;
- }
- }
- catch (Exception)
- {
- this.NoisyLog("CPU exception detected, halting.");
- InvokeHalted(new HaltArguments(HaltReason.Abort, Id));
- return ExecutionResult.Aborted;
- }
- finally
- {
- numberOfExecutedInstructions = instructionsExecutedThisRound;
- totalExecutedInstructions += instructionsExecutedThisRound;
- }
-
- return result;
- }
-
- // ICPUWithRegisters methods implementations.
- public void SetRegisterUnsafe(int register, RegisterValue value) {
- var status = write_register((Int32)mpact_id, (Int32)register, (UInt64)value);
- if (status < 0) {
- LogAndThrowRE("Failed to write register " + register);
- }
- }
-
- public RegisterValue GetRegisterUnsafe(int register) {
- var status = read_register(mpact_id, register, value_ptr);
- if (status < 0) {
- LogAndThrowRE("Failed to read register " + register);
- }
- Int64 value = Marshal.ReadInt64(value_ptr);
- return (UInt64)value;
- }
-
- private void GetMpactRegisters() {
- if (registerMap.Count != 0) return;
- Int32 num_regs = get_reg_info_size(mpact_id);
- for (Int32 i = 0; i < num_regs; i++) {
- Int32 result = get_reg_info(mpact_id, i, string_ptr, reg_info_ptr);
- if (result < 0) {
- this.Log(LogLevel.Error, "Failed to get register info for index " + i);
- continue;
- }
- var reg_info = Marshal.PtrToStructure<RegInfo>(reg_info_ptr);
- var cpu_reg = new CPURegister(reg_info.index, reg_info.width, reg_info.isGeneral, reg_info.isReadOnly);
- var reg_name = Marshal.PtrToStringAuto(string_ptr);
- registerMap.Add(reg_info.index, cpu_reg);
- registerNamesMap.Add(reg_name, reg_info.index);
- }
- }
-
- public IEnumerable<CPURegister> GetRegisters() {
- if (registerMap.Count == 0) {
- GetMpactRegisters();
- }
- return registerMap.Values.OrderBy(x => x.Index);
- }
-
- public new string[,] GetRegistersValues() {
- if (registerMap.Count == 0) {
- GetMpactRegisters();
- }
- var result = new Dictionary<string, ulong>();
- foreach (var reg in registerNamesMap) {
- var status = read_register(mpact_id, reg.Value, value_ptr);
- if (status < 0) continue;
- Int64 value = Marshal.ReadInt64(value_ptr);
- result.Add(reg.Key, Convert.ToUInt64(value));
- }
- var table = new Table().AddRow("Name", "Value");
- table.AddRows(result, x=> x.Key, x=> "0x{0:X}".FormatWith(x.Value));
- return table.ToArray();
- }
-
- private void LogAndThrowRE(string info)
- {
- this.Log(LogLevel.Error, info);
- throw new RecoverableException(info);
- }
-
- public Int32 LoadImageFile(String file_name, UInt64 address) {
- return load_image(mpact_id, file_name, address);
+ public string CpuLibraryPath {
+ get {
+ return cpu_library_path;
}
+ set {
+ this.Log(LogLevel.Info, "Lib: " + value);
+ if (String.IsNullOrWhiteSpace(value)) {
+ cpu_library_path = value;
+ return;
+ }
+ if (cpu_library_bound) {
+ LogAndThrowRE("CPU library already bound to: "
+ + cpu_library_path);
+ }
+ cpu_library_path = value;
+ try {
+ binder = new NativeBinder(this, cpu_library_path);
+ }
+ catch (System.Exception e) {
+ LogAndThrowRE("Failed to load CPU library: " + e.Message);
+ }
+ cpu_library_bound = true;
- public void OnGPIO(int number, bool value) {
+ // Instantiate the simulator, passing in callbacks to read and write
+ // from/to the system bus.
+ read_sysmem_delegate =
+ new FuncInt32UInt64IntPtrInt32(ReadSysMemory);
+ write_sysmem_delegate =
+ new FuncInt32UInt64IntPtrInt32(WriteSysMemory);
+ mpact_id = construct_with_sysbus(maxStringLen,
+ read_sysmem_delegate,
+ write_sysmem_delegate);
+ }
+ }
+
+ public string ExecutableFile {
+ get => executable_file;
+ set => executable_file = value;
+ }
+
+ public BinFileLoadInfo BinFileInfo {
+ get => bin_file_info;
+ set => bin_file_info = value;
+ }
+
+ public int CLIPort { get => cli_port; set => cli_port = value; }
+
+ public bool WaitForCLI { get => wait_for_cli; set => wait_for_cli = value; }
+
+ public override ulong ExecutedInstructions => totalExecutedInstructions;
+
+ public override ExecutionMode ExecutionMode {
+ get { return executionMode; }
+ set {
+ lock(singleStepSynchronizer.Guard) {
+ if (executionMode == value) return;
+
+ executionMode = value;
+
+ singleStepSynchronizer.Enabled = IsSingleStepMode;
+ UpdateHaltedState();
+ }
+ }
+ }
+
+ [Register]
+ public override RegisterValue PC {
+ get {
+ Int32 error = read_register(mpact_id, PC_ID, value_ptr);
+ if (error < 0) {
+ this.Log(LogLevel.Error, "Failed to read PC");
+ }
+ Int64 value = Marshal.ReadInt64(value_ptr);
+ return Convert.ToUInt64(value);
+ }
+
+ set {
+ Int32 error = write_register(mpact_id, PC_ID, value);
+ if (error < 0) {
+ this.Log(LogLevel.Error, "Failed to write PC");
+ }
+ }
+ }
+
+ protected override ExecutionResult ExecuteInstructions(
+ ulong numberOfInstructionsToExecute,
+ out ulong numberOfExecutedInstructions) {
+ UInt64 instructionsExecutedThisRound = 0UL;
+ ExecutionResult result = ExecutionResult.Ok;
+ try {
+ // Invoke simulator for the number of instructions.
+ instructionsExecutedThisRound =
+ step(mpact_id, numberOfInstructionsToExecute, error_ptr);
+ // Parse the result.
+ Int32 step_result = Marshal.ReadInt32(error_ptr);
+ switch (step_result) {
+ case -1:
+ result = ExecutionResult.Aborted;
+ break;
+ case 0:
+ result = ExecutionResult.Ok;
+ break;
+ case 1:
+ result = ExecutionResult.Interrupted;
+ break;
+ case 2:
+ result = ExecutionResult.WaitingForInterrupt;
+ break;
+ case 3:
+ result = ExecutionResult.StoppedAtBreakpoint;
+ break;
+ case 4:
+ result = ExecutionResult.StoppedAtWatchpoint;
+ break;
+ case 5:
+ result = ExecutionResult.ExternalMmuFault;
+ break;
+ default:
+ LogAndThrowRE("Unknown return value from step - "
+ + step_result);
+ break;
+ }
+ }
+ catch (Exception) {
+ this.NoisyLog("CPU exception detected, halting.");
+ InvokeHalted(new HaltArguments(HaltReason.Abort, Id));
+ return ExecutionResult.Aborted;
+ }
+ finally {
+ numberOfExecutedInstructions = instructionsExecutedThisRound;
+ totalExecutedInstructions += instructionsExecutedThisRound;
+ }
+ return result;
+ }
+
+ // ICPUWithRegisters methods implementations.
+ public void SetRegisterUnsafe(int register, RegisterValue value) {
+ var status = write_register((Int32)mpact_id, (Int32)register,
+ (UInt64)value);
+ if (status < 0) {
+ LogAndThrowRE("Failed to write register " + register);
+ }
+ }
+
+ public RegisterValue GetRegisterUnsafe(int register) {
+ var status = read_register(mpact_id, register, value_ptr);
+ if (status < 0) {
+ LogAndThrowRE("Failed to read register " + register);
+ }
+ Int64 value = Marshal.ReadInt64(value_ptr);
+ return (UInt64)value;
+ }
+
+ private void GetMpactRegisters() {
+ if (registerMap.Count != 0) return;
+ Int32 num_regs = get_reg_info_size(mpact_id);
+ for (Int32 i = 0; i < num_regs; i++) {
+ Int32 result = get_reg_info(mpact_id, i, string_ptr, reg_info_ptr);
+ if (result < 0) {
+ this.Log(LogLevel.Error,
+ "Failed to get register info for index " + i);
+ continue;
+ }
+ var reg_info = Marshal.PtrToStructure<RegInfo>(reg_info_ptr);
+ var cpu_reg = new CPURegister(reg_info.index, reg_info.width,
+ reg_info.isGeneral,
+ reg_info.isReadOnly);
+ var reg_name = Marshal.PtrToStringAuto(string_ptr);
+ registerMap.Add(reg_info.index, cpu_reg);
+ registerNamesMap.Add(reg_name, reg_info.index);
+ }
+ }
+
+ public IEnumerable<CPURegister> GetRegisters() {
+ if (registerMap.Count == 0) {
+ GetMpactRegisters();
+ }
+ return registerMap.Values.OrderBy(x => x.Index);
+ }
+
+ public new string[,] GetRegistersValues() {
+ if (registerMap.Count == 0) {
+ GetMpactRegisters();
+ }
+ var result = new Dictionary<string, ulong>();
+ foreach (var reg in registerNamesMap) {
+ var status = read_register(mpact_id, reg.Value, value_ptr);
+ if (status < 0) continue;
+ Int64 value = Marshal.ReadInt64(value_ptr);
+ result.Add(reg.Key, Convert.ToUInt64(value));
+ }
+ var table = new Table().AddRow("Name", "Value");
+ table.AddRows(result, x=> x.Key, x=> "0x{0:X}".FormatWith(x.Value));
+ return table.ToArray();
+ }
+
+ private void LogAndThrowRE(string info) {
+ this.Log(LogLevel.Error, info);
+ throw new RecoverableException(info);
+ }
+
+ public Int32 LoadImageFile(String file_name, UInt64 address) {
+ return load_image(mpact_id, file_name, address);
+ }
+
+ public void OnGPIO(int number, bool value) {
if (mpact_id <= 0) {
this.Log(LogLevel.Noisy, "OnGPIO: no simulator, discard gpio {0}:{1}", number, value);
return;
}
- Int32 status = set_irq_value(mpact_id, number, value);
- if (status < 0) {
- Console.Error.WriteLine("Failure in setting irq value");
- }
- }
+ Int32 status = set_irq_value(mpact_id, number, value);
+ if (status < 0) {
+ Console.Error.WriteLine("Failure in setting irq value");
+ }
+ }
- public Int32 ReadSysMemory(UInt64 address, IntPtr buffer, Int32 length) {
- // Read from System Bus.
- switch (length) {
- case 1:
- var data8 = new byte[length];
- data8[0] = machine.SystemBus.ReadByte(address, this);
- Marshal.Copy(data8, 0, buffer, length);
- break;
- case 2:
- var data16 = new Int16[1];
- data16[0] = (Int16) machine.SystemBus.ReadWord(address, this);
- Marshal.Copy(data16, 0, buffer, 1);
- break;
- case 4:
- var data32 = new Int32[1];
- data32[0] = (Int32) machine.SystemBus.ReadDoubleWord(address, this);
- Marshal.Copy(data32, 0, buffer, 1);
- break;
- case 8:
- var data64 = new Int64[1];
- data64[0] = (Int64) machine.SystemBus.ReadQuadWord(address, this);
- Marshal.Copy(data64, 0, buffer, 1);
- break;
- default:
- var dataN = new byte[length];
- machine.SystemBus.ReadBytes(address, length, dataN, 0, false, this);
- Marshal.Copy(dataN, 0, buffer, length);
- break;
- }
- return length;
- }
+ public Int32 ReadSysMemory(UInt64 address, IntPtr buffer, Int32 length) {
+ // Read from System Bus.
+ switch (length) {
+ case 1:
+ var data8 = new byte[length];
+ data8[0] = machine.SystemBus.ReadByte(address, this);
+ Marshal.Copy(data8, 0, buffer, length);
+ break;
+ case 2:
+ var data16 = new Int16[1];
+ data16[0] = (Int16) machine.SystemBus.ReadWord(address, this);
+ Marshal.Copy(data16, 0, buffer, 1);
+ break;
+ case 4:
+ var data32 = new Int32[1];
+ data32[0] = (Int32) machine.SystemBus.ReadDoubleWord(address,
+ this);
+ Marshal.Copy(data32, 0, buffer, 1);
+ break;
+ case 8:
+ var data64 = new Int64[1];
+ data64[0] = (Int64) machine.SystemBus.ReadQuadWord(address,
+ this);
+ Marshal.Copy(data64, 0, buffer, 1);
+ break;
+ default:
+ var dataN = new byte[length];
+ machine.SystemBus.ReadBytes(address, length, dataN, 0, false,
+ this);
+ Marshal.Copy(dataN, 0, buffer, length);
+ break;
+ }
+ return length;
+ }
- public Int32 WriteSysMemory(UInt64 address, IntPtr buffer, Int32 length) {
- // Create a managed buffer for the store data.
- // Copy the store data to the managed buffer.
- // Write the data to the system bus.
- switch (length) {
- case 1:
- var data8 = new byte[1];
- Marshal.Copy(buffer, data8, 0, 1);
- machine.SystemBus.WriteByte(address, data8[0], this);
- break;
- case 2:
- var data16 = new Int16[1];
- Marshal.Copy(buffer, data16, 0, 1);
- machine.SystemBus.WriteWord(address, (ushort)data16[0], this);
- break;
- case 4:
- var data32 = new Int32[1];
- Marshal.Copy(buffer, data32, 0, 1);
- machine.SystemBus.WriteDoubleWord(address, (uint)data32[0], this);
- break;
- case 8:
- var data64 = new Int64[1];
- Marshal.Copy(buffer, data64, 0, 1);
- machine.SystemBus.WriteQuadWord(address, (ulong)data64[0], this);
- break;
- default:
- var dataN = new byte[length];
- Marshal.Copy(buffer, dataN, 0, length);
- machine.SystemBus.WriteBytes(dataN, address);
- break;
- }
- return length;
- }
+ public Int32 WriteSysMemory(UInt64 address, IntPtr buffer, Int32 length) {
+ switch (length) {
+ case 1:
+ var data8 = new byte[1];
+ Marshal.Copy(buffer, data8, 0, 1);
+ machine.SystemBus.WriteByte(address, data8[0], this);
+ break;
+ case 2:
+ var data16 = new Int16[1];
+ Marshal.Copy(buffer, data16, 0, 1);
+ machine.SystemBus.WriteWord(address, (ushort)data16[0], this);
+ break;
+ case 4:
+ var data32 = new Int32[1];
+ Marshal.Copy(buffer, data32, 0, 1);
+ machine.SystemBus.WriteDoubleWord(address, (uint)data32[0],
+ this);
+ break;
+ case 8:
+ var data64 = new Int64[1];
+ Marshal.Copy(buffer, data64, 0, 1);
+ machine.SystemBus.WriteQuadWord(address, (ulong)data64[0],
+ this);
+ break;
+ default:
+ var dataN = new byte[length];
+ Marshal.Copy(buffer, dataN, 0, length);
+ machine.SystemBus.WriteBytes(dataN, address);
+ break;
+ }
+ return length;
+ }
- // ICPUWithHooks methods.
+ // ICPUWithHooks methods.
- public void AddHookAtInterruptBegin(Action<ulong> hook) {
- throw new RecoverableException("Interrupt hooks not currently supported");
- }
- public void AddHookAtInterruptEnd(Action<ulong> hook) {
- throw new RecoverableException("Interrupt hooks not currently supported");
- }
- public void AddHookAtWfiStateChange(Action<bool> hook) {
- throw new RecoverableException("Wfi state change hook not currently supported");
- }
+ public void AddHookAtInterruptBegin(Action<ulong> hook) {
+ throw new RecoverableException(
+ "Interrupt hooks not currently supported");
+ }
+ public void AddHookAtInterruptEnd(Action<ulong> hook) {
+ throw new RecoverableException(
+ "Interrupt hooks not currently supported");
+ }
+ public void AddHookAtWfiStateChange(Action<bool> hook) {
+ throw new RecoverableException(
+ "Wfi state change hook not currently supported");
+ }
- public void AddHook(ulong addr, Action<ICpuSupportingGdb, ulong> hook) {
- throw new RecoverableException("Hooks not currently supported");
- }
- public void RemoveHook(ulong addr, Action<ICpuSupportingGdb, ulong> hook) {
- }
- public void RemoveHooksAt(ulong addr) {
- }
- public void RemoveAllHooks() {
- }
+ public void AddHook(ulong addr, Action<ICpuSupportingGdb, ulong> hook) {
+ throw new RecoverableException("Hooks not currently supported");
+ }
+ public void RemoveHook(ulong addr, Action<ICpuSupportingGdb, ulong> hook) {
+ /* empty */
+ }
+ public void RemoveHooksAt(ulong addr) { /* empty */ }
+ public void RemoveAllHooks() { /* empty */ }
- // ICpuSuportingGdb methods.
+ // ICpuSuportingGdb methods.
- public void EnterSingleStepModeSafely(HaltArguments args, bool? blocking = null) {
- CheckCpuThreadId();
- ChangeExecutionModeToSingleStep(blocking);
- UpdateHaltedState();
- InvokeHalted(args);
- }
+ public void EnterSingleStepModeSafely(HaltArguments args,
+ bool? blocking = null) {
+ CheckCpuThreadId();
+ ChangeExecutionModeToSingleStep(blocking);
+ UpdateHaltedState();
+ InvokeHalted(args);
+ }
- public string GDBArchitecture { get { return "riscv:cheriot"; } }
+ public string GDBArchitecture { get { return "riscv:cheriot"; } }
- public List<GDBFeatureDescriptor> GDBFeatures {
- get {
- if (gdbFeatures.Any()) return gdbFeatures;
+ public List<GDBFeatureDescriptor> GDBFeatures {
+ get {
+ if (gdbFeatures.Any()) return gdbFeatures;
- // Populate the register map if it hasn't been done yet.
- if (registerNamesMap.Count == 0) {
- GetMpactRegisters();
- }
- var cpuGroup = new GDBFeatureDescriptor("org.gnu.gdb.riscv.cpu");
- var intType = $"uint32";
- var c0_index = registerNamesMap["c0"];
- for (var i = 0u; i < 16; ++i) {
- cpuGroup.Registers.Add(new GDBRegisterDescriptor((uint)c0_index + i, 32u, $"c{i}", intType, "general"));
- }
- var pcc_index = registerNamesMap["pcc"];
- cpuGroup.Registers.Add(new GDBRegisterDescriptor((uint)pcc_index, 32u, "pcc", "code_ptr", "general"));
- gdbFeatures.Add(cpuGroup);
+ // Populate the register map if it hasn't been done yet.
+ if (registerNamesMap.Count == 0) {
+ GetMpactRegisters();
+ }
+ var cpuGroup = new GDBFeatureDescriptor("org.gnu.gdb.riscv.cpu");
+ var intType = $"uint32";
+ var c0_index = registerNamesMap["c0"];
+ for (var i = 0u; i < 16; ++i) {
+ cpuGroup.Registers.Add(
+ new GDBRegisterDescriptor((uint)c0_index + i, 32u,
+ $"c{i}", intType, "general"));
+ }
+ var pcc_index = registerNamesMap["pcc"];
+ cpuGroup.Registers.Add(
+ new GDBRegisterDescriptor((uint)pcc_index, 32u, "pcc",
+ "code_ptr", "general"));
+ gdbFeatures.Add(cpuGroup);
- return gdbFeatures;
- }
- }
+ return gdbFeatures;
+ }
+ }
- // End of ICpuSupportingGdb methods.
+ // End of ICpuSupportingGdb methods.
- private List<GDBFeatureDescriptor> gdbFeatures = new List<GDBFeatureDescriptor>();
- private UInt64 memoryBase;
- private UInt64 memorySize;
- private UInt64 revocationMemBase;
- private UInt64 clintBase;
- private Dictionary<Int32, CPURegister> registerMap = new Dictionary<Int32, CPURegister>();
- private Dictionary<string, Int32> registerNamesMap = new Dictionary<string, Int32>();
- private string cpuLibraryPath;
- private bool cpuLibraryRegistered;
- private int cli_port = -1;
- private bool wait_for_cli = false;
- private NativeBinder binder;
- private readonly object nativeLock;
- private readonly Int32 maxStringLen = 32;
- private IntPtr value_ptr {get; set;}
- private IntPtr error_ptr {get; set;}
- private IntPtr reg_info_ptr {get; set;}
- private IntPtr string_ptr {get; set;}
- private FuncInt32UInt64IntPtrInt32 read_sysmem_delegate;
- private FuncInt32UInt64IntPtrInt32 write_sysmem_delegate;
+ // IMpactPeripheral methods.
+ public void WriteByte(long address, byte value) {
+ var data8 = new byte[1];
+ data8[0] = (byte) value;
+ Marshal.Copy(data8, 0, value_ptr, 1);
+ write_memory(mpact_id, (UInt64) address + base_address, value_ptr, 1);
+ }
+
+ public byte ReadByte(long address) {
+ var data8 = new byte[1];
+ read_memory(mpact_id, (UInt64) address + base_address, value_ptr, 1);
+ Marshal.Copy(value_ptr, data8, 0, 1);
+ return (byte) data8[0];
+ }
+
+ public void WriteWord(long address, ushort value) {
+ var data16 = new Int16[1];
+ data16[0] = (Int16) value;
+ Marshal.Copy(data16, 0, value_ptr, 1);
+ write_memory(mpact_id, (UInt64) address + base_address, value_ptr, 2);
+ }
+
+ public ushort ReadWord(long address) {
+ var data16 = new Int16[1];
+ read_memory(mpact_id, (UInt64) address + base_address, value_ptr, 2);
+ Marshal.Copy(value_ptr, data16, 0, 1);
+ return (ushort) data16[0];
+ }
+
+ public void WriteDoubleWord(long address, uint value) {
+ var data32 = new Int32[1];
+ data32[0] = (Int32) value;
+ Marshal.Copy(data32, 0, value_ptr, 1);
+ write_memory(mpact_id, (UInt64) address + base_address, value_ptr, 4);
+ }
+
+ public uint ReadDoubleWord(long address) {
+ var data32 = new Int32[1];
+ read_memory(mpact_id, (UInt64) address + base_address, value_ptr, 4);
+ Marshal.Copy(value_ptr, data32, 0, 1);
+ return (uint) data32[0];
+ }
+
+ public void WriteQuadWord(long address, ulong value) {
+ var data64 = new Int64[1];
+ data64[0] = (Int64) value;
+ Marshal.Copy(data64, 0, value_ptr, 1);
+ write_memory(mpact_id, (UInt64) address + base_address, value_ptr, 8);
+ }
+
+ public ulong ReadQuadWord(long address) {
+ var data64 = new Int64[1];
+ read_memory(mpact_id, (UInt64) address + base_address, value_ptr, 8);
+ Marshal.Copy(value_ptr, data64, 0, 1);
+ return (ulong) data64[0];
+ }
+
+ public byte[] ReadBytes(long offset, int count, ICPU context = null) {
+ var bytes = new byte[count];
+ var byte_array_ptr = Marshal.AllocHGlobal(count);
+ read_memory(mpact_id, (UInt64) offset + base_address, byte_array_ptr,
+ count);
+ Marshal.Copy(value_ptr, bytes, 0, count);
+ Marshal.FreeHGlobal(byte_array_ptr);
+ return bytes;
+ }
+
+ public void WriteBytes(long offset, byte[] array, int startingIndex,
+ int count, ICPU context = null) {
+ var byte_array_ptr = Marshal.AllocHGlobal(count);
+ Marshal.Copy(array, startingIndex, byte_array_ptr, count);
+ write_memory(mpact_id, (UInt64) offset + base_address, byte_array_ptr,
+ count);
+ Marshal.FreeHGlobal(byte_array_ptr);
+ }
+
+ // End of IMpactPeripheral methods.
+
+ private int cli_port = -1;
+ private bool wait_for_cli = false;
+ private UInt64 base_address = 0;
+ private UInt64 size = 0;
+ private List<GDBFeatureDescriptor>
+ gdbFeatures = new List<GDBFeatureDescriptor>();
+ private UInt64 memoryBase;
+ private UInt64 memorySize;
+ private UInt64 revocationMemBase;
+ private Dictionary<Int32, CPURegister>
+ registerMap = new Dictionary<Int32, CPURegister>();
+ private Dictionary<string, Int32>
+ registerNamesMap = new Dictionary<string, Int32>();
+ private string executable_file = "";
+ private BinFileLoadInfo
+ bin_file_info = new BinFileLoadInfo {file_name = "",
+ load_address = 0,
+ entry_point = 0};
+ private string cpu_library_path = "";
+ private bool cpu_library_bound = false;
+ private NativeBinder binder;
+ private readonly object nativeLock;
+ private readonly Int32 maxStringLen = 32;
+
+ // Pointers used in marshaling data to/from the simulator library.
+ private IntPtr value_ptr {get; set;}
+ private IntPtr error_ptr {get; set;}
+ private IntPtr reg_info_ptr {get; set;}
+ private IntPtr string_ptr {get; set;}
+
+ // Declare some additional function signatures.
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ public delegate Int32 ConnectWithSysbus(Int32 param0, Int32 param1,
+ FuncInt32UInt64IntPtrInt32 param2,
+ FuncInt32UInt64IntPtrInt32 param3);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ public delegate Int32 ConstructWithSysbus(Int32 param0,
+ FuncInt32UInt64IntPtrInt32 param1,
+ FuncInt32UInt64IntPtrInt32 param2);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ public delegate Int32 SetConfig(Int32 param0, string[] param1,
+ string[] param2, Int32 param3);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ public delegate Int32 SetIrqValue(Int32 param0, Int32 param1, bool param2);
+
+ // Int32 read_sysmem_delegate(UInt64 address, IntPtr buffer, Int32 size)
+ private FuncInt32UInt64IntPtrInt32 read_sysmem_delegate;
+ // Int32 write_sysmem_delegate(UInt64 address, IntPtr buffer, Int32 size)
+ private FuncInt32UInt64IntPtrInt32 write_sysmem_delegate;
+
+ // Functions that are imported from the mpact sim library.
#pragma warning disable 649
- [Import(UseExceptionWrapper = false)]
- private FuncInt32Int32FuncInt32UInt64IntPtrInt32FuncInt32UInt64IntPtrInt32 construct_with_sysbus; // (Int32 id, Int32 callback(Uint64, IntPtr, Int32), Int32 callback(Uint64, IntPtr, Int32));
- [Import(UseExceptionWrapper = false)]
- private FuncInt32Int32Int32FuncInt32UInt64IntPtrInt32FuncInt32UInt64IntPtrInt32 connect_with_sysbus; // (Int32 id, Int32 callback(Uint64, IntPtr, Int32), Int32 callback(Uint64, IntPtr, Int32));
- [Import(UseExceptionWrapper = false)]
- private ActionInt32 destruct; // (Int32 id);
- [Import(UseExceptionWrapper = false)]
- private ActionInt32 reset; // (Int32 id);
- [Import(UseExceptionWrapper = false)]
- private FuncInt32Int32 get_reg_info_size; // (Int32 id)
- [Import(UseExceptionWrapper = false)]
- private FuncInt32Int32Int32IntPtrIntPtr get_reg_info; // (Int32 id, IntPtr *name, IntPtr *struct);
- [Import(UseExceptionWrapper = false)]
- private FuncUInt64Int32StringIntPtr load_executable; // (Int32 id, String file_name);
- [Import(UseExceptionWrapper = false)]
- private FuncInt32Int32StringUInt64 load_image; // (Int32 id, String file_name, UInt64 address);
- [Import(UseExceptionWrapper = false)]
- private FuncUInt64Int32UInt64IntPtr step; // (Int32 id, UInt64 step, IntPtr *error);
- [Import(UseExceptionWrapper = false)]
- private FuncInt32Int32Int32IntPtr read_register; // (Int32 id, Int32 reg_id, IntPtr *value);
- [Import(UseExceptionWrapper = false)]
- private FuncInt32Int32Int32UInt64 write_register; // (Int32 id, Int32 reg_id, UInt64 value);
- [Import(UseExceptionWrapper = false)]
- private FuncInt32Int32UInt64IntPtrInt32 read_memory; // (Int32 id, UInt64 address, IntPtr buffer, Int32 size);
- [Import(UseExceptionWrapper = false)]
- private FuncInt32Int32UInt64IntPtrInt32 write_memory; // (Int32 id, UInt64 address, IntPtr buffer, Int32 size);
- // Set config.
- [Import(UseExceptionWrapper = false)]
- private FuncInt32Int32StringArrStringArrInt32 set_config; // Int32 set_config(Int32 id, string[] names string[] values, Int32 size);
- [Import(UseExceptionWrapper = false)]
- private FuncInt32Int32Int32Bool set_irq_value; // Int32 set_irq_value(Int32 id, Int32 irq_no, bool value);
+ [Import(UseExceptionWrapper = false)]
+ // Int32 construct_with_sysbus(Int32 id,
+ // Int32 read_callback(UInt64, IntPtr, Int32),
+ // Int32 write_callback(UInt64, IntPtr, Int32));
+ private ConstructWithSysbus construct_with_sysbus;
+
+ [Import(UseExceptionWrapper = false)]
+ // Int32 connect_with_sybsus(Int32 id,
+ // Int32 read_callback(UInt64, IntPtr, Int32),
+ // Int32 write_callback(UInt64, IntPtr, Int32));
+ private ConnectWithSysbus connect_with_sysbus;
+
+ [Import(UseExceptionWrapper = false)]
+ // void destruct(Int32 id);
+ private ActionInt32 destruct;
+
+ [Import(UseExceptionWrapper = false)]
+ // void reset(Int32 id);
+ private ActionInt32 reset;
+
+ [Import(UseExceptionWrapper = false)]
+ // Int32 get_reg_info_size(Int32 id)
+ private FuncInt32Int32 get_reg_info_size;
+
+ [Import(UseExceptionWrapper = false)]
+ // Int32 get_reg_info(Int32 id, IntPtr *name, IntPtr *struct);
+ private FuncInt32Int32Int32IntPtrIntPtr get_reg_info;
+
+ [Import(UseExceptionWrapper = false)]
+ // UInt64 load_executable(Int32 id, String file_name);
+ private FuncUInt64Int32StringIntPtr load_executable;
+
+ [Import(UseExceptionWrapper = false)]
+ // Int32 load_image(Int32 id, String file_name, UInt64 address);
+ private FuncInt32Int32StringUInt64 load_image;
+
+ [Import(UseExceptionWrapper = false)]
+ // UInt64 step(Int32 id, UInt64 step, IntPtr *error);
+ private FuncUInt64Int32UInt64IntPtr step;
+
+ [Import(UseExceptionWrapper = false)]
+ // Int32 read_register(Int32 id, Int32 reg_id, IntPtr *value);
+ private FuncInt32Int32Int32IntPtr read_register;
+
+ [Import(UseExceptionWrapper = false)]
+ // Int32 write_register(Int32 id, Int32 reg_id, UInt64 value);
+ private FuncInt32Int32Int32UInt64 write_register;
+
+ [Import(UseExceptionWrapper = false)]
+ // Int32 read_memory(Int32 id, UInt64 address, IntPtr buffer, Int32 size);
+ private FuncInt32Int32UInt64IntPtrInt32 read_memory;
+
+ [Import(UseExceptionWrapper = false)]
+ // Int32 write_memory(Int32 id, UInt64 address, IntPtr buffer, Int32 size);
+ private FuncInt32Int32UInt64IntPtrInt32 write_memory;
+
+ [Import(UseExceptionWrapper = false)]
+ // Int32 set_config(Int32 id, string[] names string[] values, Int32 size);
+ private SetConfig set_config;
+
+ [Import(UseExceptionWrapper = false)]
+ // Int32 set_irq_value(Int32 id, Int32 irq_no, bool value);
+ private SetIrqValue set_irq_value;
#pragma warning restore 649
- private Int32 mpact_id {get; set;}
- private ulong instructionsExecutedThisRound {get; set;}
- private ulong totalExecutedInstructions {get; set;}
- private const int PC_ID = 0x07b1;
+ private Int32 mpact_id {get; set;}
+ private ulong instructionsExecutedThisRound {get; set;}
+ private ulong totalExecutedInstructions {get; set;}
+ private const int PC_ID = 0x07b1;
+} // class MpactCheriotCPU
+
+
+// Peripheral interface class.
+public class MpactCheriotPeripheral : IKnownSize, IBytePeripheral,
+ IWordPeripheral, IDoubleWordPeripheral,
+ IQuadWordPeripheral,
+ IMultibyteWritePeripheral, IDisposable {
+
+ public MpactCheriotPeripheral(IMachine machine, long baseAddress,
+ long size, IMpactPeripheral mpactCpu) {
+ if (size == 0) {
+ throw new ConstructionException("Memory size cannot be 0");
}
-}
+ this.machine = machine;
+ this.size = size;
+ this.base_address = baseAddress;
+ this.mpact_cpu = mpactCpu;
+ }
+
+ public void Reset() {}
+
+ public void Dispose() {}
+
+ // All memory accesses are forwarded to the mpactCpu with the base_address
+ // added to the address field.
+ public void WriteByte(long address, byte value) {
+ mpact_cpu.WriteByte(address + base_address, value);
+ }
+
+ public byte ReadByte(long address) {
+ return mpact_cpu.ReadByte(address + base_address);
+ }
+
+ public void WriteWord(long address, ushort value) {
+ mpact_cpu.WriteWord(address + base_address, value);
+ }
+
+ public ushort ReadWord(long address) {
+ return mpact_cpu.ReadWord(address + base_address);
+ }
+
+ public void WriteDoubleWord(long address, uint value) {
+ mpact_cpu.WriteDoubleWord(address + base_address, value);
+ }
+
+ public uint ReadDoubleWord(long address) {
+ return mpact_cpu.ReadDoubleWord(address + base_address);
+ }
+
+ public void WriteQuadWord(long address, ulong value) {
+ mpact_cpu.WriteQuadWord(address + base_address, value);
+ }
+
+ public ulong ReadQuadWord(long address) {
+ return mpact_cpu.ReadQuadWord(address + base_address);
+ }
+
+ public byte[] ReadBytes(long offset, int count, ICPU context = null) {
+ return mpact_cpu.ReadBytes(offset + base_address, count, context);
+ }
+
+ public void WriteBytes(long offset, byte[] array, int startingIndex,
+ int count, ICPU context = null) {
+ mpact_cpu.WriteBytes(offset + base_address, array, startingIndex,
+ count, context);
+ }
+
+ public long Size { get { return size;} }
+ private IMpactPeripheral mpact_cpu;
+ private long size;
+ private long base_address = 0;
+ private IMachine machine;
+
+} // class MpactCheriotPeripheral
+
+} // namespace Antmicro.Renode.Peripherals.MpactCPU
diff --git a/shodan_infrastructure/MpactCheriotPeripheral.cs b/shodan_infrastructure/MpactCheriotPeripheral.cs
deleted file mode 100644
index e885bfa..0000000
--- a/shodan_infrastructure/MpactCheriotPeripheral.cs
+++ /dev/null
@@ -1,180 +0,0 @@
-using System;
-using System.Linq;
-using System.Runtime.InteropServices;
-using System.Threading;
-using System.Collections.Generic;
-using System.Collections.Concurrent;
-using Antmicro.Renode.Core;
-using Antmicro.Renode.Debugging;
-using Antmicro.Renode.Exceptions;
-using Antmicro.Renode.Hooks;
-using Antmicro.Renode.Logging;
-using Antmicro.Renode.Peripherals;
-using Antmicro.Renode.Peripherals.Bus;
-using Antmicro.Renode.Peripherals.CPU;
-using Antmicro.Renode.Peripherals.Timers;
-using Antmicro.Renode.Peripherals.CPU.Disassembler;
-using Antmicro.Renode.Peripherals.CPU.Registers;
-using Antmicro.Renode.Utilities;
-using Antmicro.Renode.Time;
-using Antmicro.Renode.Utilities.Binding;
-
-namespace Antmicro.Renode.Peripherals.MpactPeripheral {
-
- [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- public delegate Int32 FuncInt32Int32Int32FuncInt32UInt64IntPtrInt32FuncInt32UInt64IntPtrInt32(Int32 param0, Int32 param1,
- FuncInt32UInt64IntPtrInt32 param2, FuncInt32UInt64IntPtrInt32 param3);
-
- public class MpactCheriotPeripheral : IKnownSize, IBytePeripheral, IWordPeripheral, IDoubleWordPeripheral, IQuadWordPeripheral, IMultibyteWritePeripheral, IDisposable {
-
- public MpactCheriotPeripheral(IMachine machine, long size, int id) {
- if (size == 0) throw new ConstructionException("Memory size cannot be 0");
- this.machine = machine;
- this.size = size;
- this.id = id;
- cpuLibraryRegistered = false;
- error_ptr = Marshal.AllocHGlobal(4);
- value_ptr = Marshal.AllocHGlobal(8);
- string_ptr = Marshal.AllocHGlobal(maxStringLen);
- }
-
- public string CpuLibraryPath {
- get {
- return cpuLibraryPath;
- }
- set {
- if (!String.IsNullOrWhiteSpace(value)) {
- if (cpuLibraryRegistered) {
- this.WarningLog("cpu library already registerd and " +
- "should not be updated again.");
- return;
- }
- cpuLibraryPath = value;
- try {
- binder = new NativeBinder(this, cpuLibraryPath);
- } catch (System.Exception e) {
- LogAndThrowRE("Failed to load CPU library: " + e.Message);
- }
- cpuLibraryRegistered = true;
- } else {
- return;
- }
- }
- }
-
- public void Start() {
- if (!cpuLibraryRegistered) {
- LogAndThrowRE("Failed to register cpu library");
- return;
- }
- this.Log(LogLevel.Noisy, "Start simulator with id {0}", id);
- mpact_id = connect_with_sysbus(id, maxStringLen, null, null);
- if (mpact_id < 0) {
- LogAndThrowRE("Failed to create simulator instance");
- return;
- }
- }
-
- public void Reset() {}
- public void Dispose() {}
-
- public void WriteByte(long address, byte value) {
- var data8 = new byte[1];
- data8[0] = (byte) value;
- Marshal.Copy(data8, 0, value_ptr, 1);
- write_memory(mpact_id, (UInt64) address, value_ptr, 1);
- }
-
- public byte ReadByte(long address) {
- var data8 = new byte[1];
- read_memory(mpact_id, (UInt64) address, value_ptr, 1);
- Marshal.Copy(value_ptr, data8, 0, 1);
- return (byte) data8[0];
- }
-
- public void WriteWord(long address, ushort value) {
- var data16 = new Int16[1];
- data16[0] = (Int16) value;
- Marshal.Copy(data16, 0, value_ptr, 1);
- write_memory(mpact_id, (UInt64) address, value_ptr, 2);
- }
-
- public ushort ReadWord(long address) {
- var data16 = new Int16[1];
- read_memory(mpact_id, (UInt64) address, value_ptr, 2);
- Marshal.Copy(value_ptr, data16, 0, 1);
- return (ushort) data16[0];
- }
-
- public void WriteDoubleWord(long address, uint value) {
- var data32 = new Int32[1];
- data32[0] = (Int32) value;
- Marshal.Copy(data32, 0, value_ptr, 1);
- write_memory(mpact_id, (UInt64) address, value_ptr, 4);
- }
-
- public uint ReadDoubleWord(long address) {
- var data32 = new Int32[1];
- read_memory(mpact_id, (UInt64) address, value_ptr, 4);
- Marshal.Copy(value_ptr, data32, 0, 1);
- return (uint) data32[0];
- }
-
- public void WriteQuadWord(long address, ulong value) {
- var data64 = new Int64[1];
- data64[0] = (Int64) value;
- Marshal.Copy(data64, 0, value_ptr, 1);
- write_memory(mpact_id, (UInt64) address, value_ptr, 8);
- }
-
- public ulong ReadQuadWord(long address) {
- var data64 = new Int64[1];
- read_memory(mpact_id, (UInt64) address, value_ptr, 8);
- Marshal.Copy(value_ptr, data64, 0, 1);
- return (ulong) data64[0];
- }
-
- public byte[] ReadBytes(long offset, int count, ICPU context = null) {
- var bytes = new byte[count];
- var byte_array_ptr = Marshal.AllocHGlobal(count);
- read_memory(mpact_id, (UInt64) offset, byte_array_ptr, count);
- Marshal.Copy(value_ptr, bytes, 0, count);
- Marshal.FreeHGlobal(byte_array_ptr);
- return bytes;
- }
-
- public void WriteBytes(long offset, byte[] array, int startingIndex, int count, ICPU context = null) {
- var byte_array_ptr = Marshal.AllocHGlobal(count);
- Marshal.Copy(array, startingIndex, byte_array_ptr, count);
- write_memory(mpact_id, (UInt64) offset, byte_array_ptr, count);
- Marshal.FreeHGlobal(byte_array_ptr);
- }
-
- public long Size { get { return size;} }
- private Int32 mpact_id;
- private Int32 id {get; set;}
- private long size;
- private NativeBinder binder;
- private string cpuLibraryPath;
- private bool cpuLibraryRegistered;
- private IMachine machine;
- private readonly Int32 maxStringLen = 32;
- private IntPtr value_ptr {get; set;}
- private IntPtr error_ptr {get; set;}
- private IntPtr string_ptr {get; set;}
-
- private void LogAndThrowRE(string info) {
- this.Log(LogLevel.Error, info);
- throw new RecoverableException(info);
- }
-
- #pragma warning disable 649
- [Import(UseExceptionWrapper = false)]
- private FuncInt32Int32Int32FuncInt32UInt64IntPtrInt32FuncInt32UInt64IntPtrInt32 connect_with_sysbus; // (Int32 id, Int32 callback(Uint64, IntPtr, Int32), Int32 callback(Uint64, IntPtr, Int32));
- [Import(UseExceptionWrapper = false)]
- private FuncInt32Int32UInt64IntPtrInt32 read_memory; // (Int32 id, UInt64 address, IntPtr buffer, Int32 size);
- [Import(UseExceptionWrapper = false)]
- private FuncInt32Int32UInt64IntPtrInt32 write_memory; // (Int32 id, UInt64 address, IntPtr buffer, Int32 size);
- }
-
-} // namespace Antmicro.Renode.Peripherals.MpactPeripheral