summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Brook <paul@codesourcery.com>2009-11-11 19:59:29 +0000
committerPaul Brook <paul@codesourcery.com>2009-11-11 19:59:29 +0000
commitbe0f204aa0d8743f0627cd3cffb0ffc5bbf962e9 (patch)
tree78f9e202cea9d82873866424040a663537626665
parent97fe84f5efbd4f3ded433b7da5daca1f8fd5a82f (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.c4
-rw-r--r--hw/arm_sysctl.c16
-rw-r--r--hw/realview.c16
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);
}
}