summary refs log tree commit diff stats
path: root/include/hw
diff options
context:
space:
mode:
Diffstat (limited to 'include/hw')
-rw-r--r--include/hw/arm/allwinner-a10.h1
-rw-r--r--include/hw/arm/nrf51.h45
-rw-r--r--include/hw/arm/nrf51_soc.h9
-rw-r--r--include/hw/arm/xlnx-zynqmp.h3
-rw-r--r--include/hw/boards.h59
-rw-r--r--include/hw/char/nrf51_uart.h1
-rw-r--r--include/hw/compat.h299
-rw-r--r--include/hw/cpu/cluster.h58
-rw-r--r--include/hw/gpio/nrf51_gpio.h69
-rw-r--r--include/hw/i386/pc.h689
-rw-r--r--include/hw/loader.h7
-rw-r--r--include/hw/misc/nrf51_rng.h83
-rw-r--r--include/hw/qdev-core.h23
-rw-r--r--include/hw/timer/nrf51_timer.h80
14 files changed, 457 insertions, 969 deletions
diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h
index efb8fc8123..389e128d0f 100644
--- a/include/hw/arm/allwinner-a10.h
+++ b/include/hw/arm/allwinner-a10.h
@@ -35,6 +35,7 @@ typedef struct AwA10State {
     AwA10PICState intc;
     AwEmacState emac;
     AllwinnerAHCIState sata;
+    MemoryRegion sram_a;
 } AwA10State;
 
 #define ALLWINNER_H_
diff --git a/include/hw/arm/nrf51.h b/include/hw/arm/nrf51.h
new file mode 100644
index 0000000000..175bb6c301
--- /dev/null
+++ b/include/hw/arm/nrf51.h
@@ -0,0 +1,45 @@
+/*
+ * Nordic Semiconductor nRF51 Series SOC Common Defines
+ *
+ * This file hosts generic defines used in various nRF51 peripheral devices.
+ *
+ * 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.
+ */
+
+#ifndef NRF51_H
+#define NRF51_H
+
+#define NRF51_FLASH_BASE      0x00000000
+#define NRF51_FICR_BASE       0x10000000
+#define NRF51_FICR_SIZE       0x00000100
+#define NRF51_UICR_BASE       0x10001000
+#define NRF51_SRAM_BASE       0x20000000
+
+#define NRF51_IOMEM_BASE      0x40000000
+#define NRF51_IOMEM_SIZE      0x20000000
+
+#define NRF51_UART_BASE       0x40002000
+#define NRF51_TIMER_BASE      0x40008000
+#define NRF51_TIMER_SIZE      0x00001000
+#define NRF51_RNG_BASE        0x4000D000
+#define NRF51_NVMC_BASE       0x4001E000
+#define NRF51_GPIO_BASE       0x50000000
+
+#define NRF51_PRIVATE_BASE    0xF0000000
+#define NRF51_PRIVATE_SIZE    0x10000000
+
+#define NRF51_PAGE_SIZE       1024
+
+/* Trigger */
+#define NRF51_TRIGGER_TASK 0x01
+
+/* Events */
+#define NRF51_EVENT_CLEAR  0x00
+
+#endif
diff --git a/include/hw/arm/nrf51_soc.h b/include/hw/arm/nrf51_soc.h
index 73fc92e9a8..e06f0304b4 100644
--- a/include/hw/arm/nrf51_soc.h
+++ b/include/hw/arm/nrf51_soc.h
@@ -13,11 +13,16 @@
 #include "hw/sysbus.h"
 #include "hw/arm/armv7m.h"
 #include "hw/char/nrf51_uart.h"
+#include "hw/misc/nrf51_rng.h"
+#include "hw/gpio/nrf51_gpio.h"
+#include "hw/timer/nrf51_timer.h"
 
 #define TYPE_NRF51_SOC "nrf51-soc"
 #define NRF51_SOC(obj) \
     OBJECT_CHECK(NRF51State, (obj), TYPE_NRF51_SOC)
 
