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: Evgeny Voevodin <e.voevodin@samsung.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Andrzej Zaborowski <andrew.zaborowski@intel.com>
This commit is contained in:
Evgeny Voevodin 2012-01-13 20:52:40 +00:00 committed by Andrzej Zaborowski
parent ea0e68411e
commit 078758d074
4 changed files with 15 additions and 8 deletions

View File

@ -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;

View File

@ -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 */
0xe3a01001, /* mov r1, #1 */
0xe5801100, /* str r1, [r0, #0x100] */
0xe3a00201, /* mov r0, #0x10000000 */
0xe3800030, /* orr r0, #0x30 */
0xe59f201c, /* ldr r2, privbase */
0xe59f001c, /* ldr r0, startaddr */
0xe3a01001, /* mov r1, #1 */
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),

View File

@ -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. */

View File

@ -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,