:p
atchew
Login
Nothing too exciting, but does include the last bits of v8.1M support work. -- PMM The following changes since commit e79de63ab1bd1f6550e7b915e433bec1ad1a870a: Merge remote-tracking branch 'remotes/rth-gitlab/tags/pull-tcg-20210107' into staging (2021-01-07 20:34:05 +0000) are available in the Git repository at: https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210108 for you to fetch changes up to c9f8511ea8d2b80723af0fea1f716d752c1b5208: docs/system: arm: Add sabrelite board description (2021-01-08 15:13:39 +0000) ---------------------------------------------------------------- target-arm queue: * intc/arm_gic: Fix gic_irq_signaling_enabled() for vCPUs * target/arm: Fix MTE0_ACTIVE * target/arm: Implement v8.1M and Cortex-M55 model * hw/arm/highbank: Drop dead KVM support code * util/qemu-timer: Make timer_free() imply timer_del() * various devices: Use ptimer_free() in finalize function * docs/system: arm: Add sabrelite board description * sabrelite: Minor fixes to allow booting U-Boot ---------------------------------------------------------------- Andrew Jones (1): hw/arm/virt: Remove virt machine state 'smp_cpus' Bin Meng (4): hw/misc: imx6_ccm: Update PMU_MISC0 reset value hw/msic: imx6_ccm: Correct register value for silicon type hw/arm: sabrelite: Connect the Ethernet PHY at address 6 docs/system: arm: Add sabrelite board description Edgar E. Iglesias (1): intc/arm_gic: Fix gic_irq_signaling_enabled() for vCPUs Gan Qixin (7): digic-timer: Use ptimer_free() in the finalize function to avoid memleaks allwinner-a10-pit: Use ptimer_free() in the finalize function to avoid memleaks exynos4210_rtc: Use ptimer_free() in the finalize function to avoid memleaks exynos4210_pwm: Use ptimer_free() in the finalize function to avoid memleaks mss-timer: Use ptimer_free() in the finalize function to avoid memleaks musicpal: Use ptimer_free() in the finalize function to avoid memleaks exynos4210_mct: Use ptimer_free() in the finalize function to avoid memleaks Peter Maydell (9): hw/intc/armv7m_nvic: Correct handling of CCR.BFHFNMIGN target/arm: Correct store of FPSCR value via FPCXT_S target/arm: Implement FPCXT_NS fp system register target/arm: Implement Cortex-M55 model hw/arm/highbank: Drop dead KVM support code util/qemu-timer: Make timer_free() imply timer_del() scripts/coccinelle: New script to remove unnecessary timer_del() calls Remove superfluous timer_del() calls target/arm: Remove timer_del()/timer_deinit() before timer_free() Richard Henderson (1): target/arm: Fix MTE0_ACTIVE docs/system/arm/sabrelite.rst | 119 ++++++++++++++++++++++++++ docs/system/target-arm.rst | 1 + scripts/coccinelle/timer-del-timer-free.cocci | 18 ++++ include/hw/arm/virt.h | 3 +- include/qemu/timer.h | 24 +++--- block/iscsi.c | 2 - block/nbd.c | 1 - block/qcow2.c | 1 - hw/arm/highbank.c | 14 +-- hw/arm/musicpal.c | 12 +++ hw/arm/sabrelite.c | 4 + hw/arm/virt-acpi-build.c | 9 +- hw/arm/virt.c | 21 +++-- hw/block/nvme.c | 2 - hw/char/serial.c | 2 - hw/char/virtio-serial-bus.c | 2 - hw/ide/core.c | 1 - hw/input/hid.c | 1 - hw/intc/apic.c | 1 - hw/intc/arm_gic.c | 4 +- hw/intc/armv7m_nvic.c | 15 ++++ hw/intc/ioapic.c | 1 - hw/ipmi/ipmi_bmc_extern.c | 1 - hw/misc/imx6_ccm.c | 4 +- hw/net/e1000.c | 3 - hw/net/e1000e_core.c | 8 -- hw/net/pcnet-pci.c | 1 - hw/net/rtl8139.c | 1 - hw/net/spapr_llan.c | 1 - hw/net/virtio-net.c | 2 - hw/rtc/exynos4210_rtc.c | 9 ++ hw/s390x/s390-pci-inst.c | 1 - hw/sd/sd.c | 1 - hw/sd/sdhci.c | 2 - hw/timer/allwinner-a10-pit.c | 11 +++ hw/timer/digic-timer.c | 8 ++ hw/timer/exynos4210_mct.c | 14 +++ hw/timer/exynos4210_pwm.c | 11 +++ hw/timer/mss-timer.c | 13 +++ hw/usb/dev-hub.c | 1 - hw/usb/hcd-ehci.c | 1 - hw/usb/hcd-ohci-pci.c | 1 - hw/usb/hcd-uhci.c | 1 - hw/usb/hcd-xhci.c | 1 - hw/usb/redirect.c | 1 - hw/vfio/display.c | 1 - hw/virtio/vhost-vsock-common.c | 1 - hw/virtio/virtio-balloon.c | 1 - hw/virtio/virtio-rng.c | 1 - hw/watchdog/wdt_diag288.c | 1 - hw/watchdog/wdt_i6300esb.c | 1 - migration/colo.c | 1 - monitor/hmp-cmds.c | 1 - net/announce.c | 1 - net/colo-compare.c | 1 - net/slirp.c | 1 - replay/replay-debugging.c | 1 - target/arm/cpu.c | 2 - target/arm/cpu_tcg.c | 42 +++++++++ target/arm/helper.c | 2 +- target/s390x/cpu.c | 2 - ui/console.c | 1 - ui/spice-core.c | 1 - util/throttle.c | 1 - target/arm/translate-vfp.c.inc | 114 ++++++++++++++++++++++-- 65 files changed, 421 insertions(+), 111 deletions(-) create mode 100644 docs/system/arm/sabrelite.rst create mode 100644 scripts/coccinelle/timer-del-timer-free.cocci
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com> Correct the indexing into s->cpu_ctlr for vCPUs. Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Luc Michel <luc.michel@greensocs.com> Message-id: 20201214222154.3480243-2-edgar.iglesias@gmail.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/intc/arm_gic.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index XXXXXXX..XXXXXXX 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -XXX,XX +XXX,XX @@ static inline void gic_get_best_virq(GICState *s, int cpu, static inline bool gic_irq_signaling_enabled(GICState *s, int cpu, bool virt, int group_mask) { + int cpu_iface = virt ? (cpu + GIC_NCPU) : cpu; + if (!virt && !(s->ctlr & group_mask)) { return false; } @@ -XXX,XX +XXX,XX @@ static inline bool gic_irq_signaling_enabled(GICState *s, int cpu, bool virt, return false; } - if (!(s->cpu_ctlr[cpu] & group_mask)) { + if (!(s->cpu_ctlr[cpu_iface] & group_mask)) { return false; } -- 2.20.1
From: Andrew Jones <drjones@redhat.com> virt machine's 'smp_cpus' and machine->smp.cpus must always have the same value. And, anywhere we have virt machine state we have machine state. So let's remove the redundancy. Also, to make it easier to see that machine->smp is the true source for "smp_cpus" and "max_cpus", avoid passing them in function parameters, preferring instead to get them from the state. No functional change intended. Signed-off-by: Andrew Jones <drjones@redhat.com> Reviewed-by: David Edmondson <david.edmondson@oracle.com> Reviewed-by: Ying Fang <fangying1@huawei.com> Message-id: 20201215174815.51520-1-drjones@redhat.com [PMM: minor formatting tweak to smp_cpus variable declaration] Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- include/hw/arm/virt.h | 3 +-- hw/arm/virt-acpi-build.c | 9 +++++---- hw/arm/virt.c | 21 ++++++++++----------- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h index XXXXXXX..XXXXXXX 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -XXX,XX +XXX,XX @@ struct VirtMachineState { MemMapEntry *memmap; char *pciehb_nodename; const int *irqmap; - int smp_cpus; void *fdt; int fdt_size; uint32_t clock_phandle; @@ -XXX,XX +XXX,XX @@ static inline int virt_gicv3_redist_region_count(VirtMachineState *vms) assert(vms->gic_version == VIRT_GIC_VERSION_3); - return vms->smp_cpus > redist0_capacity ? 2 : 1; + return MACHINE(vms)->smp.cpus > redist0_capacity ? 2 : 1; } #endif /* QEMU_ARM_VIRT_H */ diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -XXX,XX +XXX,XX @@ #define ACPI_BUILD_TABLE_SIZE 0x20000 -static void acpi_dsdt_add_cpus(Aml *scope, int smp_cpus) +static void acpi_dsdt_add_cpus(Aml *scope, VirtMachineState *vms) { + MachineState *ms = MACHINE(vms); uint16_t i; - for (i = 0; i < smp_cpus; i++) { + for (i = 0; i < ms->smp.cpus; i++) { Aml *dev = aml_device("C%.03X", i); aml_append(dev, aml_name_decl("_HID", aml_string("ACPI0007"))); aml_append(dev, aml_name_decl("_UID", aml_int(i))); @@ -XXX,XX +XXX,XX @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) gicd->base_address = cpu_to_le64(memmap[VIRT_GIC_DIST].base); gicd->version = vms->gic_version; - for (i = 0; i < vms->smp_cpus; i++) { + for (i = 0; i < MACHINE(vms)->smp.cpus; i++) { AcpiMadtGenericCpuInterface *gicc = acpi_data_push(table_data, sizeof(*gicc)); ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(i)); @@ -XXX,XX +XXX,XX @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) * the RTC ACPI device at all when using UEFI. */ scope = aml_scope("\\_SB"); - acpi_dsdt_add_cpus(scope, vms->smp_cpus); + acpi_dsdt_add_cpus(scope, vms); acpi_dsdt_add_uart(scope, &memmap[VIRT_UART], (irqmap[VIRT_UART] + ARM_SPI_BASE)); if (vmc->acpi_expose_flash) { diff --git a/hw/arm/virt.c b/hw/arm/virt.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -XXX,XX +XXX,XX @@ static void fdt_add_timer_nodes(const VirtMachineState *vms) if (vms->gic_version == VIRT_GIC_VERSION_2) { irqflags = deposit32(irqflags, GIC_FDT_IRQ_PPI_CPU_START, GIC_FDT_IRQ_PPI_CPU_WIDTH, - (1 << vms->smp_cpus) - 1); + (1 << MACHINE(vms)->smp.cpus) - 1); } qemu_fdt_add_subnode(vms->fdt, "/timer"); @@ -XXX,XX +XXX,XX @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms) int cpu; int addr_cells = 1; const MachineState *ms = MACHINE(vms); + int smp_cpus = ms->smp.cpus; /* * From Documentation/devicetree/bindings/arm/cpus.txt @@ -XXX,XX +XXX,XX @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms) * The simplest way to go is to examine affinity IDs of all our CPUs. If * at least one of them has Aff3 populated, we set #address-cells to 2. */ - for (cpu = 0; cpu < vms->smp_cpus; cpu++) { + for (cpu = 0; cpu < smp_cpus; cpu++) { ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(cpu)); if (armcpu->mp_affinity & ARM_AFF3_MASK) { @@ -XXX,XX +XXX,XX @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms) qemu_fdt_setprop_cell(vms->fdt, "/cpus", "#address-cells", addr_cells); qemu_fdt_setprop_cell(vms->fdt, "/cpus", "#size-cells", 0x0); - for (cpu = vms->smp_cpus - 1; cpu >= 0; cpu--) { + for (cpu = smp_cpus - 1; cpu >= 0; cpu--) { char *nodename = g_strdup_printf("/cpus/cpu@%d", cpu); ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(cpu)); CPUState *cs = CPU(armcpu); @@ -XXX,XX +XXX,XX @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms) qemu_fdt_setprop_string(vms->fdt, nodename, "compatible", armcpu->dtb_compatible); - if (vms->psci_conduit != QEMU_PSCI_CONDUIT_DISABLED - && vms->smp_cpus > 1) { + if (vms->psci_conduit != QEMU_PSCI_CONDUIT_DISABLED && smp_cpus > 1) { qemu_fdt_setprop_string(vms->fdt, nodename, "enable-method", "psci"); } @@ -XXX,XX +XXX,XX @@ static void fdt_add_pmu_nodes(const VirtMachineState *vms) if (vms->gic_version == VIRT_GIC_VERSION_2) { irqflags = deposit32(irqflags, GIC_FDT_IRQ_PPI_CPU_START, GIC_FDT_IRQ_PPI_CPU_WIDTH, - (1 << vms->smp_cpus) - 1); + (1 << MACHINE(vms)->smp.cpus) - 1); } qemu_fdt_add_subnode(vms->fdt, "/pmu"); @@ -XXX,XX +XXX,XX @@ static void finalize_gic_version(VirtMachineState *vms) * virt_cpu_post_init() must be called after the CPUs have * been realized and the GIC has been created. */ -static void virt_cpu_post_init(VirtMachineState *vms, int max_cpus, - MemoryRegion *sysmem) +static void virt_cpu_post_init(VirtMachineState *vms, MemoryRegion *sysmem) { + int max_cpus = MACHINE(vms)->smp.max_cpus; bool aarch64, pmu, steal_time; CPUState *cpu; @@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine) exit(1); } - vms->smp_cpus = smp_cpus; - if (vms->virt && kvm_enabled()) { error_report("mach-virt: KVM does not support providing " "Virtualization extensions to the guest CPU"); @@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine) create_fdt(vms); possible_cpus = mc->possible_cpu_arch_ids(machine); + assert(possible_cpus->len == max_cpus); for (n = 0; n < possible_cpus->len; n++) { Object *cpuobj; CPUState *cs; @@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine) create_gic(vms); - virt_cpu_post_init(vms, possible_cpus->len, sysmem); + virt_cpu_post_init(vms, sysmem); fdt_add_pmu_nodes(vms); -- 2.20.1
From: Richard Henderson <richard.henderson@linaro.org> In 50244cc76abc we updated mte_check_fail to match the ARM pseudocode, using the correct EL to select the TCF field. But we failed to update MTE0_ACTIVE the same way, which led to g_assert_not_reached(). Cc: qemu-stable@nongnu.org Buglink: https://bugs.launchpad.net/bugs/1907137 Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20201221204426.88514-1-richard.henderson@linaro.org Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- target/arm/helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/arm/helper.c b/target/arm/helper.c index XXXXXXX..XXXXXXX 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el, if (FIELD_EX32(flags, TBFLAG_A64, UNPRIV) && tbid && !(env->pstate & PSTATE_TCO) - && (sctlr & SCTLR_TCF0) + && (sctlr & SCTLR_TCF) && allocation_tag_access_enabled(env, 0, sctlr)) { flags = FIELD_DP32(flags, TBFLAG_A64, MTE0_ACTIVE, 1); } -- 2.20.1
The CCR is a register most of whose bits are banked between security states but where BFHFNMIGN is not, and we keep it in the non-secure entry of the v7m.ccr[] array. The logic which tries to handle this bit fails to implement the "RAZ/WI from Nonsecure if AIRCR.BFHFNMINS is zero" requirement; correct the omission. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20201210201433.26262-2-peter.maydell@linaro.org --- hw/intc/armv7m_nvic.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index XXXXXXX..XXXXXXX 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs) */ val = cpu->env.v7m.ccr[attrs.secure]; val |= cpu->env.v7m.ccr[M_REG_NS] & R_V7M_CCR_BFHFNMIGN_MASK; + /* BFHFNMIGN is RAZ/WI from NS if AIRCR.BFHFNMINS is 0 */ + if (!attrs.secure) { + if (!(cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) { + val &= ~R_V7M_CCR_BFHFNMIGN_MASK; + } + } return val; case 0xd24: /* System Handler Control and State (SHCSR) */ if (!arm_feature(&cpu->env, ARM_FEATURE_V7)) { @@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value, (cpu->env.v7m.ccr[M_REG_NS] & ~R_V7M_CCR_BFHFNMIGN_MASK) | (value & R_V7M_CCR_BFHFNMIGN_MASK); value &= ~R_V7M_CCR_BFHFNMIGN_MASK; + } else { + /* + * BFHFNMIGN is RAZ/WI from NS if AIRCR.BFHFNMINS is 0, so + * preserve the state currently in the NS element of the array + */ + if (!(cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) { + value &= ~R_V7M_CCR_BFHFNMIGN_MASK; + value |= cpu->env.v7m.ccr[M_REG_NS] & R_V7M_CCR_BFHFNMIGN_MASK; + } } cpu->env.v7m.ccr[attrs.secure] = value; -- 2.20.1
In commit 64f863baeedc8659 we implemented the v8.1M FPCXT_S register, but we got the write behaviour wrong. On read, this register reads bits [27:0] of FPSCR plus the CONTROL.SFPA bit. On write, it doesn't just write back those bits -- it writes a value to the whole FPSCR, whose upper 4 bits are zeroes. We also incorrectly implemented the write-to-FPSCR as a simple store to vfp.xregs; this skips the "update the softfloat flags" part of the vfp_set_fpscr helper so the value would read back correctly but not actually take effect. Fix both of these things by doing a complete write to the FPSCR using the helper function. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20201210201433.26262-3-peter.maydell@linaro.org --- target/arm/translate-vfp.c.inc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc index XXXXXXX..XXXXXXX 100644 --- a/target/arm/translate-vfp.c.inc +++ b/target/arm/translate-vfp.c.inc @@ -XXX,XX +XXX,XX @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int regno, } case ARM_VFP_FPCXT_S: { - TCGv_i32 sfpa, control, fpscr; - /* Set FPSCR[27:0] and CONTROL.SFPA from value */ + TCGv_i32 sfpa, control; + /* + * Set FPSCR and CONTROL.SFPA from value; the new FPSCR takes + * bits [27:0] from value and zeroes bits [31:28]. + */ tmp = loadfn(s, opaque); sfpa = tcg_temp_new_i32(); tcg_gen_shri_i32(sfpa, tmp, 31); @@ -XXX,XX +XXX,XX @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int regno, tcg_gen_deposit_i32(control, control, sfpa, R_V7M_CONTROL_SFPA_SHIFT, 1); store_cpu_field(control, v7m.control[M_REG_S]); - fpscr = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]); - tcg_gen_andi_i32(fpscr, fpscr, FPCR_NZCV_MASK); tcg_gen_andi_i32(tmp, tmp, ~FPCR_NZCV_MASK); - tcg_gen_or_i32(fpscr, fpscr, tmp); - store_cpu_field(fpscr, vfp.xregs[ARM_VFP_FPSCR]); + gen_helper_vfp_set_fpscr(cpu_env, tmp); tcg_temp_free_i32(tmp); tcg_temp_free_i32(sfpa); break; -- 2.20.1
Implement the v8.1M FPCXT_NS floating-point system register. This is a little more complicated than FPCXT_S, because it has specific handling for "current FP state is inactive", and it only wants to do PreserveFPState(), not the full set of actions done by ExecuteFPCheck() which vfp_access_check() implements. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20201210201433.26262-4-peter.maydell@linaro.org --- target/arm/translate-vfp.c.inc | 102 ++++++++++++++++++++++++++++++++- 1 file changed, 99 insertions(+), 3 deletions(-) diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc index XXXXXXX..XXXXXXX 100644 --- a/target/arm/translate-vfp.c.inc +++ b/target/arm/translate-vfp.c.inc @@ -XXX,XX +XXX,XX @@ static FPSysRegCheckResult fp_sysreg_checks(DisasContext *s, int regno) } break; case ARM_VFP_FPCXT_S: + case ARM_VFP_FPCXT_NS: if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) { return false; } @@ -XXX,XX +XXX,XX @@ static FPSysRegCheckResult fp_sysreg_checks(DisasContext *s, int regno) return FPSysRegCheckFailed; } - if (!vfp_access_check(s)) { + /* + * FPCXT_NS is a special case: it has specific handling for + * "current FP state is inactive", and must do the PreserveFPState() + * but not the usual full set of actions done by ExecuteFPCheck(). + * So we don't call vfp_access_check() and the callers must handle this. + */ + if (regno != ARM_VFP_FPCXT_NS && !vfp_access_check(s)) { return FPSysRegCheckDone; } - return FPSysRegCheckContinue; } +static void gen_branch_fpInactive(DisasContext *s, TCGCond cond, + TCGLabel *label) +{ + /* + * FPCXT_NS is a special case: it has specific handling for + * "current FP state is inactive", and must do the PreserveFPState() + * but not the usual full set of actions done by ExecuteFPCheck(). + * We don't have a TB flag that matches the fpInactive check, so we + * do it at runtime as we don't expect FPCXT_NS accesses to be frequent. + * + * Emit code that checks fpInactive and does a conditional + * branch to label based on it: + * if cond is TCG_COND_NE then branch if fpInactive != 0 (ie if inactive) + * if cond is TCG_COND_EQ then branch if fpInactive == 0 (ie if active) + */ + assert(cond == TCG_COND_EQ || cond == TCG_COND_NE); + + /* fpInactive = FPCCR_NS.ASPEN == 1 && CONTROL.FPCA == 0 */ + TCGv_i32 aspen, fpca; + aspen = load_cpu_field(v7m.fpccr[M_REG_NS]); + fpca = load_cpu_field(v7m.control[M_REG_S]); + tcg_gen_andi_i32(aspen, aspen, R_V7M_FPCCR_ASPEN_MASK); + tcg_gen_xori_i32(aspen, aspen, R_V7M_FPCCR_ASPEN_MASK); + tcg_gen_andi_i32(fpca, fpca, R_V7M_CONTROL_FPCA_MASK); + tcg_gen_or_i32(fpca, fpca, aspen); + tcg_gen_brcondi_i32(tcg_invert_cond(cond), fpca, 0, label); + tcg_temp_free_i32(aspen); + tcg_temp_free_i32(fpca); +} + static bool gen_M_fp_sysreg_write(DisasContext *s, int regno, fp_sysreg_loadfn *loadfn, @@ -XXX,XX +XXX,XX @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int regno, { /* Do a write to an M-profile floating point system register */ TCGv_i32 tmp; + TCGLabel *lab_end = NULL; switch (fp_sysreg_checks(s, regno)) { case FPSysRegCheckFailed: @@ -XXX,XX +XXX,XX @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int regno, tcg_temp_free_i32(tmp); break; } + case ARM_VFP_FPCXT_NS: + lab_end = gen_new_label(); + /* fpInactive case: write is a NOP, so branch to end */ + gen_branch_fpInactive(s, TCG_COND_NE, lab_end); + /* !fpInactive: PreserveFPState(), and reads same as FPCXT_S */ + gen_preserve_fp_state(s); + /* fall through */ case ARM_VFP_FPCXT_S: { TCGv_i32 sfpa, control; @@ -XXX,XX +XXX,XX @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int regno, default: g_assert_not_reached(); } + if (lab_end) { + gen_set_label(lab_end); + } return true; } @@ -XXX,XX +XXX,XX @@ static bool gen_M_fp_sysreg_read(DisasContext *s, int regno, { /* Do a read from an M-profile floating point system register */ TCGv_i32 tmp; + TCGLabel *lab_end = NULL; + bool lookup_tb = false; switch (fp_sysreg_checks(s, regno)) { case FPSysRegCheckFailed: @@ -XXX,XX +XXX,XX @@ static bool gen_M_fp_sysreg_read(DisasContext *s, int regno, fpscr = load_cpu_field(v7m.fpdscr[M_REG_NS]); gen_helper_vfp_set_fpscr(cpu_env, fpscr); tcg_temp_free_i32(fpscr); - gen_lookup_tb(s); + lookup_tb = true; + break; + } + case ARM_VFP_FPCXT_NS: + { + TCGv_i32 control, sfpa, fpscr, fpdscr, zero; + TCGLabel *lab_active = gen_new_label(); + + lookup_tb = true; + + gen_branch_fpInactive(s, TCG_COND_EQ, lab_active); + /* fpInactive case: reads as FPDSCR_NS */ + TCGv_i32 tmp = load_cpu_field(v7m.fpdscr[M_REG_NS]); + storefn(s, opaque, tmp); + lab_end = gen_new_label(); + tcg_gen_br(lab_end); + + gen_set_label(lab_active); + /* !fpInactive: Reads the same as FPCXT_S, but side effects differ */ + gen_preserve_fp_state(s); + tmp = tcg_temp_new_i32(); + sfpa = tcg_temp_new_i32(); + fpscr = tcg_temp_new_i32(); + gen_helper_vfp_get_fpscr(fpscr, cpu_env); + tcg_gen_andi_i32(tmp, fpscr, ~FPCR_NZCV_MASK); + control = load_cpu_field(v7m.control[M_REG_S]); + tcg_gen_andi_i32(sfpa, control, R_V7M_CONTROL_SFPA_MASK); + tcg_gen_shli_i32(sfpa, sfpa, 31 - R_V7M_CONTROL_SFPA_SHIFT); + tcg_gen_or_i32(tmp, tmp, sfpa); + tcg_temp_free_i32(control); + /* Store result before updating FPSCR, in case it faults */ + storefn(s, opaque, tmp); + /* If SFPA is zero then set FPSCR from FPDSCR_NS */ + fpdscr = load_cpu_field(v7m.fpdscr[M_REG_NS]); + zero = tcg_const_i32(0); + tcg_gen_movcond_i32(TCG_COND_EQ, fpscr, sfpa, zero, fpdscr, fpscr); + gen_helper_vfp_set_fpscr(cpu_env, fpscr); + tcg_temp_free_i32(zero); + tcg_temp_free_i32(sfpa); + tcg_temp_free_i32(fpdscr); + tcg_temp_free_i32(fpscr); break; } default: g_assert_not_reached(); } + + if (lab_end) { + gen_set_label(lab_end); + } + if (lookup_tb) { + gen_lookup_tb(s); + } return true; } -- 2.20.1
Now that we have implemented all the features needed by the v8.1M architecture, we can add the model of the Cortex-M55. This is the configuration without MVE support; we'll add MVE later. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20201210201433.26262-5-peter.maydell@linaro.org --- target/arm/cpu_tcg.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c index XXXXXXX..XXXXXXX 100644 --- a/target/arm/cpu_tcg.c +++ b/target/arm/cpu_tcg.c @@ -XXX,XX +XXX,XX @@ static void cortex_m33_initfn(Object *obj) cpu->ctr = 0x8000c000; } +static void cortex_m55_initfn(Object *obj) +{ + ARMCPU *cpu = ARM_CPU(obj); + + set_feature(&cpu->env, ARM_FEATURE_V8); + set_feature(&cpu->env, ARM_FEATURE_V8_1M); + set_feature(&cpu->env, ARM_FEATURE_M); + set_feature(&cpu->env, ARM_FEATURE_M_MAIN); + set_feature(&cpu->env, ARM_FEATURE_M_SECURITY); + set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP); + cpu->midr = 0x410fd221; /* r0p1 */ + cpu->revidr = 0; + cpu->pmsav7_dregion = 16; + cpu->sau_sregion = 8; + /* + * These are the MVFR* values for the FPU, no MVE configuration; + * we will update them later when we implement MVE + */ + cpu->isar.mvfr0 = 0x10110221; + cpu->isar.mvfr1 = 0x12100011; + cpu->isar.mvfr2 = 0x00000040; + cpu->isar.id_pfr0 = 0x20000030; + cpu->isar.id_pfr1 = 0x00000230; + cpu->isar.id_dfr0 = 0x10200000; + cpu->id_afr0 = 0x00000000; + cpu->isar.id_mmfr0 = 0x00111040; + cpu->isar.id_mmfr1 = 0x00000000; + cpu->isar.id_mmfr2 = 0x01000000; + cpu->isar.id_mmfr3 = 0x00000011; + cpu->isar.id_isar0 = 0x01103110; + cpu->isar.id_isar1 = 0x02212000; + cpu->isar.id_isar2 = 0x20232232; + cpu->isar.id_isar3 = 0x01111131; + cpu->isar.id_isar4 = 0x01310132; + cpu->isar.id_isar5 = 0x00000000; + cpu->isar.id_isar6 = 0x00000000; + cpu->clidr = 0x00000000; /* caches not implemented */ + cpu->ctr = 0x8303c003; +} + static const ARMCPRegInfo cortexr5_cp_reginfo[] = { /* Dummy the TCM region regs for the moment */ { .name = "ATCM", .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 0, @@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_tcg_cpus[] = { .class_init = arm_v7m_class_init }, { .name = "cortex-m33", .initfn = cortex_m33_initfn, .class_init = arm_v7m_class_init }, + { .name = "cortex-m55", .initfn = cortex_m55_initfn, + .class_init = arm_v7m_class_init }, { .name = "cortex-r5", .initfn = cortex_r5_initfn }, { .name = "cortex-r5f", .initfn = cortex_r5f_initfn }, { .name = "ti925t", .initfn = ti925t_initfn }, -- 2.20.1
Support for running KVM on 32-bit Arm hosts was removed in commit 82bf7ae84ce739e. You can still run a 32-bit guest on a 64-bit Arm host CPU, but because Arm KVM requires the host and guest CPU types to match, it is not possible to run a guest that requires a Cortex-A9 or Cortex-A15 CPU there. That means that the code in the highbank/midway board models to support KVM is no longer used, and we can delete it. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Message-id: 20201215144215.28482-1-peter.maydell@linaro.org --- hw/arm/highbank.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/highbank.c +++ b/hw/arm/highbank.c @@ -XXX,XX +XXX,XX @@ #include "hw/arm/boot.h" #include "hw/loader.h" #include "net/net.h" -#include "sysemu/kvm.h" #include "sysemu/runstate.h" #include "sysemu/sysemu.h" #include "hw/boards.h" @@ -XXX,XX +XXX,XX @@ #include "hw/cpu/a15mpcore.h" #include "qemu/log.h" #include "qom/object.h" +#include "cpu.h" #define SMP_BOOT_ADDR 0x100 #define SMP_BOOT_REG 0x40 @@ -XXX,XX +XXX,XX @@ static void calxeda_init(MachineState *machine, enum cxmachines machine_id) highbank_binfo.loader_start = 0; highbank_binfo.write_secondary_boot = hb_write_secondary; highbank_binfo.secondary_cpu_reset_hook = hb_reset_secondary; - if (!kvm_enabled()) { - highbank_binfo.board_setup_addr = BOARD_SETUP_ADDR; - highbank_binfo.write_board_setup = hb_write_board_setup; - highbank_binfo.secure_board_setup = true; - } else { - warn_report("cannot load built-in Monitor support " - "if KVM is enabled. Some guests (such as Linux) " - "may not boot."); - } + highbank_binfo.board_setup_addr = BOARD_SETUP_ADDR; + highbank_binfo.write_board_setup = hb_write_board_setup; + highbank_binfo.secure_board_setup = true; arm_load_kernel(ARM_CPU(first_cpu), machine, &highbank_binfo); } -- 2.20.1
Currently timer_free() is a simple wrapper for g_free(). This means that the timer being freed must not be currently active, as otherwise QEMU might crash later when the active list is processed and still has a pointer to freed memory on it. As a result almost all calls to timer_free() are preceded by a timer_del() call, as can be seen in the output of git grep -B1 '\<timer_free\>' This is unfortunate API design as it makes it easy to accidentally misuse (by forgetting the timer_del()), and the correct use is annoyingly verbose. Make timer_free() imply a timer_del(). Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20201215154107.3255-2-peter.maydell@linaro.org --- include/qemu/timer.h | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/include/qemu/timer.h b/include/qemu/timer.h index XXXXXXX..XXXXXXX 100644 --- a/include/qemu/timer.h +++ b/include/qemu/timer.h @@ -XXX,XX +XXX,XX @@ static inline QEMUTimer *timer_new_ms(QEMUClockType type, QEMUTimerCB *cb, */ void timer_deinit(QEMUTimer *ts); -/** - * timer_free: - * @ts: the timer - * - * Free a timer (it must not be on the active list) - */ -static inline void timer_free(QEMUTimer *ts) -{ - g_free(ts); -} - /** * timer_del: * @ts: the timer @@ -XXX,XX +XXX,XX @@ static inline void timer_free(QEMUTimer *ts) */ void timer_del(QEMUTimer *ts); +/** + * timer_free: + * @ts: the timer + * + * Free a timer. This will call timer_del() for you to remove + * the timer from the active list if it was still active. + */ +static inline void timer_free(QEMUTimer *ts) +{ + timer_del(ts); + g_free(ts); +} + /** * timer_mod_ns: * @ts: the timer -- 2.20.1
Now that timer_free() implicitly calls timer_del(), sequences timer_del(mytimer); timer_free(mytimer); can be simplified to just timer_free(mytimer); Add a Coccinelle script to do this transformation. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Acked-by: Paolo Bonzini <pbonzini@redhat.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20201215154107.3255-3-peter.maydell@linaro.org --- scripts/coccinelle/timer-del-timer-free.cocci | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 scripts/coccinelle/timer-del-timer-free.cocci diff --git a/scripts/coccinelle/timer-del-timer-free.cocci b/scripts/coccinelle/timer-del-timer-free.cocci new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/scripts/coccinelle/timer-del-timer-free.cocci @@ -XXX,XX +XXX,XX @@ +// Remove superfluous timer_del() calls +// +// Copyright Linaro Limited 2020 +// This work is licensed under the terms of the GNU GPLv2 or later. +// +// spatch --macro-file scripts/cocci-macro-file.h \ +// --sp-file scripts/coccinelle/timer-del-timer-free.cocci \ +// --in-place --dir . +// +// The timer_free() function now implicitly calls timer_del() +// for you, so calls to timer_del() immediately before the +// timer_free() of the same timer can be deleted. + +@@ +expression T; +@@ +-timer_del(T); + timer_free(T); -- 2.20.1
This commit is the result of running the timer-del-timer-free.cocci script on the whole source tree. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Acked-by: Corey Minyard <cminyard@mvista.com> Acked-by: Paolo Bonzini <pbonzini@redhat.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20201215154107.3255-4-peter.maydell@linaro.org --- block/iscsi.c | 2 -- block/nbd.c | 1 - block/qcow2.c | 1 - hw/block/nvme.c | 2 -- hw/char/serial.c | 2 -- hw/char/virtio-serial-bus.c | 2 -- hw/ide/core.c | 1 - hw/input/hid.c | 1 - hw/intc/apic.c | 1 - hw/intc/ioapic.c | 1 - hw/ipmi/ipmi_bmc_extern.c | 1 - hw/net/e1000.c | 3 --- hw/net/e1000e_core.c | 8 -------- hw/net/pcnet-pci.c | 1 - hw/net/rtl8139.c | 1 - hw/net/spapr_llan.c | 1 - hw/net/virtio-net.c | 2 -- hw/s390x/s390-pci-inst.c | 1 - hw/sd/sd.c | 1 - hw/sd/sdhci.c | 2 -- hw/usb/dev-hub.c | 1 - hw/usb/hcd-ehci.c | 1 - hw/usb/hcd-ohci-pci.c | 1 - hw/usb/hcd-uhci.c | 1 - hw/usb/hcd-xhci.c | 1 - hw/usb/redirect.c | 1 - hw/vfio/display.c | 1 - hw/virtio/vhost-vsock-common.c | 1 - hw/virtio/virtio-balloon.c | 1 - hw/virtio/virtio-rng.c | 1 - hw/watchdog/wdt_diag288.c | 1 - hw/watchdog/wdt_i6300esb.c | 1 - migration/colo.c | 1 - monitor/hmp-cmds.c | 1 - net/announce.c | 1 - net/colo-compare.c | 1 - net/slirp.c | 1 - replay/replay-debugging.c | 1 - target/s390x/cpu.c | 2 -- ui/console.c | 1 - ui/spice-core.c | 1 - util/throttle.c | 1 - 42 files changed, 58 deletions(-) diff --git a/block/iscsi.c b/block/iscsi.c index XXXXXXX..XXXXXXX 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -XXX,XX +XXX,XX @@ static void iscsi_detach_aio_context(BlockDriverState *bs) iscsilun->events = 0; if (iscsilun->nop_timer) { - timer_del(iscsilun->nop_timer); timer_free(iscsilun->nop_timer); iscsilun->nop_timer = NULL; } if (iscsilun->event_timer) { - timer_del(iscsilun->event_timer); timer_free(iscsilun->event_timer); iscsilun->event_timer = NULL; } diff --git a/block/nbd.c b/block/nbd.c index XXXXXXX..XXXXXXX 100644 --- a/block/nbd.c +++ b/block/nbd.c @@ -XXX,XX +XXX,XX @@ static void nbd_recv_coroutines_wake_all(BDRVNBDState *s) static void reconnect_delay_timer_del(BDRVNBDState *s) { if (s->reconnect_delay_timer) { - timer_del(s->reconnect_delay_timer); timer_free(s->reconnect_delay_timer); s->reconnect_delay_timer = NULL; } diff --git a/block/qcow2.c b/block/qcow2.c index XXXXXXX..XXXXXXX 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -XXX,XX +XXX,XX @@ static void cache_clean_timer_del(BlockDriverState *bs) { BDRVQcow2State *s = bs->opaque; if (s->cache_clean_timer) { - timer_del(s->cache_clean_timer); timer_free(s->cache_clean_timer); s->cache_clean_timer = NULL; } diff --git a/hw/block/nvme.c b/hw/block/nvme.c index XXXXXXX..XXXXXXX 100644 --- a/hw/block/nvme.c +++ b/hw/block/nvme.c @@ -XXX,XX +XXX,XX @@ static uint16_t nvme_io_cmd(NvmeCtrl *n, NvmeRequest *req) static void nvme_free_sq(NvmeSQueue *sq, NvmeCtrl *n) { n->sq[sq->sqid] = NULL; - timer_del(sq->timer); timer_free(sq->timer); g_free(sq->io_req); if (sq->sqid) { @@ -XXX,XX +XXX,XX @@ static uint16_t nvme_get_log(NvmeCtrl *n, NvmeRequest *req) static void nvme_free_cq(NvmeCQueue *cq, NvmeCtrl *n) { n->cq[cq->cqid] = NULL; - timer_del(cq->timer); timer_free(cq->timer); msix_vector_unuse(&n->parent_obj, cq->vector); if (cq->cqid) { diff --git a/hw/char/serial.c b/hw/char/serial.c index XXXXXXX..XXXXXXX 100644 --- a/hw/char/serial.c +++ b/hw/char/serial.c @@ -XXX,XX +XXX,XX @@ static void serial_unrealize(DeviceState *dev) qemu_chr_fe_deinit(&s->chr, false); - timer_del(s->modem_status_poll); timer_free(s->modem_status_poll); - timer_del(s->fifo_timeout_timer); timer_free(s->fifo_timeout_timer); fifo8_destroy(&s->recv_fifo); diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c index XXXXXXX..XXXXXXX 100644 --- a/hw/char/virtio-serial-bus.c +++ b/hw/char/virtio-serial-bus.c @@ -XXX,XX +XXX,XX @@ static void virtio_serial_post_load_timer_cb(void *opaque) } } g_free(s->post_load->connected); - timer_del(s->post_load->timer); timer_free(s->post_load->timer); g_free(s->post_load); s->post_load = NULL; @@ -XXX,XX +XXX,XX @@ static void virtio_serial_device_unrealize(DeviceState *dev) g_free(vser->ports_map); if (vser->post_load) { g_free(vser->post_load->connected); - timer_del(vser->post_load->timer); timer_free(vser->post_load->timer); g_free(vser->post_load); } diff --git a/hw/ide/core.c b/hw/ide/core.c index XXXXXXX..XXXXXXX 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -XXX,XX +XXX,XX @@ void ide_init2(IDEBus *bus, qemu_irq irq) void ide_exit(IDEState *s) { - timer_del(s->sector_write_timer); timer_free(s->sector_write_timer); qemu_vfree(s->smart_selftest_data); qemu_vfree(s->io_buffer); diff --git a/hw/input/hid.c b/hw/input/hid.c index XXXXXXX..XXXXXXX 100644 --- a/hw/input/hid.c +++ b/hw/input/hid.c @@ -XXX,XX +XXX,XX @@ static void hid_idle_timer(void *opaque) static void hid_del_idle_timer(HIDState *hs) { if (hs->idle_timer) { - timer_del(hs->idle_timer); timer_free(hs->idle_timer); hs->idle_timer = NULL; } diff --git a/hw/intc/apic.c b/hw/intc/apic.c index XXXXXXX..XXXXXXX 100644 --- a/hw/intc/apic.c +++ b/hw/intc/apic.c @@ -XXX,XX +XXX,XX @@ static void apic_unrealize(DeviceState *dev) { APICCommonState *s = APIC(dev); - timer_del(s->timer); timer_free(s->timer); local_apics[s->id] = NULL; } diff --git a/hw/intc/ioapic.c b/hw/intc/ioapic.c index XXXXXXX..XXXXXXX 100644 --- a/hw/intc/ioapic.c +++ b/hw/intc/ioapic.c @@ -XXX,XX +XXX,XX @@ static void ioapic_unrealize(DeviceState *dev) { IOAPICCommonState *s = IOAPIC_COMMON(dev); - timer_del(s->delayed_ioapic_service_timer); timer_free(s->delayed_ioapic_service_timer); } diff --git a/hw/ipmi/ipmi_bmc_extern.c b/hw/ipmi/ipmi_bmc_extern.c index XXXXXXX..XXXXXXX 100644 --- a/hw/ipmi/ipmi_bmc_extern.c +++ b/hw/ipmi/ipmi_bmc_extern.c @@ -XXX,XX +XXX,XX @@ static void ipmi_bmc_extern_finalize(Object *obj) { IPMIBmcExtern *ibe = IPMI_BMC_EXTERN(obj); - timer_del(ibe->extern_timer); timer_free(ibe->extern_timer); } diff --git a/hw/net/e1000.c b/hw/net/e1000.c index XXXXXXX..XXXXXXX 100644 --- a/hw/net/e1000.c +++ b/hw/net/e1000.c @@ -XXX,XX +XXX,XX @@ pci_e1000_uninit(PCIDevice *dev) { E1000State *d = E1000(dev); - timer_del(d->autoneg_timer); timer_free(d->autoneg_timer); - timer_del(d->mit_timer); timer_free(d->mit_timer); - timer_del(d->flush_queue_timer); timer_free(d->flush_queue_timer); qemu_del_nic(d->nic); } diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c index XXXXXXX..XXXXXXX 100644 --- a/hw/net/e1000e_core.c +++ b/hw/net/e1000e_core.c @@ -XXX,XX +XXX,XX @@ e1000e_intrmgr_pci_unint(E1000ECore *core) { int i; - timer_del(core->radv.timer); timer_free(core->radv.timer); - timer_del(core->rdtr.timer); timer_free(core->rdtr.timer); - timer_del(core->raid.timer); timer_free(core->raid.timer); - timer_del(core->tadv.timer); timer_free(core->tadv.timer); - timer_del(core->tidv.timer); timer_free(core->tidv.timer); - timer_del(core->itr.timer); timer_free(core->itr.timer); for (i = 0; i < E1000E_MSIX_VEC_NUM; i++) { - timer_del(core->eitr[i].timer); timer_free(core->eitr[i].timer); } } @@ -XXX,XX +XXX,XX @@ e1000e_core_pci_uninit(E1000ECore *core) { int i; - timer_del(core->autoneg_timer); timer_free(core->autoneg_timer); e1000e_intrmgr_pci_unint(core); diff --git a/hw/net/pcnet-pci.c b/hw/net/pcnet-pci.c index XXXXXXX..XXXXXXX 100644 --- a/hw/net/pcnet-pci.c +++ b/hw/net/pcnet-pci.c @@ -XXX,XX +XXX,XX @@ static void pci_pcnet_uninit(PCIDevice *dev) PCIPCNetState *d = PCI_PCNET(dev); qemu_free_irq(d->state.irq); - timer_del(d->state.poll_timer); timer_free(d->state.poll_timer); qemu_del_nic(d->state.nic); } diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c index XXXXXXX..XXXXXXX 100644 --- a/hw/net/rtl8139.c +++ b/hw/net/rtl8139.c @@ -XXX,XX +XXX,XX @@ static void pci_rtl8139_uninit(PCIDevice *dev) g_free(s->cplus_txbuffer); s->cplus_txbuffer = NULL; - timer_del(s->timer); timer_free(s->timer); qemu_del_nic(s->nic); } diff --git a/hw/net/spapr_llan.c b/hw/net/spapr_llan.c index XXXXXXX..XXXXXXX 100644 --- a/hw/net/spapr_llan.c +++ b/hw/net/spapr_llan.c @@ -XXX,XX +XXX,XX @@ static void spapr_vlan_instance_finalize(Object *obj) } if (dev->rxp_timer) { - timer_del(dev->rxp_timer); timer_free(dev->rxp_timer); } } diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index XXXXXXX..XXXXXXX 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -XXX,XX +XXX,XX @@ static void virtio_net_rsc_cleanup(VirtIONet *n) g_free(seg); } - timer_del(chain->drain_timer); timer_free(chain->drain_timer); QTAILQ_REMOVE(&n->rsc_chains, chain, next); g_free(chain); @@ -XXX,XX +XXX,XX @@ static void virtio_net_del_queue(VirtIONet *n, int index) virtio_del_queue(vdev, index * 2); if (q->tx_timer) { - timer_del(q->tx_timer); timer_free(q->tx_timer); q->tx_timer = NULL; } else { diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c index XXXXXXX..XXXXXXX 100644 --- a/hw/s390x/s390-pci-inst.c +++ b/hw/s390x/s390-pci-inst.c @@ -XXX,XX +XXX,XX @@ void pci_dereg_ioat(S390PCIIOMMU *iommu) void fmb_timer_free(S390PCIBusDevice *pbdev) { if (pbdev->fmb_timer) { - timer_del(pbdev->fmb_timer); timer_free(pbdev->fmb_timer); pbdev->fmb_timer = NULL; } diff --git a/hw/sd/sd.c b/hw/sd/sd.c index XXXXXXX..XXXXXXX 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -XXX,XX +XXX,XX @@ static void sd_instance_finalize(Object *obj) { SDState *sd = SD_CARD(obj); - timer_del(sd->ocr_power_timer); timer_free(sd->ocr_power_timer); } diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c index XXXXXXX..XXXXXXX 100644 --- a/hw/sd/sdhci.c +++ b/hw/sd/sdhci.c @@ -XXX,XX +XXX,XX @@ void sdhci_initfn(SDHCIState *s) void sdhci_uninitfn(SDHCIState *s) { - timer_del(s->insert_timer); timer_free(s->insert_timer); - timer_del(s->transfer_timer); timer_free(s->transfer_timer); g_free(s->fifo_buffer); diff --git a/hw/usb/dev-hub.c b/hw/usb/dev-hub.c index XXXXXXX..XXXXXXX 100644 --- a/hw/usb/dev-hub.c +++ b/hw/usb/dev-hub.c @@ -XXX,XX +XXX,XX @@ static void usb_hub_unrealize(USBDevice *dev) &s->ports[i].port); } - timer_del(s->port_timer); timer_free(s->port_timer); } diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c index XXXXXXX..XXXXXXX 100644 --- a/hw/usb/hcd-ehci.c +++ b/hw/usb/hcd-ehci.c @@ -XXX,XX +XXX,XX @@ void usb_ehci_unrealize(EHCIState *s, DeviceState *dev) trace_usb_ehci_unrealize(); if (s->frame_timer) { - timer_del(s->frame_timer); timer_free(s->frame_timer); s->frame_timer = NULL; } diff --git a/hw/usb/hcd-ohci-pci.c b/hw/usb/hcd-ohci-pci.c index XXXXXXX..XXXXXXX 100644 --- a/hw/usb/hcd-ohci-pci.c +++ b/hw/usb/hcd-ohci-pci.c @@ -XXX,XX +XXX,XX @@ static void usb_ohci_exit(PCIDevice *dev) usb_bus_release(&s->bus); } - timer_del(s->eof_timer); timer_free(s->eof_timer); } diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c index XXXXXXX..XXXXXXX 100644 --- a/hw/usb/hcd-uhci.c +++ b/hw/usb/hcd-uhci.c @@ -XXX,XX +XXX,XX @@ static void usb_uhci_exit(PCIDevice *dev) trace_usb_uhci_exit(); if (s->frame_timer) { - timer_del(s->frame_timer); timer_free(s->frame_timer); s->frame_timer = NULL; } diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c index XXXXXXX..XXXXXXX 100644 --- a/hw/usb/hcd-xhci.c +++ b/hw/usb/hcd-xhci.c @@ -XXX,XX +XXX,XX @@ static void usb_xhci_unrealize(DeviceState *dev) } if (xhci->mfwrap_timer) { - timer_del(xhci->mfwrap_timer); timer_free(xhci->mfwrap_timer); xhci->mfwrap_timer = NULL; } diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c index XXXXXXX..XXXXXXX 100644 --- a/hw/usb/redirect.c +++ b/hw/usb/redirect.c @@ -XXX,XX +XXX,XX @@ static void usbredir_unrealize(USBDevice *udev) qemu_bh_delete(dev->chardev_close_bh); qemu_bh_delete(dev->device_reject_bh); - timer_del(dev->attach_timer); timer_free(dev->attach_timer); usbredir_cleanup_device_queues(dev); diff --git a/hw/vfio/display.c b/hw/vfio/display.c index XXXXXXX..XXXXXXX 100644 --- a/hw/vfio/display.c +++ b/hw/vfio/display.c @@ -XXX,XX +XXX,XX @@ static void vfio_display_edid_exit(VFIODisplay *dpy) g_free(dpy->edid_regs); g_free(dpy->edid_blob); - timer_del(dpy->edid_link_timer); timer_free(dpy->edid_link_timer); } diff --git a/hw/virtio/vhost-vsock-common.c b/hw/virtio/vhost-vsock-common.c index XXXXXXX..XXXXXXX 100644 --- a/hw/virtio/vhost-vsock-common.c +++ b/hw/virtio/vhost-vsock-common.c @@ -XXX,XX +XXX,XX @@ static void vhost_vsock_common_post_load_timer_cleanup(VHostVSockCommon *vvc) return; } - timer_del(vvc->post_load_timer); timer_free(vvc->post_load_timer); vvc->post_load_timer = NULL; } diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c index XXXXXXX..XXXXXXX 100644 --- a/hw/virtio/virtio-balloon.c +++ b/hw/virtio/virtio-balloon.c @@ -XXX,XX +XXX,XX @@ static bool balloon_stats_enabled(const VirtIOBalloon *s) static void balloon_stats_destroy_timer(VirtIOBalloon *s) { if (balloon_stats_enabled(s)) { - timer_del(s->stats_timer); timer_free(s->stats_timer); s->stats_timer = NULL; s->stats_poll_interval = 0; diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c index XXXXXXX..XXXXXXX 100644 --- a/hw/virtio/virtio-rng.c +++ b/hw/virtio/virtio-rng.c @@ -XXX,XX +XXX,XX @@ static void virtio_rng_device_unrealize(DeviceState *dev) VirtIORNG *vrng = VIRTIO_RNG(dev); qemu_del_vm_change_state_handler(vrng->vmstate); - timer_del(vrng->rate_limit_timer); timer_free(vrng->rate_limit_timer); virtio_del_queue(vdev, 0); virtio_cleanup(vdev); diff --git a/hw/watchdog/wdt_diag288.c b/hw/watchdog/wdt_diag288.c index XXXXXXX..XXXXXXX 100644 --- a/hw/watchdog/wdt_diag288.c +++ b/hw/watchdog/wdt_diag288.c @@ -XXX,XX +XXX,XX @@ static void wdt_diag288_unrealize(DeviceState *dev) { DIAG288State *diag288 = DIAG288(dev); - timer_del(diag288->timer); timer_free(diag288->timer); } diff --git a/hw/watchdog/wdt_i6300esb.c b/hw/watchdog/wdt_i6300esb.c index XXXXXXX..XXXXXXX 100644 --- a/hw/watchdog/wdt_i6300esb.c +++ b/hw/watchdog/wdt_i6300esb.c @@ -XXX,XX +XXX,XX @@ static void i6300esb_exit(PCIDevice *dev) { I6300State *d = WATCHDOG_I6300ESB_DEVICE(dev); - timer_del(d->timer); timer_free(d->timer); } diff --git a/migration/colo.c b/migration/colo.c index XXXXXXX..XXXXXXX 100644 --- a/migration/colo.c +++ b/migration/colo.c @@ -XXX,XX +XXX,XX @@ out: * error. */ colo_compare_unregister_notifier(&packets_compare_notifier); - timer_del(s->colo_delay_timer); timer_free(s->colo_delay_timer); qemu_event_destroy(&s->colo_checkpoint_event); diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c index XXXXXXX..XXXXXXX 100644 --- a/monitor/hmp-cmds.c +++ b/monitor/hmp-cmds.c @@ -XXX,XX +XXX,XX @@ static void hmp_migrate_status_cb(void *opaque) error_report("%s", info->error_desc); } monitor_resume(status->mon); - timer_del(status->timer); timer_free(status->timer); g_free(status); } diff --git a/net/announce.c b/net/announce.c index XXXXXXX..XXXXXXX 100644 --- a/net/announce.c +++ b/net/announce.c @@ -XXX,XX +XXX,XX @@ void qemu_announce_timer_del(AnnounceTimer *timer, bool free_named) { bool free_timer = false; if (timer->tm) { - timer_del(timer->tm); timer_free(timer->tm); timer->tm = NULL; } diff --git a/net/colo-compare.c b/net/colo-compare.c index XXXXXXX..XXXXXXX 100644 --- a/net/colo-compare.c +++ b/net/colo-compare.c @@ -XXX,XX +XXX,XX @@ static void colo_compare_timer_init(CompareState *s) static void colo_compare_timer_del(CompareState *s) { if (s->packet_check_timer) { - timer_del(s->packet_check_timer); timer_free(s->packet_check_timer); s->packet_check_timer = NULL; } diff --git a/net/slirp.c b/net/slirp.c index XXXXXXX..XXXXXXX 100644 --- a/net/slirp.c +++ b/net/slirp.c @@ -XXX,XX +XXX,XX @@ static void *net_slirp_timer_new(SlirpTimerCb cb, static void net_slirp_timer_free(void *timer, void *opaque) { - timer_del(timer); timer_free(timer); } diff --git a/replay/replay-debugging.c b/replay/replay-debugging.c index XXXXXXX..XXXXXXX 100644 --- a/replay/replay-debugging.c +++ b/replay/replay-debugging.c @@ -XXX,XX +XXX,XX @@ static void replay_delete_break(void) assert(replay_mutex_locked()); if (replay_break_timer) { - timer_del(replay_break_timer); timer_free(replay_break_timer); replay_break_timer = NULL; } diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c index XXXXXXX..XXXXXXX 100644 --- a/target/s390x/cpu.c +++ b/target/s390x/cpu.c @@ -XXX,XX +XXX,XX @@ static void s390_cpu_finalize(Object *obj) #if !defined(CONFIG_USER_ONLY) S390CPU *cpu = S390_CPU(obj); - timer_del(cpu->env.tod_timer); timer_free(cpu->env.tod_timer); - timer_del(cpu->env.cpu_timer); timer_free(cpu->env.cpu_timer); qemu_unregister_reset(s390_cpu_machine_reset_cb, cpu); diff --git a/ui/console.c b/ui/console.c index XXXXXXX..XXXXXXX 100644 --- a/ui/console.c +++ b/ui/console.c @@ -XXX,XX +XXX,XX @@ static void gui_setup_refresh(DisplayState *ds) timer_mod(ds->gui_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME)); } if (!need_timer && ds->gui_timer != NULL) { - timer_del(ds->gui_timer); timer_free(ds->gui_timer); ds->gui_timer = NULL; } diff --git a/ui/spice-core.c b/ui/spice-core.c index XXXXXXX..XXXXXXX 100644 --- a/ui/spice-core.c +++ b/ui/spice-core.c @@ -XXX,XX +XXX,XX @@ static void timer_cancel(SpiceTimer *timer) static void timer_remove(SpiceTimer *timer) { - timer_del(timer->timer); timer_free(timer->timer); g_free(timer); } diff --git a/util/throttle.c b/util/throttle.c index XXXXXXX..XXXXXXX 100644 --- a/util/throttle.c +++ b/util/throttle.c @@ -XXX,XX +XXX,XX @@ static void throttle_timer_destroy(QEMUTimer **timer) { assert(*timer != NULL); - timer_del(*timer); timer_free(*timer); *timer = NULL; } -- 2.20.1
The Arm CPU finalize function uses a sequence of timer_del(), timer_deinit(), timer_free() to free the timer. The timer_deinit() step in this was always unnecessary, and now the timer_del() is implied by timer_free(), so we can collapse this down to simply calling timer_free(). Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20201215154107.3255-5-peter.maydell@linaro.org --- target/arm/cpu.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index XXXXXXX..XXXXXXX 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -XXX,XX +XXX,XX @@ static void arm_cpu_finalizefn(Object *obj) } #ifndef CONFIG_USER_ONLY if (cpu->pmu_timer) { - timer_del(cpu->pmu_timer); - timer_deinit(cpu->pmu_timer); timer_free(cpu->pmu_timer); } #endif -- 2.20.1
From: Gan Qixin <ganqixin@huawei.com> When running device-introspect-test, a memory leak occurred in the digic_timer_init function, so use ptimer_free() in the finalize function to avoid it. ASAN shows memory leak stack: Indirect leak of 288 byte(s) in 3 object(s) allocated from: #0 0xffffab97e1f0 in __interceptor_calloc (/lib64/libasan.so.5+0xee1f0) #1 0xffffab256800 in g_malloc0 (/lib64/libglib-2.0.so.0+0x56800) #2 0xaaabf555db78 in ptimer_init /qemu/hw/core/ptimer.c:432 #3 0xaaabf5b04084 in digic_timer_init /qemu/hw/timer/digic-timer.c:142 #4 0xaaabf6339f6c in object_initialize_with_type /qemu/qom/object.c:515 #5 0xaaabf633ca04 in object_initialize_child_with_propsv /qemu/qom/object.c:564 #6 0xaaabf633cc08 in object_initialize_child_with_props /qemu/qom/object.c:547 #7 0xaaabf5b40e84 in digic_init /qemu/hw/arm/digic.c:46 #8 0xaaabf6339f6c in object_initialize_with_type /qemu/qom/object.c:515 #9 0xaaabf633a1e0 in object_new_with_type /qemu/qom/object.c:729 #10 0xaaabf6375e40 in qmp_device_list_properties /qemu/qom/qom-qmp-cmds.c:153 #11 0xaaabf653d8ec in qmp_marshal_device_list_properties /qemu/qapi/qapi-commands-qdev.c:59 #12 0xaaabf6587d08 in do_qmp_dispatch_bh /qemu/qapi/qmp-dispatch.c:110 Reported-by: Euler Robot <euler.robot@huawei.com> Signed-off-by: Gan Qixin <ganqixin@huawei.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/timer/digic-timer.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/hw/timer/digic-timer.c b/hw/timer/digic-timer.c index XXXXXXX..XXXXXXX 100644 --- a/hw/timer/digic-timer.c +++ b/hw/timer/digic-timer.c @@ -XXX,XX +XXX,XX @@ static void digic_timer_init(Object *obj) sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem); } +static void digic_timer_finalize(Object *obj) +{ + DigicTimerState *s = DIGIC_TIMER(obj); + + ptimer_free(s->ptimer); +} + static void digic_timer_class_init(ObjectClass *klass, void *class_data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -XXX,XX +XXX,XX @@ static const TypeInfo digic_timer_info = { .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(DigicTimerState), .instance_init = digic_timer_init, + .instance_finalize = digic_timer_finalize, .class_init = digic_timer_class_init, }; -- 2.20.1
From: Gan Qixin <ganqixin@huawei.com> When running device-introspect-test, a memory leak occurred in the a10_pit_init function, so use ptimer_free() in the finalize function to avoid it. ASAN shows memory leak stack: Indirect leak of 288 byte(s) in 6 object(s) allocated from: #0 0xffffab97e1f0 in __interceptor_calloc (/lib64/libasan.so.5+0xee1f0) #1 0xffffab256800 in g_malloc0 (/lib64/libglib-2.0.so.0+0x56800) #2 0xaaabf555db84 in timer_new_full /qemu/include/qemu/timer.h:523 #3 0xaaabf555db84 in timer_new /qemu/include/qemu/timer.h:544 #4 0xaaabf555db84 in timer_new_ns /qemu/include/qemu/timer.h:562 #5 0xaaabf555db84 in ptimer_init /qemu/hw/core/ptimer.c:433 #6 0xaaabf57415e8 in a10_pit_init /qemu/hw/timer/allwinner-a10-pit.c:278 #7 0xaaabf6339f6c in object_initialize_with_type /qemu/qom/object.c:515 #8 0xaaabf633ca04 in object_initialize_child_with_propsv /qemu/qom/object.c:564 #9 0xaaabf633cc08 in object_initialize_child_with_props /qemu/qom/object.c:547 #10 0xaaabf5b94680 in aw_a10_init /qemu/hw/arm/allwinner-a10.c:49 #11 0xaaabf6339f6c in object_initialize_with_type /qemu/qom/object.c:515 #12 0xaaabf633a1e0 in object_new_with_type /qemu/qom/object.c:729 Reported-by: Euler Robot <euler.robot@huawei.com> Signed-off-by: Gan Qixin <ganqixin@huawei.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/timer/allwinner-a10-pit.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/hw/timer/allwinner-a10-pit.c b/hw/timer/allwinner-a10-pit.c index XXXXXXX..XXXXXXX 100644 --- a/hw/timer/allwinner-a10-pit.c +++ b/hw/timer/allwinner-a10-pit.c @@ -XXX,XX +XXX,XX @@ static void a10_pit_init(Object *obj) } } +static void a10_pit_finalize(Object *obj) +{ + AwA10PITState *s = AW_A10_PIT(obj); + int i; + + for (i = 0; i < AW_A10_PIT_TIMER_NR; i++) { + ptimer_free(s->timer[i]); + } +} + static void a10_pit_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -XXX,XX +XXX,XX @@ static const TypeInfo a10_pit_info = { .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(AwA10PITState), .instance_init = a10_pit_init, + .instance_finalize = a10_pit_finalize, .class_init = a10_pit_class_init, }; -- 2.20.1
From: Gan Qixin <ganqixin@huawei.com> When running device-introspect-test, a memory leak occurred in the exynos4210_rtc_init function, so use ptimer_free() in the finalize function to avoid it. ASAN shows memory leak stack: Indirect leak of 96 byte(s) in 1 object(s) allocated from: #0 0xffffab97e1f0 in __interceptor_calloc (/lib64/libasan.so.5+0xee1f0) #1 0xffffab256800 in g_malloc0 (/lib64/libglib-2.0.so.0+0x56800) #2 0xaaabf555db78 in ptimer_init /qemu/hw/core/ptimer.c:432 #3 0xaaabf57b3934 in exynos4210_rtc_init /qemu/hw/rtc/exynos4210_rtc.c:567 #4 0xaaabf6339f6c in object_initialize_with_type /qemu/qom/object.c:515 #5 0xaaabf633a1e0 in object_new_with_type /qemu/qom/object.c:729 #6 0xaaabf6375e40 in qmp_device_list_properties /qemu/qom/qom-qmp-cmds.c:153 #7 0xaaabf653d8ec in qmp_marshal_device_list_properties /qemu/qapi/qapi-commands-qdev.c:59 #8 0xaaabf6587d08 in do_qmp_dispatch_bh /qemu/qapi/qmp-dispatch.c:110 #9 0xaaabf6552708 in aio_bh_call /qemu/util/async.c:136 #10 0xaaabf6552708 in aio_bh_poll /qemu/util/async.c:164 #11 0xaaabf655f19c in aio_dispatch /qemu/util/aio-posix.c:381 #12 0xaaabf65523f4 in aio_ctx_dispatch /qemu/util/async.c:306 Reported-by: Euler Robot <euler.robot@huawei.com> Signed-off-by: Gan Qixin <ganqixin@huawei.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/rtc/exynos4210_rtc.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/hw/rtc/exynos4210_rtc.c b/hw/rtc/exynos4210_rtc.c index XXXXXXX..XXXXXXX 100644 --- a/hw/rtc/exynos4210_rtc.c +++ b/hw/rtc/exynos4210_rtc.c @@ -XXX,XX +XXX,XX @@ static void exynos4210_rtc_init(Object *obj) sysbus_init_mmio(dev, &s->iomem); } +static void exynos4210_rtc_finalize(Object *obj) +{ + Exynos4210RTCState *s = EXYNOS4210_RTC(obj); + + ptimer_free(s->ptimer); + ptimer_free(s->ptimer_1Hz); +} + static void exynos4210_rtc_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -XXX,XX +XXX,XX @@ static const TypeInfo exynos4210_rtc_info = { .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(Exynos4210RTCState), .instance_init = exynos4210_rtc_init, + .instance_finalize = exynos4210_rtc_finalize, .class_init = exynos4210_rtc_class_init, }; -- 2.20.1
From: Gan Qixin <ganqixin@huawei.com> When running device-introspect-test, a memory leak occurred in the exynos4210_pwm_init function, so use ptimer_free() in the finalize function to avoid it. ASAN shows memory leak stack: Indirect leak of 240 byte(s) in 5 object(s) allocated from: #0 0xffffab97e1f0 in __interceptor_calloc (/lib64/libasan.so.5+0xee1f0) #1 0xffffab256800 in g_malloc0 (/lib64/libglib-2.0.so.0+0x56800) #2 0xaaabf555db84 in timer_new_full /qemu/include/qemu/timer.h:523 #3 0xaaabf555db84 in timer_new /qemu/include/qemu/timer.h:544 #4 0xaaabf555db84 in timer_new_ns /qemu/include/qemu/timer.h:562 #5 0xaaabf555db84 in ptimer_init /qemu/hw/core/ptimer.c:433 #6 0xaaabf56a36cc in exynos4210_pwm_init /qemu/hw/timer/exynos4210_pwm.c:401 #7 0xaaabf6339f6c in object_initialize_with_type /qemu/qom/object.c:515 #8 0xaaabf633a1e0 in object_new_with_type /qemu/qom/object.c:729 #9 0xaaabf6375e40 in qmp_device_list_properties /qemu/qom/qom-qmp-cmds.c:153 #10 0xaaabf653d8ec in qmp_marshal_device_list_properties /qemu/qapi/qapi-commands-qdev.c:59 #11 0xaaabf6587d08 in do_qmp_dispatch_bh /qemu/qapi/qmp-dispatch.c:110 #12 0xaaabf6552708 in aio_bh_call /qemu/util/async.c:136 Reported-by: Euler Robot <euler.robot@huawei.com> Signed-off-by: Gan Qixin <ganqixin@huawei.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/timer/exynos4210_pwm.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/hw/timer/exynos4210_pwm.c b/hw/timer/exynos4210_pwm.c index XXXXXXX..XXXXXXX 100644 --- a/hw/timer/exynos4210_pwm.c +++ b/hw/timer/exynos4210_pwm.c @@ -XXX,XX +XXX,XX @@ static void exynos4210_pwm_init(Object *obj) sysbus_init_mmio(dev, &s->iomem); } +static void exynos4210_pwm_finalize(Object *obj) +{ + Exynos4210PWMState *s = EXYNOS4210_PWM(obj); + int i; + + for (i = 0; i < EXYNOS4210_PWM_TIMERS_NUM; i++) { + ptimer_free(s->timer[i].ptimer); + } +} + static void exynos4210_pwm_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -XXX,XX +XXX,XX @@ static const TypeInfo exynos4210_pwm_info = { .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(Exynos4210PWMState), .instance_init = exynos4210_pwm_init, + .instance_finalize = exynos4210_pwm_finalize, .class_init = exynos4210_pwm_class_init, }; -- 2.20.1
From: Gan Qixin <ganqixin@huawei.com> When running device-introspect-test, a memory leak occurred in the mss_timer_init function, so use ptimer_free() in the finalize function to avoid it. ASAN shows memory leak stack: Indirect leak of 192 byte(s) in 2 object(s) allocated from: #0 0xffffab97e1f0 in __interceptor_calloc (/lib64/libasan.so.5+0xee1f0) #1 0xffffab256800 in g_malloc0 (/lib64/libglib-2.0.so.0+0x56800) #2 0xaaabf555db78 in ptimer_init /qemu/hw/core/ptimer.c:432 #3 0xaaabf58a0010 in mss_timer_init /qemu/hw/timer/mss-timer.c:235 #4 0xaaabf6339f6c in object_initialize_with_type /qemu/qom/object.c:515 #5 0xaaabf633ca04 in object_initialize_child_with_propsv /qemu/qom/object.c:564 #6 0xaaabf633cc08 in object_initialize_child_with_props /qemu/qom/object.c:547 #7 0xaaabf5b8316c in m2sxxx_soc_initfn /qemu/hw/arm/msf2-soc.c:70 #8 0xaaabf6339f6c in object_initialize_with_type /qemu/qom/object.c:515 #9 0xaaabf633a1e0 in object_new_with_type /qemu/qom/object.c:729 #10 0xaaabf6375e40 in qmp_device_list_properties /qemu/qom/qom-qmp-cmds.c:153 #11 0xaaabf653d8ec in qmp_marshal_device_list_properties /qemu/qapi/qapi-commands-qdev.c:59 #12 0xaaabf6587d08 in do_qmp_dispatch_bh /qemu/qapi/qmp-dispatch.c:110 Reported-by: Euler Robot <euler.robot@huawei.com> Signed-off-by: Gan Qixin <ganqixin@huawei.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/timer/mss-timer.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/hw/timer/mss-timer.c b/hw/timer/mss-timer.c index XXXXXXX..XXXXXXX 100644 --- a/hw/timer/mss-timer.c +++ b/hw/timer/mss-timer.c @@ -XXX,XX +XXX,XX @@ static void mss_timer_init(Object *obj) sysbus_init_mmio(SYS_BUS_DEVICE(obj), &t->mmio); } +static void mss_timer_finalize(Object *obj) +{ + MSSTimerState *t = MSS_TIMER(obj); + int i; + + for (i = 0; i < NUM_TIMERS; i++) { + struct Msf2Timer *st = &t->timers[i]; + + ptimer_free(st->ptimer); + } +} + static const VMStateDescription vmstate_timers = { .name = "mss-timer-block", .version_id = 1, @@ -XXX,XX +XXX,XX @@ static const TypeInfo mss_timer_info = { .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(MSSTimerState), .instance_init = mss_timer_init, + .instance_finalize = mss_timer_finalize, .class_init = mss_timer_class_init, }; -- 2.20.1
From: Gan Qixin <ganqixin@huawei.com> When running device-introspect-test, a memory leak occurred in the mv88w8618_pit_init function, so use ptimer_free() in the finalize function to avoid it. ASAN shows memory leak stack: Indirect leak of 192 byte(s) in 4 object(s) allocated from: #0 0xffffab97e1f0 in __interceptor_calloc (/lib64/libasan.so.5+0xee1f0) #1 0xffffab256800 in g_malloc0 (/lib64/libglib-2.0.so.0+0x56800) #2 0xaaabf555db84 in timer_new_full /qemu/include/qemu/timer.h:523 #3 0xaaabf555db84 in timer_new /qemu/include/qemu/timer.h:544 #4 0xaaabf555db84 in timer_new_ns /qemu/include/qemu/timer.h:562 #5 0xaaabf555db84 in ptimer_init /qemu/hw/core/ptimer.c:433 #6 0xaaabf5bb2290 in mv88w8618_timer_init /qemu/hw/arm/musicpal.c:862 #7 0xaaabf5bb2290 in mv88w8618_pit_init /qemu/hw/arm/musicpal.c:954 #8 0xaaabf6339f6c in object_initialize_with_type /qemu/qom/object.c:515 #9 0xaaabf633a1e0 in object_new_with_type /qemu/qom/object.c:729 #10 0xaaabf6375e40 in qmp_device_list_properties /qemu/qom/qom-qmp-cmds.c:153 #11 0xaaabf5a95540 in qdev_device_help /qemu/softmmu/qdev-monitor.c:283 #12 0xaaabf5a96940 in qmp_device_add /qemu/softmmu/qdev-monitor.c:801 Reported-by: Euler Robot <euler.robot@huawei.com> Signed-off-by: Gan Qixin <ganqixin@huawei.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/arm/musicpal.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/musicpal.c +++ b/hw/arm/musicpal.c @@ -XXX,XX +XXX,XX @@ static void mv88w8618_pit_init(Object *obj) sysbus_init_mmio(dev, &s->iomem); } +static void mv88w8618_pit_finalize(Object *obj) +{ + SysBusDevice *dev = SYS_BUS_DEVICE(obj); + mv88w8618_pit_state *s = MV88W8618_PIT(dev); + int i; + + for (i = 0; i < 4; i++) { + ptimer_free(s->timer[i].ptimer); + } +} + static const VMStateDescription mv88w8618_timer_vmsd = { .name = "timer", .version_id = 1, @@ -XXX,XX +XXX,XX @@ static const TypeInfo mv88w8618_pit_info = { .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(mv88w8618_pit_state), .instance_init = mv88w8618_pit_init, + .instance_finalize = mv88w8618_pit_finalize, .class_init = mv88w8618_pit_class_init, }; -- 2.20.1
From: Gan Qixin <ganqixin@huawei.com> When running device-introspect-test, a memory leak occurred in the exynos4210_mct_init function, so use ptimer_free() in the finalize function to avoid it. ASAN shows memory leak stack: Indirect leak of 96 byte(s) in 1 object(s) allocated from: #0 0xffffab97e1f0 in __interceptor_calloc (/lib64/libasan.so.5+0xee1f0) #1 0xffffab256800 in g_malloc0 (/lib64/libglib-2.0.so.0+0x56800) #2 0xaaabf555db78 in ptimer_init /qemu/hw/core/ptimer.c:432 #3 0xaaabf56b01a0 in exynos4210_mct_init /qemu/hw/timer/exynos4210_mct.c:1505 #4 0xaaabf6339f6c in object_initialize_with_type /qemu/qom/object.c:515 #5 0xaaabf633a1e0 in object_new_with_type /qemu/qom/object.c:729 #6 0xaaabf6375e40 in qmp_device_list_properties /qemu/qom/qom-qmp-cmds.c:153 #7 0xaaabf653d8ec in qmp_marshal_device_list_properties /qemu/qapi/qapi-commands-qdev.c:59 #8 0xaaabf6587d08 in do_qmp_dispatch_bh /qemu/qapi/qmp-dispatch.c:110 #9 0xaaabf6552708 in aio_bh_call /qemu/util/async.c:136 #10 0xaaabf6552708 in aio_bh_poll /qemu/util/async.c:164 #11 0xaaabf655f19c in aio_dispatch /qemu/util/aio-posix.c:381 #12 0xaaabf65523f4 in aio_ctx_dispatch /qemu/util/async.c:306 Reported-by: Euler Robot <euler.robot@huawei.com> Signed-off-by: Gan Qixin <ganqixin@huawei.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/timer/exynos4210_mct.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/hw/timer/exynos4210_mct.c b/hw/timer/exynos4210_mct.c index XXXXXXX..XXXXXXX 100644 --- a/hw/timer/exynos4210_mct.c +++ b/hw/timer/exynos4210_mct.c @@ -XXX,XX +XXX,XX @@ static void exynos4210_mct_init(Object *obj) sysbus_init_mmio(dev, &s->iomem); } +static void exynos4210_mct_finalize(Object *obj) +{ + int i; + Exynos4210MCTState *s = EXYNOS4210_MCT(obj); + + ptimer_free(s->g_timer.ptimer_frc); + + for (i = 0; i < 2; i++) { + ptimer_free(s->l_timer[i].tick_timer.ptimer_tick); + ptimer_free(s->l_timer[i].ptimer_frc); + } +} + static void exynos4210_mct_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -XXX,XX +XXX,XX @@ static const TypeInfo exynos4210_mct_info = { .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(Exynos4210MCTState), .instance_init = exynos4210_mct_init, + .instance_finalize = exynos4210_mct_finalize, .class_init = exynos4210_mct_class_init, }; -- 2.20.1
From: Bin Meng <bin.meng@windriver.com> U-Boot expects PMU_MISC0 register bit 7 is set (see init_bandgap() in arch/arm/mach-imx/mx6/soc.c) during boot. This bit indicates the bandgap has stabilized. With this change, the latest upstream U-Boot (v2021.01-rc3) for imx6 sabrelite board (mx6qsabrelite_defconfig), with a slight change made by switching CONFIG_OF_SEPARATE to CONFIG_OF_EMBED, boots to U-Boot shell on QEMU with the following command: $ qemu-system-arm -M sabrelite -smp 4 -m 1G -kernel u-boot \ -display none -serial null -serial stdio Boot log below: U-Boot 2021.01-rc3 (Dec 12 2020 - 17:40:02 +0800) CPU: Freescale i.MX?? rev1.0 at 792 MHz Reset cause: POR Model: Freescale i.MX6 Quad SABRE Lite Board Board: SABRE Lite I2C: ready DRAM: 1 GiB force_idle_bus: sda=0 scl=0 sda.gp=0x5c scl.gp=0x55 force_idle_bus: failed to clear bus, sda=0 scl=0 force_idle_bus: sda=0 scl=0 sda.gp=0x6d scl.gp=0x6c force_idle_bus: failed to clear bus, sda=0 scl=0 force_idle_bus: sda=0 scl=0 sda.gp=0xcb scl.gp=0x5 force_idle_bus: failed to clear bus, sda=0 scl=0 MMC: FSL_SDHC: 0, FSL_SDHC: 1 Loading Environment from MMC... *** Warning - No block device, using default environment In: serial Out: serial Err: serial Net: Board Net Initialization Failed No ethernet found. starting USB... Bus usb@2184000: usb dr_mode not found USB EHCI 1.00 Bus usb@2184200: USB EHCI 1.00 scanning bus usb@2184000 for devices... 1 USB Device(s) found scanning bus usb@2184200 for devices... 1 USB Device(s) found scanning usb for storage devices... 0 Storage Device(s) found scanning usb for ethernet devices... 0 Ethernet Device(s) found Hit any key to stop autoboot: 0 => Signed-off-by: Bin Meng <bin.meng@windriver.com> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Message-id: 20210106063504.10841-2-bmeng.cn@gmail.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/misc/imx6_ccm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/misc/imx6_ccm.c b/hw/misc/imx6_ccm.c index XXXXXXX..XXXXXXX 100644 --- a/hw/misc/imx6_ccm.c +++ b/hw/misc/imx6_ccm.c @@ -XXX,XX +XXX,XX @@ static void imx6_ccm_reset(DeviceState *dev) s->analog[PMU_REG_3P0] = 0x00000F74; s->analog[PMU_REG_2P5] = 0x00005071; s->analog[PMU_REG_CORE] = 0x00402010; - s->analog[PMU_MISC0] = 0x04000000; + s->analog[PMU_MISC0] = 0x04000080; s->analog[PMU_MISC1] = 0x00000000; s->analog[PMU_MISC2] = 0x00272727; -- 2.20.1
From: Bin Meng <bin.meng@windriver.com> Currently when U-Boot boots, it prints "??" for i.MX processor: CPU: Freescale i.MX?? rev1.0 at 792 MHz The register that was used to determine the silicon type is undocumented in the latest IMX6DQRM (Rev. 6, 05/2020), but we can refer to get_cpu_rev() in arch/arm/mach-imx/mx6/soc.c in the U-Boot source codes that USB_ANALOG_DIGPROG is used. Update its reset value to indicate i.MX6Q. Signed-off-by: Bin Meng <bin.meng@windriver.com> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Message-id: 20210106063504.10841-3-bmeng.cn@gmail.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/misc/imx6_ccm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/misc/imx6_ccm.c b/hw/misc/imx6_ccm.c index XXXXXXX..XXXXXXX 100644 --- a/hw/misc/imx6_ccm.c +++ b/hw/misc/imx6_ccm.c @@ -XXX,XX +XXX,XX @@ static void imx6_ccm_reset(DeviceState *dev) s->analog[USB_ANALOG_USB2_VBUS_DETECT] = 0x00000004; s->analog[USB_ANALOG_USB2_CHRG_DETECT] = 0x00000000; s->analog[USB_ANALOG_USB2_MISC] = 0x00000002; - s->analog[USB_ANALOG_DIGPROG] = 0x00000000; + s->analog[USB_ANALOG_DIGPROG] = 0x00630000; /* all PLLs need to be locked */ s->analog[CCM_ANALOG_PLL_ARM] |= CCM_ANALOG_PLL_LOCK; -- 2.20.1
From: Bin Meng <bin.meng@windriver.com> At present, when booting U-Boot on QEMU sabrelite, we see: Net: Board Net Initialization Failed No ethernet found. U-Boot scans PHY at address 4/5/6/7 (see board_eth_init() in the U-Boot source: board/boundary/nitrogen6x/nitrogen6x.c). On the real board, the Ethernet PHY is at address 6. Adjust this by updating the "fec-phy-num" property of the fsl_imx6 SoC object. With this change, U-Boot sees the PHY but complains MAC address: Net: using phy at 6 FEC [PRIME] Error: FEC address not set. This is due to U-Boot tries to read the MAC address from the fuse, which QEMU does not have any valid content filled in. However this does not prevent the Ethernet from working in QEMU. We just need to set up the MAC address later in the U-Boot command shell, by: => setenv ethaddr 00:11:22:33:44:55 Signed-off-by: Bin Meng <bin.meng@windriver.com> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Message-id: 20210106063504.10841-4-bmeng.cn@gmail.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- hw/arm/sabrelite.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hw/arm/sabrelite.c b/hw/arm/sabrelite.c index XXXXXXX..XXXXXXX 100644 --- a/hw/arm/sabrelite.c +++ b/hw/arm/sabrelite.c @@ -XXX,XX +XXX,XX @@ static void sabrelite_init(MachineState *machine) s = FSL_IMX6(object_new(TYPE_FSL_IMX6)); object_property_add_child(OBJECT(machine), "soc", OBJECT(s)); + + /* Ethernet PHY address is 6 */ + object_property_set_int(OBJECT(s), "fec-phy-num", 6, &error_fatal); + qdev_realize(DEVICE(s), NULL, &error_fatal); memory_region_add_subregion(get_system_memory(), FSL_IMX6_MMDC_ADDR, -- 2.20.1
From: Bin Meng <bin.meng@windriver.com> This adds the target guide for SABRE Lite board, and documents how to boot a Linux kernel and U-Boot bootloader. Signed-off-by: Bin Meng <bin.meng@windriver.com> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Message-id: 20210106063504.10841-5-bmeng.cn@gmail.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- docs/system/arm/sabrelite.rst | 119 ++++++++++++++++++++++++++++++++++ docs/system/target-arm.rst | 1 + 2 files changed, 120 insertions(+) create mode 100644 docs/system/arm/sabrelite.rst diff --git a/docs/system/arm/sabrelite.rst b/docs/system/arm/sabrelite.rst new file mode 100644 index XXXXXXX..XXXXXXX --- /dev/null +++ b/docs/system/arm/sabrelite.rst @@ -XXX,XX +XXX,XX @@ +Boundary Devices SABRE Lite (``sabrelite``) +=========================================== + +Boundary Devices SABRE Lite i.MX6 Development Board is a low-cost development +platform featuring the powerful Freescale / NXP Semiconductor's i.MX 6 Quad +Applications Processor. + +Supported devices +----------------- + +The SABRE Lite machine supports the following devices: + + * Up to 4 Cortex A9 cores + * Generic Interrupt Controller + * 1 Clock Controller Module + * 1 System Reset Controller + * 5 UARTs + * 2 EPIC timers + * 1 GPT timer + * 2 Watchdog timers + * 1 FEC Ethernet controller + * 3 I2C controllers + * 7 GPIO controllers + * 4 SDHC storage controllers + * 4 USB 2.0 host controllers + * 5 ECSPI controllers + * 1 SST 25VF016B flash + +Please note above list is a complete superset the QEMU SABRE Lite machine can +support. For a normal use case, a device tree blob that represents a real world +SABRE Lite board, only exposes a subset of devices to the guest software. + +Boot options +------------ + +The SABRE Lite machine can start using the standard -kernel functionality +for loading a Linux kernel, U-Boot bootloader or ELF executable. + +Running Linux kernel +-------------------- + +Linux mainline v5.10 release is tested at the time of writing. To build a Linux +mainline kernel that can be booted by the SABRE Lite machine, simply configure +the kernel using the imx_v6_v7_defconfig configuration: + +.. code-block:: bash + + $ export ARCH=arm + $ export CROSS_COMPILE=arm-linux-gnueabihf- + $ make imx_v6_v7_defconfig + $ make + +To boot the newly built Linux kernel in QEMU with the SABRE Lite machine, use: + +.. code-block:: bash + + $ qemu-system-arm -M sabrelite -smp 4 -m 1G \ + -display none -serial null -serial stdio \ + -kernel arch/arm/boot/zImage \ + -dtb arch/arm/boot/dts/imx6q-sabrelite.dtb \ + -initrd /path/to/rootfs.ext4 \ + -append "root=/dev/ram" + +Running U-Boot +-------------- + +U-Boot mainline v2020.10 release is tested at the time of writing. To build a +U-Boot mainline bootloader that can be booted by the SABRE Lite machine, use +the mx6qsabrelite_defconfig with similar commands as described above for Linux: + +.. code-block:: bash + + $ export CROSS_COMPILE=arm-linux-gnueabihf- + $ make mx6qsabrelite_defconfig + +Note we need to adjust settings by: + +.. code-block:: bash + + $ make menuconfig + +then manually select the following configuration in U-Boot: + + Device Tree Control > Provider of DTB for DT Control > Embedded DTB + +To start U-Boot using the SABRE Lite machine, provide the u-boot binary to +the -kernel argument, along with an SD card image with rootfs: + +.. code-block:: bash + + $ qemu-system-arm -M sabrelite -smp 4 -m 1G \ + -display none -serial null -serial stdio \ + -kernel u-boot + +The following example shows booting Linux kernel from dhcp, and uses the +rootfs on an SD card. This requires some additional command line parameters +for QEMU: + +.. code-block:: none + + -nic user,tftp=/path/to/kernel/zImage \ + -drive file=sdcard.img,id=rootfs -device sd-card,drive=rootfs + +The directory for the built-in TFTP server should also contain the device tree +blob of the SABRE Lite board. The sample SD card image was populated with the +root file system with one single partition. You may adjust the kernel "root=" +boot parameter accordingly. + +After U-Boot boots, type the following commands in the U-Boot command shell to +boot the Linux kernel: + +.. code-block:: none + + => setenv ethaddr 00:11:22:33:44:55 + => setenv bootfile zImage + => dhcp + => tftpboot 14000000 imx6q-sabrelite.dtb + => setenv bootargs root=/dev/mmcblk3p1 + => bootz 12000000 - 14000000 diff --git a/docs/system/target-arm.rst b/docs/system/target-arm.rst index XXXXXXX..XXXXXXX 100644 --- a/docs/system/target-arm.rst +++ b/docs/system/target-arm.rst @@ -XXX,XX +XXX,XX @@ undocumented; you can get a complete list by running arm/versatile arm/vexpress arm/aspeed + arm/sabrelite arm/digic arm/musicpal arm/gumstix -- 2.20.1
v3->v4: Windows headers define an INT type which clashed with an enum value name in arm_gicv3_its.c... The following changes since commit eae587e8e3694b1aceab23239493fb4c7e1a80f5: Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2021-09-13' into staging (2021-09-13 11:00:30 +0100) are available in the Git repository at: https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210913-3 for you to fetch changes up to 28e987a7e7edaa3ca7feeac65edca26145df8814: hw/arm/mps2.c: Mark internal-only I2C buses as 'full' (2021-09-13 21:01:08 +0100) ---------------------------------------------------------------- target-arm queue: * mark MPS2/MPS3 board-internal i2c buses as 'full' so that command line user-created devices are not plugged into them * Take an exception if PSTATE.IL is set * Support an emulated ITS in the virt board * Add support for kudo-bmc board * Probe for KVM_CAP_ARM_VM_IPA_SIZE when creating scratch VM * cadence_uart: Fix clock handling issues that prevented u-boot from running ---------------------------------------------------------------- Bin Meng (6): hw/misc: zynq_slcr: Correctly compute output clocks in the reset exit phase hw/char: cadence_uart: Disable transmit when input clock is disabled hw/char: cadence_uart: Move clock/reset check to uart_can_receive() hw/char: cadence_uart: Convert to memop_with_attrs() ops hw/char: cadence_uart: Ignore access when unclocked or in reset for uart_{read, write}() hw/char: cadence_uart: Log a guest error when device is unclocked or in reset Chris Rauer (1): hw/arm: Add support for kudo-bmc board. Marc Zyngier (1): hw/arm/virt: KVM: Probe for KVM_CAP_ARM_VM_IPA_SIZE when creating scratch VM Peter Maydell (5): target/arm: Take an exception if PSTATE.IL is set qdev: Support marking individual buses as 'full' hw/arm/mps2-tz.c: Add extra data parameter to MakeDevFn hw/arm/mps2-tz.c: Mark internal-only I2C buses as 'full' hw/arm/mps2.c: Mark internal-only I2C buses as 'full' Richard Henderson (1): target/arm: Merge disas_a64_insn into aarch64_tr_translate_insn Shashi Mallela (9): hw/intc: GICv3 ITS initial framework hw/intc: GICv3 ITS register definitions added hw/intc: GICv3 ITS command queue framework hw/intc: GICv3 ITS Command processing hw/intc: GICv3 ITS Feature enablement hw/intc: GICv3 redistributor ITS processing tests/data/acpi/virt: Add IORT files for ITS hw/arm/virt: add ITS support in virt GIC tests/data/acpi/virt: Update IORT files for ITS docs/system/arm/nuvoton.rst | 1 + hw/intc/gicv3_internal.h | 188 ++++- include/hw/arm/virt.h | 2 + include/hw/intc/arm_gicv3_common.h | 13 + include/hw/intc/arm_gicv3_its_common.h | 32 +- include/hw/qdev-core.h | 24 + target/arm/cpu.h | 1 + target/arm/kvm_arm.h | 4 +- target/arm/syndrome.h | 5 + target/arm/translate.h | 2 + hw/arm/mps2-tz.c | 92 ++- hw/arm/mps2.c | 12 +- hw/arm/npcm7xx_boards.c | 34 + hw/arm/virt.c | 29 +- hw/char/cadence_uart.c | 61 +- hw/intc/arm_gicv3.c | 14 + hw/intc/arm_gicv3_common.c | 13 + hw/intc/arm_gicv3_cpuif.c | 7 +- hw/intc/arm_gicv3_dist.c | 5 +- hw/intc/arm_gicv3_its.c | 1322 ++++++++++++++++++++++++++++++++ hw/intc/arm_gicv3_its_common.c | 7 +- hw/intc/arm_gicv3_its_kvm.c | 2 +- hw/intc/arm_gicv3_redist.c | 153 +++- hw/misc/zynq_slcr.c | 31 +- softmmu/qdev-monitor.c | 7 +- target/arm/helper-a64.c | 1 + target/arm/helper.c | 8 + target/arm/kvm.c | 7 +- target/arm/translate-a64.c | 255 +++--- target/arm/translate.c | 21 + hw/intc/meson.build | 1 + tests/data/acpi/virt/IORT | Bin 0 -> 124 bytes tests/data/acpi/virt/IORT.memhp | Bin 0 -> 124 bytes tests/data/acpi/virt/IORT.numamem | Bin 0 -> 124 bytes tests/data/acpi/virt/IORT.pxb | Bin 0 -> 124 bytes 35 files changed, 2144 insertions(+), 210 deletions(-) create mode 100644 hw/intc/arm_gicv3_its.c create mode 100644 tests/data/acpi/virt/IORT create mode 100644 tests/data/acpi/virt/IORT.memhp create mode 100644 tests/data/acpi/virt/IORT.numamem create mode 100644 tests/data/acpi/virt/IORT.pxb