arch-riscv: Make ISA class the source of CSR info
Previously, all components assume the info in arch/riscv/regs/misc.hh to be the single source of CSR info. That will however make adding non-standard CSRs difficult as all those CSRs will need to go into the same header & data structure and might conflict with each other. In this CL, we add two new functions to the ISA class that provide information about CSR. The rationale is that, the ISA class is already the owner of CSR data, so it'll also be in a better position to provide necessary CSR metadata. With the change, we can create two CPU models with slightly different custom CSRs easily by creating two derived RiscvISA classes and overriding the two functions. We assume that, any customized CSR set is still compatible with standard CSRs, so we could still utilize the same global map if only standard CSRs are accessed in the use case. Note that this does not necessarily mean you cannot or should not add your customize CSRs into the MiscRegIndex enum. You'll usually still required to do that to give each CSR an unique id. However, the ability to override CSRDataMap/CSRMaskMap provide an opportunity to remap how the CSR index encoded in the instruction maps to CSR, and also give you a chance to make the read/write logic of certain custom CSRs different. Change-Id: I168188bdb1baed11cb3e217eb021f289a13bb036 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/62891 Reviewed-by: Jason Lowe-Power <power.jg@gmail.com> Maintainer: Jason Lowe-Power <power.jg@gmail.com> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
@@ -92,30 +92,11 @@ class CSROp : public RiscvStaticInst
|
||||
uint64_t csr;
|
||||
uint64_t uimm;
|
||||
|
||||
bool valid = false;
|
||||
RegIndex midx = 0;
|
||||
std::string csrName;
|
||||
uint64_t maskVal = 0;
|
||||
|
||||
/// Constructor
|
||||
CSROp(const char *mnem, MachInst _machInst, OpClass __opClass)
|
||||
: RiscvStaticInst(mnem, _machInst, __opClass),
|
||||
csr(FUNCT12), uimm(CSRIMM)
|
||||
{
|
||||
auto csr_data_it = CSRData.find(csr);
|
||||
if (csr_data_it == CSRData.end()) {
|
||||
valid = false;
|
||||
} else {
|
||||
valid = true;
|
||||
midx = csr_data_it->second.physIndex;
|
||||
csrName = csr_data_it->second.name;
|
||||
auto mask_it = CSRMasks.find(csr);
|
||||
if (mask_it == CSRMasks.end())
|
||||
maskVal = mask(64);
|
||||
else
|
||||
maskVal = mask_it->second;
|
||||
}
|
||||
|
||||
if (csr == CSR_SATP) {
|
||||
flags[IsSquashAfter] = true;
|
||||
}
|
||||
|
||||
@@ -34,10 +34,12 @@
|
||||
#ifndef __ARCH_RISCV_ISA_HH__
|
||||
#define __ARCH_RISCV_ISA_HH__
|
||||
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "arch/generic/isa.hh"
|
||||
#include "arch/riscv/pcstate.hh"
|
||||
#include "arch/riscv/regs/misc.hh"
|
||||
#include "arch/riscv/types.hh"
|
||||
#include "base/types.hh"
|
||||
|
||||
@@ -89,6 +91,21 @@ class ISA : public BaseISA
|
||||
void setMiscRegNoEffect(RegIndex idx, RegVal val) override;
|
||||
void setMiscReg(RegIndex idx, RegVal val) override;
|
||||
|
||||
// Derived class could provide knowledge of non-standard CSRs to other
|
||||
// components by overriding the two getCSRxxxMap here and properly
|
||||
// implementing the corresponding read/set function. However, customized
|
||||
// maps should always be compatible with the standard maps.
|
||||
virtual const std::unordered_map<int, CSRMetadata>&
|
||||
getCSRDataMap() const
|
||||
{
|
||||
return CSRData;
|
||||
}
|
||||
virtual const std::unordered_map<int, RegVal>&
|
||||
getCSRMaskMap() const
|
||||
{
|
||||
return CSRMasks;
|
||||
}
|
||||
|
||||
bool inUserMode() const override;
|
||||
void copyRegsFrom(ThreadContext *src) override;
|
||||
|
||||
|
||||
@@ -323,11 +323,23 @@ def template CSRExecute {{
|
||||
%(class_name)s::execute(ExecContext *xc,
|
||||
Trace::InstRecord *traceData) const
|
||||
{
|
||||
if (!valid) {
|
||||
// We assume a riscv instruction is always run with a riscv ISA.
|
||||
auto isa = static_cast<RiscvISA::ISA*>(xc->tcBase()->getIsaPtr());
|
||||
auto& csr_data = isa->getCSRDataMap();
|
||||
auto& csr_masks = isa->getCSRMaskMap();
|
||||
|
||||
auto csr_data_it = csr_data.find(csr);
|
||||
if (csr_data_it == csr_data.end()) {
|
||||
return std::make_shared<IllegalInstFault>(
|
||||
csprintf("Illegal CSR index %#x\n", csr), machInst);
|
||||
}
|
||||
|
||||
RegIndex midx = csr_data_it->second.physIndex;
|
||||
const std::string& csrName = csr_data_it->second.name;
|
||||
auto mask_it = csr_masks.find(csr);
|
||||
RegVal maskVal = (mask_it == csr_masks.end()) ? mask(64)
|
||||
: mask_it->second;
|
||||
|
||||
%(op_decl)s;
|
||||
%(op_rd)s;
|
||||
|
||||
|
||||
@@ -46,8 +46,8 @@
|
||||
#ifndef __ARCH_RISCV_REGS_MISC_HH__
|
||||
#define __ARCH_RISCV_REGS_MISC_HH__
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "arch/generic/vec_pred_reg.hh"
|
||||
#include "arch/generic/vec_reg.hh"
|
||||
@@ -378,7 +378,7 @@ struct CSRMetadata
|
||||
const int physIndex;
|
||||
};
|
||||
|
||||
const std::map<int, CSRMetadata> CSRData = {
|
||||
const std::unordered_map<int, CSRMetadata> CSRData = {
|
||||
{CSR_USTATUS, {"ustatus", MISCREG_STATUS}},
|
||||
{CSR_UIE, {"uie", MISCREG_IE}},
|
||||
{CSR_UTVEC, {"utvec", MISCREG_UTVEC}},
|
||||
@@ -659,7 +659,7 @@ const RegVal UI_MASK = UEI_MASK | UTI_MASK | USI_MASK;
|
||||
const RegVal FFLAGS_MASK = (1 << FRM_OFFSET) - 1;
|
||||
const RegVal FRM_MASK = 0x7;
|
||||
|
||||
const std::map<int, RegVal> CSRMasks = {
|
||||
const std::unordered_map<int, RegVal> CSRMasks = {
|
||||
{CSR_USTATUS, USTATUS_MASK},
|
||||
{CSR_UIE, UI_MASK},
|
||||
{CSR_UIP, UI_MASK},
|
||||
|
||||
Reference in New Issue
Block a user