No public description

PiperOrigin-RevId: 556884353
diff --git a/sim/BUILD b/sim/BUILD
index bf3ec90..8437844 100644
--- a/sim/BUILD
+++ b/sim/BUILD
@@ -125,11 +125,13 @@
         ":kelvin_decoder",
         ":kelvin_isa",
         ":kelvin_state",
+        "@com_google_absl//absl/container:flat_hash_map",
         "@com_google_absl//absl/flags:flag",
         "@com_google_absl//absl/functional:bind_front",
         "@com_google_absl//absl/log",
         "@com_google_absl//absl/log:check",
         "@com_google_absl//absl/status",
+        "@com_google_absl//absl/status:statusor",
         "@com_google_absl//absl/strings",
         "@com_google_absl//absl/synchronization",
         "@com_google_mpact-riscv//riscv:riscv_arm_semihost",
@@ -139,6 +141,7 @@
         "@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",
+        "@com_google_mpact-sim//mpact/sim/generic:counters",
         "@com_google_mpact-sim//mpact/sim/generic:decode_cache",
         "@com_google_mpact-sim//mpact/sim/util/memory",
     ],
diff --git a/sim/kelvin_top.cc b/sim/kelvin_top.cc
index 5cd361c..a4b92da 100644
--- a/sim/kelvin_top.cc
+++ b/sim/kelvin_top.cc
@@ -16,8 +16,15 @@
 #include "absl/log/log.h"
 #include "absl/status/status.h"
 #include "absl/strings/str_cat.h"
+#include "absl/synchronization/notification.h"
+#include "riscv/riscv_arm_semihost.h"
+#include "riscv/riscv_breakpoint.h"
+#include "riscv/riscv_fp_state.h"
+#include "riscv/riscv_register.h"
 #include "riscv/riscv_register_aliases.h"
 #include "riscv/riscv_state.h"
+#include "mpact/sim/generic/component.h"
+#include "mpact/sim/generic/core_debug_interface.h"
 #include "mpact/sim/generic/data_buffer.h"
 #include "mpact/sim/generic/decode_cache.h"
 #include "mpact/sim/generic/resource_operand_interface.h"
@@ -461,6 +468,21 @@
   return absl::OkStatus();
 }
 
+absl::StatusOr<DataBuffer *> KelvinTop::GetRegisterDataBuffer(
+    const std::string &name) {
+  // The registers aren't protected by a mutex, so let's not access them while
+  // the simulator is running.
+  if (run_status_ != RunStatus::kHalted) {
+    return absl::FailedPreconditionError(
+        "GetRegisterDataBuffer: Core must be halted");
+  }
+  auto iter = state_->registers()->find(name);
+  if (iter == state_->registers()->end()) {
+    return absl::NotFoundError(absl::StrCat("Register '", name, "' not found"));
+  }
+  return iter->second->data_buffer();
+}
+
 absl::StatusOr<size_t> KelvinTop::ReadMemory(uint64_t address, void *buffer,
                                              size_t length) {
   if (run_status_ != RunStatus::kHalted) {
diff --git a/sim/kelvin_top.h b/sim/kelvin_top.h
index 206623b..aa1fc56 100644
--- a/sim/kelvin_top.h
+++ b/sim/kelvin_top.h
@@ -1,18 +1,24 @@
 #ifndef SIM_KELVIN_TOP_H_
 #define SIM_KELVIN_TOP_H_
 
+#include <cstddef>
 #include <cstdint>
 #include <string>
 
 #include "sim/kelvin_enums.h"
 #include "sim/kelvin_state.h"
+#include "absl/container/flat_hash_map.h"
 #include "absl/flags/declare.h"
+#include "absl/status/status.h"
+#include "absl/status/statusor.h"
 #include "absl/synchronization/notification.h"
 #include "riscv/riscv_arm_semihost.h"
 #include "riscv/riscv_breakpoint.h"
 #include "riscv/riscv_fp_state.h"
 #include "mpact/sim/generic/component.h"
 #include "mpact/sim/generic/core_debug_interface.h"
+#include "mpact/sim/generic/counters.h"
+#include "mpact/sim/generic/data_buffer.h"
 #include "mpact/sim/generic/decode_cache.h"
 #include "mpact/sim/generic/decoder_interface.h"
 #include "mpact/sim/generic/register.h"
@@ -25,6 +31,8 @@
 
 constexpr uint64_t kKelvinMaxMemoryAddress = 0x3f'ffffULL;  // 4MB
 
+using ::mpact::sim::generic::DataBuffer;
+
 // Top level class for the Kelvin simulator. This is the main interface for
 // interacting and controlling execution of programs running on the simulator.
 // This class brings together the decoder, the architecture state, and control.
@@ -49,6 +57,8 @@
   // Register access by register name.
   absl::StatusOr<uint64_t> ReadRegister(const std::string &name) override;
   absl::Status WriteRegister(const std::string &name, uint64_t value) override;
+  absl::StatusOr<DataBuffer *> GetRegisterDataBuffer(
+      const std::string &name) override;
 
   // Read and Write memory methods bypass any semihosting.
   absl::StatusOr<size_t> ReadMemory(uint64_t address, void *buf,