• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Commit MetaInfo

Revisionf77784446045231f7dfa46c9b872091241fa1557 (tree)
Time2018-12-13 23:41:24
AuthorRichard Henderson <richard.henderson@lina...>
CommiterPeter Maydell

Log Message

target/arm: Introduce arm_hcr_el2_eff

Replace arm_hcr_el2_{fmo,imo,amo} with a more general routine
that also takes SCR_EL3.NS (aka arm_is_secure_below_el3) into
account, as documented for the plethora of bits in HCR_EL2.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20181210150501.7990-2-richard.henderson@linaro.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Change Summary

Incremental Difference

--- a/hw/intc/arm_gicv3_cpuif.c
+++ b/hw/intc/arm_gicv3_cpuif.c
@@ -85,8 +85,8 @@ static bool icv_access(CPUARMState *env, int hcr_flags)
8585 * * access if NS EL1 and either IMO or FMO == 1:
8686 * CTLR, DIR, PMR, RPR
8787 */
88- bool flagmatch = ((hcr_flags & HCR_IMO) && arm_hcr_el2_imo(env)) ||
89- ((hcr_flags & HCR_FMO) && arm_hcr_el2_fmo(env));
88+ uint64_t hcr_el2 = arm_hcr_el2_eff(env);
89+ bool flagmatch = hcr_el2 & hcr_flags & (HCR_IMO | HCR_FMO);
9090
9191 return flagmatch && arm_current_el(env) == 1
9292 && !arm_is_secure_below_el3(env);
@@ -1552,8 +1552,9 @@ static void icc_dir_write(CPUARMState *env, const ARMCPRegInfo *ri,
15521552 /* No need to include !IsSecure in route_*_to_el2 as it's only
15531553 * tested in cases where we know !IsSecure is true.
15541554 */
1555- route_fiq_to_el2 = arm_hcr_el2_fmo(env);
1556- route_irq_to_el2 = arm_hcr_el2_imo(env);
1555+ uint64_t hcr_el2 = arm_hcr_el2_eff(env);
1556+ route_fiq_to_el2 = hcr_el2 & HCR_FMO;
1557+ route_irq_to_el2 = hcr_el2 & HCR_IMO;
15571558
15581559 switch (arm_current_el(env)) {
15591560 case 3:
@@ -1895,8 +1896,8 @@ static CPAccessResult gicv3_irqfiq_access(CPUARMState *env,
18951896 if ((env->cp15.scr_el3 & (SCR_FIQ | SCR_IRQ)) == (SCR_FIQ | SCR_IRQ)) {
18961897 switch (el) {
18971898 case 1:
1898- if (arm_is_secure_below_el3(env) ||
1899- (arm_hcr_el2_imo(env) == 0 && arm_hcr_el2_fmo(env) == 0)) {
1899+ /* Note that arm_hcr_el2_eff takes secure state into account. */
1900+ if ((arm_hcr_el2_eff(env) & (HCR_IMO | HCR_FMO)) == 0) {
19001901 r = CP_ACCESS_TRAP_EL3;
19011902 }
19021903 break;
@@ -1936,8 +1937,8 @@ static CPAccessResult gicv3_dir_access(CPUARMState *env,
19361937 static CPAccessResult gicv3_sgi_access(CPUARMState *env,
19371938 const ARMCPRegInfo *ri, bool isread)
19381939 {
1939- if ((arm_hcr_el2_imo(env) || arm_hcr_el2_fmo(env)) &&
1940- arm_current_el(env) == 1 && !arm_is_secure_below_el3(env)) {
1940+ if (arm_current_el(env) == 1 &&
1941+ (arm_hcr_el2_eff(env) & (HCR_IMO | HCR_FMO)) != 0) {
19411942 /* Takes priority over a possible EL3 trap */
19421943 return CP_ACCESS_TRAP_EL2;
19431944 }
@@ -1961,7 +1962,7 @@ static CPAccessResult gicv3_fiq_access(CPUARMState *env,
19611962 if (env->cp15.scr_el3 & SCR_FIQ) {
19621963 switch (el) {
19631964 case 1:
1964- if (arm_is_secure_below_el3(env) || !arm_hcr_el2_fmo(env)) {
1965+ if ((arm_hcr_el2_eff(env) & HCR_FMO) == 0) {
19651966 r = CP_ACCESS_TRAP_EL3;
19661967 }
19671968 break;
@@ -2000,7 +2001,7 @@ static CPAccessResult gicv3_irq_access(CPUARMState *env,
20002001 if (env->cp15.scr_el3 & SCR_IRQ) {
20012002 switch (el) {
20022003 case 1:
2003- if (arm_is_secure_below_el3(env) || !arm_hcr_el2_imo(env)) {
2004+ if ((arm_hcr_el2_eff(env) & HCR_IMO) == 0) {
20042005 r = CP_ACCESS_TRAP_EL3;
20052006 }
20062007 break;
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1729,6 +1729,14 @@ static inline bool arm_is_secure(CPUARMState *env)
17291729 }
17301730 #endif
17311731
1732+/**
1733+ * arm_hcr_el2_eff(): Return the effective value of HCR_EL2.
1734+ * E.g. when in secure state, fields in HCR_EL2 are suppressed,
1735+ * "for all purposes other than a direct read or write access of HCR_EL2."
1736+ * Not included here is HCR_RW.
1737+ */
1738+uint64_t arm_hcr_el2_eff(CPUARMState *env);
1739+
17321740 /* Return true if the specified exception level is running in AArch64 state. */
17331741 static inline bool arm_el_is_aa64(CPUARMState *env, int el)
17341742 {
@@ -2414,54 +2422,6 @@ bool write_cpustate_to_list(ARMCPU *cpu);
24142422 # define TARGET_VIRT_ADDR_SPACE_BITS 32
24152423 #endif
24162424
2417-/**
2418- * arm_hcr_el2_imo(): Return the effective value of HCR_EL2.IMO.
2419- * Depending on the values of HCR_EL2.E2H and TGE, this may be
2420- * "behaves as 1 for all purposes other than direct read/write" or
2421- * "behaves as 0 for all purposes other than direct read/write"
2422- */
2423-static inline bool arm_hcr_el2_imo(CPUARMState *env)
2424-{
2425- switch (env->cp15.hcr_el2 & (HCR_TGE | HCR_E2H)) {
2426- case HCR_TGE:
2427- return true;
2428- case HCR_TGE | HCR_E2H:
2429- return false;
2430- default:
2431- return env->cp15.hcr_el2 & HCR_IMO;
2432- }
2433-}
2434-
2435-/**
2436- * arm_hcr_el2_fmo(): Return the effective value of HCR_EL2.FMO.
2437- */
2438-static inline bool arm_hcr_el2_fmo(CPUARMState *env)
2439-{
2440- switch (env->cp15.hcr_el2 & (HCR_TGE | HCR_E2H)) {
2441- case HCR_TGE:
2442- return true;
2443- case HCR_TGE | HCR_E2H:
2444- return false;
2445- default:
2446- return env->cp15.hcr_el2 & HCR_FMO;
2447- }
2448-}
2449-
2450-/**
2451- * arm_hcr_el2_amo(): Return the effective value of HCR_EL2.AMO.
2452- */
2453-static inline bool arm_hcr_el2_amo(CPUARMState *env)
2454-{
2455- switch (env->cp15.hcr_el2 & (HCR_TGE | HCR_E2H)) {
2456- case HCR_TGE:
2457- return true;
2458- case HCR_TGE | HCR_E2H:
2459- return false;
2460- default:
2461- return env->cp15.hcr_el2 & HCR_AMO;
2462- }
2463-}
2464-
24652425 static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
24662426 unsigned int target_el)
24672427 {
@@ -2470,6 +2430,7 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
24702430 bool secure = arm_is_secure(env);
24712431 bool pstate_unmasked;
24722432 int8_t unmasked = 0;
2433+ uint64_t hcr_el2;
24732434
24742435 /* Don't take exceptions if they target a lower EL.
24752436 * This check should catch any exceptions that would not be taken but left
@@ -2479,6 +2440,8 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
24792440 return false;
24802441 }
24812442
2443+ hcr_el2 = arm_hcr_el2_eff(env);
2444+
24822445 switch (excp_idx) {
24832446 case EXCP_FIQ:
24842447 pstate_unmasked = !(env->daif & PSTATE_F);
@@ -2489,13 +2452,13 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
24892452 break;
24902453
24912454 case EXCP_VFIQ:
2492- if (secure || !arm_hcr_el2_fmo(env) || (env->cp15.hcr_el2 & HCR_TGE)) {
2455+ if (secure || !(hcr_el2 & HCR_FMO) || (hcr_el2 & HCR_TGE)) {
24932456 /* VFIQs are only taken when hypervized and non-secure. */
24942457 return false;
24952458 }
24962459 return !(env->daif & PSTATE_F);
24972460 case EXCP_VIRQ:
2498- if (secure || !arm_hcr_el2_imo(env) || (env->cp15.hcr_el2 & HCR_TGE)) {
2461+ if (secure || !(hcr_el2 & HCR_IMO) || (hcr_el2 & HCR_TGE)) {
24992462 /* VIRQs are only taken when hypervized and non-secure. */
25002463 return false;
25012464 }
@@ -2534,7 +2497,7 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
25342497 * to the CPSR.F setting otherwise we further assess the state
25352498 * below.
25362499 */
2537- hcr = arm_hcr_el2_fmo(env);
2500+ hcr = hcr_el2 & HCR_FMO;
25382501 scr = (env->cp15.scr_el3 & SCR_FIQ);
25392502
25402503 /* When EL3 is 32-bit, the SCR.FW bit controls whether the
@@ -2551,7 +2514,7 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
25512514 * when setting the target EL, so it does not have a further
25522515 * affect here.
25532516 */
2554- hcr = arm_hcr_el2_imo(env);
2517+ hcr = hcr_el2 & HCR_IMO;
25552518 scr = false;
25562519 break;
25572520 default:
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -1331,9 +1331,10 @@ static void csselr_write(CPUARMState *env, const ARMCPRegInfo *ri,
13311331 static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri)
13321332 {
13331333 CPUState *cs = ENV_GET_CPU(env);
1334+ uint64_t hcr_el2 = arm_hcr_el2_eff(env);
13341335 uint64_t ret = 0;
13351336
1336- if (arm_hcr_el2_imo(env)) {
1337+ if (hcr_el2 & HCR_IMO) {
13371338 if (cs->interrupt_request & CPU_INTERRUPT_VIRQ) {
13381339 ret |= CPSR_I;
13391340 }
@@ -1343,7 +1344,7 @@ static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri)
13431344 }
13441345 }
13451346
1346- if (arm_hcr_el2_fmo(env)) {
1347+ if (hcr_el2 & HCR_FMO) {
13471348 if (cs->interrupt_request & CPU_INTERRUPT_VFIQ) {
13481349 ret |= CPSR_F;
13491350 }
@@ -4008,6 +4009,51 @@ static void hcr_writelow(CPUARMState *env, const ARMCPRegInfo *ri,
40084009 hcr_write(env, NULL, value);
40094010 }
40104011
4012+/*
4013+ * Return the effective value of HCR_EL2.
4014+ * Bits that are not included here:
4015+ * RW (read from SCR_EL3.RW as needed)
4016+ */
4017+uint64_t arm_hcr_el2_eff(CPUARMState *env)
4018+{
4019+ uint64_t ret = env->cp15.hcr_el2;
4020+
4021+ if (arm_is_secure_below_el3(env)) {
4022+ /*
4023+ * "This register has no effect if EL2 is not enabled in the
4024+ * current Security state". This is ARMv8.4-SecEL2 speak for
4025+ * !(SCR_EL3.NS==1 || SCR_EL3.EEL2==1).
4026+ *
4027+ * Prior to that, the language was "In an implementation that
4028+ * includes EL3, when the value of SCR_EL3.NS is 0 the PE behaves
4029+ * as if this field is 0 for all purposes other than a direct
4030+ * read or write access of HCR_EL2". With lots of enumeration
4031+ * on a per-field basis. In current QEMU, this is condition
4032+ * is arm_is_secure_below_el3.
4033+ *
4034+ * Since the v8.4 language applies to the entire register, and
4035+ * appears to be backward compatible, use that.
4036+ */
4037+ ret = 0;
4038+ } else if (ret & HCR_TGE) {
4039+ /* These bits are up-to-date as of ARMv8.4. */
4040+ if (ret & HCR_E2H) {
4041+ ret &= ~(HCR_VM | HCR_FMO | HCR_IMO | HCR_AMO |
4042+ HCR_BSU_MASK | HCR_DC | HCR_TWI | HCR_TWE |
4043+ HCR_TID0 | HCR_TID2 | HCR_TPCP | HCR_TPU |
4044+ HCR_TDZ | HCR_CD | HCR_ID | HCR_MIOCNCE);
4045+ } else {
4046+ ret |= HCR_FMO | HCR_IMO | HCR_AMO;
4047+ }
4048+ ret &= ~(HCR_SWIO | HCR_PTW | HCR_VF | HCR_VI | HCR_VSE |
4049+ HCR_FB | HCR_TID1 | HCR_TID3 | HCR_TSC | HCR_TACR |
4050+ HCR_TSW | HCR_TTLB | HCR_TVM | HCR_HCD | HCR_TRVM |
4051+ HCR_TLOR);
4052+ }
4053+
4054+ return ret;
4055+}
4056+
40114057 static const ARMCPRegInfo el2_cp_reginfo[] = {
40124058 { .name = "HCR_EL2", .state = ARM_CP_STATE_AA64,
40134059 .type = ARM_CP_IO,
@@ -6526,12 +6572,13 @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
65266572 uint32_t cur_el, bool secure)
65276573 {
65286574 CPUARMState *env = cs->env_ptr;
6529- int rw;
6530- int scr;
6531- int hcr;
6575+ bool rw;
6576+ bool scr;
6577+ bool hcr;
65326578 int target_el;
65336579 /* Is the highest EL AArch64? */
6534- int is64 = arm_feature(env, ARM_FEATURE_AARCH64);
6580+ bool is64 = arm_feature(env, ARM_FEATURE_AARCH64);
6581+ uint64_t hcr_el2;
65356582
65366583 if (arm_feature(env, ARM_FEATURE_EL3)) {
65376584 rw = ((env->cp15.scr_el3 & SCR_RW) == SCR_RW);
@@ -6543,18 +6590,19 @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
65436590 rw = is64;
65446591 }
65456592
6593+ hcr_el2 = arm_hcr_el2_eff(env);
65466594 switch (excp_idx) {
65476595 case EXCP_IRQ:
65486596 scr = ((env->cp15.scr_el3 & SCR_IRQ) == SCR_IRQ);
6549- hcr = arm_hcr_el2_imo(env);
6597+ hcr = hcr_el2 & HCR_IMO;
65506598 break;
65516599 case EXCP_FIQ:
65526600 scr = ((env->cp15.scr_el3 & SCR_FIQ) == SCR_FIQ);
6553- hcr = arm_hcr_el2_fmo(env);
6601+ hcr = hcr_el2 & HCR_FMO;
65546602 break;
65556603 default:
65566604 scr = ((env->cp15.scr_el3 & SCR_EA) == SCR_EA);
6557- hcr = arm_hcr_el2_amo(env);
6605+ hcr = hcr_el2 & HCR_AMO;
65586606 break;
65596607 };
65606608