aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@eecs.berkeley.edu>2014-01-24 01:08:40 -0800
committerAndrew Waterman <waterman@eecs.berkeley.edu>2014-01-24 01:08:40 -0800
commit127fdd1d949715e32053fca5a4212dcb09790d2d (patch)
tree7c946028f781b857247a88a74bdbc0a659d783f2
parent2fa668a2d0a58165781ebec4f8e64e7a84fd4f6a (diff)
downloadriscv-isa-sim-127fdd1d949715e32053fca5a4212dcb09790d2d.zip
riscv-isa-sim-127fdd1d949715e32053fca5a4212dcb09790d2d.tar.gz
riscv-isa-sim-127fdd1d949715e32053fca5a4212dcb09790d2d.tar.bz2
Handle CSR permissions correctly
-rw-r--r--riscv/decode.h11
-rw-r--r--riscv/processor.cc5
2 files changed, 10 insertions, 6 deletions
diff --git a/riscv/decode.h b/riscv/decode.h
index 4abd9f9..ceaf492 100644
--- a/riscv/decode.h
+++ b/riscv/decode.h
@@ -169,11 +169,12 @@ private:
} while(0)
#define validate_csr(which, write) ({ \
- int write_priv = ((which) >> 10) & 3; \
- int read_priv = ((which) >> 8) & 3; \
- if ((which) == CSR_FCSR || (which) == CSR_FFLAGS || (which) == CSR_FRM) \
- require_fp; \
- if (read_priv > 0 || (write_priv > 0 && (write))) require_supervisor; \
+ unsigned my_priv = (p->get_state()->sr & SR_S) ? 1 : 0; \
+ unsigned read_priv = ((which) >> 10) & 3; \
+ unsigned write_priv = (((which) >> 8) & 3); \
+ if (read_priv == 3) read_priv = write_priv, write_priv = -1; \
+ if (my_priv < ((write) ? write_priv : read_priv)) \
+ throw trap_privileged_instruction(); \
(which); })
#endif
diff --git a/riscv/processor.cc b/riscv/processor.cc
index 067288c..05fee79 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -318,6 +318,9 @@ reg_t processor_t::get_pcr(int which)
return state.cause;
case CSR_PTBR:
return state.ptbr;
+ case CSR_SEND_IPI:
+ case CSR_CLEAR_IPI:
+ return 0;
case CSR_ASID:
return 0;
case CSR_FATC:
@@ -338,7 +341,7 @@ reg_t processor_t::get_pcr(int which)
sim->get_htif()->tick(); // not necessary, but faster
return state.fromhost;
default:
- return -1;
+ throw trap_illegal_instruction();
}
}