From 1e0fab92b1d6f350fc1f4f0093f5976588bd3afa Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Sat, 9 May 2020 23:58:09 -0700 Subject: Support consuming PMP number and granularity from DTB The feature itself isn't implemented yet. --- riscv/processor.cc | 22 ++++++++++++++++++++++ riscv/processor.h | 6 ++++++ riscv/sim.cc | 9 +++++++++ 3 files changed, 37 insertions(+) diff --git a/riscv/processor.cc b/riscv/processor.cc index b3e668a..9caee5c 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -43,6 +43,8 @@ processor_t::processor_t(const char* isa, const char* priv, const char* varch, for (auto disasm_insn : ext->get_disasms()) disassembler->add_insn(disasm_insn); + set_pmp_granularity(1 << PMP_SHIFT); + set_pmp_num(state.max_pmp); reset(); } @@ -488,6 +490,26 @@ static int ctz(reg_t val) return res; } +void processor_t::set_pmp_num(reg_t n) +{ + // check the number of pmp is in a reasonable range + if (n > state.max_pmp) { + fprintf(stderr, "error: bad number of pmp regions: '%ld' from the dtb\n", (unsigned long)n); + abort(); + } + n_pmp = n; +} + +void processor_t::set_pmp_granularity(reg_t gran) { + // check the pmp granularity is set from dtb(!=0) and is power of 2 + if (gran < (1 << PMP_SHIFT) || (gran & (gran - 1)) != 0) { + fprintf(stderr, "error: bad pmp granularity '%ld' from the dtb\n", (unsigned long)gran); + abort(); + } + + lg_pmp_granularity = ctz(gran); +} + void processor_t::take_interrupt(reg_t pending_interrupts) { reg_t mie = get_field(state.mstatus, MSTATUS_MIE); diff --git a/riscv/processor.h b/riscv/processor.h index 82416f7..52dbf3e 100644 --- a/riscv/processor.h +++ b/riscv/processor.h @@ -389,6 +389,9 @@ public: void trigger_updated(); + void set_pmp_num(reg_t pmp_num); + void set_pmp_granularity(reg_t pmp_granularity); + private: simif_t* sim; mmu_t* mmu; // main memory is always accessed via the mmu @@ -434,6 +437,9 @@ private: // Track repeated executions for processor_t::disasm() uint64_t last_pc, last_bits, executions; + reg_t n_pmp; + reg_t lg_pmp_granularity; + public: class vectorUnit_t { public: diff --git a/riscv/sim.cc b/riscv/sim.cc index 18df394..b25d79e 100644 --- a/riscv/sim.cc +++ b/riscv/sim.cc @@ -89,6 +89,15 @@ sim_t::sim_t(const char* isa, const char* priv, const char* varch, } else { bus.add_device(clint_base, clint.get()); } + + for (size_t i = 0; i < nprocs; i++) { + reg_t pmp_num = 0, pmp_granularity = 0; + fdt_parse_pmp_num((void *)dtb.c_str(), &pmp_num, "riscv"); + fdt_parse_pmp_alignment((void *)dtb.c_str(), &pmp_granularity, "riscv"); + + procs[i]->set_pmp_num(pmp_num); + procs[i]->set_pmp_granularity(pmp_granularity); + } } sim_t::~sim_t() -- cgit v1.1