+#define NRF51_NUM_TIMERS 3
+
 typedef struct NRF51State {
     /*< private >*/
     SysBusDevice parent_obj;
@@ -26,10 +31,14 @@ typedef struct NRF51State {
     ARMv7MState cpu;
 
     NRF51UARTState uart;
+    NRF51RNGState rng;
+    NRF51GPIOState gpio;
+    NRF51TimerState timer[NRF51_NUM_TIMERS];
 
     MemoryRegion iomem;
     MemoryRegion sram;
     MemoryRegion flash;
+    MemoryRegion clock;
 
     uint32_t sram_size;
     uint32_t flash_size;
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
index 98f925ab84..591515c760 100644
--- a/include/hw/arm/xlnx-zynqmp.h
+++ b/include/hw/arm/xlnx-zynqmp.h
@@ -31,6 +31,7 @@
 #include "hw/display/xlnx_dp.h"
 #include "hw/intc/xlnx-zynqmp-ipi.h"
 #include "hw/timer/xlnx-zynqmp-rtc.h"
+#include "hw/cpu/cluster.h"
 
 #define TYPE_XLNX_ZYNQMP "xlnx,zynqmp"
 #define XLNX_ZYNQMP(obj) OBJECT_CHECK(XlnxZynqMPState, (obj), \
@@ -77,6 +78,8 @@ typedef struct XlnxZynqMPState {
     DeviceState parent_obj;
 
     /*< public >*/
+    CPUClusterState apu_cluster;
+    CPUClusterState rpu_cluster;
     ARMCPU apu_cpu[XLNX_ZYNQMP_NUM_APU_CPUS];
     ARMCPU rpu_cpu[XLNX_ZYNQMP_NUM_RPU_CPUS];
     GICState gic;
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 362384815e..02f114085f 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -69,7 +69,6 @@ int machine_kvm_shadow_mem(MachineState *machine);
 int machine_phandle_start(MachineState *machine);
 bool machine_dump_guest_core(MachineState *machine);
 bool machine_mem_merge(MachineState *machine);
-void machine_register_compat_props(MachineState *machine);
 HotpluggableCPUList *machine_query_hotpluggable_cpus(MachineState *machine);
 void machine_set_cpu_numa_node(MachineState *machine,
                                const CpuInstanceProperties *props,
@@ -191,7 +190,7 @@ struct MachineClass {
     const char *default_machine_opts;
     const char *default_boot_order;
     const char *default_display;
-    GArray *compat_props;
+    GPtrArray *compat_props;
     const char *hw_version;
     ram_addr_t default_ram_size;
     const char *default_cpu_type;
@@ -289,20 +288,46 @@ struct MachineState {
     } \
     type_init(machine_initfn##_register_types)
 
-#define SET_MACHINE_COMPAT(m, COMPAT) \
-    do {                              \
-        int i;                        \
-        static GlobalProperty props[] = {       \
-            COMPAT                              \
-            { /* end of list */ }               \
-        };                                      \
-        if (!m->compat_props) { \
-            m->compat_props = g_array_new(false, false, sizeof(void *)); \
-        } \
-        for (i = 0; props[i].driver != NULL; i++) {    \
-            GlobalProperty *prop = &props[i];          \
-            g_array_append_val(m->compat_props, prop); \
-        }                                              \
-    } while (0)
+extern GlobalProperty hw_compat_3_1[];
+extern const size_t hw_compat_3_1_len;
+
+extern GlobalProperty hw_compat_3_0[];
+extern const size_t hw_compat_3_0_len;
+
+extern GlobalProperty hw_compat_2_12[];
+extern const size_t hw_compat_2_12_len;
+
+extern GlobalProperty hw_compat_2_11[];
+extern const size_t hw_compat_2_11_len;
+
+extern GlobalProperty hw_compat_2_10[];
+extern const size_t hw_compat_2_10_len;
+
+extern GlobalProperty hw_compat_2_9[];
+extern const size_t hw_compat_2_9_len;
+
+extern GlobalProperty hw_compat_2_8[];
+extern const size_t hw_compat_2_8_len;
+
+extern GlobalProperty hw_compat_2_7[];
+extern const size_t hw_compat_2_7_len;
+
+extern GlobalProperty hw_compat_2_6[];
+extern const size_t hw_compat_2_6_len;
+
+extern GlobalProperty hw_compat_2_5[];
+extern const size_t hw_compat_2_5_len;
+
+extern GlobalProperty hw_compat_2_4[];
+extern const size_t hw_compat_2_4_len;
+
+extern GlobalProperty hw_compat_2_3[];
+extern const size_t hw_compat_2_3_len;
+
+extern GlobalProperty hw_compat_2_2[];
+extern const size_t hw_compat_2_2_len;
+
+extern GlobalProperty hw_compat_2_1[];
+extern const size_t hw_compat_2_1_len;
 
 #endif
diff --git a/include/hw/char/nrf51_uart.h b/include/hw/char/nrf51_uart.h
index e3ecb7c81c..eb1c15b490 100644
--- a/include/hw/char/nrf51_uart.h
+++ b/include/hw/char/nrf51_uart.h
@@ -16,7 +16,6 @@
 #include "hw/registerfields.h"
 
 #define UART_FIFO_LENGTH 6
-#define UART_BASE 0x40002000
 #define UART_SIZE 0x1000
 
 #define TYPE_NRF51_UART "nrf51_soc.uart"
diff --git a/include/hw/compat.h b/include/hw/compat.h
deleted file mode 100644
index 3ca85b037c..0000000000
--- a/include/hw/compat.h
+++ /dev/null
@@ -1,299 +0,0 @@
-#ifndef HW_COMPAT_H
-#define HW_COMPAT_H
-
-#define HW_COMPAT_3_1 \
-    {\
-        .driver   = "pcie-root-port",\
-        .property = "x-speed",\
-        .value    = "2_5",\
-    },{\
-        .driver   = "pcie-root-port",\
-        .property = "x-width",\
-        .value    = "1",\
-    },
-
-#define HW_COMPAT_3_0 \
-    /* empty */
-
-#define 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",\
-    },
-
-#define 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",\
-    },
-
-#define HW_COMPAT_2_10 \
-    {\
-        .driver   = "virtio-mouse-device",\
-        .property = "wheel-axis",\
-        .value    = "false",\
-    },{\
-        .driver   = "virtio-tablet-device",\
-        .property = "wheel-axis",\
-        .value    = "false",\
-    },
-
-#define 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",\
-    },
-
-#define 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",\
-    },
-
-#define 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",\
-    },
-
-#define 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",\
-    },
-
-#define 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",\
-    },
-
-#define 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",\
-    },
-
-#define 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",\
-    },
-
-#define HW_COMPAT_2_2 \
-    /* empty */
-
-#define 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",\
-    },
-
-#endif /* HW_COMPAT_H */
diff --git a/include/hw/cpu/cluster.h b/include/hw/cpu/cluster.h
new file mode 100644
index 0000000000..7381823243
--- /dev/null
+++ b/include/hw/cpu/cluster.h
@@ -0,0 +1,58 @@
+/*
+ * 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>
+ */
+#ifndef HW_CPU_CLUSTER_H
+#define HW_CPU_CLUSTER_H
+
+#include "qemu/osdep.h"
+#include "hw/qdev.h"
+
+/*
+ * CPU Cluster type
+ *
+ * A cluster is a group of CPUs which are all identical and have the same view
+ * of the rest of the system. It is mainly an internal QEMU representation and
+ * does not necessarily match with the notion of clusters on the real hardware.
+ *
+ * If CPUs are not identical (for example, Cortex-A53 and Cortex-A57 CPUs in an
+ * Arm big.LITTLE system) they should be in different clusters. If the CPUs do
+ * not have the same view of memory (for example the main CPU and a management
+ * controller processor) they should be in different clusters.
+ */
+
+#define TYPE_CPU_CLUSTER "cpu-cluster"
+#define CPU_CLUSTER(obj) \
+    OBJECT_CHECK(CPUClusterState, (obj), TYPE_CPU_CLUSTER)
+
+/**
+ * CPUClusterState:
+ * @cluster_id: The cluster ID. This value is for internal use only and should
+ *   not be exposed directly to the user or to the guest.
+ *
+ * State of a CPU cluster.
+ */
+typedef struct CPUClusterState {
+    /*< private >*/
+    DeviceState parent_obj;
+
+    /*< public >*/
+    uint32_t cluster_id;
+} CPUClusterState;
+
+#endif
diff --git a/include/hw/gpio/nrf51_gpio.h b/include/hw/gpio/nrf51_gpio.h
new file mode 100644
index 0000000000..337ee534bb
--- /dev/null
+++ b/include/hw/gpio/nrf51_gpio.h
@@ -0,0 +1,69 @@
+/*
+ * nRF51 System-on-Chip general purpose input/output register definition
+ *
+ * QEMU interface:
+ * + sysbus MMIO regions 0: GPIO registers
+ * + Unnamed GPIO inputs 0-31: Set tri-state input level for GPIO pin.
+ *   Level -1: Externally Disconnected/Floating; Pull-up/down will be regarded
+ *   Level 0: Input externally driven LOW
+ *   Level 1: Input externally driven HIGH
+ * + Unnamed GPIO outputs 0-31:
+ *   Level -1: Disconnected/Floating
+ *   Level 0: Driven LOW
+ *   Level 1: Driven HIGH
+ *
+ * Accuracy of the peripheral model:
+ * + The nRF51 GPIO output driver supports two modes, standard and high-current
+ *   mode. These different drive modes are not modeled and handled the same.
+ * + Pin SENSEing is not modeled/implemented.
+ *
+ * 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.
+ *
+ */
+#ifndef NRF51_GPIO_H
+#define NRF51_GPIO_H
+
+#include "hw/sysbus.h"
+#define TYPE_NRF51_GPIO "nrf51_soc.gpio"
+#define NRF51_GPIO(obj) OBJECT_CHECK(NRF51GPIOState, (obj), TYPE_NRF51_GPIO)
+
+#define NRF51_GPIO_PINS 32
+
+#define NRF51_GPIO_SIZE 0x1000
+
+#define NRF51_GPIO_REG_OUT          0x504
+#define NRF51_GPIO_REG_OUTSET       0x508
+#define NRF51_GPIO_REG_OUTCLR       0x50C
+#define NRF51_GPIO_REG_IN           0x510
+#define NRF51_GPIO_REG_DIR          0x514
+#define NRF51_GPIO_REG_DIRSET       0x518
+#define NRF51_GPIO_REG_DIRCLR       0x51C
+#define NRF51_GPIO_REG_CNF_START    0x700
+#define NRF51_GPIO_REG_CNF_END      0x77F
+
+#define NRF51_GPIO_PULLDOWN 1
+#define NRF51_GPIO_PULLUP 3
+
+typedef struct NRF51GPIOState {
+    SysBusDevice parent_obj;
+
+    MemoryRegion mmio;
+    qemu_irq irq;
+
+    uint32_t out;
+    uint32_t in;
+    uint32_t in_mask;
+    uint32_t dir;
+    uint32_t cnf[NRF51_GPIO_PINS];
+
+    uint32_t old_out;
+    uint32_t old_out_connected;
+
+    qemu_irq output[NRF51_GPIO_PINS];
+} NRF51GPIOState;
+
+
+#endif
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index c7c0c944e8..84720bede9 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -13,7 +13,6 @@
 #include "qemu/bitmap.h"
 #include "sysemu/sysemu.h"
 #include "hw/pci/pci.h"
