Skip to content

Commit

Permalink
arm_boot: Pass base address of GIC CPU interface, not whole GIC
Browse files Browse the repository at this point in the history
The arm_boot secondary boot loader code needs the address of
the GIC CPU interface. Obtaining this from the base address
of the private peripheral region was possible for A9 and 11MPcore,
but the A15 puts the GIC CPU interface in a different place.
So make boards pass in the GIC CPU interface address directly.

Signed-off-by: Peter Maydell <[email protected]>
  • Loading branch information
pm215 committed Feb 17, 2012
1 parent b720687 commit 96eacf6
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 13 deletions.
2 changes: 1 addition & 1 deletion hw/arm-misc.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ struct arm_boot_info {
*/
target_phys_addr_t smp_loader_start;
target_phys_addr_t smp_bootreg_addr;
target_phys_addr_t smp_priv_base;
target_phys_addr_t gic_cpu_if_addr;
int nb_cpus;
int board_id;
int (*atag_board)(const struct arm_boot_info *info, void *p);
Expand Down
8 changes: 4 additions & 4 deletions hw/arm_boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,16 @@ static uint32_t bootloader[] = {
* location for the kernel secondary CPU entry point.
*/
static uint32_t smpboot[] = {
0xe59f201c, /* ldr r2, privbase */
0xe59f201c, /* ldr r2, gic_cpu_if */
0xe59f001c, /* ldr r0, startaddr */
0xe3a01001, /* mov r1, #1 */
0xe5821100, /* str r1, [r2, #256] */
0xe5821000, /* str r1, [r2] */
0xe320f003, /* wfi */
0xe5901000, /* ldr r1, [r0] */
0xe1110001, /* tst r1, r1 */
0x0afffffb, /* beq <wfi> */
0xe12fff11, /* bx r1 */
0, /* privbase: Private memory region base address. */
0, /* gic_cpu_if: base address of GIC CPU interface */
0 /* bootreg: Boot register address is held here */
};

Expand All @@ -61,7 +61,7 @@ static void default_write_secondary(CPUState *env,
{
int n;
smpboot[ARRAY_SIZE(smpboot) - 1] = info->smp_bootreg_addr;
smpboot[ARRAY_SIZE(smpboot) - 2] = info->smp_priv_base;
smpboot[ARRAY_SIZE(smpboot) - 2] = info->gic_cpu_if_addr;
for (n = 0; n < ARRAY_SIZE(smpboot); n++) {
smpboot[n] = tswap32(smpboot[n]);
}
Expand Down
3 changes: 2 additions & 1 deletion hw/exynos4_boards.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ static Exynos4210State *exynos4_boards_init_common(
exynos4_board_binfo.kernel_filename = kernel_filename;
exynos4_board_binfo.initrd_filename = initrd_filename;
exynos4_board_binfo.kernel_cmdline = kernel_cmdline;
exynos4_board_binfo.smp_priv_base = EXYNOS4210_SMP_PRIVATE_BASE_ADDR;
exynos4_board_binfo.gic_cpu_if_addr =
EXYNOS4210_SMP_PRIVATE_BASE_ADDR + 0x100;

PRINT_DEBUG("\n ram_size: %luMiB [0x%08lx]\n"
" kernel_filename: %s\n"
Expand Down
12 changes: 7 additions & 5 deletions hw/realview.c
Original file line number Diff line number Diff line change
Expand Up @@ -222,21 +222,23 @@ static void realview_init(ram_addr_t ram_size,
sysbus_mmio_map(sysbus_from_qdev(sysctl), 0, 0x10000000);

if (is_mpcore) {
target_phys_addr_t periphbase;
dev = qdev_create(NULL, is_pb ? "a9mpcore_priv": "realview_mpcore");
qdev_prop_set_uint32(dev, "num-cpu", smp_cpus);
qdev_init_nofail(dev);
busdev = sysbus_from_qdev(dev);
if (is_pb) {
realview_binfo.smp_priv_base = 0x1f000000;
periphbase = 0x1f000000;
} else {
realview_binfo.smp_priv_base = 0x10100000;
periphbase = 0x10100000;
}
sysbus_mmio_map(busdev, 0, realview_binfo.smp_priv_base);
sysbus_mmio_map(busdev, 0, periphbase);
for (n = 0; n < smp_cpus; n++) {
sysbus_connect_irq(busdev, n, cpu_irq[n]);
}
sysbus_create_varargs("l2x0", realview_binfo.smp_priv_base + 0x2000,
NULL);
sysbus_create_varargs("l2x0", periphbase + 0x2000, NULL);
/* Both A9 and 11MPCore put the GIC CPU i/f at base + 0x100 */
realview_binfo.gic_cpu_if_addr = periphbase + 0x100;
} else {
uint32_t gic_addr = is_pb ? 0x1e000000 : 0x10040000;
/* For now just create the nIRQ GIC, and ignore the others. */
Expand Down
6 changes: 4 additions & 2 deletions hw/vexpress.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ typedef void DBoardInitFn(const VEDBoardInfo *daughterboard,
struct VEDBoardInfo {
const target_phys_addr_t *motherboard_map;
target_phys_addr_t loader_start;
const target_phys_addr_t gic_cpu_if_addr;
DBoardInitFn *init;
};

Expand Down Expand Up @@ -175,8 +176,7 @@ static void a9_daughterboard_init(const VEDBoardInfo *daughterboard,
qdev_prop_set_uint32(dev, "num-cpu", smp_cpus);
qdev_init_nofail(dev);
busdev = sysbus_from_qdev(dev);
vexpress_binfo.smp_priv_base = 0x1e000000;
sysbus_mmio_map(busdev, 0, vexpress_binfo.smp_priv_base);
sysbus_mmio_map(busdev, 0, 0x1e000000);
for (n = 0; n < smp_cpus; n++) {
sysbus_connect_irq(busdev, n, cpu_irq[n]);
}
Expand Down Expand Up @@ -214,6 +214,7 @@ static void a9_daughterboard_init(const VEDBoardInfo *daughterboard,
static const VEDBoardInfo a9_daughterboard = {
.motherboard_map = motherboard_legacy_map,
.loader_start = 0x60000000,
.gic_cpu_if_addr = 0x1e000100,
.init = a9_daughterboard_init,
};

Expand Down Expand Up @@ -316,6 +317,7 @@ static void vexpress_common_init(const VEDBoardInfo *daughterboard,
vexpress_binfo.loader_start = daughterboard->loader_start;
vexpress_binfo.smp_loader_start = map[VE_SRAM];
vexpress_binfo.smp_bootreg_addr = map[VE_SYSREGS] + 0x30;
vexpress_binfo.gic_cpu_if_addr = daughterboard->gic_cpu_if_addr;
arm_load_kernel(first_cpu, &vexpress_binfo);
}

Expand Down

0 comments on commit 96eacf6

Please sign in to comment.