sencha: track mpact-cheriot changes
- support for built-in clint
- support for stock risc-v core
Change-Id: I4c77b70e7158b10a55402cfffea4228ad4ea7d29
diff --git a/shodan_infrastructure/MpactCPU.cs b/shodan_infrastructure/MpactCPU.cs
index 35eb53f..981cbe3 100644
--- a/shodan_infrastructure/MpactCPU.cs
+++ b/shodan_infrastructure/MpactCPU.cs
@@ -57,7 +57,7 @@
}
// The MpactCPU class. This class derives from BaseCPU, which implements
-// a CPU in ReNode. It is the base implemenation of the interface between
+// a CPU in ReNode. It is the base implementation of the interface between
// ReNode and the mpact_sim based simulators.
public class MpactBaseCPU : BaseCPU, ICPUWithRegisters,
IGPIOReceiver, ITimeSink,
@@ -253,12 +253,10 @@
[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");
+ if (registerMap.Count == 0) {
+ GetMpactRegisters();
}
- Int64 value = Marshal.ReadInt64(value_ptr);
- return Convert.ToUInt32(value);
+ return GetRegisterUnsafe(PC_ID);
}
set {
@@ -348,7 +346,8 @@
break;
}
} else {
- LogAndThrowRE("Unknown register id: {register}");
+ string msg = $"Unknown register id: {register} not found";
+ LogAndThrowRE(msg);
}
return (ulong)0;
}
diff --git a/shodan_infrastructure/MpactCheriotCPU.cs b/shodan_infrastructure/MpactCheriotCPU.cs
index f9e2ef8..c75db30 100644
--- a/shodan_infrastructure/MpactCheriotCPU.cs
+++ b/shodan_infrastructure/MpactCheriotCPU.cs
@@ -73,6 +73,14 @@
config_names.Add("memProfile");
config_values.Add("0x1");
}
+ if (clint_mmr_base != 0) {
+ config_names.Add("clintMMRBase");
+ config_values.Add(clint_mmr_base.ToString("X"));
+ }
+ if (clint_period != 0) {
+ config_names.Add("clintPeriod");
+ config_values.Add(clint_period.ToString("X"));
+ }
}
public bool InstProfile {
@@ -85,6 +93,16 @@
set => mem_profile = value;
}
+ public UInt64 ClintMMRBase {
+ get => clint_mmr_base;
+ set => clint_mmr_base = value;
+ }
+
+ public UInt64 ClintPeriod {
+ get => clint_period;
+ set => clint_period = value;
+ }
+
// ICPUWithHooks methods.
public void AddHookAtInterruptBegin(Action<ulong> hook) {
@@ -155,6 +173,8 @@
private bool inst_profile = false;
private bool mem_profile = false;
private UInt64 revocationMemBase;
+ private UInt64 clint_mmr_base = 0x0;
+ private UInt64 clint_period = 0;
private List<GDBFeatureDescriptor>
gdbFeatures = new List<GDBFeatureDescriptor>();
} // class MpactCheriotCPU
diff --git a/shodan_infrastructure/MpactRiscVCPU.cs b/shodan_infrastructure/MpactRiscVCPU.cs
new file mode 100644
index 0000000..ca93625
--- /dev/null
+++ b/shodan_infrastructure/MpactRiscVCPU.cs
@@ -0,0 +1,190 @@
+//
+// Copyright (c) 2010-2024 Antmicro
+//
+// This file is licensed under the MIT License.
+// Full license text is available in 'licenses/MIT.txt'.
+//
+//
+// Copyright (c) 2024 Google LLC
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file or at
+// https://opensource.org/licenses/MIT.
+//
+
+// This file specializes the MpactCPU class to add custom interfaces and
+// properties required for the mpact_cheriot simulator.
+
+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;
+using Antmicro.Renode.Peripherals.MpactCPU;
+using ELFSharp.ELF;
+using ELFSharp.UImage;
+
+namespace Antmicro.Renode.Peripherals.MpactCPU
+{
+
+// The MpactRiscvCPU class. This class derives from BaseCPU, which implements
+// a CPU in ReNode. It is the interface between ReNode and the mpact_riscv32/64
+// simulator libraries.
+public class MpactRiscVCPU : MpactBaseCPU, ICpuSupportingGdb {
+
+ public MpactRiscVCPU(uint id, UInt64 memoryBase, UInt64 memorySize,
+ string cpuType, IMachine machine,
+ Endianess endianness,
+ CpuBitness bitness = CpuBitness.Bits32)
+ : base(id, memoryBase, memorySize, cpuType, machine, endianness,
+ bitness) {
+ }
+
+ ~MpactRiscVCPU() {
+ }
+
+
+ public override string Architecture { get { return "MpactRiscV";} }
+
+ public override void SetMpactConfig(List<string> config_names,
+ List<string> config_values) {
+ base.SetMpactConfig(config_names, config_values);
+ if (inst_profile) {
+ config_names.Add("instProfile");
+ config_values.Add("0x1");
+ }
+ if (mem_profile) {
+ config_names.Add("memProfile");
+ config_values.Add("0x1");
+ }
+ // Stack
+ if (stack_size_set) {
+ config_names.Add("stackSize");
+ config_values.Add(stack_size.ToString("X"));
+ }
+ if (stack_end_set) {
+ config_names.Add("stackEnd");
+ config_values.Add(stack_end.ToString("X"));
+ }
+ }
+
+ public bool InstProfile {
+ get => inst_profile;
+ set => inst_profile = value;
+ }
+
+ public bool MemProfile {
+ get => mem_profile;
+ set => mem_profile = value;
+ }
+
+ public ulong StackSize {
+ get => stack_size;
+ set {
+ stack_size = value;
+ stack_size_set = true;
+ }
+ }
+
+ public ulong StackEnd {
+ get => stack_end;
+ set {
+ stack_end = value;
+ stack_end_set = true;
+ }
+ }
+
+ // 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 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 */ }
+
+ // ICPUSupportingGdb methods.
+
+ public void EnterSingleStepModeSafely(HaltArguments args) {
+ // this method should only be called from CPU thread,
+ // but we should check it anyway
+ CheckCpuThreadId();
+
+ ExecutionMode = ExecutionMode.SingleStep;
+
+ UpdateHaltedState();
+ InvokeHalted(args);
+ }
+
+ public string GDBArchitecture { get { return "riscv:riscv"; } }
+
+ 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);
+
+ return gdbFeatures;
+ }
+ }
+
+ // End of ICpuSupportingGdb methods.
+
+ private bool inst_profile = false;
+ private bool mem_profile = false;
+ private ulong stack_size;
+ private bool stack_size_set = false;
+ private ulong stack_end;
+ private bool stack_end_set = false;
+ private List<GDBFeatureDescriptor>
+ gdbFeatures = new List<GDBFeatureDescriptor>();
+} // class MpactRiscVCPU
+
+} // namespace Antmicro.Renode.Peripherals.MpactCPU
+