qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [RFC v1 2/2] arm: boot: Add EL jump-down code for Linux


From: Christopher Covington
Subject: Re: [Qemu-devel] [RFC v1 2/2] arm: boot: Add EL jump-down code for Linux
Date: Tue, 19 Aug 2014 12:50:35 -0400
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130106 Thunderbird/17.0.2

Hi Peter,

On 08/18/2014 08:54 PM, Peter Crosthwaite wrote:
> Linux should boot in EL2 or EL1. If in EL3, jump down before handing
> off to Linux.
> 
> Signed-off-by: Peter Crosthwaite <address@hidden>
> ---
> 
>  hw/arm/boot.c | 21 +++++++++++++++++++++
>  1 file changed, 21 insertions(+)
> 
> diff --git a/hw/arm/boot.c b/hw/arm/boot.c
> index 840f5da..f1f6365 100644
> --- a/hw/arm/boot.c
> +++ b/hw/arm/boot.c
> @@ -35,6 +35,7 @@ typedef enum {
>      FIXUP_GIC_CPU_IF, /* overwrite with GIC CPU interface address */
>      FIXUP_BOOTREG,    /* overwrite with boot register address */
>      FIXUP_DSB,        /* overwrite with correct DSB insn for cpu */
> +    FIXUP_EL,         /* overwrite with kernel entry EL */
>      FIXUP_MAX,
>  } FixupType;
>  
> @@ -46,6 +47,20 @@ typedef struct ARMInsnFixup {
>  } ARMInsnFixup;
>  
>  static const ARMInsnFixup bootloader_aarch64[] = {
> +    { 0xd5384240 }, /* mrs x0, currentel */
> +    { 0x7100301f }, /* cmp w0, #0xc */
> +    { 0x54000001 + (9 << 5) }, /* b.ne ELx_start */
> +/* Jump down from EL3 to ELx */
> +    { 0x10000001 + (9 << 5) }, /* adr x1, ELx_start */

Nit: Consider putting this right before the usage to make the code slightly
easier to follow. Always using a distinct GPR per SR (such as x2 for SPSR) or
reusing the same GPR for all the SRs (such as x0 for ELR) might also make the
code easier to follow.

> +    { 0xd53e1100 }, /* mrs x0, scr_el3 */
> +    { 0xb2400000 }, /* orr x0, x0, #0x1 - SCR.NS */
> +    { 0xb2780000 }, /* orr x0, x0, #0x80 - SCR.HCE */
> +    { 0xd51e1100 }, /* msr scr_el3, x0 */
> +    { 0xd2807820, FIXUP_EL, 7, 2 }, /* movz x0, 0x3c1 (+ EL<<2) */
> +    { 0xd51e4000 }, /* msr spsr_el3, x0 */
> +    { 0xd51e4021 }, /* msr elr_el3, x1 */
> +    { 0xd69f03e0 }, /* eret */
> +/* ELx_start: */
>      { 0x580000c0 }, /* ldr x0, arg ; Load the lower 32-bits of DTB */
>      { 0xaa1f03e1 }, /* mov x1, xzr */
>      { 0xaa1f03e2 }, /* mov x2, xzr */
> @@ -141,6 +156,7 @@ static void write_bootloader(const char *name, hwaddr 
> addr,
>          case FIXUP_GIC_CPU_IF:
>          case FIXUP_BOOTREG:
>          case FIXUP_DSB:
> +        case FIXUP_EL:
>              insn = deposit32(insn, shift, length, fixupcontext[fixup]);
>              break;
>          default:
> @@ -583,6 +599,11 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info 
> *info)
>          }
>          fixupcontext[FIXUP_ENTRYPOINT] = entry;
>  
> +        fixupcontext[FIXUP_EL] = 1;
> +        if (arm_feature(&cpu->env, ARM_FEATURE_EL2)) {
> +            fixupcontext[FIXUP_EL] = 2;
> +        }
> +
>          write_bootloader("bootloader", info->loader_start,
>                           primary_loader, fixupcontext);
>  
> 

Thanks,
Christopher

-- 
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by the Linux Foundation.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]