diff --git a/src/isa/riscv64/system/priv.c b/src/isa/riscv64/system/priv.c index 4e0dc221..fcfa2808 100644 --- a/src/isa/riscv64/system/priv.c +++ b/src/isa/riscv64/system/priv.c @@ -655,11 +655,77 @@ static inline void non_vmode_set_ie(word_t src, word_t begin, word_t end) { } #endif // CONFIG_RV_AIA +inline word_t get_mip() { + word_t tmp = 0; + + tmp = mip->val & (MIP_MASK_BASE | MIP_LCOFIP); + + IFDEF(CONFIG_RVH, tmp |= hvip->val & (MIP_VSSIP)); + + tmp |= cpu.non_reg_interrupt_pending.platform_irp_msip << 3; + +#ifdef CONFIG_SHARE +#ifdef CONFIG_RV_SSTC + if (menvcfg->stce) { + tmp |= cpu.non_reg_interrupt_pending.platform_irp_stip << 5; + } else { + tmp |= mip->val & MIP_STIP; + } +#else + tmp |= mip->val & MIP_STIP; +#endif // CONFIG_RV_SSTC +#else + tmp |= mip->val & (MIP_STIP | MIP_VSTIP | MIP_MTIP); +#endif + + IFDEF(CONFIG_RVH, tmp |= (hvip->vstip | cpu.non_reg_interrupt_pending.platform_irp_vstip) << 6); + + tmp |= cpu.non_reg_interrupt_pending.platform_irp_mtip << 7; + +#ifdef CONFIG_RV_AIA + if (mvien->seie) { + tmp |= cpu.non_reg_interrupt_pending.platform_irp_seip << 9; + } else { + tmp |= (mvip->seip | cpu.non_reg_interrupt_pending.platform_irp_seip) << 9; + } +#else + tmp |= mip->val & MIP_SEIP; +#endif // CONFIG_RV_AIA + + IFDEF(CONFIG_RVH, tmp |= (hvip->vseip | cpu.non_reg_interrupt_pending.platform_irp_vseip) << 10); + + tmp |= cpu.non_reg_interrupt_pending.platform_irp_meip << 11; + + IFDEF(CONFIG_RVH, tmp |= ((hgeip->val & hgeie->val) != 0) << 12); + + return tmp; +} + +static inline void set_mip(word_t src) { + mip->val = mask_bitset(get_mip(), MIP_MASK_BASE | LCOFI, src); + + IFDEF(CONFIG_RVH, hvip->val = mask_bitset(hvip->val, MIP_MASK_H, src)); + +#ifdef CONFIG_RV_SSTC + if (!menvcfg->stce) { + mip->val = mask_bitset(get_mip(), MIP_STIP, src); + } +#else + mip->val = mask_bitset(get_mip(), MIP_STIP, src); +#endif // CONFIG_RV_SSTC + +#ifdef CONFIG_RV_AIA + mvip->val = mask_bitset(mvip->val, MIP_SEIP & (~mvien->val), src); +#else + mip->val = mask_bitset(get_mip(), MIP_SEIP, src); +#endif // CONFIG_RV_AIA +} + #ifdef CONFIG_RV_AIA static inline word_t vmode_get_ip(word_t old_value, word_t begin, word_t end) { word_t mask = gen_mask(begin, end); - old_value |= mask & ((mip->val & (mideleg->val & hideleg->val)) | + old_value |= mask & ((get_mip() & (mideleg->val & hideleg->val)) | (mvip->val & (~mideleg->val & hideleg->val & mvien->val)) | (hvip->val & (~hideleg->val & hvien->val))); @@ -679,7 +745,7 @@ static inline void vmode_set_ip(word_t src, word_t begin, word_t end) { static inline word_t non_vmode_get_ip(word_t old_value, word_t begin, word_t end) { word_t mask = gen_mask(begin, end); - old_value |= mask & ((mip->val & mideleg->val) | + old_value |= mask & ((get_mip() & mideleg->val) | (mvip->val & (~mideleg->val & mvien->val))); return old_value; @@ -794,91 +860,25 @@ static inline void set_vsie(word_t src) { } #endif // CONFIG_RVH -inline word_t get_mip() { - word_t tmp = 0; - - tmp = mip->val & (MIP_MASK_BASE | MIP_LCOFIP); - - IFDEF(CONFIG_RVH, tmp |= hvip->val & (MIP_VSSIP)); - - tmp |= cpu.non_reg_interrupt_pending.platform_irp_msip << 3; - -#ifdef CONFIG_SHARE -#ifdef CONFIG_RV_SSTC - if (menvcfg->stce) { - tmp |= cpu.non_reg_interrupt_pending.platform_irp_stip << 5; - } else { - tmp |= mip->val & MIP_STIP; - } -#else - tmp |= mip->val & MIP_STIP; -#endif // CONFIG_RV_SSTC -#else - tmp |= mip->val & (MIP_STIP | MIP_VSTIP | MIP_MTIP); -#endif - - IFDEF(CONFIG_RVH, tmp |= (hvip->vstip | cpu.non_reg_interrupt_pending.platform_irp_vstip) << 6); - - tmp |= cpu.non_reg_interrupt_pending.platform_irp_mtip << 7; - -#ifdef CONFIG_RV_AIA - if (mvien->seie) { - tmp |= cpu.non_reg_interrupt_pending.platform_irp_seip << 9; - } else { - tmp |= (mvip->seip | cpu.non_reg_interrupt_pending.platform_irp_seip) << 9; - } -#else - tmp |= mip->val & MIP_SEIP; -#endif // CONFIG_RV_AIA - - IFDEF(CONFIG_RVH, tmp |= (hvip->vseip | cpu.non_reg_interrupt_pending.platform_irp_vseip) << 10); - - tmp |= cpu.non_reg_interrupt_pending.platform_irp_meip << 11; - - IFDEF(CONFIG_RVH, tmp |= ((hgeip->val & hgeie->val) != 0) << 12); - - return tmp; -} - -static inline void set_mip(word_t src) { - mip->val = mask_bitset(mip->val, MIP_MASK_BASE | LCOFI, src); - - IFDEF(CONFIG_RVH, hvip->val = mask_bitset(hvip->val, MIP_MASK_H, src)); - -#ifdef CONFIG_RV_SSTC - if (!menvcfg->stce) { - mip->val = mask_bitset(mip->val, MIP_STIP, src); - } -#else - mip->val = mask_bitset(mip->val, MIP_STIP, src); -#endif // CONFIG_RV_SSTC - -#ifdef CONFIG_RV_AIA - mvip->val = mask_bitset(mvip->val, MIP_SEIP & (~mvien->val), src); -#else - mip->val = mask_bitset(mip->val, MIP_SEIP, src); -#endif // CONFIG_RV_AIA -} - static inline word_t non_vmode_get_sip() { word_t tmp = 0; #ifdef CONFIG_RV_AIA - tmp |= mip->val & (MIP_SSIP | MIP_STIP | MIP_SEIP) & mideleg->val; + tmp |= get_mip() & (MIP_SSIP | MIP_STIP | MIP_SEIP) & mideleg->val; tmp |= mvip->val & (MIP_SSIP | MIP_SEIP) & (~mideleg->val & mvien->val); tmp |= non_vmode_get_ip(tmp, 13, 63); #else - tmp = mip->val & SIP_MASK; + tmp = get_mip() & SIP_MASK; #endif // CONFIG_RV_AIA return tmp; } static inline void non_vmode_set_sip(word_t src) { #ifdef CONFIG_RV_AIA - mip->val = mask_bitset(mip->val, (MIP_SSIP | MIP_LCOFIP) & mideleg->val, src); + mip->val = mask_bitset(get_mip(), (MIP_SSIP | MIP_LCOFIP) & mideleg->val, src); mvip->val = mask_bitset(mvip->val, (MIP_SSIP | MIP_LCOFIP) & (~mideleg->val & mvien->val), src); non_vmode_set_ip(src, 14, 63); #else - mip->val = mask_bitset(mip->val, ((cpu.mode == MODE_S) ? SIP_WMASK_S : SIP_MASK), src); + mip->val = mask_bitset(get_mip(), ((cpu.mode == MODE_S) ? SIP_WMASK_S : SIP_MASK), src); #endif // CONFIG_RV_AIA } @@ -888,10 +888,10 @@ static inline word_t get_mvip() { tmp = mvip->val & MVIP_MASK; - tmp |= mvien->ssie ? mvip->val & MIP_SSIP : mip->val & MIP_SSIP; + tmp |= mvien->ssie ? mvip->val & MIP_SSIP : get_mip() & MIP_SSIP; if (!menvcfg->stce) { - tmp |= mip->val & MIP_STIP; + tmp |= get_mip() & MIP_STIP; } tmp |= mvip->val & MIP_SEIP; @@ -906,10 +906,10 @@ static inline void set_mvip(word_t src) { mvip->val = mask_bitset(mvip->val, MIP_SSIP & mvien->val, src); - mip->val = mask_bitset(mip->val, MIP_SSIP & (~mvien->val), src); + mip->val = mask_bitset(get_mip(), MIP_SSIP & (~mvien->val), src); if (!menvcfg->stce) { - mip->val = mask_bitset(mip->val, MIP_STIP, src); + mip->val = mask_bitset(get_mip(), MIP_STIP, src); } mvip->val = mask_bitset(mvip->val, MIP_SEIP, src); @@ -920,12 +920,12 @@ static inline void set_mvip(word_t src) { static inline word_t vmode_get_sip() { word_t tmp = 0; - tmp = (mip->val & VSI_MASK) >> 1; + tmp = (get_mip() & VSI_MASK) >> 1; #ifdef CONFIG_RV_AIA tmp |= vmode_get_ip(tmp, 13, 63); #else - IFDEF(CONFIG_RV_SSCOFPMF, tmp |= mip->val & mideleg->val & hideleg->val & MIP_LCOFIP); + IFDEF(CONFIG_RV_SSCOFPMF, tmp |= get_mip() & mideleg->val & hideleg->val & MIP_LCOFIP); #endif // CONFIG_RV_AIA return tmp; @@ -937,12 +937,12 @@ static inline void vmode_set_sip(word_t src) { hvip->val = mask_bitset(hvip->val, MIP_VSSIP, src << 1); #ifdef CONFIG_RV_AIA - mip->val = mask_bitset(mip->val, MIP_LCOFIP & mideleg->val & hideleg->val, src); + mip->val = mask_bitset(get_mip(), MIP_LCOFIP & mideleg->val & hideleg->val, src); mvip->val = mask_bitset(mvip->val, MIP_LCOFIP & (~mideleg->val & hideleg->val & mvien->val), src); hvip->val = mask_bitset(hvip->val, MIP_LCOFIP & (~hideleg->val & hvien->val), src); vmode_set_ip(src, 14, 63); #else - IFDEF(CONFIG_RV_SSCOFPMF, mip->val = mask_bitset(mip->val, MIP_LCOFIP & mideleg->val & hideleg->val, src)); + IFDEF(CONFIG_RV_SSCOFPMF, mip->val = mask_bitset(get_mip(), MIP_LCOFIP & mideleg->val & hideleg->val, src)); #endif // CONFIG_RV_AIA } #endif // CONFIG_RVH @@ -956,7 +956,7 @@ static inline word_t get_vsip() { #ifdef CONFIG_RV_AIA tmp |= vmode_get_ip(tmp, 13, 63); #else - IFDEF(CONFIG_RV_SSCOFPMF, tmp |= mip->val & MIP_LCOFIP & mideleg->val & hideleg->val); + IFDEF(CONFIG_RV_SSCOFPMF, tmp |= get_mip() & MIP_LCOFIP & mideleg->val & hideleg->val); #endif // CONFIG_RV_AIA return tmp; @@ -967,12 +967,12 @@ static inline word_t get_vsip() { static inline void set_vsip(word_t src) { hvip->val = mask_bitset(hvip->val, MIP_VSSIP & (hideleg->val & (mideleg->val | MIDELEG_FORCED_MASK)), src << 1); #ifdef CONFIG_RV_AIA - mip->val = mask_bitset(mip->val, MIP_LCOFIP & mideleg->val & hideleg->val, src); + mip->val = mask_bitset(get_mip(), MIP_LCOFIP & mideleg->val & hideleg->val, src); mvip->val = mask_bitset(mvip->val, MIP_LCOFIP & (~mideleg->val & hideleg->val & mvien->val), src); hvip->val = mask_bitset(hvip->val, MIP_LCOFIP & (~hideleg->val & hvien->val), src); vmode_set_ip(src, 14, 63); #else - IFDEF(CONFIG_RV_SSCOFPMF, mip->val = mask_bitset(mip->val, MIP_LCOFIP & mideleg->val & hideleg->val, src)); + IFDEF(CONFIG_RV_SSCOFPMF, mip->val = mask_bitset(get_mip(), MIP_LCOFIP & mideleg->val & hideleg->val, src)); #endif // CONFIG_RV_AIA } #endif // CONFIG_RVH