blob: 1df90b0dee81fe6132c6fcb41015082562313f11 [file] [log] [blame]
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MPACT_CHERIOT__RISCV_CHERIOT_MINSTRET_H_
#define MPACT_CHERIOT__RISCV_CHERIOT_MINSTRET_H_
#include <cstdint>
#include <string>
#include "cheriot/riscv_cheriot_csr_enum.h"
#include "mpact/sim/generic/counters.h"
#include "riscv//riscv_csr.h"
// This file provides the declarations for the CherIoT minstret/minstreth
// CSRs. They are tied to the instruction counter of the top level of the
// simulator. That binding is done when the simulator is instantiated. Until
// that is done, the CSR just works like a scratch CSR.
// Since this CSR is both readable and writable, but the counter value cannot
// be changed, every time the register is written, a relative offset is computed
// from the counter, so that the values read are relative to the most recent
// write of the CSR.
namespace mpact::sim::cheriot {
using ::mpact::sim::generic::SimpleCounter;
using ::mpact::sim::riscv::RiscVSimpleCsr;
class CheriotState;
class RiscVCheriotMInstret : public RiscVSimpleCsr<uint32_t> {
public:
RiscVCheriotMInstret(std::string name, CheriotState* state);
RiscVCheriotMInstret(const RiscVCheriotMInstret&) = delete;
RiscVCheriotMInstret& operator=(const RiscVCheriotMInstret&) = delete;
~RiscVCheriotMInstret() override = default;
// RiscVSimpleCsr method overrides.
uint32_t GetUint32() override;
uint64_t GetUint64() override;
void Set(uint32_t) override;
void Set(uint64_t) override;
void set_counter(SimpleCounter<uint64_t>* counter) { counter_ = counter; }
private:
inline uint32_t GetCounterValue() const {
return static_cast<uint32_t>(counter_->GetValue() & 0xffff'ffffULL);
};
SimpleCounter<uint64_t>* counter_ = nullptr;
uint32_t offset_ = 0;
};
class RiscVCheriotMInstreth : public RiscVSimpleCsr<uint32_t> {
public:
RiscVCheriotMInstreth(std::string name, CheriotState* state);
RiscVCheriotMInstreth(const RiscVCheriotMInstret&) = delete;
RiscVCheriotMInstreth& operator=(const RiscVCheriotMInstret&) = delete;
~RiscVCheriotMInstreth() override = default;
// RiscVSimpleCsr method overrides.
uint32_t GetUint32() override;
uint64_t GetUint64() override;
void Set(uint32_t) override;
void Set(uint64_t) override;
void set_counter(SimpleCounter<uint64_t>* counter) { counter_ = counter; }
private:
inline uint32_t GetCounterValue() const {
return static_cast<uint32_t>(counter_->GetValue() >> 32);
};
SimpleCounter<uint64_t>* counter_ = nullptr;
uint32_t offset_ = 0;
};
} // namespace mpact::sim::cheriot
#endif // MPACT_CHERIOT__RISCV_CHERIOT_MINSTRET_H_