diff --git a/cheriot.resc b/cheriot.resc
index bf46c98..1dce9fd 100644
--- a/cheriot.resc
+++ b/cheriot.resc
@@ -16,9 +16,11 @@
 
 mach create "cheriot"
 
+include @sim/config/shodan_infrastructure/MpactCPU.cs
+EnsureTypeIsLoaded "Antmicro.Renode.Peripherals.MpactCPU.MpactBaseCPU"
+EnsureTypeIsLoaded "Antmicro.Renode.Peripherals.MpactCPU.MpactPeripheral"
 include @sim/config/shodan_infrastructure/MpactCheriotCPU.cs
 EnsureTypeIsLoaded "Antmicro.Renode.Peripherals.MpactCPU.MpactCheriotCPU"
-EnsureTypeIsLoaded "Antmicro.Renode.Peripherals.MpactCPU.MpactCheriotPeripheral"
 
 $platformfile?=@sim/config/platforms/sail.repl
 
diff --git a/platforms/cheriot.repl b/platforms/cheriot.repl
index 59c12ec..9e82f1a 100644
--- a/platforms/cheriot.repl
+++ b/platforms/cheriot.repl
@@ -21,7 +21,7 @@
     memorySize: 0x10000000
     revocationMemoryBase: 0x83000000
 
-ram_smc : MpactCPU.MpactCheriotPeripheral @ sysbus 0x80000000
+ram_smc : MpactCPU.MpactPeripheral @ sysbus 0x80000000
     size: 0x10000000
     baseAddress: 0x80000000
     mpactCpu: cpu1
diff --git a/sencha.resc b/sencha.resc
index 3ba02e5..2a00994 100644
--- a/sencha.resc
+++ b/sencha.resc
@@ -19,9 +19,11 @@
 using sysbus
 mach create $name
 
+include @sim/config/shodan_infrastructure/MpactCPU.cs
+EnsureTypeIsLoaded "Antmicro.Renode.Peripherals.MpactCPU.MpactBaseCPU"
+EnsureTypeIsLoaded "Antmicro.Renode.Peripherals.MpactCPU.MpactPeripheral"
 include @sim/config/shodan_infrastructure/MpactCheriotCPU.cs
 EnsureTypeIsLoaded "Antmicro.Renode.Peripherals.MpactCPU.MpactCheriotCPU"
