Browse Source

Merge pull request #2175 from riscv-software-src/improve-mmu-impl

Clean up VA size handling
pull/2181/head
Andrew Waterman 5 months ago
committed by GitHub
parent
commit
6963ea936a
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 22
      riscv/csrs.cc
  2. 1
      riscv/decode_macros.h
  3. 2
      riscv/insns/sfence_inval_ir.h
  4. 2
      riscv/insns/sfence_vma.h
  5. 6
      riscv/isa_parser.h
  6. 41
      riscv/processor.cc
  7. 4
      riscv/processor.h
  8. 12
      riscv/sim.cc

22
riscv/csrs.cc

@ -431,7 +431,7 @@ reg_t cause_csr_t::read() const noexcept {
// implement class base_status_csr_t
base_status_csr_t::base_status_csr_t(processor_t* const proc, const reg_t addr):
csr_t(proc, addr),
has_page(proc->extension_enabled_const('S') && proc->supports_impl(IMPL_MMU)),
has_page(proc->extension_enabled_const('S') && proc->has_mmu()),
sstatus_write_mask(compute_sstatus_write_mask()),
sstatus_read_mask(sstatus_write_mask | SSTATUS_UBE | SSTATUS_UXL
| (proc->get_const_xlen() == 32 ? SSTATUS32_SD : SSTATUS64_SD)) {
@ -1005,7 +1005,7 @@ bool medeleg_csr_t::unlogged_write(const reg_t val) noexcept {
| (1 << CAUSE_STORE_ACCESS)
| (1 << CAUSE_USER_ECALL)
| (1 << CAUSE_SUPERVISOR_ECALL)
| (proc->supports_impl(IMPL_MMU) ? mmu_exceptions : 0)
| (proc->has_mmu() ? mmu_exceptions : 0)
| (proc->extension_enabled('H') ? hypervisor_exceptions : 0)
| (1 << CAUSE_SOFTWARE_CHECK_FAULT)
| (1 << CAUSE_HARDWARE_ERROR_FAULT)
@ -1088,7 +1088,7 @@ base_atp_csr_t::base_atp_csr_t(processor_t* const proc, const reg_t addr):
}
bool base_atp_csr_t::unlogged_write(const reg_t val) noexcept {
const reg_t newval = proc->supports_impl(IMPL_MMU) ? compute_new_satp(val) : 0;
const reg_t newval = proc->has_mmu() ? compute_new_satp(val) : 0;
if (newval != read())
proc->get_mmu()->flush_tlb();
return basic_csr_t::unlogged_write(newval);
@ -1097,16 +1097,16 @@ bool base_atp_csr_t::unlogged_write(const reg_t val) noexcept {
bool base_atp_csr_t::satp_valid(reg_t val) const noexcept {
if (proc->get_xlen() == 32) {
switch (get_field(val, SATP32_MODE)) {
case SATP_MODE_SV32: return proc->supports_impl(IMPL_MMU_SV32);
case SATP_MODE_OFF: return true;
case SATP_MODE_SV32: return proc->get_max_vaddr_bits() >= 32;
default: return false;
}
} else {
switch (get_field(val, SATP64_MODE)) {
case SATP_MODE_SV39: return proc->supports_impl(IMPL_MMU_SV39);
case SATP_MODE_SV48: return proc->supports_impl(IMPL_MMU_SV48);
case SATP_MODE_SV57: return proc->supports_impl(IMPL_MMU_SV57);
case SATP_MODE_OFF: return true;
case SATP_MODE_SV39: return proc->get_max_vaddr_bits() >= 39;
case SATP_MODE_SV48: return proc->get_max_vaddr_bits() >= 48;
case SATP_MODE_SV57: return proc->get_max_vaddr_bits() >= 57;
default: return false;
}
}
@ -1345,9 +1345,9 @@ bool hgatp_csr_t::unlogged_write(const reg_t val) noexcept {
(proc->supports_impl(IMPL_MMU_VMID) ? HGATP64_VMID : 0);
if (get_field(val, HGATP64_MODE) == HGATP_MODE_OFF ||
(proc->supports_impl(IMPL_MMU_SV39) && get_field(val, HGATP64_MODE) == HGATP_MODE_SV39X4) ||
(proc->supports_impl(IMPL_MMU_SV48) && get_field(val, HGATP64_MODE) == HGATP_MODE_SV48X4) ||
(proc->supports_impl(IMPL_MMU_SV57) && get_field(val, HGATP64_MODE) == HGATP_MODE_SV57X4))
(proc->get_max_vaddr_bits() >= 39 && get_field(val, HGATP64_MODE) == HGATP_MODE_SV39X4) ||
(proc->get_max_vaddr_bits() >= 48 && get_field(val, HGATP64_MODE) == HGATP_MODE_SV48X4) ||
(proc->get_max_vaddr_bits() >= 57 && get_field(val, HGATP64_MODE) == HGATP_MODE_SV57X4))
mask |= HGATP64_MODE;
}
mask &= ~(reg_t)3;
@ -2037,7 +2037,7 @@ hstatus_csr_t::hstatus_csr_t(processor_t* const proc, const reg_t addr):
bool hstatus_csr_t::unlogged_write(const reg_t val) noexcept {
const reg_t mask = (proc->extension_enabled(EXT_SVUKTE) ? HSTATUS_HUKTE : 0)
| HSTATUS_VTSR | HSTATUS_VTW
| (proc->supports_impl(IMPL_MMU) ? HSTATUS_VTVM : 0)
| (proc->has_mmu() ? HSTATUS_VTVM : 0)
| (proc->extension_enabled(EXT_SSNPM) ? HSTATUS_HUPMM : 0)
| HSTATUS_HU | HSTATUS_SPVP | HSTATUS_SPV | HSTATUS_GVA;

1
riscv/decode_macros.h

@ -163,7 +163,6 @@ static inline bool is_aligned(const unsigned val, const unsigned pos)
#define require_rv32 require(xlen == 32)
#define require_extension(s) require(p->extension_enabled(s))
#define require_either_extension(A,B) require(p->extension_enabled(A) || p->extension_enabled(B));
#define require_impl(s) require(p->supports_impl(s))
#define require_fp STATE.fflags->verify_permissions(insn, false)
#define require_accelerator require(STATE.sstatus->enabled(SSTATUS_XS))
#define require_vector_vs require(p->any_vector_extensions() && STATE.sstatus->enabled(SSTATUS_VS))

2
riscv/insns/sfence_inval_ir.h

@ -1,4 +1,4 @@
require_extension('S');
require_extension(EXT_SVINVAL);
require_impl(IMPL_MMU);
require(p->has_mmu());
require_privilege_hs_qualified(PRV_S);

2
riscv/insns/sfence_vma.h

@ -1,5 +1,5 @@
require_extension('S');
require_impl(IMPL_MMU);
require(p->has_mmu());
if (STATE.v) {
if (STATE.prv == PRV_U || get_field(STATE.hstatus->read(), HSTATUS_VTVM))
require_novirt();

6
riscv/isa_parser.h

@ -114,12 +114,6 @@ typedef enum {
} isa_extension_t;
typedef enum {
IMPL_MMU_SV32,
IMPL_MMU_SV39,
IMPL_MMU_SV48,
IMPL_MMU_SV57,
IMPL_MMU_SBARE,
IMPL_MMU,
IMPL_MMU_VMID,
IMPL_MMU_ASID,
} impl_extension_t;

41
riscv/processor.cc

@ -67,11 +67,7 @@ processor_t::processor_t(const char* isa_str, const char* priv_str,
set_pmp_granularity(cfg->pmpgranularity);
set_pmp_num(cfg->pmpregions);
if (isa.get_max_xlen() == 32)
set_mmu_capability(IMPL_MMU_SV32);
else if (isa.get_max_xlen() == 64)
set_mmu_capability(IMPL_MMU_SV57);
set_max_vaddr_bits(0);
set_impl(IMPL_MMU_ASID, true);
set_impl(IMPL_MMU_VMID, true);
@ -217,31 +213,26 @@ void processor_t::set_pmp_granularity(reg_t gran)
lg_pmp_granularity = ctz(gran);
}
void processor_t::set_mmu_capability(int cap)
void processor_t::set_max_vaddr_bits(unsigned n)
{
switch (cap) {
case IMPL_MMU_SV32:
set_impl(IMPL_MMU_SV32, true);
set_impl(IMPL_MMU, true);
switch (n) {
case 0:
break;
case IMPL_MMU_SV57:
set_impl(IMPL_MMU_SV57, true);
[[fallthrough]];
case IMPL_MMU_SV48:
set_impl(IMPL_MMU_SV48, true);
[[fallthrough]];
case IMPL_MMU_SV39:
set_impl(IMPL_MMU_SV39, true);
set_impl(IMPL_MMU, true);
case 32:
if (isa.get_max_xlen() != 32)
abort();
break;
default:
set_impl(IMPL_MMU_SV32, false);
set_impl(IMPL_MMU_SV39, false);
set_impl(IMPL_MMU_SV48, false);
set_impl(IMPL_MMU_SV57, false);
set_impl(IMPL_MMU, false);
case 39:
case 48:
case 57:
if (isa.get_max_xlen() != 64)
abort();
break;
default:
abort();
}
max_vaddr_bits = n;
}
reg_t processor_t::select_an_interrupt_with_default_priority(reg_t enabled_interrupts) const

4
riscv/processor.h

@ -290,6 +290,9 @@ public:
extension_enable_table[ext] = enable && isa.extension_enabled(ext);
}
void set_impl(uint8_t impl, bool val) { impl_table[impl] = val; }
bool has_mmu() const { return max_vaddr_bits != 0; }
unsigned get_max_vaddr_bits() const { return max_vaddr_bits; }
void set_max_vaddr_bits(unsigned);
bool supports_impl(uint8_t impl) const {
return impl_table[impl];
}
@ -358,6 +361,7 @@ private:
state_t state;
uint32_t id;
unsigned xlen;
unsigned max_vaddr_bits;
bool histogram_enabled;
bool log_commits_enabled;
FILE *log_file;

12
riscv/sim.cc

@ -214,16 +214,16 @@ sim_t::sim_t(const cfg_t *cfg, bool halted,
// handle mmu-type
const char *mmu_type;
rc = fdt_parse_mmu_type(fdt, cpu_offset, &mmu_type);
procs[cpu_idx]->set_max_vaddr_bits(0);
if (rc == 0) {
procs[cpu_idx]->set_mmu_capability(IMPL_MMU_SBARE);
if (strncmp(mmu_type, "riscv,sv32", strlen("riscv,sv32")) == 0) {
procs[cpu_idx]->set_mmu_capability(IMPL_MMU_SV32);
procs[cpu_idx]->set_max_vaddr_bits(32);
} else if (strncmp(mmu_type, "riscv,sv39", strlen("riscv,sv39")) == 0) {
procs[cpu_idx]->set_mmu_capability(IMPL_MMU_SV39);
procs[cpu_idx]->set_max_vaddr_bits(39);
} else if (strncmp(mmu_type, "riscv,sv48", strlen("riscv,sv48")) == 0) {
procs[cpu_idx]->set_mmu_capability(IMPL_MMU_SV48);
procs[cpu_idx]->set_max_vaddr_bits(48);
} else if (strncmp(mmu_type, "riscv,sv57", strlen("riscv,sv57")) == 0) {
procs[cpu_idx]->set_mmu_capability(IMPL_MMU_SV57);
procs[cpu_idx]->set_max_vaddr_bits(57);
} else if (strncmp(mmu_type, "riscv,sbare", strlen("riscv,sbare")) == 0) {
// has been set in the beginning
} else {
@ -233,8 +233,6 @@ sim_t::sim_t(const cfg_t *cfg, bool halted,
<< mmu_type << ").\n";
exit(1);
}
} else {
procs[cpu_idx]->set_mmu_capability(IMPL_MMU_SBARE);
}
procs[cpu_idx]->reset();

Loading…
Cancel
Save