This updates the interface between ReNode and Mpact simulators.

This adds a cpu_type string to the connect and construct calls from ReNode.
This allows the cpu type that is configured in ReNode to be passed to Mpact,
allowing the Mpact simulator interface to customize the simulator instance
according to the configured CPU type.

PiperOrigin-RevId: 661288754
Change-Id: Idaa6e8d669e22b2331f8412020464ec7bd3a9133
diff --git a/mpact/sim/util/renode/renode_cs/MpactCPU.cs b/mpact/sim/util/renode/renode_cs/MpactCPU.cs
index 981cbe3..94dd699 100644
--- a/mpact/sim/util/renode/renode_cs/MpactCPU.cs
+++ b/mpact/sim/util/renode/renode_cs/MpactCPU.cs
@@ -81,6 +81,7 @@
                     string cpuType, IMachine machine, Endianess endianness,
                     CpuBitness bitness = CpuBitness.Bits32)
         : base(id, cpuType, machine, endianness, bitness) {
+        this.cpu_type = cpuType;
         this.memoryBase = memoryBase;
         this.memorySize = memorySize;
         // Allocate space for marshaling data to/from simulator.
@@ -203,7 +204,7 @@
                     new FuncInt32UInt64IntPtrInt32(ReadSysMemory);
             write_sysmem_delegate =
                     new FuncInt32UInt64IntPtrInt32(WriteSysMemory);
-            mpact_id = construct_with_sysbus(maxStringLen,
+            mpact_id = construct_with_sysbus(cpu_type, maxStringLen,
                                              read_sysmem_delegate,
                                              write_sysmem_delegate);
             if (mpact_id < 0) {
@@ -592,14 +593,14 @@
 
     // Declare some additional function signatures.
     [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-    public delegate Int32 ConnectWithSysbus(Int32 param0, Int32 param1,
-                                            FuncInt32UInt64IntPtrInt32 param2,
-                                            FuncInt32UInt64IntPtrInt32 param3);
+    public delegate Int32 ConnectWithSysbus(string param0, Int32 param1, Int32 param2,
+                                            FuncInt32UInt64IntPtrInt32 param3,
+                                            FuncInt32UInt64IntPtrInt32 param4);
 
     [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-    public delegate Int32 ConstructWithSysbus(Int32 param0,
-                                              FuncInt32UInt64IntPtrInt32 param1,
-                                              FuncInt32UInt64IntPtrInt32 param2);
+    public delegate Int32 ConstructWithSysbus(string param0, Int32 param1,
+                                              FuncInt32UInt64IntPtrInt32 param2,
+                                              FuncInt32UInt64IntPtrInt32 param3);
 
     [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
     public delegate Int32 SetConfig(Int32 param0, string[] param1,
@@ -620,13 +621,13 @@
     // Functions that are imported from the mpact sim library.
 #pragma warning disable 649
     [Import(UseExceptionWrapper = false)]
-    // Int32 construct_with_sysbus(Int32 id,
+    // Int32 construct_with_sysbus(string cpu_type, 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 connect_with_sybsus(string cpu_type, Int32 id,
     //                           Int32 read_callback(UInt64, IntPtr, Int32),
     //                           Int32 write_callback(UInt64, IntPtr, Int32));
     private ConnectWithSysbus connect_with_sysbus;
@@ -687,6 +688,7 @@
 #pragma warning restore 649
 
     private Int32 mpact_id = -1;
+    private string cpu_type;
     private ulong instructionsExecutedThisRound {get; set;}
     private ulong totalExecutedInstructions {get; set;}
     private const int PC_ID = 0x07b1;
diff --git a/mpact/sim/util/renode/renode_cs/MpactCheriotCPU.cs b/mpact/sim/util/renode/renode_cs/MpactCheriotCPU.cs
index c75db30..8abf5cc 100644
--- a/mpact/sim/util/renode/renode_cs/MpactCheriotCPU.cs
+++ b/mpact/sim/util/renode/renode_cs/MpactCheriotCPU.cs
@@ -42,6 +42,12 @@
 namespace Antmicro.Renode.Peripherals.MpactCPU
 {
 
+public enum CheriotCpu {
+    Base = 0,
+    Rvv = 1,
+    RvvFp = 2,
+}
+
 // 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.
diff --git a/mpact/sim/util/renode/renode_mpact.cc b/mpact/sim/util/renode/renode_mpact.cc
index a4ada0c..b43487b 100644
--- a/mpact/sim/util/renode/renode_mpact.cc
+++ b/mpact/sim/util/renode/renode_mpact.cc
@@ -36,37 +36,38 @@
 
 // This function must be defined in the library.
 extern ::mpact::sim::util::renode::RenodeDebugInterface *CreateMpactSim(
-    std::string, MemoryInterface *);
+    std::string name, std::string cpu_type, MemoryInterface *);
 
 using ::mpact::sim::util::renode::RenodeAgent;
 using ::mpact::sim::util::renode::RenodeCpuRegister;
 
 // Implementation of the C interface functions. They each forward the call to
 // the corresponding method in RenodeAgent.
-int32_t construct(int32_t max_name_length) {
-  return RenodeAgent::Instance()->Construct(max_name_length, nullptr, nullptr);
+int32_t construct(char *cpu_type, int32_t max_name_length) {
+  return RenodeAgent::Instance()->Construct(cpu_type, max_name_length, nullptr,
+                                            nullptr);
 }
 
-int32_t construct_with_sysbus(int32_t max_name_length,
+int32_t construct_with_sysbus(char *cpu_type, int32_t max_name_length,
                               int32_t (*read_callback)(uint64_t, char *,
                                                        int32_t),
                               int32_t (*write_callback)(uint64_t, char *,
                                                         int32_t)) {
-  return RenodeAgent::Instance()->Construct(max_name_length, read_callback,
-                                            write_callback);
+  return RenodeAgent::Instance()->Construct(cpu_type, max_name_length,
+                                            read_callback, write_callback);
 }
 
-int32_t connect(int32_t id, int32_t max_name_length) {
-  return RenodeAgent::Instance()->Connect(id, max_name_length, nullptr,
-                                          nullptr);
+int32_t connect(char *cpu_type, int32_t id, int32_t max_name_length) {
+  return RenodeAgent::Instance()->Connect(cpu_type, id, max_name_length,
+                                          nullptr, nullptr);
 }
 
-int32_t connect_with_sysbus(int32_t id, int32_t max_name_length,
+int32_t connect_with_sysbus(char *cpu_type, int32_t id, int32_t max_name_length,
                             int32_t (*read_callback)(uint64_t, char *, int32_t),
                             int32_t (*write_callback)(uint64_t, char *,
                                                       int32_t)) {
-  return RenodeAgent::Instance()->Connect(id, max_name_length, read_callback,
-                                          write_callback);
+  return RenodeAgent::Instance()->Connect(cpu_type, id, max_name_length,
+                                          read_callback, write_callback);
 }
 
 void destruct(int32_t id) { RenodeAgent::Instance()->Destroy(id); }
@@ -136,14 +137,14 @@
 int32_t RenodeAgent::count_ = 0;
 
 // Create the debug instance by calling the factory function.
-int32_t RenodeAgent::Construct(int32_t max_name_length,
+int32_t RenodeAgent::Construct(char *cpu_type, int32_t max_name_length,
                                int32_t (*read_callback)(uint64_t, char *,
                                                         int32_t),
                                int32_t (*write_callback)(uint64_t, char *,
                                                          int32_t)) {
   std::string name = absl::StrCat("renode", count_);
   auto *memory_access = new RenodeMemoryAccess(read_callback, write_callback);
-  auto *dbg = CreateMpactSim(name, memory_access);
+  auto *dbg = CreateMpactSim(name, cpu_type, memory_access);
   if (dbg == nullptr) {
     delete memory_access;
     return -1;
@@ -159,11 +160,10 @@
   return RenodeAgent::count_++;
 }
 
-int32_t RenodeAgent::Connect(int32_t id, int32_t max_name_length,
-                             int32_t (*read_callback)(uint64_t, char *,
-                                                      int32_t),
-                             int32_t (*write_callback)(uint64_t, char *,
-                                                       int32_t)) {
+int32_t RenodeAgent::Connect(
+    char *cpu_type, int32_t id, int32_t max_name_length,
+    int32_t (*read_callback)(uint64_t, char *, int32_t),
+    int32_t (*write_callback)(uint64_t, char *, int32_t)) {
   // First check if the instance already exists.
   auto iter = core_dbg_instances_.find(id);
   if (iter != core_dbg_instances_.end()) {
@@ -183,7 +183,7 @@
   // The instance does not exist, so create a new debug instance.
   std::string name = absl::StrCat("renode", id);
   auto *memory_access = new RenodeMemoryAccess(read_callback, write_callback);
-  auto *dbg = CreateMpactSim(name, memory_access);
+  auto *dbg = CreateMpactSim(name, cpu_type, memory_access);
   if (dbg == nullptr) {
     delete memory_access;
     return -1;
diff --git a/mpact/sim/util/renode/renode_mpact.h b/mpact/sim/util/renode/renode_mpact.h
index 51948cd..533cc81 100644
--- a/mpact/sim/util/renode/renode_mpact.h
+++ b/mpact/sim/util/renode/renode_mpact.h
@@ -38,8 +38,8 @@
 // Create a debug instance, returning its id. A return value of zero indicates
 // and error. The sysbus variant of the call provides methods to perform loads
 // and stores from a memory space managed by the caller.
-int32_t construct(int32_t max_name_length);
-int32_t construct_with_sysbus(int32_t max_name_length,
+int32_t construct(char *cpu_type, int32_t max_name_length);
+int32_t construct_with_sysbus(char *cpu_type, int32_t max_name_length,
                               int32_t (*read_callback)(uint64_t, char *,
                                                        int32_t),
                               int32_t (*write_callback)(uint64_t, char *,
@@ -48,8 +48,8 @@
 // the given id. A return value of zero indicates an error. The sysbus variant
 // of the call provides methods to perform loads and stores from a memory space
 // managed by the caller.
-int32_t connect(int32_t id, int32_t max_name_length);
-int32_t connect_with_sysbus(int32_t id, int32_t max_name_length,
+int32_t connect(char *cpu_type, int32_t id, int32_t max_name_length);
+int32_t connect_with_sysbus(char *cpu_type, int32_t id, int32_t max_name_length,
                             int32_t (*read_callback)(uint64_t, char *, int32_t),
                             int32_t (*write_callback)(uint64_t, char *,
                                                       int32_t));
@@ -125,10 +125,10 @@
   }
 
   // These methods correspond to the C methods defined above.
-  int32_t Construct(int32_t max_name_length,
+  int32_t Construct(char *cpu_type, int32_t max_name_length,
                     int32_t (*read_callback)(uint64_t, char *, int32_t),
                     int32_t (*write_callback)(uint64_t, char *, int32_t));
-  int32_t Connect(int32_t id, int32_t max_name_length,
+  int32_t Connect(char *cpu_type, int32_t id, int32_t max_name_length,
                   int32_t (*read_callback)(uint64_t, char *, int32_t),
                   int32_t (*write_callback)(uint64_t, char *, int32_t));
   void Destroy(int32_t id);
diff --git a/mpact/sim/util/renode/socket_cli.cc b/mpact/sim/util/renode/socket_cli.cc
index 54d7135..a03efdc 100644
--- a/mpact/sim/util/renode/socket_cli.cc
+++ b/mpact/sim/util/renode/socket_cli.cc
@@ -14,6 +14,7 @@
 
 #include "mpact/sim/util/renode/socket_cli.h"
 
+#include <fcntl.h>
 #include <netinet/in.h>
 #include <sys/socket.h>
 #include <sys/types.h>
@@ -127,10 +128,13 @@
       LOG(ERROR) << "Failed to shutdown server socket " << server_socket_
                  << ": " << strerror(errno);
     }
-    int err = close(server_socket_);
-    if (err != 0) {
-      LOG(ERROR) << "Failed to close server socket " << server_socket_ << ": "
-                 << strerror(errno);
+    res = fcntl(server_socket_, F_GETFD);
+    if (res >= 0) {
+      int err = close(server_socket_);
+      if (err != 0) {
+        LOG(ERROR) << "Failed to close server socket " << server_socket_ << ": "
+                   << strerror(errno);
+      }
     }
   }
   if (cli_thread_.joinable()) cli_thread_.join();