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)},