diff mbox series

[08/25] hw/arm/boot: Export write_bootloader for Aspeed machines

Message ID 20230119123449.531826-9-clg@kaod.org
State New
Headers show
Series aspeed: Various extensions, fixes and cleanups | expand

Commit Message

Cédric Le Goater Jan. 19, 2023, 12:34 p.m. UTC
AST2600 Aspeed machines have an home made boot loader for secondaries.
To improve support, export the internal ARM boot loader and use it
instead.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
 include/hw/arm/boot.h | 24 ++++++++++++++++++++++++
 hw/arm/aspeed.c       | 42 ++++++++++++++++++++++--------------------
 hw/arm/boot.c         | 34 +++++++---------------------------
 3 files changed, 53 insertions(+), 47 deletions(-)

Comments

Joel Stanley Feb. 1, 2023, 5:45 a.m. UTC | #1
On Thu, 19 Jan 2023 at 12:37, Cédric Le Goater <clg@kaod.org> wrote:
>
> AST2600 Aspeed machines have an home made boot loader for secondaries.
> To improve support, export the internal ARM boot loader and use it
> instead.

I didn't quite follow why we're doing this. Is it just a cleanup?

>
> Signed-off-by: Cédric Le Goater <clg@kaod.org>
> ---
>  include/hw/arm/boot.h | 24 ++++++++++++++++++++++++
>  hw/arm/aspeed.c       | 42 ++++++++++++++++++++++--------------------
>  hw/arm/boot.c         | 34 +++++++---------------------------
>  3 files changed, 53 insertions(+), 47 deletions(-)
>
> diff --git a/include/hw/arm/boot.h b/include/hw/arm/boot.h
> index f18cc3064f..23edd0d31b 100644
> --- a/include/hw/arm/boot.h
> +++ b/include/hw/arm/boot.h
> @@ -183,4 +183,28 @@ void arm_write_secure_board_setup_dummy_smc(ARMCPU *cpu,
>                                              const struct arm_boot_info *info,
>                                              hwaddr mvbar_addr);
>
> +typedef enum {
> +    FIXUP_NONE = 0,     /* do nothing */
> +    FIXUP_TERMINATOR,   /* end of insns */
> +    FIXUP_BOARDID,      /* overwrite with board ID number */
> +    FIXUP_BOARD_SETUP,  /* overwrite with board specific setup code address */
> +    FIXUP_ARGPTR_LO,    /* overwrite with pointer to kernel args */
> +    FIXUP_ARGPTR_HI,    /* overwrite with pointer to kernel args (high half) */
> +    FIXUP_ENTRYPOINT_LO, /* overwrite with kernel entry point */
> +    FIXUP_ENTRYPOINT_HI, /* overwrite with kernel entry point (high half) */
> +    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_MAX,
> +} FixupType;
> +
> +typedef struct ARMInsnFixup {
> +    uint32_t insn;
> +    FixupType fixup;
> +} ARMInsnFixup;
> +
> +void arm_write_bootloader(const char *name, hwaddr addr,
> +                          const ARMInsnFixup *insns, uint32_t *fixupcontext,
> +                          AddressSpace *as);
> +
>  #endif /* HW_ARM_BOOT_H */
> diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> index 4919a1fe9e..c373bd2851 100644
> --- a/hw/arm/aspeed.c
> +++ b/hw/arm/aspeed.c
> @@ -198,33 +198,35 @@ struct AspeedMachineState {
>  static void aspeed_write_smpboot(ARMCPU *cpu,
>                                   const struct arm_boot_info *info)
>  {
> -    static const uint32_t poll_mailbox_ready[] = {
> +    AddressSpace *as = arm_boot_address_space(cpu, info);
> +    static const ARMInsnFixup poll_mailbox_ready[] = {
>          /*
>           * r2 = per-cpu go sign value
>           * r1 = AST_SMP_MBOX_FIELD_ENTRY
>           * r0 = AST_SMP_MBOX_FIELD_GOSIGN
>           */
> -        0xee100fb0,  /* mrc     p15, 0, r0, c0, c0, 5 */
> -        0xe21000ff,  /* ands    r0, r0, #255          */
> -        0xe59f201c,  /* ldr     r2, [pc, #28]         */
> -        0xe1822000,  /* orr     r2, r2, r0            */
> -
> -        0xe59f1018,  /* ldr     r1, [pc, #24]         */
> -        0xe59f0018,  /* ldr     r0, [pc, #24]         */
> -
> -        0xe320f002,  /* wfe                           */
> -        0xe5904000,  /* ldr     r4, [r0]              */
> -        0xe1520004,  /* cmp     r2, r4                */
> -        0x1afffffb,  /* bne     <wfe>                 */
> -        0xe591f000,  /* ldr     pc, [r1]              */
> -        AST_SMP_MBOX_GOSIGN,
> -        AST_SMP_MBOX_FIELD_ENTRY,
> -        AST_SMP_MBOX_FIELD_GOSIGN,
> +        { 0xee100fb0 },  /* mrc     p15, 0, r0, c0, c0, 5 */
> +        { 0xe21000ff },  /* ands    r0, r0, #255          */
> +        { 0xe59f201c },  /* ldr     r2, [pc, #28]         */
> +        { 0xe1822000 },  /* orr     r2, r2, r0            */
> +
> +        { 0xe59f1018 },  /* ldr     r1, [pc, #24]         */
> +        { 0xe59f0018 },  /* ldr     r0, [pc, #24]         */
> +
> +        { 0xe320f002 },  /* wfe                           */
> +        { 0xe5904000 },  /* ldr     r4, [r0]              */
> +        { 0xe1520004 },  /* cmp     r2, r4                */
> +        { 0x1afffffb },  /* bne     <wfe>                 */
> +        { 0xe591f000 },  /* ldr     pc, [r1]              */
> +        { AST_SMP_MBOX_GOSIGN },
> +        { AST_SMP_MBOX_FIELD_ENTRY },
> +        { AST_SMP_MBOX_FIELD_GOSIGN },
> +        { 0, FIXUP_TERMINATOR }
>      };
> +    uint32_t fixupcontext[FIXUP_MAX] = { 0 };
>
> -    rom_add_blob_fixed("aspeed.smpboot", poll_mailbox_ready,
> -                       sizeof(poll_mailbox_ready),
> -                       info->smp_loader_start);
> +    arm_write_bootloader("aspeed.smpboot", info->smp_loader_start,
> +                         poll_mailbox_ready, fixupcontext, as);
>  }
>
>  static void aspeed_reset_secondary(ARMCPU *cpu,
> diff --git a/hw/arm/boot.c b/hw/arm/boot.c
> index 3d7d11f782..ed6fd7c77f 100644
> --- a/hw/arm/boot.c
> +++ b/hw/arm/boot.c
> @@ -59,26 +59,6 @@ AddressSpace *arm_boot_address_space(ARMCPU *cpu,
>      return cpu_get_address_space(cs, asidx);
>  }
>
> -typedef enum {
> -    FIXUP_NONE = 0,     /* do nothing */
> -    FIXUP_TERMINATOR,   /* end of insns */
> -    FIXUP_BOARDID,      /* overwrite with board ID number */
> -    FIXUP_BOARD_SETUP,  /* overwrite with board specific setup code address */
> -    FIXUP_ARGPTR_LO,    /* overwrite with pointer to kernel args */
> -    FIXUP_ARGPTR_HI,    /* overwrite with pointer to kernel args (high half) */
> -    FIXUP_ENTRYPOINT_LO, /* overwrite with kernel entry point */
> -    FIXUP_ENTRYPOINT_HI, /* overwrite with kernel entry point (high half) */
> -    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_MAX,
> -} FixupType;
> -
> -typedef struct ARMInsnFixup {
> -    uint32_t insn;
> -    FixupType fixup;
> -} ARMInsnFixup;
> -
>  static const ARMInsnFixup bootloader_aarch64[] = {
>      { 0x580000c0 }, /* ldr x0, arg ; Load the lower 32-bits of DTB */
>      { 0xaa1f03e1 }, /* mov x1, xzr */
> @@ -149,9 +129,9 @@ static const ARMInsnFixup smpboot[] = {
>      { 0, FIXUP_TERMINATOR }
>  };
>
> -static void write_bootloader(const char *name, hwaddr addr,
> -                             const ARMInsnFixup *insns, uint32_t *fixupcontext,
> -                             AddressSpace *as)
> +void arm_write_bootloader(const char *name, hwaddr addr,
> +                          const ARMInsnFixup *insns, uint32_t *fixupcontext,
> +                          AddressSpace *as)
>  {
>      /* Fix up the specified bootloader fragment and write it into
>       * guest memory using rom_add_blob_fixed(). fixupcontext is
> @@ -213,8 +193,8 @@ static void default_write_secondary(ARMCPU *cpu,
>          fixupcontext[FIXUP_DSB] = CP15_DSB_INSN;
>      }
>
> -    write_bootloader("smpboot", info->smp_loader_start,
> -                     smpboot, fixupcontext, as);
> +    arm_write_bootloader("smpboot", info->smp_loader_start,
> +                         smpboot, fixupcontext, as);
>  }
>
>  void arm_write_secure_board_setup_dummy_smc(ARMCPU *cpu,
> @@ -1173,8 +1153,8 @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
>          fixupcontext[FIXUP_ENTRYPOINT_LO] = entry;
>          fixupcontext[FIXUP_ENTRYPOINT_HI] = entry >> 32;
>
> -        write_bootloader("bootloader", info->loader_start,
> -                         primary_loader, fixupcontext, as);
> +        arm_write_bootloader("bootloader", info->loader_start,
> +                             primary_loader, fixupcontext, as);
>
>          if (info->write_board_setup) {
>              info->write_board_setup(cpu, info);
> --
> 2.39.0
>
>
Cédric Le Goater Feb. 1, 2023, 7:58 a.m. UTC | #2
On 2/1/23 06:45, Joel Stanley wrote:
> On Thu, 19 Jan 2023 at 12:37, Cédric Le Goater <clg@kaod.org> wrote:
>>
>> AST2600 Aspeed machines have an home made boot loader for secondaries.
>> To improve support, export the internal ARM boot loader and use it
>> instead.
> 
> I didn't quite follow why we're doing this. Is it just a cleanup?

It comes from this discussion :

   https://lore.kernel.org/qemu-devel/20221222215549.86872-1-philmd@linaro.org/

I will leave Phil handle it. The patch is on the list now.

Thanks,

C.


>>
>> Signed-off-by: Cédric Le Goater <clg@kaod.org>
>> ---
>>   include/hw/arm/boot.h | 24 ++++++++++++++++++++++++
>>   hw/arm/aspeed.c       | 42 ++++++++++++++++++++++--------------------
>>   hw/arm/boot.c         | 34 +++++++---------------------------
>>   3 files changed, 53 insertions(+), 47 deletions(-)
>>
>> diff --git a/include/hw/arm/boot.h b/include/hw/arm/boot.h
>> index f18cc3064f..23edd0d31b 100644
>> --- a/include/hw/arm/boot.h
>> +++ b/include/hw/arm/boot.h
>> @@ -183,4 +183,28 @@ void arm_write_secure_board_setup_dummy_smc(ARMCPU *cpu,
>>                                               const struct arm_boot_info *info,
>>                                               hwaddr mvbar_addr);
>>
>> +typedef enum {
>> +    FIXUP_NONE = 0,     /* do nothing */
>> +    FIXUP_TERMINATOR,   /* end of insns */
>> +    FIXUP_BOARDID,      /* overwrite with board ID number */
>> +    FIXUP_BOARD_SETUP,  /* overwrite with board specific setup code address */
>> +    FIXUP_ARGPTR_LO,    /* overwrite with pointer to kernel args */
>> +    FIXUP_ARGPTR_HI,    /* overwrite with pointer to kernel args (high half) */
>> +    FIXUP_ENTRYPOINT_LO, /* overwrite with kernel entry point */
>> +    FIXUP_ENTRYPOINT_HI, /* overwrite with kernel entry point (high half) */
>> +    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_MAX,
>> +} FixupType;
>> +
>> +typedef struct ARMInsnFixup {
>> +    uint32_t insn;
>> +    FixupType fixup;
>> +} ARMInsnFixup;
>> +
>> +void arm_write_bootloader(const char *name, hwaddr addr,
>> +                          const ARMInsnFixup *insns, uint32_t *fixupcontext,
>> +                          AddressSpace *as);
>> +
>>   #endif /* HW_ARM_BOOT_H */
>> diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
>> index 4919a1fe9e..c373bd2851 100644
>> --- a/hw/arm/aspeed.c
>> +++ b/hw/arm/aspeed.c
>> @@ -198,33 +198,35 @@ struct AspeedMachineState {
>>   static void aspeed_write_smpboot(ARMCPU *cpu,
>>                                    const struct arm_boot_info *info)
>>   {
>> -    static const uint32_t poll_mailbox_ready[] = {
>> +    AddressSpace *as = arm_boot_address_space(cpu, info);
>> +    static const ARMInsnFixup poll_mailbox_ready[] = {
>>           /*
>>            * r2 = per-cpu go sign value
>>            * r1 = AST_SMP_MBOX_FIELD_ENTRY
>>            * r0 = AST_SMP_MBOX_FIELD_GOSIGN
>>            */
>> -        0xee100fb0,  /* mrc     p15, 0, r0, c0, c0, 5 */
>> -        0xe21000ff,  /* ands    r0, r0, #255          */
>> -        0xe59f201c,  /* ldr     r2, [pc, #28]         */
>> -        0xe1822000,  /* orr     r2, r2, r0            */
>> -
>> -        0xe59f1018,  /* ldr     r1, [pc, #24]         */
>> -        0xe59f0018,  /* ldr     r0, [pc, #24]         */
>> -
>> -        0xe320f002,  /* wfe                           */
>> -        0xe5904000,  /* ldr     r4, [r0]              */
>> -        0xe1520004,  /* cmp     r2, r4                */
>> -        0x1afffffb,  /* bne     <wfe>                 */
>> -        0xe591f000,  /* ldr     pc, [r1]              */
>> -        AST_SMP_MBOX_GOSIGN,
>> -        AST_SMP_MBOX_FIELD_ENTRY,
>> -        AST_SMP_MBOX_FIELD_GOSIGN,
>> +        { 0xee100fb0 },  /* mrc     p15, 0, r0, c0, c0, 5 */
>> +        { 0xe21000ff },  /* ands    r0, r0, #255          */
>> +        { 0xe59f201c },  /* ldr     r2, [pc, #28]         */
>> +        { 0xe1822000 },  /* orr     r2, r2, r0            */
>> +
>> +        { 0xe59f1018 },  /* ldr     r1, [pc, #24]         */
>> +        { 0xe59f0018 },  /* ldr     r0, [pc, #24]         */
>> +
>> +        { 0xe320f002 },  /* wfe                           */
>> +        { 0xe5904000 },  /* ldr     r4, [r0]              */
>> +        { 0xe1520004 },  /* cmp     r2, r4                */
>> +        { 0x1afffffb },  /* bne     <wfe>                 */
>> +        { 0xe591f000 },  /* ldr     pc, [r1]              */
>> +        { AST_SMP_MBOX_GOSIGN },
>> +        { AST_SMP_MBOX_FIELD_ENTRY },
>> +        { AST_SMP_MBOX_FIELD_GOSIGN },
>> +        { 0, FIXUP_TERMINATOR }
>>       };
>> +    uint32_t fixupcontext[FIXUP_MAX] = { 0 };
>>
>> -    rom_add_blob_fixed("aspeed.smpboot", poll_mailbox_ready,
>> -                       sizeof(poll_mailbox_ready),
>> -                       info->smp_loader_start);
>> +    arm_write_bootloader("aspeed.smpboot", info->smp_loader_start,
>> +                         poll_mailbox_ready, fixupcontext, as);
>>   }
>>
>>   static void aspeed_reset_secondary(ARMCPU *cpu,
>> diff --git a/hw/arm/boot.c b/hw/arm/boot.c
>> index 3d7d11f782..ed6fd7c77f 100644
>> --- a/hw/arm/boot.c
>> +++ b/hw/arm/boot.c
>> @@ -59,26 +59,6 @@ AddressSpace *arm_boot_address_space(ARMCPU *cpu,
>>       return cpu_get_address_space(cs, asidx);
>>   }
>>
>> -typedef enum {
>> -    FIXUP_NONE = 0,     /* do nothing */
>> -    FIXUP_TERMINATOR,   /* end of insns */
>> -    FIXUP_BOARDID,      /* overwrite with board ID number */
>> -    FIXUP_BOARD_SETUP,  /* overwrite with board specific setup code address */
>> -    FIXUP_ARGPTR_LO,    /* overwrite with pointer to kernel args */
>> -    FIXUP_ARGPTR_HI,    /* overwrite with pointer to kernel args (high half) */
>> -    FIXUP_ENTRYPOINT_LO, /* overwrite with kernel entry point */
>> -    FIXUP_ENTRYPOINT_HI, /* overwrite with kernel entry point (high half) */
>> -    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_MAX,
>> -} FixupType;
>> -
>> -typedef struct ARMInsnFixup {
>> -    uint32_t insn;
>> -    FixupType fixup;
>> -} ARMInsnFixup;
>> -
>>   static const ARMInsnFixup bootloader_aarch64[] = {
>>       { 0x580000c0 }, /* ldr x0, arg ; Load the lower 32-bits of DTB */
>>       { 0xaa1f03e1 }, /* mov x1, xzr */
>> @@ -149,9 +129,9 @@ static const ARMInsnFixup smpboot[] = {
>>       { 0, FIXUP_TERMINATOR }
>>   };
>>
>> -static void write_bootloader(const char *name, hwaddr addr,
>> -                             const ARMInsnFixup *insns, uint32_t *fixupcontext,
>> -                             AddressSpace *as)
>> +void arm_write_bootloader(const char *name, hwaddr addr,
>> +                          const ARMInsnFixup *insns, uint32_t *fixupcontext,
>> +                          AddressSpace *as)
>>   {
>>       /* Fix up the specified bootloader fragment and write it into
>>        * guest memory using rom_add_blob_fixed(). fixupcontext is
>> @@ -213,8 +193,8 @@ static void default_write_secondary(ARMCPU *cpu,
>>           fixupcontext[FIXUP_DSB] = CP15_DSB_INSN;
>>       }
>>
>> -    write_bootloader("smpboot", info->smp_loader_start,
>> -                     smpboot, fixupcontext, as);
>> +    arm_write_bootloader("smpboot", info->smp_loader_start,
>> +                         smpboot, fixupcontext, as);
>>   }
>>
>>   void arm_write_secure_board_setup_dummy_smc(ARMCPU *cpu,
>> @@ -1173,8 +1153,8 @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
>>           fixupcontext[FIXUP_ENTRYPOINT_LO] = entry;
>>           fixupcontext[FIXUP_ENTRYPOINT_HI] = entry >> 32;
>>
>> -        write_bootloader("bootloader", info->loader_start,
>> -                         primary_loader, fixupcontext, as);
>> +        arm_write_bootloader("bootloader", info->loader_start,
>> +                             primary_loader, fixupcontext, as);
>>
>>           if (info->write_board_setup) {
>>               info->write_board_setup(cpu, info);
>> --
>> 2.39.0
>>
>>
Philippe Mathieu-Daudé Feb. 1, 2023, 12:20 p.m. UTC | #3
On 1/2/23 08:58, Cédric Le Goater wrote:
> On 2/1/23 06:45, Joel Stanley wrote:
>> On Thu, 19 Jan 2023 at 12:37, Cédric Le Goater <clg@kaod.org> wrote:
>>>
>>> AST2600 Aspeed machines have an home made boot loader for secondaries.
>>> To improve support, export the internal ARM boot loader and use it
>>> instead.
>>
>> I didn't quite follow why we're doing this. Is it just a cleanup?
> 
> It comes from this discussion :
> 
>    
> https://lore.kernel.org/qemu-devel/20221222215549.86872-1-philmd@linaro.org/

Joel, see:
https://lore.kernel.org/qemu-devel/CAFEAcA9KD8WwPTKVQQUfAZxaqA=ASweZtJ=sAV0Vd8TkpqDBOw@mail.gmail.com/
diff mbox series

Patch

diff --git a/include/hw/arm/boot.h b/include/hw/arm/boot.h
index f18cc3064f..23edd0d31b 100644
--- a/include/hw/arm/boot.h
+++ b/include/hw/arm/boot.h
@@ -183,4 +183,28 @@  void arm_write_secure_board_setup_dummy_smc(ARMCPU *cpu,
                                             const struct arm_boot_info *info,
                                             hwaddr mvbar_addr);
 
+typedef enum {
+    FIXUP_NONE = 0,     /* do nothing */
+    FIXUP_TERMINATOR,   /* end of insns */
+    FIXUP_BOARDID,      /* overwrite with board ID number */
+    FIXUP_BOARD_SETUP,  /* overwrite with board specific setup code address */
+    FIXUP_ARGPTR_LO,    /* overwrite with pointer to kernel args */
+    FIXUP_ARGPTR_HI,    /* overwrite with pointer to kernel args (high half) */
+    FIXUP_ENTRYPOINT_LO, /* overwrite with kernel entry point */
+    FIXUP_ENTRYPOINT_HI, /* overwrite with kernel entry point (high half) */
+    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_MAX,
+} FixupType;
+
+typedef struct ARMInsnFixup {
+    uint32_t insn;
+    FixupType fixup;
+} ARMInsnFixup;
+
+void arm_write_bootloader(const char *name, hwaddr addr,
+                          const ARMInsnFixup *insns, uint32_t *fixupcontext,
+                          AddressSpace *as);
+
 #endif /* HW_ARM_BOOT_H */
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index 4919a1fe9e..c373bd2851 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -198,33 +198,35 @@  struct AspeedMachineState {
 static void aspeed_write_smpboot(ARMCPU *cpu,
                                  const struct arm_boot_info *info)
 {
-    static const uint32_t poll_mailbox_ready[] = {
+    AddressSpace *as = arm_boot_address_space(cpu, info);
+    static const ARMInsnFixup poll_mailbox_ready[] = {
         /*
          * r2 = per-cpu go sign value
          * r1 = AST_SMP_MBOX_FIELD_ENTRY
          * r0 = AST_SMP_MBOX_FIELD_GOSIGN
          */
-        0xee100fb0,  /* mrc     p15, 0, r0, c0, c0, 5 */
-        0xe21000ff,  /* ands    r0, r0, #255          */
-        0xe59f201c,  /* ldr     r2, [pc, #28]         */
-        0xe1822000,  /* orr     r2, r2, r0            */
-
-        0xe59f1018,  /* ldr     r1, [pc, #24]         */
-        0xe59f0018,  /* ldr     r0, [pc, #24]         */
-
-        0xe320f002,  /* wfe                           */
-        0xe5904000,  /* ldr     r4, [r0]              */
-        0xe1520004,  /* cmp     r2, r4                */
-        0x1afffffb,  /* bne     <wfe>                 */
-        0xe591f000,  /* ldr     pc, [r1]              */
-        AST_SMP_MBOX_GOSIGN,
-        AST_SMP_MBOX_FIELD_ENTRY,
-        AST_SMP_MBOX_FIELD_GOSIGN,
+        { 0xee100fb0 },  /* mrc     p15, 0, r0, c0, c0, 5 */
+        { 0xe21000ff },  /* ands    r0, r0, #255          */
+        { 0xe59f201c },  /* ldr     r2, [pc, #28]         */
+        { 0xe1822000 },  /* orr     r2, r2, r0            */
+
+        { 0xe59f1018 },  /* ldr     r1, [pc, #24]         */
+        { 0xe59f0018 },  /* ldr     r0, [pc, #24]         */
+
+        { 0xe320f002 },  /* wfe                           */
+        { 0xe5904000 },  /* ldr     r4, [r0]              */
+        { 0xe1520004 },  /* cmp     r2, r4                */
+        { 0x1afffffb },  /* bne     <wfe>                 */
+        { 0xe591f000 },  /* ldr     pc, [r1]              */
+        { AST_SMP_MBOX_GOSIGN },
+        { AST_SMP_MBOX_FIELD_ENTRY },
+        { AST_SMP_MBOX_FIELD_GOSIGN },
+        { 0, FIXUP_TERMINATOR }
     };
+    uint32_t fixupcontext[FIXUP_MAX] = { 0 };
 
-    rom_add_blob_fixed("aspeed.smpboot", poll_mailbox_ready,
-                       sizeof(poll_mailbox_ready),
-                       info->smp_loader_start);
+    arm_write_bootloader("aspeed.smpboot", info->smp_loader_start,
+                         poll_mailbox_ready, fixupcontext, as);
 }
 
 static void aspeed_reset_secondary(ARMCPU *cpu,
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 3d7d11f782..ed6fd7c77f 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -59,26 +59,6 @@  AddressSpace *arm_boot_address_space(ARMCPU *cpu,
     return cpu_get_address_space(cs, asidx);
 }
 
-typedef enum {
-    FIXUP_NONE = 0,     /* do nothing */
-    FIXUP_TERMINATOR,   /* end of insns */
-    FIXUP_BOARDID,      /* overwrite with board ID number */
-    FIXUP_BOARD_SETUP,  /* overwrite with board specific setup code address */
-    FIXUP_ARGPTR_LO,    /* overwrite with pointer to kernel args */
-    FIXUP_ARGPTR_HI,    /* overwrite with pointer to kernel args (high half) */
-    FIXUP_ENTRYPOINT_LO, /* overwrite with kernel entry point */
-    FIXUP_ENTRYPOINT_HI, /* overwrite with kernel entry point (high half) */
-    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_MAX,
-} FixupType;
-
-typedef struct ARMInsnFixup {
-    uint32_t insn;
-    FixupType fixup;
-} ARMInsnFixup;
-
 static const ARMInsnFixup bootloader_aarch64[] = {
     { 0x580000c0 }, /* ldr x0, arg ; Load the lower 32-bits of DTB */
     { 0xaa1f03e1 }, /* mov x1, xzr */
@@ -149,9 +129,9 @@  static const ARMInsnFixup smpboot[] = {
     { 0, FIXUP_TERMINATOR }
 };
 
-static void write_bootloader(const char *name, hwaddr addr,
-                             const ARMInsnFixup *insns, uint32_t *fixupcontext,
-                             AddressSpace *as)
+void arm_write_bootloader(const char *name, hwaddr addr,
+                          const ARMInsnFixup *insns, uint32_t *fixupcontext,
+                          AddressSpace *as)
 {
     /* Fix up the specified bootloader fragment and write it into
      * guest memory using rom_add_blob_fixed(). fixupcontext is
@@ -213,8 +193,8 @@  static void default_write_secondary(ARMCPU *cpu,
         fixupcontext[FIXUP_DSB] = CP15_DSB_INSN;
     }
 
-    write_bootloader("smpboot", info->smp_loader_start,
-                     smpboot, fixupcontext, as);
+    arm_write_bootloader("smpboot", info->smp_loader_start,
+                         smpboot, fixupcontext, as);
 }
 
 void arm_write_secure_board_setup_dummy_smc(ARMCPU *cpu,
@@ -1173,8 +1153,8 @@  static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
         fixupcontext[FIXUP_ENTRYPOINT_LO] = entry;
         fixupcontext[FIXUP_ENTRYPOINT_HI] = entry >> 32;
 
-        write_bootloader("bootloader", info->loader_start,
-                         primary_loader, fixupcontext, as);
+        arm_write_bootloader("bootloader", info->loader_start,
+                             primary_loader, fixupcontext, as);
 
         if (info->write_board_setup) {
             info->write_board_setup(cpu, info);