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 +