Browse Source

Merge pull request #647 from avpatel/guest_ext_status_fix_v1

Guest/VM extension status related fixes
pull/656/head
Andrew Waterman 6 years ago
committed by GitHub
parent
commit
8faa928819
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      riscv/decode.h
  2. 25
      riscv/processor.cc

2
riscv/decode.h

@ -244,7 +244,7 @@ private:
#define require_fp require((((STATE.mstatus & MSTATUS_FS) != 0) && (STATE.v == 0)) || (((STATE.mstatus & MSTATUS_FS) != 0) && ((STATE.vsstatus & SSTATUS_FS) != 0) && STATE.v))
#define require_accelerator require((STATE.mstatus & MSTATUS_XS) != 0)
#define require_vector_vs require((STATE.mstatus & MSTATUS_VS) != 0);
#define require_vector_vs require((((STATE.mstatus & MSTATUS_VS) != 0) && (STATE.v == 0)) || (((STATE.mstatus & MSTATUS_VS) != 0) && ((STATE.vsstatus & SSTATUS_VS) != 0) && STATE.v))
#define require_vector(alu) \
do { \
require_vector_vs; \

25
riscv/processor.cc

@ -647,17 +647,24 @@ void processor_t::set_virt(bool virt)
if (state.v and !virt) {
/*
* When transitioning from virt-on (VS/VU) to virt-off (HS/M)
* we should sync Guest/VM FS, VS, and XS state with Host FS,
* VS, and XS state.
* we should mark Host extension status (i.e. FS, VS, and XS
* bits) as dirty when Guest/VM extension status is dirty and
* Host extension status is initial, clean, or dirty.
*/
state.vsstatus &= ~SSTATUS_FS;
state.vsstatus |= (state.mstatus & SSTATUS_FS);
if (supports_extension('V')) {
state.vsstatus &= ~SSTATUS_VS;
state.vsstatus |= (state.mstatus & SSTATUS_VS);
if ((state.vsstatus & SSTATUS_FS) &&
((state.mstatus & SSTATUS_FS) == SSTATUS_FS)) {
state.vsstatus |= SSTATUS_FS;
}
state.vsstatus &= ~SSTATUS_XS;
state.vsstatus |= (state.mstatus & SSTATUS_XS);
if (supports_extension('V') &&
(state.vsstatus & SSTATUS_VS) &&
((state.mstatus & SSTATUS_VS) == SSTATUS_VS)) {
state.vsstatus |= SSTATUS_VS;
}
if ((state.vsstatus & SSTATUS_XS) &&
((state.mstatus & SSTATUS_XS) == SSTATUS_XS)) {
state.vsstatus |= SSTATUS_XS;
}
/* Update SD bit of Host */
state.vsstatus &= (xlen == 64 ? ~SSTATUS64_SD : ~SSTATUS32_SD);
if (((state.mstatus & SSTATUS_FS) == SSTATUS_FS) ||
((state.vsstatus & SSTATUS_VS) == SSTATUS_VS) ||

Loading…
Cancel
Save