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
