diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2014-10-24 12:40:28 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2014-10-24 12:40:29 +0100 |
commit | 71b7f54fdfa6a9bd56546b5c3996311b7b836636 (patch) | |
tree | baddcc6aa7092b7dc6d01f97d244d0a4f9f20aae /hw | |
parent | 8b135a288ae8dec2359e9bd410312039da2e7cd2 (diff) | |
parent | dbe9d1636787dd226d3f9a61c07fbc27e0db5bbf (diff) | |
download | qemu-71b7f54fdfa6a9bd56546b5c3996311b7b836636.zip qemu-71b7f54fdfa6a9bd56546b5c3996311b7b836636.tar.gz qemu-71b7f54fdfa6a9bd56546b5c3996311b7b836636.tar.bz2 |
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20141024' into staging
target-arm queue:
* remove pointless 'info pcmcia' and a lot of now-dead code
* register ARM cpu reset handlers even if not using -kernel
* update to libvixl 1.6
* various minor code cleanups
* support PSCI under TCG ('virt' machine can now be shut down,
SMP configurations work)
* correct the sense of the AArch64 DCZID DZP bit
* report a valid L1Ip field in CTR_EL0 for CPU type "any"
* correctly UNDEF writes to FPINST/FPINST2 from EL0
* more preparatory code refactoring for EL2/EL3 support
# gpg: Signature made Fri 24 Oct 2014 12:35:52 BST using RSA key ID 14360CDE
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>"
* remotes/pmaydell/tags/pull-target-arm-20141024: (23 commits)
target-arm: A32: Emulate the SMC instruction
target-arm: make arm_current_el() return EL3
target-arm: rename arm_current_pl to arm_current_el
target-arm: reject switching to monitor mode
target-arm: add arm_is_secure() function
target-arm: increase arrays of registers R13 & R14
target-arm: correctly UNDEF writes to FPINST/FPINST2 from EL0
target-arm: Report a valid L1Ip field in CTR_EL0 for CPU type "any"
target-arm: Correct sense of the DCZID DZP bit
arm/virt: enable PSCI emulation support for system emulation
target-arm: add emulation of PSCI calls for system emulation
target-arm: Add support for A32 and T32 HVC and SMC insns
target-arm: Handle SMC/HVC undef-if-no-ELx in pre_* helpers
target-arm: add missing PSCI constants needed for PSCI emulation
target-arm: do not set do_interrupt handlers for ARM and AArch64 user modes
target-arm: add powered off cpu state
omap_gpmc.c: Remove duplicate assignment
disas/libvixl/a64/instructions-a64.h: Remove unused constants
arm_gic: remove unused parameter.
disas/libvixl: Update to libvixl 1.6
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/arm/boot.c | 17 | ||||
-rw-r--r-- | hw/arm/virt.c | 97 | ||||
-rw-r--r-- | hw/ide/microdrive.c | 1 | ||||
-rw-r--r-- | hw/intc/arm_gic.c | 4 | ||||
-rw-r--r-- | hw/intc/armv7m_nvic.c | 2 | ||||
-rw-r--r-- | hw/intc/gic_internal.h | 2 | ||||
-rw-r--r-- | hw/misc/omap_gpmc.c | 2 | ||||
-rw-r--r-- | hw/pcmcia/pxa2xx.c | 21 |
8 files changed, 66 insertions, 80 deletions
diff --git a/hw/arm/boot.c b/hw/arm/boot.c index c8dc34f..bffbea5 100644 --- a/hw/arm/boot.c +++ b/hw/arm/boot.c @@ -478,7 +478,7 @@ static void do_cpu_reset(void *opaque) void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info) { - CPUState *cs = CPU(cpu); + CPUState *cs; int kernel_size; int initrd_size; int is_linux = 0; @@ -488,6 +488,15 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info) int big_endian; static const ARMInsnFixup *primary_loader; + /* CPU objects (unlike devices) are not automatically reset on system + * reset, so we must always register a handler to do so. If we're + * actually loading a kernel, the handler is also responsible for + * arranging that we start it correctly. + */ + for (cs = CPU(cpu); cs; cs = CPU_NEXT(cs)) { + qemu_register_reset(do_cpu_reset, ARM_CPU(cs)); + } + /* Load the kernel. */ if (!info->kernel_filename) { @@ -652,9 +661,7 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info) } info->is_linux = is_linux; - for (; cs; cs = CPU_NEXT(cs)) { - cpu = ARM_CPU(cs); - cpu->env.boot_info = info; - qemu_register_reset(do_cpu_reset, cpu); + for (cs = CPU(cpu); cs; cs = CPU_NEXT(cs)) { + ARM_CPU(cs)->env.boot_info = info; } } diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 8ea592e..78f618d 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -191,47 +191,48 @@ static void create_fdt(VirtBoardInfo *vbi) static void fdt_add_psci_node(const VirtBoardInfo *vbi) { + uint32_t cpu_suspend_fn; + uint32_t cpu_off_fn; + uint32_t cpu_on_fn; + uint32_t migrate_fn; void *fdt = vbi->fdt; ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(0)); - /* No PSCI for TCG yet */ - if (kvm_enabled()) { - uint32_t cpu_suspend_fn; - uint32_t cpu_off_fn; - uint32_t cpu_on_fn; - uint32_t migrate_fn; - - qemu_fdt_add_subnode(fdt, "/psci"); - if (armcpu->psci_version == 2) { - const char comp[] = "arm,psci-0.2\0arm,psci"; - qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp)); - - cpu_off_fn = QEMU_PSCI_0_2_FN_CPU_OFF; - if (arm_feature(&armcpu->env, ARM_FEATURE_AARCH64)) { - cpu_suspend_fn = QEMU_PSCI_0_2_FN64_CPU_SUSPEND; - cpu_on_fn = QEMU_PSCI_0_2_FN64_CPU_ON; - migrate_fn = QEMU_PSCI_0_2_FN64_MIGRATE; - } else { - cpu_suspend_fn = QEMU_PSCI_0_2_FN_CPU_SUSPEND; - cpu_on_fn = QEMU_PSCI_0_2_FN_CPU_ON; - migrate_fn = QEMU_PSCI_0_2_FN_MIGRATE; - } - } else { - qemu_fdt_setprop_string(fdt, "/psci", "compatible", "arm,psci"); + qemu_fdt_add_subnode(fdt, "/psci"); + if (armcpu->psci_version == 2) { + const char comp[] = "arm,psci-0.2\0arm,psci"; + qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp)); - cpu_suspend_fn = QEMU_PSCI_0_1_FN_CPU_SUSPEND; - cpu_off_fn = QEMU_PSCI_0_1_FN_CPU_OFF; - cpu_on_fn = QEMU_PSCI_0_1_FN_CPU_ON; - migrate_fn = QEMU_PSCI_0_1_FN_MIGRATE; + cpu_off_fn = QEMU_PSCI_0_2_FN_CPU_OFF; + if (arm_feature(&armcpu->env, ARM_FEATURE_AARCH64)) { + cpu_suspend_fn = QEMU_PSCI_0_2_FN64_CPU_SUSPEND; + cpu_on_fn = QEMU_PSCI_0_2_FN64_CPU_ON; + migrate_fn = QEMU_PSCI_0_2_FN64_MIGRATE; + } else { + cpu_suspend_fn = QEMU_PSCI_0_2_FN_CPU_SUSPEND; + cpu_on_fn = QEMU_PSCI_0_2_FN_CPU_ON; + migrate_fn = QEMU_PSCI_0_2_FN_MIGRATE; } + } else { + qemu_fdt_setprop_string(fdt, "/psci", "compatible", "arm,psci"); - qemu_fdt_setprop_string(fdt, "/psci", "method", "hvc"); - - qemu_fdt_setprop_cell(fdt, "/psci", "cpu_suspend", cpu_suspend_fn); - qemu_fdt_setprop_cell(fdt, "/psci", "cpu_off", cpu_off_fn); - qemu_fdt_setprop_cell(fdt, "/psci", "cpu_on", cpu_on_fn); - qemu_fdt_setprop_cell(fdt, "/psci", "migrate", migrate_fn); + cpu_suspend_fn = QEMU_PSCI_0_1_FN_CPU_SUSPEND; + cpu_off_fn = QEMU_PSCI_0_1_FN_CPU_OFF; + cpu_on_fn = QEMU_PSCI_0_1_FN_CPU_ON; + migrate_fn = QEMU_PSCI_0_1_FN_MIGRATE; } + + /* We adopt the PSCI spec's nomenclature, and use 'conduit' to refer + * to the instruction that should be used to invoke PSCI functions. + * However, the device tree binding uses 'method' instead, so that is + * what we should use here. + */ + qemu_fdt_setprop_string(fdt, "/psci", "method", "hvc"); + + qemu_fdt_setprop_cell(fdt, "/psci", "cpu_suspend", cpu_suspend_fn); + qemu_fdt_setprop_cell(fdt, "/psci", "cpu_off", cpu_off_fn); + qemu_fdt_setprop_cell(fdt, "/psci", "cpu_on", cpu_on_fn); + qemu_fdt_setprop_cell(fdt, "/psci", "migrate", migrate_fn); } static void fdt_add_timer_nodes(const VirtBoardInfo *vbi) @@ -240,14 +241,23 @@ static void fdt_add_timer_nodes(const VirtBoardInfo *vbi) * but for the GIC implementation provided by both QEMU and KVM * they are edge-triggered. */ + ARMCPU *armcpu; uint32_t irqflags = GIC_FDT_IRQ_FLAGS_EDGE_LO_HI; irqflags = deposit32(irqflags, GIC_FDT_IRQ_PPI_CPU_START, GIC_FDT_IRQ_PPI_CPU_WIDTH, (1 << vbi->smp_cpus) - 1); qemu_fdt_add_subnode(vbi->fdt, "/timer"); - qemu_fdt_setprop_string(vbi->fdt, "/timer", - "compatible", "arm,armv7-timer"); + + armcpu = ARM_CPU(qemu_get_cpu(0)); + if (arm_feature(&armcpu->env, ARM_FEATURE_V8)) { + const char compat[] = "arm,armv8-timer\0arm,armv7-timer"; + qemu_fdt_setprop(vbi->fdt, "/timer", "compatible", + compat, sizeof(compat)); + } else { + qemu_fdt_setprop_string(vbi->fdt, "/timer", "compatible", + "arm,armv7-timer"); + } qemu_fdt_setprop_cells(vbi->fdt, "/timer", "interrupts", GIC_FDT_IRQ_TYPE_PPI, 13, irqflags, GIC_FDT_IRQ_TYPE_PPI, 14, irqflags, @@ -539,23 +549,12 @@ static void machvirt_init(MachineState *machine) vbi->smp_cpus = smp_cpus; - /* - * Only supported method of starting secondary CPUs is PSCI and - * PSCI is not yet supported with TCG, so limit smp_cpus to 1 - * if we're not using KVM. - */ - if (!kvm_enabled() && smp_cpus > 1) { - error_report("mach-virt: must enable KVM to use multiple CPUs"); - exit(1); - } - if (machine->ram_size > vbi->memmap[VIRT_MEM].size) { error_report("mach-virt: cannot model more than 30GB RAM"); exit(1); } create_fdt(vbi); - fdt_add_timer_nodes(vbi); for (n = 0; n < smp_cpus; n++) { ObjectClass *oc = cpu_class_by_name(TYPE_ARM_CPU, cpu_model); @@ -567,6 +566,9 @@ static void machvirt_init(MachineState *machine) } cpuobj = object_new(object_class_get_name(oc)); + object_property_set_int(cpuobj, QEMU_PSCI_CONDUIT_HVC, "psci-conduit", + NULL); + /* Secondary CPUs start in PSCI powered-down state */ if (n > 0) { object_property_set_bool(cpuobj, true, "start-powered-off", NULL); @@ -579,6 +581,7 @@ static void machvirt_init(MachineState *machine) object_property_set_bool(cpuobj, true, "realized", NULL); } + fdt_add_timer_nodes(vbi); fdt_add_cpu_nodes(vbi); fdt_add_psci_node(vbi); diff --git a/hw/ide/microdrive.c b/hw/ide/microdrive.c index ed85185..6639dd4 100644 --- a/hw/ide/microdrive.c +++ b/hw/ide/microdrive.c @@ -543,7 +543,6 @@ static int dscm1xxxx_attach(PCMCIACardState *card) device_reset(DEVICE(md)); md_interrupt_update(md); - card->slot->card_string = "DSCM-1xxxx Hitachi Microdrive"; return 0; } diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index db9110c..270ce05 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -769,7 +769,7 @@ static const MemoryRegionOps gic_cpu_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; -void gic_init_irqs_and_distributor(GICState *s, int num_irq) +void gic_init_irqs_and_distributor(GICState *s) { SysBusDevice *sbd = SYS_BUS_DEVICE(s); int i; @@ -808,7 +808,7 @@ static void arm_gic_realize(DeviceState *dev, Error **errp) return; } - gic_init_irqs_and_distributor(s, s->num_irq); + gic_init_irqs_and_distributor(s); /* Memory regions for the CPU interfaces (NVIC doesn't have these): * a region for "CPU interface for this core", then a region for diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index 1a7af45..d0543d4 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -488,7 +488,7 @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp) error_propagate(errp, local_err); return; } - gic_init_irqs_and_distributor(&s->gic, s->num_irq); + gic_init_irqs_and_distributor(&s->gic); /* The NVIC and system controller register area looks like this: * 0..0xff : system control registers, including systick * 0x100..0xcff : GIC-like registers diff --git a/hw/intc/gic_internal.h b/hw/intc/gic_internal.h index 48a58d7..e87ef36 100644 --- a/hw/intc/gic_internal.h +++ b/hw/intc/gic_internal.h @@ -59,7 +59,7 @@ void gic_set_pending_private(GICState *s, int cpu, int irq); uint32_t gic_acknowledge_irq(GICState *s, int cpu); void gic_complete_irq(GICState *s, int cpu, int irq); void gic_update(GICState *s); -void gic_init_irqs_and_distributor(GICState *s, int num_irq); +void gic_init_irqs_and_distributor(GICState *s); void gic_set_priority(GICState *s, int cpu, int irq, uint8_t val); static inline bool gic_test_pending(GICState *s, int irq, int cm) diff --git a/hw/misc/omap_gpmc.c b/hw/misc/omap_gpmc.c index fbbe2ff..a0de52f 100644 --- a/hw/misc/omap_gpmc.c +++ b/hw/misc/omap_gpmc.c @@ -466,8 +466,6 @@ void omap_gpmc_reset(struct omap_gpmc_s *s) s->cs_file[i].config[3] = 0x10031003; s->cs_file[i].config[4] = 0x10f1111; s->cs_file[i].config[5] = 0; - s->cs_file[i].config[6] = 0xf00 | (i ? 0 : 1 << 6); - s->cs_file[i].config[6] = 0xf00; /* In theory we could probe attached devices for some CFG1 * bits here, but we just retain them across resets as they diff --git a/hw/pcmcia/pxa2xx.c b/hw/pcmcia/pxa2xx.c index 55e8a2a..a7e1877 100644 --- a/hw/pcmcia/pxa2xx.c +++ b/hw/pcmcia/pxa2xx.c @@ -149,24 +149,11 @@ PXA2xxPCMCIAState *pxa2xx_pcmcia_init(MemoryRegion *sysmem, sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base); s = PXA2XX_PCMCIA(dev); - if (base == 0x30000000) { - s->slot.slot_string = "PXA PC Card Socket 1"; - } else { - s->slot.slot_string = "PXA PC Card Socket 0"; - } - qdev_init_nofail(dev); return s; } -static void pxa2xx_pcmcia_realize(DeviceState *dev, Error **errp) -{ - PXA2xxPCMCIAState *s = PXA2XX_PCMCIA(dev); - - pcmcia_socket_register(&s->slot); -} - static void pxa2xx_pcmcia_initfn(Object *obj) { SysBusDevice *sbd = SYS_BUS_DEVICE(obj); @@ -262,19 +249,11 @@ void pxa2xx_pcmcia_set_irq_cb(void *opaque, qemu_irq irq, qemu_irq cd_irq) s->cd_irq = cd_irq; } -static void pxa2xx_pcmcia_class_init(ObjectClass *oc, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(oc); - - dc->realize = pxa2xx_pcmcia_realize; -} - static const TypeInfo pxa2xx_pcmcia_type_info = { .name = TYPE_PXA2XX_PCMCIA, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(PXA2xxPCMCIAState), .instance_init = pxa2xx_pcmcia_initfn, - .class_init = pxa2xx_pcmcia_class_init, }; static void pxa2xx_pcmcia_register_types(void) |