No public description

PiperOrigin-RevId: 639071669
Change-Id: I01d808555c040f3a7c1c5b6562ecba2eca11471e
diff --git a/cheriot/cheriot_cli_forwarder.cc b/cheriot/cheriot_cli_forwarder.cc
index ce7ae7a..633f763 100644
--- a/cheriot/cheriot_cli_forwarder.cc
+++ b/cheriot/cheriot_cli_forwarder.cc
@@ -16,27 +16,27 @@
 
 #include <cstddef>
 #include <cstdint>
+#include <string>
 #include <utility>
 
 #include "absl/functional/any_invocable.h"
 #include "absl/status/status.h"
 #include "absl/status/statusor.h"
 #include "cheriot/cheriot_renode_cli_top.h"
+#include "cheriot/cheriot_state.h"
 #include "mpact/sim/generic/core_debug_interface.h"
-#include "mpact/sim/util/renode/cli_forwarder.h"
 
 namespace mpact {
 namespace sim {
 namespace cheriot {
 
 using ::mpact::sim::generic::AccessType;
-using ::mpact::sim::util::renode::CLIForwarder;
 using RunStatus = ::mpact::sim::generic::CoreDebugInterface::RunStatus;
 using HaltReasonValueType =
     ::mpact::sim::generic::CoreDebugInterface::HaltReasonValueType;
 
 CheriotCLIForwarder::CheriotCLIForwarder(CheriotRenodeCLITop *cheriot_cli_top)
-    : CLIForwarder(cheriot_cli_top), cheriot_cli_top_(cheriot_cli_top) {}
+    : cheriot_cli_top_(cheriot_cli_top) {}
 
 // Forward the calls to the CheriotRenodeCLITop class - CLI methods.
 
@@ -78,6 +78,81 @@
   cheriot_cli_top_->CLISetBreakOnControlFlowChange(value);
 }
 
+absl::Status CheriotCLIForwarder::Halt() { return cheriot_cli_top_->CLIHalt(); }
+
+absl::StatusOr<int> CheriotCLIForwarder::Step(int num) {
+  return cheriot_cli_top_->CLIStep(num);
+}
+
+absl::Status CheriotCLIForwarder::Run() { return cheriot_cli_top_->CLIRun(); }
+
+absl::Status CheriotCLIForwarder::Wait() { return cheriot_cli_top_->CLIWait(); }
+
+// Returns the current run status.
+absl::StatusOr<RunStatus> CheriotCLIForwarder::GetRunStatus() {
+  return cheriot_cli_top_->CLIGetRunStatus();
+}
+
+// Returns the reason for the most recent halt.
+absl::StatusOr<HaltReasonValueType> CheriotCLIForwarder::GetLastHaltReason() {
+  return cheriot_cli_top_->CLIGetLastHaltReason();
+}
+
+// Read/write the named registers.
+absl::StatusOr<uint64_t> CheriotCLIForwarder::ReadRegister(
+    const std::string &name) {
+  return cheriot_cli_top_->CLIReadRegister(name);
+}
+
+absl::Status CheriotCLIForwarder::WriteRegister(const std::string &name,
+                                                uint64_t value) {
+  return cheriot_cli_top_->CLIWriteRegister(name, value);
+}
+
+absl::StatusOr<DataBuffer *> CheriotCLIForwarder::GetRegisterDataBuffer(
+    const std::string &name) {
+  return cheriot_cli_top_->CLIGetRegisterDataBuffer(name);
+}
+
+// Read/write the buffers to memory.
+absl::StatusOr<size_t> CheriotCLIForwarder::ReadMemory(uint64_t address,
+                                                       void *buf,
+                                                       size_t length) {
+  return cheriot_cli_top_->CLIReadMemory(address, buf, length);
+}
+
+absl::StatusOr<size_t> CheriotCLIForwarder::WriteMemory(uint64_t address,
+                                                        const void *buf,
+                                                        size_t length) {
+  return cheriot_cli_top_->CLIWriteMemory(address, buf, length);
+}
+
+bool CheriotCLIForwarder::HasBreakpoint(uint64_t address) {
+  return cheriot_cli_top_->CLIHasBreakpoint(address);
+}
+
+absl::Status CheriotCLIForwarder::SetSwBreakpoint(uint64_t address) {
+  return cheriot_cli_top_->CLISetSwBreakpoint(address);
+}
+
+absl::Status CheriotCLIForwarder::ClearSwBreakpoint(uint64_t address) {
+  return cheriot_cli_top_->CLIClearSwBreakpoint(address);
+}
+
+absl::Status CheriotCLIForwarder::ClearAllSwBreakpoints() {
+  return cheriot_cli_top_->CLIClearAllSwBreakpoints();
+}
+
+absl::StatusOr<Instruction *> CheriotCLIForwarder::GetInstruction(
+    uint64_t address) {
+  return cheriot_cli_top_->CLIGetInstruction(address);
+}
+
+absl::StatusOr<std::string> CheriotCLIForwarder::GetDisassembly(
+    uint64_t address) {
+  return cheriot_cli_top_->CLIGetDisassembly(address);
+}
+
 }  // namespace cheriot
 }  // namespace sim
 }  // namespace mpact
