Adds a new CSR type RiscVShadowCsr that allows a CSR to provide a more
restrictive view of another CSR.
Adds cycle/cycleh and instret/instreth as shadow CSRs
PiperOrigin-RevId: 705640436
Change-Id: I875751b7d31ee319b8d2edbcedb9a942bb267085
diff --git a/cheriot/cheriot_state.cc b/cheriot/cheriot_state.cc
index 6dc3ca0..4b7edec 100644
--- a/cheriot/cheriot_state.cc
+++ b/cheriot/cheriot_state.cc
@@ -17,7 +17,6 @@
#include <algorithm>
#include <cstdint>
#include <limits>
-#include <new>
#include <string>
#include <string_view>
#include <utility>
@@ -57,6 +56,7 @@
using ::mpact::sim::riscv::RiscVCsrEnum;
using ::mpact::sim::riscv::RiscVCsrInterface;
using ::mpact::sim::riscv::RiscVPmp;
+using ::mpact::sim::riscv::RiscVShadowCsr;
using ::mpact::sim::riscv::RiscVSimpleCsr;
using ::mpact::sim::riscv::RiscVXlen;
@@ -197,24 +197,18 @@
auto *minstret = CreateCsr<RiscVCounterCsr<T, CheriotState>>(
state, csr_vec, "minstret", RiscVCsrEnum ::kMInstret, state);
CHECK_NE(minstret, nullptr);
- if (sizeof(T) == sizeof(uint32_t)) {
- CHECK_NE(CreateCsr<RiscVCounterCsrHigh<CheriotState>>(
- state, csr_vec, "minstreth", RiscVCsrEnum::kMInstretH, state,
- reinterpret_cast<RiscVCounterCsr<uint32_t, CheriotState> *>(
- minstret)),
- nullptr);
- }
+ auto minstreth = CreateCsr<RiscVCounterCsrHigh<CheriotState>>(
+ state, csr_vec, "minstreth", RiscVCsrEnum::kMInstretH, state,
+ reinterpret_cast<RiscVCounterCsr<uint32_t, CheriotState> *>(minstret));
+ CHECK_NE(minstreth, nullptr);
// mcycle/mcycleh
auto *mcycle = CreateCsr<RiscVCounterCsr<T, CheriotState>>(
state, csr_vec, "mcycle", RiscVCsrEnum::kMCycle, state);
CHECK_NE(mcycle, nullptr);
- if (sizeof(T) == sizeof(uint32_t)) {
- CHECK_NE(CreateCsr<RiscVCounterCsrHigh<CheriotState>>(
- state, csr_vec, "mcycleh", RiscVCsrEnum::kMCycleH, state,
- reinterpret_cast<RiscVCounterCsr<uint32_t, CheriotState> *>(
- mcycle)),
- nullptr);
- }
+ auto *mcycleh = CreateCsr<RiscVCounterCsrHigh<CheriotState>>(
+ state, csr_vec, "mcycleh", RiscVCsrEnum::kMCycleH, state,
+ reinterpret_cast<RiscVCounterCsr<uint32_t, CheriotState> *>(mcycle));
+ CHECK_NE(mcycleh, nullptr);
// Stack high water mark CSRs. Mshwm gets updated automatically during
// execution. mshwm
@@ -241,7 +235,24 @@
// None in CHERIoT.
// User level CSRs
- // None in CHERIoT.
+ // instret/instreth
+ CHECK_NE(CreateCsr<RiscVShadowCsr<T>>(
+ state, csr_vec, "instret", RiscVCsrEnum ::kInstret,
+ std::numeric_limits<T>::max(), 0, state, minstret),
+ nullptr);
+ CHECK_NE(CreateCsr<RiscVShadowCsr<T>>(
+ state, csr_vec, "instreth", RiscVCsrEnum::kInstretH,
+ std::numeric_limits<T>::max(), 0, state, minstreth),
+ nullptr);
+ // cycle/cycleh
+ CHECK_NE(CreateCsr<RiscVShadowCsr<T>>(
+ state, csr_vec, "cycle", RiscVCsrEnum::kCycle,
+ std::numeric_limits<T>::max(), 0, state, mcycle),
+ nullptr);
+ CHECK_NE(CreateCsr<RiscVShadowCsr<T>>(
+ state, csr_vec, "cycleh", RiscVCsrEnum::kCycleH,
+ std::numeric_limits<T>::max(), 0, state, mcycleh),
+ nullptr);
// PMP CSRs
state->pmp_ = new RiscVPmp(state);
@@ -690,9 +701,9 @@
// Called upon returning from an interrupt or exception.
void CheriotState::SignalReturnFromInterrupt() {
- // First increment the interrupt return counter. Then pop the interrupt info.
- // This way any code that is triggered by the interrupt return counter will
- // be able to access the interrupt info.
+ // First increment the interrupt return counter. Then pop the interrupt
+ // info. This way any code that is triggered by the interrupt return counter
+ // will be able to access the interrupt info.
counter_interrupt_returns_.Increment(1);
interrupt_info_list_.pop_back();
}
diff --git a/cheriot/riscv_cheriot_csr_enum.h b/cheriot/riscv_cheriot_csr_enum.h
index 0000bb1..7cdeaf8 100644
--- a/cheriot/riscv_cheriot_csr_enum.h
+++ b/cheriot/riscv_cheriot_csr_enum.h
@@ -52,12 +52,12 @@
kTime = 0xc01,
kInstret = 0xc02,
- // Ignoring perf monitoring counters for now.
-
kCycleH = 0xc80,
kTimeH = 0xc81,
kInstretH = 0x82,
+ // Ignoring perf monitoring counters for now.
+
// Ignoring high bits of perf monitoring counters for now.
// Supervisor trap setup.