-#include "hw/compat.h"
 #include "hw/mem/pc-dimm.h"
 #include "hw/mem/nvdimm.h"
 #include "hw/acpi/acpi_dev_interface.h"
@@ -294,171 +293,62 @@ int e820_add_entry(uint64_t, uint64_t, uint32_t);
 int e820_get_num_entries(void);
 bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
 
-#define PC_COMPAT_3_1 \
-    HW_COMPAT_3_1 \
-    {\
-        .driver   = "intel-iommu",\
-        .property = "dma-drain",\
-        .value    = "off",\
-    },
+extern GlobalProperty pc_compat_3_1[];
+extern const size_t pc_compat_3_1_len;
 
-#define PC_COMPAT_3_0 \
-    HW_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",\
-    },
+extern GlobalProperty pc_compat_3_0[];
+extern const size_t pc_compat_3_0_len;
 
-#define PC_COMPAT_2_12 \
-    HW_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),\
-    },
+extern GlobalProperty pc_compat_2_12[];
+extern const size_t pc_compat_2_12_len;
 
-#define PC_COMPAT_2_11 \
-    HW_COMPAT_2_11 \
-    {\
-        .driver   = TYPE_X86_CPU,\
-        .property = "x-migrate-smi-count",\
-        .value    = "off",\
-    },{\
-        .driver   = "Skylake-Server" "-" TYPE_X86_CPU,\
-        .property = "clflushopt",\
-        .value    = "off",\
-    },
+extern GlobalProperty pc_compat_2_11[];
+extern const size_t pc_compat_2_11_len;
 
