fixes privilege wrapper for M/U to cope with 64bit
This commit is contained in:
		@@ -181,6 +181,89 @@ public:
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // specialization 64bit
 | 
				
			||||||
 | 
					    template <typename T> class hart_state<T, typename std::enable_if<std::is_same<T, uint64_t>::value>::type> {
 | 
				
			||||||
 | 
					    public:
 | 
				
			||||||
 | 
					        BEGIN_BF_DECL(mstatus_t, T);
 | 
				
			||||||
 | 
					        // SD bit is read-only and is set when either the FS or XS bits encode a Dirty state (i.e., SD=((FS==11) OR XS==11)))
 | 
				
			||||||
 | 
					        BF_FIELD(SD, 63, 1);
 | 
				
			||||||
 | 
					        // value of XLEN for S-mode
 | 
				
			||||||
 | 
					        BF_FIELD(SXL, 34, 2);
 | 
				
			||||||
 | 
					        // value of XLEN for U-mode
 | 
				
			||||||
 | 
					        BF_FIELD(UXL, 32, 2);
 | 
				
			||||||
 | 
					        // Trap SRET
 | 
				
			||||||
 | 
					        BF_FIELD(TSR, 22, 1);
 | 
				
			||||||
 | 
					        // Timeout Wait
 | 
				
			||||||
 | 
					        BF_FIELD(TW, 21, 1);
 | 
				
			||||||
 | 
					        // Trap Virtual Memory
 | 
				
			||||||
 | 
					        BF_FIELD(TVM, 20, 1);
 | 
				
			||||||
 | 
					        // Make eXecutable Readable
 | 
				
			||||||
 | 
					        BF_FIELD(MXR, 19, 1);
 | 
				
			||||||
 | 
					        // permit Supervisor User Memory access
 | 
				
			||||||
 | 
					        BF_FIELD(SUM, 18, 1);
 | 
				
			||||||
 | 
					        // Modify PRiVilege
 | 
				
			||||||
 | 
					        BF_FIELD(MPRV, 17, 1);
 | 
				
			||||||
 | 
					        // status of additional user-mode extensions and associated state, All off/None dirty or clean, some on/None dirty, some clean/Some dirty
 | 
				
			||||||
 | 
					        BF_FIELD(XS, 15, 2);
 | 
				
			||||||
 | 
					        // floating-point unit status Off/Initial/Clean/Dirty
 | 
				
			||||||
 | 
					        BF_FIELD(FS, 13, 2);
 | 
				
			||||||
 | 
					        // machine previous privilege
 | 
				
			||||||
 | 
					        BF_FIELD(MPP, 11, 2);
 | 
				
			||||||
 | 
					        // supervisor previous privilege
 | 
				
			||||||
 | 
					        BF_FIELD(SPP, 8, 1);
 | 
				
			||||||
 | 
					        // previous machine interrupt-enable
 | 
				
			||||||
 | 
					        BF_FIELD(MPIE, 7, 1);
 | 
				
			||||||
 | 
					        // previous supervisor interrupt-enable
 | 
				
			||||||
 | 
					        BF_FIELD(SPIE, 5, 1);
 | 
				
			||||||
 | 
					        // previous user interrupt-enable
 | 
				
			||||||
 | 
					        BF_FIELD(UPIE, 4, 1);
 | 
				
			||||||
 | 
					        // machine interrupt-enable
 | 
				
			||||||
 | 
					        BF_FIELD(MIE, 3, 1);
 | 
				
			||||||
 | 
					        // supervisor interrupt-enable
 | 
				
			||||||
 | 
					        BF_FIELD(SIE, 1, 1);
 | 
				
			||||||
 | 
					        // user interrupt-enable
 | 
				
			||||||
 | 
					        BF_FIELD(UIE, 0, 1);
 | 
				
			||||||
 | 
					        END_BF_DECL();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        mstatus_t mstatus;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        static const reg_t mstatus_reset_val = 0x1800;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        void write_mstatus(T val, unsigned priv_lvl) {
 | 
				
			||||||
 | 
					            auto mask = get_mask(priv_lvl);
 | 
				
			||||||
 | 
					            auto new_val = (mstatus.backing.val & ~mask) | (val & mask);
 | 
				
			||||||
 | 
					            mstatus = new_val;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        static constexpr uint64_t get_mask(unsigned priv_lvl) {
 | 
				
			||||||
 | 
					#if __cplusplus < 201402L
 | 
				
			||||||
 | 
					            return priv_lvl == PRIV_U ? 0x011ULL : priv_lvl == PRIV_S ? 0x000de133ULL : 0x007ff9ddULL;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					            switch (priv_lvl) {
 | 
				
			||||||
 | 
					            case PRIV_U: return 0x00000011UL; // 0b1000 0000 0000 0000 0000 0000 0001 0001
 | 
				
			||||||
 | 
					            default:
 | 
				
			||||||
 | 
					            //       +-SD
 | 
				
			||||||
 | 
					            //       |        +-TSR
 | 
				
			||||||
 | 
					            //       |        |+-TW
 | 
				
			||||||
 | 
					            //       |        ||+-TVM
 | 
				
			||||||
 | 
					            //       |        |||+-MXR
 | 
				
			||||||
 | 
					            //       |        ||||+-SUM
 | 
				
			||||||
 | 
					            //       |        |||||+-MPRV
 | 
				
			||||||
 | 
					            //       |        |||||| +-XS
 | 
				
			||||||
 | 
					            //       |        |||||| | +-FS
 | 
				
			||||||
 | 
					            //       |        |||||| | | +-MPP
 | 
				
			||||||
 | 
					            //       |        |||||| | | |  +-SPP
 | 
				
			||||||
 | 
					            //       |        |||||| | | |  |+-MPIE
 | 
				
			||||||
 | 
					            //       |        |||||| | | |  ||  +-UPIE
 | 
				
			||||||
 | 
					            //       |        ||||||/|/|/|  ||  |+-MIE
 | 
				
			||||||
 | 
					            //       |        ||||||/|/|/|  ||  ||  +-UIE
 | 
				
			||||||
 | 
					            return 0b00000000000000000001100010011001;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    using hart_state_type = hart_state<reg_t>;
 | 
					    using hart_state_type = hart_state<reg_t>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    constexpr reg_t get_irq_mask(size_t mode) {
 | 
					    constexpr reg_t get_irq_mask(size_t mode) {
 | 
				
			||||||
@@ -450,7 +533,7 @@ riscv_hart_mu_p<BASE, FEAT>::riscv_hart_mu_p(feature_config cfg)
 | 
				
			|||||||
            csr_rd_cb[i] = &this_class::read_csr_reg;
 | 
					            csr_rd_cb[i] = &this_class::read_csr_reg;
 | 
				
			||||||
            csr_wr_cb[i] = &this_class::write_csr_reg;
 | 
					            csr_wr_cb[i] = &this_class::write_csr_reg;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        for(size_t i=pmpcfg0; i<=pmpcfg3; ++i){
 | 
					        for(size_t i=pmpcfg0; i<pmpcfg0+16/sizeof(reg_t); ++i){
 | 
				
			||||||
            csr_rd_cb[i] = &this_class::read_csr_reg;
 | 
					            csr_rd_cb[i] = &this_class::read_csr_reg;
 | 
				
			||||||
            csr_wr_cb[i] = &this_class::write_pmpcfg_reg;
 | 
					            csr_wr_cb[i] = &this_class::write_pmpcfg_reg;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -627,9 +710,10 @@ template <typename BASE, features_e FEAT> bool riscv_hart_mu_p<BASE, FEAT>::pmp_
 | 
				
			|||||||
    constexpr auto PMP_NAPOT =0x3U;
 | 
					    constexpr auto PMP_NAPOT =0x3U;
 | 
				
			||||||
    reg_t base = 0;
 | 
					    reg_t base = 0;
 | 
				
			||||||
    auto any_active = false;
 | 
					    auto any_active = false;
 | 
				
			||||||
 | 
					    auto const cfg_reg_size=sizeof(reg_t);
 | 
				
			||||||
    for (size_t i = 0; i < 16; i++) {
 | 
					    for (size_t i = 0; i < 16; i++) {
 | 
				
			||||||
        reg_t tor = csr[pmpaddr0+i] << PMP_SHIFT;
 | 
					        reg_t tor = csr[pmpaddr0+i] << PMP_SHIFT;
 | 
				
			||||||
        uint8_t cfg = csr[pmpcfg0+(i/4)]>>(i%4);
 | 
					        uint8_t cfg = csr[pmpcfg0+(i/cfg_reg_size)]>>(i%cfg_reg_size);
 | 
				
			||||||
        if (cfg & PMP_A) {
 | 
					        if (cfg & PMP_A) {
 | 
				
			||||||
            any_active=true;
 | 
					            any_active=true;
 | 
				
			||||||
            auto pmp_a = (cfg & PMP_A) >> 3;
 | 
					            auto pmp_a = (cfg & PMP_A) >> 3;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user