summaryrefslogtreecommitdiff
path: root/target/riscv/pmp.c
diff options
context:
space:
mode:
authorYifei Jiang <jiangyifei@huawei.com>2020-10-26 19:55:27 +0800
committerAlistair Francis <alistair.francis@wdc.com>2020-11-03 07:17:23 -0800
commit24beb03e46de8602b318d5f234ce0ba489a7dbfc (patch)
treeb1a80f07b811ad94bd25ecf49fda8159c6197cf5 /target/riscv/pmp.c
parentf7697f0e629eb75d411bc6f314c6fff68fa4c238 (diff)
downloadqemu-24beb03e46de8602b318d5f234ce0ba489a7dbfc.zip
target/riscv: Add PMP state description
In the case of supporting PMP feature, add PMP state description to vmstate_riscv_cpu. 'vmstate_pmp_addr' and 'num_rules' could be regenerated by pmp_update_rule(). But there exists the problem of updating num_rules repeatedly in pmp_update_rule(). So here extracts pmp_update_rule_addr() and pmp_update_rule_nums() to update 'vmstate_pmp_addr' and 'num_rules' respectively. Signed-off-by: Yifei Jiang <jiangyifei@huawei.com> Signed-off-by: Yipeng Yin <yinyipeng1@huawei.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-id: 20201026115530.304-4-jiangyifei@huawei.com Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Diffstat (limited to 'target/riscv/pmp.c')
-rw-r--r--target/riscv/pmp.c29
1 files changed, 18 insertions, 11 deletions
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index c394e867f8..2eda8e1e2f 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -136,18 +136,8 @@ static void pmp_decode_napot(target_ulong a, target_ulong *sa, target_ulong *ea)
}
}
-
-/* Convert cfg/addr reg values here into simple 'sa' --> start address and 'ea'
- * end address values.
- * This function is called relatively infrequently whereas the check that
- * an address is within a pmp rule is called often, so optimise that one
- */
-static void pmp_update_rule(CPURISCVState *env, uint32_t pmp_index)
+void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index)
{
- int i;
-
- env->pmp_state.num_rules = 0;
-
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 prev_addr = 0u;
@@ -186,7 +176,13 @@ static void pmp_update_rule(CPURISCVState *env, uint32_t pmp_index)
env->pmp_state.addr[pmp_index].sa = sa;
env->pmp_state.addr[pmp_index].ea = ea;
+}
+void pmp_update_rule_nums(CPURISCVState *env)
+{
+ int i;
+
+ env->pmp_state.num_rules = 0;
for (i = 0; i < MAX_RISCV_PMPS; i++) {
const uint8_t a_field =
pmp_get_a_field(env->pmp_state.pmp[i].cfg_reg);
@@ -196,6 +192,17 @@ static void pmp_update_rule(CPURISCVState *env, uint32_t pmp_index)
}
}
+/* Convert cfg/addr reg values here into simple 'sa' --> start address and 'ea'
+ * end address values.
+ * This function is called relatively infrequently whereas the check that
+ * an address is within a pmp rule is called often, so optimise that one
+ */
+static void pmp_update_rule(CPURISCVState *env, uint32_t pmp_index)
+{
+ pmp_update_rule_addr(env, pmp_index);
+ pmp_update_rule_nums(env);
+}
+
static int pmp_is_in_range(CPURISCVState *env, int pmp_index, target_ulong addr)
{
int result = 0;