-#define PC_COMPAT_2_10 \
-    HW_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",\
-    },
+extern GlobalProperty pc_compat_2_10[];
+extern const size_t pc_compat_2_10_len;
 
-#define PC_COMPAT_2_9 \
-    HW_COMPAT_2_9 \
-    {\
-        .driver   = "mch",\
-        .property = "extended-tseg-mbytes",\
-        .value    = stringify(0),\
-    },\
+extern GlobalProperty pc_compat_2_9[];
+extern const size_t pc_compat_2_9_len;
 
-#define PC_COMPAT_2_8 \
-    HW_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",\
-    },
+extern GlobalProperty pc_compat_2_8[];
+extern const size_t pc_compat_2_8_len;
 
-#define PC_COMPAT_2_7 \
-    HW_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",\
-    },
+extern GlobalProperty pc_compat_2_7[];
+extern const size_t pc_compat_2_7_len;
 
-#define PC_COMPAT_2_6 \
-    HW_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",\
-    },
+extern GlobalProperty pc_compat_2_6[];
+extern const size_t pc_compat_2_6_len;
 
-#define PC_COMPAT_2_5 \
-    HW_COMPAT_2_5
+extern GlobalProperty pc_compat_2_5[];
+extern const size_t pc_compat_2_5_len;
+
+extern GlobalProperty pc_compat_2_4[];
+extern const size_t pc_compat_2_4_len;
+
+extern GlobalProperty pc_compat_2_3[];
+extern const size_t pc_compat_2_3_len;
+
+extern GlobalProperty pc_compat_2_2[];
+extern const size_t pc_compat_2_2_len;
+
+extern GlobalProperty pc_compat_2_1[];
+extern const size_t pc_compat_2_1_len;
+
+extern GlobalProperty pc_compat_2_0[];
+extern const size_t pc_compat_2_0_len;
+
+extern GlobalProperty pc_compat_1_7[];
+extern const size_t pc_compat_1_7_len;
+
+extern GlobalProperty pc_compat_1_6[];
+extern const size_t pc_compat_1_6_len;
+
+extern GlobalProperty pc_compat_1_5[];
+extern const size_t pc_compat_1_5_len;
+
+extern GlobalProperty pc_compat_1_4[];
+extern const size_t pc_compat_1_4_len;
 
 /* Helper for setting model-id for CPU models that changed model-id
  * depending on QEMU versions up to QEMU 2.4.
@@ -480,491 +370,6 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
         .value    = "QEMU Virtual CPU version " v,\
     },
 
-#define PC_COMPAT_2_4 \
-    HW_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",\
-    },
-
-
-#define PC_COMPAT_2_3 \
-    HW_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",\
-    },
-
-#define PC_COMPAT_2_2 \
-    HW_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",\
-    },
-
-#define PC_COMPAT_2_1 \
-    HW_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",\
-    },
-
-#define 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",\
-    },
-
-#define 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),\
-    },
-
-#define 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),\
-    },
-
-#define 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),\
-    },
-
-#define 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",\
-    },
-
 #define DEFINE_PC_MACHINE(suffix, namestr, initfn, optsfn) \
     static void pc_machine_##suffix##_class_init(ObjectClass *oc, void *data) \
     { \
diff --git a/include/hw/loader.h b/include/hw/loader.h
index 0a0ad808ea..de8a29603b 100644
--- a/include/hw/loader.h
+++ b/include/hw/loader.h
@@ -175,10 +175,15 @@ void load_elf_hdr(const char *filename, void *hdr, bool *is64, Error **errp);
 int load_aout(const char *filename, hwaddr addr, int max_sz,
               int bswap_needed, hwaddr target_page_size);
 
+#define LOAD_UIMAGE_LOADADDR_INVALID (-1)
+
 /** load_uimage_as:
  * @filename: Path of uimage file
  * @ep: Populated with program entry point. Ignored if NULL.
- * @loadaddr: Populated with the load address. Ignored if NULL.
+ * @loadaddr: load address if none specified in the image or when loading a
+ *            ramdisk. Populated with the load address. Ignored if NULL or
+ *            LOAD_UIMAGE_LOADADDR_INVALID (images which do not specify a load
+ *            address will not be loadable).
  * @is_linux: Is set to true if the image loaded is Linux. Ignored if NULL.
  * @translate_fn: optional function to translate load addresses
  * @translate_opaque: opaque data passed to @translate_fn
diff --git a/include/hw/misc/nrf51_rng.h b/include/hw/misc/nrf51_rng.h
new file mode 100644
index 0000000000..3d6bf79997
--- /dev/null
+++ b/include/hw/misc/nrf51_rng.h
@@ -0,0 +1,83 @@
+/*
+ * nRF51 Random Number Generator
+ *
+ * QEMU interface:
+ * + Property "period_unfiltered_us": Time between two biased values in
+ *   microseconds.
+ * + Property "period_filtered_us": Time between two unbiased values in
+ *   microseconds.
+ * + sysbus MMIO regions 0: Memory Region with tasks, events and registers
+ *   to be mapped to the peripherals instance address by the SOC.
+ * + Named GPIO output "irq": Interrupt line of the peripheral. Must be
+ *   connected to the associated peripheral interrupt line of the NVIC.
+ * + Named GPIO output "eep_valrdy": Event set when new random value is ready
+ *   to be read.
+ * + Named GPIO input "tep_start": Task that triggers start of continuous
+ *   generation of random values.
+ * + Named GPIO input "tep_stop": Task that ends continuous generation of
+ *   random values.
+ *
+ * Accuracy of the peripheral model:
+ * + Stochastic properties of different configurations of the random source
+ *   are not modeled.
+ * + Generation of unfiltered and filtered random values take at least the
+ *   average generation time stated in the production specification;
+ *   non-deterministic generation times are not modeled.
+ *
+ * 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.
+ *
+ */
+#ifndef NRF51_RNG_H
+#define NRF51_RNG_H
+
+#include "hw/sysbus.h"
+#include "qemu/timer.h"
+#define TYPE_NRF51_RNG "nrf51_soc.rng"
+#define NRF51_RNG(obj) OBJECT_CHECK(NRF51RNGState, (obj), TYPE_NRF51_RNG)
+
+#define NRF51_RNG_SIZE         0x1000
+
+#define NRF51_RNG_TASK_START   0x000
+#define NRF51_RNG_TASK_STOP    0x004
+#define NRF51_RNG_EVENT_VALRDY 0x100
+#define NRF51_RNG_REG_SHORTS   0x200
+#define NRF51_RNG_REG_SHORTS_VALRDY_STOP 0
+#define NRF51_RNG_REG_INTEN    0x300
+#define NRF51_RNG_REG_INTEN_VALRDY 0
+#define NRF51_RNG_REG_INTENSET 0x304
+#define NRF51_RNG_REG_INTENCLR 0x308
+#define NRF51_RNG_REG_CONFIG   0x504
+#define NRF51_RNG_REG_CONFIG_DECEN 0
+#define NRF51_RNG_REG_VALUE    0x508
+
+typedef struct {
+    SysBusDevice parent_obj;
+
+    MemoryRegion mmio;
+    qemu_irq irq;
+
+    /* Event End Points */
+    qemu_irq eep_valrdy;
+
+    QEMUTimer timer;
+
+    /* Time between generation of successive unfiltered values in us */
+    uint16_t period_unfiltered_us;
+    /* Time between generation of successive filtered values in us */
+    uint16_t period_filtered_us;
+
+    uint8_t value;
+
+    uint32_t active;
+    uint32_t event_valrdy;
+    uint32_t shortcut_stop_on_valrdy;
+    uint32_t interrupt_enabled;
+    uint32_t filter_enabled;
+
+} NRF51RNGState;
+
+
+#endif /* NRF51_RNG_H_ */
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index 92851e55df..bc014c1c9f 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -249,24 +249,27 @@ struct PropertyInfo {
 
 /**
  * GlobalProperty:
- * @user_provided: Set to true if property comes from user-provided config
- * (command-line or config file).
  * @used: Set to true if property was used when initializing a device.
- * @errp: Error destination, used like first argument of error_setg()
- *        in case property setting fails later. If @errp is NULL, we
- *        print warnings instead of ignoring errors silently. For
- *        hotplugged devices, errp is always ignored and warnings are
- *        printed instead.
+ *
+ * An error is fatal for non-hotplugged devices, when the global is applied.
  */
 typedef struct GlobalProperty {
     const char *driver;
     const char *property;
     const char *value;
-    bool user_provided;
     bool used;
-    Error **errp;
 } GlobalProperty;
 
+static inline void
+compat_props_add(GPtrArray *arr,
+                 GlobalProperty props[], size_t nelem)
+{
+    int i;
+    for (i = 0; i < nelem; i++) {
+        g_ptr_array_add(arr, (void *)&props[i]);
+    }
+}
+
 /*** Board API.  This should go away once we have a machine config file.  ***/
 
 DeviceState *qdev_create(BusState *bus, const char *name);
@@ -412,6 +415,8 @@ const char *qdev_fw_name(DeviceState *dev);
 
 Object *qdev_get_machine(void);
 
+void object_apply_compat_props(Object *obj);
+
 /* FIXME: make this a link<> */
 void qdev_set_parent_bus(DeviceState *dev, BusState *bus);
 
diff --git a/include/hw/timer/nrf51_timer.h b/include/hw/timer/nrf51_timer.h
new file mode 100644
index 0000000000..85cad2300d
--- /dev/null
+++ b/include/hw/timer/nrf51_timer.h
@@ -0,0 +1,80 @@
+/*
+ * nRF51 System-on-Chip Timer peripheral
+ *
+ * QEMU interface:
+ * + sysbus MMIO regions 0: GPIO registers
+ * + sysbus irq
+ *
+ * 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.
+ */
+#ifndef NRF51_TIMER_H
+#define NRF51_TIMER_H
+
+#include "hw/sysbus.h"
+#include "qemu/timer.h"
+#define TYPE_NRF51_TIMER "nrf51_soc.timer"
+#define NRF51_TIMER(obj) OBJECT_CHECK(NRF51TimerState, (obj), TYPE_NRF51_TIMER)
+
+#define NRF51_TIMER_REG_COUNT 4
+
+#define NRF51_TIMER_TASK_START 0x000
+#define NRF51_TIMER_TASK_STOP 0x004
+#define NRF51_TIMER_TASK_COUNT 0x008
+#define NRF51_TIMER_TASK_CLEAR 0x00C
+#define NRF51_TIMER_TASK_SHUTDOWN 0x010
+#define NRF51_TIMER_TASK_CAPTURE_0 0x040
+#define NRF51_TIMER_TASK_CAPTURE_3 0x04C
+
+#define NRF51_TIMER_EVENT_COMPARE_0 0x140
+#define NRF51_TIMER_EVENT_COMPARE_1 0x144
+#define NRF51_TIMER_EVENT_COMPARE_2 0x148
+#define NRF51_TIMER_EVENT_COMPARE_3 0x14C
+
+#define NRF51_TIMER_REG_SHORTS 0x200
+#define NRF51_TIMER_REG_SHORTS_MASK 0xf0f
+#define NRF51_TIMER_REG_INTENSET 0x304
+#define NRF51_TIMER_REG_INTENCLR 0x308
+#define NRF51_TIMER_REG_INTEN_MASK 0xf0000
+#define NRF51_TIMER_REG_MODE 0x504
+#define NRF51_TIMER_REG_MODE_MASK 0x01
+#define NRF51_TIMER_TIMER 0
+#define NRF51_TIMER_COUNTER 1
+#define NRF51_TIMER_REG_BITMODE 0x508
+#define NRF51_TIMER_REG_BITMODE_MASK 0x03
+#define NRF51_TIMER_WIDTH_16 0
+#define NRF51_TIMER_WIDTH_8 1
+#define NRF51_TIMER_WIDTH_24 2
+#define NRF51_TIMER_WIDTH_32 3
+#define NRF51_TIMER_REG_PRESCALER 0x510
+#define NRF51_TIMER_REG_PRESCALER_MASK 0x0F
+#define NRF51_TIMER_REG_CC0 0x540
+#define NRF51_TIMER_REG_CC3 0x54C
+
+typedef struct NRF51TimerState {
+    SysBusDevice parent_obj;
+
+    MemoryRegion iomem;
+    qemu_irq irq;
+
+    QEMUTimer timer;
+    int64_t timer_start_ns;
+    int64_t update_counter_ns;
+    uint32_t counter;
+
+    bool running;
+
+    uint8_t events_compare[NRF51_TIMER_REG_COUNT];
+    uint32_t cc[NRF51_TIMER_REG_COUNT];
+    uint32_t shorts;
+    uint32_t inten;
+    uint32_t mode;
+    uint32_t bitmode;
+    uint32_t prescaler;
+
+} NRF51TimerState;
+
+
+#endif