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

--

--

--

Software Engineer, Software Architect, Embedded Systems, Distributed Systems, Digital Design, ソフトウェアエンジニア http://www.linkedin.com/in/phil-mulholland-884a8

Love podcasts or audiobooks? Learn on the go with our new app.

Four Lessons Learned from Building Microservices

🎁Roles-Giveaway

Hello Error my Old Friend!

Why Am I Having Sitecore Performance Issues?

A history of express.co.uk

CS 371P Spring 2022 #12: Anya Uwakwe

TryhackMe -BrainStorm

Programmers health

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

Software Engineer, Software Architect, Embedded Systems, Distributed Systems, Digital Design, ソフトウェアエンジニア http://www.linkedin.com/in/phil-mulholland-884a8

More from Medium

C++20 Concurrency — Part 2: jthreads

Adding Color to Your Output From C

Modern C++ in Advent of Code: Day24

C vs C++: Major Differences To Check In The Year 2022