-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"
diff --git a/shodan_infrastructure/MpactCPU.cs b/shodan_infrastructure/MpactCPU.cs
new file mode 100644
index 0000000..01241ab
--- /dev/null
+++ b/shodan_infrastructure/MpactCPU.cs
@@ -0,0 +1,771 @@
+//
+// 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 is derived from ReNode plugin sources, but has been modified
+// so that it can be used as a plugin that interfaces with an mpact based
+// simulator that implement the mpact_renode "C" linkage interface.
+
+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 ELFSharp.ELF;
+using ELFSharp.UImage;
+
+namespace Antmicro.Renode.Peripherals.MpactCPU {
+
+// 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 {}
+
+
+// Struct containing info for loading binary image files.
+public struct BinFileLoadInfo {
+    public string file_name;
+    public UInt64 load_address;
+    public UInt64 entry_point;
+}
+
+// The MpactCPU class. This class derives from BaseCPU, which implements
+// a CPU in ReNode. It is the base implemenation of the interface between
+// ReNode and the mpact_sim based simulators.
+public class MpactBaseCPU : BaseCPU, ICPUWithRegisters,
+                            IGPIOReceiver, ITimeSink,
+                            IDisposable, IMpactPeripheral {
+
+    // 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;
+    }
+
+    public MpactBaseCPU(uint id, UInt64 memoryBase, UInt64 memorySize,
+                    string cpuType, IMachine machine, Endianess endianness,
+                    CpuBitness bitness = CpuBitness.Bits32)
+        : base(id, cpuType, machine, endianness, bitness) {
+        this.memoryBase = memoryBase;
+        this.memorySize = memorySize;
+        // 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);
+    }
+
+    ~MpactBaseCPU() {
+        Marshal.FreeHGlobal(error_ptr);
+        Marshal.FreeHGlobal(value_ptr);
+        Marshal.FreeHGlobal(reg_info_ptr);
+        Marshal.FreeHGlobal(string_ptr);
+    }
+
+
+    public override string Architecture { get { return "MpactSim";} }
+
+    public virtual void SetMpactConfig(List<string> config_names,
+		               List<string> config_values) {
+        config_names.Add("memoryBase");
+        config_names.Add("memorySize");
+        config_values.Add("0x" + memoryBase.ToString("X"));
+        config_values.Add("0x" + memorySize.ToString("X"));
+        if (cli_port != 0) {
+            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"));
+        }
+    }
+
+    public override void Start() {
+        base.Start();
+
+        // Set up configuration array.
+        var config_names = new List<string>();
+        var config_values = new List<string>();
+	SetMpactConfig(config_names, config_values);
+	// Configure mpact sim.
+        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");
+        }
+        // Load executable file, symbols only from executable file, or bin
+	// file if specified. Use symbols load if the executable is loaded
+	// by the system.
+        this.Log(LogLevel.Info, "symbol_file: '" + symbol_file + "'");
+        if (!executable_file.Equals("")) {
+            var entry_point = load_elf(mpact_id, executable_file,
+                                       /*for_symbols_only=*/false,
+                                       error_ptr);
+            Int32 result = Marshal.ReadInt32(error_ptr);
+            if (result < 0) {
+                LogAndThrowRE("Failed to load executable");
+            }
+            PC = entry_point;
+        } else if (!symbol_file.Equals("")) {
+            this.Log(LogLevel.Info, "loading symbol_file: '" + symbol_file + "'");
+            load_elf(mpact_id, symbol_file, /*for_symbols_only=*/true,
+                     error_ptr);
+            Int32 result = Marshal.ReadInt32(error_ptr);
+            if (result < 0) {
+                LogAndThrowRE("Failed to load symbols");
+            }
+        } 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 override void Reset() {
+        base.Reset();
+        instructionsExecutedThisRound = 0;
+        totalExecutedInstructions = 0;
+        // Call simulator to reset.
+        reset(mpact_id);
+    }
+
+    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 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;
+
+            // 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);
+            if (mpact_id < 0) {
+                LogAndThrowRE("Failed to create simulator instance");
+            }
+        }
+    }
+
+    public string ExecutableFile {
+        get => executable_file;
+        set => executable_file = value;
+    }
+
+    public string SymbolFile {
+        get => symbol_file;
+        set => symbol_file = value;
+    }
+
+    public BinFileLoadInfo BinFileInfo {
+        get => bin_file_info;
+        set => bin_file_info = value;
+    }
+
+    public ushort 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.ToUInt32(value);
+        }
+
+        set {
+            Int32 error = write_register(mpact_id, PC_ID, value);
+            if (error < 0) {
+                this.Log(LogLevel.Error, "Failed to write PC");
+            }
+        }
+    }
+
+    public 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);
+        CPURegister cpu_register;
+        if (registerMap.TryGetValue(register, out cpu_register)) {
+            var width = cpu_register.Width;
+            switch (width) {
+                case 8: return (byte)value;
+                case 16: return (ushort)value;
+                case 32: return (uint)value;
+                case 64: return (ulong)value;
+                default:
+                    LogAndThrowRE("Unexpected register width: {width}");
+                    break;
+            }
+        } else {
+            LogAndThrowRE("Unknown register id: {register}");
+        }
+        return (ulong)0;
+    }
+
+    protected 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");
+        }
+    }
+
+    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) {
+        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;
+    }
+
+    // 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, 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);
+    }
+
+    // End of IMpactPeripheral methods.
+    protected Dictionary<string, Int32>
+                registerNamesMap = new Dictionary<string, Int32>();
+
+    private ushort cli_port = 0;
+    private bool wait_for_cli = true;
+    private UInt64 size = 0;
+    private List<GDBFeatureDescriptor>
+                gdbFeatures = new List<GDBFeatureDescriptor>();
+    private UInt64 memoryBase;
+    private UInt64 memorySize;
+    private Dictionary<Int32, CPURegister>
+                registerMap = new Dictionary<Int32, CPURegister>();
+    private string executable_file = "";
+    private string symbol_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);
+
+    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+    public delegate UInt64 LoadElf(Int32 param0, string param1, bool param2,
+                                   IntPtr param3);
+
+    // 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)]
+    // 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_elf(Int32 id, String file_name,
+    //                 bool for_symbols_only, Int32* error_ptr);
+    private LoadElf load_elf;
+
+    [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 = -1;
+    private ulong instructionsExecutedThisRound {get; set;}
+    private ulong totalExecutedInstructions {get; set;}
+    private const int PC_ID = 0x07b1;
+}  // class MpactCheriotCPU
+
+
+// Peripheral interface class.
+public class MpactPeripheral : IKnownSize, IBytePeripheral,
+                               IWordPeripheral, IDoubleWordPeripheral,
+                               IQuadWordPeripheral,
+                               IMultibyteWritePeripheral, IDisposable {
+
+    public MpactPeripheral(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 MpactPeripheral
+
+}  // namespace Antmicro.Renode.Peripherals.MpactCPU
+
diff --git a/shodan_infrastructure/MpactCheriotCPU.cs b/shodan_infrastructure/MpactCheriotCPU.cs
index 3c5960e..dbb7afb 100644
--- a/shodan_infrastructure/MpactCheriotCPU.cs
+++ b/shodan_infrastructure/MpactCheriotCPU.cs
@@ -1,17 +1,19 @@
 //
+// 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
 //
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
+// 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.
 //
-//     https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
+
+// This file specializes the MpactCPU class to add custom interfaces and
+// properties required for the mpact_cheriot simulator.
 
 using System;
 using System.Linq;
@@ -33,435 +35,54 @@
 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
 {
 
-// 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 {}
-
-
-// Struct containing info for loading binary image files.
-public struct BinFileLoadInfo {
-    public string file_name;
-    public UInt64 load_address;
-    public UInt64 entry_point;
-}
-
 // 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 {
-
-    // 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;
-    }
+public class MpactCheriotCPU : MpactBaseCPU, ICpuSupportingGdb {
 
     public MpactCheriotCPU(uint id, UInt64 memoryBase, UInt64 memorySize,
-		           UInt64 revocationMemoryBase, string cpuType,
-			   IMachine machine, Endianess endianness,
+                           UInt64 revocationMemoryBase, string cpuType,
+                           IMachine machine, Endianess endianness,
                            CpuBitness bitness = CpuBitness.Bits32)
-        : base(id, cpuType, machine, endianness, bitness) {
-        this.memoryBase = memoryBase;
-        this.memorySize = memorySize;
+        : base(id, memoryBase, memorySize, cpuType, machine, endianness,
+               bitness) {
         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);
     }
 
     ~MpactCheriotCPU() {
-        Marshal.FreeHGlobal(error_ptr);
-        Marshal.FreeHGlobal(value_ptr);
-        Marshal.FreeHGlobal(reg_info_ptr);
-        Marshal.FreeHGlobal(string_ptr);
     }
 
 
     public override string Architecture { get { return "MpactCheriot";} }
 
-    public override void Start() {
-        base.Start();
-
-        // 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) {
-            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"));
+    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");
         }
-        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.
-        this.Log(LogLevel.Info, "symbol_file: '" + symbol_file + "'");
-        if (!executable_file.Equals("")) {
-            var entry_point = load_elf(mpact_id, executable_file,
-                                       /*for_symbols_only=*/false,
-                                       error_ptr);
-            Int32 result = Marshal.ReadInt32(error_ptr);
-            if (result < 0) {
-                LogAndThrowRE("Failed to load executable");
-            }
-            PC = entry_point;
-        } else if (!symbol_file.Equals("")) {
-            this.Log(LogLevel.Info, "loading symbol_file: '" + symbol_file + "'");
-            load_elf(mpact_id, symbol_file, /*for_symbols_only=*/true,
-                     error_ptr);
-            Int32 result = Marshal.ReadInt32(error_ptr);
-            if (result < 0) {
-                LogAndThrowRE("Failed to load symbols");
-            }
-        } 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;
+        if (mem_profile) {
+            config_names.Add("memProfile");
+            config_values.Add("0x1");
         }
     }
 
-    public override void Reset() {
-        base.Reset();
-        instructionsExecutedThisRound = 0;
-        totalExecutedInstructions = 0;
-        // Call simulator to reset.
-        reset(mpact_id);
+    public bool InstProfile {
+        get => inst_profile;
+        set => inst_profile = value;
     }
 
-    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 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;
-
-            // 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 string SymbolFile {
-        get => symbol_file;
-        set => symbol_file = value;
-    }
-
-    public BinFileLoadInfo BinFileInfo {
-        get => bin_file_info;
-        set => bin_file_info = value;
-    }
-
-    public ushort 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");
-            }
-        }
-    }
-
-    public 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 (UInt32)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");
-        }
-    }
-
-    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) {
-        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 bool MemProfile {
+        get => mem_profile;
+        set => mem_profile = value;
     }
 
     // ICPUWithHooks methods.
@@ -476,7 +97,7 @@
     }
     public void AddHookAtWfiStateChange(Action<bool> hook) {
         throw new RecoverableException(
-			"Wfi state change hook not currently supported");
+                        "Wfi state change hook not currently supported");
     }
 
     public void AddHook(ulong addr, Action<ICpuSupportingGdb, ulong> hook) {
@@ -488,10 +109,10 @@
     public void RemoveHooksAt(ulong addr) { /* empty */ }
     public void RemoveAllHooks() { /* empty */ }
 
-    // ICpuSuportingGdb methods.
+    // ICPUSupportingGdb methods.
 
     public void EnterSingleStepModeSafely(HaltArguments args,
-		                          bool? blocking = null) {
+                                          bool? blocking = null) {
         CheckCpuThreadId();
         ChangeExecutionModeToSingleStep(blocking);
         UpdateHaltedState();
@@ -513,13 +134,13 @@
             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"));
+                        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"));
+                        new GDBRegisterDescriptor((uint)pcc_index, 32u, "pcc",
+                                                  "code_ptr", "general"));
             gdbFeatures.Add(cpuGroup);
 
             return gdbFeatures;
@@ -528,290 +149,12 @@
 
     // End of ICpuSupportingGdb methods.
 
-    // 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 ushort cli_port = 0;
-    private bool wait_for_cli = true;
-    private UInt64 base_address = 0;
-    private UInt64 size = 0;
-    private List<GDBFeatureDescriptor>
-	        gdbFeatures = new List<GDBFeatureDescriptor>();
-    private UInt64 memoryBase;
-    private UInt64 memorySize;
+    private bool inst_profile = false;
+    private bool mem_profile = false;
     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 string symbol_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);
-
-    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-    public delegate UInt64 LoadElf(Int32 param0, string param1, bool param2,
-                                   IntPtr param3);
-
-    // 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)]
-    // 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_elf(Int32 id, String file_name,
-    //                 bool for_symbols_only, Int32* error_ptr);
-    private LoadElf load_elf;
-
-    [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 = -1;
-    private ulong instructionsExecutedThisRound {get; set;}
-    private ulong totalExecutedInstructions {get; set;}
-    private const int PC_ID = 0x07b1;
+    private List<GDBFeatureDescriptor>
+                gdbFeatures = new List<GDBFeatureDescriptor>();
 }  // 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
 
