aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/alpha/typhoon.c47
-rw-r--r--hw/arm/allwinner-a10.c6
-rw-r--r--hw/arm/armv7m.c5
-rw-r--r--hw/arm/boot.c8
-rw-r--r--hw/arm/nrf51_soc.c117
-rw-r--r--hw/arm/virt.c46
-rw-r--r--hw/arm/xlnx-versal-virt.c2
-rw-r--r--hw/arm/xlnx-zynqmp.c23
-rw-r--r--hw/core/loader.c19
-rw-r--r--hw/core/machine.c349
-rw-r--r--hw/core/qdev-properties.c49
-rw-r--r--hw/core/qdev.c15
-rw-r--r--hw/core/uboot_image.h1
-rw-r--r--hw/cpu/Makefile.objs2
-rw-r--r--hw/cpu/cluster.c50
-rw-r--r--hw/display/qxl.c2
-rw-r--r--hw/display/ramfb-standalone.c1
-rw-r--r--hw/gpio/Makefile.objs1
-rw-r--r--hw/gpio/nrf51_gpio.c300
-rw-r--r--hw/gpio/trace-events7
-rw-r--r--hw/i386/kvm/ioapic.c2
-rw-r--r--hw/i386/pc.c678
-rw-r--r--hw/i386/pc_piix.c508
-rw-r--r--hw/i386/pc_q35.c89
-rw-r--r--hw/ide/pci.c1
-rw-r--r--hw/ide/piix.c1
-rw-r--r--hw/ide/via.c1
-rw-r--r--hw/intc/ioapic.c2
-rw-r--r--hw/intc/spapr_xive.c23
-rw-r--r--hw/intc/xics.c4
-rw-r--r--hw/intc/xics_kvm.c3
-rw-r--r--hw/intc/xics_spapr.c10
-rw-r--r--hw/intc/xive.c11
-rw-r--r--hw/microblaze/boot.c2
-rw-r--r--hw/misc/Makefile.objs1
-rw-r--r--hw/misc/macio/mac_dbdma.c1
-rw-r--r--hw/misc/nrf51_rng.c262
-rw-r--r--hw/misc/tz-mpc.c2
-rw-r--r--hw/moxie/moxiesim.c1
-rw-r--r--hw/nios2/boot.c2
-rw-r--r--hw/nvram/fw_cfg.c1
-rw-r--r--hw/pci/pci.c33
-rw-r--r--hw/ppc/e500.c1
-rw-r--r--hw/ppc/pnv.c27
-rw-r--r--hw/ppc/pnv_core.c4
-rw-r--r--hw/ppc/pnv_psi.c7
-rw-r--r--hw/ppc/ppc440_bamboo.c2
-rw-r--r--hw/ppc/ppc4xx_devs.c3
-rw-r--r--hw/ppc/sam460ex.c2
-rw-r--r--hw/ppc/spapr.c287
-rw-r--r--hw/ppc/spapr_cpu_core.c9
-rw-r--r--hw/ppc/spapr_hcall.c93
-rw-r--r--hw/ppc/spapr_irq.c270
-rw-r--r--hw/ppc/spapr_pci.c11
-rw-r--r--hw/ppc/trace-events3
-rw-r--r--hw/s390x/s390-virtio-ccw.c196
-rw-r--r--hw/sparc/sun4m.c1
-rw-r--r--hw/timer/Makefile.objs1
-rw-r--r--hw/timer/i8254.c1
-rw-r--r--hw/timer/nrf51_timer.c393
-rw-r--r--hw/timer/trace-events5
-rw-r--r--hw/usb/bus.c6
-rw-r--r--hw/usb/ccid-card-emulated.c2
-rw-r--r--hw/usb/dev-mtp.c1
-rw-r--r--hw/usb/hcd-ehci-pci.c53
-rw-r--r--hw/usb/hcd-ehci-sysbus.c17
-rw-r--r--hw/usb/hcd-ehci.h1
-rw-r--r--hw/xen/xen-common.c41
68 files changed, 3326 insertions, 799 deletions
diff --git a/hw/alpha/typhoon.c b/hw/alpha/typhoon.c
index 8004afe45b..cbacea5fbd 100644
--- a/hw/alpha/typhoon.c
+++ b/hw/alpha/typhoon.c
@@ -75,7 +75,9 @@ static void cpu_irq_change(AlphaCPU *cpu, uint64_t req)
}
}
-static uint64_t cchip_read(void *opaque, hwaddr addr, unsigned size)
+static MemTxResult cchip_read(void *opaque, hwaddr addr,
+ uint64_t *data, unsigned size,
+ MemTxAttrs attrs)
{
CPUState *cpu = current_cpu;
TyphoonState *s = opaque;
@@ -196,11 +198,11 @@ static uint64_t cchip_read(void *opaque, hwaddr addr, unsigned size)
break;
default:
- cpu_unassigned_access(cpu, addr, false, false, 0, size);
- return -1;
+ return MEMTX_ERROR;
}
- return ret;
+ *data = ret;
+ return MEMTX_OK;
}
static uint64_t dchip_read(void *opaque, hwaddr addr, unsigned size)
@@ -209,7 +211,8 @@ static uint64_t dchip_read(void *opaque, hwaddr addr, unsigned size)
return 0;
}
-static uint64_t pchip_read(void *opaque, hwaddr addr, unsigned size)
+static MemTxResult pchip_read(void *opaque, hwaddr addr, uint64_t *data,
+ unsigned size, MemTxAttrs attrs)
{
TyphoonState *s = opaque;
uint64_t ret = 0;
@@ -294,15 +297,16 @@ static uint64_t pchip_read(void *opaque, hwaddr addr, unsigned size)
break;
default:
- cpu_unassigned_access(current_cpu, addr, false, false, 0, size);
- return -1;
+ return MEMTX_ERROR;
}
- return ret;
+ *data = ret;
+ return MEMTX_OK;
}
-static void cchip_write(void *opaque, hwaddr addr,
- uint64_t val, unsigned size)
+static MemTxResult cchip_write(void *opaque, hwaddr addr,
+ uint64_t val, unsigned size,
+ MemTxAttrs attrs)
{
TyphoonState *s = opaque;
uint64_t oldval, newval;
@@ -446,9 +450,10 @@ static void cchip_write(void *opaque, hwaddr addr,
break;
default:
- cpu_unassigned_access(current_cpu, addr, true, false, 0, size);
- return;
+ return MEMTX_ERROR;
}
+
+ return MEMTX_OK;
}
static void dchip_write(void *opaque, hwaddr addr,
@@ -457,8 +462,9 @@ static void dchip_write(void *opaque, hwaddr addr,
/* Skip this. It's all related to DRAM timing and setup. */
}
-static void pchip_write(void *opaque, hwaddr addr,
- uint64_t val, unsigned size)
+static MemTxResult pchip_write(void *opaque, hwaddr addr,
+ uint64_t val, unsigned size,
+ MemTxAttrs attrs)
{
TyphoonState *s = opaque;
uint64_t oldval;
@@ -553,14 +559,15 @@ static void pchip_write(void *opaque, hwaddr addr,
break;
default:
- cpu_unassigned_access(current_cpu, addr, true, false, 0, size);
- return;
+ return MEMTX_ERROR;
}
+
+ return MEMTX_OK;
}
static const MemoryRegionOps cchip_ops = {
- .read = cchip_read,
- .write = cchip_write,
+ .read_with_attrs = cchip_read,
+ .write_with_attrs = cchip_write,
.endianness = DEVICE_LITTLE_ENDIAN,
.valid = {
.min_access_size = 8,
@@ -587,8 +594,8 @@ static const MemoryRegionOps dchip_ops = {
};
static const MemoryRegionOps pchip_ops = {
- .read = pchip_read,
- .write = pchip_write,
+ .read_with_attrs = pchip_read,
+ .write_with_attrs = pchip_write,
.endianness = DEVICE_LITTLE_ENDIAN,
.valid = {
.min_access_size = 8,
diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c
index 9fe875cdb5..df0d079ad0 100644
--- a/hw/arm/allwinner-a10.c
+++ b/hw/arm/allwinner-a10.c
@@ -22,6 +22,7 @@
#include "hw/sysbus.h"
#include "hw/devices.h"
#include "hw/arm/allwinner-a10.h"
+#include "hw/misc/unimp.h"
static void aw_a10_init(Object *obj)
{
@@ -85,6 +86,11 @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
sysbus_connect_irq(sysbusdev, 4, s->irq[67]);
sysbus_connect_irq(sysbusdev, 5, s->irq[68]);
+ memory_region_init_ram(&s->sram_a, OBJECT(dev), "sram A", 48 * KiB,
+ &error_fatal);
+ memory_region_add_subregion(get_system_memory(), 0x00000000, &s->sram_a);
+ create_unimplemented_device("a10-sram-ctrl", 0x01c00000, 4 * KiB);
+
/* FIXME use qdev NIC properties instead of nd_table[] */
if (nd_table[0].used) {
qemu_check_nic_model(&nd_table[0], TYPE_AW_EMAC);
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index 4bf9131b81..f444652830 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -285,11 +285,6 @@ void armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename, int mem_size)
big_endian = 0;
#endif
- if (!kernel_filename && !qtest_enabled()) {
- error_report("Guest image must be specified (using -kernel)");
- exit(1);
- }
-
if (arm_feature(&cpu->env, ARM_FEATURE_EL3)) {
asidx = ARMASIdx_S;
} else {
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 94fce12802..c7a67af7a9 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -30,8 +30,9 @@
* Documentation/arm/Booting and Documentation/arm64/booting.txt
* They have different preferred image load offsets from system RAM base.
*/
-#define KERNEL_ARGS_ADDR 0x100
-#define KERNEL_LOAD_ADDR 0x00010000
+#define KERNEL_ARGS_ADDR 0x100
+#define KERNEL_NOLOAD_ADDR 0x02000000
+#define KERNEL_LOAD_ADDR 0x00010000
#define KERNEL64_LOAD_ADDR 0x00080000
#define ARM64_TEXT_OFFSET_OFFSET 8
@@ -1082,7 +1083,8 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
}
entry = elf_entry;
if (kernel_size < 0) {
- kernel_size = load_uimage_as(info->kernel_filename, &entry, NULL,
+ uint64_t loadaddr = info->loader_start + KERNEL_NOLOAD_ADDR;
+ kernel_size = load_uimage_as(info->kernel_filename, &entry, &loadaddr,
&is_linux, NULL, NULL, as);
}
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64) && kernel_size < 0) {
diff --git a/hw/arm/nrf51_soc.c b/hw/arm/nrf51_soc.c
index b89c1bdea0..1630c27594 100644
--- a/hw/arm/nrf51_soc.c
+++ b/hw/arm/nrf51_soc.c
@@ -21,35 +21,46 @@
#include "qemu/log.h"
#include "cpu.h"
+#include "hw/arm/nrf51.h"
#include "hw/arm/nrf51_soc.h"
-#define IOMEM_BASE 0x40000000
-#define IOMEM_SIZE 0x20000000
-
-#define FICR_BASE 0x10000000
-#define FICR_SIZE 0x000000fc
-
-#define FLASH_BASE 0x00000000
-#define SRAM_BASE 0x20000000
-
-#define PRIVATE_BASE 0xF0000000
-#define PRIVATE_SIZE 0x10000000
-
/*
* The size and base is for the NRF51822 part. If other parts
* are supported in the future, add a sub-class of NRF51SoC for
* the specific variants
*/
-#define NRF51822_FLASH_SIZE (256 * 1024)
-#define NRF51822_SRAM_SIZE (16 * 1024)
+#define NRF51822_FLASH_SIZE (256 * NRF51_PAGE_SIZE)
+#define NRF51822_SRAM_SIZE (16 * NRF51_PAGE_SIZE)
#define BASE_TO_IRQ(base) ((base >> 12) & 0x1F)
+static uint64_t clock_read(void *opaque, hwaddr addr, unsigned int size)
+{
+ qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx " [%u]\n",
+ __func__, addr, size);
+ return 1;
+}
+
+static void clock_write(void *opaque, hwaddr addr, uint64_t data,
+ unsigned int size)
+{
+ qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx " <- 0x%" PRIx64 " [%u]\n",
+ __func__, addr, data, size);
+}
+
+static const MemoryRegionOps clock_ops = {
+ .read = clock_read,
+ .write = clock_write
+};
+
+
static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
{
NRF51State *s = NRF51_SOC(dev_soc);
MemoryRegion *mr;
Error *err = NULL;
+ uint8_t i = 0;
+ hwaddr base_addr = 0;
if (!s->board_memory) {
error_setg(errp, "memory property was not set");
@@ -76,14 +87,14 @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
error_propagate(errp, err);
return;
}
- memory_region_add_subregion(&s->container, FLASH_BASE, &s->flash);
+ memory_region_add_subregion(&s->container, NRF51_FLASH_BASE, &s->flash);
memory_region_init_ram(&s->sram, NULL, "nrf51.sram", s->sram_size, &err);
if (err) {
error_propagate(errp, err);
return;
}
- memory_region_add_subregion(&s->container, SRAM_BASE, &s->sram);
+ memory_region_add_subregion(&s->container, NRF51_SRAM_BASE, &s->sram);
/* UART */
object_property_set_bool(OBJECT(&s->uart), true, "realized", &err);
@@ -92,19 +103,71 @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
return;
}
mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->uart), 0);
- memory_region_add_subregion_overlap(&s->container, UART_BASE, mr, 0);
+ memory_region_add_subregion_overlap(&s->container, NRF51_UART_BASE, mr, 0);
sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart), 0,
qdev_get_gpio_in(DEVICE(&s->cpu),
- BASE_TO_IRQ(UART_BASE)));
+ BASE_TO_IRQ(NRF51_UART_BASE)));
+
+ /* RNG */
+ object_property_set_bool(OBJECT(&s->rng), true, "realized", &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->rng), 0);
+ memory_region_add_subregion_overlap(&s->container, NRF51_RNG_BASE, mr, 0);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->rng), 0,
+ qdev_get_gpio_in(DEVICE(&s->cpu),
+ BASE_TO_IRQ(NRF51_RNG_BASE)));
+
+ /* GPIO */
+ object_property_set_bool(OBJECT(&s->gpio), true, "realized", &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->gpio), 0);
+ memory_region_add_subregion_overlap(&s->container, NRF51_GPIO_BASE, mr, 0);
+
+ /* Pass all GPIOs to the SOC layer so they are available to the board */
+ qdev_pass_gpios(DEVICE(&s->gpio), dev_soc, NULL);
+
+ /* TIMER */
+ for (i = 0; i < NRF51_NUM_TIMERS; i++) {
+ object_property_set_bool(OBJECT(&s->timer[i]), true, "realized", &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+
+ base_addr = NRF51_TIMER_BASE + i * NRF51_TIMER_SIZE;
- create_unimplemented_device("nrf51_soc.io", IOMEM_BASE, IOMEM_SIZE);
- create_unimplemented_device("nrf51_soc.ficr", FICR_BASE, FICR_SIZE);
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->timer[i]), 0, base_addr);
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer[i]), 0,
+ qdev_get_gpio_in(DEVICE(&s->cpu),
+ BASE_TO_IRQ(base_addr)));
+ }
+
+ /* STUB Peripherals */
+ memory_region_init_io(&s->clock, NULL, &clock_ops, NULL,
+ "nrf51_soc.clock", 0x1000);
+ memory_region_add_subregion_overlap(&s->container,
+ NRF51_IOMEM_BASE, &s->clock, -1);
+
+ create_unimplemented_device("nrf51_soc.io", NRF51_IOMEM_BASE,
+ NRF51_IOMEM_SIZE);
+ create_unimplemented_device("nrf51_soc.ficr", NRF51_FICR_BASE,
+ NRF51_FICR_SIZE);
create_unimplemented_device("nrf51_soc.private",
- PRIVATE_BASE, PRIVATE_SIZE);
+ NRF51_PRIVATE_BASE, NRF51_PRIVATE_SIZE);
}
static void nrf51_soc_init(Object *obj)
{
+ uint8_t i = 0;
+
NRF51State *s = NRF51_SOC(obj);
memory_region_init(&s->container, obj, "nrf51-container", UINT64_MAX);
@@ -119,6 +182,18 @@ static void nrf51_soc_init(Object *obj)
TYPE_NRF51_UART);
object_property_add_alias(obj, "serial0", OBJECT(&s->uart), "chardev",
&error_abort);
+
+ sysbus_init_child_obj(obj, "rng", &s->rng, sizeof(s->rng),
+ TYPE_NRF51_RNG);
+
+ sysbus_init_child_obj(obj, "gpio", &s->gpio, sizeof(s->gpio),
+ TYPE_NRF51_GPIO);
+
+ for (i = 0; i < NRF51_NUM_TIMERS; i++) {
+ sysbus_init_child_obj(obj, "timer[*]", &s->timer[i],
+ sizeof(s->timer[i]), TYPE_NRF51_TIMER);
+
+ }
}
static Property nrf51_soc_properties[] = {
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index c2641e56ea..99c2b6e60d 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -43,7 +43,6 @@
#include "sysemu/numa.h"
#include "sysemu/sysemu.h"
#include "sysemu/kvm.h"
-#include "hw/compat.h"
#include "hw/loader.h"
#include "exec/address-spaces.h"
#include "qemu/bitops.h"
@@ -1872,84 +1871,63 @@ static void virt_machine_4_0_options(MachineClass *mc)
}
DEFINE_VIRT_MACHINE_AS_LATEST(4, 0)
-#define VIRT_COMPAT_3_1 \
- HW_COMPAT_3_1
-
static void virt_machine_3_1_options(MachineClass *mc)
{
virt_machine_4_0_options(mc);
- SET_MACHINE_COMPAT(mc, VIRT_COMPAT_3_1);
+ compat_props_add(mc->compat_props, hw_compat_3_1, hw_compat_3_1_len);
}
DEFINE_VIRT_MACHINE(3, 1)
-#define VIRT_COMPAT_3_0 \
- HW_COMPAT_3_0
-
static void virt_machine_3_0_options(MachineClass *mc)
{
virt_machine_3_1_options(mc);
- SET_MACHINE_COMPAT(mc, VIRT_COMPAT_3_0);
+ compat_props_add(mc->compat_props, hw_compat_3_0, hw_compat_3_0_len);
}
DEFINE_VIRT_MACHINE(3, 0)
-#define VIRT_COMPAT_2_12 \
- HW_COMPAT_2_12
-
static void virt_machine_2_12_options(MachineClass *mc)
{
VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
virt_machine_3_0_options(mc);
- SET_MACHINE_COMPAT(mc, VIRT_COMPAT_2_12);
+ compat_props_add(mc->compat_props, hw_compat_2_12, hw_compat_2_12_len);
vmc->no_highmem_ecam = true;
mc->max_cpus = 255;
}
DEFINE_VIRT_MACHINE(2, 12)
-#define VIRT_COMPAT_2_11 \
- HW_COMPAT_2_11
-
static void virt_machine_2_11_options(MachineClass *mc)
{
VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
virt_machine_2_12_options(mc);
- SET_MACHINE_COMPAT(mc, VIRT_COMPAT_2_11);
+ compat_props_add(mc->compat_props, hw_compat_2_11, hw_compat_2_11_len);
vmc->smbios_old_sys_ver = true;
}
DEFINE_VIRT_MACHINE(2, 11)
-#define VIRT_COMPAT_2_10 \
- HW_COMPAT_2_10
-
static void virt_machine_2_10_options(MachineClass *mc)
{
virt_machine_2_11_options(mc);
- SET_MACHINE_COMPAT(mc, VIRT_COMPAT_2_10);
+ compat_props_add(mc->compat_props, hw_compat_2_10, hw_compat_2_10_len);
/* before 2.11 we never faulted accesses to bad addresses */
mc->ignore_memory_transaction_failures = true;
}
DEFINE_VIRT_MACHINE(2, 10)
-#define VIRT_COMPAT_2_9 \
- HW_COMPAT_2_9
-
static void virt_machine_2_9_options(MachineClass *mc)
{
virt_machine_2_10_options(mc);
- SET_MACHINE_COMPAT(mc, VIRT_COMPAT_2_9);
+ compat_props_add(mc->compat_props, hw_compat_2_9, hw_compat_2_9_len);
}
DEFINE_VIRT_MACHINE(2, 9)
-#define VIRT_COMPAT_2_8 \
- HW_COMPAT_2_8
-
static void virt_machine_2_8_options(MachineClass *mc)
{
VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
virt_machine_2_9_options(mc);
- SET_MACHINE_COMPAT(mc, VIRT_COMPAT_2_8);
+ compat_props_add(mc->compat_props, hw_compat_2_8, hw_compat_2_8_len);
/* For 2.8 and earlier we falsely claimed in the DT that
* our timers were edge-triggered, not level-triggered.
*/
@@ -1957,15 +1935,12 @@ static void virt_machine_2_8_options(MachineClass *mc)
}
DEFINE_VIRT_MACHINE(2, 8)
-#define VIRT_COMPAT_2_7 \
- HW_COMPAT_2_7
-
static void virt_machine_2_7_options(MachineClass *mc)
{
VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
virt_machine_2_8_options(mc);
- SET_MACHINE_COMPAT(mc, VIRT_COMPAT_2_7);
+ compat_props_add(mc->compat_props, hw_compat_2_7, hw_compat_2_7_len);
/* ITS was introduced with 2.8 */
vmc->no_its = true;
/* Stick with 1K pages for migration compatibility */
@@ -1973,15 +1948,12 @@ static void virt_machine_2_7_options(MachineClass *mc)
}
DEFINE_VIRT_MACHINE(2, 7)
-#define VIRT_COMPAT_2_6 \
- HW_COMPAT_2_6
-
static void virt_machine_2_6_options(MachineClass *mc)
{
VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
virt_machine_2_7_options(mc);
- SET_MACHINE_COMPAT(mc, VIRT_COMPAT_2_6);
+ compat_props_add(mc->compat_props, hw_compat_2_6, hw_compat_2_6_len);
vmc->disallow_affinity_adjustment = true;
/* Disable PMU for 2.6 as PMU support was first introduced in 2.7 */
vmc->no_pmu = true;
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
index c6feeac532..f95fde2309 100644
--- a/hw/arm/xlnx-versal-virt.c
+++ b/hw/arm/xlnx-versal-virt.c
@@ -130,6 +130,7 @@ static void fdt_add_gic_nodes(VersalVirt *s)
2, MM_GIC_APU_REDIST_0_SIZE);
qemu_fdt_setprop_cell(s->fdt, nodename, "#interrupt-cells", 3);
qemu_fdt_setprop_string(s->fdt, nodename, "compatible", "arm,gic-v3");
+ g_free(nodename);
}
static void fdt_add_timer_nodes(VersalVirt *s)
@@ -364,6 +365,7 @@ static void create_virtio_regions(VersalVirt *s)
sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic_irq);
mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
memory_region_add_subregion(&s->soc.mr_ps, base, mr);
+ g_free(name);
}
for (i = 0; i < NUM_VIRTIO_TRANSPORT; i++) {
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
index c195040350..c67ac2e64a 100644
--- a/hw/arm/xlnx-zynqmp.c
+++ b/hw/arm/xlnx-zynqmp.c
@@ -178,12 +178,19 @@ static void xlnx_zynqmp_create_rpu(XlnxZynqMPState *s, const char *boot_cpu,
int i;
int num_rpus = MIN(smp_cpus - XLNX_ZYNQMP_NUM_APU_CPUS, XLNX_ZYNQMP_NUM_RPU_CPUS);
+ object_initialize_child(OBJECT(s), "rpu-cluster", &s->rpu_cluster,
+ sizeof(s->rpu_cluster), TYPE_CPU_CLUSTER,
+ &error_abort, NULL);
+ qdev_prop_set_uint32(DEVICE(&s->rpu_cluster), "cluster-id", 1);
+
+ qdev_init_nofail(DEVICE(&s->rpu_cluster));
+
for (i = 0; i < num_rpus; i++) {
char *name;
object_initialize(&s->rpu_cpu[i], sizeof(s->rpu_cpu[i]),
"cortex-r5f-" TYPE_ARM_CPU);
- object_property_add_child(OBJECT(s), "rpu-cpu[*]",
+ object_property_add_child(OBJECT(&s->rpu_cluster), "rpu-cpu[*]",
OBJECT(&s->rpu_cpu[i]), &error_abort);
name = object_get_canonical_path_component(OBJECT(&s->rpu_cpu[i]));
@@ -213,10 +220,16 @@ static void xlnx_zynqmp_init(Object *obj)
int i;
int num_apus = MIN(smp_cpus, XLNX_ZYNQMP_NUM_APU_CPUS);
+ object_initialize_child(obj, "apu-cluster", &s->apu_cluster,
+ sizeof(s->apu_cluster), TYPE_CPU_CLUSTER,
+ &error_abort, NULL);
+ qdev_prop_set_uint32(DEVICE(&s->apu_cluster), "cluster-id", 0);
+
for (i = 0; i < num_apus; i++) {
- object_initialize_child(obj, "apu-cpu[*]", &s->apu_cpu[i],
- sizeof(s->apu_cpu[i]),
- "cortex-a53-" TYPE_ARM_CPU, &error_abort, NULL);
+ object_initialize_child(OBJECT(&s->apu_cluster), "apu-cpu[*]",
+ &s->apu_cpu[i], sizeof(s->apu_cpu[i]),
+ "cortex-a53-" TYPE_ARM_CPU, &error_abort,
+ NULL);
}
sysbus_init_child_obj(obj, "gic", &s->gic, sizeof(s->gic),
@@ -333,6 +346,8 @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
qdev_prop_set_bit(DEVICE(&s->gic),
"has-virtualization-extensions", s->virt);
+ qdev_init_nofail(DEVICE(&s->apu_cluster));
+
/* Realize APUs before realizing the GIC. KVM requires this. */
for (i = 0; i < num_apus; i++) {
char *name;
diff --git a/hw/core/loader.c b/hw/core/loader.c
index fa41842280..c7182dfa64 100644
--- a/hw/core/loader.c
+++ b/hw/core/loader.c
@@ -613,13 +613,26 @@ static int load_uboot_image(const char *filename, hwaddr *ep, hwaddr *loadaddr,
goto out;
if (hdr->ih_type != image_type) {
- fprintf(stderr, "Wrong image type %d, expected %d\n", hdr->ih_type,
- image_type);
- goto out;
+ if (!(image_type == IH_TYPE_KERNEL &&
+ hdr->ih_type == IH_TYPE_KERNEL_NOLOAD)) {
+ fprintf(stderr, "Wrong image type %d, expected %d\n", hdr->ih_type,
+ image_type);
+ goto out;
+ }
}
/* TODO: Implement other image types. */
switch (hdr->ih_type) {
+ case IH_TYPE_KERNEL_NOLOAD:
+ if (!loadaddr || *loadaddr == LOAD_UIMAGE_LOADADDR_INVALID) {
+ fprintf(stderr, "this image format (kernel_noload) cannot be "
+ "loaded on this machine type");
+ goto out;
+ }
+
+ hdr->ih_load = *loadaddr + sizeof(*hdr);
+ hdr->ih_ep += hdr->ih_load;
+ /* fall through */
case IH_TYPE_KERNEL:
address = hdr->ih_load;
if (translate_fn) {
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 4439ea663f..1a0a9ab111 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -21,6 +21,334 @@
#include "sysemu/numa.h"
#include "qemu/error-report.h"
#include "sysemu/qtest.h"
+#include "hw/pci/pci.h"
+
+GlobalProperty hw_compat_3_1[] = {
+ {
+ .driver = "pcie-root-port",
+ .property = "x-speed",
+ .value = "2_5",
+ },{
+ .driver = "pcie-root-port",
+ .property = "x-width",
+ .value = "1",
+ },{
+ .driver = "memory-backend-file",
+ .property = "x-use-canonical-path-for-ramblock-id",
+ .value = "true",
+ },{
+ .driver = "memory-backend-memfd",
+ .property = "x-use-canonical-path-for-ramblock-id",
+ .value = "true",
+ },
+};
+const size_t hw_compat_3_1_len = G_N_ELEMENTS(hw_compat_3_1);
+
+GlobalProperty hw_compat_3_0[] = {};
+const size_t hw_compat_3_0_len = G_N_ELEMENTS(hw_compat_3_0);
+
+GlobalProperty hw_compat_2_12[] = {
+ {
+ .driver = "migration",
+ .property = "decompress-error-check",
+ .value = "off",
+ },{
+ .driver = "hda-audio",
+ .property = "use-timer",
+ .value = "false",
+ },{
+ .driver = "cirrus-vga",
+ .property = "global-vmstate",
+ .value = "true",
+ },{
+ .driver = "VGA",
+ .property = "global-vmstate",
+ .value = "true",
+ },{
+ .driver = "vmware-svga",
+ .property = "global-vmstate",
+ .value = "true",
+ },{
+ .driver = "qxl-vga",
+ .property = "global-vmstate",
+ .value = "true",
+ },
+};
+const size_t hw_compat_2_12_len = G_N_ELEMENTS(hw_compat_2_12);
+
+GlobalProperty hw_compat_2_11[] = {
+ {
+ .driver = "hpet",
+ .property = "hpet-offset-saved",
+ .value = "false",
+ },{
+ .driver = "virtio-blk-pci",
+ .property = "vectors",
+ .value = "2",
+ },{
+ .driver = "vhost-user-blk-pci",
+ .property = "vectors",
+ .value = "2",
+ },{
+ .driver = "e1000",
+ .property = "migrate_tso_props",
+ .value = "off",
+ },
+};
+const size_t hw_compat_2_11_len = G_N_ELEMENTS(hw_compat_2_11);
+
+GlobalProperty hw_compat_2_10[] = {
+ {
+ .driver = "virtio-mouse-device",
+ .property = "wheel-axis",
+ .value = "false",
+ },{
+ .driver = "virtio-tablet-device",
+ .property = "wheel-axis",
+ .value = "false",
+ },
+};
+const size_t hw_compat_2_10_len = G_N_ELEMENTS(hw_compat_2_10);
+
+GlobalProperty hw_compat_2_9[] = {
+ {
+ .driver = "pci-bridge",
+ .property = "shpc",
+ .value = "off",
+ },{
+ .driver = "intel-iommu",
+ .property = "pt",
+ .value = "off",
+ },{
+ .driver = "virtio-net-device",
+ .property = "x-mtu-bypass-backend",
+ .value = "off",
+ },{
+ .driver = "pcie-root-port",
+ .property = "x-migrate-msix",
+ .value = "false",
+ },
+};
+const size_t hw_compat_2_9_len = G_N_ELEMENTS(hw_compat_2_9);
+
+GlobalProperty hw_compat_2_8[] = {
+ {
+ .driver = "fw_cfg_mem",
+ .property = "x-file-slots",
+ .value = stringify(0x10),
+ },{
+ .driver = "fw_cfg_io",
+ .property = "x-file-slots",
+ .value = stringify(0x10),
+ },{
+ .driver = "pflash_cfi01",
+ .property = "old-multiple-chip-handling",
+ .value = "on",
+ },{
+ .driver = "pci-bridge",
+ .property = "shpc",
+ .value = "on",
+ },{
+ .driver = TYPE_PCI_DEVICE,
+ .property = "x-pcie-extcap-init",
+ .value = "off",
+ },{
+ .driver = "virtio-pci",
+ .property = "x-pcie-deverr-init",
+ .value = "off",
+ },{
+ .driver = "virtio-pci",
+ .property = "x-pcie-lnkctl-init",
+ .value = "off",
+ },{
+ .driver = "virtio-pci",
+ .property = "x-pcie-pm-init",
+ .value = "off",
+ },{
+ .driver = "cirrus-vga",
+ .property = "vgamem_mb",
+ .value = "8",
+ },{
+ .driver = "isa-cirrus-vga",
+ .property = "vgamem_mb",
+ .value = "8",
+ },
+};
+const size_t hw_compat_2_8_len = G_N_ELEMENTS(hw_compat_2_8);
+
+GlobalProperty hw_compat_2_7[] = {
+ {
+ .driver = "virtio-pci",
+ .property = "page-per-vq",
+ .value = "on",
+ },{
+ .driver = "virtio-serial-device",
+ .property = "emergency-write",
+ .value = "off",
+ },{
+ .driver = "ioapic",
+ .property = "version",
+ .value = "0x11",
+ },{
+ .driver = "intel-iommu",
+ .property = "x-buggy-eim",
+ .value = "true",
+ },{
+ .driver = "virtio-pci",
+ .property = "x-ignore-backend-features",
+ .value = "on",
+ },
+};
+const size_t hw_compat_2_7_len = G_N_ELEMENTS(hw_compat_2_7);
+
+GlobalProperty hw_compat_2_6[] = {
+ {
+ .driver = "virtio-mmio",
+ .property = "format_transport_address",
+ .value = "off",
+ },{
+ .driver = "virtio-pci",
+ .property = "disable-modern",
+ .value = "on",
+ },{
+ .driver = "virtio-pci",
+ .property = "disable-legacy",
+ .value = "off",
+ },
+};
+const size_t hw_compat_2_6_len = G_N_ELEMENTS(hw_compat_2_6);
+
+GlobalProperty hw_compat_2_5[] = {
+ {
+ .driver = "isa-fdc",
+ .property = "fallback",
+ .value = "144",
+ },{
+ .driver = "pvscsi",
+ .property = "x-old-pci-configuration",
+ .value = "on",
+ },{
+ .driver = "pvscsi",
+ .property = "x-disable-pcie",
+ .value = "on",
+ },
+ {
+ .driver = "vmxnet3",
+ .property = "x-old-msi-offsets",
+ .value = "on",
+ },{
+ .driver = "vmxnet3",
+ .property = "x-disable-pcie",
+ .value = "on",
+ },
+};
+const size_t hw_compat_2_5_len = G_N_ELEMENTS(hw_compat_2_5);
+
+GlobalProperty hw_compat_2_4[] = {
+ {
+ .driver = "virtio-blk-device",
+ .property = "scsi",
+ .value = "true",
+ },{
+ .driver = "e1000",
+ .property = "extra_mac_registers",
+ .value = "off",
+ },{
+ .driver = "virtio-pci",
+ .property = "x-disable-pcie",
+ .value = "on",
+ },{
+ .driver = "virtio-pci",
+ .property = "migrate-extra",
+ .value = "off",
+ },{
+ .driver = "fw_cfg_mem",
+ .property = "dma_enabled",
+ .value = "off",
+ },{
+ .driver = "fw_cfg_io",
+ .property = "dma_enabled",
+ .value = "off",
+ }
+};
+const size_t hw_compat_2_4_len = G_N_ELEMENTS(hw_compat_2_4);
+
+GlobalProperty hw_compat_2_3[] = {
+ {
+ .driver = "virtio-blk-pci",
+ .property = "any_layout",
+ .value = "off",
+ },{
+ .driver = "virtio-balloon-pci",
+ .property = "any_layout",
+ .value = "off",
+ },{
+ .driver = "virtio-serial-pci",
+ .property = "any_layout",
+ .value = "off",
+ },{
+ .driver = "virtio-9p-pci",
+ .property = "any_layout",
+ .value = "off",
+ },{
+ .driver = "virtio-rng-pci",
+ .property = "any_layout",
+ .value = "off",
+ },{
+ .driver = TYPE_PCI_DEVICE,
+ .property = "x-pcie-lnksta-dllla",
+ .value = "off",
+ },{
+ .driver = "migration",
+ .property = "send-configuration",
+ .value = "off",
+ },{
+ .driver = "migration",
+ .property = "send-section-footer",
+ .value = "off",
+ },{
+ .driver = "migration",
+ .property = "store-global-state",
+ .value = "off",
+ },
+};
+const size_t hw_compat_2_3_len = G_N_ELEMENTS(hw_compat_2_3);
+
+GlobalProperty hw_compat_2_2[] = {};
+const size_t hw_compat_2_2_len = G_N_ELEMENTS(hw_compat_2_2);
+
+GlobalProperty hw_compat_2_1[] = {
+ {
+ .driver = "intel-hda",
+ .property = "old_msi_addr",
+ .value = "on",
+ },{
+ .driver = "VGA",
+ .property = "qemu-extended-regs",
+ .value = "off",
+ },{
+ .driver = "secondary-vga",
+ .property = "qemu-extended-regs",
+ .value = "off",
+ },{
+ .driver = "virtio-scsi-pci",
+ .property = "any_layout",
+ .value = "off",
+ },{
+ .driver = "usb-mouse",
+ .property = "usb_version",
+ .value = stringify(1),
+ },{
+ .driver = "usb-kbd",
+ .property = "usb_version",
+ .value = stringify(1),
+ },{
+ .driver = "virtio-pci",
+ .property = "virtio-pci-bus-master-bug-migration",
+ .value = "on",
+ },
+};
+const size_t hw_compat_2_1_len = G_N_ELEMENTS(hw_compat_2_1);
static char *machine_get_accel(Object *obj, Error **errp)
{
@@ -591,7 +919,7 @@ static void machine_class_init(ObjectClass *oc, void *data)
object_class_property_add_bool(oc, "dump-guest-core",
machine_get_dump_guest_core, machine_set_dump_guest_core, &error_abort);
object_class_property_set_description(oc, "dump-guest-core",
- "Include guest memory in a core dump", &error_abort);
+ "Include guest memory in a core dump", &error_abort);
object_class_property_add_bool(oc, "mem-merge",
machine_get_mem_merge, machine_set_mem_merge, &error_abort);
@@ -647,6 +975,7 @@ static void machine_class_base_init(ObjectClass *oc, void *data)
assert(g_str_has_suffix(cname, TYPE_MACHINE_SUFFIX));
mc->name = g_strndup(cname,
strlen(cname) - strlen(TYPE_MACHINE_SUFFIX));
+ mc->compat_props = g_ptr_array_new();
}
}
@@ -836,24 +1165,6 @@ void machine_run_board_init(MachineState *machine)
machine_class->init(machine);
}
-void machine_register_compat_props(MachineState *machine)
-{
- MachineClass *mc = MACHINE_GET_CLASS(machine);
- int i;
- GlobalProperty *p;
-
- if (!mc->compat_props) {
- return;
- }
-
- for (i = 0; i < mc->compat_props->len; i++) {
- p = g_array_index(mc->compat_props, GlobalProperty *, i);
- /* Machine compat_props must never cause errors: */
- p->errp = &error_abort;
- qdev_prop_register_global(p);
- }
-}
-
static const TypeInfo machine_info = {
.name = TYPE_MACHINE,
.parent = TYPE_OBJECT,
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 943dc2654b..5da1439a8b 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -1173,28 +1173,35 @@ void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value)
*ptr = value;
}
-static GList *global_props;
+static GPtrArray *global_props(void)
+{
+ static GPtrArray *gp;
+
+ if (!gp) {
+ gp = g_ptr_array_new();
+ }
+
+ return gp;
+}
void qdev_prop_register_global(GlobalProperty *prop)
{
- global_props = g_list_append(global_props, prop);
+ g_ptr_array_add(global_props(), prop);
}
int qdev_prop_check_globals(void)
{
- GList *l;
- int ret = 0;
+ int i, ret = 0;
- for (l = global_props; l; l = l->next) {
- GlobalProperty *prop = l->data;
+ for (i = 0; i < global_props()->len; i++) {
+ GlobalProperty *prop;
ObjectClass *oc;
DeviceClass *dc;
+
+ prop = g_ptr_array_index(global_props(), i);
if (prop->used) {
continue;
}
- if (!prop->user_provided) {
- continue;
- }
oc = object_class_by_name(prop->driver);
oc = object_class_dynamic_cast(oc, TYPE_DEVICE);
if (!oc) {
@@ -1216,28 +1223,8 @@ int qdev_prop_check_globals(void)
void qdev_prop_set_globals(DeviceState *dev)
{
- GList *l;
-
- for (l = global_props; l; l = l->next) {
- GlobalProperty *prop = l->data;
- Error *err = NULL;
-
- if (object_dynamic_cast(OBJECT(dev), prop->driver) == NULL) {
- continue;
- }
- prop->used = true;
- object_property_parse(OBJECT(dev), prop->value, prop->property, &err);
- if (err != NULL) {
- error_prepend(&err, "can't apply global %s.%s=%s: ",
- prop->driver, prop->property, prop->value);
- if (!dev->hotplugged && prop->errp) {
- error_propagate(prop->errp, err);
- } else {
- assert(prop->user_provided);
- warn_report_err(err);
- }
- }
- }
+ object_apply_global_props(OBJECT(dev), global_props(),
+ dev->hotplugged ? NULL : &error_fatal);
}
/* --- 64bit unsigned int 'size' type --- */
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 6b3cc55b27..3769a2bccb 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -970,8 +970,23 @@ static void device_initfn(Object *obj)
QLIST_INIT(&dev->gpios);
}
+void object_apply_compat_props(Object *obj)
+{
+ if (object_dynamic_cast(qdev_get_machine(), TYPE_MACHINE)) {
+ MachineState *m = MACHINE(qdev_get_machine());
+ MachineClass *mc = MACHINE_GET_CLASS(m);
+ AccelClass *ac = ACCEL_GET_CLASS(m->accelerator);
+
+ if (ac->compat_props) {
+ object_apply_global_props(obj, ac->compat_props, &error_abort);
+ }
+ object_apply_global_props(obj, mc->compat_props, &error_abort);
+ }
+}
+
static void device_post_init(Object *obj)
{
+ object_apply_compat_props(obj);
qdev_prop_set_globals(DEVICE(obj));
}
diff --git a/hw/core/uboot_image.h b/hw/core/uboot_image.h
index 34c11a70a6..608022de6e 100644
--- a/hw/core/uboot_image.h
+++ b/hw/core/uboot_image.h
@@ -124,6 +124,7 @@
#define IH_TYPE_SCRIPT 6 /* Script file */
#define IH_TYPE_FILESYSTEM 7 /* Filesystem Image (any type) */
#define IH_TYPE_FLATDT 8 /* Binary Flat Device Tree Blob */
+#define IH_TYPE_KERNEL_NOLOAD 14 /* OS Kernel Image (noload) */
/*
* Compression Types
diff --git a/hw/cpu/Makefile.objs b/hw/cpu/Makefile.objs
index cd52d20b65..8db9e8a7b3 100644
--- a/hw/cpu/Makefile.objs
+++ b/hw/cpu/Makefile.objs
@@ -2,4 +2,4 @@ obj-$(CONFIG_ARM11MPCORE) += arm11mpcore.o
obj-$(CONFIG_REALVIEW) += realview_mpcore.o
obj-$(CONFIG_A9MPCORE) += a9mpcore.o
obj-$(CONFIG_A15MPCORE) += a15mpcore.o
-common-obj-y += core.o
+common-obj-y += core.o cluster.o
diff --git a/hw/cpu/cluster.c b/hw/cpu/cluster.c
new file mode 100644
index 0000000000..9d50a235d5
--- /dev/null
+++ b/hw/cpu/cluster.c
@@ -0,0 +1,50 @@
+/*
+ * QEMU CPU cluster
+ *
+ * Copyright (c) 2018 GreenSocs SAS
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see
+ * <http://www.gnu.org/licenses/gpl-2.0.html>
+ */
+
+#include "qemu/osdep.h"
+#include "hw/cpu/cluster.h"
+#include "qapi/error.h"
+#include "qemu/module.h"
+
+static Property cpu_cluster_properties[] = {
+ DEFINE_PROP_UINT32("cluster-id", CPUClusterState, cluster_id, 0),
+ DEFINE_PROP_END_OF_LIST()
+};
+
+static void cpu_cluster_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ dc->props = cpu_cluster_properties;
+}
+
+static const TypeInfo cpu_cluster_type_info = {
+ .name = TYPE_CPU_CLUSTER,
+ .parent = TYPE_DEVICE,
+ .instance_size = sizeof(CPUClusterState),
+ .class_init = cpu_cluster_class_init,
+};
+
+static void cpu_cluster_register_types(void)
+{
+ type_register_static(&cpu_cluster_type_info);
+}
+
+type_init(cpu_cluster_register_types)
diff --git a/hw/display/qxl.c b/hw/display/qxl.c
index 9087db5dee..8e9a65e75b 100644
--- a/hw/display/qxl.c
+++ b/hw/display/qxl.c
@@ -1189,9 +1189,7 @@ static void qxl_enter_vga_mode(PCIQXLDevice *d)
return;
}
trace_qxl_enter_vga_mode(d->id);
-#if SPICE_SERVER_VERSION >= 0x000c03 /* release 0.12.3 */
spice_qxl_driver_unload(&d->ssd.qxl);
-#endif
graphic_console_set_hwops(d->ssd.dcl.con, d->vga.hw_ops, &d->vga);
update_displaychangelistener(&d->ssd.dcl, GUI_REFRESH_INTERVAL_DEFAULT);
qemu_spice_create_host_primary(&d->ssd);
diff --git a/hw/display/ramfb-standalone.c b/hw/display/ramfb-standalone.c
index c0d241ba01..da3229a1f6 100644
--- a/hw/display/ramfb-standalone.c
+++ b/hw/display/ramfb-standalone.c
@@ -1,7 +1,6 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "hw/loader.h"
-#include "hw/isa/isa.h"
#include "hw/display/ramfb.h"
#include "ui/console.h"
#include "sysemu/sysemu.h"
diff --git a/hw/gpio/Makefile.objs b/hw/gpio/Makefile.objs
index fa0a72e6d0..e5da0cb54f 100644
--- a/hw/gpio/Makefile.objs
+++ b/hw/gpio/Makefile.objs
@@ -8,3 +8,4 @@ common-obj-$(CONFIG_GPIO_KEY) += gpio_key.o
obj-$(CONFIG_OMAP) += omap_gpio.o
obj-$(CONFIG_IMX) += imx_gpio.o
obj-$(CONFIG_RASPI) += bcm2835_gpio.o
+obj-$(CONFIG_NRF51_SOC) += nrf51_gpio.o
diff --git a/hw/gpio/nrf51_gpio.c b/hw/gpio/nrf51_gpio.c
new file mode 100644
index 0000000000..86e047d649
--- /dev/null
+++ b/hw/gpio/nrf51_gpio.c
@@ -0,0 +1,300 @@
+/*
+ * nRF51 System-on-Chip general purpose input/output register definition
+ *
+ * Reference Manual: http://infocenter.nordicsemi.com/pdf/nRF51_RM_v3.0.pdf
+ * Product Spec: http://infocenter.nordicsemi.com/pdf/nRF51822_PS_v3.1.pdf
+ *
+ * Copyright 2018 Steffen Görtz <contrib@steffen-goertz.de>
+ *
+ * This code is licensed under the GPL version 2 or later. See
+ * the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "hw/gpio/nrf51_gpio.h"
+#include "trace.h"
+
+/*
+ * Check if the output driver is connected to the direction switch
+ * given the current configuration and logic level.
+ * It is not differentiated between standard and "high"(-power) drive modes.
+ */
+static bool is_connected(uint32_t config, uint32_t level)
+{
+ bool state;
+ uint32_t drive_config = extract32(config, 8, 3);
+
+ switch (drive_config) {
+ case 0 ... 3:
+ state = true;
+ break;
+ case 4 ... 5:
+ state = level != 0;
+ break;
+ case 6 ... 7:
+ state = level == 0;
+ break;
+ default:
+ g_assert_not_reached();
+ break;
+ }
+
+ return state;
+}
+
+static void update_output_irq(NRF51GPIOState *s, size_t i,
+ bool connected, bool level)
+{
+ int64_t irq_level = connected ? level : -1;
+ bool old_connected = extract32(s->old_out_connected, i, 1);
+ bool old_level = extract32(s->old_out, i, 1);
+
+ if ((old_connected != connected) || (old_level != level)) {
+ qemu_set_irq(s->output[i], irq_level);
+ trace_nrf51_gpio_update_output_irq(i, irq_level);
+ }
+
+ s->old_out = deposit32(s->old_out, i, 1, level);
+ s->old_out_connected = deposit32(s->old_out_connected, i, 1, connected);
+}
+
+static void update_state(NRF51GPIOState *s)
+{
+ uint32_t pull;
+ size_t i;
+ bool connected_out, dir, connected_in, out, input;
+
+ for (i = 0; i < NRF51_GPIO_PINS; i++) {
+ pull = extract32(s->cnf[i], 2, 2);
+ dir = extract32(s->cnf[i], 0, 1);
+ connected_in = extract32(s->in_mask, i, 1);
+ out = extract32(s->out, i, 1);
+ input = !extract32(s->cnf[i], 1, 1);
+ connected_out = is_connected(s->cnf[i], out) && dir;
+
+ update_output_irq(s, i, connected_out, out);
+
+ /* Pin both driven externally and internally */
+ if (connected_out && connected_in) {
+ qemu_log_mask(LOG_GUEST_ERROR, "GPIO pin %zu short circuited\n", i);
+ }
+
+ /*
+ * Input buffer disconnected from internal/external drives, so
+ * pull-up/pull-down becomes relevant
+ */
+ if (!input || (input && !connected_in && !connected_out)) {
+ if (pull == NRF51_GPIO_PULLDOWN) {
+ s->in = deposit32(s->in, i, 1, 0);
+ } else if (pull == NRF51_GPIO_PULLUP) {
+ s->in = deposit32(s->in, i, 1, 1);
+ }
+ }
+
+ /* Self stimulation through internal output driver */
+ if (connected_out && !connected_in && input) {
+ s->in = deposit32(s->in, i, 1, out);
+ }
+ }
+
+}
+
+/*
+ * Direction is exposed in both the DIR register and the DIR bit
+ * of each PINs CNF configuration register. Reflect bits for pins in DIR
+ * to individual pin configuration registers.
+ */
+static void reflect_dir_bit_in_cnf(NRF51GPIOState *s)
+{
+ size_t i;
+
+ uint32_t value = s->dir;
+
+ for (i = 0; i < NRF51_GPIO_PINS; i++) {
+ s->cnf[i] = (s->cnf[i] & ~(1UL)) | ((value >> i) & 0x01);
+ }
+}
+
+static uint64_t nrf51_gpio_read(void *opaque, hwaddr offset, unsigned int size)
+{
+ NRF51GPIOState *s = NRF51_GPIO(opaque);
+ uint64_t r = 0;
+ size_t idx;
+
+ switch (offset) {
+ case NRF51_GPIO_REG_OUT ... NRF51_GPIO_REG_OUTCLR:
+ r = s->out;
+ break;
+
+ case NRF51_GPIO_REG_IN:
+ r = s->in;
+ break;
+
+ case NRF51_GPIO_REG_DIR ... NRF51_GPIO_REG_DIRCLR:
+ r = s->dir;
+ break;
+
+ case NRF51_GPIO_REG_CNF_START ... NRF51_GPIO_REG_CNF_END:
+ idx = (offset - NRF51_GPIO_REG_CNF_START) / 4;
+ r = s->cnf[idx];
+ break;
+
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: bad read offset 0x%" HWADDR_PRIx "\n",
+ __func__, offset);
+ }
+
+ trace_nrf51_gpio_read(offset, r);
+
+ return r;
+}
+
+static void nrf51_gpio_write(void *opaque, hwaddr offset,
+ uint64_t value, unsigned int size)
+{
+ NRF51GPIOState *s = NRF51_GPIO(opaque);
+ size_t idx;
+
+ trace_nrf51_gpio_write(offset, value);
+
+ switch (offset) {
+ case NRF51_GPIO_REG_OUT:
+ s->out = value;
+ break;
+
+ case NRF51_GPIO_REG_OUTSET:
+ s->out |= value;
+ break;
+
+ case NRF51_GPIO_REG_OUTCLR:
+ s->out &= ~value;
+ break;
+
+ case NRF51_GPIO_REG_DIR:
+ s->dir = value;
+ reflect_dir_bit_in_cnf(s);
+ break;
+
+ case NRF51_GPIO_REG_DIRSET:
+ s->dir |= value;
+ reflect_dir_bit_in_cnf(s);
+ break;
+
+ case NRF51_GPIO_REG_DIRCLR:
+ s->dir &= ~value;
+ reflect_dir_bit_in_cnf(s);
+ break;
+
+ case NRF51_GPIO_REG_CNF_START ... NRF51_GPIO_REG_CNF_END:
+ idx = (offset - NRF51_GPIO_REG_CNF_START) / 4;
+ s->cnf[idx] = value;
+ /*
+ * direction is exposed in both the DIR register and the DIR bit
+ * of each PINs CNF configuration register.
+ */
+ s->dir = (s->dir & ~(1UL << idx)) | ((value & 0x01) << idx);
+ break;
+
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: bad write offset 0x%" HWADDR_PRIx "\n",
+ __func__, offset);
+ }
+
+ update_state(s);
+}
+
+static const MemoryRegionOps gpio_ops = {
+ .read = nrf51_gpio_read,
+ .write = nrf51_gpio_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+ .impl.min_access_size = 4,
+ .impl.max_access_size = 4,
+};
+
+static void nrf51_gpio_set(void *opaque, int line, int value)
+{
+ NRF51GPIOState *s = NRF51_GPIO(opaque);
+
+ trace_nrf51_gpio_set(line, value);
+
+ assert(line >= 0 && line < NRF51_GPIO_PINS);
+
+ s->in_mask = deposit32(s->in_mask, line, 1, value >= 0);
+ if (value >= 0) {
+ s->in = deposit32(s->in, line, 1, value != 0);
+ }
+
+ update_state(s);
+}
+
+static void nrf51_gpio_reset(DeviceState *dev)
+{
+ NRF51GPIOState *s = NRF51_GPIO(dev);
+ size_t i;
+
+ s->out = 0;
+ s->old_out = 0;
+ s->old_out_connected = 0;
+ s->in = 0;
+ s->in_mask = 0;
+ s->dir = 0;
+
+ for (i = 0; i < NRF51_GPIO_PINS; i++) {
+ s->cnf[i] = 0x00000002;
+ }
+}
+
+static const VMStateDescription vmstate_nrf51_gpio = {
+ .name = TYPE_NRF51_GPIO,
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(out, NRF51GPIOState),
+ VMSTATE_UINT32(in, NRF51GPIOState),
+ VMSTATE_UINT32(in_mask, NRF51GPIOState),
+ VMSTATE_UINT32(dir, NRF51GPIOState),
+ VMSTATE_UINT32_ARRAY(cnf, NRF51GPIOState, NRF51_GPIO_PINS),
+ VMSTATE_UINT32(old_out, NRF51GPIOState),
+ VMSTATE_UINT32(old_out_connected, NRF51GPIOState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static void nrf51_gpio_init(Object *obj)
+{
+ NRF51GPIOState *s = NRF51_GPIO(obj);
+
+ memory_region_init_io(&s->mmio, obj, &gpio_ops, s,
+ TYPE_NRF51_GPIO, NRF51_GPIO_SIZE);
+ sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
+
+ qdev_init_gpio_in(DEVICE(s), nrf51_gpio_set, NRF51_GPIO_PINS);
+ qdev_init_gpio_out(DEVICE(s), s->output, NRF51_GPIO_PINS);
+}
+
+static void nrf51_gpio_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ dc->vmsd = &vmstate_nrf51_gpio;
+ dc->reset = nrf51_gpio_reset;
+ dc->desc = "nRF51 GPIO";
+}
+
+static const TypeInfo nrf51_gpio_info = {
+ .name = TYPE_NRF51_GPIO,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(NRF51GPIOState),
+ .instance_init = nrf51_gpio_init,
+ .class_init = nrf51_gpio_class_init
+};
+
+static void nrf51_gpio_register_types(void)
+{
+ type_register_static(&nrf51_gpio_info);
+}
+
+type_init(nrf51_gpio_register_types)
diff --git a/hw/gpio/trace-events b/hw/gpio/trace-events
new file mode 100644
index 0000000000..cb41a89756
--- /dev/null
+++ b/hw/gpio/trace-events
@@ -0,0 +1,7 @@
+# See docs/devel/tracing.txt for syntax documentation.
+
+# hw/gpio/nrf51_gpio.c
+nrf51_gpio_read(uint64_t offset, uint64_t r) "offset 0x%" PRIx64 " value 0x%" PRIx64
+nrf51_gpio_write(uint64_t offset, uint64_t value) "offset 0x%" PRIx64 " value 0x%" PRIx64
+nrf51_gpio_set(int64_t line, int64_t value) "line %" PRIi64 " value %" PRIi64
+nrf51_gpio_update_output_irq(int64_t line, int64_t value) "line %" PRIi64 " value %" PRIi64 \ No newline at end of file
diff --git a/hw/i386/kvm/ioapic.c b/hw/i386/kvm/ioapic.c
index 5b40d75439..e453692199 100644
--- a/hw/i386/kvm/ioapic.c
+++ b/hw/i386/kvm/ioapic.c
@@ -163,7 +163,7 @@ static void kvm_ioapic_class_init(ObjectClass *klass, void *data)
}
static const TypeInfo kvm_ioapic_info = {
- .name = "kvm-ioapic",
+ .name = TYPE_KVM_IOAPIC,
.parent = TYPE_IOAPIC_COMMON,
.instance_size = sizeof(KVMIOAPICState),
.class_init = kvm_ioapic_class_init,
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index f248662e97..3c9e20ad9c 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -72,6 +72,7 @@
#include "qapi/visitor.h"
#include "qom/cpu.h"
#include "hw/nmi.h"
+#include "hw/usb.h"
#include "hw/i386/intel_iommu.h"
#include "hw/net/ne2000-isa.h"
@@ -109,6 +110,679 @@ static struct e820_entry *e820_table;
static unsigned e820_entries;
struct hpet_fw_config hpet_cfg = {.count = UINT8_MAX};
+GlobalProperty pc_compat_3_1[] = {
+ {
+ .driver = "intel-iommu",
+ .property = "dma-drain",
+ .value = "off",
+ },
+};
+const size_t pc_compat_3_1_len = G_N_ELEMENTS(pc_compat_3_1);
+
+GlobalProperty pc_compat_3_0[] = {
+ {
+ .driver = TYPE_X86_CPU,
+ .property = "x-hv-synic-kvm-only",
+ .value = "on",
+ },{
+ .driver = "Skylake-Server" "-" TYPE_X86_CPU,
+ .property = "pku",
+ .value = "off",
+ },{
+ .driver = "Skylake-Server-IBRS" "-" TYPE_X86_CPU,
+ .property = "pku",
+ .value = "off",
+ },
+};
+const size_t pc_compat_3_0_len = G_N_ELEMENTS(pc_compat_3_0);
+
+GlobalProperty pc_compat_2_12[] = {
+ {
+ .driver = TYPE_X86_CPU,
+ .property = "legacy-cache",
+ .value = "on",
+ },{
+ .driver = TYPE_X86_CPU,
+ .property = "topoext",
+ .value = "off",
+ },{
+ .driver = "EPYC-" TYPE_X86_CPU,
+ .property = "xlevel",
+ .value = stringify(0x8000000a),
+ },{
+ .driver = "EPYC-IBPB-" TYPE_X86_CPU,
+ .property = "xlevel",
+ .value = stringify(0x8000000a),
+ },
+};
+const size_t pc_compat_2_12_len = G_N_ELEMENTS(pc_compat_2_12);
+
+GlobalProperty pc_compat_2_11[] = {
+ {
+ .driver = TYPE_X86_CPU,
+ .property = "x-migrate-smi-count",
+ .value = "off",
+ },{
+ .driver = "Skylake-Server" "-" TYPE_X86_CPU,
+ .property = "clflushopt",
+ .value = "off",
+ },
+};
+const size_t pc_compat_2_11_len = G_N_ELEMENTS(pc_compat_2_11);
+
+GlobalProperty pc_compat_2_10[] = {
+ {
+ .driver = TYPE_X86_CPU,
+ .property = "x-hv-max-vps",
+ .value = "0x40",
+ },{
+ .driver = "i440FX-pcihost",
+ .property = "x-pci-hole64-fix",
+ .value = "off",
+ },{
+ .driver = "q35-pcihost",
+ .property = "x-pci-hole64-fix",
+ .value = "off",
+ },
+};
+const size_t pc_compat_2_10_len = G_N_ELEMENTS(pc_compat_2_10);
+
+GlobalProperty pc_compat_2_9[] = {
+ {
+ .driver = "mch",
+ .property = "extended-tseg-mbytes",
+ .value = stringify(0),
+ },
+};
+const size_t pc_compat_2_9_len = G_N_ELEMENTS(pc_compat_2_9);
+
+GlobalProperty pc_compat_2_8[] = {
+ {
+ .driver = TYPE_X86_CPU,
+ .property = "tcg-cpuid",
+ .value = "off",
+ },
+ {
+ .driver = "kvmclock",
+ .property = "x-mach-use-reliable-get-clock",
+ .value = "off",
+ },
+ {
+ .driver = "ICH9-LPC",
+ .property = "x-smi-broadcast",
+ .value = "off",
+ },
+ {
+ .driver = TYPE_X86_CPU,
+ .property = "vmware-cpuid-freq",
+ .value = "off",
+ },
+ {
+ .driver = "Haswell-" TYPE_X86_CPU,
+ .property = "stepping",
+ .value = "1",
+ },
+};
+const size_t pc_compat_2_8_len = G_N_ELEMENTS(pc_compat_2_8);
+
+GlobalProperty pc_compat_2_7[] = {
+ {
+ .driver = TYPE_X86_CPU,
+ .property = "l3-cache",
+ .value = "off",
+ },
+ {
+ .driver = TYPE_X86_CPU,
+ .property = "full-cpuid-auto-level",
+ .value = "off",
+ },
+ {
+ .driver = "Opteron_G3" "-" TYPE_X86_CPU,
+ .property = "family",
+ .value = "15",
+ },
+ {
+ .driver = "Opteron_G3" "-" TYPE_X86_CPU,
+ .property = "model",
+ .value = "6",
+ },
+ {
+ .driver = "Opteron_G3" "-" TYPE_X86_CPU,
+ .property = "stepping",
+ .value = "1",
+ },
+ {
+ .driver = "isa-pcspk",
+ .property = "migrate",
+ .value = "off",
+ },
+};
+const size_t pc_compat_2_7_len = G_N_ELEMENTS(pc_compat_2_7);
+
+GlobalProperty pc_compat_2_6[] = {
+ {
+ .driver = TYPE_X86_CPU,
+ .property = "cpuid-0xb",
+ .value = "off",
+ },{
+ .driver = "vmxnet3",
+ .property = "romfile",
+ .value = "",
+ },
+ {
+ .driver = TYPE_X86_CPU,
+ .property = "fill-mtrr-mask",
+ .value = "off",
+ },
+ {
+ .driver = "apic-common",
+ .property = "legacy-instance-id",
+ .value = "on",
+ }
+};
+const size_t pc_compat_2_6_len = G_N_ELEMENTS(pc_compat_2_6);
+
+GlobalProperty pc_compat_2_5[] = {};
+const size_t pc_compat_2_5_len = G_N_ELEMENTS(pc_compat_2_5);
+
+GlobalProperty pc_compat_2_4[] = {
+ PC_CPU_MODEL_IDS("2.4.0")
+ {
+ .driver = "Haswell-" TYPE_X86_CPU,
+ .property = "abm",
+ .value = "off",
+ },
+ {
+ .driver = "Haswell-noTSX-" TYPE_X86_CPU,
+ .property = "abm",
+ .value = "off",
+ },
+ {
+ .driver = "Broadwell-" TYPE_X86_CPU,
+ .property = "abm",
+ .value = "off",
+ },
+ {
+ .driver = "Broadwell-noTSX-" TYPE_X86_CPU,
+ .property = "abm",
+ .value = "off",
+ },
+ {
+ .driver = "host" "-" TYPE_X86_CPU,
+ .property = "host-cache-info",
+ .value = "on",
+ },
+ {
+ .driver = TYPE_X86_CPU,
+ .property = "check",
+ .value = "off",
+ },
+ {
+ .driver = "qemu64" "-" TYPE_X86_CPU,
+ .property = "sse4a",
+ .value = "on",
+ },
+ {
+ .driver = "qemu64" "-" TYPE_X86_CPU,
+ .property = "abm",
+ .value = "on",
+ },
+ {
+ .driver = "qemu64" "-" TYPE_X86_CPU,
+ .property = "popcnt",
+ .value = "on",
+ },
+ {
+ .driver = "qemu32" "-" TYPE_X86_CPU,
+ .property = "popcnt",
+ .value = "on",
+ },{
+ .driver = "Opteron_G2" "-" TYPE_X86_CPU,
+ .property = "rdtscp",
+ .value = "on",
+ },{
+ .driver = "Opteron_G3" "-" TYPE_X86_CPU,
+ .property = "rdtscp",
+ .value = "on",
+ },{
+ .driver = "Opteron_G4" "-" TYPE_X86_CPU,
+ .property = "rdtscp",
+ .value = "on",
+ },{
+ .driver = "Opteron_G5" "-" TYPE_X86_CPU,
+ .property = "rdtscp",
+ .value = "on",
+ }
+};
+const size_t pc_compat_2_4_len = G_N_ELEMENTS(pc_compat_2_4);
+
+GlobalProperty pc_compat_2_3[] = {
+ PC_CPU_MODEL_IDS("2.3.0")
+ {
+ .driver = TYPE_X86_CPU,
+ .property = "arat",
+ .value = "off",
+ },{
+ .driver = "qemu64" "-" TYPE_X86_CPU,
+ .property = "min-level",
+ .value = stringify(4),
+ },{
+ .driver = "kvm64" "-" TYPE_X86_CPU,
+ .property = "min-level",
+ .value = stringify(5),
+ },{
+ .driver = "pentium3" "-" TYPE_X86_CPU,
+ .property = "min-level",
+ .value = stringify(2),
+ },{
+ .driver = "n270" "-" TYPE_X86_CPU,
+ .property = "min-level",
+ .value = stringify(5),
+ },{
+ .driver = "Conroe" "-" TYPE_X86_CPU,
+ .property = "min-level",
+ .value = stringify(4),
+ },{
+ .driver = "Penryn" "-" TYPE_X86_CPU,
+ .property = "min-level",
+ .value = stringify(4),
+ },{
+ .driver = "Nehalem" "-" TYPE_X86_CPU,
+ .property = "min-level",
+ .value = stringify(4),
+ },{
+ .driver = "n270" "-" TYPE_X86_CPU,
+ .property = "min-xlevel",
+ .value = stringify(0x8000000a),
+ },{
+ .driver = "Penryn" "-" TYPE_X86_CPU,
+ .property = "min-xlevel",
+ .value = stringify(0x8000000a),
+ },{
+ .driver = "Conroe" "-" TYPE_X86_CPU,
+ .property = "min-xlevel",
+ .value = stringify(0x8000000a),
+ },{
+ .driver = "Nehalem" "-" TYPE_X86_CPU,
+ .property = "min-xlevel",
+ .value = stringify(0x8000000a),
+ },{
+ .driver = "Westmere" "-" TYPE_X86_CPU,
+ .property = "min-xlevel",
+ .value = stringify(0x8000000a),
+ },{
+ .driver = "SandyBridge" "-" TYPE_X86_CPU,
+ .property = "min-xlevel",
+ .value = stringify(0x8000000a),
+ },{
+ .driver = "IvyBridge" "-" TYPE_X86_CPU,
+ .property = "min-xlevel",
+ .value = stringify(0x8000000a),
+ },{
+ .driver = "Haswell" "-" TYPE_X86_CPU,
+ .property = "min-xlevel",
+ .value = stringify(0x8000000a),
+ },{
+ .driver = "Haswell-noTSX" "-" TYPE_X86_CPU,
+ .property = "min-xlevel",
+ .value = stringify(0x8000000a),
+ },{
+ .driver = "Broadwell" "-" TYPE_X86_CPU,
+ .property = "min-xlevel",
+ .value = stringify(0x8000000a),
+ },{
+ .driver = "Broadwell-noTSX" "-" TYPE_X86_CPU,
+ .property = "min-xlevel",
+ .value = stringify(0x8000000a),
+ },{
+ .driver = TYPE_X86_CPU,
+ .property = "kvm-no-smi-migration",
+ .value = "on",
+ },
+};
+const size_t pc_compat_2_3_len = G_N_ELEMENTS(pc_compat_2_3);
+
+GlobalProperty pc_compat_2_2[] = {
+ PC_CPU_MODEL_IDS("2.2.0")
+ {
+ .driver = "kvm64" "-" TYPE_X86_CPU,
+ .property = "vme",
+ .value = "off",
+ },
+ {
+ .driver = "kvm32" "-" TYPE_X86_CPU,
+ .property = "vme",
+ .value = "off",
+ },
+ {
+ .driver = "Conroe" "-" TYPE_X86_CPU,
+ .property = "vme",
+ .value = "off",
+ },
+ {
+ .driver = "Penryn" "-" TYPE_X86_CPU,
+ .property = "vme",
+ .value = "off",
+ },
+ {
+ .driver = "Nehalem" "-" TYPE_X86_CPU,
+ .property = "vme",
+ .value = "off",
+ },
+ {
+ .driver = "Westmere" "-" TYPE_X86_CPU,
+ .property = "vme",
+ .value = "off",
+ },
+ {
+ .driver = "SandyBridge" "-" TYPE_X86_CPU,
+ .property = "vme",
+ .value = "off",
+ },
+ {
+ .driver = "Haswell" "-" TYPE_X86_CPU,
+ .property = "vme",
+ .value = "off",
+ },
+ {
+ .driver = "Broadwell" "-" TYPE_X86_CPU,
+ .property = "vme",
+ .value = "off",
+ },
+ {
+ .driver = "Opteron_G1" "-" TYPE_X86_CPU,
+ .property = "vme",
+ .value = "off",
+ },
+ {
+ .driver = "Opteron_G2" "-" TYPE_X86_CPU,
+ .property = "vme",
+ .value = "off",
+ },
+ {
+ .driver = "Opteron_G3" "-" TYPE_X86_CPU,
+ .property = "vme",
+ .value = "off",
+ },
+ {
+ .driver = "Opteron_G4" "-" TYPE_X86_CPU,
+ .property = "vme",
+ .value = "off",
+ },
+ {
+ .driver = "Opteron_G5" "-" TYPE_X86_CPU,
+ .property = "vme",
+ .value = "off",
+ },
+ {
+ .driver = "Haswell" "-" TYPE_X86_CPU,
+ .property = "f16c",
+ .value = "off",
+ },
+ {
+ .driver = "Haswell" "-" TYPE_X86_CPU,
+ .property = "rdrand",
+ .value = "off",
+ },
+ {
+ .driver = "Broadwell" "-" TYPE_X86_CPU,
+ .property = "f16c",
+ .value = "off",
+ },
+ {
+ .driver = "Broadwell" "-" TYPE_X86_CPU,
+ .property = "rdrand",
+ .value = "off",
+ },
+};
+const size_t pc_compat_2_2_len = G_N_ELEMENTS(pc_compat_2_2);
+
+GlobalProperty pc_compat_2_1[] = {
+ PC_CPU_MODEL_IDS("2.1.0")
+ {
+ .driver = "coreduo" "-" TYPE_X86_CPU,
+ .property = "vmx",
+ .value = "on",
+ },
+ {
+ .driver = "core2duo" "-" TYPE_X86_CPU,
+ .property = "vmx",
+ .value = "on",
+ },
+};
+const size_t pc_compat_2_1_len = G_N_ELEMENTS(pc_compat_2_1);
+
+GlobalProperty pc_compat_2_0[] = {
+ PC_CPU_MODEL_IDS("2.0.0")
+ {
+ .driver = "virtio-scsi-pci",
+ .property = "any_layout",
+ .value = "off",
+ },{
+ .driver = "PIIX4_PM",
+ .property = "memory-hotplug-support",
+ .value = "off",
+ },
+ {
+ .driver = "apic",
+ .property = "version",
+ .value = stringify(0x11),
+ },
+ {
+ .driver = "nec-usb-xhci",
+ .property = "superspeed-ports-first",
+ .value = "off",
+ },
+ {
+ .driver = "nec-usb-xhci",
+ .property = "force-pcie-endcap",
+ .value = "on",
+ },
+ {
+ .driver = "pci-serial",
+ .property = "prog_if",
+ .value = stringify(0),
+ },
+ {
+ .driver = "pci-serial-2x",
+ .property = "prog_if",
+ .value = stringify(0),
+ },
+ {
+ .driver = "pci-serial-4x",
+ .property = "prog_if",
+ .value = stringify(0),
+ },
+ {
+ .driver = "virtio-net-pci",
+ .property = "guest_announce",
+ .value = "off",
+ },
+ {
+ .driver = "ICH9-LPC",
+ .property = "memory-hotplug-support",
+ .value = "off",
+ },{
+ .driver = "xio3130-downstream",
+ .property = COMPAT_PROP_PCP,
+ .value = "off",
+ },{
+ .driver = "ioh3420",
+ .property = COMPAT_PROP_PCP,
+ .value = "off",
+ },
+};
+const size_t pc_compat_2_0_len = G_N_ELEMENTS(pc_compat_2_0);
+
+GlobalProperty pc_compat_1_7[] = {
+ PC_CPU_MODEL_IDS("1.7.0")
+ {
+ .driver = TYPE_USB_DEVICE,
+ .property = "msos-desc",
+ .value = "no",
+ },
+ {
+ .driver = "PIIX4_PM",
+ .property = "acpi-pci-hotplug-with-bridge-support",
+ .value = "off",
+ },
+ {
+ .driver = "hpet",
+ .property = HPET_INTCAP,
+ .value = stringify(4),
+ },
+};
+const size_t pc_compat_1_7_len = G_N_ELEMENTS(pc_compat_1_7);
+
+GlobalProperty pc_compat_1_6[] = {
+ PC_CPU_MODEL_IDS("1.6.0")
+ {
+ .driver = "e1000",
+ .property = "mitigation",
+ .value = "off",
+ },{
+ .driver = "qemu64-" TYPE_X86_CPU,
+ .property = "model",
+ .value = stringify(2),
+ },{
+ .driver = "qemu32-" TYPE_X86_CPU,
+ .property = "model",
+ .value = stringify(3),
+ },{
+ .driver = "i440FX-pcihost",
+ .property = "short_root_bus",
+ .value = stringify(1),
+ },{
+ .driver = "q35-pcihost",
+ .property = "short_root_bus",
+ .value = stringify(1),
+ },
+};
+const size_t pc_compat_1_6_len = G_N_ELEMENTS(pc_compat_1_6);
+
+GlobalProperty pc_compat_1_5[] = {
+ PC_CPU_MODEL_IDS("1.5.0")
+ {
+ .driver = "Conroe-" TYPE_X86_CPU,
+ .property = "model",
+ .value = stringify(2),
+ },{
+ .driver = "Conroe-" TYPE_X86_CPU,
+ .property = "min-level",
+ .value = stringify(2),
+ },{
+ .driver = "Penryn-" TYPE_X86_CPU,
+ .property = "model",
+ .value = stringify(2),
+ },{
+ .driver = "Penryn-" TYPE_X86_CPU,
+ .property = "min-level",
+ .value = stringify(2),
+ },{
+ .driver = "Nehalem-" TYPE_X86_CPU,
+ .property = "model",
+ .value = stringify(2),
+ },{
+ .driver = "Nehalem-" TYPE_X86_CPU,
+ .property = "min-level",
+ .value = stringify(2),
+ },{
+ .driver = "virtio-net-pci",
+ .property = "any_layout",
+ .value = "off",
+ },{
+ .driver = TYPE_X86_CPU,
+ .property = "pmu",
+ .value = "on",
+ },{
+ .driver = "i440FX-pcihost",
+ .property = "short_root_bus",
+ .value = stringify(0),
+ },{
+ .driver = "q35-pcihost",
+ .property = "short_root_bus",
+ .value = stringify(0),
+ },
+};
+const size_t pc_compat_1_5_len = G_N_ELEMENTS(pc_compat_1_5);
+
+GlobalProperty pc_compat_1_4[] = {
+ PC_CPU_MODEL_IDS("1.4.0")
+ {
+ .driver = "scsi-hd",
+ .property = "discard_granularity",
+ .value = stringify(0),
+ },{
+ .driver = "scsi-cd",
+ .property = "discard_granularity",
+ .value = stringify(0),
+ },{
+ .driver = "scsi-disk",
+ .property = "discard_granularity",
+ .value = stringify(0),
+ },{
+ .driver = "ide-hd",
+ .property = "discard_granularity",
+ .value = stringify(0),
+ },{
+ .driver = "ide-cd",
+ .property = "discard_granularity",
+ .value = stringify(0),
+ },{
+ .driver = "ide-drive",
+ .property = "discard_granularity",
+ .value = stringify(0),
+ },{
+ .driver = "virtio-blk-pci",
+ .property = "discard_granularity",
+ .value = stringify(0),
+ },{
+ .driver = "virtio-serial-pci",
+ .property = "vectors",
+ /* DEV_NVECTORS_UNSPECIFIED as a uint32_t string */
+ .value = stringify(0xFFFFFFFF),
+ },{
+ .driver = "virtio-net-pci",
+ .property = "ctrl_guest_offloads",
+ .value = "off",
+ },{
+ .driver = "e1000",
+ .property = "romfile",
+ .value = "pxe-e1000.rom",
+ },{
+ .driver = "ne2k_pci",
+ .property = "romfile",
+ .value = "pxe-ne2k_pci.rom",
+ },{
+ .driver = "pcnet",
+ .property = "romfile",
+ .value = "pxe-pcnet.rom",
+ },{
+ .driver = "rtl8139",
+ .property = "romfile",
+ .value = "pxe-rtl8139.rom",
+ },{
+ .driver = "virtio-net-pci",
+ .property = "romfile",
+ .value = "pxe-virtio.rom",
+ },{
+ .driver = "486-" TYPE_X86_CPU,
+ .property = "model",
+ .value = stringify(0),
+ },
+ {
+ .driver = "n270" "-" TYPE_X86_CPU,
+ .property = "movbe",
+ .value = "off",
+ },
+ {
+ .driver = "Westmere" "-" TYPE_X86_CPU,
+ .property = "pclmulqdq",
+ .value = "off",
+ },
+};
+const size_t pc_compat_1_4_len = G_N_ELEMENTS(pc_compat_1_4);
+
void gsi_handler(void *opaque, int n, int level)
{
GSIState *s = opaque;
@@ -1665,9 +2339,9 @@ void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name)
unsigned int i;
if (kvm_ioapic_in_kernel()) {
- dev = qdev_create(NULL, "kvm-ioapic");
+ dev = qdev_create(NULL, TYPE_KVM_IOAPIC);
} else {
- dev = qdev_create(NULL, "ioapic");
+ dev = qdev_create(NULL, TYPE_IOAPIC);
}
if (parent_name) {
object_property_add_child(object_resolve_path(parent_name, NULL),
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 7f1cb527b5..ed6984638e 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -310,7 +310,7 @@ static void pc_init1(MachineState *machine,
* HW_COMPAT_*, PC_COMPAT_*, or * pc_*_machine_options().
*/
-static void pc_compat_2_3(MachineState *machine)
+static void pc_compat_2_3_fn(MachineState *machine)
{
PCMachineState *pcms = PC_MACHINE(machine);
if (kvm_enabled()) {
@@ -318,46 +318,46 @@ static void pc_compat_2_3(MachineState *machine)
}
}
-static void pc_compat_2_2(MachineState *machine)
+static void pc_compat_2_2_fn(MachineState *machine)
{
- pc_compat_2_3(machine);
+ pc_compat_2_3_fn(machine);
}
-static void pc_compat_2_1(MachineState *machine)
+static void pc_compat_2_1_fn(MachineState *machine)
{
- pc_compat_2_2(machine);
+ pc_compat_2_2_fn(machine);
x86_cpu_change_kvm_default("svm", NULL);
}
-static void pc_compat_2_0(MachineState *machine)
+static void pc_compat_2_0_fn(MachineState *machine)
{
- pc_compat_2_1(machine);
+ pc_compat_2_1_fn(machine);
}
-static void pc_compat_1_7(MachineState *machine)
+static void pc_compat_1_7_fn(MachineState *machine)
{
- pc_compat_2_0(machine);
+ pc_compat_2_0_fn(machine);
x86_cpu_change_kvm_default("x2apic", NULL);
}
-static void pc_compat_1_6(MachineState *machine)
+static void pc_compat_1_6_fn(MachineState *machine)
{
- pc_compat_1_7(machine);
+ pc_compat_1_7_fn(machine);
}
-static void pc_compat_1_5(MachineState *machine)
+static void pc_compat_1_5_fn(MachineState *machine)
{
- pc_compat_1_6(machine);
+ pc_compat_1_6_fn(machine);
}
-static void pc_compat_1_4(MachineState *machine)
+static void pc_compat_1_4_fn(MachineState *machine)
{
- pc_compat_1_5(machine);
+ pc_compat_1_5_fn(machine);
}
static void pc_compat_1_3(MachineState *machine)
{
- pc_compat_1_4(machine);
+ pc_compat_1_4_fn(machine);
enable_compat_apic_id_mode();
}
@@ -443,7 +443,8 @@ static void pc_i440fx_3_1_machine_options(MachineClass *m)
pc_i440fx_4_0_machine_options(m);
m->is_default = 0;
m->alias = NULL;
- SET_MACHINE_COMPAT(m, PC_COMPAT_3_1);
+ compat_props_add(m->compat_props, hw_compat_3_1, hw_compat_3_1_len);
+ compat_props_add(m->compat_props, pc_compat_3_1, pc_compat_3_1_len);
}
DEFINE_I440FX_MACHINE(v3_1, "pc-i440fx-3.1", NULL,
@@ -452,7 +453,8 @@ DEFINE_I440FX_MACHINE(v3_1, "pc-i440fx-3.1", NULL,
static void pc_i440fx_3_0_machine_options(MachineClass *m)
{
pc_i440fx_3_1_machine_options(m);
- SET_MACHINE_COMPAT(m, PC_COMPAT_3_0);
+ compat_props_add(m->compat_props, hw_compat_3_0, hw_compat_3_0_len);
+ compat_props_add(m->compat_props, pc_compat_3_0, pc_compat_3_0_len);
}
DEFINE_I440FX_MACHINE(v3_0, "pc-i440fx-3.0", NULL,
@@ -461,7 +463,8 @@ DEFINE_I440FX_MACHINE(v3_0, "pc-i440fx-3.0", NULL,
static void pc_i440fx_2_12_machine_options(MachineClass *m)
{
pc_i440fx_3_0_machine_options(m);
- SET_MACHINE_COMPAT(m, PC_COMPAT_2_12);
+ compat_props_add(m->compat_props, hw_compat_2_12, hw_compat_2_12_len);
+ compat_props_add(m->compat_props, pc_compat_2_12, pc_compat_2_12_len);
}
DEFINE_I440FX_MACHINE(v2_12, "pc-i440fx-2.12", NULL,
@@ -470,7 +473,8 @@ DEFINE_I440FX_MACHINE(v2_12, "pc-i440fx-2.12", NULL,
static void pc_i440fx_2_11_machine_options(MachineClass *m)
{
pc_i440fx_2_12_machine_options(m);
- SET_MACHINE_COMPAT(m, PC_COMPAT_2_11);
+ compat_props_add(m->compat_props, hw_compat_2_11, hw_compat_2_11_len);
+ compat_props_add(m->compat_props, pc_compat_2_11, pc_compat_2_11_len);
}
DEFINE_I440FX_MACHINE(v2_11, "pc-i440fx-2.11", NULL,
@@ -479,7 +483,8 @@ DEFINE_I440FX_MACHINE(v2_11, "pc-i440fx-2.11", NULL,
static void pc_i440fx_2_10_machine_options(MachineClass *m)
{
pc_i440fx_2_11_machine_options(m);
- SET_MACHINE_COMPAT(m, PC_COMPAT_2_10);
+ compat_props_add(m->compat_props, hw_compat_2_10, hw_compat_2_10_len);
+ compat_props_add(m->compat_props, pc_compat_2_10, pc_compat_2_10_len);
m->auto_enable_numa_with_memhp = false;
}
@@ -489,7 +494,8 @@ DEFINE_I440FX_MACHINE(v2_10, "pc-i440fx-2.10", NULL,
static void pc_i440fx_2_9_machine_options(MachineClass *m)
{
pc_i440fx_2_10_machine_options(m);
- SET_MACHINE_COMPAT(m, PC_COMPAT_2_9);
+ compat_props_add(m->compat_props, hw_compat_2_9, hw_compat_2_9_len);
+ compat_props_add(m->compat_props, pc_compat_2_9, pc_compat_2_9_len);
m->numa_auto_assign_ram = numa_legacy_auto_assign_ram;
}
@@ -499,109 +505,114 @@ DEFINE_I440FX_MACHINE(v2_9, "pc-i440fx-2.9", NULL,
static void pc_i440fx_2_8_machine_options(MachineClass *m)
{
pc_i440fx_2_9_machine_options(m);
- SET_MACHINE_COMPAT(m, PC_COMPAT_2_8);
+ compat_props_add(m->compat_props, hw_compat_2_8, hw_compat_2_8_len);
+ compat_props_add(m->compat_props, pc_compat_2_8, pc_compat_2_8_len);
}
DEFINE_I440FX_MACHINE(v2_8, "pc-i440fx-2.8", NULL,
pc_i440fx_2_8_machine_options);
-
static void pc_i440fx_2_7_machine_options(MachineClass *m)
{
pc_i440fx_2_8_machine_options(m);
- SET_MACHINE_COMPAT(m, PC_COMPAT_2_7);
+ compat_props_add(m->compat_props, hw_compat_2_7, hw_compat_2_7_len);
+ compat_props_add(m->compat_props, pc_compat_2_7, pc_compat_2_7_len);
}
DEFINE_I440FX_MACHINE(v2_7, "pc-i440fx-2.7", NULL,
pc_i440fx_2_7_machine_options);
-
static void pc_i440fx_2_6_machine_options(MachineClass *m)
{
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+
pc_i440fx_2_7_machine_options(m);
pcmc->legacy_cpu_hotplug = true;
pcmc->linuxboot_dma_enabled = false;
- SET_MACHINE_COMPAT(m, PC_COMPAT_2_6);
+ compat_props_add(m->compat_props, hw_compat_2_6, hw_compat_2_6_len);
+ compat_props_add(m->compat_props, pc_compat_2_6, pc_compat_2_6_len);
}
DEFINE_I440FX_MACHINE(v2_6, "pc-i440fx-2.6", NULL,
pc_i440fx_2_6_machine_options);
-
static void pc_i440fx_2_5_machine_options(MachineClass *m)
{
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+
pc_i440fx_2_6_machine_options(m);
pcmc->save_tsc_khz = false;
m->legacy_fw_cfg_order = 1;
- SET_MACHINE_COMPAT(m, PC_COMPAT_2_5);
+ compat_props_add(m->compat_props, hw_compat_2_5, hw_compat_2_5_len);
+ compat_props_add(m->compat_props, pc_compat_2_5, pc_compat_2_5_len);
}
DEFINE_I440FX_MACHINE(v2_5, "pc-i440fx-2.5", NULL,
pc_i440fx_2_5_machine_options);
-
static void pc_i440fx_2_4_machine_options(MachineClass *m)
{
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+
pc_i440fx_2_5_machine_options(m);
m->hw_version = "2.4.0";
pcmc->broken_reserved_end = true;
- SET_MACHINE_COMPAT(m, PC_COMPAT_2_4);
+ compat_props_add(m->compat_props, hw_compat_2_4, hw_compat_2_4_len);
+ compat_props_add(m->compat_props, pc_compat_2_4, pc_compat_2_4_len);
}
DEFINE_I440FX_MACHINE(v2_4, "pc-i440fx-2.4", NULL,
pc_i440fx_2_4_machine_options)
-
static void pc_i440fx_2_3_machine_options(MachineClass *m)
{
pc_i440fx_2_4_machine_options(m);
m->hw_version = "2.3.0";
- SET_MACHINE_COMPAT(m, PC_COMPAT_2_3);
+ compat_props_add(m->compat_props, hw_compat_2_3, hw_compat_2_3_len);
+ compat_props_add(m->compat_props, pc_compat_2_3, pc_compat_2_3_len);
}
-DEFINE_I440FX_MACHINE(v2_3, "pc-i440fx-2.3", pc_compat_2_3,
+DEFINE_I440FX_MACHINE(v2_3, "pc-i440fx-2.3", pc_compat_2_3_fn,
pc_i440fx_2_3_machine_options);
-
static void pc_i440fx_2_2_machine_options(MachineClass *m)
{
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+
pc_i440fx_2_3_machine_options(m);
m->hw_version = "2.2.0";
m->default_machine_opts = "firmware=bios-256k.bin,suppress-vmdesc=on";
- SET_MACHINE_COMPAT(m, PC_COMPAT_2_2);
+ compat_props_add(m->compat_props, hw_compat_2_2, hw_compat_2_2_len);
+ compat_props_add(m->compat_props, pc_compat_2_2, pc_compat_2_2_len);
pcmc->rsdp_in_ram = false;
}
-DEFINE_I440FX_MACHINE(v2_2, "pc-i440fx-2.2", pc_compat_2_2,
+DEFINE_I440FX_MACHINE(v2_2, "pc-i440fx-2.2", pc_compat_2_2_fn,
pc_i440fx_2_2_machine_options);
-
static void pc_i440fx_2_1_machine_options(MachineClass *m)
{
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+
pc_i440fx_2_2_machine_options(m);
m->hw_version = "2.1.0";
m->default_display = NULL;
- SET_MACHINE_COMPAT(m, PC_COMPAT_2_1);
+ compat_props_add(m->compat_props, hw_compat_2_1, hw_compat_2_1_len);
+ compat_props_add(m->compat_props, pc_compat_2_1, pc_compat_2_1_len);
pcmc->smbios_uuid_encoded = false;
pcmc->enforce_aligned_dimm = false;
}
-DEFINE_I440FX_MACHINE(v2_1, "pc-i440fx-2.1", pc_compat_2_1,
+DEFINE_I440FX_MACHINE(v2_1, "pc-i440fx-2.1", pc_compat_2_1_fn,
pc_i440fx_2_1_machine_options);
-
-
static void pc_i440fx_2_0_machine_options(MachineClass *m)
{
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+
pc_i440fx_2_1_machine_options(m);
m->hw_version = "2.0.0";
- SET_MACHINE_COMPAT(m, PC_COMPAT_2_0);
+ compat_props_add(m->compat_props, pc_compat_2_0, pc_compat_2_0_len);
pcmc->smbios_legacy_mode = true;
pcmc->has_reserved_memory = false;
/* This value depends on the actual DSDT and SSDT compiled into
@@ -624,329 +635,330 @@ static void pc_i440fx_2_0_machine_options(MachineClass *m)
pcmc->acpi_data_size = 0x10000;
}
-DEFINE_I440FX_MACHINE(v2_0, "pc-i440fx-2.0", pc_compat_2_0,
+DEFINE_I440FX_MACHINE(v2_0, "pc-i440fx-2.0", pc_compat_2_0_fn,
pc_i440fx_2_0_machine_options);
-
static void pc_i440fx_1_7_machine_options(MachineClass *m)
{
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+
pc_i440fx_2_0_machine_options(m);
m->hw_version = "1.7.0";
m->default_machine_opts = NULL;
m->option_rom_has_mr = true;
- SET_MACHINE_COMPAT(m, PC_COMPAT_1_7);
+ compat_props_add(m->compat_props, pc_compat_1_7, pc_compat_1_7_len);
pcmc->smbios_defaults = false;
pcmc->gigabyte_align = false;
pcmc->legacy_acpi_table_size = 6414;
}
-DEFINE_I440FX_MACHINE(v1_7, "pc-i440fx-1.7", pc_compat_1_7,
+DEFINE_I440FX_MACHINE(v1_7, "pc-i440fx-1.7", pc_compat_1_7_fn,
pc_i440fx_1_7_machine_options);
-
static void pc_i440fx_1_6_machine_options(MachineClass *m)
{
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+
pc_i440fx_1_7_machine_options(m);
m->hw_version = "1.6.0";
m->rom_file_has_mr = false;
- SET_MACHINE_COMPAT(m, PC_COMPAT_1_6);
+ compat_props_add(m->compat_props, pc_compat_1_6, pc_compat_1_6_len);
pcmc->has_acpi_build = false;
}
-DEFINE_I440FX_MACHINE(v1_6, "pc-i440fx-1.6", pc_compat_1_6,
+DEFINE_I440FX_MACHINE(v1_6, "pc-i440fx-1.6", pc_compat_1_6_fn,
pc_i440fx_1_6_machine_options);
-
static void pc_i440fx_1_5_machine_options(MachineClass *m)
{
pc_i440fx_1_6_machine_options(m);
m->hw_version = "1.5.0";
- SET_MACHINE_COMPAT(m, PC_COMPAT_1_5);
+ compat_props_add(m->compat_props, pc_compat_1_5, pc_compat_1_5_len);
}
-DEFINE_I440FX_MACHINE(v1_5, "pc-i440fx-1.5", pc_compat_1_5,
+DEFINE_I440FX_MACHINE(v1_5, "pc-i440fx-1.5", pc_compat_1_5_fn,
pc_i440fx_1_5_machine_options);
-
static void pc_i440fx_1_4_machine_options(MachineClass *m)
{
pc_i440fx_1_5_machine_options(m);
m->hw_version = "1.4.0";
m->hot_add_cpu = NULL;
- SET_MACHINE_COMPAT(m, PC_COMPAT_1_4);
+ compat_props_add(m->compat_props, pc_compat_1_4, pc_compat_1_4_len);
}
-DEFINE_I440FX_MACHINE(v1_4, "pc-i440fx-1.4", pc_compat_1_4,
+DEFINE_I440FX_MACHINE(v1_4, "pc-i440fx-1.4", pc_compat_1_4_fn,
pc_i440fx_1_4_machine_options);
-
-#define PC_COMPAT_1_3 \
- PC_CPU_MODEL_IDS("1.3.0") \
- {\
- .driver = "usb-tablet",\
- .property = "usb_version",\
- .value = stringify(1),\
- },{\
- .driver = "virtio-net-pci",\
- .property = "ctrl_mac_addr",\
- .value = "off", \
- },{ \
- .driver = "virtio-net-pci", \
- .property = "mq", \
- .value = "off", \
- }, {\
- .driver = "e1000",\
- .property = "autonegotiation",\
- .value = "off",\
- },
-
-
static void pc_i440fx_1_3_machine_options(MachineClass *m)
{
+ static GlobalProperty compat[] = {
+ PC_CPU_MODEL_IDS("1.3.0")
+ {
+ .driver = "usb-tablet",
+ .property = "usb_version",
+ .value = stringify(1),
+ },{
+ .driver = "virtio-net-pci",
+ .property = "ctrl_mac_addr",
+ .value = "off",
+ },{
+ .driver = "virtio-net-pci",
+ .property = "mq",
+ .value = "off",
+ }, {
+ .driver = "e1000",
+ .property = "autonegotiation",
+ .value = "off",
+ },
+ };
+
pc_i440fx_1_4_machine_options(m);
m->hw_version = "1.3.0";
- SET_MACHINE_COMPAT(m, PC_COMPAT_1_3);
+ compat_props_add(m->compat_props, compat, G_N_ELEMENTS(compat));
}
DEFINE_I440FX_MACHINE(v1_3, "pc-1.3", pc_compat_1_3,
pc_i440fx_1_3_machine_options);
-#define PC_COMPAT_1_2 \
- PC_CPU_MODEL_IDS("1.2.0") \
- {\
- .driver = "nec-usb-xhci",\
- .property = "msi",\
- .value = "off",\
- },{\
- .driver = "nec-usb-xhci",\
- .property = "msix",\
- .value = "off",\
- },{\
- .driver = "ivshmem",\
- .property = "use64",\
- .value = "0",\
- },{\
- .driver = "qxl",\
- .property = "revision",\
- .value = stringify(3),\
- },{\
- .driver = "qxl-vga",\
- .property = "revision",\
- .value = stringify(3),\
- },{\
- .driver = "VGA",\
- .property = "mmio",\
- .value = "off",\
- },
-
static void pc_i440fx_1_2_machine_options(MachineClass *m)
{
+ static GlobalProperty compat[] = {
+ PC_CPU_MODEL_IDS("1.2.0")
+ {
+ .driver = "nec-usb-xhci",
+ .property = "msi",
+ .value = "off",
+ },{
+ .driver = "nec-usb-xhci",
+ .property = "msix",
+ .value = "off",
+ },{
+ .driver = "ivshmem",
+ .property = "use64",
+ .value = "0",
+ },{
+ .driver = "qxl",
+ .property = "revision",
+ .value = stringify(3),
+ },{
+ .driver = "qxl-vga",
+ .property = "revision",
+ .value = stringify(3),
+ },{
+ .driver = "VGA",
+ .property = "mmio",
+ .value = "off",
+ },
+ };
+
pc_i440fx_1_3_machine_options(m);
m->hw_version = "1.2.0";
- SET_MACHINE_COMPAT(m, PC_COMPAT_1_2);
+ compat_props_add(m->compat_props, compat, G_N_ELEMENTS(compat));
}
DEFINE_I440FX_MACHINE(v1_2, "pc-1.2", pc_compat_1_2,
pc_i440fx_1_2_machine_options);
-#define PC_COMPAT_1_1 \
- PC_CPU_MODEL_IDS("1.1.0") \
- {\
- .driver = "virtio-scsi-pci",\
- .property = "hotplug",\
- .value = "off",\
- },{\
- .driver = "virtio-scsi-pci",\
- .property = "param_change",\
- .value = "off",\
- },{\
- .driver = "VGA",\
- .property = "vgamem_mb",\
- .value = stringify(8),\
- },{\
- .driver = "vmware-svga",\
- .property = "vgamem_mb",\
- .value = stringify(8),\
- },{\
- .driver = "qxl-vga",\
- .property = "vgamem_mb",\
- .value = stringify(8),\
- },{\
- .driver = "qxl",\
- .property = "vgamem_mb",\
- .value = stringify(8),\
- },{\
- .driver = "virtio-blk-pci",\
- .property = "config-wce",\
- .value = "off",\
- },
-
static void pc_i440fx_1_1_machine_options(MachineClass *m)
{
+ static GlobalProperty compat[] = {
+ PC_CPU_MODEL_IDS("1.1.0")
+ {
+ .driver = "virtio-scsi-pci",
+ .property = "hotplug",
+ .value = "off",
+ },{
+ .driver = "virtio-scsi-pci",
+ .property = "param_change",
+ .value = "off",
+ },{
+ .driver = "VGA",
+ .property = "vgamem_mb",
+ .value = stringify(8),
+ },{
+ .driver = "vmware-svga",
+ .property = "vgamem_mb",
+ .value = stringify(8),
+ },{
+ .driver = "qxl-vga",
+ .property = "vgamem_mb",
+ .value = stringify(8),
+ },{
+ .driver = "qxl",
+ .property = "vgamem_mb",
+ .value = stringify(8),
+ },{
+ .driver = "virtio-blk-pci",
+ .property = "config-wce",
+ .value = "off",
+ },
+ };
+
pc_i440fx_1_2_machine_options(m);
m->hw_version = "1.1.0";
- SET_MACHINE_COMPAT(m, PC_COMPAT_1_1);
+ compat_props_add(m->compat_props, compat, G_N_ELEMENTS(compat));
}
DEFINE_I440FX_MACHINE(v1_1, "pc-1.1", pc_compat_1_2,
pc_i440fx_1_1_machine_options);
-
-#define PC_COMPAT_1_0 \
- PC_CPU_MODEL_IDS("1.0") \
- {\
- .driver = TYPE_ISA_FDC,\
- .property = "check_media_rate",\
- .value = "off",\
- }, {\
- .driver = "virtio-balloon-pci",\
- .property = "class",\
- .value = stringify(PCI_CLASS_MEMORY_RAM),\
- },{\
- .driver = "apic-common",\
- .property = "vapic",\
- .value = "off",\
- },{\
- .driver = TYPE_USB_DEVICE,\
- .property = "full-path",\
- .value = "no",\
- },
-
static void pc_i440fx_1_0_machine_options(MachineClass *m)
{
+ static GlobalProperty compat[] = {
+ PC_CPU_MODEL_IDS("1.0")
+ {
+ .driver = TYPE_ISA_FDC,
+ .property = "check_media_rate",
+ .value = "off",
+ },{
+ .driver = "virtio-balloon-pci",
+ .property = "class",
+ .value = stringify(PCI_CLASS_MEMORY_RAM),
+ },{
+ .driver = "apic-common",
+ .property = "vapic",
+ .value = "off",
+ },{
+ .driver = TYPE_USB_DEVICE,
+ .property = "full-path",
+ .value = "no",
+ },
+ };
+
pc_i440fx_1_1_machine_options(m);
m->hw_version = "1.0";
- SET_MACHINE_COMPAT(m, PC_COMPAT_1_0);
+ compat_props_add(m->compat_props, compat, G_N_ELEMENTS(compat));
}
DEFINE_I440FX_MACHINE(v1_0, "pc-1.0", pc_compat_1_2,
pc_i440fx_1_0_machine_options);
-#define PC_COMPAT_0_15 \
- PC_CPU_MODEL_IDS("0.15")
-
static void pc_i440fx_0_15_machine_options(MachineClass *m)
{
+ static GlobalProperty compat[] = {
+ PC_CPU_MODEL_IDS("0.15")
+ };
+
pc_i440fx_1_0_machine_options(m);
m->hw_version = "0.15";
m->deprecation_reason = "use a newer machine type instead";
- SET_MACHINE_COMPAT(m, PC_COMPAT_0_15);
+ compat_props_add(m->compat_props, compat, G_N_ELEMENTS(compat));
}
DEFINE_I440FX_MACHINE(v0_15, "pc-0.15", pc_compat_1_2,
pc_i440fx_0_15_machine_options);
-#define PC_COMPAT_0_14 \
- PC_CPU_MODEL_IDS("0.14") \
- {\
- .driver = "virtio-blk-pci",\
- .property = "event_idx",\
- .value = "off",\
- },{\
- .driver = "virtio-serial-pci",\
- .property = "event_idx",\
- .value = "off",\
- },{\
- .driver = "virtio-net-pci",\
- .property = "event_idx",\
- .value = "off",\
- },{\
- .driver = "virtio-balloon-pci",\
- .property = "event_idx",\
- .value = "off",\
- },{\
- .driver = "qxl",\
- .property = "revision",\
- .value = stringify(2),\
- },{\
- .driver = "qxl-vga",\
- .property = "revision",\
- .value = stringify(2),\
- },
-
static void pc_i440fx_0_14_machine_options(MachineClass *m)
{
+ static GlobalProperty compat[] = {
+ PC_CPU_MODEL_IDS("0.14")
+ {
+ .driver = "virtio-blk-pci",
+ .property = "event_idx",
+ .value = "off",
+ },{
+ .driver = "virtio-serial-pci",
+ .property = "event_idx",
+ .value = "off",
+ },{
+ .driver = "virtio-net-pci",
+ .property = "event_idx",
+ .value = "off",
+ },{
+ .driver = "virtio-balloon-pci",
+ .property = "event_idx",
+ .value = "off",
+ },{
+ .driver = "qxl",
+ .property = "revision",
+ .value = stringify(2),
+ },{
+ .driver = "qxl-vga",
+ .property = "revision",
+ .value = stringify(2),
+ },
+ };
+
pc_i440fx_0_15_machine_options(m);
m->hw_version = "0.14";
- SET_MACHINE_COMPAT(m, PC_COMPAT_0_14);
+ compat_props_add(m->compat_props, compat, G_N_ELEMENTS(compat));
}
DEFINE_I440FX_MACHINE(v0_14, "pc-0.14", pc_compat_1_2,
pc_i440fx_0_14_machine_options);
-
-#define PC_COMPAT_0_13 \
- PC_CPU_MODEL_IDS("0.13") \
- {\
- .driver = TYPE_PCI_DEVICE,\
- .property = "command_serr_enable",\
- .value = "off",\
- },{\
- .driver = "AC97",\
- .property = "use_broken_id",\
- .value = stringify(1),\
- },{\
- .driver = "virtio-9p-pci",\
- .property = "vectors",\
- .value = stringify(0),\
- },{\
- .driver = "VGA",\
- .property = "rombar",\
- .value = stringify(0),\
- },{\
- .driver = "vmware-svga",\
- .property = "rombar",\
- .value = stringify(0),\
- },
-
static void pc_i440fx_0_13_machine_options(MachineClass *m)
{
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+ static GlobalProperty compat[] = {
+ PC_CPU_MODEL_IDS("0.13")
+ {
+ .driver = TYPE_PCI_DEVICE,
+ .property = "command_serr_enable",
+ .value = "off",
+ },{
+ .driver = "AC97",
+ .property = "use_broken_id",
+ .value = stringify(1),
+ },{
+ .driver = "virtio-9p-pci",
+ .property = "vectors",
+ .value = stringify(0),
+ },{
+ .driver = "VGA",
+ .property = "rombar",
+ .value = stringify(0),
+ },{
+ .driver = "vmware-svga",
+ .property = "rombar",
+ .value = stringify(0),
+ },
+ };
+
pc_i440fx_0_14_machine_options(m);
m->hw_version = "0.13";
- SET_MACHINE_COMPAT(m, PC_COMPAT_0_13);
+ compat_props_add(m->compat_props, compat, G_N_ELEMENTS(compat));
pcmc->kvmclock_enabled = false;
}
DEFINE_I440FX_MACHINE(v0_13, "pc-0.13", pc_compat_0_13,
pc_i440fx_0_13_machine_options);
-
-#define PC_COMPAT_0_12 \
- PC_CPU_MODEL_IDS("0.12") \
- {\
- .driver = "virtio-serial-pci",\
- .property = "max_ports",\
- .value = stringify(1),\
- },{\
- .driver = "virtio-serial-pci",\
- .property = "vectors",\
- .value = stringify(0),\
- },{\
- .driver = "usb-mouse",\
- .property = "serial",\
- .value = "1",\
- },{\
- .driver = "usb-tablet",\
- .property = "serial",\
- .value = "1",\
- },{\
- .driver = "usb-kbd",\
- .property = "serial",\
- .value = "1",\
- },
-
static void pc_i440fx_0_12_machine_options(MachineClass *m)
{
+ static GlobalProperty compat[] = {
+ PC_CPU_MODEL_IDS("0.12")
+ {
+ .driver = "virtio-serial-pci",
+ .property = "max_ports",
+ .value = stringify(1),
+ },{
+ .driver = "virtio-serial-pci",
+ .property = "vectors",
+ .value = stringify(0),
+ },{
+ .driver = "usb-mouse",
+ .property = "serial",
+ .value = "1",
+ },{
+ .driver = "usb-tablet",
+ .property = "serial",
+ .value = "1",
+ },{
+ .driver = "usb-kbd",
+ .property = "serial",
+ .value = "1",
+ },
+ };
+
pc_i440fx_0_13_machine_options(m);
m->hw_version = "0.12";
- SET_MACHINE_COMPAT(m, PC_COMPAT_0_12);
+ compat_props_add(m->compat_props, compat, G_N_ELEMENTS(compat));
}
DEFINE_I440FX_MACHINE(v0_12, "pc-0.12", pc_compat_0_13,
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 0a3f3f18e4..b7b7959934 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -58,6 +58,59 @@
/* ICH9 AHCI has 6 ports */
#define MAX_SATA_PORTS 6
+struct ehci_companions {
+ const char *name;
+ int func;
+ int port;
+};
+
+static const struct ehci_companions ich9_1d[] = {
+ { .name = "ich9-usb-uhci1", .func = 0, .port = 0 },
+ { .name = "ich9-usb-uhci2", .func = 1, .port = 2 },
+ { .name = "ich9-usb-uhci3", .func = 2, .port = 4 },
+};
+
+static const struct ehci_companions ich9_1a[] = {
+ { .name = "ich9-usb-uhci4", .func = 0, .port = 0 },
+ { .name = "ich9-usb-uhci5", .func = 1, .port = 2 },
+ { .name = "ich9-usb-uhci6", .func = 2, .port = 4 },
+};
+
+static int ehci_create_ich9_with_companions(PCIBus *bus, int slot)
+{
+ const struct ehci_companions *comp;
+ PCIDevice *ehci, *uhci;
+ BusState *usbbus;
+ const char *name;
+ int i;
+
+ switch (slot) {
+ case 0x1d:
+ name = "ich9-usb-ehci1";
+ comp = ich9_1d;
+ break;
+ case 0x1a:
+ name = "ich9-usb-ehci2";
+ comp = ich9_1a;
+ break;
+ default:
+ return -1;
+ }
+
+ ehci = pci_create_multifunction(bus, PCI_DEVFN(slot, 7), true, name);
+ qdev_init_nofail(&ehci->qdev);
+ usbbus = QLIST_FIRST(&ehci->qdev.child_bus);
+
+ for (i = 0; i < 3; i++) {
+ uhci = pci_create_multifunction(bus, PCI_DEVFN(slot, comp[i].func),
+ true, comp[i].name);
+ qdev_prop_set_string(&uhci->qdev, "masterbus", usbbus->name);
+ qdev_prop_set_uint32(&uhci->qdev, "firstport", comp[i].port);
+ qdev_init_nofail(&uhci->qdev);
+ }
+ return 0;
+}
+
/* PC hardware initialisation */
static void pc_q35_init(MachineState *machine)
{
@@ -326,7 +379,8 @@ static void pc_q35_3_1_machine_options(MachineClass *m)
pc_q35_4_0_machine_options(m);
m->default_kernel_irqchip_split = false;
m->alias = NULL;
- SET_MACHINE_COMPAT(m, PC_COMPAT_3_1);
+ compat_props_add(m->compat_props, hw_compat_3_1, hw_compat_3_1_len);
+ compat_props_add(m->compat_props, pc_compat_3_1, pc_compat_3_1_len);
}
DEFINE_Q35_MACHINE(v3_1, "pc-q35-3.1", NULL,
@@ -335,7 +389,8 @@ DEFINE_Q35_MACHINE(v3_1, "pc-q35-3.1", NULL,
static void pc_q35_3_0_machine_options(MachineClass *m)
{
pc_q35_3_1_machine_options(m);
- SET_MACHINE_COMPAT(m, PC_COMPAT_3_0);
+ compat_props_add(m->compat_props, hw_compat_3_0, hw_compat_3_0_len);
+ compat_props_add(m->compat_props, pc_compat_3_0, pc_compat_3_0_len);
}
DEFINE_Q35_MACHINE(v3_0, "pc-q35-3.0", NULL,
@@ -344,7 +399,8 @@ DEFINE_Q35_MACHINE(v3_0, "pc-q35-3.0", NULL,
static void pc_q35_2_12_machine_options(MachineClass *m)
{
pc_q35_3_0_machine_options(m);
- SET_MACHINE_COMPAT(m, PC_COMPAT_2_12);
+ compat_props_add(m->compat_props, hw_compat_2_12, hw_compat_2_12_len);
+ compat_props_add(m->compat_props, pc_compat_2_12, pc_compat_2_12_len);
}
DEFINE_Q35_MACHINE(v2_12, "pc-q35-2.12", NULL,
@@ -356,7 +412,8 @@ static void pc_q35_2_11_machine_options(MachineClass *m)
pc_q35_2_12_machine_options(m);
pcmc->default_nic_model = "e1000";
- SET_MACHINE_COMPAT(m, PC_COMPAT_2_11);
+ compat_props_add(m->compat_props, hw_compat_2_11, hw_compat_2_11_len);
+ compat_props_add(m->compat_props, pc_compat_2_11, pc_compat_2_11_len);
}
DEFINE_Q35_MACHINE(v2_11, "pc-q35-2.11", NULL,
@@ -365,7 +422,8 @@ DEFINE_Q35_MACHINE(v2_11, "pc-q35-2.11", NULL,
static void pc_q35_2_10_machine_options(MachineClass *m)
{
pc_q35_2_11_machine_options(m);
- SET_MACHINE_COMPAT(m, PC_COMPAT_2_10);
+ compat_props_add(m->compat_props, hw_compat_2_10, hw_compat_2_10_len);
+ compat_props_add(m->compat_props, pc_compat_2_10, pc_compat_2_10_len);
m->numa_auto_assign_ram = numa_legacy_auto_assign_ram;
m->auto_enable_numa_with_memhp = false;
}
@@ -376,7 +434,8 @@ DEFINE_Q35_MACHINE(v2_10, "pc-q35-2.10", NULL,
static void pc_q35_2_9_machine_options(MachineClass *m)
{
pc_q35_2_10_machine_options(m);
- SET_MACHINE_COMPAT(m, PC_COMPAT_2_9);
+ compat_props_add(m->compat_props, hw_compat_2_9, hw_compat_2_9_len);
+ compat_props_add(m->compat_props, pc_compat_2_9, pc_compat_2_9_len);
}
DEFINE_Q35_MACHINE(v2_9, "pc-q35-2.9", NULL,
@@ -385,7 +444,8 @@ DEFINE_Q35_MACHINE(v2_9, "pc-q35-2.9", NULL,
static void pc_q35_2_8_machine_options(MachineClass *m)
{
pc_q35_2_9_machine_options(m);
- SET_MACHINE_COMPAT(m, PC_COMPAT_2_8);
+ compat_props_add(m->compat_props, hw_compat_2_8, hw_compat_2_8_len);
+ compat_props_add(m->compat_props, pc_compat_2_8, pc_compat_2_8_len);
}
DEFINE_Q35_MACHINE(v2_8, "pc-q35-2.8", NULL,
@@ -395,7 +455,8 @@ static void pc_q35_2_7_machine_options(MachineClass *m)
{
pc_q35_2_8_machine_options(m);
m->max_cpus = 255;
- SET_MACHINE_COMPAT(m, PC_COMPAT_2_7);
+ compat_props_add(m->compat_props, hw_compat_2_7, hw_compat_2_7_len);
+ compat_props_add(m->compat_props, pc_compat_2_7, pc_compat_2_7_len);
}
DEFINE_Q35_MACHINE(v2_7, "pc-q35-2.7", NULL,
@@ -404,10 +465,12 @@ DEFINE_Q35_MACHINE(v2_7, "pc-q35-2.7", NULL,
static void pc_q35_2_6_machine_options(MachineClass *m)
{
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+
pc_q35_2_7_machine_options(m);
pcmc->legacy_cpu_hotplug = true;
pcmc->linuxboot_dma_enabled = false;
- SET_MACHINE_COMPAT(m, PC_COMPAT_2_6);
+ compat_props_add(m->compat_props, hw_compat_2_6, hw_compat_2_6_len);
+ compat_props_add(m->compat_props, pc_compat_2_6, pc_compat_2_6_len);
}
DEFINE_Q35_MACHINE(v2_6, "pc-q35-2.6", NULL,
@@ -416,10 +479,12 @@ DEFINE_Q35_MACHINE(v2_6, "pc-q35-2.6", NULL,
static void pc_q35_2_5_machine_options(MachineClass *m)
{
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+
pc_q35_2_6_machine_options(m);
pcmc->save_tsc_khz = false;
m->legacy_fw_cfg_order = 1;
- SET_MACHINE_COMPAT(m, PC_COMPAT_2_5);
+ compat_props_add(m->compat_props, hw_compat_2_5, hw_compat_2_5_len);
+ compat_props_add(m->compat_props, pc_compat_2_5, pc_compat_2_5_len);
}
DEFINE_Q35_MACHINE(v2_5, "pc-q35-2.5", NULL,
@@ -428,10 +493,12 @@ DEFINE_Q35_MACHINE(v2_5, "pc-q35-2.5", NULL,
static void pc_q35_2_4_machine_options(MachineClass *m)
{
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
+
pc_q35_2_5_machine_options(m);
m->hw_version = "2.4.0";
pcmc->broken_reserved_end = true;
- SET_MACHINE_COMPAT(m, PC_COMPAT_2_4);
+ compat_props_add(m->compat_props, hw_compat_2_4, hw_compat_2_4_len);
+ compat_props_add(m->compat_props, pc_compat_2_4, pc_compat_2_4_len);
}
DEFINE_Q35_MACHINE(v2_4, "pc-q35-2.4", NULL,
diff --git a/hw/ide/pci.c b/hw/ide/pci.c
index fe1ceeb0cd..b75154f99f 100644
--- a/hw/ide/pci.c
+++ b/hw/ide/pci.c
@@ -25,7 +25,6 @@
#include "qemu/osdep.h"
#include "hw/hw.h"
#include "hw/pci/pci.h"
-#include "hw/isa/isa.h"
#include "sysemu/dma.h"
#include "qemu/error-report.h"
#include "hw/ide/pci.h"
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index a3afe1fd29..885c16e938 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -26,7 +26,6 @@
#include "qemu/osdep.h"
#include "hw/hw.h"
#include "hw/pci/pci.h"
-#include "hw/isa/isa.h"
#include "sysemu/block-backend.h"
#include "sysemu/sysemu.h"
#include "sysemu/blockdev.h"
diff --git a/hw/ide/via.c b/hw/ide/via.c
index 238f038d72..987d99c5ec 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -26,7 +26,6 @@
#include "qemu/osdep.h"
#include "hw/hw.h"
#include "hw/pci/pci.h"
-#include "hw/isa/isa.h"
#include "sysemu/sysemu.h"
#include "sysemu/dma.h"
diff --git a/hw/intc/ioapic.c b/hw/intc/ioapic.c
index 4e529729b4..9d75f84d3b 100644
--- a/hw/intc/ioapic.c
+++ b/hw/intc/ioapic.c
@@ -429,7 +429,7 @@ static void ioapic_class_init(ObjectClass *klass, void *data)
}
static const TypeInfo ioapic_info = {
- .name = "ioapic",
+ .name = TYPE_IOAPIC,
.parent = TYPE_IOAPIC_COMMON,
.instance_size = sizeof(IOAPICCommonState),
.class_init = ioapic_class_init,
diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index 0e39c90cbd..d391177ab8 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -179,6 +179,15 @@ static void spapr_xive_map_mmio(sPAPRXive *xive)
sysbus_mmio_map(SYS_BUS_DEVICE(xive), 2, xive->tm_base);
}
+void spapr_xive_mmio_set_enabled(sPAPRXive *xive, bool enable)
+{
+ memory_region_set_enabled(&xive->source.esb_mmio, enable);
+ memory_region_set_enabled(&xive->tm_mmio, enable);
+
+ /* Disable the END ESBs until a guest OS makes use of them */
+ memory_region_set_enabled(&xive->end_source.esb_mmio, false);
+}
+
/*
* When a Virtual Processor is scheduled to run on a HW thread, the
* hypervisor pushes its identifier in the OS CAM line. Emulate the
@@ -488,20 +497,6 @@ bool spapr_xive_irq_free(sPAPRXive *xive, uint32_t lisn)
return true;
}
-qemu_irq spapr_xive_qirq(sPAPRXive *xive, uint32_t lisn)
-{
- XiveSource *xsrc = &xive->source;
-
- if (lisn >= xive->nr_irqs) {
- return NULL;
- }
-
- /* The sPAPR machine/device should have claimed the IRQ before */
- assert(xive_eas_is_valid(&xive->eat[lisn]));
-
- return xive_source_qirq(xsrc, lisn);
-}
-
/*
* XIVE hcalls
*
diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 406efee064..16e8ffa2aa 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -461,7 +461,7 @@ static void ics_simple_set_irq_lsi(ICSState *ics, int srcno, int val)
ics_simple_resend_lsi(ics, srcno);
}
-static void ics_simple_set_irq(void *opaque, int srcno, int val)
+void ics_simple_set_irq(void *opaque, int srcno, int val)
{
ICSState *ics = (ICSState *)opaque;
@@ -571,8 +571,6 @@ static void ics_simple_realize(DeviceState *dev, Error **errp)
return;
}
- ics->qirqs = qemu_allocate_irqs(ics_simple_set_irq, ics, ics->nr_irqs);
-
qemu_register_reset(ics_simple_reset_handler, ics);
}
diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
index e8fa9a53ae..ac94594b19 100644
--- a/hw/intc/xics_kvm.c
+++ b/hw/intc/xics_kvm.c
@@ -298,7 +298,7 @@ static int ics_set_kvm_state(ICSState *ics, int version_id)
return 0;
}
-static void ics_kvm_set_irq(void *opaque, int srcno, int val)
+void ics_kvm_set_irq(void *opaque, int srcno, int val)
{
ICSState *ics = opaque;
struct kvm_irq_level args;
@@ -344,7 +344,6 @@ static void ics_kvm_realize(DeviceState *dev, Error **errp)
error_propagate(errp, local_err);
return;
}
- ics->qirqs = qemu_allocate_irqs(ics_kvm_set_irq, ics, ics->nr_irqs);
qemu_register_reset(ics_kvm_reset_handler, ics);
}
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index f67d3c80bf..9c1a90d709 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -44,7 +44,7 @@ static target_ulong h_cppr(PowerPCCPU *cpu, sPAPRMachineState *spapr,
{
target_ulong cppr = args[0];
- icp_set_cppr(ICP(cpu->intc), cppr);
+ icp_set_cppr(cpu->icp, cppr);
return H_SUCCESS;
}
@@ -65,7 +65,7 @@ static target_ulong h_ipi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
static target_ulong h_xirr(PowerPCCPU *cpu, sPAPRMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
- uint32_t xirr = icp_accept(ICP(cpu->intc));
+ uint32_t xirr = icp_accept(cpu->icp);
args[0] = xirr;
return H_SUCCESS;
@@ -74,7 +74,7 @@ static target_ulong h_xirr(PowerPCCPU *cpu, sPAPRMachineState *spapr,
static target_ulong h_xirr_x(PowerPCCPU *cpu, sPAPRMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
- uint32_t xirr = icp_accept(ICP(cpu->intc));
+ uint32_t xirr = icp_accept(cpu->icp);
args[0] = xirr;
args[1] = cpu_get_host_ticks();
@@ -86,7 +86,7 @@ static target_ulong h_eoi(PowerPCCPU *cpu, sPAPRMachineState *spapr,
{
target_ulong xirr = args[0];
- icp_eoi(ICP(cpu->intc), xirr);
+ icp_eoi(cpu->icp, xirr);
return H_SUCCESS;
}
@@ -94,7 +94,7 @@ static target_ulong h_ipoll(PowerPCCPU *cpu, sPAPRMachineState *spapr,
target_ulong opcode, target_ulong *args)
{
uint32_t mfrr;
- uint32_t xirr = icp_ipoll(ICP(cpu->intc), &mfrr);
+ uint32_t xirr = icp_ipoll(cpu->icp, &mfrr);
args[0] = xirr;
args[1] = mfrr;
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index ea33494338..a3cb0cf0e3 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -321,7 +321,7 @@ static void xive_tm_write(void *opaque, hwaddr offset,
uint64_t value, unsigned size)
{
PowerPCCPU *cpu = POWERPC_CPU(current_cpu);
- XiveTCTX *tctx = XIVE_TCTX(cpu->intc);
+ XiveTCTX *tctx = cpu->tctx;
const XiveTmOp *xto;
/*
@@ -360,7 +360,7 @@ static void xive_tm_write(void *opaque, hwaddr offset,
static uint64_t xive_tm_read(void *opaque, hwaddr offset, unsigned size)
{
PowerPCCPU *cpu = POWERPC_CPU(current_cpu);
- XiveTCTX *tctx = XIVE_TCTX(cpu->intc);
+ XiveTCTX *tctx = cpu->tctx;
const XiveTmOp *xto;
/*
@@ -845,7 +845,7 @@ static const MemoryRegionOps xive_source_esb_ops = {
},
};
-static void xive_source_set_irq(void *opaque, int srcno, int val)
+void xive_source_set_irq(void *opaque, int srcno, int val)
{
XiveSource *xsrc = XIVE_SOURCE(opaque);
bool notify = false;
@@ -932,9 +932,6 @@ static void xive_source_realize(DeviceState *dev, Error **errp)
&xive_source_esb_ops, xsrc, "xive.esb",
(1ull << xsrc->esb_shift) * xsrc->nr_irqs);
- xsrc->qirqs = qemu_allocate_irqs(xive_source_set_irq, xsrc,
- xsrc->nr_irqs);
-
qemu_register_reset(xive_source_reset, dev);
}
@@ -1186,7 +1183,7 @@ static bool xive_presenter_match(XiveRouter *xrtr, uint8_t format,
CPU_FOREACH(cs) {
PowerPCCPU *cpu = POWERPC_CPU(cs);
- XiveTCTX *tctx = XIVE_TCTX(cpu->intc);
+ XiveTCTX *tctx = cpu->tctx;
int ring;
/*
diff --git a/hw/microblaze/boot.c b/hw/microblaze/boot.c
index 35bfeda7aa..489ab839b7 100644
--- a/hw/microblaze/boot.c
+++ b/hw/microblaze/boot.c
@@ -156,7 +156,7 @@ void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base,
/* If it wasn't an ELF image, try an u-boot image. */
if (kernel_size < 0) {
- hwaddr uentry, loadaddr;
+ hwaddr uentry, loadaddr = LOAD_UIMAGE_LOADADDR_INVALID;
kernel_size = load_uimage(kernel_filename, &uentry, &loadaddr, 0,
NULL, NULL);
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 680350b3c3..04f3bfa516 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -74,3 +74,4 @@ obj-$(CONFIG_PVPANIC) += pvpanic.o
obj-$(CONFIG_AUX) += auxbus.o
obj-$(CONFIG_ASPEED_SOC) += aspeed_scu.o aspeed_sdmc.o
obj-$(CONFIG_MSF2) += msf2-sysreg.o
+obj-$(CONFIG_NRF51_SOC) += nrf51_rng.o
diff --git a/hw/misc/macio/mac_dbdma.c b/hw/misc/macio/mac_dbdma.c
index 87ae246d37..e5917d8f2e 100644
--- a/hw/misc/macio/mac_dbdma.c
+++ b/hw/misc/macio/mac_dbdma.c
@@ -38,7 +38,6 @@
*/
#include "qemu/osdep.h"
#include "hw/hw.h"
-#include "hw/isa/isa.h"
#include "hw/ppc/mac_dbdma.h"
#include "qemu/main-loop.h"
#include "qemu/log.h"
diff --git a/hw/misc/nrf51_rng.c b/hw/misc/nrf51_rng.c
new file mode 100644
index 0000000000..d188f044f4
--- /dev/null
+++ b/hw/misc/nrf51_rng.c
@@ -0,0 +1,262 @@
+/*
+ * nRF51 Random Number Generator
+ *
+ * Reference Manual: http://infocenter.nordicsemi.com/pdf/nRF51_RM_v3.0.1.pdf
+ *
+ * Copyright 2018 Steffen Görtz <contrib@steffen-goertz.de>
+ *
+ * This code is licensed under the GPL version 2 or later. See
+ * the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qapi/error.h"
+#include "hw/arm/nrf51.h"
+#include "hw/misc/nrf51_rng.h"
+#include "crypto/random.h"
+
+static void update_irq(NRF51RNGState *s)
+{
+ bool irq = s->interrupt_enabled && s->event_valrdy;
+ qemu_set_irq(s->irq, irq);
+}
+
+static uint64_t rng_read(void *opaque, hwaddr offset, unsigned int size)
+{
+ NRF51RNGState *s = NRF51_RNG(opaque);
+ uint64_t r = 0;
+
+ switch (offset) {
+ case NRF51_RNG_EVENT_VALRDY:
+ r = s->event_valrdy;
+ break;
+ case NRF51_RNG_REG_SHORTS:
+ r = s->shortcut_stop_on_valrdy;
+ break;
+ case NRF51_RNG_REG_INTEN:
+ case NRF51_RNG_REG_INTENSET:
+ case NRF51_RNG_REG_INTENCLR:
+ r = s->interrupt_enabled;
+ break;
+ case NRF51_RNG_REG_CONFIG:
+ r = s->filter_enabled;
+ break;
+ case NRF51_RNG_REG_VALUE:
+ r = s->value;
+ break;
+
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: bad read offset 0x%" HWADDR_PRIx "\n",
+ __func__, offset);
+ }
+
+ return r;
+}
+
+static int64_t calc_next_timeout(NRF51RNGState *s)
+{
+ int64_t timeout = qemu_clock_get_us(QEMU_CLOCK_VIRTUAL);
+ if (s->filter_enabled) {
+ timeout += s->period_filtered_us;
+ } else {
+ timeout += s->period_unfiltered_us;
+ }
+
+ return timeout;
+}
+
+
+static void rng_update_timer(NRF51RNGState *s)
+{
+ if (s->active) {
+ timer_mod(&s->timer, calc_next_timeout(s));
+ } else {
+ timer_del(&s->timer);
+ }
+}
+
+
+static void rng_write(void *opaque, hwaddr offset,
+ uint64_t value, unsigned int size)
+{
+ NRF51RNGState *s = NRF51_RNG(opaque);
+
+ switch (offset) {
+ case NRF51_RNG_TASK_START:
+ if (value == NRF51_TRIGGER_TASK) {
+ s->active = 1;
+ rng_update_timer(s);
+ }
+ break;
+ case NRF51_RNG_TASK_STOP:
+ if (value == NRF51_TRIGGER_TASK) {
+ s->active = 0;
+ rng_update_timer(s);
+ }
+ break;
+ case NRF51_RNG_EVENT_VALRDY:
+ if (value == NRF51_EVENT_CLEAR) {
+ s->event_valrdy = 0;
+ }
+ break;
+ case NRF51_RNG_REG_SHORTS:
+ s->shortcut_stop_on_valrdy =
+ (value & BIT_MASK(NRF51_RNG_REG_SHORTS_VALRDY_STOP)) ? 1 : 0;
+ break;
+ case NRF51_RNG_REG_INTEN:
+ s->interrupt_enabled =
+ (value & BIT_MASK(NRF51_RNG_REG_INTEN_VALRDY)) ? 1 : 0;
+ break;
+ case NRF51_RNG_REG_INTENSET:
+ if (value & BIT_MASK(NRF51_RNG_REG_INTEN_VALRDY)) {
+ s->interrupt_enabled = 1;
+ }
+ break;
+ case NRF51_RNG_REG_INTENCLR:
+ if (value & BIT_MASK(NRF51_RNG_REG_INTEN_VALRDY)) {
+ s->interrupt_enabled = 0;
+ }
+ break;
+ case NRF51_RNG_REG_CONFIG:
+ s->filter_enabled =
+ (value & BIT_MASK(NRF51_RNG_REG_CONFIG_DECEN)) ? 1 : 0;
+ break;
+
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: bad write offset 0x%" HWADDR_PRIx "\n",
+ __func__, offset);
+ }
+
+ update_irq(s);
+}
+
+static const MemoryRegionOps rng_ops = {
+ .read = rng_read,
+ .write = rng_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+ .impl.min_access_size = 4,
+ .impl.max_access_size = 4
+};
+
+static void nrf51_rng_timer_expire(void *opaque)
+{
+ NRF51RNGState *s = NRF51_RNG(opaque);
+
+ qcrypto_random_bytes(&s->value, 1, &error_abort);
+
+ s->event_valrdy = 1;
+ qemu_set_irq(s->eep_valrdy, 1);
+
+ if (s->shortcut_stop_on_valrdy) {
+ s->active = 0;
+ }
+
+ rng_update_timer(s);
+ update_irq(s);
+}
+
+static void nrf51_rng_tep_start(void *opaque, int n, int level)
+{
+ NRF51RNGState *s = NRF51_RNG(opaque);
+
+ if (level) {
+ s->active = 1;
+ rng_update_timer(s);
+ }
+}
+
+static void nrf51_rng_tep_stop(void *opaque, int n, int level)
+{
+ NRF51RNGState *s = NRF51_RNG(opaque);
+
+ if (level) {
+ s->active = 0;
+ rng_update_timer(s);
+ }
+}
+
+
+static void nrf51_rng_init(Object *obj)
+{
+ NRF51RNGState *s = NRF51_RNG(obj);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+
+ memory_region_init_io(&s->mmio, obj, &rng_ops, s,
+ TYPE_NRF51_RNG, NRF51_RNG_SIZE);
+ sysbus_init_mmio(sbd, &s->mmio);
+
+ timer_init_us(&s->timer, QEMU_CLOCK_VIRTUAL, nrf51_rng_timer_expire, s);
+
+ sysbus_init_irq(sbd, &s->irq);
+
+ /* Tasks */
+ qdev_init_gpio_in_named(DEVICE(s), nrf51_rng_tep_start, "tep_start", 1);
+ qdev_init_gpio_in_named(DEVICE(s), nrf51_rng_tep_stop, "tep_stop", 1);
+
+ /* Events */
+ qdev_init_gpio_out_named(DEVICE(s), &s->eep_valrdy, "eep_valrdy", 1);
+}
+
+static void nrf51_rng_reset(DeviceState *dev)
+{
+ NRF51RNGState *s = NRF51_RNG(dev);
+
+ s->value = 0;
+ s->active = 0;
+ s->event_valrdy = 0;
+ s->shortcut_stop_on_valrdy = 0;
+ s->interrupt_enabled = 0;
+ s->filter_enabled = 0;
+
+ rng_update_timer(s);
+}
+
+
+static Property nrf51_rng_properties[] = {
+ DEFINE_PROP_UINT16("period_unfiltered_us", NRF51RNGState,
+ period_unfiltered_us, 167),
+ DEFINE_PROP_UINT16("period_filtered_us", NRF51RNGState,
+ period_filtered_us, 660),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static const VMStateDescription vmstate_rng = {
+ .name = "nrf51_soc.rng",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(active, NRF51RNGState),
+ VMSTATE_UINT32(event_valrdy, NRF51RNGState),
+ VMSTATE_UINT32(shortcut_stop_on_valrdy, NRF51RNGState),
+ VMSTATE_UINT32(interrupt_enabled, NRF51RNGState),
+ VMSTATE_UINT32(filter_enabled, NRF51RNGState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static void nrf51_rng_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ dc->props = nrf51_rng_properties;
+ dc->vmsd = &vmstate_rng;
+ dc->reset = nrf51_rng_reset;
+}
+
+static const TypeInfo nrf51_rng_info = {
+ .name = TYPE_NRF51_RNG,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(NRF51RNGState),
+ .instance_init = nrf51_rng_init,
+ .class_init = nrf51_rng_class_init
+};
+
+static void nrf51_rng_register_types(void)
+{
+ type_register_static(&nrf51_rng_info);
+}
+
+type_init(nrf51_rng_register_types)
diff --git a/hw/misc/tz-mpc.c b/hw/misc/tz-mpc.c
index fb48a1540b..9a84be75ed 100644
--- a/hw/misc/tz-mpc.c
+++ b/hw/misc/tz-mpc.c
@@ -150,7 +150,7 @@ static MemTxResult tz_mpc_reg_read(void *opaque, hwaddr addr,
r = s->ctrl;
break;
case A_BLK_MAX:
- r = s->blk_max;
+ r = s->blk_max - 1;
break;
case A_BLK_CFG:
/* We are never in "init in progress state", so this just indicates
diff --git a/hw/moxie/moxiesim.c b/hw/moxie/moxiesim.c
index 4b0ce09c5e..c6b6f7262d 100644
--- a/hw/moxie/moxiesim.c
+++ b/hw/moxie/moxiesim.c
@@ -31,7 +31,6 @@
#include "cpu.h"
#include "hw/sysbus.h"
#include "hw/hw.h"
-#include "hw/isa/isa.h"
#include "net/net.h"
#include "sysemu/sysemu.h"
#include "hw/boards.h"
diff --git a/hw/nios2/boot.c b/hw/nios2/boot.c
index 4bb5b601d3..ed5cb28e94 100644
--- a/hw/nios2/boot.c
+++ b/hw/nios2/boot.c
@@ -161,7 +161,7 @@ void nios2_load_kernel(Nios2CPU *cpu, hwaddr ddr_base,
/* If it wasn't an ELF image, try an u-boot image. */
if (kernel_size < 0) {
- hwaddr uentry, loadaddr;
+ hwaddr uentry, loadaddr = LOAD_UIMAGE_LOADADDR_INVALID;
kernel_size = load_uimage(kernel_filename, &uentry, &loadaddr, 0,
NULL, NULL);
diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index de58c7be46..53e8e010a8 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -27,7 +27,6 @@
#include "sysemu/sysemu.h"
#include "sysemu/dma.h"
#include "hw/boards.h"
-#include "hw/isa/isa.h"
#include "hw/nvram/fw_cfg.h"
#include "hw/sysbus.h"
#include "trace.h"
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index d831fa0a36..46d5010fac 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -333,6 +333,13 @@ static void pci_host_bus_register(DeviceState *host)
QLIST_INSERT_HEAD(&pci_host_bridges, host_bridge, next);
}
+static void pci_host_bus_unregister(DeviceState *host)
+{
+ PCIHostState *host_bridge = PCI_HOST_BRIDGE(host);
+
+ QLIST_REMOVE(host_bridge, next);
+}
+
PCIBus *pci_device_root_bus(const PCIDevice *d)
{
PCIBus *bus = pci_get_bus(d);
@@ -379,6 +386,11 @@ static void pci_root_bus_init(PCIBus *bus, DeviceState *parent,
pci_host_bus_register(parent);
}
+static void pci_bus_uninit(PCIBus *bus)
+{
+ pci_host_bus_unregister(BUS(bus)->parent);
+}
+
bool pci_bus_is_express(PCIBus *bus)
{
return object_dynamic_cast(OBJECT(bus), TYPE_PCIE_BUS);
@@ -413,6 +425,12 @@ PCIBus *pci_root_bus_new(DeviceState *parent, const char *name,
return bus;
}
+void pci_root_bus_cleanup(PCIBus *bus)
+{
+ pci_bus_uninit(bus);
+ object_unparent(OBJECT(bus));
+}
+
void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
void *irq_opaque, int nirq)
{
@@ -423,6 +441,15 @@ void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
bus->irq_count = g_malloc0(nirq * sizeof(bus->irq_count[0]));
}
+void pci_bus_irqs_cleanup(PCIBus *bus)
+{
+ bus->set_irq = NULL;
+ bus->map_irq = NULL;
+ bus->irq_opaque = NULL;
+ bus->nirq = 0;
+ g_free(bus->irq_count);
+}
+
PCIBus *pci_register_root_bus(DeviceState *parent, const char *name,
pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
void *irq_opaque,
@@ -439,6 +466,12 @@ PCIBus *pci_register_root_bus(DeviceState *parent, const char *name,
return bus;
}
+void pci_unregister_root_bus(PCIBus *bus)
+{
+ pci_bus_irqs_cleanup(bus);
+ pci_root_bus_cleanup(bus);
+}
+
int pci_bus_num(PCIBus *s)
{
return PCI_BUS_GET_CLASS(s)->bus_num(s);
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index b20fea0dfc..0581e9e3d4 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -995,6 +995,7 @@ void ppce500_init(MachineState *machine)
* Hrm. No ELF image? Try a uImage, maybe someone is giving us an
* ePAPR compliant kernel
*/
+ loadaddr = LOAD_UIMAGE_LOADADDR_INVALID;
payload_size = load_uimage(filename, &bios_entry, &loadaddr, NULL,
NULL, NULL);
if (payload_size < 0) {
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 346f5e7aed..d84acef55b 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -668,11 +668,20 @@ static uint32_t pnv_chip_core_pir_p8(PnvChip *chip, uint32_t core_id)
return (chip->chip_id << 7) | (core_id << 3);
}
-static Object *pnv_chip_power8_intc_create(PnvChip *chip, Object *child,
- Error **errp)
+static void pnv_chip_power8_intc_create(PnvChip *chip, PowerPCCPU *cpu,
+ Error **errp)
{
- return icp_create(child, TYPE_PNV_ICP, XICS_FABRIC(qdev_get_machine()),
- errp);
+ Error *local_err = NULL;
+ Object *obj;
+
+ obj = icp_create(OBJECT(cpu), TYPE_PNV_ICP, XICS_FABRIC(qdev_get_machine()),
+ &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ cpu->icp = ICP(obj);
}
/*
@@ -690,10 +699,10 @@ static uint32_t pnv_chip_core_pir_p9(PnvChip *chip, uint32_t core_id)
return (chip->chip_id << 8) | (core_id << 2);
}
-static Object *pnv_chip_power9_intc_create(PnvChip *chip, Object *child,
- Error **errp)
+static void pnv_chip_power9_intc_create(PnvChip *chip, PowerPCCPU *cpu,
+ Error **errp)
{
- return NULL;
+ return;
}
/* Allowed core identifiers on a POWER8 Processor Chip :
@@ -1090,7 +1099,7 @@ static ICPState *pnv_icp_get(XICSFabric *xi, int pir)
{
PowerPCCPU *cpu = ppc_get_vcpu_by_pir(pir);
- return cpu ? ICP(cpu->intc) : NULL;
+ return cpu ? cpu->icp : NULL;
}
static void pnv_pic_print_info(InterruptStatsProvider *obj,
@@ -1103,7 +1112,7 @@ static void pnv_pic_print_info(InterruptStatsProvider *obj,
CPU_FOREACH(cs) {
PowerPCCPU *cpu = POWERPC_CPU(cs);
- icp_pic_print_info(ICP(cpu->intc), mon);
+ icp_pic_print_info(cpu->icp, mon);
}
for (i = 0; i < pnv->num_chips; i++) {
diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c
index ad1bcc7990..b98f277f1e 100644
--- a/hw/ppc/pnv_core.c
+++ b/hw/ppc/pnv_core.c
@@ -114,7 +114,7 @@ static void pnv_realize_vcpu(PowerPCCPU *cpu, PnvChip *chip, Error **errp)
return;
}
- cpu->intc = pcc->intc_create(chip, OBJECT(cpu), &local_err);
+ pcc->intc_create(chip, cpu, &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
@@ -190,7 +190,7 @@ err:
static void pnv_unrealize_vcpu(PowerPCCPU *cpu)
{
qemu_unregister_reset(pnv_cpu_reset, cpu);
- object_unparent(cpu->intc);
+ object_unparent(OBJECT(cpu->icp));
cpu_remove_sync(CPU(cpu));
object_unparent(OBJECT(cpu));
}
diff --git a/hw/ppc/pnv_psi.c b/hw/ppc/pnv_psi.c
index 5b969127c3..8ced095063 100644
--- a/hw/ppc/pnv_psi.c
+++ b/hw/ppc/pnv_psi.c
@@ -207,7 +207,6 @@ static const uint64_t stat_bits[] = {
void pnv_psi_irq_set(PnvPsi *psi, PnvPsiIrq irq, bool state)
{
- ICSState *ics = &psi->ics;
uint32_t xivr_reg;
uint32_t stat_reg;
uint32_t src;
@@ -227,14 +226,14 @@ void pnv_psi_irq_set(PnvPsi *psi, PnvPsiIrq irq, bool state)
/* TODO: optimization, check mask here. That means
* re-evaluating when unmasking
*/
- qemu_irq_raise(ics->qirqs[src]);
+ qemu_irq_raise(psi->qirqs[src]);
} else {
psi->regs[stat_reg] &= ~stat_bits[irq];
/* FSP and PSI are muxed so don't lower if either is still set */
if (stat_reg != PSIHB_XSCOM_CR ||
!(psi->regs[stat_reg] & (PSIHB_CR_PSI_IRQ | PSIHB_CR_FSP_IRQ))) {
- qemu_irq_lower(ics->qirqs[src]);
+ qemu_irq_lower(psi->qirqs[src]);
} else {
state = true;
}
@@ -491,6 +490,8 @@ static void pnv_psi_realize(DeviceState *dev, Error **errp)
ics_set_irq_type(ics, i, true);
}
+ psi->qirqs = qemu_allocate_irqs(ics_simple_set_irq, ics, ics->nr_irqs);
+
/* XSCOM region for PSI registers */
pnv_xscom_region_init(&psi->xscom_regs, OBJECT(dev), &pnv_psi_xscom_ops,
psi, "xscom-psi", PNV_XSCOM_PSIHB_SIZE);
diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c
index b8aa55d526..fc06191588 100644
--- a/hw/ppc/ppc440_bamboo.c
+++ b/hw/ppc/ppc440_bamboo.c
@@ -179,7 +179,7 @@ static void bamboo_init(MachineState *machine)
CPUPPCState *env;
uint64_t elf_entry;
uint64_t elf_lowaddr;
- hwaddr loadaddr = 0;
+ hwaddr loadaddr = LOAD_UIMAGE_LOADADDR_INVALID;
target_long initrd_size = 0;
DeviceState *dev;
int success;
diff --git a/hw/ppc/ppc4xx_devs.c b/hw/ppc/ppc4xx_devs.c
index 8c6f3c9577..9b6e4c60fa 100644
--- a/hw/ppc/ppc4xx_devs.c
+++ b/hw/ppc/ppc4xx_devs.c
@@ -32,8 +32,7 @@
#include "exec/address-spaces.h"
#include "qemu/error-report.h"
-#define DEBUG_UIC
-
+/*#define DEBUG_UIC*/
#ifdef DEBUG_UIC
# define LOG_UIC(...) qemu_log_mask(CPU_LOG_INT, ## __VA_ARGS__)
diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c
index 4b051c0950..84ea592749 100644
--- a/hw/ppc/sam460ex.c
+++ b/hw/ppc/sam460ex.c
@@ -402,7 +402,7 @@ static void sam460ex_init(MachineState *machine)
CPUPPCState *env;
PPC4xxI2CState *i2c[2];
hwaddr entry = UBOOT_ENTRY;
- hwaddr loadaddr = 0;
+ hwaddr loadaddr = LOAD_UIMAGE_LOADADDR_INVALID;
target_long initrd_size = 0;
DeviceState *dev;
SysBusDevice *sbdev;
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 19a07c5c9d..83081defde 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -70,7 +70,6 @@
#include "hw/nmi.h"
#include "hw/intc/intc.h"
-#include "hw/compat.h"
#include "qemu/cutils.h"
#include "hw/ppc/spapr_cpu_core.h"
#include "hw/mem/memory-device.h"
@@ -1049,6 +1048,7 @@ static void spapr_dt_rtas(sPAPRMachineState *spapr, void *fdt)
add_str(hypertas, "hcall-sprg0");
add_str(hypertas, "hcall-copy");
add_str(hypertas, "hcall-debug");
+ add_str(hypertas, "hcall-vphn");
add_str(qemu_hypertas, "hcall-memop1");
if (!kvm_enabled() || kvmppc_spapr_use_multitce()) {
@@ -1669,7 +1669,10 @@ static void spapr_machine_reset(void)
/* Load the fdt */
qemu_fdt_dumpdtb(fdt, fdt_totalsize(fdt));
cpu_physical_memory_write(fdt_addr, fdt, fdt_totalsize(fdt));
- g_free(fdt);
+ g_free(spapr->fdt_blob);
+ spapr->fdt_size = fdt_totalsize(fdt);
+ spapr->fdt_initial_size = spapr->fdt_size;
+ spapr->fdt_blob = fdt;
/* Set up the entry state */
spapr_cpu_set_entry_state(first_ppc_cpu, SPAPR_ENTRY_POINT, fdt_addr);
@@ -1744,12 +1747,17 @@ static int spapr_post_load(void *opaque, int version_id)
return err;
}
- /* In earlier versions, there was no separate qdev for the PAPR
+ /*
+ * In earlier versions, there was no separate qdev for the PAPR
* RTC, so the RTC offset was stored directly in sPAPREnvironment.
* So when migrating from those versions, poke the incoming offset
- * value into the RTC device */
+ * value into the RTC device
+ */
if (version_id < 3) {
err = spapr_rtc_import_offset(&spapr->rtc, spapr->rtc_offset);
+ if (err) {
+ return err;
+ }
}
if (kvm_enabled() && spapr->patb_entry) {
@@ -1920,6 +1928,39 @@ static const VMStateDescription vmstate_spapr_irq_map = {
},
};
+static bool spapr_dtb_needed(void *opaque)
+{
+ sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(opaque);
+
+ return smc->update_dt_enabled;
+}
+
+static int spapr_dtb_pre_load(void *opaque)
+{
+ sPAPRMachineState *spapr = (sPAPRMachineState *)opaque;
+
+ g_free(spapr->fdt_blob);
+ spapr->fdt_blob = NULL;
+ spapr->fdt_size = 0;
+
+ return 0;
+}
+
+static const VMStateDescription vmstate_spapr_dtb = {
+ .name = "spapr_dtb",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .needed = spapr_dtb_needed,
+ .pre_load = spapr_dtb_pre_load,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(fdt_initial_size, sPAPRMachineState),
+ VMSTATE_UINT32(fdt_size, sPAPRMachineState),
+ VMSTATE_VBUFFER_ALLOC_UINT32(fdt_blob, sPAPRMachineState, 0, NULL,
+ fdt_size),
+ VMSTATE_END_OF_LIST()
+ },
+};
+
static const VMStateDescription vmstate_spapr = {
.name = "spapr",
.version_id = 3,
@@ -1949,6 +1990,7 @@ static const VMStateDescription vmstate_spapr = {
&vmstate_spapr_cap_ibs,
&vmstate_spapr_irq_map,
&vmstate_spapr_cap_nested_kvm_hv,
+ &vmstate_spapr_dtb,
NULL
}
};
@@ -2515,6 +2557,17 @@ static void spapr_init_cpus(sPAPRMachineState *spapr)
}
}
+static PCIHostState *spapr_create_default_phb(void)
+{
+ DeviceState *dev;
+
+ dev = qdev_create(NULL, TYPE_SPAPR_PCI_HOST_BRIDGE);
+ qdev_prop_set_uint32(dev, "index", 0);
+ qdev_init_nofail(dev);
+
+ return PCI_HOST_BRIDGE(dev);
+}
+
/* pSeries LPAR / sPAPR hardware init */
static void spapr_machine_init(MachineState *machine)
{
@@ -2633,11 +2686,11 @@ static void spapr_machine_init(MachineState *machine)
spapr_ovec_set(spapr->ov5, OV5_DRMEM_V2);
/* advertise XIVE on POWER9 machines */
- if (spapr->irq->ov5 & SPAPR_OV5_XIVE_EXPLOIT) {
+ if (spapr->irq->ov5 & (SPAPR_OV5_XIVE_EXPLOIT | SPAPR_OV5_XIVE_BOTH)) {
if (ppc_type_check_compat(machine->cpu_type, CPU_POWERPC_LOGICAL_3_00,
0, spapr->max_compat_pvr)) {
spapr_ovec_set(spapr->ov5, OV5_XIVE_EXPLOIT);
- } else {
+ } else if (spapr->irq->ov5 & SPAPR_OV5_XIVE_EXPLOIT) {
error_report("XIVE-only machines require a POWER9 CPU");
exit(1);
}
@@ -2747,7 +2800,7 @@ static void spapr_machine_init(MachineState *machine)
/* Set up PCI */
spapr_pci_rtas_init();
- phb = spapr_create_phb(spapr, 0);
+ phb = spapr_create_default_phb();
for (i = 0; i < nb_nics; i++) {
NICInfo *nd = &nd_table[i];
@@ -3063,6 +3116,8 @@ static char *spapr_get_ic_mode(Object *obj, Error **errp)
return g_strdup("xics");
} else if (spapr->irq == &spapr_irq_xive) {
return g_strdup("xive");
+ } else if (spapr->irq == &spapr_irq_dual) {
+ return g_strdup("dual");
}
g_assert_not_reached();
}
@@ -3076,6 +3131,8 @@ static void spapr_set_ic_mode(Object *obj, const char *value, Error **errp)
spapr->irq = &spapr_irq_xics;
} else if (strcmp(value, "xive") == 0) {
spapr->irq = &spapr_irq_xive;
+ } else if (strcmp(value, "dual") == 0) {
+ spapr->irq = &spapr_irq_dual;
} else {
error_setg(errp, "Bad value for \"ic-mode\" property");
}
@@ -3124,7 +3181,7 @@ static void spapr_instance_init(Object *obj)
object_property_add_str(obj, "ic-mode", spapr_get_ic_mode,
spapr_set_ic_mode, NULL);
object_property_set_description(obj, "ic-mode",
- "Specifies the interrupt controller mode (xics, xive)",
+ "Specifies the interrupt controller mode (xics, xive, dual)",
NULL);
}
@@ -3792,8 +3849,6 @@ static void spapr_phb_placement(sPAPRMachineState *spapr, uint32_t index,
* 1TiB 64-bit MMIO windows for each PHB.
*/
const uint64_t base_buid = 0x800000020000000ULL;
-#define SPAPR_MAX_PHBS ((SPAPR_PCI_LIMIT - SPAPR_PCI_BASE) / \
- SPAPR_PCI_MEM64_WIN_SIZE - 1)
int i;
/* Sanity check natural alignments */
@@ -3841,7 +3896,7 @@ static ICPState *spapr_icp_get(XICSFabric *xi, int vcpu_id)
{
PowerPCCPU *cpu = spapr_find_cpu(vcpu_id);
- return cpu ? ICP(cpu->intc) : NULL;
+ return cpu ? cpu->icp : NULL;
}
static void spapr_pic_print_info(InterruptStatsProvider *obj,
@@ -3931,6 +3986,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
hc->unplug = spapr_machine_device_unplug;
smc->dr_lmb_enabled = true;
+ smc->update_dt_enabled = true;
mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power9_v2.0");
mc->has_hotpluggable_cpus = true;
smc->resize_hpt_default = SPAPR_RESIZE_HPT_ENABLED;
@@ -4021,14 +4077,14 @@ DEFINE_SPAPR_MACHINE(4_0, "4.0", true);
/*
* pseries-3.1
*/
-#define SPAPR_COMPAT_3_1 \
- HW_COMPAT_3_1
-
static void spapr_machine_3_1_class_options(MachineClass *mc)
{
+ sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+
spapr_machine_4_0_class_options(mc);
- SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_3_1);
+ compat_props_add(mc->compat_props, hw_compat_3_1, hw_compat_3_1_len);
mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power8_v2.0");
+ smc->update_dt_enabled = false;
}
DEFINE_SPAPR_MACHINE(3_1, "3.1", false);
@@ -4036,15 +4092,13 @@ DEFINE_SPAPR_MACHINE(3_1, "3.1", false);
/*
* pseries-3.0
*/
-#define SPAPR_COMPAT_3_0 \
- HW_COMPAT_3_0
static void spapr_machine_3_0_class_options(MachineClass *mc)
{
sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
spapr_machine_3_1_class_options(mc);
- SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_3_0);
+ compat_props_add(mc->compat_props, hw_compat_3_0, hw_compat_3_0_len);
smc->legacy_irq_allocation = true;
smc->irq = &spapr_irq_xics_legacy;
@@ -4055,25 +4109,25 @@ DEFINE_SPAPR_MACHINE(3_0, "3.0", false);
/*
* pseries-2.12
*/
-#define SPAPR_COMPAT_2_12 \
- HW_COMPAT_2_12 \
- { \
- .driver = TYPE_POWERPC_CPU, \
- .property = "pre-3.0-migration", \
- .value = "on", \
- }, \
- { \
- .driver = TYPE_SPAPR_CPU_CORE, \
- .property = "pre-3.0-migration", \
- .value = "on", \
- },
-
static void spapr_machine_2_12_class_options(MachineClass *mc)
{
sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+ static GlobalProperty compat[] = {
+ {
+ .driver = TYPE_POWERPC_CPU,
+ .property = "pre-3.0-migration",
+ .value = "on",
+ },
+ {
+ .driver = TYPE_SPAPR_CPU_CORE,
+ .property = "pre-3.0-migration",
+ .value = "on",
+ },
+ };
spapr_machine_3_0_class_options(mc);
- SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_12);
+ compat_props_add(mc->compat_props, hw_compat_2_12, hw_compat_2_12_len);
+ compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
/* We depend on kvm_enabled() to choose a default value for the
* hpt-max-page-size capability. Of course we can't do it here
@@ -4100,8 +4154,6 @@ DEFINE_SPAPR_MACHINE(2_12_sxxm, "2.12-sxxm", false);
/*
* pseries-2.11
*/
-#define SPAPR_COMPAT_2_11 \
- HW_COMPAT_2_11
static void spapr_machine_2_11_class_options(MachineClass *mc)
{
@@ -4109,7 +4161,7 @@ static void spapr_machine_2_11_class_options(MachineClass *mc)
spapr_machine_2_12_class_options(mc);
smc->default_caps.caps[SPAPR_CAP_HTM] = SPAPR_CAP_ON;
- SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_11);
+ compat_props_add(mc->compat_props, hw_compat_2_11, hw_compat_2_11_len);
}
DEFINE_SPAPR_MACHINE(2_11, "2.11", false);
@@ -4117,13 +4169,11 @@ DEFINE_SPAPR_MACHINE(2_11, "2.11", false);
/*
* pseries-2.10
*/
-#define SPAPR_COMPAT_2_10 \
- HW_COMPAT_2_10
static void spapr_machine_2_10_class_options(MachineClass *mc)
{
spapr_machine_2_11_class_options(mc);
- SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_10);
+ compat_props_add(mc->compat_props, hw_compat_2_10, hw_compat_2_10_len);
}
DEFINE_SPAPR_MACHINE(2_10, "2.10", false);
@@ -4131,20 +4181,21 @@ DEFINE_SPAPR_MACHINE(2_10, "2.10", false);
/*
* pseries-2.9
*/
-#define SPAPR_COMPAT_2_9 \
- HW_COMPAT_2_9 \
- { \
- .driver = TYPE_POWERPC_CPU, \
- .property = "pre-2.10-migration", \
- .value = "on", \
- }, \
static void spapr_machine_2_9_class_options(MachineClass *mc)
{
sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+ static GlobalProperty compat[] = {
+ {
+ .driver = TYPE_POWERPC_CPU,
+ .property = "pre-2.10-migration",
+ .value = "on",
+ },
+ };
spapr_machine_2_10_class_options(mc);
- SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_9);
+ compat_props_add(mc->compat_props, hw_compat_2_9, hw_compat_2_9_len);
+ compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
mc->numa_auto_assign_ram = numa_legacy_auto_assign_ram;
smc->pre_2_10_has_unused_icps = true;
smc->resize_hpt_default = SPAPR_RESIZE_HPT_DISABLED;
@@ -4155,18 +4206,20 @@ DEFINE_SPAPR_MACHINE(2_9, "2.9", false);
/*
* pseries-2.8
*/
-#define SPAPR_COMPAT_2_8 \
- HW_COMPAT_2_8 \
- { \
- .driver = TYPE_SPAPR_PCI_HOST_BRIDGE, \
- .property = "pcie-extended-configuration-space", \
- .value = "off", \
- },
static void spapr_machine_2_8_class_options(MachineClass *mc)
{
+ static GlobalProperty compat[] = {
+ {
+ .driver = TYPE_SPAPR_PCI_HOST_BRIDGE,
+ .property = "pcie-extended-configuration-space",
+ .value = "off",
+ },
+ };
+
spapr_machine_2_9_class_options(mc);
- SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_8);
+ compat_props_add(mc->compat_props, hw_compat_2_8, hw_compat_2_8_len);
+ compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
mc->numa_mem_align_shift = 23;
}
@@ -4175,28 +4228,6 @@ DEFINE_SPAPR_MACHINE(2_8, "2.8", false);
/*
* pseries-2.7
*/
-#define SPAPR_COMPAT_2_7 \
- HW_COMPAT_2_7 \
- { \
- .driver = TYPE_SPAPR_PCI_HOST_BRIDGE, \
- .property = "mem_win_size", \
- .value = stringify(SPAPR_PCI_2_7_MMIO_WIN_SIZE),\
- }, \
- { \
- .driver = TYPE_SPAPR_PCI_HOST_BRIDGE, \
- .property = "mem64_win_size", \
- .value = "0", \
- }, \
- { \
- .driver = TYPE_POWERPC_CPU, \
- .property = "pre-2.8-migration", \
- .value = "on", \
- }, \
- { \
- .driver = TYPE_SPAPR_PCI_HOST_BRIDGE, \
- .property = "pre-2.8-migration", \
- .value = "on", \
- },
static void phb_placement_2_7(sPAPRMachineState *spapr, uint32_t index,
uint64_t *buid, hwaddr *pio,
@@ -4250,11 +4281,34 @@ static void phb_placement_2_7(sPAPRMachineState *spapr, uint32_t index,
static void spapr_machine_2_7_class_options(MachineClass *mc)
{
sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+ static GlobalProperty compat[] = {
+ {
+ .driver = TYPE_SPAPR_PCI_HOST_BRIDGE,
+ .property = "mem_win_size",
+ .value = stringify(SPAPR_PCI_2_7_MMIO_WIN_SIZE),
+ },
+ {
+ .driver = TYPE_SPAPR_PCI_HOST_BRIDGE,
+ .property = "mem64_win_size",
+ .value = "0",
+ },
+ {
+ .driver = TYPE_POWERPC_CPU,
+ .property = "pre-2.8-migration",
+ .value = "on",
+ },
+ {
+ .driver = TYPE_SPAPR_PCI_HOST_BRIDGE,
+ .property = "pre-2.8-migration",
+ .value = "on",
+ },
+ };
spapr_machine_2_8_class_options(mc);
mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power7_v2.3");
mc->default_machine_opts = "modern-hotplug-events=off";
- SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_7);
+ compat_props_add(mc->compat_props, hw_compat_2_7, hw_compat_2_7_len);
+ compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
smc->phb_placement = phb_placement_2_7;
}
@@ -4263,19 +4317,21 @@ DEFINE_SPAPR_MACHINE(2_7, "2.7", false);
/*
* pseries-2.6
*/
-#define SPAPR_COMPAT_2_6 \
- HW_COMPAT_2_6 \
- { \
- .driver = TYPE_SPAPR_PCI_HOST_BRIDGE,\
- .property = "ddw",\
- .value = stringify(off),\
- },
static void spapr_machine_2_6_class_options(MachineClass *mc)
{
+ static GlobalProperty compat[] = {
+ {
+ .driver = TYPE_SPAPR_PCI_HOST_BRIDGE,
+ .property = "ddw",
+ .value = stringify(off),
+ },
+ };
+
spapr_machine_2_7_class_options(mc);
mc->has_hotpluggable_cpus = false;
- SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_6);
+ compat_props_add(mc->compat_props, hw_compat_2_6, hw_compat_2_6_len);
+ compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
}
DEFINE_SPAPR_MACHINE(2_6, "2.6", false);
@@ -4283,21 +4339,22 @@ DEFINE_SPAPR_MACHINE(2_6, "2.6", false);
/*
* pseries-2.5
*/
-#define SPAPR_COMPAT_2_5 \
- HW_COMPAT_2_5 \
- { \
- .driver = "spapr-vlan", \
- .property = "use-rx-buffer-pools", \
- .value = "off", \
- },
static void spapr_machine_2_5_class_options(MachineClass *mc)
{
sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
+ static GlobalProperty compat[] = {
+ {
+ .driver = "spapr-vlan",
+ .property = "use-rx-buffer-pools",
+ .value = "off",
+ },
+ };
spapr_machine_2_6_class_options(mc);
smc->use_ohci_by_default = true;
- SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_5);
+ compat_props_add(mc->compat_props, hw_compat_2_5, hw_compat_2_5_len);
+ compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
}
DEFINE_SPAPR_MACHINE(2_5, "2.5", false);
@@ -4305,8 +4362,6 @@ DEFINE_SPAPR_MACHINE(2_5, "2.5", false);
/*
* pseries-2.4
*/
-#define SPAPR_COMPAT_2_4 \
- HW_COMPAT_2_4
static void spapr_machine_2_4_class_options(MachineClass *mc)
{
@@ -4314,7 +4369,7 @@ static void spapr_machine_2_4_class_options(MachineClass *mc)
spapr_machine_2_5_class_options(mc);
smc->dr_lmb_enabled = false;
- SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_4);
+ compat_props_add(mc->compat_props, hw_compat_2_4, hw_compat_2_4_len);
}
DEFINE_SPAPR_MACHINE(2_4, "2.4", false);
@@ -4322,18 +4377,19 @@ DEFINE_SPAPR_MACHINE(2_4, "2.4", false);
/*
* pseries-2.3
*/
-#define SPAPR_COMPAT_2_3 \
- HW_COMPAT_2_3 \
- {\
- .driver = "spapr-pci-host-bridge",\
- .property = "dynamic-reconfiguration",\
- .value = "off",\
- },
static void spapr_machine_2_3_class_options(MachineClass *mc)
{
+ static GlobalProperty compat[] = {
+ {
+ .driver = "spapr-pci-host-bridge",
+ .property = "dynamic-reconfiguration",
+ .value = "off",
+ },
+ };
spapr_machine_2_4_class_options(mc);
- SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_3);
+ compat_props_add(mc->compat_props, hw_compat_2_3, hw_compat_2_3_len);
+ compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
}
DEFINE_SPAPR_MACHINE(2_3, "2.3", false);
@@ -4341,18 +4397,19 @@ DEFINE_SPAPR_MACHINE(2_3, "2.3", false);
* pseries-2.2
*/
-#define SPAPR_COMPAT_2_2 \
- HW_COMPAT_2_2 \
- {\
- .driver = TYPE_SPAPR_PCI_HOST_BRIDGE,\
- .property = "mem_win_size",\
- .value = "0x20000000",\
- },
-
static void spapr_machine_2_2_class_options(MachineClass *mc)
{
+ static GlobalProperty compat[] = {
+ {
+ .driver = TYPE_SPAPR_PCI_HOST_BRIDGE,
+ .property = "mem_win_size",
+ .value = "0x20000000",
+ },
+ };
+
spapr_machine_2_3_class_options(mc);
- SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_2);
+ compat_props_add(mc->compat_props, hw_compat_2_2, hw_compat_2_2_len);
+ compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
mc->default_machine_opts = "modern-hotplug-events=off,suppress-vmdesc=on";
}
DEFINE_SPAPR_MACHINE(2_2, "2.2", false);
@@ -4360,13 +4417,11 @@ DEFINE_SPAPR_MACHINE(2_2, "2.2", false);
/*
* pseries-2.1
*/
-#define SPAPR_COMPAT_2_1 \
- HW_COMPAT_2_1
static void spapr_machine_2_1_class_options(MachineClass *mc)
{
spapr_machine_2_2_class_options(mc);
- SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_1);
+ compat_props_add(mc->compat_props, hw_compat_2_1, hw_compat_2_1_len);
}
DEFINE_SPAPR_MACHINE(2_1, "2.1", false);
diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
index 82666436e9..0405306d1e 100644
--- a/hw/ppc/spapr_cpu_core.c
+++ b/hw/ppc/spapr_cpu_core.c
@@ -194,7 +194,12 @@ static void spapr_unrealize_vcpu(PowerPCCPU *cpu, sPAPRCPUCore *sc)
vmstate_unregister(NULL, &vmstate_spapr_cpu_state, cpu->machine_data);
}
qemu_unregister_reset(spapr_cpu_reset, cpu);
- object_unparent(cpu->intc);
+ if (cpu->icp) {
+ object_unparent(OBJECT(cpu->icp));
+ }
+ if (cpu->tctx) {
+ object_unparent(OBJECT(cpu->tctx));
+ }
cpu_remove_sync(CPU(cpu));
object_unparent(OBJECT(cpu));
}
@@ -232,7 +237,7 @@ static void spapr_realize_vcpu(PowerPCCPU *cpu, sPAPRMachineState *spapr,
qemu_register_reset(spapr_cpu_reset, cpu);
spapr_cpu_reset(cpu);
- cpu->intc = spapr->irq->cpu_intc_create(spapr, OBJECT(cpu), &local_err);
+ spapr->irq->cpu_intc_create(spapr, cpu, &local_err);
if (local_err) {
goto error_unregister;
}
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index ae913d070f..17bcaa3822 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -1654,6 +1654,17 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
(spapr_h_cas_compose_response(spapr, args[1], args[2],
ov5_updates) != 0);
}
+
+ /*
+ * Generate a machine reset when we have an update of the
+ * interrupt mode. Only required when the machine supports both
+ * modes.
+ */
+ if (!spapr->cas_reboot) {
+ spapr->cas_reboot = spapr_ovec_test(ov5_updates, OV5_XIVE_EXPLOIT)
+ && spapr->irq->ov5 & SPAPR_OV5_XIVE_BOTH;
+ }
+
spapr_ovec_cleanup(ov5_updates);
if (spapr->cas_reboot) {
@@ -1663,6 +1674,42 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
return H_SUCCESS;
}
+static target_ulong h_home_node_associativity(PowerPCCPU *cpu,
+ sPAPRMachineState *spapr,
+ target_ulong opcode,
+ target_ulong *args)
+{
+ target_ulong flags = args[0];
+ target_ulong procno = args[1];
+ PowerPCCPU *tcpu;
+ int idx;
+
+ /* only support procno from H_REGISTER_VPA */
+ if (flags != 0x1) {
+ return H_FUNCTION;
+ }
+
+ tcpu = spapr_find_cpu(procno);
+ if (tcpu == NULL) {
+ return H_P2;
+ }
+
+ /* sequence is the same as in the "ibm,associativity" property */
+
+ idx = 0;
+#define ASSOCIATIVITY(a, b) (((uint64_t)(a) << 32) | \
+ ((uint64_t)(b) & 0xffffffff))
+ args[idx++] = ASSOCIATIVITY(0, 0);
+ args[idx++] = ASSOCIATIVITY(0, tcpu->node_id);
+ args[idx++] = ASSOCIATIVITY(procno, -1);
+ for ( ; idx < 6; idx++) {
+ args[idx] = -1;
+ }
+#undef ASSOCIATIVITY
+
+ return H_SUCCESS;
+}
+
static target_ulong h_get_cpu_characteristics(PowerPCCPU *cpu,
sPAPRMachineState *spapr,
target_ulong opcode,
@@ -1717,6 +1764,46 @@ static target_ulong h_get_cpu_characteristics(PowerPCCPU *cpu,
args[0] = characteristics;
args[1] = behaviour;
+ return H_SUCCESS;
+}
+
+static target_ulong h_update_dt(PowerPCCPU *cpu, sPAPRMachineState *spapr,
+ target_ulong opcode, target_ulong *args)
+{
+ target_ulong dt = ppc64_phys_to_real(args[0]);
+ struct fdt_header hdr = { 0 };
+ unsigned cb;
+ sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr);
+ void *fdt;
+
+ cpu_physical_memory_read(dt, &hdr, sizeof(hdr));
+ cb = fdt32_to_cpu(hdr.totalsize);
+
+ if (!smc->update_dt_enabled) {
+ return H_SUCCESS;
+ }
+
+ /* Check that the fdt did not grow out of proportion */
+ if (cb > spapr->fdt_initial_size * 2) {
+ trace_spapr_update_dt_failed_size(spapr->fdt_initial_size, cb,
+ fdt32_to_cpu(hdr.magic));
+ return H_PARAMETER;
+ }
+
+ fdt = g_malloc0(cb);
+ cpu_physical_memory_read(dt, fdt, cb);
+
+ /* Check the fdt consistency */
+ if (fdt_check_full(fdt, cb)) {
+ trace_spapr_update_dt_failed_check(spapr->fdt_initial_size, cb,
+ fdt32_to_cpu(hdr.magic));
+ return H_PARAMETER;
+ }
+
+ g_free(spapr->fdt_blob);
+ spapr->fdt_size = cb;
+ spapr->fdt_blob = fdt;
+ trace_spapr_update_dt(cb);
return H_SUCCESS;
}
@@ -1822,6 +1909,12 @@ static void hypercall_register_types(void)
/* ibm,client-architecture-support support */
spapr_register_hypercall(KVMPPC_H_CAS, h_client_architecture_support);
+
+ spapr_register_hypercall(KVMPPC_H_UPDATE_DT, h_update_dt);
+
+ /* Virtual Processor Home Node */
+ spapr_register_hypercall(H_HOME_NODE_ASSOCIATIVITY,
+ h_home_node_associativity);
}
type_init(hypercall_register_types)
diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c
index 7b3b5afec2..5fce72fe0f 100644
--- a/hw/ppc/spapr_irq.c
+++ b/hw/ppc/spapr_irq.c
@@ -171,7 +171,7 @@ static qemu_irq spapr_qirq_xics(sPAPRMachineState *spapr, int irq)
uint32_t srcno = irq - ics->offset;
if (ics_valid_irq(ics, irq)) {
- return ics->qirqs[srcno];
+ return spapr->qirqs[srcno];
}
return NULL;
@@ -184,16 +184,26 @@ static void spapr_irq_print_info_xics(sPAPRMachineState *spapr, Monitor *mon)
CPU_FOREACH(cs) {
PowerPCCPU *cpu = POWERPC_CPU(cs);
- icp_pic_print_info(ICP(cpu->intc), mon);
+ icp_pic_print_info(cpu->icp, mon);
}
ics_pic_print_info(spapr->ics, mon);
}
-static Object *spapr_irq_cpu_intc_create_xics(sPAPRMachineState *spapr,
- Object *cpu, Error **errp)
+static void spapr_irq_cpu_intc_create_xics(sPAPRMachineState *spapr,
+ PowerPCCPU *cpu, Error **errp)
{
- return icp_create(cpu, spapr->icp_type, XICS_FABRIC(spapr), errp);
+ Error *local_err = NULL;
+ Object *obj;
+
+ obj = icp_create(OBJECT(cpu), spapr->icp_type, XICS_FABRIC(spapr),
+ &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ cpu->icp = ICP(obj);
}
static int spapr_irq_post_load_xics(sPAPRMachineState *spapr, int version_id)
@@ -202,12 +212,29 @@ static int spapr_irq_post_load_xics(sPAPRMachineState *spapr, int version_id)
CPUState *cs;
CPU_FOREACH(cs) {
PowerPCCPU *cpu = POWERPC_CPU(cs);
- icp_resend(ICP(cpu->intc));
+ icp_resend(cpu->icp);
}
}
return 0;
}
+static void spapr_irq_set_irq_xics(void *opaque, int srcno, int val)
+{
+ sPAPRMachineState *spapr = opaque;
+ MachineState *machine = MACHINE(opaque);
+
+ if (kvm_enabled() && machine_kernel_irqchip_allowed(machine)) {
+ ics_kvm_set_irq(spapr->ics, srcno, val);
+ } else {
+ ics_simple_set_irq(spapr->ics, srcno, val);
+ }
+}
+
+static void spapr_irq_reset_xics(sPAPRMachineState *spapr, Error **errp)
+{
+ /* TODO: create the KVM XICS device */
+}
+
#define SPAPR_IRQ_XICS_NR_IRQS 0x1000
#define SPAPR_IRQ_XICS_NR_MSIS \
(XICS_IRQ_BASE + SPAPR_IRQ_XICS_NR_IRQS - SPAPR_IRQ_MSI)
@@ -225,6 +252,8 @@ sPAPRIrq spapr_irq_xics = {
.dt_populate = spapr_dt_xics,
.cpu_intc_create = spapr_irq_cpu_intc_create_xics,
.post_load = spapr_irq_post_load_xics,
+ .reset = spapr_irq_reset_xics,
+ .set_irq = spapr_irq_set_irq_xics,
};
/*
@@ -284,7 +313,16 @@ static void spapr_irq_free_xive(sPAPRMachineState *spapr, int irq, int num)
static qemu_irq spapr_qirq_xive(sPAPRMachineState *spapr, int irq)
{
- return spapr_xive_qirq(spapr->xive, irq);
+ sPAPRXive *xive = spapr->xive;
+
+ if (irq >= xive->nr_irqs) {
+ return NULL;
+ }
+
+ /* The sPAPR machine/device should have claimed the IRQ before */
+ assert(xive_eas_is_valid(&xive->eat[irq]));
+
+ return spapr->qirqs[irq];
}
static void spapr_irq_print_info_xive(sPAPRMachineState *spapr,
@@ -295,23 +333,31 @@ static void spapr_irq_print_info_xive(sPAPRMachineState *spapr,
CPU_FOREACH(cs) {
PowerPCCPU *cpu = POWERPC_CPU(cs);
- xive_tctx_pic_print_info(XIVE_TCTX(cpu->intc), mon);
+ xive_tctx_pic_print_info(cpu->tctx, mon);
}
spapr_xive_pic_print_info(spapr->xive, mon);
}
-static Object *spapr_irq_cpu_intc_create_xive(sPAPRMachineState *spapr,
- Object *cpu, Error **errp)
+static void spapr_irq_cpu_intc_create_xive(sPAPRMachineState *spapr,
+ PowerPCCPU *cpu, Error **errp)
{
- Object *obj = xive_tctx_create(cpu, XIVE_ROUTER(spapr->xive), errp);
+ Error *local_err = NULL;
+ Object *obj;
+
+ obj = xive_tctx_create(OBJECT(cpu), XIVE_ROUTER(spapr->xive), &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ cpu->tctx = XIVE_TCTX(obj);
/*
* (TCG) Early setting the OS CAM line for hotplugged CPUs as they
- * don't benificiate from the reset of the XIVE IRQ backend
+ * don't beneficiate from the reset of the XIVE IRQ backend
*/
- spapr_xive_set_tctx_os_cam(XIVE_TCTX(obj));
- return obj;
+ spapr_xive_set_tctx_os_cam(cpu->tctx);
}
static int spapr_irq_post_load_xive(sPAPRMachineState *spapr, int version_id)
@@ -327,8 +373,18 @@ static void spapr_irq_reset_xive(sPAPRMachineState *spapr, Error **errp)
PowerPCCPU *cpu = POWERPC_CPU(cs);
/* (TCG) Set the OS CAM line of the thread interrupt context. */
- spapr_xive_set_tctx_os_cam(XIVE_TCTX(cpu->intc));
+ spapr_xive_set_tctx_os_cam(cpu->tctx);
}
+
+ /* Activate the XIVE MMIOs */
+ spapr_xive_mmio_set_enabled(spapr->xive, true);
+}
+
+static void spapr_irq_set_irq_xive(void *opaque, int srcno, int val)
+{
+ sPAPRMachineState *spapr = opaque;
+
+ xive_source_set_irq(&spapr->xive->source, srcno, val);
}
/*
@@ -353,6 +409,186 @@ sPAPRIrq spapr_irq_xive = {
.cpu_intc_create = spapr_irq_cpu_intc_create_xive,
.post_load = spapr_irq_post_load_xive,
.reset = spapr_irq_reset_xive,
+ .set_irq = spapr_irq_set_irq_xive,
+};
+
+/*
+ * Dual XIVE and XICS IRQ backend.
+ *
+ * Both interrupt mode, XIVE and XICS, objects are created but the
+ * machine starts in legacy interrupt mode (XICS). It can be changed
+ * by the CAS negotiation process and, in that case, the new mode is
+ * activated after an extra machine reset.
+ */
+
+/*
+ * Returns the sPAPR IRQ backend negotiated by CAS. XICS is the
+ * default.
+ */
+static sPAPRIrq *spapr_irq_current(sPAPRMachineState *spapr)
+{
+ return spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT) ?
+ &spapr_irq_xive : &spapr_irq_xics;
+}
+
+static void spapr_irq_init_dual(sPAPRMachineState *spapr, Error **errp)
+{
+ MachineState *machine = MACHINE(spapr);
+ Error *local_err = NULL;
+
+ if (kvm_enabled() && machine_kernel_irqchip_allowed(machine)) {
+ error_setg(errp, "No KVM support for the 'dual' machine");
+ return;
+ }
+
+ spapr_irq_xics.init(spapr, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ /*
+ * Align the XICS and the XIVE IRQ number space under QEMU.
+ *
+ * However, the XICS KVM device still considers that the IRQ
+ * numbers should start at XICS_IRQ_BASE (0x1000). Either we
+ * should introduce a KVM device ioctl to set the offset or ignore
+ * the lower 4K numbers when using the get/set ioctl of the XICS
+ * KVM device. The second option seems the least intrusive.
+ */
+ spapr->ics->offset = 0;
+
+ spapr_irq_xive.init(spapr, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+}
+
+static int spapr_irq_claim_dual(sPAPRMachineState *spapr, int irq, bool lsi,
+ Error **errp)
+{
+ Error *local_err = NULL;
+ int ret;
+
+ ret = spapr_irq_xics.claim(spapr, irq, lsi, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return ret;
+ }
+
+ ret = spapr_irq_xive.claim(spapr, irq, lsi, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return ret;
+ }
+
+ return ret;
+}
+
+static void spapr_irq_free_dual(sPAPRMachineState *spapr, int irq, int num)
+{
+ spapr_irq_xics.free(spapr, irq, num);
+ spapr_irq_xive.free(spapr, irq, num);
+}
+
+static qemu_irq spapr_qirq_dual(sPAPRMachineState *spapr, int irq)
+{
+ sPAPRXive *xive = spapr->xive;
+ ICSState *ics = spapr->ics;
+
+ if (irq >= spapr->irq->nr_irqs) {
+ return NULL;
+ }
+
+ /*
+ * The IRQ number should have been claimed under both interrupt
+ * controllers.
+ */
+ assert(!ICS_IRQ_FREE(ics, irq - ics->offset));
+ assert(xive_eas_is_valid(&xive->eat[irq]));
+
+ return spapr->qirqs[irq];
+}
+
+static void spapr_irq_print_info_dual(sPAPRMachineState *spapr, Monitor *mon)
+{
+ spapr_irq_current(spapr)->print_info(spapr, mon);
+}
+
+static void spapr_irq_dt_populate_dual(sPAPRMachineState *spapr,
+ uint32_t nr_servers, void *fdt,
+ uint32_t phandle)
+{
+ spapr_irq_current(spapr)->dt_populate(spapr, nr_servers, fdt, phandle);
+}
+
+static void spapr_irq_cpu_intc_create_dual(sPAPRMachineState *spapr,
+ PowerPCCPU *cpu, Error **errp)
+{
+ Error *local_err = NULL;
+
+ spapr_irq_xive.cpu_intc_create(spapr, cpu, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ spapr_irq_xics.cpu_intc_create(spapr, cpu, errp);
+}
+
+static int spapr_irq_post_load_dual(sPAPRMachineState *spapr, int version_id)
+{
+ /*
+ * Force a reset of the XIVE backend after migration. The machine
+ * defaults to XICS at startup.
+ */
+ if (spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) {
+ spapr_irq_xive.reset(spapr, &error_fatal);
+ }
+
+ return spapr_irq_current(spapr)->post_load(spapr, version_id);
+}
+
+static void spapr_irq_reset_dual(sPAPRMachineState *spapr, Error **errp)
+{
+ /*
+ * Deactivate the XIVE MMIOs. The XIVE backend will reenable them
+ * if selected.
+ */
+ spapr_xive_mmio_set_enabled(spapr->xive, false);
+
+ spapr_irq_current(spapr)->reset(spapr, errp);
+}
+
+static void spapr_irq_set_irq_dual(void *opaque, int srcno, int val)
+{
+ sPAPRMachineState *spapr = opaque;
+
+ spapr_irq_current(spapr)->set_irq(spapr, srcno, val);
+}
+
+/*
+ * Define values in sync with the XIVE and XICS backend
+ */
+#define SPAPR_IRQ_DUAL_NR_IRQS 0x2000
+#define SPAPR_IRQ_DUAL_NR_MSIS (SPAPR_IRQ_DUAL_NR_IRQS - SPAPR_IRQ_MSI)
+
+sPAPRIrq spapr_irq_dual = {
+ .nr_irqs = SPAPR_IRQ_DUAL_NR_IRQS,
+ .nr_msis = SPAPR_IRQ_DUAL_NR_MSIS,
+ .ov5 = SPAPR_OV5_XIVE_BOTH,
+
+ .init = spapr_irq_init_dual,
+ .claim = spapr_irq_claim_dual,
+ .free = spapr_irq_free_dual,
+ .qirq = spapr_qirq_dual,
+ .print_info = spapr_irq_print_info_dual,
+ .dt_populate = spapr_irq_dt_populate_dual,
+ .cpu_intc_create = spapr_irq_cpu_intc_create_dual,
+ .post_load = spapr_irq_post_load_dual,
+ .reset = spapr_irq_reset_dual,
+ .set_irq = spapr_irq_set_irq_dual
};
/*
@@ -366,6 +602,9 @@ void spapr_irq_init(sPAPRMachineState *spapr, Error **errp)
}
spapr->irq->init(spapr, errp);
+
+ spapr->qirqs = qemu_allocate_irqs(spapr->irq->set_irq, spapr,
+ spapr->irq->nr_irqs);
}
int spapr_irq_claim(sPAPRMachineState *spapr, int irq, bool lsi, Error **errp)
@@ -465,4 +704,5 @@ sPAPRIrq spapr_irq_xics_legacy = {
.dt_populate = spapr_dt_xics,
.cpu_intc_create = spapr_irq_cpu_intc_create_xics,
.post_load = spapr_irq_post_load_xics,
+ .set_irq = spapr_irq_set_irq_xics,
};
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index bfb02ee96b..b74f2632ec 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -1988,17 +1988,6 @@ static const TypeInfo spapr_phb_info = {
}
};
-PCIHostState *spapr_create_phb(sPAPRMachineState *spapr, int index)
-{
- DeviceState *dev;
-
- dev = qdev_create(NULL, TYPE_SPAPR_PCI_HOST_BRIDGE);
- qdev_prop_set_uint32(dev, "index", index);
- qdev_init_nofail(dev);
-
- return PCI_HOST_BRIDGE(dev);
-}
-
typedef struct sPAPRFDT {
void *fdt;
int node_off;
diff --git a/hw/ppc/trace-events b/hw/ppc/trace-events
index dc5e65aee9..0af155ed32 100644
--- a/hw/ppc/trace-events
+++ b/hw/ppc/trace-events
@@ -22,6 +22,9 @@ spapr_cas_pvr_try(uint32_t pvr) "0x%x"
spapr_cas_pvr(uint32_t cur_pvr, bool explicit_match, uint32_t new_pvr) "current=0x%x, explicit_match=%u, new=0x%x"
spapr_h_resize_hpt_prepare(uint64_t flags, uint64_t shift) "flags=0x%"PRIx64", shift=%"PRIu64
spapr_h_resize_hpt_commit(uint64_t flags, uint64_t shift) "flags=0x%"PRIx64", shift=%"PRIu64
+spapr_update_dt(unsigned cb) "New blob %u bytes"
+spapr_update_dt_failed_size(unsigned cbold, unsigned cbnew, unsigned magic) "Old blob %u bytes, new blob %u bytes, magic 0x%x"
+spapr_update_dt_failed_check(unsigned cbold, unsigned cbnew, unsigned magic) "Old blob %u bytes, new blob %u bytes, magic 0x%x"
# hw/ppc/spapr_iommu.c
spapr_iommu_put(uint64_t liobn, uint64_t ioba, uint64_t tce, uint64_t ret) "liobn=0x%"PRIx64" ioba=0x%"PRIx64" tce=0x%"PRIx64" ret=%"PRId64
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index fd9d0b0542..c737507053 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -28,7 +28,6 @@
#include "hw/s390x/storage-keys.h"
#include "hw/s390x/storage-attributes.h"
#include "hw/s390x/event-facility.h"
-#include "hw/compat.h"
#include "ipl.h"
#include "hw/s390x/s390-virtio-ccw.h"
#include "hw/s390x/css-bridge.h"
@@ -651,100 +650,6 @@ bool css_migration_enabled(void)
} \
type_init(ccw_machine_register_##suffix)
-#define CCW_COMPAT_3_1 \
- HW_COMPAT_3_1
-
-#define CCW_COMPAT_3_0 \
- HW_COMPAT_3_0
-
-#define CCW_COMPAT_2_12 \
- HW_COMPAT_2_12
-
-#define CCW_COMPAT_2_11 \
- HW_COMPAT_2_11 \
- {\
- .driver = TYPE_SCLP_EVENT_FACILITY,\
- .property = "allow_all_mask_sizes",\
- .value = "off",\
- },
-
-#define CCW_COMPAT_2_10 \
- HW_COMPAT_2_10
-
-#define CCW_COMPAT_2_9 \
- HW_COMPAT_2_9 \
- {\
- .driver = TYPE_S390_STATTRIB,\
- .property = "migration-enabled",\
- .value = "off",\
- },
-
-#define CCW_COMPAT_2_8 \
- HW_COMPAT_2_8 \
- {\
- .driver = TYPE_S390_FLIC_COMMON,\
- .property = "adapter_routes_max_batch",\
- .value = "64",\
- },
-
-#define CCW_COMPAT_2_7 \
- HW_COMPAT_2_7
-
-#define CCW_COMPAT_2_6 \
- HW_COMPAT_2_6 \
- {\
- .driver = TYPE_S390_IPL,\
- .property = "iplbext_migration",\
- .value = "off",\
- }, {\
- .driver = TYPE_VIRTUAL_CSS_BRIDGE,\
- .property = "css_dev_path",\
- .value = "off",\
- },
-
-#define CCW_COMPAT_2_5 \
- HW_COMPAT_2_5
-
-#define CCW_COMPAT_2_4 \
- HW_COMPAT_2_4 \
- {\
- .driver = TYPE_S390_SKEYS,\
- .property = "migration-enabled",\
- .value = "off",\
- },{\
- .driver = "virtio-blk-ccw",\
- .property = "max_revision",\
- .value = "0",\
- },{\
- .driver = "virtio-balloon-ccw",\
- .property = "max_revision",\
- .value = "0",\
- },{\
- .driver = "virtio-serial-ccw",\
- .property = "max_revision",\
- .value = "0",\
- },{\
- .driver = "virtio-9p-ccw",\
- .property = "max_revision",\
- .value = "0",\
- },{\
- .driver = "virtio-rng-ccw",\
- .property = "max_revision",\
- .value = "0",\
- },{\
- .driver = "virtio-net-ccw",\
- .property = "max_revision",\
- .value = "0",\
- },{\
- .driver = "virtio-scsi-ccw",\
- .property = "max_revision",\
- .value = "0",\
- },{\
- .driver = "vhost-scsi-ccw",\
- .property = "max_revision",\
- .value = "0",\
- },
-
static void ccw_machine_4_0_instance_options(MachineState *machine)
{
}
@@ -762,7 +667,7 @@ static void ccw_machine_3_1_instance_options(MachineState *machine)
static void ccw_machine_3_1_class_options(MachineClass *mc)
{
ccw_machine_4_0_class_options(mc);
- SET_MACHINE_COMPAT(mc, CCW_COMPAT_3_1);
+ compat_props_add(mc->compat_props, hw_compat_3_1, hw_compat_3_1_len);
}
DEFINE_CCW_MACHINE(3_1, "3.1", false);
@@ -777,7 +682,7 @@ static void ccw_machine_3_0_class_options(MachineClass *mc)
s390mc->hpage_1m_allowed = false;
ccw_machine_3_1_class_options(mc);
- SET_MACHINE_COMPAT(mc, CCW_COMPAT_3_0);
+ compat_props_add(mc->compat_props, hw_compat_3_0, hw_compat_3_0_len);
}
DEFINE_CCW_MACHINE(3_0, "3.0", false);
@@ -791,7 +696,7 @@ static void ccw_machine_2_12_instance_options(MachineState *machine)
static void ccw_machine_2_12_class_options(MachineClass *mc)
{
ccw_machine_3_0_class_options(mc);
- SET_MACHINE_COMPAT(mc, CCW_COMPAT_2_12);
+ compat_props_add(mc->compat_props, hw_compat_2_12, hw_compat_2_12_len);
}
DEFINE_CCW_MACHINE(2_12, "2.12", false);
@@ -806,8 +711,17 @@ static void ccw_machine_2_11_instance_options(MachineState *machine)
static void ccw_machine_2_11_class_options(MachineClass *mc)
{
+ static GlobalProperty compat[] = {
+ {
+ .driver = TYPE_SCLP_EVENT_FACILITY,
+ .property = "allow_all_mask_sizes",
+ .value = "off",
+ },
+ };
+
ccw_machine_2_12_class_options(mc);
- SET_MACHINE_COMPAT(mc, CCW_COMPAT_2_11);
+ compat_props_add(mc->compat_props, hw_compat_2_11, hw_compat_2_11_len);
+ compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
}
DEFINE_CCW_MACHINE(2_11, "2.11", false);
@@ -819,7 +733,7 @@ static void ccw_machine_2_10_instance_options(MachineState *machine)
static void ccw_machine_2_10_class_options(MachineClass *mc)
{
ccw_machine_2_11_class_options(mc);
- SET_MACHINE_COMPAT(mc, CCW_COMPAT_2_10);
+ compat_props_add(mc->compat_props, hw_compat_2_10, hw_compat_2_10_len);
}
DEFINE_CCW_MACHINE(2_10, "2.10", false);
@@ -836,9 +750,17 @@ static void ccw_machine_2_9_instance_options(MachineState *machine)
static void ccw_machine_2_9_class_options(MachineClass *mc)
{
S390CcwMachineClass *s390mc = S390_MACHINE_CLASS(mc);
+ static GlobalProperty compat[] = {
+ {
+ .driver = TYPE_S390_STATTRIB,
+ .property = "migration-enabled",
+ .value = "off",
+ },
+ };
ccw_machine_2_10_class_options(mc);
- SET_MACHINE_COMPAT(mc, CCW_COMPAT_2_9);
+ compat_props_add(mc->compat_props, hw_compat_2_9, hw_compat_2_9_len);
+ compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
s390mc->css_migration_enabled = false;
}
DEFINE_CCW_MACHINE(2_9, "2.9", false);
@@ -850,8 +772,17 @@ static void ccw_machine_2_8_instance_options(MachineState *machine)
static void ccw_machine_2_8_class_options(MachineClass *mc)
{
+ static GlobalProperty compat[] = {
+ {
+ .driver = TYPE_S390_FLIC_COMMON,
+ .property = "adapter_routes_max_batch",
+ .value = "64",
+ },
+ };
+
ccw_machine_2_9_class_options(mc);
- SET_MACHINE_COMPAT(mc, CCW_COMPAT_2_8);
+ compat_props_add(mc->compat_props, hw_compat_2_8, hw_compat_2_8_len);
+ compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
}
DEFINE_CCW_MACHINE(2_8, "2.8", false);
@@ -866,7 +797,7 @@ static void ccw_machine_2_7_class_options(MachineClass *mc)
s390mc->cpu_model_allowed = false;
ccw_machine_2_8_class_options(mc);
- SET_MACHINE_COMPAT(mc, CCW_COMPAT_2_7);
+ compat_props_add(mc->compat_props, hw_compat_2_7, hw_compat_2_7_len);
}
DEFINE_CCW_MACHINE(2_7, "2.7", false);
@@ -878,10 +809,22 @@ static void ccw_machine_2_6_instance_options(MachineState *machine)
static void ccw_machine_2_6_class_options(MachineClass *mc)
{
S390CcwMachineClass *s390mc = S390_MACHINE_CLASS(mc);
+ static GlobalProperty compat[] = {
+ {
+ .driver = TYPE_S390_IPL,
+ .property = "iplbext_migration",
+ .value = "off",
+ }, {
+ .driver = TYPE_VIRTUAL_CSS_BRIDGE,
+ .property = "css_dev_path",
+ .value = "off",
+ },
+ };
s390mc->ri_allowed = false;
ccw_machine_2_7_class_options(mc);
- SET_MACHINE_COMPAT(mc, CCW_COMPAT_2_6);
+ compat_props_add(mc->compat_props, hw_compat_2_6, hw_compat_2_6_len);
+ compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
}
DEFINE_CCW_MACHINE(2_6, "2.6", false);
@@ -893,7 +836,7 @@ static void ccw_machine_2_5_instance_options(MachineState *machine)
static void ccw_machine_2_5_class_options(MachineClass *mc)
{
ccw_machine_2_6_class_options(mc);
- SET_MACHINE_COMPAT(mc, CCW_COMPAT_2_5);
+ compat_props_add(mc->compat_props, hw_compat_2_5, hw_compat_2_5_len);
}
DEFINE_CCW_MACHINE(2_5, "2.5", false);
@@ -904,8 +847,49 @@ static void ccw_machine_2_4_instance_options(MachineState *machine)
static void ccw_machine_2_4_class_options(MachineClass *mc)
{
+ static GlobalProperty compat[] = {
+ {
+ .driver = TYPE_S390_SKEYS,
+ .property = "migration-enabled",
+ .value = "off",
+ },{
+ .driver = "virtio-blk-ccw",
+ .property = "max_revision",
+ .value = "0",
+ },{
+ .driver = "virtio-balloon-ccw",
+ .property = "max_revision",
+ .value = "0",
+ },{
+ .driver = "virtio-serial-ccw",
+ .property = "max_revision",
+ .value = "0",
+ },{
+ .driver = "virtio-9p-ccw",
+ .property = "max_revision",
+ .value = "0",
+ },{
+ .driver = "virtio-rng-ccw",
+ .property = "max_revision",
+ .value = "0",
+ },{
+ .driver = "virtio-net-ccw",
+ .property = "max_revision",
+ .value = "0",
+ },{
+ .driver = "virtio-scsi-ccw",
+ .property = "max_revision",
+ .value = "0",
+ },{
+ .driver = "vhost-scsi-ccw",
+ .property = "max_revision",
+ .value = "0",
+ },
+ };
+
ccw_machine_2_5_class_options(mc);
- SET_MACHINE_COMPAT(mc, CCW_COMPAT_2_4);
+ compat_props_add(mc->compat_props, hw_compat_2_4, hw_compat_2_4_len);
+ compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat));
}
DEFINE_CCW_MACHINE(2_4, "2.4", false);
diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index 639906cca3..709ee37e08 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -37,7 +37,6 @@
#include "net/net.h"
#include "hw/boards.h"
#include "hw/scsi/esp.h"
-#include "hw/isa/isa.h"
#include "hw/nvram/sun_nvram.h"
#include "hw/nvram/chrp_nvram.h"
#include "hw/nvram/fw_cfg.h"
diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
index b32194d153..0e9a4530f8 100644
--- a/hw/timer/Makefile.objs
+++ b/hw/timer/Makefile.objs
@@ -23,6 +23,7 @@ common-obj-$(CONFIG_IMX) += imx_gpt.o
common-obj-$(CONFIG_LM32) += lm32_timer.o
common-obj-$(CONFIG_MILKYMIST) += milkymist-sysctl.o
common-obj-$(CONFIG_XLNX_ZYNQMP) += xlnx-zynqmp-rtc.o
+common-obj-$(CONFIG_NRF51_SOC) += nrf51_timer.o
obj-$(CONFIG_ALTERA_TIMER) += altera_timer.o
obj-$(CONFIG_EXYNOS4) += exynos4210_mct.o
diff --git a/hw/timer/i8254.c b/hw/timer/i8254.c
index 1057850808..20f834e7da 100644
--- a/hw/timer/i8254.c
+++ b/hw/timer/i8254.c
@@ -23,7 +23,6 @@
*/
#include "qemu/osdep.h"
#include "hw/hw.h"
-#include "hw/isa/isa.h"
#include "qemu/timer.h"
#include "hw/timer/i8254.h"
#include "hw/timer/i8254_internal.h"
diff --git a/hw/timer/nrf51_timer.c b/hw/timer/nrf51_timer.c
new file mode 100644
index 0000000000..0c90662896
--- /dev/null
+++ b/hw/timer/nrf51_timer.c
@@ -0,0 +1,393 @@
+/*
+ * nRF51 System-on-Chip Timer peripheral
+ *
+ * Reference Manual: http://infocenter.nordicsemi.com/pdf/nRF51_RM_v3.0.pdf
+ * Product Spec: http://infocenter.nordicsemi.com/pdf/nRF51822_PS_v3.1.pdf
+ *
+ * Copyright 2018 Steffen Görtz <contrib@steffen-goertz.de>
+ * Copyright (c) 2019 Red Hat, Inc.
+ *
+ * This code is licensed under the GPL version 2 or later. See
+ * the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "hw/arm/nrf51.h"
+#include "hw/timer/nrf51_timer.h"
+#include "trace.h"
+
+#define TIMER_CLK_FREQ 16000000UL
+
+static uint32_t const bitwidths[] = {16, 8, 24, 32};
+
+static uint32_t ns_to_ticks(NRF51TimerState *s, int64_t ns)
+{
+ uint32_t freq = TIMER_CLK_FREQ >> s->prescaler;
+
+ return muldiv64(ns, freq, NANOSECONDS_PER_SECOND);
+}
+
+static int64_t ticks_to_ns(NRF51TimerState *s, uint32_t ticks)
+{
+ uint32_t freq = TIMER_CLK_FREQ >> s->prescaler;
+
+ return muldiv64(ticks, NANOSECONDS_PER_SECOND, freq);
+}
+
+/* Returns number of ticks since last call */
+static uint32_t update_counter(NRF51TimerState *s, int64_t now)
+{
+ uint32_t ticks = ns_to_ticks(s, now - s->update_counter_ns);
+
+ s->counter = (s->counter + ticks) % BIT(bitwidths[s->bitmode]);
+ s->update_counter_ns = now;
+ return ticks;
+}
+
+/* Assumes s->counter is up-to-date */
+static void rearm_timer(NRF51TimerState *s, int64_t now)
+{
+ int64_t min_ns = INT64_MAX;
+ size_t i;
+
+ for (i = 0; i < NRF51_TIMER_REG_COUNT; i++) {
+ int64_t delta_ns;
+
+ if (s->events_compare[i]) {
+ continue; /* already expired, ignore it for now */
+ }
+
+ if (s->cc[i] <= s->counter) {
+ delta_ns = ticks_to_ns(s, BIT(bitwidths[s->bitmode]) -
+ s->counter + s->cc[i]);
+ } else {
+ delta_ns = ticks_to_ns(s, s->cc[i] - s->counter);
+ }
+
+ if (delta_ns < min_ns) {
+ min_ns = delta_ns;
+ }
+ }
+
+ if (min_ns != INT64_MAX) {
+ timer_mod_ns(&s->timer, now + min_ns);
+ }
+}
+
+static void update_irq(NRF51TimerState *s)
+{
+ bool flag = false;
+ size_t i;
+
+ for (i = 0; i < NRF51_TIMER_REG_COUNT; i++) {
+ flag |= s->events_compare[i] && extract32(s->inten, 16 + i, 1);
+ }
+ qemu_set_irq(s->irq, flag);
+}
+
+static void timer_expire(void *opaque)
+{
+ NRF51TimerState *s = NRF51_TIMER(opaque);
+ int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+ uint32_t cc_remaining[NRF51_TIMER_REG_COUNT];
+ bool should_stop = false;
+ uint32_t ticks;
+ size_t i;
+
+ for (i = 0; i < NRF51_TIMER_REG_COUNT; i++) {
+ if (s->cc[i] > s->counter) {
+ cc_remaining[i] = s->cc[i] - s->counter;
+ } else {
+ cc_remaining[i] = BIT(bitwidths[s->bitmode]) -
+ s->counter + s->cc[i];
+ }
+ }
+
+ ticks = update_counter(s, now);
+
+ for (i = 0; i < NRF51_TIMER_REG_COUNT; i++) {
+ if (cc_remaining[i] <= ticks) {
+ s->events_compare[i] = 1;
+
+ if (s->shorts & BIT(i)) {
+ s->timer_start_ns = now;
+ s->update_counter_ns = s->timer_start_ns;
+ s->counter = 0;
+ }
+
+ should_stop |= s->shorts & BIT(i + 8);
+ }
+ }
+
+ update_irq(s);
+
+ if (should_stop) {
+ s->running = false;
+ timer_del(&s->timer);
+ } else {
+ rearm_timer(s, now);
+ }
+}
+
+static void counter_compare(NRF51TimerState *s)
+{
+ uint32_t counter = s->counter;
+ size_t i;
+
+ for (i = 0; i < NRF51_TIMER_REG_COUNT; i++) {
+ if (counter == s->cc[i]) {
+ s->events_compare[i] = 1;
+
+ if (s->shorts & BIT(i)) {
+ s->counter = 0;
+ }
+ }
+ }
+}
+
+static uint64_t nrf51_timer_read(void *opaque, hwaddr offset, unsigned int size)
+{
+ NRF51TimerState *s = NRF51_TIMER(opaque);
+ uint64_t r = 0;
+
+ switch (offset) {
+ case NRF51_TIMER_EVENT_COMPARE_0 ... NRF51_TIMER_EVENT_COMPARE_3:
+ r = s->events_compare[(offset - NRF51_TIMER_EVENT_COMPARE_0) / 4];
+ break;
+ case NRF51_TIMER_REG_SHORTS:
+ r = s->shorts;
+ break;
+ case NRF51_TIMER_REG_INTENSET:
+ r = s->inten;
+ break;
+ case NRF51_TIMER_REG_INTENCLR:
+ r = s->inten;
+ break;
+ case NRF51_TIMER_REG_MODE:
+ r = s->mode;
+ break;
+ case NRF51_TIMER_REG_BITMODE:
+ r = s->bitmode;
+ break;
+ case NRF51_TIMER_REG_PRESCALER:
+ r = s->prescaler;
+ break;
+ case NRF51_TIMER_REG_CC0 ... NRF51_TIMER_REG_CC3:
+ r = s->cc[(offset - NRF51_TIMER_REG_CC0) / 4];
+ break;
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: bad read offset 0x%" HWADDR_PRIx "\n",
+ __func__, offset);
+ }
+
+ trace_nrf51_timer_read(offset, r, size);
+
+ return r;
+}
+
+static void nrf51_timer_write(void *opaque, hwaddr offset,
+ uint64_t value, unsigned int size)
+{
+ NRF51TimerState *s = NRF51_TIMER(opaque);
+ uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+ size_t idx;
+
+ trace_nrf51_timer_write(offset, value, size);
+
+ switch (offset) {
+ case NRF51_TIMER_TASK_START:
+ if (value == NRF51_TRIGGER_TASK && s->mode == NRF51_TIMER_TIMER) {
+ s->running = true;
+ s->timer_start_ns = now - ticks_to_ns(s, s->counter);
+ s->update_counter_ns = s->timer_start_ns;
+ rearm_timer(s, now);
+ }
+ break;
+ case NRF51_TIMER_TASK_STOP:
+ case NRF51_TIMER_TASK_SHUTDOWN:
+ if (value == NRF51_TRIGGER_TASK) {
+ s->running = false;
+ timer_del(&s->timer);
+ }
+ break;
+ case NRF51_TIMER_TASK_COUNT:
+ if (value == NRF51_TRIGGER_TASK && s->mode == NRF51_TIMER_COUNTER) {
+ s->counter = (s->counter + 1) % BIT(bitwidths[s->bitmode]);
+ counter_compare(s);
+ }
+ break;
+ case NRF51_TIMER_TASK_CLEAR:
+ if (value == NRF51_TRIGGER_TASK) {
+ s->timer_start_ns = now;
+ s->update_counter_ns = s->timer_start_ns;
+ s->counter = 0;
+ if (s->running) {
+ rearm_timer(s, now);
+ }
+ }
+ break;
+ case NRF51_TIMER_TASK_CAPTURE_0 ... NRF51_TIMER_TASK_CAPTURE_3:
+ if (value == NRF51_TRIGGER_TASK) {
+ if (s->running) {
+ timer_expire(s); /* update counter and all state */
+ }
+
+ idx = (offset - NRF51_TIMER_TASK_CAPTURE_0) / 4;
+ s->cc[idx] = s->counter;
+ }
+ break;
+ case NRF51_TIMER_EVENT_COMPARE_0 ... NRF51_TIMER_EVENT_COMPARE_3:
+ if (value == NRF51_EVENT_CLEAR) {
+ s->events_compare[(offset - NRF51_TIMER_EVENT_COMPARE_0) / 4] = 0;
+
+ if (s->running) {
+ timer_expire(s); /* update counter and all state */
+ }
+ }
+ break;
+ case NRF51_TIMER_REG_SHORTS:
+ s->shorts = value & NRF51_TIMER_REG_SHORTS_MASK;
+ break;
+ case NRF51_TIMER_REG_INTENSET:
+ s->inten |= value & NRF51_TIMER_REG_INTEN_MASK;
+ break;
+ case NRF51_TIMER_REG_INTENCLR:
+ s->inten &= ~(value & NRF51_TIMER_REG_INTEN_MASK);
+ break;
+ case NRF51_TIMER_REG_MODE:
+ s->mode = value;
+ break;
+ case NRF51_TIMER_REG_BITMODE:
+ if (s->mode == NRF51_TIMER_TIMER && s->running) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: erroneous change of BITMODE while timer is running\n",
+ __func__);
+ }
+ s->bitmode = value & NRF51_TIMER_REG_BITMODE_MASK;
+ break;
+ case NRF51_TIMER_REG_PRESCALER:
+ if (s->mode == NRF51_TIMER_TIMER && s->running) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: erroneous change of PRESCALER while timer is running\n",
+ __func__);
+ }
+ s->prescaler = value & NRF51_TIMER_REG_PRESCALER_MASK;
+ break;
+ case NRF51_TIMER_REG_CC0 ... NRF51_TIMER_REG_CC3:
+ if (s->running) {
+ timer_expire(s); /* update counter */
+ }
+
+ idx = (offset - NRF51_TIMER_REG_CC0) / 4;
+ s->cc[idx] = value % BIT(bitwidths[s->bitmode]);
+
+ if (s->running) {
+ rearm_timer(s, now);
+ }
+ break;
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: bad write offset 0x%" HWADDR_PRIx "\n",
+ __func__, offset);
+ }
+
+ update_irq(s);
+}
+
+static const MemoryRegionOps rng_ops = {
+ .read = nrf51_timer_read,
+ .write = nrf51_timer_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+ .impl.min_access_size = 4,
+ .impl.max_access_size = 4,
+};
+
+static void nrf51_timer_init(Object *obj)
+{
+ NRF51TimerState *s = NRF51_TIMER(obj);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+
+ memory_region_init_io(&s->iomem, obj, &rng_ops, s,
+ TYPE_NRF51_TIMER, NRF51_TIMER_SIZE);
+ sysbus_init_mmio(sbd, &s->iomem);
+ sysbus_init_irq(sbd, &s->irq);
+
+ timer_init_ns(&s->timer, QEMU_CLOCK_VIRTUAL, timer_expire, s);
+}
+
+static void nrf51_timer_reset(DeviceState *dev)
+{
+ NRF51TimerState *s = NRF51_TIMER(dev);
+
+ timer_del(&s->timer);
+ s->timer_start_ns = 0x00;
+ s->update_counter_ns = 0x00;
+ s->counter = 0x00;
+ s->running = false;
+
+ memset(s->events_compare, 0x00, sizeof(s->events_compare));
+ memset(s->cc, 0x00, sizeof(s->cc));
+
+ s->shorts = 0x00;
+ s->inten = 0x00;
+ s->mode = 0x00;
+ s->bitmode = 0x00;
+ s->prescaler = 0x00;
+}
+
+static int nrf51_timer_post_load(void *opaque, int version_id)
+{
+ NRF51TimerState *s = NRF51_TIMER(opaque);
+
+ if (s->running && s->mode == NRF51_TIMER_TIMER) {
+ timer_expire(s);
+ }
+ return 0;
+}
+
+static const VMStateDescription vmstate_nrf51_timer = {
+ .name = TYPE_NRF51_TIMER,
+ .version_id = 1,
+ .post_load = nrf51_timer_post_load,
+ .fields = (VMStateField[]) {
+ VMSTATE_TIMER(timer, NRF51TimerState),
+ VMSTATE_INT64(timer_start_ns, NRF51TimerState),
+ VMSTATE_INT64(update_counter_ns, NRF51TimerState),
+ VMSTATE_UINT32(counter, NRF51TimerState),
+ VMSTATE_BOOL(running, NRF51TimerState),
+ VMSTATE_UINT8_ARRAY(events_compare, NRF51TimerState,
+ NRF51_TIMER_REG_COUNT),
+ VMSTATE_UINT32_ARRAY(cc, NRF51TimerState, NRF51_TIMER_REG_COUNT),
+ VMSTATE_UINT32(shorts, NRF51TimerState),
+ VMSTATE_UINT32(inten, NRF51TimerState),
+ VMSTATE_UINT32(mode, NRF51TimerState),
+ VMSTATE_UINT32(bitmode, NRF51TimerState),
+ VMSTATE_UINT32(prescaler, NRF51TimerState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static void nrf51_timer_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ dc->reset = nrf51_timer_reset;
+ dc->vmsd = &vmstate_nrf51_timer;
+}
+
+static const TypeInfo nrf51_timer_info = {
+ .name = TYPE_NRF51_TIMER,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(NRF51TimerState),
+ .instance_init = nrf51_timer_init,
+ .class_init = nrf51_timer_class_init
+};
+
+static void nrf51_timer_register_types(void)
+{
+ type_register_static(&nrf51_timer_info);
+}
+
+type_init(nrf51_timer_register_types)
diff --git a/hw/timer/trace-events b/hw/timer/trace-events
index 75bd3b1042..0144a68951 100644
--- a/hw/timer/trace-events
+++ b/hw/timer/trace-events
@@ -72,3 +72,8 @@ sun4v_rtc_write(uint64_t addr, uint64_t value) "write: addr 0x%" PRIx64 " value
# hw/timer/xlnx-zynqmp-rtc.c
xlnx_zynqmp_rtc_gettime(int year, int month, int day, int hour, int min, int sec) "Get time from host: %d-%d-%d %2d:%02d:%02d"
+
+# hw/timer/nrf51_timer.c
+nrf51_timer_read(uint64_t addr, uint32_t value, unsigned size) "read addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u"
+nrf51_timer_write(uint64_t addr, uint32_t value, unsigned size) "write addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u"
+
diff --git a/hw/usb/bus.c b/hw/usb/bus.c
index bf796d67e6..6fffab7bfa 100644
--- a/hw/usb/bus.c
+++ b/hw/usb/bus.c
@@ -59,12 +59,6 @@ static int usb_device_post_load(void *opaque, int version_id)
} else {
dev->attached = true;
}
- if (dev->setup_index < 0 ||
- dev->setup_len < 0 ||
- dev->setup_index > dev->setup_len ||
- dev->setup_len > sizeof(dev->data_buf)) {
- return -EINVAL;
- }
return 0;
}
diff --git a/hw/usb/ccid-card-emulated.c b/hw/usb/ccid-card-emulated.c
index 25976ed84f..e0457d305b 100644
--- a/hw/usb/ccid-card-emulated.c
+++ b/hw/usb/ccid-card-emulated.c
@@ -549,6 +549,8 @@ static void emulated_realize(CCIDCardState *base, Error **errp)
qemu_thread_create(&card->apdu_thread_id, "ccid/apdu", handle_apdu_thread,
card, QEMU_THREAD_JOINABLE);
+ return;
+
out2:
clean_event_notifier(card);
out1:
diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c
index 6098005cd4..b19b576278 100644
--- a/hw/usb/dev-mtp.c
+++ b/hw/usb/dev-mtp.c
@@ -1729,6 +1729,7 @@ static void usb_mtp_write_metadata(MTPState *s, uint64_t dlen)
if (strchr(filename, '/')) {
usb_mtp_queue_result(s, RES_PARAMETER_NOT_SUPPORTED, d->trans,
0, 0, 0, 0);
+ g_free(filename);
return;
}
diff --git a/hw/usb/hcd-ehci-pci.c b/hw/usb/hcd-ehci-pci.c
index 8c0fc53a26..69abbf7b7b 100644
--- a/hw/usb/hcd-ehci-pci.c
+++ b/hw/usb/hcd-ehci-pci.c
@@ -230,56 +230,3 @@ static void ehci_pci_register_types(void)
}
type_init(ehci_pci_register_types)
-
-struct ehci_companions {
- const char *name;
- int func;
- int port;
-};
-
-static const struct ehci_companions ich9_1d[] = {
- { .name = "ich9-usb-uhci1", .func = 0, .port = 0 },
- { .name = "ich9-usb-uhci2", .func = 1, .port = 2 },
- { .name = "ich9-usb-uhci3", .func = 2, .port = 4 },
-};
-
-static const struct ehci_companions ich9_1a[] = {
- { .name = "ich9-usb-uhci4", .func = 0, .port = 0 },
- { .name = "ich9-usb-uhci5", .func = 1, .port = 2 },
- { .name = "ich9-usb-uhci6", .func = 2, .port = 4 },
-};
-
-int ehci_create_ich9_with_companions(PCIBus *bus, int slot)
-{
- const struct ehci_companions *comp;
- PCIDevice *ehci, *uhci;
- BusState *usbbus;
- const char *name;
- int i;
-
- switch (slot) {
- case 0x1d:
- name = "ich9-usb-ehci1";
- comp = ich9_1d;
- break;
- case 0x1a:
- name = "ich9-usb-ehci2";
- comp = ich9_1a;
- break;
- default:
- return -1;
- }
-
- ehci = pci_create_multifunction(bus, PCI_DEVFN(slot, 7), true, name);
- qdev_init_nofail(&ehci->qdev);
- usbbus = QLIST_FIRST(&ehci->qdev.child_bus);
-
- for (i = 0; i < 3; i++) {
- uhci = pci_create_multifunction(bus, PCI_DEVFN(slot, comp[i].func),
- true, comp[i].name);
- qdev_prop_set_string(&uhci->qdev, "masterbus", usbbus->name);
- qdev_prop_set_uint32(&uhci->qdev, "firstport", comp[i].port);
- qdev_init_nofail(&uhci->qdev);
- }
- return 0;
-}
diff --git a/hw/usb/hcd-ehci-sysbus.c b/hw/usb/hcd-ehci-sysbus.c
index 3b83beb140..331faf8bc3 100644
--- a/hw/usb/hcd-ehci-sysbus.c
+++ b/hw/usb/hcd-ehci-sysbus.c
@@ -94,6 +94,22 @@ static const TypeInfo ehci_type_info = {
.class_size = sizeof(SysBusEHCIClass),
};
+static void ehci_platform_class_init(ObjectClass *oc, void *data)
+{
+ SysBusEHCIClass *sec = SYS_BUS_EHCI_CLASS(oc);
+ DeviceClass *dc = DEVICE_CLASS(oc);
+
+ sec->capsbase = 0x0;
+ sec->opregbase = 0x20;
+ set_bit(DEVICE_CATEGORY_USB, dc->categories);
+}
+
+static const TypeInfo ehci_platform_type_info = {
+ .name = TYPE_PLATFORM_EHCI,
+ .parent = TYPE_SYS_BUS_EHCI,
+ .class_init = ehci_platform_class_init,
+};
+
static void ehci_xlnx_class_init(ObjectClass *oc, void *data)
{
SysBusEHCIClass *sec = SYS_BUS_EHCI_CLASS(oc);
@@ -245,6 +261,7 @@ static const TypeInfo ehci_fusbh200_type_info = {
static void ehci_sysbus_register_types(void)
{
type_register_static(&ehci_type_info);
+ type_register_static(&ehci_platform_type_info);
type_register_static(&ehci_xlnx_type_info);
type_register_static(&ehci_exynos4210_type_info);
type_register_static(&ehci_tegra2_type_info);
diff --git a/hw/usb/hcd-ehci.h b/hw/usb/hcd-ehci.h
index 0bc364b286..cd30b5d5e0 100644
--- a/hw/usb/hcd-ehci.h
+++ b/hw/usb/hcd-ehci.h
@@ -342,6 +342,7 @@ typedef struct EHCIPCIState {
#define TYPE_SYS_BUS_EHCI "sysbus-ehci-usb"
+#define TYPE_PLATFORM_EHCI "platform-ehci-usb"
#define TYPE_EXYNOS4210_EHCI "exynos4210-ehci-usb"
#define TYPE_TEGRA2_EHCI "tegra2-ehci-usb"
#define TYPE_PPC4xx_EHCI "ppc4xx-ehci-usb"
diff --git a/hw/xen/xen-common.c b/hw/xen/xen-common.c
index 6ec14c73ca..d51148b6b3 100644
--- a/hw/xen/xen-common.c
+++ b/hw/xen/xen-common.c
@@ -159,33 +159,34 @@ static int xen_init(MachineState *ms)
return 0;
}
-static GlobalProperty xen_compat_props[] = {
- {
- .driver = "migration",
- .property = "store-global-state",
- .value = "off",
- },
- {
- .driver = "migration",
- .property = "send-configuration",
- .value = "off",
- },
- {
- .driver = "migration",
- .property = "send-section-footer",
- .value = "off",
- },
- { /* end of list */ },
-};
-
static void xen_accel_class_init(ObjectClass *oc, void *data)
{
AccelClass *ac = ACCEL_CLASS(oc);
+ static GlobalProperty compat[] = {
+ {
+ .driver = "migration",
+ .property = "store-global-state",
+ .value = "off",
+ },
+ {
+ .driver = "migration",
+ .property = "send-configuration",
+ .value = "off",
+ },
+ {
+ .driver = "migration",
+ .property = "send-section-footer",
+ .value = "off",
+ }
+ };
+
ac->name = "Xen";
ac->init_machine = xen_init;
ac->setup_post = xen_setup_post;
ac->allowed = &xen_allowed;
- ac->global_props = xen_compat_props;
+ ac->compat_props = g_ptr_array_new();
+
+ compat_props_add(ac->compat_props, compat, G_N_ELEMENTS(compat));
}
#define TYPE_XEN_ACCEL ACCEL_CLASS_NAME("xen")