Refactored breakpoint and action points.
PiperOrigin-RevId: 643345868
Change-Id: I192800fbbc04ad9c98e21339c57b940f54d9c459
diff --git a/cheriot/BUILD b/cheriot/BUILD
index e2750df..4bb61f5 100644
--- a/cheriot/BUILD
+++ b/cheriot/BUILD
@@ -151,8 +151,9 @@
"@com_google_absl//absl/strings",
"@com_google_absl//absl/strings:str_format",
"@com_google_absl//absl/synchronization",
- "@com_google_mpact-riscv//riscv:riscv_breakpoint",
+ "@com_google_mpact-riscv//riscv:riscv_action_point_memory_interface",
"@com_google_mpact-riscv//riscv:riscv_state",
+ "@com_google_mpact-sim//mpact/sim/generic:action_points",
"@com_google_mpact-sim//mpact/sim/generic:component",
"@com_google_mpact-sim//mpact/sim/generic:core",
"@com_google_mpact-sim//mpact/sim/generic:core_debug_interface",
diff --git a/cheriot/cheriot_top.cc b/cheriot/cheriot_top.cc
index 5321f0d..2078de5 100644
--- a/cheriot/cheriot_top.cc
+++ b/cheriot/cheriot_top.cc
@@ -36,6 +36,8 @@
#include "cheriot/cheriot_state.h"
#include "cheriot/riscv_cheriot_enums.h"
#include "cheriot/riscv_cheriot_register_aliases.h"
+#include "mpact/sim/generic/action_point_manager_base.h"
+#include "mpact/sim/generic/breakpoint_manager.h"
#include "mpact/sim/generic/component.h"
#include "mpact/sim/generic/core_debug_interface.h"
#include "mpact/sim/generic/counters.h"
@@ -49,8 +51,7 @@
#include "mpact/sim/util/memory/tagged_memory_interface.h"
#include "mpact/sim/util/memory/tagged_memory_watcher.h"
#include "re2/re2.h"
-#include "riscv//riscv_action_point.h"
-#include "riscv//riscv_breakpoint.h"
+#include "riscv//riscv_action_point_memory_interface.h"
#include "riscv//riscv_csr.h"
#include "riscv//riscv_register.h"
@@ -60,6 +61,9 @@
constexpr char kCheriotName[] = "CherIoT";
+using ::mpact::sim::generic::ActionPointManagerBase;
+using ::mpact::sim::generic::BreakpointManager;
+using ::mpact::sim::riscv::RiscVActionPointMemoryInterface;
using EC = ::mpact::sim::cheriot::ExceptionCode;
using PB = ::mpact::sim::cheriot::CheriotRegister::PermissionBits;
@@ -127,20 +131,21 @@
CHECK_OK(AddCounter(&counter_pc_)) << "Failed to register pc counter";
// Breakpoints.
- rv_action_point_manager_ = new riscv::RiscVActionPointManager(
+ rv_ap_memory_if_ = new RiscVActionPointMemoryInterface(
memory, absl::bind_front(&generic::DecodeCache::Invalidate,
cheriot_decode_cache_));
- rv_bp_manager_ = new riscv::RiscVBreakpointManager(
- rv_action_point_manager_,
- [this](HaltReason halt_reason) { RequestHalt(halt_reason, nullptr); });
+ rv_ap_manager_ = new ActionPointManagerBase(rv_ap_memory_if_);
+ rv_bp_manager_ = new BreakpointManager(rv_ap_manager_, [this]() {
+ RequestHalt(HaltReason::kSoftwareBreakpoint, nullptr);
+ });
// Set the software action callback.
state_->AddEbreakHandler([this](const Instruction *inst) {
- if (rv_action_point_manager_->IsActionPointActive(inst->address())) {
+ if (rv_ap_manager_->IsActionPointActive(inst->address())) {
// Need to request a halt so that the action point can be stepped past
// after executing the actions. However, an action may override the
// particular halt reason (e.g., breakpoints).
RequestHalt(HaltReason::kActionPoint, inst);
- rv_action_point_manager_->PerformActions(inst->address());
+ rv_ap_manager_->PerformActions(inst->address());
return true;
}
return false;
@@ -220,7 +225,7 @@
absl::Status CheriotTop::StepPastBreakpoint() {
uint64_t pc = state_->pc_operand()->AsUint64(0);
// Disable the breakpoint.
- rv_action_point_manager_->WriteOriginalInstruction(pc);
+ (void)rv_ap_manager_->ap_memory_interface()->WriteOriginalInstruction(pc);
// Execute the real instruction.
auto real_inst = cheriot_decode_cache_->GetDecodedInstruction(pc);
real_inst->IncRef();
@@ -236,7 +241,7 @@
counter_num_instructions_.Increment(1);
real_inst->DecRef();
// Re-enable the breakpoint.
- rv_action_point_manager_->WriteBreakpointInstruction(pc);
+ (void)rv_ap_manager_->ap_memory_interface()->WriteBreakpointInstruction(pc);
// Get the next pc value.
if (state_->branch()) {
state_->set_branch(false);
@@ -760,37 +765,37 @@
return absl::OkStatus();
}
-// Methods for Action points forward to the rv_action_point_manager_ methods.
+// Methods for Action points forward to the rv_ap_manager_ methods.
absl::StatusOr<int> CheriotTop::SetActionPoint(
uint64_t address, absl::AnyInvocable<void(uint64_t, int)> action) {
- if (rv_action_point_manager_ == nullptr) {
+ if (rv_ap_manager_ == nullptr) {
return absl::InternalError("Action points are not enabled");
}
- auto res = rv_action_point_manager_->SetAction(address, std::move(action));
+ auto res = rv_ap_manager_->SetAction(address, std::move(action));
if (!res.ok()) return res;
return res.value();
}
absl::Status CheriotTop::ClearActionPoint(uint64_t address, int id) {
- if (rv_action_point_manager_ == nullptr) {
+ if (rv_ap_manager_ == nullptr) {
return absl::InternalError("Action points are not enabled");
}
- return rv_action_point_manager_->ClearAction(address, id);
+ return rv_ap_manager_->ClearAction(address, id);
}
absl::Status CheriotTop::EnableAction(uint64_t address, int id) {
- if (rv_action_point_manager_ == nullptr) {
+ if (rv_ap_manager_ == nullptr) {
return absl::InternalError("Action points are not enabled");
}
- return rv_action_point_manager_->EnableAction(address, id);
+ return rv_ap_manager_->EnableAction(address, id);
}
absl::Status CheriotTop::DisableAction(uint64_t address, int id) {
- if (rv_action_point_manager_ == nullptr) {
+ if (rv_ap_manager_ == nullptr) {
return absl::InternalError("Action points are not enabled");
}
- return rv_action_point_manager_->DisableAction(address, id);
+ return rv_ap_manager_->DisableAction(address, id);
}
// Set a data watchpoint for the given address range and access type.
@@ -898,16 +903,18 @@
// If requesting the disassembly for an instruction at an action point, we
// need to write the original instruction back to memory before getting the
// disassembly.
- bool inst_swap = rv_action_point_manager_->IsActionPointActive(address);
+ bool inst_swap = rv_ap_manager_->IsActionPointActive(address);
if (inst_swap) {
- rv_action_point_manager_->WriteOriginalInstruction(address);
+ (void)rv_ap_manager_->ap_memory_interface()->WriteOriginalInstruction(
+ address);
}
// Get the decoded instruction.
inst = cheriot_decode_cache_->GetDecodedInstruction(address);
auto disasm = inst != nullptr ? inst->AsString() : "Invalid instruction";
// Swap back if required.
if (inst_swap) {
- rv_action_point_manager_->WriteBreakpointInstruction(address);
+ (void)rv_ap_manager_->ap_memory_interface()->WriteBreakpointInstruction(
+ address);
}
return disasm;
}
diff --git a/cheriot/cheriot_top.h b/cheriot/cheriot_top.h
index 4fc8d17..eb7415d 100644
--- a/cheriot/cheriot_top.h
+++ b/cheriot/cheriot_top.h
@@ -31,7 +31,8 @@
#include "cheriot/cheriot_decoder.h"
#include "cheriot/cheriot_register.h"
#include "cheriot/cheriot_state.h"
-#include "cheriot/riscv_cheriot_enums.h"
+#include "mpact/sim/generic/action_point_manager_base.h"
+#include "mpact/sim/generic/breakpoint_manager.h"
#include "mpact/sim/generic/component.h"
#include "mpact/sim/generic/core_debug_interface.h"
#include "mpact/sim/generic/counters.h"
@@ -40,16 +41,18 @@
#include "mpact/sim/generic/decoder_interface.h"
#include "mpact/sim/util/memory/memory_interface.h"
#include "mpact/sim/util/memory/memory_watcher.h"
-#include "mpact/sim/util/memory/tagged_memory_interface.h"
#include "mpact/sim/util/memory/tagged_memory_watcher.h"
#include "re2/re2.h"
-#include "riscv//riscv_action_point.h"
-#include "riscv//riscv_breakpoint.h"
+#include "riscv//riscv_action_point_memory_interface.h"
namespace mpact {
namespace sim {
namespace cheriot {
+using ::mpact::sim::generic::ActionPointManagerBase;
+using ::mpact::sim::generic::BreakpointManager;
+using ::mpact::sim::riscv::RiscVActionPointMemoryInterface;
+
struct BranchTraceEntry {
uint32_t from;
uint32_t to;
@@ -165,10 +168,12 @@
CheriotState *state_;
// Flag that indicates an instruction needs to be stepped over.
bool need_to_step_over_ = false;
+ // Action point memory interface.
+ RiscVActionPointMemoryInterface *rv_ap_memory_if_ = nullptr;
// Action point manager.
- riscv::RiscVActionPointManager *rv_action_point_manager_ = nullptr;
+ ActionPointManagerBase *rv_ap_manager_ = nullptr;
// Breakpoint manager.
- riscv::RiscVBreakpointManager *rv_bp_manager_ = nullptr;
+ BreakpointManager *rv_bp_manager_ = nullptr;
// Textual description of halt reason.
std::string halt_string_;
// The pc register instance.