diff options
author | Paul Brook <paul@codesourcery.com> | 2009-11-11 19:59:29 +0000 |
---|---|---|
committer | Paul Brook <paul@codesourcery.com> | 2009-11-11 19:59:29 +0000 |
commit | be0f204aa0d8743f0627cd3cffb0ffc5bbf962e9 (patch) | |
tree | 78f9e202cea9d82873866424040a663537626665 | |
parent | 97fe84f5efbd4f3ded433b7da5daca1f8fd5a82f (diff) |
Fix ARM MCore secondary cpu boot
Make MPCore secondary cpu initialization work with the new reset
handling. Also change the inital FLAG value from 3 to zero to match
recent kenrels.
Signed-off-by: Paul Brook <paul@codesourcery.com>
-rw-r--r-- | hw/arm_boot.c | 4 | ||||
-rw-r--r-- | hw/arm_sysctl.c | 16 | ||||
-rw-r--r-- | hw/realview.c | 16 |
3 files changed, 27 insertions, 9 deletions
diff --git a/hw/arm_boot.c b/hw/arm_boot.c index 28e9dbd607..e273803645 100644 --- a/hw/arm_boot.c +++ b/hw/arm_boot.c @@ -39,8 +39,8 @@ static uint32_t smpboot[] = { 0xe3800030, /* orr r0, #0x30 */ 0xe320f003, /* wfi */ 0xe5901000, /* ldr r1, [r0] */ - 0xe3110003, /* tst r1, #3 */ - 0x1afffffb, /* bne <wfi> */ + 0xe1110001, /* tst r1, r1 */ + 0x0afffffb, /* beq <wfi> */ 0xe12fff11 /* bx r1 */ }; diff --git a/hw/arm_sysctl.c b/hw/arm_sysctl.c index 72c7ccbe3d..856e770921 100644 --- a/hw/arm_sysctl.c +++ b/hw/arm_sysctl.c @@ -27,6 +27,18 @@ typedef struct { uint32_t resetlevel; } arm_sysctl_state; +static void arm_sysctl_reset(DeviceState *d) +{ + arm_sysctl_state *s = FROM_SYSBUS(arm_sysctl_state, sysbus_from_qdev(d)); + + s->leds = 0; + s->lockval = 0; + s->cfgdata1 = 0; + s->cfgdata2 = 0; + s->flags = 0; + s->resetlevel = 0; +} + static uint32_t arm_sysctl_read(void *opaque, target_phys_addr_t offset) { arm_sysctl_state *s = (arm_sysctl_state *)opaque; @@ -195,9 +207,6 @@ static int arm_sysctl_init1(SysBusDevice *dev) arm_sysctl_state *s = FROM_SYSBUS(arm_sysctl_state, dev); int iomemtype; - /* The MPcore bootloader uses these flags to start secondary CPUs. - We don't use a bootloader, so do this here. */ - s->flags = 3; iomemtype = cpu_register_io_memory(arm_sysctl_readfn, arm_sysctl_writefn, s); sysbus_init_mmio(dev, 0x1000, iomemtype); @@ -220,6 +229,7 @@ static SysBusDeviceInfo arm_sysctl_info = { .init = arm_sysctl_init1, .qdev.name = "realview_sysctl", .qdev.size = sizeof(arm_sysctl_state), + .qdev.reset = arm_sysctl_reset, .qdev.props = (Property[]) { DEFINE_PROP_UINT32("sys_id", arm_sysctl_state, sys_id, 0), DEFINE_PROP_END_OF_LIST(), diff --git a/hw/realview.c b/hw/realview.c index c494a20c88..95ad727d43 100644 --- a/hw/realview.c +++ b/hw/realview.c @@ -24,6 +24,17 @@ static struct arm_boot_info realview_binfo = { .board_id = 0x33b, }; +static void secondary_cpu_reset(void *opaque) +{ + CPUState *env = opaque; + + cpu_reset(env); + /* Set entry point for secondary CPUs. This assumes we're using + the init code from arm_boot.c. Real hardware resets all CPUs + the same. */ + env->regs[15] = 0x80000000; +} + static void realview_init(ram_addr_t ram_size, const char *boot_device, const char *kernel_filename, const char *kernel_cmdline, @@ -59,10 +70,7 @@ static void realview_init(ram_addr_t ram_size, irqp = arm_pic_init_cpu(env); cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ]; if (n > 0) { - /* Set entry point for secondary CPUs. This assumes we're using - the init code from arm_boot.c. Real hardware resets all CPUs - the same. */ - env->regs[15] = 0x80000000; + qemu_register_reset(secondary_cpu_reset, env); } } |