From 971cf098413fe227a28f5dc30a1e50872e9e04ef Mon Sep 17 00:00:00 2001 From: Scott Johnson Date: Sat, 6 Mar 2021 08:51:32 -0800 Subject: Add get_const_xlen() as a way to document assumptions of unchanging xlen Spike does not support dynamic xlen today, but if it should in the future, this will help identify all the code that needs to be updated. --- riscv/csrs.cc | 14 +++++++------- riscv/mmu.cc | 4 ++-- riscv/processor.h | 6 ++++++ 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/riscv/csrs.cc b/riscv/csrs.cc index c4e51d4..d76c642 100644 --- a/riscv/csrs.cc +++ b/riscv/csrs.cc @@ -335,14 +335,14 @@ bool vsstatus_csr_t::unlogged_write(const reg_t val) noexcept { reg_t mask = SSTATUS_VS_MASK; mask |= (proc->supports_extension('V') ? SSTATUS_VS : 0); reg_t newval = (this->val & ~mask) | (val & mask); - newval &= (proc->get_xlen() == 64 ? ~SSTATUS64_SD : ~SSTATUS32_SD); + newval &= (proc->get_const_xlen() == 64 ? ~SSTATUS64_SD : ~SSTATUS32_SD); if (((newval & SSTATUS_FS) == SSTATUS_FS) || ((newval & SSTATUS_VS) == SSTATUS_VS) || ((newval & SSTATUS_XS) == SSTATUS_XS)) { - newval |= (proc->get_xlen() == 64 ? SSTATUS64_SD : SSTATUS32_SD); + newval |= (proc->get_const_xlen() == 64 ? SSTATUS64_SD : SSTATUS32_SD); } if (proc->supports_extension('U')) - newval = set_field(newval, SSTATUS_UXL, xlen_to_uxl(proc->get_max_xlen())); + newval = set_field(newval, SSTATUS_UXL, xlen_to_uxl(proc->get_const_xlen())); this->val = newval; return true; @@ -359,7 +359,7 @@ reg_t sstatus_proxy_csr_t::read() const noexcept { reg_t mask = SSTATUS_SIE | SSTATUS_SPIE | SSTATUS_UBE | SSTATUS_SPP | SSTATUS_FS | (proc->supports_extension('V') ? SSTATUS_VS : 0) | SSTATUS_XS | SSTATUS_SUM | SSTATUS_MXR | SSTATUS_UXL - | (proc->get_xlen() == 32 ? SSTATUS32_SD : SSTATUS64_SD); + | (proc->get_const_xlen() == 32 ? SSTATUS32_SD : SSTATUS64_SD); return mstatus->read() & mask; } @@ -425,15 +425,15 @@ bool mstatus_csr_t::unlogged_write(const reg_t val) noexcept { bool dirty = (new_mstatus & MSTATUS_FS) == MSTATUS_FS; dirty |= (new_mstatus & MSTATUS_XS) == MSTATUS_XS; dirty |= (new_mstatus & MSTATUS_VS) == MSTATUS_VS; - if (proc->get_max_xlen() == 32) + if (proc->get_const_xlen() == 32) new_mstatus = set_field(new_mstatus, MSTATUS32_SD, dirty); else new_mstatus = set_field(new_mstatus, MSTATUS64_SD, dirty); if (proc->supports_extension('U')) - new_mstatus = set_field(new_mstatus, MSTATUS_UXL, xlen_to_uxl(proc->get_max_xlen())); + new_mstatus = set_field(new_mstatus, MSTATUS_UXL, xlen_to_uxl(proc->get_const_xlen())); if (proc->supports_extension('S')) - new_mstatus = set_field(new_mstatus, MSTATUS_SXL, xlen_to_uxl(proc->get_max_xlen())); + new_mstatus = set_field(new_mstatus, MSTATUS_SXL, xlen_to_uxl(proc->get_const_xlen())); this->val = new_mstatus; return true; diff --git a/riscv/mmu.cc b/riscv/mmu.cc index b50ca8c..0d6509a 100644 --- a/riscv/mmu.cc +++ b/riscv/mmu.cc @@ -263,7 +263,7 @@ reg_t mmu_t::s2xlate(reg_t gva, reg_t gpa, access_type type, access_type trap_ty if (!virt) return gpa; - vm_info vm = decode_vm_info(proc->max_xlen, true, 0, proc->get_state()->hgatp); + vm_info vm = decode_vm_info(proc->get_const_xlen(), true, 0, proc->get_state()->hgatp); if (vm.levels == 0) return gpa; @@ -341,7 +341,7 @@ reg_t mmu_t::walk(reg_t addr, access_type type, reg_t mode, bool virt, bool hlvx { reg_t page_mask = (reg_t(1) << PGSHIFT) - 1; reg_t satp = (virt) ? proc->get_state()->vsatp : proc->get_state()->satp; - vm_info vm = decode_vm_info(proc->max_xlen, false, mode, satp); + vm_info vm = decode_vm_info(proc->get_const_xlen(), false, mode, satp); if (vm.levels == 0) return s2xlate(addr, addr & ((reg_t(2) << (proc->xlen-1))-1), type, type, virt, hlvx) & ~page_mask; // zero-extend from xlen diff --git a/riscv/processor.h b/riscv/processor.h index 4697ca4..d7c8ee2 100644 --- a/riscv/processor.h +++ b/riscv/processor.h @@ -300,6 +300,12 @@ public: mmu_t* get_mmu() { return mmu; } state_t* get_state() { return &state; } unsigned get_xlen() { return xlen; } + unsigned get_const_xlen() { + // Any code that assumes a const xlen should use this method to + // document that assumption. If Spike ever changes to allow + // variable xlen, this method should be removed. + return xlen; + } unsigned get_max_xlen() { return max_xlen; } std::string get_isa_string() { return isa_string; } unsigned get_flen() { -- cgit v1.1