moves mmu related code into mmu unit

This commit is contained in:
2025-03-15 09:34:19 +01:00
parent e238369e18
commit 54233b448d
19 changed files with 683 additions and 598 deletions

View File

@@ -37,7 +37,6 @@
#include "iss/arch/traits.h"
#include "iss/log_categories.h"
#include "iss/mmio/memory_if.h"
#include "iss/vm_types.h"
#include "mstatus.h"
#include "util/delegate.h"
@@ -54,6 +53,7 @@
#include <unordered_map>
#include <util/logging.h>
#include <util/sparse_array.h>
#include "../mem/memory_if.h"
#if defined(__GNUC__)
#define likely(x) ::__builtin_expect(!!(x), 1)
@@ -198,23 +198,6 @@ enum riscv_csr {
dscratch1 = 0x7B3
};
enum {
PGSHIFT = 12,
PTE_PPN_SHIFT = 10,
// page table entry (PTE) fields
PTE_V = 0x001, // Valid
PTE_R = 0x002, // Read
PTE_W = 0x004, // Write
PTE_X = 0x008, // Execute
PTE_U = 0x010, // User
PTE_G = 0x020, // Global
PTE_A = 0x040, // Accessed
PTE_D = 0x080, // Dirty
PTE_SOFT = 0x300 // Reserved for Software
};
template <typename T> inline bool PTE_TABLE(T PTE) { return (((PTE) & (PTE_V | PTE_R | PTE_W | PTE_X)) == PTE_V); }
enum { PRIV_U = 0, PRIV_S = 1, PRIV_M = 3, PRIV_D = 4 };
enum {
@@ -233,21 +216,6 @@ enum {
ISA_U = 1 << 20
};
struct vm_info {
int levels;
int idxbits;
int ptesize;
uint64_t ptbase;
bool is_active() { return levels; }
};
struct feature_config {
uint64_t tcm_base{0x10000000};
uint64_t tcm_size{0x8000};
uint64_t io_address{0xf0000000};
uint64_t io_addr_mask{0xf0000000};
};
class trap_load_access_fault : public trap_access {
public:
trap_load_access_fault(uint64_t badaddr)
@@ -281,15 +249,18 @@ template <typename WORD_TYPE> struct priv_if {
std::function<iss::status(unsigned, WORD_TYPE&)> read_csr;
std::function<iss::status(unsigned, WORD_TYPE)> write_csr;
std::function<iss::status(uint8_t const*)> exec_htif;
std::function<void(uint16_t,uint16_t,WORD_TYPE)> raise_trap; // trap_id, cause, fault_data
std::unordered_map<unsigned, rd_csr_f>& csr_rd_cb;
std::unordered_map<unsigned, wr_csr_f>& csr_wr_cb;
hart_state<WORD_TYPE>& mstatus;
hart_state<WORD_TYPE>& state;
uint8_t& PRIV;
WORD_TYPE& PC;
uint64_t& tohost;
uint64_t& fromhost;
unsigned& mcause_max_irq;
unsigned& max_irq;
};
template <typename BASE, typename LOGCAT = logging::disass> struct riscv_hart_common : public BASE, public mmio::memory_elem {
template <typename BASE, typename LOGCAT = logging::disass> struct riscv_hart_common : public BASE, public mem::memory_elem {
const std::array<const char, 4> lvl = {{'U', 'S', 'H', 'M'}};
const std::array<const char*, 16> trap_str = {{""
"Instruction address misaligned", // 0
@@ -718,12 +689,19 @@ template <typename BASE, typename LOGCAT = logging::disass> struct riscv_hart_co
return priv_if<reg_t>{.read_csr = [this](unsigned addr, reg_t& val) -> iss::status { return read_csr(addr, val); },
.write_csr = [this](unsigned addr, reg_t val) -> iss::status { return write_csr(addr, val); },
.exec_htif = [this](uint8_t const* data) -> iss::status { return execute_htif(data); },
.raise_trap = [this](uint16_t trap_id, uint16_t cause, reg_t fault_data){
this->reg.trap_state = 0x80ULL << 24 | (cause << 16) | trap_id;
this->fault_data = fault_data;
},
.csr_rd_cb{this->csr_rd_cb},
.csr_wr_cb{csr_wr_cb},
.mstatus{this->state},
.state{this->state},
.PRIV{this->reg.PRIV},
.PC{this->reg.PC},
.tohost{this->tohost},
.fromhost{this->fromhost},
.mcause_max_irq{mcause_max_irq}};
.max_irq{mcause_max_irq}};
}
iss::status execute_htif(uint8_t const* data) {
@@ -763,14 +741,14 @@ template <typename BASE, typename LOGCAT = logging::disass> struct riscv_hart_co
}
}
mmio::memory_hierarchy memories;
mem::memory_hierarchy memories;
virtual mmio::memory_if get_mem_if() override {
virtual mem::memory_if get_mem_if() override {
assert(false || "This function should nevver be called");
return mmio::memory_if{};
return mem::memory_if{};
}
virtual void set_next(mmio::memory_if mem_if) { memory = mem_if; };
virtual void set_next(mem::memory_if mem_if) { memory = mem_if; };
void set_irq_num(unsigned i) { mcause_max_irq = 1 << util::ilog2(i); }
@@ -789,7 +767,7 @@ protected:
}
}
mmio::memory_if memory;
mem::memory_if memory;
struct riscv_instrumentation_if : public iss::instrumentation_if {
riscv_instrumentation_if(riscv_hart_common<BASE, LOGCAT>& arch)
@@ -846,7 +824,6 @@ protected:
int64_t cycle_offset{0};
int64_t instret_offset{0};
semihosting_cb_t<reg_t> semihosting_cb;
std::array<vm_info, 2> vm;
unsigned mcause_max_irq{16U};
};