aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--riscv/encoding.h8
-rw-r--r--riscv/processor.cc12
-rw-r--r--riscv/sim.cc1
3 files changed, 18 insertions, 3 deletions
diff --git a/riscv/encoding.h b/riscv/encoding.h
index fb1536e..219fee3 100644
--- a/riscv/encoding.h
+++ b/riscv/encoding.h
@@ -9,7 +9,7 @@
#define MSTATUS_MIE 0x00000008
#define MSTATUS_UPIE 0x00000010
#define MSTATUS_SPIE 0x00000020
-#define MSTATUS_HPIE 0x00000040
+#define MSTATUS_UBE 0x00000040
#define MSTATUS_MPIE 0x00000080
#define MSTATUS_SPP 0x00000100
#define MSTATUS_VS 0x00000600
@@ -25,14 +25,20 @@
#define MSTATUS32_SD 0x80000000
#define MSTATUS_UXL 0x0000000300000000
#define MSTATUS_SXL 0x0000000C00000000
+#define MSTATUS_SBE 0x0000001000000000
+#define MSTATUS_MBE 0x0000002000000000
#define MSTATUS_GVA 0x0000004000000000
#define MSTATUS_MPV 0x0000008000000000
#define MSTATUS64_SD 0x8000000000000000
+#define MSTATUSH_SBE 0x00000010
+#define MSTATUSH_MBE 0x00000020
+
#define SSTATUS_UIE 0x00000001
#define SSTATUS_SIE 0x00000002
#define SSTATUS_UPIE 0x00000010
#define SSTATUS_SPIE 0x00000020
+#define SSTATUS_UBE 0x00000040
#define SSTATUS_SPP 0x00000100
#define SSTATUS_VS 0x00000600
#define SSTATUS_FS 0x00006000
diff --git a/riscv/processor.cc b/riscv/processor.cc
index 564f1b3..b61bd33 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -446,6 +446,10 @@ void processor_t::enable_log_commits()
void processor_t::reset()
{
state.reset(max_isa);
+#ifdef RISCV_ENABLE_DUAL_ENDIAN
+ if (mmu->is_target_big_endian())
+ state.mstatus |= MSTATUS_UBE | MSTATUS_SBE | MSTATUS_MBE;
+#endif
state.mideleg = supports_extension('H') ? MIDELEG_FORCED_MASK : 0;
@@ -1411,8 +1415,8 @@ reg_t processor_t::get_csr(int which, insn_t insn, bool write, bool peek)
ret(state.mcounteren);
case CSR_MCOUNTINHIBIT: ret(0);
case CSR_SSTATUS: {
- reg_t mask = SSTATUS_SIE | SSTATUS_SPIE | SSTATUS_SPP | SSTATUS_FS
- | (supports_extension('V') ? SSTATUS_VS : 0)
+ reg_t mask = SSTATUS_SIE | SSTATUS_SPIE | SSTATUS_UBE | SSTATUS_SPP
+ | SSTATUS_FS | (supports_extension('V') ? SSTATUS_VS : 0)
| SSTATUS_XS | SSTATUS_SUM | SSTATUS_MXR | SSTATUS_UXL;
reg_t sstatus = state.mstatus & mask;
if ((sstatus & SSTATUS_FS) == SSTATUS_FS ||
@@ -1486,6 +1490,10 @@ reg_t processor_t::get_csr(int which, insn_t insn, bool write, bool peek)
}
}
case CSR_MSTATUS: ret(state.mstatus);
+ case CSR_MSTATUSH:
+ if (xlen == 32)
+ ret((state.mstatus >> 32) & (MSTATUSH_SBE | MSTATUSH_MBE));
+ break;
case CSR_MIP: ret(state.mip);
case CSR_MIE: ret(state.mie);
case CSR_MEPC: ret(state.mepc & pc_alignment_mask());
diff --git a/riscv/sim.cc b/riscv/sim.cc
index 6faa1ac..ddf1f2c 100644
--- a/riscv/sim.cc
+++ b/riscv/sim.cc
@@ -350,6 +350,7 @@ void sim_t::set_target_endianness(memif_endianness_t endianness)
debug_mmu->set_target_big_endian(enable);
for (size_t i = 0; i < procs.size(); i++) {
procs[i]->get_mmu()->set_target_big_endian(enable);
+ procs[i]->reset();
}
#else
assert(endianness == memif_endianness_little);