Re: [Qemu-devel] [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? 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
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
-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
-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
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