diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2020-11-10 09:24:56 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2020-11-10 09:24:56 +0000 |
commit | f7e1914adad8885a5d4c70239ab90d901ed97e9f (patch) | |
tree | e117402b27c20ce664ca2ee01023d271d272c438 /target/riscv/op_helper.c | |
parent | 43afbbd9fea1b255cc81f5f4bfd0b6a88826c735 (diff) | |
parent | 96338fefc19a143abdc91f6c44f37683274b08d4 (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.c | 124 |
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 */ |