diff mbox

[1/8] target-arm: Properly support EL2 and EL3 in arm_el_is_aa64()

Message ID 1452796451-2946-2-git-send-email-peter.maydell@linaro.org
State New
Headers show

Commit Message

Peter Maydell Jan. 14, 2016, 6:34 p.m. UTC
Support EL2 and EL3 in arm_el_is_aa64() by implementing the
logic for checking the SCR_EL3 and HCR_EL2 register-width bits
as appropriate to determine the register width of lower exception
levels.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 target-arm/cpu.h | 33 ++++++++++++++++++++++++---------
 1 file changed, 24 insertions(+), 9 deletions(-)

Comments

Edgar E. Iglesias Jan. 15, 2016, 2:38 p.m. UTC | #1
On Thu, Jan 14, 2016 at 06:34:04PM +0000, Peter Maydell wrote:
> Support EL2 and EL3 in arm_el_is_aa64() by implementing the
> logic for checking the SCR_EL3 and HCR_EL2 register-width bits
> as appropriate to determine the register width of lower exception
> levels.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Hi Peter,

On the ZynqMP we've got the Cortex-A53 EL3 RW configurable at reset
time. At some later point we'll likely have to implement that
runtime option...

Anyway:
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>


> ---
>  target-arm/cpu.h | 33 ++++++++++++++++++++++++---------
>  1 file changed, 24 insertions(+), 9 deletions(-)
> 
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 5f81342..b8b3364 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -969,18 +969,33 @@ static inline bool arm_is_secure(CPUARMState *env)
>  /* Return true if the specified exception level is running in AArch64 state. */
>  static inline bool arm_el_is_aa64(CPUARMState *env, int el)
>  {
> -    /* We don't currently support EL2, and this isn't valid for EL0
> -     * (if we're in EL0, is_a64() is what you want, and if we're not in EL0
> -     * then the state of EL0 isn't well defined.)
> +    /* This isn't valid for EL0 (if we're in EL0, is_a64() is what you want,
> +     * and if we're not in EL0 then the state of EL0 isn't well defined.)
>       */
> -    assert(el == 1 || el == 3);
> +    assert(el >= 1 && el <= 3);
> +    bool aa64 = arm_feature(env, ARM_FEATURE_AARCH64);
>  
> -    /* AArch64-capable CPUs always run with EL1 in AArch64 mode. This
> -     * is a QEMU-imposed simplification which we may wish to change later.
> -     * If we in future support EL2 and/or EL3, then the state of lower
> -     * exception levels is controlled by the HCR.RW and SCR.RW bits.
> +    /* The highest exception level is always at the maximum supported
> +     * register width, and then lower levels have a register width controlled
> +     * by bits in the SCR or HCR registers.
>       */
> -    return arm_feature(env, ARM_FEATURE_AARCH64);
> +    if (el == 3) {
> +        return aa64;
> +    }
> +
> +    if (arm_feature(env, ARM_FEATURE_EL3)) {
> +        aa64 = aa64 && (env->cp15.scr_el3 & SCR_RW);
> +    }
> +
> +    if (el == 2) {
> +        return aa64;
> +    }
> +
> +    if (arm_feature(env, ARM_FEATURE_EL2) && !arm_is_secure_below_el3(env)) {
> +        aa64 = aa64 && (env->cp15.hcr_el2 & HCR_RW);
> +    }
> +
> +    return aa64;
>  }
>  
>  /* Function for determing whether guest cp register reads and writes should
> -- 
> 1.9.1
>
Peter Maydell Jan. 15, 2016, 2:50 p.m. UTC | #2
On 15 January 2016 at 14:38, Edgar E. Iglesias <edgar.iglesias@gmail.com> wrote:
> On Thu, Jan 14, 2016 at 06:34:04PM +0000, Peter Maydell wrote:
>> Support EL2 and EL3 in arm_el_is_aa64() by implementing the
>> logic for checking the SCR_EL3 and HCR_EL2 register-width bits
>> as appropriate to determine the register width of lower exception
>> levels.
>>
>> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
>
> Hi Peter,
>
> On the ZynqMP we've got the Cortex-A53 EL3 RW configurable at reset
> time. At some later point we'll likely have to implement that
> runtime option...

That might be tricky, we fairly well bake in "AARCH64 feature means
64-bit highest EL" at the moment. The KVM code takes the approach
of "if it's not going to reset in AArch64 then unset the feature bit".

Anyway, we'll cross that bridge when we get to it.

Do you have much locally extra that you needed for enabling
EL3 in the Cortex-A53? I have an ARM Trusted Firmware + OP-TEE
setup now that I'm going to use to work through the missing bits,
but if you've already gone through that effort there's no need
my duplicating work...

thanks
-- PMM
Sergey Fedorov Jan. 29, 2016, 4:45 p.m. UTC | #3
On 14.01.2016 21:34, Peter Maydell wrote:
> Support EL2 and EL3 in arm_el_is_aa64() by implementing the
> logic for checking the SCR_EL3 and HCR_EL2 register-width bits
> as appropriate to determine the register width of lower exception
> levels.

Reviewed-by: Sergey Fedorov <serge.fdrv@gmail.com>

>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  target-arm/cpu.h | 33 ++++++++++++++++++++++++---------
>  1 file changed, 24 insertions(+), 9 deletions(-)
>
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 5f81342..b8b3364 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -969,18 +969,33 @@ static inline bool arm_is_secure(CPUARMState *env)
>  /* Return true if the specified exception level is running in AArch64 state. */
>  static inline bool arm_el_is_aa64(CPUARMState *env, int el)
>  {
> -    /* We don't currently support EL2, and this isn't valid for EL0
> -     * (if we're in EL0, is_a64() is what you want, and if we're not in EL0
> -     * then the state of EL0 isn't well defined.)
> +    /* This isn't valid for EL0 (if we're in EL0, is_a64() is what you want,
> +     * and if we're not in EL0 then the state of EL0 isn't well defined.)
>       */
> -    assert(el == 1 || el == 3);
> +    assert(el >= 1 && el <= 3);
> +    bool aa64 = arm_feature(env, ARM_FEATURE_AARCH64);
>  
> -    /* AArch64-capable CPUs always run with EL1 in AArch64 mode. This
> -     * is a QEMU-imposed simplification which we may wish to change later.
> -     * If we in future support EL2 and/or EL3, then the state of lower
> -     * exception levels is controlled by the HCR.RW and SCR.RW bits.
> +    /* The highest exception level is always at the maximum supported
> +     * register width, and then lower levels have a register width controlled
> +     * by bits in the SCR or HCR registers.
>       */
> -    return arm_feature(env, ARM_FEATURE_AARCH64);
> +    if (el == 3) {
> +        return aa64;
> +    }
> +
> +    if (arm_feature(env, ARM_FEATURE_EL3)) {
> +        aa64 = aa64 && (env->cp15.scr_el3 & SCR_RW);
> +    }
> +
> +    if (el == 2) {
> +        return aa64;
> +    }
> +
> +    if (arm_feature(env, ARM_FEATURE_EL2) && !arm_is_secure_below_el3(env)) {
> +        aa64 = aa64 && (env->cp15.hcr_el2 & HCR_RW);
> +    }
> +
> +    return aa64;
>  }
>  
>  /* Function for determing whether guest cp register reads and writes should
Sergey Fedorov Jan. 29, 2016, 4:50 p.m. UTC | #4
On 29.01.2016 19:45, Sergey Fedorov wrote:
> On 14.01.2016 21:34, Peter Maydell wrote:
>> > Support EL2 and EL3 in arm_el_is_aa64() by implementing the
>> > logic for checking the SCR_EL3 and HCR_EL2 register-width bits
>> > as appropriate to determine the register width of lower exception
>> > levels.
> Reviewed-by: Sergey Fedorov <serge.fdrv@gmail.com>

Oops... I should put this below the following "Signed-off-by" statement :)

>
>> >
>> > Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Peter Maydell Jan. 29, 2016, 5:05 p.m. UTC | #5
On 29 January 2016 at 16:45, Sergey Fedorov <serge.fdrv@gmail.com> wrote:
> On 14.01.2016 21:34, Peter Maydell wrote:
>> Support EL2 and EL3 in arm_el_is_aa64() by implementing the
>> logic for checking the SCR_EL3 and HCR_EL2 register-width bits
>> as appropriate to determine the register width of lower exception
>> levels.
>
> Reviewed-by: Sergey Fedorov <serge.fdrv@gmail.com>

Thanks for the review, but this series went into master last week :-)

-- PMM
Sergey Fedorov Jan. 29, 2016, 5:08 p.m. UTC | #6
On 29.01.2016 20:05, Peter Maydell wrote:
> On 29 January 2016 at 16:45, Sergey Fedorov <serge.fdrv@gmail.com> wrote:
>> > On 14.01.2016 21:34, Peter Maydell wrote:
>>> >> Support EL2 and EL3 in arm_el_is_aa64() by implementing the
>>> >> logic for checking the SCR_EL3 and HCR_EL2 register-width bits
>>> >> as appropriate to determine the register width of lower exception
>>> >> levels.
>> >
>> > Reviewed-by: Sergey Fedorov <serge.fdrv@gmail.com>
> Thanks for the review, but this series went into master last week :-)

Heh, I missed that somehow :) Anyway, great patches!
diff mbox

Patch

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 5f81342..b8b3364 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -969,18 +969,33 @@  static inline bool arm_is_secure(CPUARMState *env)
 /* Return true if the specified exception level is running in AArch64 state. */
 static inline bool arm_el_is_aa64(CPUARMState *env, int el)
 {
-    /* We don't currently support EL2, and this isn't valid for EL0
-     * (if we're in EL0, is_a64() is what you want, and if we're not in EL0
-     * then the state of EL0 isn't well defined.)
+    /* This isn't valid for EL0 (if we're in EL0, is_a64() is what you want,
+     * and if we're not in EL0 then the state of EL0 isn't well defined.)
      */
-    assert(el == 1 || el == 3);
+    assert(el >= 1 && el <= 3);
+    bool aa64 = arm_feature(env, ARM_FEATURE_AARCH64);
 
-    /* AArch64-capable CPUs always run with EL1 in AArch64 mode. This
-     * is a QEMU-imposed simplification which we may wish to change later.
-     * If we in future support EL2 and/or EL3, then the state of lower
-     * exception levels is controlled by the HCR.RW and SCR.RW bits.
+    /* The highest exception level is always at the maximum supported
+     * register width, and then lower levels have a register width controlled
+     * by bits in the SCR or HCR registers.
      */
-    return arm_feature(env, ARM_FEATURE_AARCH64);
+    if (el == 3) {
+        return aa64;
+    }
+
+    if (arm_feature(env, ARM_FEATURE_EL3)) {
+        aa64 = aa64 && (env->cp15.scr_el3 & SCR_RW);
+    }
+
+    if (el == 2) {
+        return aa64;
+    }
+
+    if (arm_feature(env, ARM_FEATURE_EL2) && !arm_is_secure_below_el3(env)) {
+        aa64 = aa64 && (env->cp15.hcr_el2 & HCR_RW);
+    }
+
+    return aa64;
 }
 
 /* Function for determing whether guest cp register reads and writes should