target/riscv/pmp: Use hwaddr instead of target_ulong for RV32

The Sv32 page-based virtual-memory scheme described in RISCV privileged
spec Section 5.3 supports 34-bit physical addresses for RV32, so the
PMP scheme must support addresses wider than XLEN for RV32. However,
PMP address register format is still 32 bit wide.

Signed-off-by: Ivan Klokov <ivan.klokov@syntacore.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20231123091214.20312-1-ivan.klokov@syntacore.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
Ivan Klokov 2023-11-23 12:12:14 +03:00 committed by Alistair Francis
parent 7767f8b122
commit 6f5bb7d405
2 changed files with 16 additions and 18 deletions

View File

@ -150,8 +150,7 @@ void pmp_unlock_entries(CPURISCVState *env)
} }
} }
static void pmp_decode_napot(target_ulong a, target_ulong *sa, static void pmp_decode_napot(hwaddr a, hwaddr *sa, hwaddr *ea)
target_ulong *ea)
{ {
/* /*
* aaaa...aaa0 8-byte NAPOT range * aaaa...aaa0 8-byte NAPOT range
@ -173,8 +172,8 @@ void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index)
uint8_t this_cfg = env->pmp_state.pmp[pmp_index].cfg_reg; uint8_t this_cfg = env->pmp_state.pmp[pmp_index].cfg_reg;
target_ulong this_addr = env->pmp_state.pmp[pmp_index].addr_reg; target_ulong this_addr = env->pmp_state.pmp[pmp_index].addr_reg;
target_ulong prev_addr = 0u; target_ulong prev_addr = 0u;
target_ulong sa = 0u; hwaddr sa = 0u;
target_ulong ea = 0u; hwaddr ea = 0u;
if (pmp_index >= 1u) { if (pmp_index >= 1u) {
prev_addr = env->pmp_state.pmp[pmp_index - 1].addr_reg; prev_addr = env->pmp_state.pmp[pmp_index - 1].addr_reg;
@ -227,8 +226,7 @@ void pmp_update_rule_nums(CPURISCVState *env)
} }
} }
static int pmp_is_in_range(CPURISCVState *env, int pmp_index, static int pmp_is_in_range(CPURISCVState *env, int pmp_index, hwaddr addr)
target_ulong addr)
{ {
int result = 0; int result = 0;
@ -305,14 +303,14 @@ static bool pmp_hart_has_privs_default(CPURISCVState *env, pmp_priv_t privs,
* Return true if a pmp rule match or default match * Return true if a pmp rule match or default match
* Return false if no match * Return false if no match
*/ */
bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr, bool pmp_hart_has_privs(CPURISCVState *env, hwaddr addr,
target_ulong size, pmp_priv_t privs, target_ulong size, pmp_priv_t privs,
pmp_priv_t *allowed_privs, target_ulong mode) pmp_priv_t *allowed_privs, target_ulong mode)
{ {
int i = 0; int i = 0;
int pmp_size = 0; int pmp_size = 0;
target_ulong s = 0; hwaddr s = 0;
target_ulong e = 0; hwaddr e = 0;
/* Short cut if no rules */ /* Short cut if no rules */
if (0 == pmp_get_num_rules(env)) { if (0 == pmp_get_num_rules(env)) {
@ -624,12 +622,12 @@ target_ulong mseccfg_csr_read(CPURISCVState *env)
* To avoid this we return a size of 1 (which means no caching) if the PMP * To avoid this we return a size of 1 (which means no caching) if the PMP
* region only covers partial of the TLB page. * region only covers partial of the TLB page.
*/ */
target_ulong pmp_get_tlb_size(CPURISCVState *env, target_ulong addr) target_ulong pmp_get_tlb_size(CPURISCVState *env, hwaddr addr)
{ {
target_ulong pmp_sa; hwaddr pmp_sa;
target_ulong pmp_ea; hwaddr pmp_ea;
target_ulong tlb_sa = addr & ~(TARGET_PAGE_SIZE - 1); hwaddr tlb_sa = addr & ~(TARGET_PAGE_SIZE - 1);
target_ulong tlb_ea = tlb_sa + TARGET_PAGE_SIZE - 1; hwaddr tlb_ea = tlb_sa + TARGET_PAGE_SIZE - 1;
int i; int i;
/* /*

View File

@ -53,8 +53,8 @@ typedef struct {
} pmp_entry_t; } pmp_entry_t;
typedef struct { typedef struct {
target_ulong sa; hwaddr sa;
target_ulong ea; hwaddr ea;
} pmp_addr_t; } pmp_addr_t;
typedef struct { typedef struct {
@ -73,11 +73,11 @@ target_ulong mseccfg_csr_read(CPURISCVState *env);
void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index, void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index,
target_ulong val); target_ulong val);
target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index); target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index);
bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr, bool pmp_hart_has_privs(CPURISCVState *env, hwaddr addr,
target_ulong size, pmp_priv_t privs, target_ulong size, pmp_priv_t privs,
pmp_priv_t *allowed_privs, pmp_priv_t *allowed_privs,
target_ulong mode); target_ulong mode);
target_ulong pmp_get_tlb_size(CPURISCVState *env, target_ulong addr); target_ulong pmp_get_tlb_size(CPURISCVState *env, hwaddr addr);
void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index); void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index);
void pmp_update_rule_nums(CPURISCVState *env); void pmp_update_rule_nums(CPURISCVState *env);
uint32_t pmp_get_num_rules(CPURISCVState *env); uint32_t pmp_get_num_rules(CPURISCVState *env);