aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2021-01-08 15:37:04 +0000
committerPeter Maydell <peter.maydell@linaro.org>2021-01-08 15:37:04 +0000
commit7b09f127738ae3d0e71716cea086fc8f847a5686 (patch)
treec026305c2ce384dff6e99efb4927c7118b43fb6f
parente79de63ab1bd1f6550e7b915e433bec1ad1a870a (diff)
parentc9f8511ea8d2b80723af0fea1f716d752c1b5208 (diff)
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20210108' into staging
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 # gpg: Signature made Fri 08 Jan 2021 15:34:25 GMT # gpg: using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE # gpg: issuer "peter.maydell@linaro.org" # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [ultimate] # gpg: aka "Peter Maydell <pmaydell@gmail.com>" [ultimate] # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [ultimate] # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * remotes/pmaydell/tags/pull-target-arm-20210108: (23 commits) docs/system: arm: Add sabrelite board description hw/arm: sabrelite: Connect the Ethernet PHY at address 6 hw/msic: imx6_ccm: Correct register value for silicon type hw/misc: imx6_ccm: Update PMU_MISC0 reset value exynos4210_mct: Use ptimer_free() in the finalize function to avoid memleaks musicpal: Use ptimer_free() in the finalize function to avoid memleaks mss-timer: Use ptimer_free() in the finalize function to avoid memleaks exynos4210_pwm: Use ptimer_free() in the finalize function to avoid memleaks exynos4210_rtc: Use ptimer_free() in the finalize function to avoid memleaks allwinner-a10-pit: Use ptimer_free() in the finalize function to avoid memleaks digic-timer: Use ptimer_free() in the finalize function to avoid memleaks target/arm: Remove timer_del()/timer_deinit() before timer_free() Remove superfluous timer_del() calls scripts/coccinelle: New script to remove unnecessary timer_del() calls util/qemu-timer: Make timer_free() imply timer_del() hw/arm/highbank: Drop dead KVM support code target/arm: Implement Cortex-M55 model target/arm: Implement FPCXT_NS fp system register target/arm: Correct store of FPSCR value via FPCXT_S hw/intc/armv7m_nvic: Correct handling of CCR.BFHFNMIGN ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--block/iscsi.c2
-rw-r--r--block/nbd.c1
-rw-r--r--block/qcow2.c1
-rw-r--r--docs/system/arm/sabrelite.rst119
-rw-r--r--docs/system/target-arm.rst1
-rw-r--r--hw/arm/highbank.c14
-rw-r--r--hw/arm/musicpal.c12
-rw-r--r--hw/arm/sabrelite.c4
-rw-r--r--hw/arm/virt-acpi-build.c9
-rw-r--r--hw/arm/virt.c21
-rw-r--r--hw/block/nvme.c2
-rw-r--r--hw/char/serial.c2
-rw-r--r--hw/char/virtio-serial-bus.c2
-rw-r--r--hw/ide/core.c1
-rw-r--r--hw/input/hid.c1
-rw-r--r--hw/intc/apic.c1
-rw-r--r--hw/intc/arm_gic.c4
-rw-r--r--hw/intc/armv7m_nvic.c15
-rw-r--r--hw/intc/ioapic.c1
-rw-r--r--hw/ipmi/ipmi_bmc_extern.c1
-rw-r--r--hw/misc/imx6_ccm.c4
-rw-r--r--hw/net/e1000.c3
-rw-r--r--hw/net/e1000e_core.c8
-rw-r--r--hw/net/pcnet-pci.c1
-rw-r--r--hw/net/rtl8139.c1
-rw-r--r--hw/net/spapr_llan.c1
-rw-r--r--hw/net/virtio-net.c2
-rw-r--r--hw/rtc/exynos4210_rtc.c9
-rw-r--r--hw/s390x/s390-pci-inst.c1
-rw-r--r--hw/sd/sd.c1
-rw-r--r--hw/sd/sdhci.c2
-rw-r--r--hw/timer/allwinner-a10-pit.c11
-rw-r--r--hw/timer/digic-timer.c8
-rw-r--r--hw/timer/exynos4210_mct.c14
-rw-r--r--hw/timer/exynos4210_pwm.c11
-rw-r--r--hw/timer/mss-timer.c13
-rw-r--r--hw/usb/dev-hub.c1
-rw-r--r--hw/usb/hcd-ehci.c1
-rw-r--r--hw/usb/hcd-ohci-pci.c1
-rw-r--r--hw/usb/hcd-uhci.c1
-rw-r--r--hw/usb/hcd-xhci.c1
-rw-r--r--hw/usb/redirect.c1
-rw-r--r--hw/vfio/display.c1
-rw-r--r--hw/virtio/vhost-vsock-common.c1
-rw-r--r--hw/virtio/virtio-balloon.c1
-rw-r--r--hw/virtio/virtio-rng.c1
-rw-r--r--hw/watchdog/wdt_diag288.c1
-rw-r--r--hw/watchdog/wdt_i6300esb.c1
-rw-r--r--include/hw/arm/virt.h3
-rw-r--r--include/qemu/timer.h24
-rw-r--r--migration/colo.c1
-rw-r--r--monitor/hmp-cmds.c1
-rw-r--r--net/announce.c1
-rw-r--r--net/colo-compare.c1
-rw-r--r--net/slirp.c1
-rw-r--r--replay/replay-debugging.c1
-rw-r--r--scripts/coccinelle/timer-del-timer-free.cocci18
-rw-r--r--target/arm/cpu.c2
-rw-r--r--target/arm/cpu_tcg.c42
-rw-r--r--target/arm/helper.c2
-rw-r--r--target/arm/translate-vfp.c.inc114
-rw-r--r--target/s390x/cpu.c2
-rw-r--r--ui/console.c1
-rw-r--r--ui/spice-core.c1
-rw-r--r--util/throttle.c1
65 files changed, 421 insertions, 111 deletions
diff --git a/block/iscsi.c b/block/iscsi.c
index 7d4b3b56d5..4d2a416ce7 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -1524,12 +1524,10 @@ 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 42536702b6..242a258f3a 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -194,7 +194,6 @@ 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 3a90ef2786..5d94f45be9 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -852,7 +852,6 @@ 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/docs/system/arm/sabrelite.rst b/docs/system/arm/sabrelite.rst
new file mode 100644
index 0000000000..71713310e3
--- /dev/null
+++ b/docs/system/arm/sabrelite.rst
@@ -0,0 +1,119 @@
+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 bde4b8e044..edd013c7bb 100644
--- a/docs/system/target-arm.rst
+++ b/docs/system/target-arm.rst
@@ -83,6 +83,7 @@ undocumented; you can get a complete list by running
arm/versatile
arm/vexpress
arm/aspeed
+ arm/sabrelite
arm/digic
arm/musicpal
arm/gumstix
diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
index bf7b8f4c64..bf886268c5 100644
--- a/hw/arm/highbank.c
+++ b/hw/arm/highbank.c
@@ -26,7 +26,6 @@
#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"
@@ -38,6 +37,7 @@
#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
@@ -396,15 +396,9 @@ 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);
}
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
index 458b1cbeb7..6aec84aeed 100644
--- a/hw/arm/musicpal.c
+++ b/hw/arm/musicpal.c
@@ -959,6 +959,17 @@ 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,
@@ -994,6 +1005,7 @@ 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,
};
diff --git a/hw/arm/sabrelite.c b/hw/arm/sabrelite.c
index 91d8c43a7e..a3dbf85e0e 100644
--- a/hw/arm/sabrelite.c
+++ b/hw/arm/sabrelite.c
@@ -51,6 +51,10 @@ 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,
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 711cf2069f..9d9ee24053 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -59,11 +59,12 @@
#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)));
@@ -484,7 +485,7 @@ 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));
@@ -603,7 +604,7 @@ 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 bf3a717111..86070dfd98 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -323,7 +323,7 @@ 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");
@@ -350,6 +350,7 @@ 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
@@ -364,7 +365,7 @@ 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) {
@@ -377,7 +378,7 @@ 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);
@@ -387,8 +388,7 @@ 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");
}
@@ -534,7 +534,7 @@ 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");
@@ -1674,9 +1674,9 @@ 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;
@@ -1829,8 +1829,6 @@ 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");
@@ -1846,6 +1844,7 @@ 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;
@@ -1966,7 +1965,7 @@ 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);
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index 01b657b1c5..27d2c72716 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -1052,7 +1052,6 @@ 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) {
@@ -1334,7 +1333,6 @@ 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 6e52539648..bc2e322970 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -941,10 +941,8 @@ 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 cf08ef9728..b20038991a 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -741,7 +741,6 @@ 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;
@@ -1138,7 +1137,6 @@ 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 e85821637c..b49e4cfbc6 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -2716,7 +2716,6 @@ 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 89239b5634..e1d2e46083 100644
--- a/hw/input/hid.c
+++ b/hw/input/hid.c
@@ -88,7 +88,6 @@ 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 1c8be40d8b..3ada22f427 100644
--- a/hw/intc/apic.c
+++ b/hw/intc/apic.c
@@ -888,7 +888,6 @@ 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/arm_gic.c b/hw/intc/arm_gic.c
index c60dc6b5e6..af41e2fb44 100644
--- a/hw/intc/arm_gic.c
+++ b/hw/intc/arm_gic.c
@@ -141,6 +141,8 @@ 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;
}
@@ -149,7 +151,7 @@ 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;
}
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index f63aa2d871..0d8426dafc 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -1106,6 +1106,12 @@ 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)) {
@@ -1683,6 +1689,15 @@ 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;
diff --git a/hw/intc/ioapic.c b/hw/intc/ioapic.c
index a3021a4de1..264262959d 100644
--- a/hw/intc/ioapic.c
+++ b/hw/intc/ioapic.c
@@ -474,7 +474,6 @@ 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 e141a5cd45..acf2bab35f 100644
--- a/hw/ipmi/ipmi_bmc_extern.c
+++ b/hw/ipmi/ipmi_bmc_extern.c
@@ -511,7 +511,6 @@ 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/misc/imx6_ccm.c b/hw/misc/imx6_ccm.c
index cb740427ec..4c830fd89a 100644
--- a/hw/misc/imx6_ccm.c
+++ b/hw/misc/imx6_ccm.c
@@ -450,7 +450,7 @@ 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;
@@ -462,7 +462,7 @@ 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;
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
index d7d05ae30a..d8da2f6528 100644
--- a/hw/net/e1000.c
+++ b/hw/net/e1000.c
@@ -1647,11 +1647,8 @@ 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 095c01ebc6..4dcb92d966 100644
--- a/hw/net/e1000e_core.c
+++ b/hw/net/e1000e_core.c
@@ -434,23 +434,16 @@ 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);
}
}
@@ -3355,7 +3348,6 @@ 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 ccc3fce2a0..95d27102aa 100644
--- a/hw/net/pcnet-pci.c
+++ b/hw/net/pcnet-pci.c
@@ -183,7 +183,6 @@ 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 ba5ace1ab7..4675ac878e 100644
--- a/hw/net/rtl8139.c
+++ b/hw/net/rtl8139.c
@@ -3338,7 +3338,6 @@ 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 581320a0e7..10e85a4556 100644
--- a/hw/net/spapr_llan.c
+++ b/hw/net/spapr_llan.c
@@ -363,7 +363,6 @@ 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 8356eeec13..09ceb02c9d 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -1862,7 +1862,6 @@ 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);
@@ -2645,7 +2644,6 @@ 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/rtc/exynos4210_rtc.c b/hw/rtc/exynos4210_rtc.c
index 4c97624478..45c0a951c4 100644
--- a/hw/rtc/exynos4210_rtc.c
+++ b/hw/rtc/exynos4210_rtc.c
@@ -584,6 +584,14 @@ 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);
@@ -597,6 +605,7 @@ 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,
};
diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
index 76b08a39a7..654fac6c0a 100644
--- a/hw/s390x/s390-pci-inst.c
+++ b/hw/s390x/s390-pci-inst.c
@@ -955,7 +955,6 @@ 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 2aeab39c3f..4375ed5b8b 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -2133,7 +2133,6 @@ 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 2f8b74a84f..8ffa53999d 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -1330,9 +1330,7 @@ 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/timer/allwinner-a10-pit.c b/hw/timer/allwinner-a10-pit.c
index f84fc0ea25..c3fc2a4daa 100644
--- a/hw/timer/allwinner-a10-pit.c
+++ b/hw/timer/allwinner-a10-pit.c
@@ -279,6 +279,16 @@ 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);
@@ -294,6 +304,7 @@ 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,
};
diff --git a/hw/timer/digic-timer.c b/hw/timer/digic-timer.c
index 32612228da..e3aae4a45a 100644
--- a/hw/timer/digic-timer.c
+++ b/hw/timer/digic-timer.c
@@ -154,6 +154,13 @@ 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);
@@ -167,6 +174,7 @@ 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,
};
diff --git a/hw/timer/exynos4210_mct.c b/hw/timer/exynos4210_mct.c
index 439053acd2..d0e5343996 100644
--- a/hw/timer/exynos4210_mct.c
+++ b/hw/timer/exynos4210_mct.c
@@ -1530,6 +1530,19 @@ 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);
@@ -1543,6 +1556,7 @@ 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,
};
diff --git a/hw/timer/exynos4210_pwm.c b/hw/timer/exynos4210_pwm.c
index de181428b4..220088120e 100644
--- a/hw/timer/exynos4210_pwm.c
+++ b/hw/timer/exynos4210_pwm.c
@@ -410,6 +410,16 @@ 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);
@@ -423,6 +433,7 @@ 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,
};
diff --git a/hw/timer/mss-timer.c b/hw/timer/mss-timer.c
index 29943fd744..fe0ca905f3 100644
--- a/hw/timer/mss-timer.c
+++ b/hw/timer/mss-timer.c
@@ -244,6 +244,18 @@ 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,
@@ -287,6 +299,7 @@ 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,
};
diff --git a/hw/usb/dev-hub.c b/hw/usb/dev-hub.c
index 40c1f90694..e35813d772 100644
--- a/hw/usb/dev-hub.c
+++ b/hw/usb/dev-hub.c
@@ -576,7 +576,6 @@ 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 ae7f20c502..aca018d8b5 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -2534,7 +2534,6 @@ 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 f95199e0bb..8e1146b862 100644
--- a/hw/usb/hcd-ohci-pci.c
+++ b/hw/usb/hcd-ohci-pci.c
@@ -97,7 +97,6 @@ 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 27ca237d71..5969eb86b3 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -1283,7 +1283,6 @@ 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 9ce7ca706e..46212b1e69 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -3395,7 +3395,6 @@ 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 03b6f61f75..7e9e3fecbf 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -1481,7 +1481,6 @@ 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 342054193b..42d67e870b 100644
--- a/hw/vfio/display.c
+++ b/hw/vfio/display.c
@@ -186,7 +186,6 @@ 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 5b2ebf3496..4ad6e234ad 100644
--- a/hw/virtio/vhost-vsock-common.c
+++ b/hw/virtio/vhost-vsock-common.c
@@ -151,7 +151,6 @@ 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 e83017c02d..e770955176 100644
--- a/hw/virtio/virtio-balloon.c
+++ b/hw/virtio/virtio-balloon.c
@@ -204,7 +204,6 @@ 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 2886c0ce2a..76ce937693 100644
--- a/hw/virtio/virtio-rng.c
+++ b/hw/virtio/virtio-rng.c
@@ -233,7 +233,6 @@ 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 4c4b6a6ab7..e135a4de8b 100644
--- a/hw/watchdog/wdt_diag288.c
+++ b/hw/watchdog/wdt_diag288.c
@@ -110,7 +110,6 @@ 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 502f45a939..4c52e3bb9e 100644
--- a/hw/watchdog/wdt_i6300esb.c
+++ b/hw/watchdog/wdt_i6300esb.c
@@ -454,7 +454,6 @@ static void i6300esb_exit(PCIDevice *dev)
{
I6300State *d = WATCHDOG_I6300ESB_DEVICE(dev);
- timer_del(d->timer);
timer_free(d->timer);
}
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index abf54fab49..e4a2d21642 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -151,7 +151,6 @@ struct VirtMachineState {
MemMapEntry *memmap;
char *pciehb_nodename;
const int *irqmap;
- int smp_cpus;
void *fdt;
int fdt_size;
uint32_t clock_phandle;
@@ -182,7 +181,7 @@ 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/include/qemu/timer.h b/include/qemu/timer.h
index bdecc5b41f..61296ea980 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -610,17 +610,6 @@ 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
*
@@ -632,6 +621,19 @@ 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
* @expire_time: the expiry time in nanoseconds
diff --git a/migration/colo.c b/migration/colo.c
index 3f1d3dfd95..de27662cab 100644
--- a/migration/colo.c
+++ b/migration/colo.c
@@ -636,7 +636,6 @@ 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 0dd594f92b..fd4d77e246 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -1586,7 +1586,6 @@ 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 db90d3bd4b..26f057f5ee 100644
--- a/net/announce.c
+++ b/net/announce.c
@@ -41,7 +41,6 @@ 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 337025b44f..84db4978ac 100644
--- a/net/colo-compare.c
+++ b/net/colo-compare.c
@@ -951,7 +951,6 @@ 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 77042e6df7..8350c6d45f 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -184,7 +184,6 @@ 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 1d6a968406..5ec574724a 100644
--- a/replay/replay-debugging.c
+++ b/replay/replay-debugging.c
@@ -78,7 +78,6 @@ 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/scripts/coccinelle/timer-del-timer-free.cocci b/scripts/coccinelle/timer-del-timer-free.cocci
new file mode 100644
index 0000000000..c3cfd42803
--- /dev/null
+++ b/scripts/coccinelle/timer-del-timer-free.cocci
@@ -0,0 +1,18 @@
+// 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);
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 62e319eb6a..8387e94b94 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1305,8 +1305,6 @@ 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
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
index 0013e25412..98544db2df 100644
--- a/target/arm/cpu_tcg.c
+++ b/target/arm/cpu_tcg.c
@@ -401,6 +401,46 @@ 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,
@@ -655,6 +695,8 @@ 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 },
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 2d0d4cd1e1..d077dd9ef5 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -12928,7 +12928,7 @@ 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);
}
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
index 0db936084b..10766f210c 100644
--- a/target/arm/translate-vfp.c.inc
+++ b/target/arm/translate-vfp.c.inc
@@ -663,6 +663,7 @@ 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;
}
@@ -674,13 +675,48 @@ 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,
@@ -688,6 +724,7 @@ 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:
@@ -721,10 +758,20 @@ 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, 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);
@@ -732,11 +779,8 @@ 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;
@@ -744,6 +788,9 @@ 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;
}
@@ -753,6 +800,8 @@ 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:
@@ -811,12 +860,59 @@ 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;
}
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
index 8a734c2f8c..7da70afbf2 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -313,9 +313,7 @@ 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 4db5b04cc2..d80ce7037c 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -253,7 +253,6 @@ 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 eea52f5389..5746d0aae7 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
@@ -76,7 +76,6 @@ 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 b38e742da5..81f247a8d1 100644
--- a/util/throttle.c
+++ b/util/throttle.c
@@ -247,7 +247,6 @@ static void throttle_timer_destroy(QEMUTimer **timer)
{
assert(*timer != NULL);
- timer_del(*timer);
timer_free(*timer);
*timer = NULL;
}