Re: [Qemu-devel] [PATCH v1 1/3] xilinx_zynq: added smp support

2012-04-20 Thread Peter Crosthwaite
Ping!

I realise there were issues with the other patches in this series, but
this one on its own is self contained and valuable in its own right.
Can we get a review accordingly?

Regards,
Peter

On Wed, Apr 11, 2012 at 3:50 AM, John Linn john.l...@xilinx.com wrote:
 -Original Message-
 From: Peter A. G. Crosthwaite [mailto:peter.crosthwa...@petalogix.com]
 Sent: Sunday, April 01, 2012 10:20 PM
 To: peter.crosthwa...@petalogix.com; qemu-devel@nongnu.org;
 p...@codesourcery.com; peter.mayd...@linaro.org;
 edgar.igles...@gmail.com
 Cc: Duy Le; John Linn; john.willi...@petalogix.com
 Subject: [PATCH v1 1/3] xilinx_zynq: added smp support

 Added linux smp support for the xilinx zynq platform (2x cpus are
 supported)

 Signed-off-by: Peter A. G. Crosthwaite
 peter.crosthwa...@petalogix.com

 Signed-off-by: John Linn john.l...@xilinx.com

 ---
  hw/xilinx_zynq.c |   64
 --
 ---
  1 files changed, 53 insertions(+), 11 deletions(-)

 diff --git a/hw/xilinx_zynq.c b/hw/xilinx_zynq.c
 index 7290c64..56d0b96 100644
 --- a/hw/xilinx_zynq.c
 +++ b/hw/xilinx_zynq.c
 @@ -30,6 +30,42 @@

  #define IRQ_OFFSET 32 /* pic interrupts start from index 32 */

 +#define SMP_BOOT_ADDR 0x0fff
 +
 +static void zynq_reset_secondary(CPUARMState *env,
 +                                    const struct arm_boot_info *info)
 +{
 +    env-regs[15] = SMP_BOOT_ADDR;
 +}
 +
 +/* Entry point for secondary CPU */
 +static uint32_t zynq_smpboot[] = {
 +    0xe59f0020, /* ldr     r0, privbase */
 +    0xe3a004FF, /* mov     r0 = 0xFFF0 */
 +    0xe38008FF, /* orr     ...*/
 +    0xe3800CFF, /* orr      */
 +    0xe38000F0, /* orr     . */
 +    0xe320f002, /* wfe */
 +    0xe5901000, /* ldr     r1, [r0] */
 +    0xe1110001, /* tst     r1, r1 */
 +    0x0afb, /* beq     wfe */
 +    0xe12fff11, /* bx      r1 */
 +    0,
 +    0
 +};
 +
 +static void zynq_write_secondary_boot(CPUARMState *env,
 +                                    const struct arm_boot_info *info)
 +{
 +    int n;
 +
 +    for (n = 0; n  ARRAY_SIZE(zynq_smpboot); n++) {
 +        zynq_smpboot[n] = tswap32(zynq_smpboot[n]);
 +    }
 +    rom_add_blob_fixed(smpboot, zynq_smpboot, sizeof(zynq_smpboot),
 +            SMP_BOOT_ADDR);
 +}
 +
  static struct arm_boot_info zynq_binfo = {};

  static void gem_init(NICInfo *nd, uint32_t base, qemu_irq irq)
 @@ -60,19 +96,21 @@ static void zynq_init(ram_addr_t ram_size, const
 char *boot_device,
      qemu_irq pic[64];
      NICInfo *nd;
      int n;
 -    qemu_irq cpu_irq;
 +    qemu_irq cpu_irq[2];

      if (!cpu_model) {
          cpu_model = cortex-a9;
      }

 -    env = cpu_init(cpu_model);
 -    if (!env) {
 -        fprintf(stderr, Unable to find CPU definition\n);
 -        exit(1);
 +    for (n = 0; n  smp_cpus; n++) {
 +        env = cpu_init(cpu_model);
 +        if (!env) {
 +            fprintf(stderr, Unable to find CPU definition\n);
 +            exit(1);
 +        }
 +        irqp = arm_pic_init_cpu(env);
 +        cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
      }
 -    irqp = arm_pic_init_cpu(env);
 -    cpu_irq = irqp[ARM_PIC_CPU_IRQ];

      /* max 2GB ram */
      if (ram_size  0x8000) {
 @@ -103,11 +141,13 @@ static void zynq_init(ram_addr_t ram_size, const
 char *boot_device,
      sysbus_mmio_map(sysbus_from_qdev(dev), 0, 0xF800);

      dev = qdev_create(NULL, a9mpcore_priv);
 -    qdev_prop_set_uint32(dev, num-cpu, 1);
 +    qdev_prop_set_uint32(dev, num-cpu, smp_cpus);
      qdev_init_nofail(dev);
      busdev = sysbus_from_qdev(dev);
      sysbus_mmio_map(busdev, 0, 0xF8F0);
 -    sysbus_connect_irq(busdev, 0, cpu_irq);
 +    for (n = 0; n  smp_cpus; n++) {
 +        sysbus_connect_irq(busdev, n, cpu_irq[n]);
 +    }

      for (n = 0; n  64; n++) {
          pic[n] = qdev_get_gpio_in(dev, n);
 @@ -134,7 +174,9 @@ static void zynq_init(ram_addr_t ram_size, const
 char *boot_device,
      zynq_binfo.kernel_filename = kernel_filename;
      zynq_binfo.kernel_cmdline = kernel_cmdline;
      zynq_binfo.initrd_filename = initrd_filename;
 -    zynq_binfo.nb_cpus = 1;
 +    zynq_binfo.nb_cpus = smp_cpus;
 +    zynq_binfo.write_secondary_boot = zynq_write_secondary_boot;
 +    zynq_binfo.secondary_cpu_reset_hook = zynq_reset_secondary;
      zynq_binfo.board_id = 0xd32;
      zynq_binfo.loader_start = 0;
      arm_load_kernel(first_cpu, zynq_binfo);
 @@ -145,7 +187,7 @@ static QEMUMachine zynq_machine = {
      .desc = Xilinx Zynq Platform Baseboard for Cortex-A9,
      .init = zynq_init,
      .use_scsi = 1,
 -    .max_cpus = 1,
 +    .max_cpus = 2,
      .no_sdcard = 1
  };

 --
 1.7.3.2



 This email and any attachments are intended for the sole use of the named 
 recipient(s) and contain(s) confidential information that may be proprietary, 
 privileged or copyrighted under applicable law. If you are not the intended 
 recipient, do not read, copy, or forward this email message or any 
 attachments. Delete this email message and 

Re: [Qemu-devel] [PATCH v1 1/3] xilinx_zynq: added smp support

2012-04-20 Thread Peter Maydell
On 2 April 2012 06:20, Peter A. G. Crosthwaite
peter.crosthwa...@petalogix.com wrote:
 Added linux smp support for the xilinx zynq platform (2x cpus are supported)

 Signed-off-by: Peter A. G. Crosthwaite peter.crosthwa...@petalogix.com
 ---
  hw/xilinx_zynq.c |   64 -
  1 files changed, 53 insertions(+), 11 deletions(-)

 diff --git a/hw/xilinx_zynq.c b/hw/xilinx_zynq.c
 index 7290c64..56d0b96 100644
 --- a/hw/xilinx_zynq.c
 +++ b/hw/xilinx_zynq.c
 @@ -30,6 +30,42 @@

  #define IRQ_OFFSET 32 /* pic interrupts start from index 32 */

 +#define SMP_BOOT_ADDR 0x0fff
 +
 +static void zynq_reset_secondary(CPUARMState *env,
 +                                    const struct arm_boot_info *info)
 +{
 +    env-regs[15] = SMP_BOOT_ADDR;
 +}
 +
 +/* Entry point for secondary CPU */
 +static uint32_t zynq_smpboot[] = {
 +    0xe59f0020, /* ldr     r0, privbase */
 +    0xe3a004FF, /* mov     r0 = 0xFFF0 */
 +    0xe38008FF, /* orr     ...*/
 +    0xe3800CFF, /* orr      */
 +    0xe38000F0, /* orr     . */

These four insns are a rather longwinded way of saying
0xe3ef /* ldr r0, =0xfff0 (mvn r0, #15) */
aren't they?

 +    0xe320f002, /* wfe */
 +    0xe5901000, /* ldr     r1, [r0] */
 +    0xe1110001, /* tst     r1, r1 */
 +    0x0afb, /* beq     wfe */
 +    0xe12fff11, /* bx      r1 */
 +    0,
 +    0
 +};

Who is responsible for resetting the 0xFFF0
location so that on reset the secondary CPUs don't
immediately leave their pen? It looks from a quick glance
like this is in the on-chip RAM, is that right?
(If it is in RAM, then maybe you should be using the
default_reset_secondary() rather than your own version?)

-- PMM



Re: [Qemu-devel] [PATCH v1 1/3] xilinx_zynq: added smp support

2012-04-20 Thread John Linn
 -Original Message-
 From: Peter Crosthwaite [mailto:peter.crosthwa...@petalogix.com]
 Sent: Thursday, April 19, 2012 11:18 PM
 To: John Linn
 Cc: qemu-devel@nongnu.org; p...@codesourcery.com;
 peter.mayd...@linaro.org; edgar.igles...@gmail.com; Duy Le;
 john.willi...@petalogix.com
 Subject: Re: [PATCH v1 1/3] xilinx_zynq: added smp support
 
 Ping!
 
 I realise there were issues with the other patches in this series, but
 this one on its own is self contained and valuable in its own right.
 Can we get a review accordingly?

Sure.

-- John

 
 Regards,
 Peter
 
 On Wed, Apr 11, 2012 at 3:50 AM, John Linn john.l...@xilinx.com wrote:
  -Original Message-
  From: Peter A. G. Crosthwaite
 [mailto:peter.crosthwa...@petalogix.com]
  Sent: Sunday, April 01, 2012 10:20 PM
  To: peter.crosthwa...@petalogix.com; qemu-devel@nongnu.org;
  p...@codesourcery.com; peter.mayd...@linaro.org;
  edgar.igles...@gmail.com
  Cc: Duy Le; John Linn; john.willi...@petalogix.com
  Subject: [PATCH v1 1/3] xilinx_zynq: added smp support
 
  Added linux smp support for the xilinx zynq platform (2x cpus are
  supported)
 
  Signed-off-by: Peter A. G. Crosthwaite
  peter.crosthwa...@petalogix.com
 
  Signed-off-by: John Linn john.l...@xilinx.com
 
  ---
   hw/xilinx_zynq.c |   64
  --
  ---
   1 files changed, 53 insertions(+), 11 deletions(-)
 
  diff --git a/hw/xilinx_zynq.c b/hw/xilinx_zynq.c
  index 7290c64..56d0b96 100644
  --- a/hw/xilinx_zynq.c
  +++ b/hw/xilinx_zynq.c
  @@ -30,6 +30,42 @@
 
   #define IRQ_OFFSET 32 /* pic interrupts start from index 32 */
 
  +#define SMP_BOOT_ADDR 0x0fff
  +
  +static void zynq_reset_secondary(CPUARMState *env,
  +                                    const struct arm_boot_info
 *info)
  +{
  +    env-regs[15] = SMP_BOOT_ADDR;
  +}
  +
  +/* Entry point for secondary CPU */
  +static uint32_t zynq_smpboot[] = {
  +    0xe59f0020, /* ldr     r0, privbase */
  +    0xe3a004FF, /* mov     r0 = 0xFFF0 */
  +    0xe38008FF, /* orr     ...*/
  +    0xe3800CFF, /* orr      */
  +    0xe38000F0, /* orr     . */
  +    0xe320f002, /* wfe */
  +    0xe5901000, /* ldr     r1, [r0] */
  +    0xe1110001, /* tst     r1, r1 */
  +    0x0afb, /* beq     wfe */
  +    0xe12fff11, /* bx      r1 */
  +    0,
  +    0
  +};
  +
  +static void zynq_write_secondary_boot(CPUARMState *env,
  +                                    const struct arm_boot_info
 *info)
  +{
  +    int n;
  +
  +    for (n = 0; n  ARRAY_SIZE(zynq_smpboot); n++) {
  +        zynq_smpboot[n] = tswap32(zynq_smpboot[n]);
  +    }
  +    rom_add_blob_fixed(smpboot, zynq_smpboot,
 sizeof(zynq_smpboot),
  +            SMP_BOOT_ADDR);
  +}
  +
   static struct arm_boot_info zynq_binfo = {};
 
   static void gem_init(NICInfo *nd, uint32_t base, qemu_irq irq)
  @@ -60,19 +96,21 @@ static void zynq_init(ram_addr_t ram_size, const
  char *boot_device,
       qemu_irq pic[64];
       NICInfo *nd;
       int n;
  -    qemu_irq cpu_irq;
  +    qemu_irq cpu_irq[2];
 
       if (!cpu_model) {
           cpu_model = cortex-a9;
       }
 
  -    env = cpu_init(cpu_model);
  -    if (!env) {
  -        fprintf(stderr, Unable to find CPU definition\n);
  -        exit(1);
  +    for (n = 0; n  smp_cpus; n++) {
  +        env = cpu_init(cpu_model);
  +        if (!env) {
  +            fprintf(stderr, Unable to find CPU definition\n);
  +            exit(1);
  +        }
  +        irqp = arm_pic_init_cpu(env);
  +        cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
       }
  -    irqp = arm_pic_init_cpu(env);
  -    cpu_irq = irqp[ARM_PIC_CPU_IRQ];
 
       /* max 2GB ram */
       if (ram_size  0x8000) {
  @@ -103,11 +141,13 @@ static void zynq_init(ram_addr_t ram_size,
 const
  char *boot_device,
       sysbus_mmio_map(sysbus_from_qdev(dev), 0, 0xF800);
 
       dev = qdev_create(NULL, a9mpcore_priv);
  -    qdev_prop_set_uint32(dev, num-cpu, 1);
  +    qdev_prop_set_uint32(dev, num-cpu, smp_cpus);
       qdev_init_nofail(dev);
       busdev = sysbus_from_qdev(dev);
       sysbus_mmio_map(busdev, 0, 0xF8F0);
  -    sysbus_connect_irq(busdev, 0, cpu_irq);
  +    for (n = 0; n  smp_cpus; n++) {
  +        sysbus_connect_irq(busdev, n, cpu_irq[n]);
  +    }
 
       for (n = 0; n  64; n++) {
           pic[n] = qdev_get_gpio_in(dev, n);
  @@ -134,7 +174,9 @@ static void zynq_init(ram_addr_t ram_size, const
  char *boot_device,
       zynq_binfo.kernel_filename = kernel_filename;
       zynq_binfo.kernel_cmdline = kernel_cmdline;
       zynq_binfo.initrd_filename = initrd_filename;
  -    zynq_binfo.nb_cpus = 1;
  +    zynq_binfo.nb_cpus = smp_cpus;
  +    zynq_binfo.write_secondary_boot = zynq_write_secondary_boot;
  +    zynq_binfo.secondary_cpu_reset_hook = zynq_reset_secondary;
       zynq_binfo.board_id = 0xd32;
       zynq_binfo.loader_start = 0;
       arm_load_kernel(first_cpu, zynq_binfo);
  @@ -145,7 +187,7 @@ static QEMUMachine zynq_machine = {
       .desc = Xilinx 

Re: [Qemu-devel] [PATCH v1 1/3] xilinx_zynq: added smp support

2012-04-10 Thread John Linn
 -Original Message-
 From: Peter A. G. Crosthwaite [mailto:peter.crosthwa...@petalogix.com]
 Sent: Sunday, April 01, 2012 10:20 PM
 To: peter.crosthwa...@petalogix.com; qemu-devel@nongnu.org;
 p...@codesourcery.com; peter.mayd...@linaro.org;
 edgar.igles...@gmail.com
 Cc: Duy Le; John Linn; john.willi...@petalogix.com
 Subject: [PATCH v1 1/3] xilinx_zynq: added smp support
 
 Added linux smp support for the xilinx zynq platform (2x cpus are
 supported)
 
 Signed-off-by: Peter A. G. Crosthwaite
 peter.crosthwa...@petalogix.com

Signed-off-by: John Linn john.l...@xilinx.com

 ---
  hw/xilinx_zynq.c |   64
--
 ---
  1 files changed, 53 insertions(+), 11 deletions(-)
 
 diff --git a/hw/xilinx_zynq.c b/hw/xilinx_zynq.c
 index 7290c64..56d0b96 100644
 --- a/hw/xilinx_zynq.c
 +++ b/hw/xilinx_zynq.c
 @@ -30,6 +30,42 @@
 
  #define IRQ_OFFSET 32 /* pic interrupts start from index 32 */
 
 +#define SMP_BOOT_ADDR 0x0fff
 +
 +static void zynq_reset_secondary(CPUARMState *env,
 +const struct arm_boot_info *info)
 +{
 +env-regs[15] = SMP_BOOT_ADDR;
 +}
 +
 +/* Entry point for secondary CPU */
 +static uint32_t zynq_smpboot[] = {
 +0xe59f0020, /* ldr r0, privbase */
 +0xe3a004FF, /* mov r0 = 0xFFF0 */
 +0xe38008FF, /* orr ...*/
 +0xe3800CFF, /* orr  */
 +0xe38000F0, /* orr . */
 +0xe320f002, /* wfe */
 +0xe5901000, /* ldr r1, [r0] */
 +0xe1110001, /* tst r1, r1 */
 +0x0afb, /* beq wfe */
 +0xe12fff11, /* bx  r1 */
 +0,
 +0
 +};
 +
 +static void zynq_write_secondary_boot(CPUARMState *env,
 +const struct arm_boot_info *info)
 +{
 +int n;
 +
 +for (n = 0; n  ARRAY_SIZE(zynq_smpboot); n++) {
 +zynq_smpboot[n] = tswap32(zynq_smpboot[n]);
 +}
 +rom_add_blob_fixed(smpboot, zynq_smpboot, sizeof(zynq_smpboot),
 +SMP_BOOT_ADDR);
 +}
 +
  static struct arm_boot_info zynq_binfo = {};
 
  static void gem_init(NICInfo *nd, uint32_t base, qemu_irq irq)
 @@ -60,19 +96,21 @@ static void zynq_init(ram_addr_t ram_size, const
 char *boot_device,
  qemu_irq pic[64];
  NICInfo *nd;
  int n;
 -qemu_irq cpu_irq;
 +qemu_irq cpu_irq[2];
 
  if (!cpu_model) {
  cpu_model = cortex-a9;
  }
 
 -env = cpu_init(cpu_model);
 -if (!env) {
 -fprintf(stderr, Unable to find CPU definition\n);
 -exit(1);
 +for (n = 0; n  smp_cpus; n++) {
 +env = cpu_init(cpu_model);
 +if (!env) {
 +fprintf(stderr, Unable to find CPU definition\n);
 +exit(1);
 +}
 +irqp = arm_pic_init_cpu(env);
 +cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
  }
 -irqp = arm_pic_init_cpu(env);
 -cpu_irq = irqp[ARM_PIC_CPU_IRQ];
 
  /* max 2GB ram */
  if (ram_size  0x8000) {
 @@ -103,11 +141,13 @@ static void zynq_init(ram_addr_t ram_size, const
 char *boot_device,
  sysbus_mmio_map(sysbus_from_qdev(dev), 0, 0xF800);
 
  dev = qdev_create(NULL, a9mpcore_priv);
 -qdev_prop_set_uint32(dev, num-cpu, 1);
 +qdev_prop_set_uint32(dev, num-cpu, smp_cpus);
  qdev_init_nofail(dev);
  busdev = sysbus_from_qdev(dev);
  sysbus_mmio_map(busdev, 0, 0xF8F0);
 -sysbus_connect_irq(busdev, 0, cpu_irq);
 +for (n = 0; n  smp_cpus; n++) {
 +sysbus_connect_irq(busdev, n, cpu_irq[n]);
 +}
 
  for (n = 0; n  64; n++) {
  pic[n] = qdev_get_gpio_in(dev, n);
 @@ -134,7 +174,9 @@ static void zynq_init(ram_addr_t ram_size, const
 char *boot_device,
  zynq_binfo.kernel_filename = kernel_filename;
  zynq_binfo.kernel_cmdline = kernel_cmdline;
  zynq_binfo.initrd_filename = initrd_filename;
 -zynq_binfo.nb_cpus = 1;
 +zynq_binfo.nb_cpus = smp_cpus;
 +zynq_binfo.write_secondary_boot = zynq_write_secondary_boot;
 +zynq_binfo.secondary_cpu_reset_hook = zynq_reset_secondary;
  zynq_binfo.board_id = 0xd32;
  zynq_binfo.loader_start = 0;
  arm_load_kernel(first_cpu, zynq_binfo);
 @@ -145,7 +187,7 @@ static QEMUMachine zynq_machine = {
  .desc = Xilinx Zynq Platform Baseboard for Cortex-A9,
  .init = zynq_init,
  .use_scsi = 1,
 -.max_cpus = 1,
 +.max_cpus = 2,
  .no_sdcard = 1
  };
 
 --
 1.7.3.2
 


This email and any attachments are intended for the sole use of the named 
recipient(s) and contain(s) confidential information that may be proprietary, 
privileged or copyrighted under applicable law. If you are not the intended 
recipient, do not read, copy, or forward this email message or any attachments. 
Delete this email message and any attachments immediately.





[Qemu-devel] [PATCH v1 1/3] xilinx_zynq: added smp support

2012-04-01 Thread Peter A. G. Crosthwaite
Added linux smp support for the xilinx zynq platform (2x cpus are supported)

Signed-off-by: Peter A. G. Crosthwaite peter.crosthwa...@petalogix.com
---
 hw/xilinx_zynq.c |   64 -
 1 files changed, 53 insertions(+), 11 deletions(-)

diff --git a/hw/xilinx_zynq.c b/hw/xilinx_zynq.c
index 7290c64..56d0b96 100644
--- a/hw/xilinx_zynq.c
+++ b/hw/xilinx_zynq.c
@@ -30,6 +30,42 @@
 
 #define IRQ_OFFSET 32 /* pic interrupts start from index 32 */
 
+#define SMP_BOOT_ADDR 0x0fff
+
+static void zynq_reset_secondary(CPUARMState *env,
+const struct arm_boot_info *info)
+{
+env-regs[15] = SMP_BOOT_ADDR;
+}
+
+/* Entry point for secondary CPU */
+static uint32_t zynq_smpboot[] = {
+0xe59f0020, /* ldr r0, privbase */
+0xe3a004FF, /* mov r0 = 0xFFF0 */
+0xe38008FF, /* orr ...*/
+0xe3800CFF, /* orr  */
+0xe38000F0, /* orr . */
+0xe320f002, /* wfe */
+0xe5901000, /* ldr r1, [r0] */
+0xe1110001, /* tst r1, r1 */
+0x0afb, /* beq wfe */
+0xe12fff11, /* bx  r1 */
+0,
+0
+};
+
+static void zynq_write_secondary_boot(CPUARMState *env,
+const struct arm_boot_info *info)
+{
+int n;
+
+for (n = 0; n  ARRAY_SIZE(zynq_smpboot); n++) {
+zynq_smpboot[n] = tswap32(zynq_smpboot[n]);
+}
+rom_add_blob_fixed(smpboot, zynq_smpboot, sizeof(zynq_smpboot),
+SMP_BOOT_ADDR);
+}
+
 static struct arm_boot_info zynq_binfo = {};
 
 static void gem_init(NICInfo *nd, uint32_t base, qemu_irq irq)
@@ -60,19 +96,21 @@ static void zynq_init(ram_addr_t ram_size, const char 
*boot_device,
 qemu_irq pic[64];
 NICInfo *nd;
 int n;
-qemu_irq cpu_irq;
+qemu_irq cpu_irq[2];
 
 if (!cpu_model) {
 cpu_model = cortex-a9;
 }
 
-env = cpu_init(cpu_model);
-if (!env) {
-fprintf(stderr, Unable to find CPU definition\n);
-exit(1);
+for (n = 0; n  smp_cpus; n++) {
+env = cpu_init(cpu_model);
+if (!env) {
+fprintf(stderr, Unable to find CPU definition\n);
+exit(1);
+}
+irqp = arm_pic_init_cpu(env);
+cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
 }
-irqp = arm_pic_init_cpu(env);
-cpu_irq = irqp[ARM_PIC_CPU_IRQ];
 
 /* max 2GB ram */
 if (ram_size  0x8000) {
@@ -103,11 +141,13 @@ static void zynq_init(ram_addr_t ram_size, const char 
*boot_device,
 sysbus_mmio_map(sysbus_from_qdev(dev), 0, 0xF800);
 
 dev = qdev_create(NULL, a9mpcore_priv);
-qdev_prop_set_uint32(dev, num-cpu, 1);
+qdev_prop_set_uint32(dev, num-cpu, smp_cpus);
 qdev_init_nofail(dev);
 busdev = sysbus_from_qdev(dev);
 sysbus_mmio_map(busdev, 0, 0xF8F0);
-sysbus_connect_irq(busdev, 0, cpu_irq);
+for (n = 0; n  smp_cpus; n++) {
+sysbus_connect_irq(busdev, n, cpu_irq[n]);
+}
 
 for (n = 0; n  64; n++) {
 pic[n] = qdev_get_gpio_in(dev, n);
@@ -134,7 +174,9 @@ static void zynq_init(ram_addr_t ram_size, const char 
*boot_device,
 zynq_binfo.kernel_filename = kernel_filename;
 zynq_binfo.kernel_cmdline = kernel_cmdline;
 zynq_binfo.initrd_filename = initrd_filename;
-zynq_binfo.nb_cpus = 1;
+zynq_binfo.nb_cpus = smp_cpus;
+zynq_binfo.write_secondary_boot = zynq_write_secondary_boot;
+zynq_binfo.secondary_cpu_reset_hook = zynq_reset_secondary;
 zynq_binfo.board_id = 0xd32;
 zynq_binfo.loader_start = 0;
 arm_load_kernel(first_cpu, zynq_binfo);
@@ -145,7 +187,7 @@ static QEMUMachine zynq_machine = {
 .desc = Xilinx Zynq Platform Baseboard for Cortex-A9,
 .init = zynq_init,
 .use_scsi = 1,
-.max_cpus = 1,
+.max_cpus = 2,
 .no_sdcard = 1
 };
 
-- 
1.7.3.2