diff --git a/cheriot/cheriot_cli_forwarder.h b/cheriot/cheriot_cli_forwarder.h
index 04dac62..04368e4 100644
--- a/cheriot/cheriot_cli_forwarder.h
+++ b/cheriot/cheriot_cli_forwarder.h
@@ -19,11 +19,14 @@
 
 #include <cstddef>
 #include <cstdint>
+#include <string>
 
 #include "absl/functional/any_invocable.h"
 #include "absl/status/status.h"
 #include "absl/status/statusor.h"
+#include "cheriot/cheriot_debug_interface.h"
 #include "cheriot/cheriot_renode_cli_top.h"
+#include "cheriot/cheriot_state.h"
 #include "mpact/sim/generic/core_debug_interface.h"
 #include "mpact/sim/util/renode/cli_forwarder.h"
 
@@ -37,7 +40,7 @@
 using ::mpact::sim::generic::AccessType;
 using ::mpact::sim::util::renode::CLIForwarder;
 
-class CheriotCLIForwarder : public CLIForwarder {
+class CheriotCLIForwarder : public CheriotDebugInterface {
  public:
   explicit CheriotCLIForwarder(CheriotRenodeCLITop *top);
   CheriotCLIForwarder() = delete;
@@ -45,7 +48,7 @@
   CheriotCLIForwarder &operator=(const CLIForwarder &) = delete;
 
   absl::StatusOr<size_t> ReadTagMemory(uint64_t address, void *buf,
-                                       size_t length);
+                                       size_t length) override;
   // Set a data watchpoint for the given memory range. Any access matching the
   // given access type (load/store) will halt execution following the completion
   // of that access.
@@ -64,9 +67,61 @@
   absl::Status DisableAction(uint64_t address, int id);
   // Enable breaking on control flow change.
   void SetBreakOnControlFlowChange(bool value);
+  // Request that core stop running.
+  absl::Status Halt() override;
+  // Step the core by num instructions.
+  absl::StatusOr<int> Step(int num) override;
+  // Allow the core to free-run. The loop to run the instructions should be
+  // in a separate thread so that this method can return. This allows a user
+  // interface built on top of this interface to handle multiple cores running
+  // at the same time.
+  absl::Status Run() override;
+  // Wait until the current core halts execution.
+  absl::Status Wait() override;
+
+  // Returns the current run status.
+  absl::StatusOr<RunStatus> GetRunStatus() override;
+  // Returns the reason for the most recent halt.
+  absl::StatusOr<HaltReasonValueType> GetLastHaltReason() override;
+
+  absl::StatusOr<uint64_t> ReadRegister(const std::string &name) override;
+  absl::Status WriteRegister(const std::string &name, uint64_t value) override;
+
+  // Some registers, including vector registers, have values that exceed the
+  // 64 bits supported in the Read/Write register API calls. This function
+  // obtains the DataBuffer structure for such registers, provided they use one.
+  // The data in the DataBuffer instance can be written as well as read.
+  // Note (1): DataBuffer instances are reference counted. If the simulator is
+  // advanced after obtaining the instance, it may become invalid if it isn't
+  // IncRef'ed appropriately (see data_buffer.h).
+  // Note (2): In some cases, a register write may replace the DataBuffer
+  // instance within a register so that any stored references to it become
+  // stale.
+  absl::StatusOr<DataBuffer *> GetRegisterDataBuffer(
+      const std::string &name) override;
+
+  // Read/write the buffers to memory.
+  absl::StatusOr<size_t> ReadMemory(uint64_t address, void *buf,
+                                    size_t length) override;
+  absl::StatusOr<size_t> WriteMemory(uint64_t address, const void *buf,
+                                     size_t length) override;
+
+  // Test to see if there's a breakpoint at the given address.
+  bool HasBreakpoint(uint64_t address) override;
+  // Set/Clear software breakpoints at the given addresses.
+  absl::Status SetSwBreakpoint(uint64_t address) override;
+  absl::Status ClearSwBreakpoint(uint64_t address) override;
+  // Remove all software breakpoints.
+  absl::Status ClearAllSwBreakpoints() override;
+
+  // Return the instruction object for the instruction at the given address.
+  absl::StatusOr<Instruction *> GetInstruction(uint64_t address) override;
+  // Return the string representation for the instruction at the given address.
+  absl::StatusOr<std::string> GetDisassembly(uint64_t address) override;
 
  private:
   CheriotRenodeCLITop *cheriot_cli_top_;
+  CLIForwarder *cli_forwarder_;
 };
 
 }  // namespace cheriot
