Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean Up How CSR Registers are Read and Written #58

Open
kathlenemagnus-mips opened this issue Jan 29, 2025 · 1 comment
Open

Clean Up How CSR Registers are Read and Written #58

kathlenemagnus-mips opened this issue Jan 29, 2025 · 1 comment

Comments

@kathlenemagnus-mips
Copy link
Contributor

In arch/register_macros.hpp, we have several macros defined for reading and writing to whole CSR registers and CSR fields:

#define READ_CSR_REG(reg_name) \
state->getCsrRegister(atlas::CSR::reg_name::reg_num)->dmiRead<uint64_t>()
#define WRITE_CSR_REG(reg_name, reg_value) \
if constexpr (atlas::CSR::reg_name::writable_fields_bit_mask != 0xffffffffffffffff) \
{ \
const auto old_value = \
state->getCsrRegister(atlas::CSR::reg_name::reg_num)->dmiRead<uint64_t>(); \
state->getCsrRegister(atlas::CSR::reg_name::reg_num) \
->dmiWrite( \
atlas::RegisterBitMask<atlas::CSR::reg_name::writable_fields_bit_mask>::mask( \
old_value, reg_value)); \
} \
else \
{ \
state->getCsrRegister(atlas::CSR::reg_name::reg_num)->dmiWrite(reg_value); \
}
#define READ_CSR_FIELD(reg_name, field_name) \
atlas::CSRFields<atlas::CSR::reg_name::field_name>::readField( \
state->getCsrRegister(atlas::CSR::reg_name::reg_num)->dmiRead<uint64_t>())
#define WRITE_CSR_FIELD(reg_name, field_name, field_value) \
{ \
const auto old_value = \
state->getCsrRegister(atlas::CSR::reg_name::reg_num)->dmiRead<uint64_t>(); \
WRITE_CSR_REG(reg_name, \
(old_value | (field_value << atlas::CSR::reg_name::field_name::low_bit))); \
}
#define PEEK_CSR_REG(reg_name) READ_CSR_REG(reg_name)
#define POKE_CSR_REG(reg_name, reg_value) \
state->getCsrRegister(atlas::CSR::reg_name::reg_num)->dmiWrite(reg_value);

This works fine when we need to explicitly access a CSR. For example, when handling an exception, we read and write to the same set of CSRs every time and can access them by name. What these macros don't support is accessing a CSR through a register pointer like this:

const AtlasInstPtr & insn = state->getCurrentInst();
const uint32_t csr_num = insn->getMavisOpcodeInfo()->getSpecialField(mavis::OpcodeInfo::SpecialField::CSR);
auto csr_reg = state->getCsrRegister(csr_num);

The problem is that we don't have a way of getting the CSR fields or the writable_fields_bit_mask without having the name of the CSR. Open to suggestions on how to improve this. One idea would be to take the CSR structs that contain the field definitions and put them in a map indexed by the CSR number.

@kathlenemagnus-mips
Copy link
Contributor Author

  • Rewrite CSR macros to access the CSR number as a parameter instead of the CSR name @colby-nyce
  • Fix WRITE_CSR_FIELD macro @lzhu-pub
  • Update CSR macros to support RV32 and RV64
  • Get rv64mi-p-csr arch test to pass @kathlenemagnus

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant