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