aboutsummaryrefslogtreecommitdiff
path: root/target/riscv/op_helper.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2020-11-10 09:24:56 +0000
committerPeter Maydell <peter.maydell@linaro.org>2020-11-10 09:24:56 +0000
commitf7e1914adad8885a5d4c70239ab90d901ed97e9f (patch)
treee117402b27c20ce664ca2ee01023d271d272c438 /target/riscv/op_helper.c
parent43afbbd9fea1b255cc81f5f4bfd0b6a88826c735 (diff)
parent96338fefc19a143abdc91f6c44f37683274b08d4 (diff)
Merge remote-tracking branch 'remotes/alistair/tags/pull-riscv-to-apply-20201109' into staging
This fixes two bugs in the RISC-V port. One is a bug in the Ibex PLIC, the other fixes the Hypvervisor access functions. # gpg: Signature made Tue 10 Nov 2020 03:53:49 GMT # gpg: using RSA key F6C4AC46D4934868D3B8CE8F21E10D29DF977054 # gpg: Good signature from "Alistair Francis <alistair@alistair23.me>" [full] # Primary key fingerprint: F6C4 AC46 D493 4868 D3B8 CE8F 21E1 0D29 DF97 7054 * remotes/alistair/tags/pull-riscv-to-apply-20201109: hw/intc/ibex_plic: Clear the claim register when read target/riscv: Split the Hypervisor execute load helpers target/riscv: Remove the hyp load and store functions target/riscv: Remove the HS_TWO_STAGE flag target/riscv: Set the virtualised MMU mode when doing hyp accesses target/riscv: Add a virtualised MMU Mode Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target/riscv/op_helper.c')
-rw-r--r--target/riscv/op_helper.c124
1 files changed, 6 insertions, 118 deletions
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index e20d56dcb8..d55def76cf 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -227,130 +227,18 @@ void helper_hyp_gvma_tlb_flush(CPURISCVState *env)
helper_hyp_tlb_flush(env);
}
-target_ulong helper_hyp_load(CPURISCVState *env, target_ulong address,
- target_ulong attrs, target_ulong memop)
+target_ulong helper_hyp_hlvx_hu(CPURISCVState *env, target_ulong address)
{
- if (env->priv == PRV_M ||
- (env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) ||
- (env->priv == PRV_U && !riscv_cpu_virt_enabled(env) &&
- get_field(env->hstatus, HSTATUS_HU))) {
- target_ulong pte;
-
- riscv_cpu_set_two_stage_lookup(env, true);
-
- switch (memop) {
- case MO_SB:
- pte = cpu_ldsb_data_ra(env, address, GETPC());
- break;
- case MO_UB:
- pte = cpu_ldub_data_ra(env, address, GETPC());
- break;
- case MO_TESW:
- pte = cpu_ldsw_data_ra(env, address, GETPC());
- break;
- case MO_TEUW:
- pte = cpu_lduw_data_ra(env, address, GETPC());
- break;
- case MO_TESL:
- pte = cpu_ldl_data_ra(env, address, GETPC());
- break;
- case MO_TEUL:
- pte = cpu_ldl_data_ra(env, address, GETPC());
- break;
- case MO_TEQ:
- pte = cpu_ldq_data_ra(env, address, GETPC());
- break;
- default:
- g_assert_not_reached();
- }
-
- riscv_cpu_set_two_stage_lookup(env, false);
-
- return pte;
- }
-
- if (riscv_cpu_virt_enabled(env)) {
- riscv_raise_exception(env, RISCV_EXCP_VIRT_INSTRUCTION_FAULT, GETPC());
- } else {
- riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
- }
- return 0;
-}
-
-void helper_hyp_store(CPURISCVState *env, target_ulong address,
- target_ulong val, target_ulong attrs, target_ulong memop)
-{
- if (env->priv == PRV_M ||
- (env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) ||
- (env->priv == PRV_U && !riscv_cpu_virt_enabled(env) &&
- get_field(env->hstatus, HSTATUS_HU))) {
- riscv_cpu_set_two_stage_lookup(env, true);
-
- switch (memop) {
- case MO_SB:
- case MO_UB:
- cpu_stb_data_ra(env, address, val, GETPC());
- break;
- case MO_TESW:
- case MO_TEUW:
- cpu_stw_data_ra(env, address, val, GETPC());
- break;
- case MO_TESL:
- case MO_TEUL:
- cpu_stl_data_ra(env, address, val, GETPC());
- break;
- case MO_TEQ:
- cpu_stq_data_ra(env, address, val, GETPC());
- break;
- default:
- g_assert_not_reached();
- }
-
- riscv_cpu_set_two_stage_lookup(env, false);
+ int mmu_idx = cpu_mmu_index(env, true) | TB_FLAGS_PRIV_HYP_ACCESS_MASK;
- return;
- }
-
- if (riscv_cpu_virt_enabled(env)) {
- riscv_raise_exception(env, RISCV_EXCP_VIRT_INSTRUCTION_FAULT, GETPC());
- } else {
- riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
- }
+ return cpu_lduw_mmuidx_ra(env, address, mmu_idx, GETPC());
}
-target_ulong helper_hyp_x_load(CPURISCVState *env, target_ulong address,
- target_ulong attrs, target_ulong memop)
+target_ulong helper_hyp_hlvx_wu(CPURISCVState *env, target_ulong address)
{
- if (env->priv == PRV_M ||
- (env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) ||
- (env->priv == PRV_U && !riscv_cpu_virt_enabled(env) &&
- get_field(env->hstatus, HSTATUS_HU))) {
- target_ulong pte;
-
- riscv_cpu_set_two_stage_lookup(env, true);
-
- switch (memop) {
- case MO_TEUW:
- pte = cpu_lduw_data_ra(env, address, GETPC());
- break;
- case MO_TEUL:
- pte = cpu_ldl_data_ra(env, address, GETPC());
- break;
- default:
- g_assert_not_reached();
- }
-
- riscv_cpu_set_two_stage_lookup(env, false);
-
- return pte;
- }
+ int mmu_idx = cpu_mmu_index(env, true) | TB_FLAGS_PRIV_HYP_ACCESS_MASK;
- if (riscv_cpu_virt_enabled(env)) {
- riscv_raise_exception(env, RISCV_EXCP_VIRT_INSTRUCTION_FAULT, GETPC());
- } else {
- riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
- }
- return 0;
+ return cpu_ldl_mmuidx_ra(env, address, mmu_idx, GETPC());
}
#endif /* !CONFIG_USER_ONLY */