Commit 078758d0 authored by Evgeny Voevodin's avatar Evgeny Voevodin Committed by Andrzej Zaborowski
Browse files

hw/arm_boot.c: Make SMP boards specify address to poll in bootup loop



The secondary CPU bootloader in arm_boot.c holds secondary CPUs in a
pen until the primary CPU releases them. Make boards specify the
address to be polled to determine whether to leave the pen (it was
previously hardcoded to 0x10000030, which is a Versatile Express/
Realview specific system register address).

Signed-off-by: default avatarEvgeny Voevodin <e.voevodin@samsung.com>
Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
Signed-off-by: default avatarAndrzej Zaborowski <andrew.zaborowski@intel.com>
parent ea0e6841
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ struct arm_boot_info {
    const char *initrd_filename;
    target_phys_addr_t loader_start;
    target_phys_addr_t smp_loader_start;
    target_phys_addr_t smp_bootreg_addr;
    target_phys_addr_t smp_priv_base;
    int nb_cpus;
    int board_id;
+10 −8
Original line number Diff line number Diff line
@@ -31,17 +31,17 @@ static uint32_t bootloader[] = {
/* Entry point for secondary CPUs.  Enable interrupt controller and
   Issue WFI until start address is written to system controller.  */
static uint32_t smpboot[] = {
  0xe59f0020, /* ldr     r0, privbase */
  0xe59f201c, /* ldr r2, privbase */
  0xe59f001c, /* ldr r0, startaddr */
  0xe3a01001, /* mov r1, #1 */
  0xe5801100, /* str     r1, [r0, #0x100] */
  0xe3a00201, /* mov     r0, #0x10000000 */
  0xe3800030, /* orr     r0, #0x30 */
  0xe5821100, /* str r1, [r2, #256] */
  0xe320f003, /* wfi */
  0xe5901000, /* ldr     r1, [r0] */
  0xe1110001, /* tst     r1, r1 */
  0x0afffffb, /* beq     <wfi> */
  0xe12fff11, /* bx      r1 */
  0 /* privbase: Private memory region base address.  */
  0,          /* privbase: Private memory region base address.  */
  0           /* bootreg: Boot register address is held here */
};

#define WRITE_WORD(p, value) do { \
@@ -197,6 +197,7 @@ static void do_cpu_reset(void *opaque)
                                    info->loader_start);
                }
            } else {
                stl_phys_notdirty(info->smp_bootreg_addr, 0);
                env->regs[15] = info->smp_loader_start;
            }
        }
@@ -272,8 +273,9 @@ void arm_load_kernel(CPUState *env, struct arm_boot_info *info)
        rom_add_blob_fixed("bootloader", bootloader, sizeof(bootloader),
                           info->loader_start);
        if (info->nb_cpus > 1) {
            smpboot[10] = info->smp_priv_base;
            for (n = 0; n < sizeof(smpboot) / 4; n++) {
            smpboot[ARRAY_SIZE(smpboot) - 1] = info->smp_bootreg_addr;
            smpboot[ARRAY_SIZE(smpboot) - 2] = info->smp_priv_base;
            for (n = 0; n < ARRAY_SIZE(smpboot); n++) {
                smpboot[n] = tswap32(smpboot[n]);
            }
            rom_add_blob_fixed("smpboot", smpboot, sizeof(smpboot),
+2 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include "exec-memory.h"

#define SMP_BOOT_ADDR 0xe0000000
#define SMP_BOOTREG_ADDR 0x10000030

typedef struct {
    SysBusDevice busdev;
@@ -96,6 +97,7 @@ static void realview_register_devices(void)

static struct arm_boot_info realview_binfo = {
    .smp_loader_start = SMP_BOOT_ADDR,
    .smp_bootreg_addr = SMP_BOOTREG_ADDR,
};

/* The following two lists must be consistent.  */
+2 −0
Original line number Diff line number Diff line
@@ -31,11 +31,13 @@
#include "exec-memory.h"

#define SMP_BOOT_ADDR 0xe0000000
#define SMP_BOOTREG_ADDR 0x10000030

#define VEXPRESS_BOARD_ID 0x8e0

static struct arm_boot_info vexpress_binfo = {
    .smp_loader_start = SMP_BOOT_ADDR,
    .smp_bootreg_addr = SMP_BOOTREG_ADDR,
};

static void vexpress_a9_init(ram_addr_t ram_size,