RISC-V: A Baremetal Introduction using C++. System Registers.

RISC-V Special Instructions and C++

auto this_cause = riscv::csrs.mcause.read();
riscv::csrs.mie.mti.set();
riscv::csrs.mtvec.write(
reinterpret_cast<std::uintptr_t>(irq_vector));
namespace riscv {
namespace csr {
#if __riscv_xlen==32
using uint_xlen_t = std::uint32_t;
#elif __riscv_xlen==64
using uint_xlen_t = std::uint64_t;
#endif
struct mtvec_ops {
using datatype = uint_xlen_t;
static constexpr priv_t priv = MRW;
static void write(uint_xlen_t value) {
__asm__ volatile ("csrw mtvec, %0"
: /* output: none */
: "r" (value) /* input*/
: /* clobbers: none */);
}
}
}
}
namespace riscv {
namespace csr {
template<class C> class read_write_reg {
public :
using write_datatype_t = typename C::datatype;
/** Write to the CSR. */
inline void write(const write_datatype_t value) {
C::write(value);
}
};
// Instantiate the read_write_reg class
// with the mtvec operations
using mtvec_reg = read_write_reg<mtvec_ops>;
// ...
struct all {
riscv::csr::mtvec_reg mtvec;
}
} /* csr */
static csr::all csrs;
} /* riscv */
riscv::csrs.mtvec.write( reinterpret_cast<std::uintptr_t>(entry));

RISC-V CSRs and Bit Level Access

namespace riscv {
namespace csr {
struct mie_ops {
/** Atomic modify and set bits for mie */
static void set_bits(uint_xlen_t mask) {
__asm__ volatile ("csrrs zero, mie, %0"
: /* output: none */
: "r" (mask) /* input */
: /* clobbers: none */);
}
/** Atomic modify and set bits from immediate for mie */
static void set_bits_imm(const uint8_t mask) {
__asm__ volatile ("csrrsi zero, mie, %0"
: /* output: none */
: "i" (mask) /* input */
: /* clobbers: none */);
}
}; /* mie_ops */
template<class C, class F> class read_write_field {
public:
inline void set(void) {
if constexpr ((F::BIT_MASK & CSR_IMM_OP_MASK) ==
F::BIT_MASK) {
C::set_bits_imm(F::BIT_MASK);
} else {
C::set_bits(F::BIT_MASK);
}
}
};
/* Machine Status */
template<class OPS> class mstatus_reg :
public read_write_reg<OPS>
{
public:
read_write_field<OPS,
riscv::csr::mstatus_data::mie> mie;
};
using mstatus = mstatus_reg<riscv::csr::mstatus_ops>;;
} /* csr */
} /* riscv */
// Global interrupt enable
riscv::csrs.mstatus.mie.set();

Conclusion

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Phil Mulholland

Phil Mulholland

Experienced in Distributed Systems, Event-Driven Systems, Firmware for SoC/MCU, Systems Simulation, Network Monitoring and Analysis, Automated Testing and RTL.