@@ -308,11 +308,78 @@ template <typename WORD_TYPE> struct priv_if {
308308};
309309
310310template <typename BASE = logging::disass> struct riscv_hart_common : public BASE , public mem ::memory_elem {
311- // Extension status bits (SD needs to be set when writing FS / VS / XS):
311+
312+ constexpr static unsigned MEM = traits<BASE>::MEM;
313+
314+ using core = BASE;
315+ using this_class = riscv_hart_common<BASE>;
316+ using reg_t = typename core::reg_t ;
317+
318+ using rd_csr_f = std::function<iss::status(unsigned addr, reg_t &)>;
319+ using wr_csr_f = std::function<iss::status(unsigned addr, reg_t )>;
320+
321+ // Extension status bits (SD needs to be set when any of FS / VS / XS are dirty [0b11]):
312322 // TODO implement XS
313323 static constexpr uint32_t extension_status_mask =
314324 (traits<BASE>::FP_REGS_SIZE ? (0b11u << 13 ) : 0u ) | (traits<BASE>::V_REGS_SIZE ? (0b11u << 9 ) : 0u );
315325
326+ // Notation for differing fields is: 32 bits / 64 bits
327+ static constexpr uint32_t mstatus_lower = 0b00000000000000000001100010001000 ;
328+ static constexpr uint32_t sstatus_lower = 0b00000000011111100000000100100010 ;
329+ static constexpr uint32_t ustatus_lower = 0b00000000000000000000000000010001 ;
330+ // ||||||/|||||||||/|/|/|/|||||||||
331+ // |||||/ ||||||||| | | | ||||||||+-- UIE
332+ // ||||/||||||||||| | | | |||||||+--- SIE
333+ // |||/|||||||||||| | | | ||||||+---- WPRI
334+ // ||/||||||||||||| | | | |||||+----- MIE
335+ // |||||||||||||||| | | | ||||+------ UPIE
336+ // |||||||||||||||| | | | |||+------- SPIE
337+ // |||||||||||||||| | | | ||+-------- UBE
338+ // |||||||||||||||| | | | |+--------- MPIE
339+ // |||||||||||||||| | | | +---------- SPP
340+ // |||||||||||||||| | | +------------ VS
341+ // |||||||||||||||| | +-------------- MPP
342+ // |||||||||||||||| +---------------- FS
343+ // |||||||||||||||+------------------ XS
344+ // ||||||||||||||+------------------- MPRV
345+ // |||||||||||||+-------------------- SUM
346+ // ||||||||||||+--------------------- MXR
347+ // |||||||||||+---------------------- TVM
348+ // ||||||||||+----------------------- TW
349+ // |||||||||+------------------------ TSR
350+ // ||||||||+------------------------- SPELP
351+ // |||||||+-------------------------- SDT
352+ // |++++++--------------------------- WPRI
353+ // +--------------------------------- SD / WPRI
354+
355+ // upper half does not correspond to mstatush bit meanings (UXL and SXL)
356+ static constexpr uint32_t mstatus_upper = 0b00000000000000000000000000001111 ;
357+ static constexpr uint32_t sstatus_upper = 0b00000000000000000000000000000011 ;
358+ // |||||||||||||||||||||||||||||/|/
359+ // ||||||||||||||||||||||||||||| +--- WPRI / UXL
360+ // ||||||||||||||||||||||||||||+----- WPRI / SXL
361+ // |||||||||||||||||||||||||||+------ SBE
362+ // |||||||||||||||||||||||||+-------- MBE
363+ // ||||||||||||||||||||||||+--------- GVA
364+ // |||||||||||||||||||||||+---------- MPV
365+ // ||||||||||||||||||||||+----------- WPRI
366+ // |||||||||||||||||||||+------------ MPELP
367+ // ||||||||||||||||||||+------------- MDT
368+ // |+++++++++++++++++++-------------- WPRI
369+ // +--------------------------------- WPRI / SD
370+
371+ static constexpr reg_t get_mstatus_mask () {
372+ if constexpr (sizeof (reg_t ) == 4 )
373+ return mstatus_lower | riscv_hart_common<BASE>::extension_status_mask;
374+ else if constexpr (sizeof (reg_t ) == 8 )
375+ return static_cast <reg_t >(mstatus_upper) << 32 | mstatus_lower | riscv_hart_common<BASE>::extension_status_mask;
376+ else
377+ static_assert (" Unsupported XLEN value" );
378+ }
379+ static constexpr reg_t get_mu_status_mask (unsigned priv_lvl) { return ustatus_lower | (priv_lvl >= PRIV_M ? get_mstatus_mask () : 0 ); }
380+ static constexpr reg_t get_msu_status_mask (unsigned priv_lvl) {
381+ return get_mu_status_mask (priv_lvl) | ((priv_lvl >= PRIV_S) ? sstatus_lower : 0 );
382+ }
316383 const std::array<const char , 4 > lvl = {{' U' , ' S' , ' H' , ' M' }};
317384 const std::array<const char *, 16 > trap_str = {{" "
318385 " Instruction address misaligned" , // 0
@@ -335,14 +402,6 @@ template <typename BASE = logging::disass> struct riscv_hart_common : public BAS
335402 " Machine software interrupt" , " User timer interrupt" , " Supervisor timer interrupt" ,
336403 " Reserved" , " Machine timer interrupt" , " User external interrupt" ,
337404 " Supervisor external interrupt" , " Reserved" , " Machine external interrupt" }};
338- constexpr static unsigned MEM = traits<BASE>::MEM;
339-
340- using core = BASE;
341- using this_class = riscv_hart_common<BASE>;
342- using reg_t = typename core::reg_t ;
343-
344- using rd_csr_f = std::function<iss::status(unsigned addr, reg_t &)>;
345- using wr_csr_f = std::function<iss::status(unsigned addr, reg_t )>;
346405
347406#define MK_CSR_RD_CB (FCT ) [this ](unsigned a, reg_t & r) -> iss::status { return this ->FCT (a, r); };
348407#define MK_CSR_WR_CB (FCT ) [this ](unsigned a, reg_t r) -> iss::status { return this ->FCT (a, r); };
0 commit comments