diff --git a/cheriot/cheriot_renode.cc b/cheriot/cheriot_renode.cc
index 5db8b7f..be0c484 100644
--- a/cheriot/cheriot_renode.cc
+++ b/cheriot/cheriot_renode.cc
@@ -34,6 +34,7 @@
 #include "absl/strings/str_cat.h"
 #include "cheriot/cheriot_cli_forwarder.h"
 #include "cheriot/cheriot_debug_info.h"
+#include "cheriot/cheriot_debug_interface.h"
 #include "cheriot/cheriot_instrumentation_control.h"
 #include "cheriot/cheriot_renode_cli_top.h"
 #include "cheriot/cheriot_renode_register_info.h"
@@ -234,7 +235,7 @@
   }
   auto res = program_loader_->GetSymbol("tohost");
   // Add watchpoint for tohost if the symbol exists.
-  if (!res.ok()) {
+  if (res.ok()) {
     // If there is a 'tohost' symbol, set up a write watchpoint on that address
     // to catch writes that mark program exit.
     uint64_t tohost_addr = res.value().first;
@@ -459,7 +460,9 @@
     cmd_shell_ = new DebugCommandShell();
     instrumentation_control_ = new CheriotInstrumentationControl(
         cmd_shell_, cheriot_top_, mem_profiler_);
-    cmd_shell_->AddCore({cheriot_cli_forwarder_, program_loader_});
+    cmd_shell_->AddCore(
+        {static_cast<CheriotDebugInterface *>(cheriot_cli_forwarder_),
+         program_loader_});
     cmd_shell_->AddCommand(
         instrumentation_control_->Usage(),
         absl::bind_front(&CheriotInstrumentationControl::PerformShellCommand,
diff --git a/cheriot/cheriot_top.cc b/cheriot/cheriot_top.cc
index f829a88..b75b5b3 100644
--- a/cheriot/cheriot_top.cc
+++ b/cheriot/cheriot_top.cc
@@ -743,6 +743,7 @@
   auto *tag_db = db_factory_.Allocate<uint8_t>(length);
   state_->tagged_memory()->Load(address, nullptr, tag_db, nullptr, nullptr);
   std::memcpy(buf, tag_db->raw_ptr(), length);
+  tag_db->DecRef();
   return length;
 }
 
diff --git a/cheriot/debug_command_shell.cc b/cheriot/debug_command_shell.cc
index 70727f8..cdde439 100644
--- a/cheriot/debug_command_shell.cc
+++ b/cheriot/debug_command_shell.cc
@@ -1248,7 +1248,6 @@
     sep = ", ";
   }
   absl::StrAppend(&tag_string, "]");
-
   // Get the result and format it.
   void *void_buffer = mem_buffer_;
   std::string output;
diff --git a/cheriot/memory_use_profiler.cc b/cheriot/memory_use_profiler.cc
index 199b0aa..ac8ed47 100644
--- a/cheriot/memory_use_profiler.cc
+++ b/cheriot/memory_use_profiler.cc
@@ -193,7 +193,8 @@
 void TaggedMemoryUseProfiler::Load(uint64_t address, DataBuffer *db,
                                    DataBuffer *tags, Instruction *inst,
                                    ReferenceCount *context) {
-  if (is_enabled_) tracker_.MarkUsed(address, db->size<uint8_t>());
+  if ((db != nullptr) && is_enabled_)
+    tracker_.MarkUsed(address, db->size<uint8_t>());
   if (tagged_memory_) tagged_memory_->Load(address, db, tags, inst, context);
 }
 
@@ -216,7 +217,8 @@
 
 void TaggedMemoryUseProfiler::Store(uint64_t address, DataBuffer *db,
                                     DataBuffer *tags) {
-  if (is_enabled_) tracker_.MarkUsed(address, db->size<uint8_t>());
+  if ((db != nullptr) && is_enabled_)
+    tracker_.MarkUsed(address, db->size<uint8_t>());
   if (tagged_memory_) tagged_memory_->Store(address, db, tags);
 }
 
diff --git a/riscv_cheriot.isa b/riscv_cheriot.isa
index 5e0386b..fea34c3 100644
--- a/riscv_cheriot.isa
+++ b/riscv_cheriot.isa
@@ -483,7 +483,7 @@
     //   disasm: "fsd", "%rdrs2, %I_css_uimm6x8(%x2)",
     //   semfunc: "&RV64::RiscVISd";
     clw{(: c3rs1, I_cl_uimm5x4 : ), (: : c3rd)},
-      disasm: ".clw", "%c3rd, %I_cl_uimm5x4(%c3rs1)",
+      disasm: "c.clw", "%c3rd, %I_cl_uimm5x4(%c3rs1)",
       semfunc: "&RiscVILw", "&RiscVILwChild";
     // Reused for clc
     cld{(: c3cs1, I_cl_uimm5x8 : ), (: : c3cd)},