aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/9pfs/virtio-9p-device.c2
-rw-r--r--hw/9pfs/virtio-9p-local.c1
-rw-r--r--hw/9pfs/virtio-9p.h18
-rw-r--r--hw/acpi/Makefile.objs1
-rw-r--r--hw/acpi/aml-build.c889
-rw-r--r--hw/acpi/bios-linker-loader.c4
-rw-r--r--hw/acpi/ich9.c14
-rw-r--r--hw/acpi/memory_hotplug.c3
-rw-r--r--hw/acpi/pcihp.c18
-rw-r--r--hw/acpi/piix4.c15
-rw-r--r--hw/arm/digic_boards.c6
-rw-r--r--hw/audio/ac97.c5
-rw-r--r--hw/audio/es1370.c5
-rw-r--r--hw/audio/intel-hda.c6
-rw-r--r--hw/block/nand.c2
-rw-r--r--hw/block/virtio-blk.c31
-rw-r--r--hw/char/serial-pci.c22
-rw-r--r--hw/char/spapr_vty.c10
-rw-r--r--hw/char/virtio-serial-bus.c4
-rw-r--r--hw/core/qdev-properties.c21
-rw-r--r--hw/core/qdev.c8
-rw-r--r--hw/core/sysbus.c2
-rw-r--r--hw/display/cirrus_vga.c11
-rw-r--r--hw/display/qxl.c36
-rw-r--r--hw/display/vga-pci.c38
-rw-r--r--hw/display/vmware_vga.c6
-rw-r--r--hw/dma/pl330.c4
-rw-r--r--hw/i2c/smbus_ich9.c5
-rw-r--r--hw/i386/Makefile.objs4
-rw-r--r--hw/i386/acpi-build.c1191
-rw-r--r--hw/i386/acpi-dsdt-cpu-hotplug.dsl17
-rw-r--r--hw/i386/acpi-dsdt-isa.dsl11
-rw-r--r--hw/i386/acpi-dsdt-mem-hotplug.dsl36
-rw-r--r--hw/i386/acpi-dsdt-pci-crs.dsl92
-rw-r--r--hw/i386/acpi-dsdt.dsl46
-rw-r--r--hw/i386/acpi-dsdt.hex.generated676
-rw-r--r--hw/i386/kvm/pci-assign.c10
-rw-r--r--hw/i386/pc.c23
-rw-r--r--hw/i386/pc_piix.c3
-rw-r--r--hw/i386/pc_q35.c3
-rw-r--r--hw/i386/q35-acpi-dsdt.dsl19
-rw-r--r--hw/i386/q35-acpi-dsdt.hex.generated628
-rw-r--r--hw/i386/ssdt-mem.dsl77
-rw-r--r--hw/i386/ssdt-mem.hex.generated213
-rw-r--r--hw/i386/ssdt-misc.dsl122
-rw-r--r--hw/i386/ssdt-misc.hex.generated399
-rw-r--r--hw/i386/ssdt-pcihp.dsl100
-rw-r--r--hw/i386/ssdt-pcihp.hex.generated251
-rw-r--r--hw/i386/ssdt-proc.dsl63
-rw-r--r--hw/i386/ssdt-proc.hex.generated134
-rw-r--r--hw/i386/ssdt-tpm.hex.generated6
-rw-r--r--hw/ide/cmd646.c5
-rw-r--r--hw/ide/ich.c13
-rw-r--r--hw/ide/pci.c2
-rw-r--r--hw/ide/piix.c10
-rw-r--r--hw/ide/via.c6
-rw-r--r--hw/input/adb.c22
-rw-r--r--hw/intc/openpic.c280
-rw-r--r--hw/ipack/tpci200.c6
-rw-r--r--hw/isa/i82378.c6
-rw-r--r--hw/isa/lpc_ich9.c14
-rw-r--r--hw/isa/piix4.c5
-rw-r--r--hw/isa/vt82c686.c24
-rw-r--r--hw/lm32/milkymist.c1
-rw-r--r--hw/microblaze/boot.c2
-rw-r--r--hw/misc/applesmc.c5
-rw-r--r--hw/misc/macio/cuda.c5
-rw-r--r--hw/misc/macio/macio.c27
-rw-r--r--hw/misc/milkymist-pfpu.c2
-rw-r--r--hw/misc/pci-testdev.c6
-rw-r--r--hw/net/e1000.c6
-rw-r--r--hw/net/eepro100.c6
-rw-r--r--hw/net/lance.c3
-rw-r--r--hw/net/ne2000.c6
-rw-r--r--hw/net/pcnet-pci.c6
-rw-r--r--hw/net/pcnet.c4
-rw-r--r--hw/net/pcnet.h2
-rw-r--r--hw/net/rtl8139.c6
-rw-r--r--hw/net/spapr_llan.c6
-rw-r--r--hw/net/vhost_net.c4
-rw-r--r--hw/net/virtio-net.c61
-rw-r--r--hw/net/vmxnet3.c6
-rw-r--r--hw/net/xilinx_ethlite.c1
-rw-r--r--hw/nvram/spapr_nvram.c15
-rw-r--r--hw/pci-bridge/dec.c5
-rw-r--r--hw/pci-host/apb.c5
-rw-r--r--hw/pci-host/bonito.c6
-rw-r--r--hw/pci-host/grackle.c5
-rw-r--r--hw/pci-host/piix.c12
-rw-r--r--hw/pci-host/ppce500.c6
-rw-r--r--hw/pci-host/prep.c6
-rw-r--r--hw/pci-host/q35.c5
-rw-r--r--hw/pci-host/uninorth.c20
-rw-r--r--hw/pci-host/versatile.c5
-rw-r--r--hw/pci/Makefile.objs2
-rw-r--r--hw/pci/pci-hotplug-old.c342
-rw-r--r--hw/pci/pci.c127
-rw-r--r--hw/ppc/Makefile.objs2
-rw-r--r--hw/ppc/e500.c21
-rw-r--r--hw/ppc/spapr.c104
-rw-r--r--hw/ppc/spapr_events.c2
-rw-r--r--hw/ppc/spapr_hcall.c2
-rw-r--r--hw/ppc/spapr_iommu.c26
-rw-r--r--hw/ppc/spapr_pci.c321
-rw-r--r--hw/ppc/spapr_pci_vfio.c115
-rw-r--r--hw/ppc/spapr_rtas.c49
-rw-r--r--hw/ppc/spapr_rtc.c212
-rw-r--r--hw/ppc/spapr_vio.c47
-rw-r--r--hw/s390x/s390-virtio-bus.h36
-rw-r--r--hw/s390x/s390-virtio.h7
-rw-r--r--hw/s390x/virtio-ccw.c12
-rw-r--r--hw/scsi/spapr_vscsi.c13
-rw-r--r--hw/scsi/vhost-scsi.c6
-rw-r--r--hw/scsi/virtio-scsi.c9
-rw-r--r--hw/sd/sdhci.c5
-rw-r--r--hw/sparc/leon3.c1
-rw-r--r--hw/timer/a9gtimer.c2
-rw-r--r--hw/timer/mc146818rtc.c44
-rw-r--r--hw/tpm/tpm_int.h1
-rw-r--r--hw/tpm/tpm_passthrough.c49
-rw-r--r--hw/tpm/tpm_tis.c131
-rw-r--r--hw/tpm/tpm_tis.h2
-rw-r--r--hw/usb/hcd-ehci-pci.c6
-rw-r--r--hw/usb/hcd-xhci.c6
-rw-r--r--hw/vfio/common.c11
-rw-r--r--hw/virtio/dataplane/vring.c10
-rw-r--r--hw/virtio/vhost-backend.c2
-rw-r--r--hw/virtio/virtio-balloon.c2
-rw-r--r--hw/virtio/virtio-bus.c14
-rw-r--r--hw/virtio/virtio-mmio.c2
-rw-r--r--hw/virtio/virtio-pci.c63
-rw-r--r--hw/virtio/virtio.c33
-rw-r--r--hw/watchdog/wdt_i6300esb.c6
-rw-r--r--hw/xen/xen_pt_config_init.c8
-rw-r--r--hw/xtensa/sim.c2
-rw-r--r--hw/xtensa/xtfpga.c10
136 files changed, 3051 insertions, 4773 deletions
diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c
index 2572747629..30492ecb02 100644
--- a/hw/9pfs/virtio-9p-device.c
+++ b/hw/9pfs/virtio-9p-device.c
@@ -23,7 +23,7 @@
static uint32_t virtio_9p_get_features(VirtIODevice *vdev, uint32_t features)
{
- features |= 1 << VIRTIO_9P_MOUNT_TAG;
+ virtio_add_feature(&features, VIRTIO_9P_MOUNT_TAG);
return features;
}
diff --git a/hw/9pfs/virtio-9p-local.c b/hw/9pfs/virtio-9p-local.c
index a183eee662..d05c91779f 100644
--- a/hw/9pfs/virtio-9p-local.c
+++ b/hw/9pfs/virtio-9p-local.c
@@ -332,7 +332,6 @@ static ssize_t local_readlink(FsContext *fs_ctx, V9fsPath *fs_path,
tsize = read(fd, (void *)buf, bufsz);
} while (tsize == -1 && errno == EINTR);
close(fd);
- return tsize;
} else if ((fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) ||
(fs_ctx->export_flags & V9FS_SM_NONE)) {
buffer = rpath(fs_ctx, path);
diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h
index 2c3603aed0..58dafa9e14 100644
--- a/hw/9pfs/virtio-9p.h
+++ b/hw/9pfs/virtio-9p.h
@@ -7,16 +7,14 @@
#include <utime.h>
#include <sys/resource.h>
#include <glib.h>
+#include "standard-headers/linux/virtio_9p.h"
#include "hw/virtio/virtio.h"
+#include "hw/virtio/virtio-9p.h"
#include "fsdev/file-op-9p.h"
#include "fsdev/virtio-9p-marshal.h"
#include "qemu/thread.h"
#include "block/coroutine.h"
-/* The feature bitmap for virtio 9P */
-/* The mount point is specified in a config variable */
-#define VIRTIO_9P_MOUNT_TAG 0
-
enum {
P9_TLERROR = 6,
P9_RLERROR,
@@ -144,10 +142,6 @@ struct V9fsPDU
* 1) change user needs to set groups and stuff
*/
-/* from Linux's linux/virtio_9p.h */
-
-/* The ID for virtio console */
-#define VIRTIO_ID_9P 9
#define MAX_REQ 128
#define MAX_TAG_LEN 32
@@ -277,14 +271,6 @@ typedef struct V9fsWriteState {
int cnt;
} V9fsWriteState;
-struct virtio_9p_config
-{
- /* number of characters in tag */
- uint16_t tag_len;
- /* Variable size tag name */
- uint8_t tag[0];
-} QEMU_PACKED;
-
typedef struct V9fsMkState {
V9fsPDU *pdu;
size_t offset;
diff --git a/hw/acpi/Makefile.objs b/hw/acpi/Makefile.objs
index ee82073338..b9fefa7635 100644
--- a/hw/acpi/Makefile.objs
+++ b/hw/acpi/Makefile.objs
@@ -2,3 +2,4 @@ common-obj-$(CONFIG_ACPI) += core.o piix4.o ich9.o pcihp.o cpu_hotplug.o
common-obj-$(CONFIG_ACPI) += memory_hotplug.o
common-obj-$(CONFIG_ACPI) += acpi_interface.o
common-obj-$(CONFIG_ACPI) += bios-linker-loader.o
+common-obj-$(CONFIG_ACPI) += aml-build.o
diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
new file mode 100644
index 0000000000..876cada4b2
--- /dev/null
+++ b/hw/acpi/aml-build.c
@@ -0,0 +1,889 @@
+/* Support for generating ACPI tables and passing them to Guests
+ *
+ * Copyright (C) 2015 Red Hat Inc
+ *
+ * Author: Michael S. Tsirkin <mst@redhat.com>
+ * Author: Igor Mammedov <imammedo@redhat.com>
+ *
+ * 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/>.
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <stdbool.h>
+#include <string.h>
+#include "hw/acpi/aml-build.h"
+#include "qemu/bswap.h"
+
+static GArray *build_alloc_array(void)
+{
+ return g_array_new(false, true /* clear */, 1);
+}
+
+static void build_free_array(GArray *array)
+{
+ g_array_free(array, true);
+}
+
+static void build_prepend_byte(GArray *array, uint8_t val)
+{
+ g_array_prepend_val(array, val);
+}
+
+static void build_append_byte(GArray *array, uint8_t val)
+{
+ g_array_append_val(array, val);
+}
+
+static void build_append_array(GArray *array, GArray *val)
+{
+ g_array_append_vals(array, val->data, val->len);
+}
+
+#define ACPI_NAMESEG_LEN 4
+
+static void
+build_append_nameseg(GArray *array, const char *seg)
+{
+ /* It would be nicer to use g_string_vprintf but it's only there in 2.22 */
+ int len;
+
+ len = strlen(seg);
+ assert(len <= ACPI_NAMESEG_LEN);
+
+ g_array_append_vals(array, seg, len);
+ /* Pad up to ACPI_NAMESEG_LEN characters if necessary. */
+ g_array_append_vals(array, "____", ACPI_NAMESEG_LEN - len);
+}
+
+static void
+build_append_namestringv(GArray *array, const char *format, va_list ap)
+{
+ /* It would be nicer to use g_string_vprintf but it's only there in 2.22 */
+ char *s;
+ int len;
+ va_list va_len;
+ char **segs;
+ char **segs_iter;
+ int seg_count = 0;
+
+ va_copy(va_len, ap);
+ len = vsnprintf(NULL, 0, format, va_len);
+ va_end(va_len);
+ len += 1;
+ s = g_new(typeof(*s), len);
+
+ len = vsnprintf(s, len, format, ap);
+
+ segs = g_strsplit(s, ".", 0);
+ g_free(s);
+
+ /* count segments */
+ segs_iter = segs;
+ while (*segs_iter) {
+ ++segs_iter;
+ ++seg_count;
+ }
+ /*
+ * ACPI 5.0 spec: 20.2.2 Name Objects Encoding:
+ * "SegCount can be from 1 to 255"
+ */
+ assert(seg_count > 0 && seg_count <= 255);
+
+ /* handle RootPath || PrefixPath */
+ s = *segs;
+ while (*s == '\\' || *s == '^') {
+ build_append_byte(array, *s);
+ ++s;
+ }
+
+ switch (seg_count) {
+ case 1:
+ if (!*s) {
+ build_append_byte(array, 0x0); /* NullName */
+ } else {
+ build_append_nameseg(array, s);
+ }
+ break;
+
+ case 2:
+ build_append_byte(array, 0x2E); /* DualNamePrefix */
+ build_append_nameseg(array, s);
+ build_append_nameseg(array, segs[1]);
+ break;
+ default:
+ build_append_byte(array, 0x2F); /* MultiNamePrefix */
+ build_append_byte(array, seg_count);
+
+ /* handle the 1st segment manually due to prefix/root path */
+ build_append_nameseg(array, s);
+
+ /* add the rest of segments */
+ segs_iter = segs + 1;
+ while (*segs_iter) {
+ build_append_nameseg(array, *segs_iter);
+ ++segs_iter;
+ }
+ break;
+ }
+ g_strfreev(segs);
+}
+
+static void build_append_namestring(GArray *array, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ build_append_namestringv(array, format, ap);
+ va_end(ap);
+}
+
+/* 5.4 Definition Block Encoding */
+enum {
+ PACKAGE_LENGTH_1BYTE_SHIFT = 6, /* Up to 63 - use extra 2 bits. */
+ PACKAGE_LENGTH_2BYTE_SHIFT = 4,
+ PACKAGE_LENGTH_3BYTE_SHIFT = 12,
+ PACKAGE_LENGTH_4BYTE_SHIFT = 20,
+};
+
+static void
+build_prepend_package_length(GArray *package, unsigned length, bool incl_self)
+{
+ uint8_t byte;
+ unsigned length_bytes;
+
+ if (length + 1 < (1 << PACKAGE_LENGTH_1BYTE_SHIFT)) {
+ length_bytes = 1;
+ } else if (length + 2 < (1 << PACKAGE_LENGTH_3BYTE_SHIFT)) {
+ length_bytes = 2;
+ } else if (length + 3 < (1 << PACKAGE_LENGTH_4BYTE_SHIFT)) {
+ length_bytes = 3;
+ } else {
+ length_bytes = 4;
+ }
+
+ /*
+ * NamedField uses PkgLength encoding but it doesn't include length
+ * of PkgLength itself.
+ */
+ if (incl_self) {
+ /*
+ * PkgLength is the length of the inclusive length of the data
+ * and PkgLength's length itself when used for terms with
+ * explitit length.
+ */
+ length += length_bytes;
+ }
+
+ switch (length_bytes) {
+ case 1:
+ byte = length;
+ build_prepend_byte(package, byte);
+ return;
+ case 4:
+ byte = length >> PACKAGE_LENGTH_4BYTE_SHIFT;
+ build_prepend_byte(package, byte);
+ length &= (1 << PACKAGE_LENGTH_4BYTE_SHIFT) - 1;
+ /* fall through */
+ case 3:
+ byte = length >> PACKAGE_LENGTH_3BYTE_SHIFT;
+ build_prepend_byte(package, byte);
+ length &= (1 << PACKAGE_LENGTH_3BYTE_SHIFT) - 1;
+ /* fall through */
+ case 2:
+ byte = length >> PACKAGE_LENGTH_2BYTE_SHIFT;
+ build_prepend_byte(package, byte);
+ length &= (1 << PACKAGE_LENGTH_2BYTE_SHIFT) - 1;
+ /* fall through */
+ }
+ /*
+ * Most significant two bits of byte zero indicate how many following bytes
+ * are in PkgLength encoding.
+ */
+ byte = ((length_bytes - 1) << PACKAGE_LENGTH_1BYTE_SHIFT) | length;
+ build_prepend_byte(package, byte);
+}
+
+static void
+build_append_pkg_length(GArray *array, unsigned length, bool incl_self)
+{
+ GArray *tmp = build_alloc_array();
+
+ build_prepend_package_length(tmp, length, incl_self);
+ build_append_array(array, tmp);
+ build_free_array(tmp);
+}
+
+static void build_package(GArray *package, uint8_t op)
+{
+ build_prepend_package_length(package, package->len, true);
+ build_prepend_byte(package, op);
+}
+
+static void build_extop_package(GArray *package, uint8_t op)
+{
+ build_package(package, op);
+ build_prepend_byte(package, 0x5B); /* ExtOpPrefix */
+}
+
+static void build_append_int_noprefix(GArray *table, uint64_t value, int size)
+{
+ int i;
+
+ for (i = 0; i < size; ++i) {
+ build_append_byte(table, value & 0xFF);
+ value = value >> 8;
+ }
+}
+
+static void build_append_int(GArray *table, uint64_t value)
+{
+ if (value == 0x00) {
+ build_append_byte(table, 0x00); /* ZeroOp */
+ } else if (value == 0x01) {
+ build_append_byte(table, 0x01); /* OneOp */
+ } else if (value <= 0xFF) {
+ build_append_byte(table, 0x0A); /* BytePrefix */
+ build_append_int_noprefix(table, value, 1);
+ } else if (value <= 0xFFFF) {
+ build_append_byte(table, 0x0B); /* WordPrefix */
+ build_append_int_noprefix(table, value, 2);
+ } else if (value <= 0xFFFFFFFF) {
+ build_append_byte(table, 0x0C); /* DWordPrefix */
+ build_append_int_noprefix(table, value, 4);
+ } else {
+ build_append_byte(table, 0x0E); /* QWordPrefix */
+ build_append_int_noprefix(table, value, 8);
+ }
+}
+
+static GPtrArray *alloc_list;
+
+static Aml *aml_alloc(void)
+{
+ Aml *var = g_new0(typeof(*var), 1);
+
+ g_ptr_array_add(alloc_list, var);
+ var->block_flags = AML_NO_OPCODE;
+ var->buf = build_alloc_array();
+ return var;
+}
+
+static Aml *aml_opcode(uint8_t op)
+{
+ Aml *var = aml_alloc();
+
+ var->op = op;
+ var->block_flags = AML_OPCODE;
+ return var;
+}
+
+static Aml *aml_bundle(uint8_t op, AmlBlockFlags flags)
+{
+ Aml *var = aml_alloc();
+
+ var->op = op;
+ var->block_flags = flags;
+ return var;
+}
+
+static void aml_free(gpointer data, gpointer user_data)
+{
+ Aml *var = data;
+ build_free_array(var->buf);
+}
+
+Aml *init_aml_allocator(void)
+{
+ Aml *var;
+
+ assert(!alloc_list);
+ alloc_list = g_ptr_array_new();
+ var = aml_alloc();
+ return var;
+}
+
+void free_aml_allocator(void)
+{
+ g_ptr_array_foreach(alloc_list, aml_free, NULL);
+ g_ptr_array_free(alloc_list, true);
+ alloc_list = 0;
+}
+
+/* pack data with DefBuffer encoding */
+static void build_buffer(GArray *array, uint8_t op)
+{
+ GArray *data = build_alloc_array();
+
+ build_append_int(data, array->len);
+ g_array_prepend_vals(array, data->data, data->len);
+ build_free_array(data);
+ build_package(array, op);
+}
+
+void aml_append(Aml *parent_ctx, Aml *child)
+{
+ switch (child->block_flags) {
+ case AML_OPCODE:
+ build_append_byte(parent_ctx->buf, child->op);
+ break;
+ case AML_EXT_PACKAGE:
+ build_extop_package(child->buf, child->op);
+ break;
+ case AML_PACKAGE:
+ build_package(child->buf, child->op);
+ break;
+ case AML_RES_TEMPLATE:
+ build_append_byte(child->buf, 0x79); /* EndTag */
+ /*
+ * checksum operations are treated as succeeded if checksum
+ * field is zero. [ACPI Spec 1.0b, 6.4.2.8 End Tag]
+ */
+ build_append_byte(child->buf, 0);
+ /* fall through, to pack resources in buffer */
+ case AML_BUFFER:
+ build_buffer(child->buf, child->op);
+ break;
+ case AML_NO_OPCODE:
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ build_append_array(parent_ctx->buf, child->buf);
+}
+
+/* ACPI 1.0b: 16.2.5.1 Namespace Modifier Objects Encoding: DefScope */
+Aml *aml_scope(const char *name_format, ...)
+{
+ va_list ap;
+ Aml *var = aml_bundle(0x10 /* ScopeOp */, AML_PACKAGE);
+ va_start(ap, name_format);
+ build_append_namestringv(var->buf, name_format, ap);
+ va_end(ap);
+ return var;
+}
+
+/* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefReturn */
+Aml *aml_return(Aml *val)
+{
+ Aml *var = aml_opcode(0xA4 /* ReturnOp */);
+ aml_append(var, val);
+ return var;
+}
+
+/*
+ * ACPI 1.0b: 16.2.3 Data Objects Encoding:
+ * encodes: ByteConst, WordConst, DWordConst, QWordConst, ZeroOp, OneOp
+ */
+Aml *aml_int(const uint64_t val)
+{
+ Aml *var = aml_alloc();
+ build_append_int(var->buf, val);
+ return var;
+}
+
+/*
+ * helper to construct NameString, which returns Aml object
+ * for using with aml_append or other aml_* terms
+ */
+Aml *aml_name(const char *name_format, ...)
+{
+ va_list ap;
+ Aml *var = aml_alloc();
+ va_start(ap, name_format);
+ build_append_namestringv(var->buf, name_format, ap);
+ va_end(ap);
+ return var;
+}
+
+/* ACPI 1.0b: 16.2.5.1 Namespace Modifier Objects Encoding: DefName */
+Aml *aml_name_decl(const char *name, Aml *val)
+{
+ Aml *var = aml_opcode(0x08 /* NameOp */);
+ build_append_namestring(var->buf, "%s", name);
+ aml_append(var, val);
+ return var;
+}
+
+/* ACPI 1.0b: 16.2.6.1 Arg Objects Encoding */
+Aml *aml_arg(int pos)
+{
+ Aml *var;
+ uint8_t op = 0x68 /* ARG0 op */ + pos;
+
+ assert(pos <= 6);
+ var = aml_opcode(op);
+ return var;
+}
+
+/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefStore */
+Aml *aml_store(Aml *val, Aml *target)
+{
+ Aml *var = aml_opcode(0x70 /* StoreOp */);
+ aml_append(var, val);
+ aml_append(var, target);
+ return var;
+}
+
+/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefAnd */
+Aml *aml_and(Aml *arg1, Aml *arg2)
+{
+ Aml *var = aml_opcode(0x7B /* AndOp */);
+ aml_append(var, arg1);
+ aml_append(var, arg2);
+ build_append_int(var->buf, 0x00 /* NullNameOp */);
+ return var;
+}
+
+/* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefNotify */
+Aml *aml_notify(Aml *arg1, Aml *arg2)
+{
+ Aml *var = aml_opcode(0x86 /* NotifyOp */);
+ aml_append(var, arg1);
+ aml_append(var, arg2);
+ return var;
+}
+
+/* helper to call method with 1 argument */
+Aml *aml_call1(const char *method, Aml *arg1)
+{
+ Aml *var = aml_alloc();
+ build_append_namestring(var->buf, "%s", method);
+ aml_append(var, arg1);
+ return var;
+}
+
+/* helper to call method with 2 arguments */
+Aml *aml_call2(const char *method, Aml *arg1, Aml *arg2)
+{
+ Aml *var = aml_alloc();
+ build_append_namestring(var->buf, "%s", method);
+ aml_append(var, arg1);
+ aml_append(var, arg2);
+ return var;
+}
+
+/* helper to call method with 3 arguments */
+Aml *aml_call3(const char *method, Aml *arg1, Aml *arg2, Aml *arg3)
+{
+ Aml *var = aml_alloc();
+ build_append_namestring(var->buf, "%s", method);
+ aml_append(var, arg1);
+ aml_append(var, arg2);
+ aml_append(var, arg3);
+ return var;
+}
+
+/* helper to call method with 4 arguments */
+Aml *aml_call4(const char *method, Aml *arg1, Aml *arg2, Aml *arg3, Aml *arg4)
+{
+ Aml *var = aml_alloc();
+ build_append_namestring(var->buf, "%s", method);
+ aml_append(var, arg1);
+ aml_append(var, arg2);
+ aml_append(var, arg3);
+ aml_append(var, arg4);
+ return var;
+}
+
+/* ACPI 1.0b: 6.4.2.5 I/O Port Descriptor */
+Aml *aml_io(AmlIODecode dec, uint16_t min_base, uint16_t max_base,
+ uint8_t aln, uint8_t len)
+{
+ Aml *var = aml_alloc();
+ build_append_byte(var->buf, 0x47); /* IO port descriptor */
+ build_append_byte(var->buf, dec);
+ build_append_byte(var->buf, min_base & 0xff);
+ build_append_byte(var->buf, (min_base >> 8) & 0xff);
+ build_append_byte(var->buf, max_base & 0xff);
+ build_append_byte(var->buf, (max_base >> 8) & 0xff);
+ build_append_byte(var->buf, aln);
+ build_append_byte(var->buf, len);
+ return var;
+}
+
+/*
+ * ACPI 1.0b: 6.4.2.1.1 ASL Macro for IRQ Descriptor
+ *
+ * More verbose description at:
+ * ACPI 5.0: 19.5.64 IRQNoFlags (Interrupt Resource Descriptor Macro)
+ * 6.4.2.1 IRQ Descriptor
+ */
+Aml *aml_irq_no_flags(uint8_t irq)
+{
+ uint16_t irq_mask;
+ Aml *var = aml_alloc();
+
+ assert(irq < 16);
+ build_append_byte(var->buf, 0x22); /* IRQ descriptor 2 byte form */
+
+ irq_mask = 1U << irq;
+ build_append_byte(var->buf, irq_mask & 0xFF); /* IRQ mask bits[7:0] */
+ build_append_byte(var->buf, irq_mask >> 8); /* IRQ mask bits[15:8] */
+ return var;
+}
+
+/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLEqual */
+Aml *aml_equal(Aml *arg1, Aml *arg2)
+{
+ Aml *var = aml_opcode(0x93 /* LequalOp */);
+ aml_append(var, arg1);
+ aml_append(var, arg2);
+ build_append_int(var->buf, 0x00); /* NullNameOp */
+ return var;
+}
+
+/* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefIfElse */
+Aml *aml_if(Aml *predicate)
+{
+ Aml *var = aml_bundle(0xA0 /* IfOp */, AML_PACKAGE);
+ aml_append(var, predicate);
+ return var;
+}
+
+/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefMethod */
+Aml *aml_method(const char *name, int arg_count)
+{
+ Aml *var = aml_bundle(0x14 /* MethodOp */, AML_PACKAGE);
+ build_append_namestring(var->buf, "%s", name);
+ build_append_byte(var->buf, arg_count); /* MethodFlags: ArgCount */
+ return var;
+}
+
+/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefDevice */
+Aml *aml_device(const char *name_format, ...)
+{
+ va_list ap;
+ Aml *var = aml_bundle(0x82 /* DeviceOp */, AML_EXT_PACKAGE);
+ va_start(ap, name_format);
+ build_append_namestringv(var->buf, name_format, ap);
+ va_end(ap);
+ return var;
+}
+
+/* ACPI 1.0b: 6.4.1 ASL Macros for Resource Descriptors */
+Aml *aml_resource_template(void)
+{
+ /* ResourceTemplate is a buffer of Resources with EndTag at the end */
+ Aml *var = aml_bundle(0x11 /* BufferOp */, AML_RES_TEMPLATE);
+ return var;
+}
+
+/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefBuffer */
+Aml *aml_buffer(void)
+{
+ Aml *var = aml_bundle(0x11 /* BufferOp */, AML_BUFFER);
+ return var;
+}
+
+/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefPackage */
+Aml *aml_package(uint8_t num_elements)
+{
+ Aml *var = aml_bundle(0x12 /* PackageOp */, AML_PACKAGE);
+ build_append_byte(var->buf, num_elements);
+ return var;
+}
+
+/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefOpRegion */
+Aml *aml_operation_region(const char *name, AmlRegionSpace rs,
+ uint32_t offset, uint32_t len)
+{
+ Aml *var = aml_alloc();
+ build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
+ build_append_byte(var->buf, 0x80); /* OpRegionOp */
+ build_append_namestring(var->buf, "%s", name);
+ build_append_byte(var->buf, rs);
+ build_append_int(var->buf, offset);
+ build_append_int(var->buf, len);
+ return var;
+}
+
+/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: NamedField */
+Aml *aml_named_field(const char *name, unsigned length)
+{
+ Aml *var = aml_alloc();
+ build_append_nameseg(var->buf, name);
+ build_append_pkg_length(var->buf, length, false);
+ return var;
+}
+
+/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: ReservedField */
+Aml *aml_reserved_field(unsigned length)
+{
+ Aml *var = aml_alloc();
+ /* ReservedField := 0x00 PkgLength */
+ build_append_byte(var->buf, 0x00);
+ build_append_pkg_length(var->buf, length, false);
+ return var;
+}
+
+/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefField */
+Aml *aml_field(const char *name, AmlFieldFlags flags)
+{
+ Aml *var = aml_bundle(0x81 /* FieldOp */, AML_EXT_PACKAGE);
+ build_append_namestring(var->buf, "%s", name);
+ build_append_byte(var->buf, flags);
+ return var;
+}
+
+/* ACPI 1.0b: 16.2.3 Data Objects Encoding: String */
+Aml *aml_string(const char *name_format, ...)
+{
+ Aml *var = aml_opcode(0x0D /* StringPrefix */);
+ va_list ap, va_len;
+ char *s;
+ int len;
+
+ va_start(ap, name_format);
+ va_copy(va_len, ap);
+ len = vsnprintf(NULL, 0, name_format, va_len);
+ va_end(va_len);
+ len += 1;
+ s = g_new0(typeof(*s), len);
+
+ len = vsnprintf(s, len, name_format, ap);
+ va_end(ap);
+
+ g_array_append_vals(var->buf, s, len);
+ build_append_byte(var->buf, 0x0); /* NullChar */
+ g_free(s);
+
+ return var;
+}
+
+/* ACPI 1.0b: 16.2.6.2 Local Objects Encoding */
+Aml *aml_local(int num)
+{
+ Aml *var;
+ uint8_t op = 0x60 /* Local0Op */ + num;
+
+ assert(num <= 7);
+ var = aml_opcode(op);
+ return var;
+}
+
+/* ACPI 2.0a: 17.2.2 Data Objects Encoding: DefVarPackage */
+Aml *aml_varpackage(uint32_t num_elements)
+{
+ Aml *var = aml_bundle(0x13 /* VarPackageOp */, AML_PACKAGE);
+ build_append_int(var->buf, num_elements);
+ return var;
+}
+
+/* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefProcessor */
+Aml *aml_processor(uint8_t proc_id, uint32_t pblk_addr, uint8_t pblk_len,
+ const char *name_format, ...)
+{
+ va_list ap;
+ Aml *var = aml_bundle(0x83 /* ProcessorOp */, AML_EXT_PACKAGE);
+ va_start(ap, name_format);
+ build_append_namestringv(var->buf, name_format, ap);
+ va_end(ap);
+ build_append_byte(var->buf, proc_id); /* ProcID */
+ build_append_int_noprefix(var->buf, pblk_addr, sizeof(pblk_addr));
+ build_append_byte(var->buf, pblk_len); /* PblkLen */
+ return var;
+}
+
+static uint8_t Hex2Digit(char c)
+{
+ if (c >= 'A') {
+ return c - 'A' + 10;
+ }
+
+ return c - '0';
+}
+
+/* ACPI 1.0b: 15.2.3.6.4.1 EISAID Macro - Convert EISA ID String To Integer */
+Aml *aml_eisaid(const char *str)
+{
+ Aml *var = aml_alloc();
+ uint32_t id;
+
+ g_assert(strlen(str) == 7);
+ id = (str[0] - 0x40) << 26 |
+ (str[1] - 0x40) << 21 |
+ (str[2] - 0x40) << 16 |
+ Hex2Digit(str[3]) << 12 |
+ Hex2Digit(str[4]) << 8 |
+ Hex2Digit(str[5]) << 4 |
+ Hex2Digit(str[6]);
+
+ build_append_byte(var->buf, 0x0C); /* DWordPrefix */
+ build_append_int_noprefix(var->buf, bswap32(id), sizeof(id));
+ return var;
+}
+
+/* ACPI 1.0b: 6.4.3.5.5 Word Address Space Descriptor: bytes 3-5 */
+static Aml *aml_as_desc_header(AmlResourceType type, AmlMinFixed min_fixed,
+ AmlMaxFixed max_fixed, AmlDecode dec,
+ uint8_t type_flags)
+{
+ uint8_t flags = max_fixed | min_fixed | dec;
+ Aml *var = aml_alloc();
+
+ build_append_byte(var->buf, type);
+ build_append_byte(var->buf, flags);
+ build_append_byte(var->buf, type_flags); /* Type Specific Flags */
+ return var;
+}
+
+/* ACPI 1.0b: 6.4.3.5.5 Word Address Space Descriptor */
+static Aml *aml_word_as_desc(AmlResourceType type, AmlMinFixed min_fixed,
+ AmlMaxFixed max_fixed, AmlDecode dec,
+ uint16_t addr_gran, uint16_t addr_min,
+ uint16_t addr_max, uint16_t addr_trans,
+ uint16_t len, uint8_t type_flags)
+{
+ Aml *var = aml_alloc();
+
+ build_append_byte(var->buf, 0x88); /* Word Address Space Descriptor */
+ /* minimum length since we do not encode optional fields */
+ build_append_byte(var->buf, 0x0D);
+ build_append_byte(var->buf, 0x0);
+
+ aml_append(var,
+ aml_as_desc_header(type, min_fixed, max_fixed, dec, type_flags));
+ build_append_int_noprefix(var->buf, addr_gran, sizeof(addr_gran));
+ build_append_int_noprefix(var->buf, addr_min, sizeof(addr_min));
+ build_append_int_noprefix(var->buf, addr_max, sizeof(addr_max));
+ build_append_int_noprefix(var->buf, addr_trans, sizeof(addr_trans));
+ build_append_int_noprefix(var->buf, len, sizeof(len));
+ return var;
+}
+
+/* ACPI 1.0b: 6.4.3.5.3 DWord Address Space Descriptor */
+static Aml *aml_dword_as_desc(AmlResourceType type, AmlMinFixed min_fixed,
+ AmlMaxFixed max_fixed, AmlDecode dec,
+ uint32_t addr_gran, uint32_t addr_min,
+ uint32_t addr_max, uint32_t addr_trans,
+ uint32_t len, uint8_t type_flags)
+{
+ Aml *var = aml_alloc();
+
+ build_append_byte(var->buf, 0x87); /* DWord Address Space Descriptor */
+ /* minimum length since we do not encode optional fields */
+ build_append_byte(var->buf, 23);
+ build_append_byte(var->buf, 0x0);
+
+
+ aml_append(var,
+ aml_as_desc_header(type, min_fixed, max_fixed, dec, type_flags));
+ build_append_int_noprefix(var->buf, addr_gran, sizeof(addr_gran));
+ build_append_int_noprefix(var->buf, addr_min, sizeof(addr_min));
+ build_append_int_noprefix(var->buf, addr_max, sizeof(addr_max));
+ build_append_int_noprefix(var->buf, addr_trans, sizeof(addr_trans));
+ build_append_int_noprefix(var->buf, len, sizeof(len));
+ return var;
+}
+
+/* ACPI 1.0b: 6.4.3.5.1 QWord Address Space Descriptor */
+static Aml *aml_qword_as_desc(AmlResourceType type, AmlMinFixed min_fixed,
+ AmlMaxFixed max_fixed, AmlDecode dec,
+ uint64_t addr_gran, uint64_t addr_min,
+ uint64_t addr_max, uint64_t addr_trans,
+ uint64_t len, uint8_t type_flags)
+{
+ Aml *var = aml_alloc();
+
+ build_append_byte(var->buf, 0x8A); /* QWord Address Space Descriptor */
+ /* minimum length since we do not encode optional fields */
+ build_append_byte(var->buf, 0x2B);
+ build_append_byte(var->buf, 0x0);
+
+ aml_append(var,
+ aml_as_desc_header(type, min_fixed, max_fixed, dec, type_flags));
+ build_append_int_noprefix(var->buf, addr_gran, sizeof(addr_gran));
+ build_append_int_noprefix(var->buf, addr_min, sizeof(addr_min));
+ build_append_int_noprefix(var->buf, addr_max, sizeof(addr_max));
+ build_append_int_noprefix(var->buf, addr_trans, sizeof(addr_trans));
+ build_append_int_noprefix(var->buf, len, sizeof(len));
+ return var;
+}
+
+/*
+ * ACPI 1.0b: 6.4.3.5.6 ASL Macros for WORD Address Descriptor
+ *
+ * More verbose description at:
+ * ACPI 5.0: 19.5.141 WordBusNumber (Word Bus Number Resource Descriptor Macro)
+ */
+Aml *aml_word_bus_number(AmlMinFixed min_fixed, AmlMaxFixed max_fixed,
+ AmlDecode dec, uint16_t addr_gran,
+ uint16_t addr_min, uint16_t addr_max,
+ uint16_t addr_trans, uint16_t len)
+
+{
+ return aml_word_as_desc(aml_bus_number_range, min_fixed, max_fixed, dec,
+ addr_gran, addr_min, addr_max, addr_trans, len, 0);
+}
+
+/*
+ * ACPI 1.0b: 6.4.3.5.6 ASL Macros for WORD Address Descriptor
+ *
+ * More verbose description at:
+ * ACPI 5.0: 19.5.142 WordIO (Word IO Resource Descriptor Macro)
+ */
+Aml *aml_word_io(AmlMinFixed min_fixed, AmlMaxFixed max_fixed,
+ AmlDecode dec, AmlISARanges isa_ranges,
+ uint16_t addr_gran, uint16_t addr_min,
+ uint16_t addr_max, uint16_t addr_trans,
+ uint16_t len)
+
+{
+ return aml_word_as_desc(aml_io_range, min_fixed, max_fixed, dec,
+ addr_gran, addr_min, addr_max, addr_trans, len,
+ isa_ranges);
+}
+
+/*
+ * ACPI 1.0b: 6.4.3.5.4 ASL Macros for DWORD Address Space Descriptor
+ *
+ * More verbose description at:
+ * ACPI 5.0: 19.5.34 DWordMemory (DWord Memory Resource Descriptor Macro)
+ */
+Aml *aml_dword_memory(AmlDecode dec, AmlMinFixed min_fixed,
+ AmlMaxFixed max_fixed, AmlCacheble cacheable,
+ AmlReadAndWrite read_and_write,
+ uint32_t addr_gran, uint32_t addr_min,
+ uint32_t addr_max, uint32_t addr_trans,
+ uint32_t len)
+{
+ uint8_t flags = read_and_write | (cacheable << 1);
+
+ return aml_dword_as_desc(aml_memory_range, min_fixed, max_fixed,
+ dec, addr_gran, addr_min, addr_max,
+ addr_trans, len, flags);
+}
+
+/*
+ * ACPI 1.0b: 6.4.3.5.2 ASL Macros for QWORD Address Space Descriptor
+ *
+ * More verbose description at:
+ * ACPI 5.0: 19.5.102 QWordMemory (QWord Memory Resource Descriptor Macro)
+ */
+Aml *aml_qword_memory(AmlDecode dec, AmlMinFixed min_fixed,
+ AmlMaxFixed max_fixed, AmlCacheble cacheable,
+ AmlReadAndWrite read_and_write,
+ uint64_t addr_gran, uint64_t addr_min,
+ uint64_t addr_max, uint64_t addr_trans,
+ uint64_t len)
+{
+ uint8_t flags = read_and_write | (cacheable << 1);
+
+ return aml_qword_as_desc(aml_memory_range, min_fixed, max_fixed,
+ dec, addr_gran, addr_min, addr_max,
+ addr_trans, len, flags);
+}
diff --git a/hw/acpi/bios-linker-loader.c b/hw/acpi/bios-linker-loader.c
index 5cc4d90c16..d9382f826a 100644
--- a/hw/acpi/bios-linker-loader.c
+++ b/hw/acpi/bios-linker-loader.c
@@ -141,6 +141,7 @@ void bios_linker_loader_add_pointer(GArray *linker,
uint8_t pointer_size)
{
BiosLinkerLoaderEntry entry;
+ size_t offset = (gchar *)pointer - table->data;
memset(&entry, 0, sizeof entry);
strncpy(entry.pointer.dest_file, dest_file,
@@ -148,7 +149,8 @@ void bios_linker_loader_add_pointer(GArray *linker,
strncpy(entry.pointer.src_file, src_file,
sizeof entry.pointer.src_file - 1);
entry.command = cpu_to_le32(BIOS_LINKER_LOADER_COMMAND_ADD_POINTER);
- entry.pointer.offset = cpu_to_le32((gchar *)pointer - table->data);
+ assert(table->len >= offset + pointer_size);
+ entry.pointer.offset = cpu_to_le32(offset);
entry.pointer.size = pointer_size;
assert(pointer_size == 1 || pointer_size == 2 ||
pointer_size == 4 || pointer_size == 8);
diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 884dab3d45..5352e197cb 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -397,6 +397,20 @@ void ich9_pm_device_plug_cb(ICH9LPCPMRegs *pm, DeviceState *dev, Error **errp)
}
}
+void ich9_pm_device_unplug_request_cb(ICH9LPCPMRegs *pm, DeviceState *dev,
+ Error **errp)
+{
+ error_setg(errp, "acpi: device unplug request for not supported device"
+ " type: %s", object_get_typename(OBJECT(dev)));
+}
+
+void ich9_pm_device_unplug_cb(ICH9LPCPMRegs *pm, DeviceState *dev,
+ Error **errp)
+{
+ error_setg(errp, "acpi: device unplug for not supported device"
+ " type: %s", object_get_typename(OBJECT(dev)));
+}
+
void ich9_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list)
{
ICH9LPCState *s = ICH9_LPC_DEVICE(adev);
diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c
index ed3924126f..c6580dabb7 100644
--- a/hw/acpi/memory_hotplug.c
+++ b/hw/acpi/memory_hotplug.c
@@ -168,7 +168,8 @@ void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st,
{
MemStatus *mdev;
Error *local_err = NULL;
- int slot = object_property_get_int(OBJECT(dev), "slot", &local_err);
+ int slot = object_property_get_int(OBJECT(dev), PC_DIMM_SLOT_PROP,
+ &local_err);
if (local_err) {
error_propagate(errp, local_err);
diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
index 34dedf1e8b..612fec03ee 100644
--- a/hw/acpi/pcihp.c
+++ b/hw/acpi/pcihp.c
@@ -297,10 +297,11 @@ static const MemoryRegionOps acpi_pcihp_io_ops = {
},
};
-void acpi_pcihp_init(AcpiPciHpState *s, PCIBus *root_bus,
+void acpi_pcihp_init(Object *owner, AcpiPciHpState *s, PCIBus *root_bus,
MemoryRegion *address_space_io, bool bridges_enabled)
{
- uint16_t io_size = ACPI_PCIHP_SIZE;
+ s->io_len = ACPI_PCIHP_SIZE;
+ s->io_base = ACPI_PCIHP_ADDR;
s->root= root_bus;
s->legacy_piix = !bridges_enabled;
@@ -308,16 +309,21 @@ void acpi_pcihp_init(AcpiPciHpState *s, PCIBus *root_bus,
if (s->legacy_piix) {
unsigned *bus_bsel = g_malloc(sizeof *bus_bsel);
- io_size = ACPI_PCIHP_LEGACY_SIZE;
+ s->io_len = ACPI_PCIHP_LEGACY_SIZE;
*bus_bsel = ACPI_PCIHP_BSEL_DEFAULT;
object_property_add_uint32_ptr(OBJECT(root_bus), ACPI_PCIHP_PROP_BSEL,
bus_bsel, NULL);
}
- memory_region_init_io(&s->io, NULL, &acpi_pcihp_io_ops, s,
- "acpi-pci-hotplug", io_size);
- memory_region_add_subregion(address_space_io, ACPI_PCIHP_ADDR, &s->io);
+ memory_region_init_io(&s->io, owner, &acpi_pcihp_io_ops, s,
+ "acpi-pci-hotplug", s->io_len);
+ memory_region_add_subregion(address_space_io, s->io_base, &s->io);
+
+ object_property_add_uint16_ptr(owner, ACPI_PCIHP_IO_BASE_PROP, &s->io_base,
+ &error_abort);
+ object_property_add_uint16_ptr(owner, ACPI_PCIHP_IO_LEN_PROP, &s->io_len,
+ &error_abort);
}
const VMStateDescription vmstate_acpi_pcihp_pci_status = {
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 184e7e49b9..d1f11793a0 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -370,6 +370,13 @@ static void piix4_device_unplug_request_cb(HotplugHandler *hotplug_dev,
}
}
+static void piix4_device_unplug_cb(HotplugHandler *hotplug_dev,
+ DeviceState *dev, Error **errp)
+{
+ error_setg(errp, "acpi: device unplug for not supported device"
+ " type: %s", object_get_typename(OBJECT(dev)));
+}
+
static void piix4_update_bus_hotplug(PCIBus *pci_bus, void *opaque)
{
PIIX4PMState *s = opaque;
@@ -420,7 +427,7 @@ static void piix4_pm_add_propeties(PIIX4PMState *s)
&s->io_base, NULL);
}
-static int piix4_pm_initfn(PCIDevice *dev)
+static void piix4_pm_realize(PCIDevice *dev, Error **errp)
{
PIIX4PMState *s = PIIX4_PM(dev);
uint8_t *pci_conf;
@@ -470,7 +477,6 @@ static int piix4_pm_initfn(PCIDevice *dev)
piix4_acpi_system_hot_add_init(pci_address_space_io(dev), dev->bus, s);
piix4_pm_add_propeties(s);
- return 0;
}
Object *piix4_pm_find(void)
@@ -556,7 +562,7 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
"acpi-gpe0", GPE_LEN);
memory_region_add_subregion(parent, GPE_BASE, &s->io_gpe);
- acpi_pcihp_init(&s->acpi_pci_hotplug, bus, parent,
+ acpi_pcihp_init(OBJECT(s), &s->acpi_pci_hotplug, bus, parent,
s->use_acpi_pci_hotplug);
acpi_cpu_hotplug_init(parent, OBJECT(s), &s->gpe_cpu,
@@ -593,7 +599,7 @@ static void piix4_pm_class_init(ObjectClass *klass, void *data)
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_CLASS(klass);
- k->init = piix4_pm_initfn;
+ k->realize = piix4_pm_realize;
k->config_write = pm_write_config;
k->vendor_id = PCI_VENDOR_ID_INTEL;
k->device_id = PCI_DEVICE_ID_INTEL_82371AB_3;
@@ -610,6 +616,7 @@ static void piix4_pm_class_init(ObjectClass *klass, void *data)
dc->hotpluggable = false;
hc->plug = piix4_device_plug_cb;
hc->unplug_request = piix4_device_unplug_request_cb;
+ hc->unplug = piix4_device_unplug_cb;
adevc->ospm_status = piix4_ospm_status;
}
diff --git a/hw/arm/digic_boards.c b/hw/arm/digic_boards.c
index 2a4b8720a6..7114c36e38 100644
--- a/hw/arm/digic_boards.c
+++ b/hw/arm/digic_boards.c
@@ -65,7 +65,7 @@ static void digic4_board_init(DigicBoard *board)
s->digic = DIGIC(object_new(TYPE_DIGIC));
object_property_set_bool(OBJECT(s->digic), true, "realized", &err);
if (err != NULL) {
- error_report("Couldn't realize DIGIC SoC: %s\n",
+ error_report("Couldn't realize DIGIC SoC: %s",
error_get_pretty(err));
exit(1);
}
@@ -104,13 +104,13 @@ static void digic_load_rom(DigicBoardState *s, hwaddr addr,
char *fn = qemu_find_file(QEMU_FILE_TYPE_BIOS, filename);
if (!fn) {
- error_report("Couldn't find rom image '%s'.\n", filename);
+ error_report("Couldn't find rom image '%s'.", filename);
exit(1);
}
rom_size = load_image_targphys(fn, addr, max_size);
if (rom_size < 0 || rom_size > max_size) {
- error_report("Couldn't load rom image '%s'.\n", filename);
+ error_report("Couldn't load rom image '%s'.", filename);
exit(1);
}
}
diff --git a/hw/audio/ac97.c b/hw/audio/ac97.c
index 111ec0e848..b17383555e 100644
--- a/hw/audio/ac97.c
+++ b/hw/audio/ac97.c
@@ -1337,7 +1337,7 @@ static void ac97_on_reset (DeviceState *dev)
mixer_reset (s);
}
-static int ac97_initfn (PCIDevice *dev)
+static void ac97_realize(PCIDevice *dev, Error **errp)
{
AC97LinkState *s = DO_UPCAST (AC97LinkState, dev, dev);
uint8_t *c = s->dev.config;
@@ -1384,7 +1384,6 @@ static int ac97_initfn (PCIDevice *dev)
pci_register_bar (&s->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->io_nabm);
AUD_register_card ("ac97", &s->card);
ac97_on_reset (&s->dev.qdev);
- return 0;
}
static int ac97_init (PCIBus *bus)
@@ -1403,7 +1402,7 @@ static void ac97_class_init (ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS (klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS (klass);
- k->init = ac97_initfn;
+ k->realize = ac97_realize;
k->vendor_id = PCI_VENDOR_ID_INTEL;
k->device_id = PCI_DEVICE_ID_INTEL_82801AA_5;
k->revision = 0x01;
diff --git a/hw/audio/es1370.c b/hw/audio/es1370.c
index e67d1ea165..8e7bcf503e 100644
--- a/hw/audio/es1370.c
+++ b/hw/audio/es1370.c
@@ -1016,7 +1016,7 @@ static void es1370_on_reset (void *opaque)
es1370_reset (s);
}
-static int es1370_initfn (PCIDevice *dev)
+static void es1370_realize(PCIDevice *dev, Error **errp)
{
ES1370State *s = DO_UPCAST (ES1370State, dev, dev);
uint8_t *c = s->dev.config;
@@ -1039,7 +1039,6 @@ static int es1370_initfn (PCIDevice *dev)
AUD_register_card ("es1370", &s->card);
es1370_reset (s);
- return 0;
}
static int es1370_init (PCIBus *bus)
@@ -1053,7 +1052,7 @@ static void es1370_class_init (ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS (klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS (klass);
- k->init = es1370_initfn;
+ k->realize = es1370_realize;
k->vendor_id = PCI_VENDOR_ID_ENSONIQ;
k->device_id = PCI_DEVICE_ID_ENSONIQ_ES1370;
k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO;
diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c
index 2885231a6d..433463e9c5 100644
--- a/hw/audio/intel-hda.c
+++ b/hw/audio/intel-hda.c
@@ -1126,7 +1126,7 @@ static void intel_hda_reset(DeviceState *dev)
intel_hda_update_irq(d);
}
-static int intel_hda_init(PCIDevice *pci)
+static void intel_hda_realize(PCIDevice *pci, Error **errp)
{
IntelHDAState *d = INTEL_HDA(pci);
uint8_t *conf = d->pci.config;
@@ -1147,8 +1147,6 @@ static int intel_hda_init(PCIDevice *pci)
hda_codec_bus_init(DEVICE(pci), &d->codecs, sizeof(d->codecs),
intel_hda_response, intel_hda_xfer);
-
- return 0;
}
static void intel_hda_exit(PCIDevice *pci)
@@ -1245,7 +1243,7 @@ static void intel_hda_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- k->init = intel_hda_init;
+ k->realize = intel_hda_realize;
k->exit = intel_hda_exit;
k->vendor_id = PCI_VENDOR_ID_INTEL;
k->class_id = PCI_CLASS_MULTIMEDIA_HD_AUDIO;
diff --git a/hw/block/nand.c b/hw/block/nand.c
index 1882a0cbeb..61d2cec032 100644
--- a/hw/block/nand.c
+++ b/hw/block/nand.c
@@ -393,7 +393,7 @@ static void nand_realize(DeviceState *dev, Error **errp)
nand_init_2048(s);
break;
default:
- error_setg(errp, "Unsupported NAND block size %#x\n",
+ error_setg(errp, "Unsupported NAND block size %#x",
1 << s->page_shift);
return;
}
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index 0468297688..000c38d2a1 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -667,11 +667,11 @@ static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config)
memset(&blkcfg, 0, sizeof(blkcfg));
virtio_stq_p(vdev, &blkcfg.capacity, capacity);
virtio_stl_p(vdev, &blkcfg.seg_max, 128 - 2);
- virtio_stw_p(vdev, &blkcfg.cylinders, conf->cyls);
+ virtio_stw_p(vdev, &blkcfg.geometry.cylinders, conf->cyls);
virtio_stl_p(vdev, &blkcfg.blk_size, blk_size);
virtio_stw_p(vdev, &blkcfg.min_io_size, conf->min_io_size / blk_size);
virtio_stw_p(vdev, &blkcfg.opt_io_size, conf->opt_io_size / blk_size);
- blkcfg.heads = conf->heads;
+ blkcfg.geometry.heads = conf->heads;
/*
* We must ensure that the block device capacity is a multiple of
* the logical block size. If that is not the case, let's use
@@ -684,9 +684,9 @@ static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config)
* per track (cylinder).
*/
if (blk_getlength(s->blk) / conf->heads / conf->secs % blk_size) {
- blkcfg.sectors = conf->secs & ~s->sector_mask;
+ blkcfg.geometry.sectors = conf->secs & ~s->sector_mask;
} else {
- blkcfg.sectors = conf->secs;
+ blkcfg.geometry.sectors = conf->secs;
}
blkcfg.size_max = 0;
blkcfg.physical_block_exp = get_physical_block_exp(conf);
@@ -711,20 +711,20 @@ static uint32_t virtio_blk_get_features(VirtIODevice *vdev, uint32_t features)
{
VirtIOBlock *s = VIRTIO_BLK(vdev);
- features |= (1 << VIRTIO_BLK_F_SEG_MAX);
- features |= (1 << VIRTIO_BLK_F_GEOMETRY);
- features |= (1 << VIRTIO_BLK_F_TOPOLOGY);
- features |= (1 << VIRTIO_BLK_F_BLK_SIZE);
- features |= (1 << VIRTIO_BLK_F_SCSI);
+ virtio_add_feature(&features, VIRTIO_BLK_F_SEG_MAX);
+ virtio_add_feature(&features, VIRTIO_BLK_F_GEOMETRY);
+ virtio_add_feature(&features, VIRTIO_BLK_F_TOPOLOGY);
+ virtio_add_feature(&features, VIRTIO_BLK_F_BLK_SIZE);
+ virtio_add_feature(&features, VIRTIO_BLK_F_SCSI);
if (s->conf.config_wce) {
- features |= (1 << VIRTIO_BLK_F_CONFIG_WCE);
+ virtio_add_feature(&features, VIRTIO_BLK_F_CONFIG_WCE);
}
if (blk_enable_write_cache(s->blk)) {
- features |= (1 << VIRTIO_BLK_F_WCE);
+ virtio_add_feature(&features, VIRTIO_BLK_F_WCE);
}
if (blk_is_read_only(s->blk)) {
- features |= 1 << VIRTIO_BLK_F_RO;
+ virtio_add_feature(&features, VIRTIO_BLK_F_RO);
}
return features;
@@ -733,7 +733,6 @@ static uint32_t virtio_blk_get_features(VirtIODevice *vdev, uint32_t features)
static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t status)
{
VirtIOBlock *s = VIRTIO_BLK(vdev);
- uint32_t features;
if (s->dataplane && !(status & (VIRTIO_CONFIG_S_DRIVER |
VIRTIO_CONFIG_S_DRIVER_OK))) {
@@ -744,8 +743,6 @@ static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t status)
return;
}
- features = vdev->guest_features;
-
/* A guest that supports VIRTIO_BLK_F_CONFIG_WCE must be able to send
* cache flushes. Thus, the "auto writethrough" behavior is never
* necessary for guests that support the VIRTIO_BLK_F_CONFIG_WCE feature.
@@ -761,10 +758,10 @@ static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t status)
*
* s->blk would erroneously be placed in writethrough mode.
*/
- if (!(features & (1 << VIRTIO_BLK_F_CONFIG_WCE))) {
+ if (!virtio_has_feature(vdev, VIRTIO_BLK_F_CONFIG_WCE)) {
aio_context_acquire(blk_get_aio_context(s->blk));
blk_set_enable_write_cache(s->blk,
- !!(features & (1 << VIRTIO_BLK_F_WCE)));
+ virtio_has_feature(vdev, VIRTIO_BLK_F_WCE));
aio_context_release(blk_get_aio_context(s->blk));
}
}
diff --git a/hw/char/serial-pci.c b/hw/char/serial-pci.c
index f05c9b4d86..467c3b4f9a 100644
--- a/hw/char/serial-pci.c
+++ b/hw/char/serial-pci.c
@@ -48,7 +48,7 @@ typedef struct PCIMultiSerialState {
uint8_t prog_if;
} PCIMultiSerialState;
-static int serial_pci_init(PCIDevice *dev)
+static void serial_pci_realize(PCIDevice *dev, Error **errp)
{
PCISerialState *pci = DO_UPCAST(PCISerialState, dev, dev);
SerialState *s = &pci->state;
@@ -57,9 +57,8 @@ static int serial_pci_init(PCIDevice *dev)
s->baudbase = 115200;
serial_realize_core(s, &err);
if (err != NULL) {
- qerror_report_err(err);
- error_free(err);
- return -1;
+ error_propagate(errp, err);
+ return;
}
pci->dev.config[PCI_CLASS_PROG] = pci->prog_if;
@@ -68,7 +67,6 @@ static int serial_pci_init(PCIDevice *dev)
memory_region_init_io(&s->io, OBJECT(pci), &serial_io_ops, s, "serial", 8);
pci_register_bar(&pci->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io);
- return 0;
}
static void multi_serial_irq_mux(void *opaque, int n, int level)
@@ -85,7 +83,7 @@ static void multi_serial_irq_mux(void *opaque, int n, int level)
pci_set_irq(&pci->dev, pending);
}
-static int multi_serial_pci_init(PCIDevice *dev)
+static void multi_serial_pci_realize(PCIDevice *dev, Error **errp)
{
PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
PCIMultiSerialState *pci = DO_UPCAST(PCIMultiSerialState, dev, dev);
@@ -116,9 +114,8 @@ static int multi_serial_pci_init(PCIDevice *dev)
s->baudbase = 115200;
serial_realize_core(s, &err);
if (err != NULL) {
- qerror_report_err(err);
- error_free(err);
- return -1;
+ error_propagate(errp, err);
+ return;
}
s->irq = pci->irqs[i];
pci->name[i] = g_strdup_printf("uart #%d", i+1);
@@ -126,7 +123,6 @@ static int multi_serial_pci_init(PCIDevice *dev)
pci->name[i], 8);
memory_region_add_subregion(&pci->iobar, 8 * i, &s->io);
}
- return 0;
}
static void serial_pci_exit(PCIDevice *dev)
@@ -203,7 +199,7 @@ static void serial_pci_class_initfn(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *pc = PCI_DEVICE_CLASS(klass);
- pc->init = serial_pci_init;
+ pc->realize = serial_pci_realize;
pc->exit = serial_pci_exit;
pc->vendor_id = PCI_VENDOR_ID_REDHAT;
pc->device_id = PCI_DEVICE_ID_REDHAT_SERIAL;
@@ -218,7 +214,7 @@ static void multi_2x_serial_pci_class_initfn(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *pc = PCI_DEVICE_CLASS(klass);
- pc->init = multi_serial_pci_init;
+ pc->realize = multi_serial_pci_realize;
pc->exit = multi_serial_pci_exit;
pc->vendor_id = PCI_VENDOR_ID_REDHAT;
pc->device_id = PCI_DEVICE_ID_REDHAT_SERIAL2;
@@ -233,7 +229,7 @@ static void multi_4x_serial_pci_class_initfn(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *pc = PCI_DEVICE_CLASS(klass);
- pc->init = multi_serial_pci_init;
+ pc->realize = multi_serial_pci_realize;
pc->exit = multi_serial_pci_exit;
pc->vendor_id = PCI_VENDOR_ID_REDHAT;
pc->device_id = PCI_DEVICE_ID_REDHAT_SERIAL4;
diff --git a/hw/char/spapr_vty.c b/hw/char/spapr_vty.c
index 0adf096ae0..4e464bd15a 100644
--- a/hw/char/spapr_vty.c
+++ b/hw/char/spapr_vty.c
@@ -60,19 +60,17 @@ void vty_putchars(VIOsPAPRDevice *sdev, uint8_t *buf, int len)
qemu_chr_fe_write(dev->chardev, buf, len);
}
-static int spapr_vty_init(VIOsPAPRDevice *sdev)
+static void spapr_vty_realize(VIOsPAPRDevice *sdev, Error **errp)
{
VIOsPAPRVTYDevice *dev = VIO_SPAPR_VTY_DEVICE(sdev);
if (!dev->chardev) {
- fprintf(stderr, "spapr-vty: Can't create vty without a chardev!\n");
- exit(1);
+ error_setg(errp, "chardev property not set");
+ return;
}
qemu_chr_add_handlers(dev->chardev, vty_can_receive,
vty_receive, NULL, dev);
-
- return 0;
}
/* Forward declaration */
@@ -163,7 +161,7 @@ static void spapr_vty_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
VIOsPAPRDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass);
- k->init = spapr_vty_init;
+ k->realize = spapr_vty_realize;
k->dt_name = "vty";
k->dt_type = "serial";
k->dt_compatible = "hvterm1";
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
index 47fbb34bdd..9a029d2130 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -75,7 +75,7 @@ static VirtIOSerialPort *find_port_by_name(char *name)
static bool use_multiport(VirtIOSerial *vser)
{
VirtIODevice *vdev = VIRTIO_DEVICE(vser);
- return vdev->guest_features & (1 << VIRTIO_CONSOLE_F_MULTIPORT);
+ return virtio_has_feature(vdev, VIRTIO_CONSOLE_F_MULTIPORT);
}
static size_t write_to_port(VirtIOSerialPort *port,
@@ -474,7 +474,7 @@ static uint32_t get_features(VirtIODevice *vdev, uint32_t features)
vser = VIRTIO_SERIAL(vdev);
if (vser->bus.max_nr_ports > 1) {
- features |= (1 << VIRTIO_CONSOLE_F_MULTIPORT);
+ virtio_add_feature(&features, VIRTIO_CONSOLE_F_MULTIPORT);
}
return features;
}
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index ba81709142..570d5f0bad 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -991,8 +991,8 @@ int qdev_prop_check_globals(void)
return ret;
}
-void qdev_prop_set_globals_for_type(DeviceState *dev, const char *typename,
- Error **errp)
+static void qdev_prop_set_globals_for_type(DeviceState *dev,
+ const char *typename)
{
GlobalProperty *prop;
@@ -1005,25 +1005,22 @@ void qdev_prop_set_globals_for_type(DeviceState *dev, const char *typename,
prop->used = true;
object_property_parse(OBJECT(dev), prop->value, prop->property, &err);
if (err != NULL) {
- error_propagate(errp, err);
+ assert(prop->user_provided);
+ error_report("Warning: global %s.%s=%s ignored (%s)",
+ prop->driver, prop->property, prop->value,
+ error_get_pretty(err));
+ error_free(err);
return;
}
}
}
-void qdev_prop_set_globals(DeviceState *dev, Error **errp)
+void qdev_prop_set_globals(DeviceState *dev)
{
ObjectClass *class = object_get_class(OBJECT(dev));
do {
- Error *err = NULL;
-
- qdev_prop_set_globals_for_type(dev, object_class_get_name(class),
- &err);
- if (err != NULL) {
- error_propagate(errp, err);
- return;
- }
+ qdev_prop_set_globals_for_type(dev, object_class_get_name(class));
class = object_class_get_parent(class);
} while (class);
}
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index a02a4cb2ab..6be58669f7 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -1196,13 +1196,7 @@ static void device_initfn(Object *obj)
static void device_post_init(Object *obj)
{
- Error *err = NULL;
- qdev_prop_set_globals(DEVICE(obj), &err);
- if (err) {
- qerror_report_err(err);
- error_free(err);
- exit(EXIT_FAILURE);
- }
+ qdev_prop_set_globals(DEVICE(obj));
}
/* Unlink device from bus and free the structure. */
diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c
index 84af59379d..b53c351aa4 100644
--- a/hw/core/sysbus.c
+++ b/hw/core/sysbus.c
@@ -91,6 +91,8 @@ bool sysbus_has_irq(SysBusDevice *dev, int n)
ObjectProperty *r;
r = object_property_find(OBJECT(dev), prop, NULL);
+ g_free(prop);
+
return (r != NULL);
}
diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c
index ec923c8c4b..8765a7e1d0 100644
--- a/hw/display/cirrus_vga.c
+++ b/hw/display/cirrus_vga.c
@@ -3006,7 +3006,7 @@ static const TypeInfo isa_cirrus_vga_info = {
*
***************************************/
-static int pci_cirrus_vga_initfn(PCIDevice *dev)
+static void pci_cirrus_vga_realize(PCIDevice *dev, Error **errp)
{
PCICirrusVGAState *d = DO_UPCAST(PCICirrusVGAState, dev, dev);
CirrusVGAState *s = &d->cirrus_vga;
@@ -3017,9 +3017,9 @@ static int pci_cirrus_vga_initfn(PCIDevice *dev)
Also accept 8 MB/16 MB for backward compatibility. */
if (s->vga.vram_size_mb != 4 && s->vga.vram_size_mb != 8 &&
s->vga.vram_size_mb != 16) {
- error_report("Invalid cirrus_vga ram size '%u'",
- s->vga.vram_size_mb);
- return -1;
+ error_setg(errp, "Invalid cirrus_vga ram size '%u'",
+ s->vga.vram_size_mb);
+ return;
}
/* setup VGA */
vga_common_init(&s->vga, OBJECT(dev), true);
@@ -3044,7 +3044,6 @@ static int pci_cirrus_vga_initfn(PCIDevice *dev)
if (device_id == CIRRUS_ID_CLGD5446) {
pci_register_bar(&d->dev, 1, 0, &s->cirrus_mmio_io);
}
- return 0;
}
static Property pci_vga_cirrus_properties[] = {
@@ -3058,7 +3057,7 @@ static void cirrus_vga_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- k->init = pci_cirrus_vga_initfn;
+ k->realize = pci_cirrus_vga_realize;
k->romfile = VGABIOS_CIRRUS_FILENAME;
k->vendor_id = PCI_VENDOR_ID_CIRRUS;
k->device_id = CIRRUS_ID_CLGD5446;
diff --git a/hw/display/qxl.c b/hw/display/qxl.c
index 762f75dc2d..b6d65b9487 100644
--- a/hw/display/qxl.c
+++ b/hw/display/qxl.c
@@ -1913,7 +1913,7 @@ static void qxl_init_ramsize(PCIQXLDevice *qxl)
qxl->vram_size = pow2ceil(qxl->vram_size);
}
-static int qxl_init_common(PCIQXLDevice *qxl)
+static void qxl_realize_common(PCIQXLDevice *qxl, Error **errp)
{
uint8_t* config = qxl->pci.config;
uint32_t pci_device_rev;
@@ -1945,9 +1945,9 @@ static int qxl_init_common(PCIQXLDevice *qxl)
io_size = pow2ceil(QXL_IO_RANGE_SIZE);
break;
default:
- error_report("Invalid revision %d for qxl device (max %d)",
- qxl->revision, QXL_DEFAULT_REVISION);
- return -1;
+ error_setg(errp, "Invalid revision %d for qxl device (max %d)",
+ qxl->revision, QXL_DEFAULT_REVISION);
+ return;
}
pci_set_byte(&config[PCI_REVISION_ID], pci_device_rev);
@@ -2011,9 +2011,9 @@ static int qxl_init_common(PCIQXLDevice *qxl)
qxl->ssd.qxl.base.sif = &qxl_interface.base;
if (qemu_spice_add_display_interface(&qxl->ssd.qxl, qxl->vga.con) != 0) {
- error_report("qxl interface %d.%d not supported by spice-server",
- SPICE_INTERFACE_QXL_MAJOR, SPICE_INTERFACE_QXL_MINOR);
- return -1;
+ error_setg(errp, "qxl interface %d.%d not supported by spice-server",
+ SPICE_INTERFACE_QXL_MAJOR, SPICE_INTERFACE_QXL_MINOR);
+ return;
}
qemu_add_vm_change_state_handler(qxl_vm_change_state_handler, qxl);
@@ -2022,15 +2022,13 @@ static int qxl_init_common(PCIQXLDevice *qxl)
qxl->update_area_bh = qemu_bh_new(qxl_render_update_area_bh, qxl);
qxl->ssd.cursor_bh = qemu_bh_new(qemu_spice_cursor_refresh_bh, &qxl->ssd);
-
- return 0;
}
-static int qxl_init_primary(PCIDevice *dev)
+static void qxl_realize_primary(PCIDevice *dev, Error **errp)
{
PCIQXLDevice *qxl = DO_UPCAST(PCIQXLDevice, pci, dev);
VGACommonState *vga = &qxl->vga;
- int rc;
+ Error *local_err = NULL;
qxl->id = 0;
qxl_init_ramsize(qxl);
@@ -2047,18 +2045,18 @@ static int qxl_init_primary(PCIDevice *dev)
vga->con = graphic_console_init(DEVICE(dev), 0, &qxl_ops, qxl);
qemu_spice_display_init_common(&qxl->ssd);
- rc = qxl_init_common(qxl);
- if (rc != 0) {
- return rc;
+ qxl_realize_common(qxl, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
}
qxl->ssd.dcl.ops = &display_listener_ops;
qxl->ssd.dcl.con = vga->con;
register_displaychangelistener(&qxl->ssd.dcl);
- return rc;
}
-static int qxl_init_secondary(PCIDevice *dev)
+static void qxl_realize_secondary(PCIDevice *dev, Error **errp)
{
static int device_id = 1;
PCIQXLDevice *qxl = DO_UPCAST(PCIQXLDevice, pci, dev);
@@ -2071,7 +2069,7 @@ static int qxl_init_secondary(PCIDevice *dev)
qxl->vga.vram_ptr = memory_region_get_ram_ptr(&qxl->vga.vram);
qxl->vga.con = graphic_console_init(DEVICE(dev), 0, &qxl_ops, qxl);
- return qxl_init_common(qxl);
+ qxl_realize_common(qxl, errp);
}
static void qxl_pre_save(void *opaque)
@@ -2284,7 +2282,7 @@ static void qxl_primary_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- k->init = qxl_init_primary;
+ k->realize = qxl_realize_primary;
k->romfile = "vgabios-qxl.bin";
k->vendor_id = REDHAT_PCI_VENDOR_ID;
k->device_id = QXL_DEVICE_ID_STABLE;
@@ -2309,7 +2307,7 @@ static void qxl_secondary_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- k->init = qxl_init_secondary;
+ k->realize = qxl_realize_secondary;
k->vendor_id = REDHAT_PCI_VENDOR_ID;
k->device_id = QXL_DEVICE_ID_STABLE;
k->class_id = PCI_CLASS_DISPLAY_OTHER;
diff --git a/hw/display/vga-pci.c b/hw/display/vga-pci.c
index 53739e4f79..aabfc23cd9 100644
--- a/hw/display/vga-pci.c
+++ b/hw/display/vga-pci.c
@@ -181,6 +181,20 @@ static void pci_vga_qext_write(void *ptr, hwaddr addr,
}
}
+static bool vga_get_big_endian_fb(Object *obj, Error **errp)
+{
+ PCIVGAState *d = DO_UPCAST(PCIVGAState, dev, PCI_DEVICE(obj));
+
+ return d->vga.big_endian_fb;
+}
+
+static void vga_set_big_endian_fb(Object *obj, bool value, Error **errp)
+{
+ PCIVGAState *d = DO_UPCAST(PCIVGAState, dev, PCI_DEVICE(obj));
+
+ d->vga.big_endian_fb = value;
+}
+
static const MemoryRegionOps pci_vga_qext_ops = {
.read = pci_vga_qext_read,
.write = pci_vga_qext_write,
@@ -189,7 +203,7 @@ static const MemoryRegionOps pci_vga_qext_ops = {
.endianness = DEVICE_LITTLE_ENDIAN,
};
-static int pci_std_vga_initfn(PCIDevice *dev)
+static void pci_std_vga_realize(PCIDevice *dev, Error **errp)
{
PCIVGAState *d = DO_UPCAST(PCIVGAState, dev, dev);
VGACommonState *s = &d->vga;
@@ -232,11 +246,16 @@ static int pci_std_vga_initfn(PCIDevice *dev)
/* compatibility with pc-0.13 and older */
vga_init_vbe(s, OBJECT(dev), pci_address_space(dev));
}
+}
- return 0;
+static void pci_std_vga_init(Object *obj)
+{
+ /* Expose framebuffer byteorder via QOM */
+ object_property_add_bool(obj, "big-endian-framebuffer",
+ vga_get_big_endian_fb, vga_set_big_endian_fb, NULL);
}
-static int pci_secondary_vga_initfn(PCIDevice *dev)
+static void pci_secondary_vga_realize(PCIDevice *dev, Error **errp)
{
PCIVGAState *d = DO_UPCAST(PCIVGAState, dev, dev);
VGACommonState *s = &d->vga;
@@ -267,8 +286,13 @@ static int pci_secondary_vga_initfn(PCIDevice *dev)
pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->vram);
pci_register_bar(&d->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &d->mmio);
+}
- return 0;
+static void pci_secondary_vga_init(Object *obj)
+{
+ /* Expose framebuffer byteorder via QOM */
+ object_property_add_bool(obj, "big-endian-framebuffer",
+ vga_get_big_endian_fb, vga_set_big_endian_fb, NULL);
}
static void pci_secondary_vga_reset(DeviceState *dev)
@@ -298,7 +322,7 @@ static void vga_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- k->init = pci_std_vga_initfn;
+ k->realize = pci_std_vga_realize;
k->romfile = "vgabios-stdvga.bin";
k->vendor_id = PCI_VENDOR_ID_QEMU;
k->device_id = PCI_DEVICE_ID_QEMU_VGA;
@@ -314,7 +338,7 @@ static void secondary_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- k->init = pci_secondary_vga_initfn;
+ k->realize = pci_secondary_vga_realize;
k->vendor_id = PCI_VENDOR_ID_QEMU;
k->device_id = PCI_DEVICE_ID_QEMU_VGA;
k->class_id = PCI_CLASS_DISPLAY_OTHER;
@@ -327,6 +351,7 @@ static void secondary_class_init(ObjectClass *klass, void *data)
static const TypeInfo vga_info = {
.name = "VGA",
.parent = TYPE_PCI_DEVICE,
+ .instance_init = pci_std_vga_init,
.instance_size = sizeof(PCIVGAState),
.class_init = vga_class_init,
};
@@ -334,6 +359,7 @@ static const TypeInfo vga_info = {
static const TypeInfo secondary_info = {
.name = "secondary-vga",
.parent = TYPE_PCI_DEVICE,
+ .instance_init = pci_secondary_vga_init,
.instance_size = sizeof(PCIVGAState),
.class_init = secondary_class_init,
};
diff --git a/hw/display/vmware_vga.c b/hw/display/vmware_vga.c
index 1751f19793..c17ddd1fcd 100644
--- a/hw/display/vmware_vga.c
+++ b/hw/display/vmware_vga.c
@@ -1298,7 +1298,7 @@ static const MemoryRegionOps vmsvga_io_ops = {
},
};
-static int pci_vmsvga_initfn(PCIDevice *dev)
+static void pci_vmsvga_realize(PCIDevice *dev, Error **errp)
{
struct pci_vmsvga_state_s *s = VMWARE_SVGA(dev);
@@ -1323,8 +1323,6 @@ static int pci_vmsvga_initfn(PCIDevice *dev)
/* compatibility with pc-0.13 and older */
vga_init_vbe(&s->chip.vga, OBJECT(dev), pci_address_space(dev));
}
-
- return 0;
}
static Property vga_vmware_properties[] = {
@@ -1338,7 +1336,7 @@ static void vmsvga_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- k->init = pci_vmsvga_initfn;
+ k->realize = pci_vmsvga_realize;
k->romfile = "vgabios-vmware.bin";
k->vendor_id = PCI_VENDOR_ID_VMWARE;
k->device_id = SVGA_PCI_DEVICE_ID;
diff --git a/hw/dma/pl330.c b/hw/dma/pl330.c
index 16cf77e7b2..5be3df521d 100644
--- a/hw/dma/pl330.c
+++ b/hw/dma/pl330.c
@@ -1566,7 +1566,7 @@ static void pl330_realize(DeviceState *dev, Error **errp)
s->cfg[1] |= 5;
break;
default:
- error_setg(errp, "Bad value for i-cache_len property: %" PRIx8 "\n",
+ error_setg(errp, "Bad value for i-cache_len property: %" PRIx8,
s->i_cache_len);
return;
}
@@ -1601,7 +1601,7 @@ static void pl330_realize(DeviceState *dev, Error **errp)
s->cfg[CFG_CRD] |= 0x4;
break;
default:
- error_setg(errp, "Bad value for data_width property: %" PRIx8 "\n",
+ error_setg(errp, "Bad value for data_width property: %" PRIx8,
s->data_width);
return;
}
diff --git a/hw/i2c/smbus_ich9.c b/hw/i2c/smbus_ich9.c
index 0803dc4d18..91d4d322ca 100644
--- a/hw/i2c/smbus_ich9.c
+++ b/hw/i2c/smbus_ich9.c
@@ -71,7 +71,7 @@ static void ich9_smbus_write_config(PCIDevice *d, uint32_t address,
}
}
-static int ich9_smbus_initfn(PCIDevice *d)
+static void ich9_smbus_realize(PCIDevice *d, Error **errp)
{
ICH9SMBState *s = ICH9_SMB_DEVICE(d);
@@ -84,7 +84,6 @@ static int ich9_smbus_initfn(PCIDevice *d)
pm_smbus_init(&d->qdev, &s->smb);
pci_register_bar(d, ICH9_SMB_SMB_BASE_BAR, PCI_BASE_ADDRESS_SPACE_IO,
&s->smb.io);
- return 0;
}
static void ich9_smb_class_init(ObjectClass *klass, void *data)
@@ -98,7 +97,7 @@ static void ich9_smb_class_init(ObjectClass *klass, void *data)
k->class_id = PCI_CLASS_SERIAL_SMBUS;
dc->vmsd = &vmstate_ich9_smbus;
dc->desc = "ICH9 SMBUS Bridge";
- k->init = ich9_smbus_initfn;
+ k->realize = ich9_smbus_realize;
k->config_write = ich9_smbus_write_config;
/*
* Reason: part of ICH9 southbridge, needs to be wired up by
diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs
index 2b678ef2a6..e058a39147 100644
--- a/hw/i386/Makefile.objs
+++ b/hw/i386/Makefile.objs
@@ -7,10 +7,8 @@ obj-$(CONFIG_XEN) += ../xenpv/ xen/
obj-y += kvmvapic.o
obj-y += acpi-build.o
-hw/i386/acpi-build.o: hw/i386/acpi-build.c hw/i386/acpi-dsdt.hex \
- hw/i386/ssdt-proc.hex hw/i386/ssdt-pcihp.hex hw/i386/ssdt-misc.hex \
+hw/i386/acpi-build.o: hw/i386/acpi-build.c \
hw/i386/acpi-dsdt.hex hw/i386/q35-acpi-dsdt.hex \
- hw/i386/q35-acpi-dsdt.hex hw/i386/ssdt-mem.hex \
hw/i386/ssdt-tpm.hex
iasl-option=$(shell if test -z "`$(1) $(2) 2>&1 > /dev/null`" \
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 4944249b84..d0a5c85e10 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -54,6 +54,8 @@
#include "hw/i386/q35-acpi-dsdt.hex"
#include "hw/i386/acpi-dsdt.hex"
+#include "hw/acpi/aml-build.h"
+
#include "qapi/qmp/qint.h"
#include "qom/qom-qobject.h"
#include "exec/ram_addr.h"
@@ -99,15 +101,21 @@ typedef struct AcpiPmInfo {
uint32_t gpe0_blk;
uint32_t gpe0_blk_len;
uint32_t io_base;
+ uint16_t cpu_hp_io_base;
+ uint16_t cpu_hp_io_len;
+ uint16_t mem_hp_io_base;
+ uint16_t mem_hp_io_len;
+ uint16_t pcihp_io_base;
+ uint16_t pcihp_io_len;
} AcpiPmInfo;
typedef struct AcpiMiscInfo {
bool has_hpet;
bool has_tpm;
- DECLARE_BITMAP(slot_hotplug_enable, PCI_SLOT_MAX);
const unsigned char *dsdt_code;
unsigned dsdt_size;
uint16_t pvpanic_port;
+ uint16_t applesmc_io_base;
} AcpiMiscInfo;
typedef struct AcpiBuildPciBusHotplugState {
@@ -119,7 +127,6 @@ typedef struct AcpiBuildPciBusHotplugState {
static void acpi_get_dsdt(AcpiMiscInfo *info)
{
- uint16_t *applesmc_sta;
Object *piix = piix4_pm_find();
Object *lpc = ich9_lpc_find();
assert(!!piix != !!lpc);
@@ -127,17 +134,11 @@ static void acpi_get_dsdt(AcpiMiscInfo *info)
if (piix) {
info->dsdt_code = AcpiDsdtAmlCode;
info->dsdt_size = sizeof AcpiDsdtAmlCode;
- applesmc_sta = piix_dsdt_applesmc_sta;
}
if (lpc) {
info->dsdt_code = Q35AcpiDsdtAmlCode;
info->dsdt_size = sizeof Q35AcpiDsdtAmlCode;
- applesmc_sta = q35_dsdt_applesmc_sta;
}
-
- /* Patch in appropriate value for AppleSMC _STA */
- *(uint8_t *)(info->dsdt_code + *applesmc_sta) =
- applesmc_find() ? 0x0b : 0x00;
}
static
@@ -172,14 +173,26 @@ static void acpi_get_pm_info(AcpiPmInfo *pm)
Object *obj = NULL;
QObject *o;
+ pm->pcihp_io_base = 0;
+ pm->pcihp_io_len = 0;
if (piix) {
obj = piix;
+ pm->cpu_hp_io_base = PIIX4_CPU_HOTPLUG_IO_BASE;
+ pm->pcihp_io_base =
+ object_property_get_int(obj, ACPI_PCIHP_IO_BASE_PROP, NULL);
+ pm->pcihp_io_len =
+ object_property_get_int(obj, ACPI_PCIHP_IO_LEN_PROP, NULL);
}
if (lpc) {
obj = lpc;
+ pm->cpu_hp_io_base = ICH9_CPU_HOTPLUG_IO_BASE;
}
assert(obj);
+ pm->cpu_hp_io_len = ACPI_GPE_PROC_LEN;
+ pm->mem_hp_io_base = ACPI_MEMORY_HOTPLUG_BASE;
+ pm->mem_hp_io_len = ACPI_MEMORY_HOTPLUG_IO_LEN;
+
/* Fill in optional s3/s4 related properties */
o = object_property_get_qobject(obj, ACPI_PM_PROP_S3_DISABLED, NULL);
if (o) {
@@ -228,6 +241,7 @@ static void acpi_get_misc_info(AcpiMiscInfo *info)
info->has_hpet = hpet_find();
info->has_tpm = tpm_find();
info->pvpanic_port = pvpanic_port();
+ info->applesmc_io_base = applesmc_port();
}
static void acpi_get_pci_info(PcPciInfo *info)
@@ -280,208 +294,6 @@ build_header(GArray *linker, GArray *table_data,
table_data->data, h, len, &h->checksum);
}
-static inline GArray *build_alloc_array(void)
-{
- return g_array_new(false, true /* clear */, 1);
-}
-
-static inline void build_free_array(GArray *array)
-{
- g_array_free(array, true);
-}
-
-static inline void build_prepend_byte(GArray *array, uint8_t val)
-{
- g_array_prepend_val(array, val);
-}
-
-static inline void build_append_byte(GArray *array, uint8_t val)
-{
- g_array_append_val(array, val);
-}
-
-static inline void build_append_array(GArray *array, GArray *val)
-{
- g_array_append_vals(array, val->data, val->len);
-}
-
-#define ACPI_NAMESEG_LEN 4
-
-static void GCC_FMT_ATTR(2, 3)
-build_append_nameseg(GArray *array, const char *format, ...)
-{
- /* It would be nicer to use g_string_vprintf but it's only there in 2.22 */
- char s[] = "XXXX";
- int len;
- va_list args;
-
- va_start(args, format);
- len = vsnprintf(s, sizeof s, format, args);
- va_end(args);
-
- assert(len <= ACPI_NAMESEG_LEN);
-
- g_array_append_vals(array, s, len);
- /* Pad up to ACPI_NAMESEG_LEN characters if necessary. */
- g_array_append_vals(array, "____", ACPI_NAMESEG_LEN - len);
-}
-
-/* 5.4 Definition Block Encoding */
-enum {
- PACKAGE_LENGTH_1BYTE_SHIFT = 6, /* Up to 63 - use extra 2 bits. */
- PACKAGE_LENGTH_2BYTE_SHIFT = 4,
- PACKAGE_LENGTH_3BYTE_SHIFT = 12,
- PACKAGE_LENGTH_4BYTE_SHIFT = 20,
-};
-
-static void build_prepend_package_length(GArray *package, unsigned min_bytes)
-{
- uint8_t byte;
- unsigned length = package->len;
- unsigned length_bytes;
-
- if (length + 1 < (1 << PACKAGE_LENGTH_1BYTE_SHIFT)) {
- length_bytes = 1;
- } else if (length + 2 < (1 << PACKAGE_LENGTH_3BYTE_SHIFT)) {
- length_bytes = 2;
- } else if (length + 3 < (1 << PACKAGE_LENGTH_4BYTE_SHIFT)) {
- length_bytes = 3;
- } else {
- length_bytes = 4;
- }
-
- /* Force length to at least min_bytes.
- * This wastes memory but that's how bios did it.
- */
- length_bytes = MAX(length_bytes, min_bytes);
-
- /* PkgLength is the length of the inclusive length of the data. */
- length += length_bytes;
-
- switch (length_bytes) {
- case 1:
- byte = length;
- build_prepend_byte(package, byte);
- return;
- case 4:
- byte = length >> PACKAGE_LENGTH_4BYTE_SHIFT;
- build_prepend_byte(package, byte);
- length &= (1 << PACKAGE_LENGTH_4BYTE_SHIFT) - 1;
- /* fall through */
- case 3:
- byte = length >> PACKAGE_LENGTH_3BYTE_SHIFT;
- build_prepend_byte(package, byte);
- length &= (1 << PACKAGE_LENGTH_3BYTE_SHIFT) - 1;
- /* fall through */
- case 2:
- byte = length >> PACKAGE_LENGTH_2BYTE_SHIFT;
- build_prepend_byte(package, byte);
- length &= (1 << PACKAGE_LENGTH_2BYTE_SHIFT) - 1;
- /* fall through */
- }
- /*
- * Most significant two bits of byte zero indicate how many following bytes
- * are in PkgLength encoding.
- */
- byte = ((length_bytes - 1) << PACKAGE_LENGTH_1BYTE_SHIFT) | length;
- build_prepend_byte(package, byte);
-}
-
-static void build_package(GArray *package, uint8_t op, unsigned min_bytes)
-{
- build_prepend_package_length(package, min_bytes);
- build_prepend_byte(package, op);
-}
-
-static void build_extop_package(GArray *package, uint8_t op)
-{
- build_package(package, op, 1);
- build_prepend_byte(package, 0x5B); /* ExtOpPrefix */
-}
-
-static void build_append_value(GArray *table, uint32_t value, int size)
-{
- uint8_t prefix;
- int i;
-
- switch (size) {
- case 1:
- prefix = 0x0A; /* BytePrefix */
- break;
- case 2:
- prefix = 0x0B; /* WordPrefix */
- break;
- case 4:
- prefix = 0x0C; /* DWordPrefix */
- break;
- default:
- assert(0);
- return;
- }
- build_append_byte(table, prefix);
- for (i = 0; i < size; ++i) {
- build_append_byte(table, value & 0xFF);
- value = value >> 8;
- }
-}
-
-static void build_append_int(GArray *table, uint32_t value)
-{
- if (value == 0x00) {
- build_append_byte(table, 0x00); /* ZeroOp */
- } else if (value == 0x01) {
- build_append_byte(table, 0x01); /* OneOp */
- } else if (value <= 0xFF) {
- build_append_value(table, value, 1);
- } else if (value <= 0xFFFF) {
- build_append_value(table, value, 2);
- } else {
- build_append_value(table, value, 4);
- }
-}
-
-static GArray *build_alloc_method(const char *name, uint8_t arg_count)
-{
- GArray *method = build_alloc_array();
-
- build_append_nameseg(method, "%s", name);
- build_append_byte(method, arg_count); /* MethodFlags: ArgCount */
-
- return method;
-}
-
-static void build_append_and_cleanup_method(GArray *device, GArray *method)
-{
- uint8_t op = 0x14; /* MethodOp */
-
- build_package(method, op, 0);
-
- build_append_array(device, method);
- build_free_array(method);
-}
-
-static void build_append_notify_target_ifequal(GArray *method,
- GArray *target_name,
- uint32_t value, int size)
-{
- GArray *notify = build_alloc_array();
- uint8_t op = 0xA0; /* IfOp */
-
- build_append_byte(notify, 0x93); /* LEqualOp */
- build_append_byte(notify, 0x68); /* Arg0Op */
- build_append_value(notify, value, size);
- build_append_byte(notify, 0x86); /* NotifyOp */
- build_append_array(notify, target_name);
- build_append_byte(notify, 0x69); /* Arg1Op */
-
- /* Pack it up */
- build_package(notify, op, 1);
-
- build_append_array(method, notify);
-
- build_free_array(notify);
-}
-
/* End here */
#define ACPI_PORT_SMI_CMD 0x00b2 /* TODO: this is APM_CNT_IOPORT */
@@ -508,24 +320,6 @@ static void acpi_align_size(GArray *blob, unsigned align)
g_array_set_size(blob, ROUND_UP(acpi_data_len(blob), align));
}
-/* Set a value within table in a safe manner */
-#define ACPI_BUILD_SET_LE(table, size, off, bits, val) \
- do { \
- uint64_t ACPI_BUILD_SET_LE_val = cpu_to_le64(val); \
- memcpy(acpi_data_get_ptr(table, size, off, \
- (bits) / BITS_PER_BYTE), \
- &ACPI_BUILD_SET_LE_val, \
- (bits) / BITS_PER_BYTE); \
- } while (0)
-
-static inline void *acpi_data_get_ptr(uint8_t *table_data, unsigned table_size,
- unsigned off, unsigned size)
-{
- assert(off + size > off);
- assert(off + size <= table_size);
- return table_data + off;
-}
-
static inline void acpi_add_table(GArray *table_offsets, GArray *table_data)
{
uint32_t offset = cpu_to_le32(table_data->len);
@@ -673,115 +467,8 @@ build_madt(GArray *table_data, GArray *linker, AcpiCpuInfo *cpu,
table_data->len - madt_start, 1);
}
-/* Encode a hex value */
-static inline char acpi_get_hex(uint32_t val)
-{
- val &= 0x0f;
- return (val <= 9) ? ('0' + val) : ('A' + val - 10);
-}
-
-#include "hw/i386/ssdt-proc.hex"
-
-/* 0x5B 0x83 ProcessorOp PkgLength NameString ProcID */
-#define ACPI_PROC_OFFSET_CPUHEX (*ssdt_proc_name - *ssdt_proc_start + 2)
-#define ACPI_PROC_OFFSET_CPUID1 (*ssdt_proc_name - *ssdt_proc_start + 4)
-#define ACPI_PROC_OFFSET_CPUID2 (*ssdt_proc_id - *ssdt_proc_start)
-#define ACPI_PROC_SIZEOF (*ssdt_proc_end - *ssdt_proc_start)
-#define ACPI_PROC_AML (ssdp_proc_aml + *ssdt_proc_start)
-
-/* 0x5B 0x82 DeviceOp PkgLength NameString */
-#define ACPI_PCIHP_OFFSET_HEX (*ssdt_pcihp_name - *ssdt_pcihp_start + 1)
-#define ACPI_PCIHP_OFFSET_ID (*ssdt_pcihp_id - *ssdt_pcihp_start)
-#define ACPI_PCIHP_OFFSET_ADR (*ssdt_pcihp_adr - *ssdt_pcihp_start)
-#define ACPI_PCIHP_OFFSET_EJ0 (*ssdt_pcihp_ej0 - *ssdt_pcihp_start)
-#define ACPI_PCIHP_SIZEOF (*ssdt_pcihp_end - *ssdt_pcihp_start)
-#define ACPI_PCIHP_AML (ssdp_pcihp_aml + *ssdt_pcihp_start)
-
-#define ACPI_PCINOHP_OFFSET_HEX (*ssdt_pcinohp_name - *ssdt_pcinohp_start + 1)
-#define ACPI_PCINOHP_OFFSET_ADR (*ssdt_pcinohp_adr - *ssdt_pcinohp_start)
-#define ACPI_PCINOHP_SIZEOF (*ssdt_pcinohp_end - *ssdt_pcinohp_start)
-#define ACPI_PCINOHP_AML (ssdp_pcihp_aml + *ssdt_pcinohp_start)
-
-#define ACPI_PCIVGA_OFFSET_HEX (*ssdt_pcivga_name - *ssdt_pcivga_start + 1)
-#define ACPI_PCIVGA_OFFSET_ADR (*ssdt_pcivga_adr - *ssdt_pcivga_start)
-#define ACPI_PCIVGA_SIZEOF (*ssdt_pcivga_end - *ssdt_pcivga_start)
-#define ACPI_PCIVGA_AML (ssdp_pcihp_aml + *ssdt_pcivga_start)
-
-#define ACPI_PCIQXL_OFFSET_HEX (*ssdt_pciqxl_name - *ssdt_pciqxl_start + 1)
-#define ACPI_PCIQXL_OFFSET_ADR (*ssdt_pciqxl_adr - *ssdt_pciqxl_start)
-#define ACPI_PCIQXL_SIZEOF (*ssdt_pciqxl_end - *ssdt_pciqxl_start)
-#define ACPI_PCIQXL_AML (ssdp_pcihp_aml + *ssdt_pciqxl_start)
-
-#include "hw/i386/ssdt-mem.hex"
-
-/* 0x5B 0x82 DeviceOp PkgLength NameString DimmID */
-#define ACPI_MEM_OFFSET_HEX (*ssdt_mem_name - *ssdt_mem_start + 2)
-#define ACPI_MEM_OFFSET_ID (*ssdt_mem_id - *ssdt_mem_start + 7)
-#define ACPI_MEM_SIZEOF (*ssdt_mem_end - *ssdt_mem_start)
-#define ACPI_MEM_AML (ssdm_mem_aml + *ssdt_mem_start)
-
-#define ACPI_SSDT_SIGNATURE 0x54445353 /* SSDT */
-#define ACPI_SSDT_HEADER_LENGTH 36
-
-#include "hw/i386/ssdt-misc.hex"
-#include "hw/i386/ssdt-pcihp.hex"
#include "hw/i386/ssdt-tpm.hex"
-static void
-build_append_notify_method(GArray *device, const char *name,
- const char *format, int count)
-{
- int i;
- GArray *method = build_alloc_method(name, 2);
-
- for (i = 0; i < count; i++) {
- GArray *target = build_alloc_array();
- build_append_nameseg(target, format, i);
- assert(i < 256); /* Fits in 1 byte */
- build_append_notify_target_ifequal(method, target, i, 1);
- build_free_array(target);
- }
-
- build_append_and_cleanup_method(device, method);
-}
-
-static void patch_pcihp(int slot, uint8_t *ssdt_ptr)
-{
- unsigned devfn = PCI_DEVFN(slot, 0);
-
- ssdt_ptr[ACPI_PCIHP_OFFSET_HEX] = acpi_get_hex(devfn >> 4);
- ssdt_ptr[ACPI_PCIHP_OFFSET_HEX + 1] = acpi_get_hex(devfn);
- ssdt_ptr[ACPI_PCIHP_OFFSET_ID] = slot;
- ssdt_ptr[ACPI_PCIHP_OFFSET_ADR + 2] = slot;
-}
-
-static void patch_pcinohp(int slot, uint8_t *ssdt_ptr)
-{
- unsigned devfn = PCI_DEVFN(slot, 0);
-
- ssdt_ptr[ACPI_PCINOHP_OFFSET_HEX] = acpi_get_hex(devfn >> 4);
- ssdt_ptr[ACPI_PCINOHP_OFFSET_HEX + 1] = acpi_get_hex(devfn);
- ssdt_ptr[ACPI_PCINOHP_OFFSET_ADR + 2] = slot;
-}
-
-static void patch_pcivga(int slot, uint8_t *ssdt_ptr)
-{
- unsigned devfn = PCI_DEVFN(slot, 0);
-
- ssdt_ptr[ACPI_PCIVGA_OFFSET_HEX] = acpi_get_hex(devfn >> 4);
- ssdt_ptr[ACPI_PCIVGA_OFFSET_HEX + 1] = acpi_get_hex(devfn);
- ssdt_ptr[ACPI_PCIVGA_OFFSET_ADR + 2] = slot;
-}
-
-static void patch_pciqxl(int slot, uint8_t *ssdt_ptr)
-{
- unsigned devfn = PCI_DEVFN(slot, 0);
-
- ssdt_ptr[ACPI_PCIQXL_OFFSET_HEX] = acpi_get_hex(devfn >> 4);
- ssdt_ptr[ACPI_PCIQXL_OFFSET_HEX + 1] = acpi_get_hex(devfn);
- ssdt_ptr[ACPI_PCIQXL_OFFSET_ADR + 2] = slot;
-}
-
/* Assign BSEL property to all buses. In the future, this can be changed
* to only assign to buses that support hotplug.
*/
@@ -812,261 +499,155 @@ static void acpi_set_pci_info(void)
}
}
-static void build_pci_bus_state_init(AcpiBuildPciBusHotplugState *state,
- AcpiBuildPciBusHotplugState *parent,
- bool pcihp_bridge_en)
-{
- state->parent = parent;
- state->device_table = build_alloc_array();
- state->notify_table = build_alloc_array();
- state->pcihp_bridge_en = pcihp_bridge_en;
-}
-
-static void build_pci_bus_state_cleanup(AcpiBuildPciBusHotplugState *state)
+static void build_append_pcihp_notify_entry(Aml *method, int slot)
{
- build_free_array(state->device_table);
- build_free_array(state->notify_table);
-}
-
-static void *build_pci_bus_begin(PCIBus *bus, void *parent_state)
-{
- AcpiBuildPciBusHotplugState *parent = parent_state;
- AcpiBuildPciBusHotplugState *child = g_malloc(sizeof *child);
-
- build_pci_bus_state_init(child, parent, parent->pcihp_bridge_en);
+ Aml *if_ctx;
+ int32_t devfn = PCI_DEVFN(slot, 0);
- return child;
+ if_ctx = aml_if(aml_and(aml_arg(0), aml_int(0x1U << slot)));
+ aml_append(if_ctx, aml_notify(aml_name("S%.02X", devfn), aml_arg(1)));
+ aml_append(method, if_ctx);
}
-static void build_pci_bus_end(PCIBus *bus, void *bus_state)
+static void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus,
+ bool pcihp_bridge_en)
{
- AcpiBuildPciBusHotplugState *child = bus_state;
- AcpiBuildPciBusHotplugState *parent = child->parent;
- GArray *bus_table = build_alloc_array();
- DECLARE_BITMAP(slot_hotplug_enable, PCI_SLOT_MAX);
- DECLARE_BITMAP(slot_device_present, PCI_SLOT_MAX);
- DECLARE_BITMAP(slot_device_system, PCI_SLOT_MAX);
- DECLARE_BITMAP(slot_device_vga, PCI_SLOT_MAX);
- DECLARE_BITMAP(slot_device_qxl, PCI_SLOT_MAX);
- uint8_t op;
- int i;
+ Aml *dev, *notify_method, *method;
QObject *bsel;
- GArray *method;
- bool bus_hotplug_support = false;
-
- /*
- * Skip bridge subtree creation if bridge hotplug is disabled
- * to make acpi tables compatible with legacy machine types.
- */
- if (!child->pcihp_bridge_en && bus->parent_dev) {
- return;
- }
-
- if (bus->parent_dev) {
- op = 0x82; /* DeviceOp */
- build_append_nameseg(bus_table, "S%.02X",
- bus->parent_dev->devfn);
- build_append_byte(bus_table, 0x08); /* NameOp */
- build_append_nameseg(bus_table, "_SUN");
- build_append_value(bus_table, PCI_SLOT(bus->parent_dev->devfn), 1);
- build_append_byte(bus_table, 0x08); /* NameOp */
- build_append_nameseg(bus_table, "_ADR");
- build_append_value(bus_table, (PCI_SLOT(bus->parent_dev->devfn) << 16) |
- PCI_FUNC(bus->parent_dev->devfn), 4);
- } else {
- op = 0x10; /* ScopeOp */;
- build_append_nameseg(bus_table, "PCI0");
- }
+ PCIBus *sec;
+ int i;
bsel = object_property_get_qobject(OBJECT(bus), ACPI_PCIHP_PROP_BSEL, NULL);
if (bsel) {
- build_append_byte(bus_table, 0x08); /* NameOp */
- build_append_nameseg(bus_table, "BSEL");
- build_append_int(bus_table, qint_get_int(qobject_to_qint(bsel)));
- memset(slot_hotplug_enable, 0xff, sizeof slot_hotplug_enable);
- } else {
- /* No bsel - no slots are hot-pluggable */
- memset(slot_hotplug_enable, 0x00, sizeof slot_hotplug_enable);
- }
+ int64_t bsel_val = qint_get_int(qobject_to_qint(bsel));
- memset(slot_device_present, 0x00, sizeof slot_device_present);
- memset(slot_device_system, 0x00, sizeof slot_device_present);
- memset(slot_device_vga, 0x00, sizeof slot_device_vga);
- memset(slot_device_qxl, 0x00, sizeof slot_device_qxl);
+ aml_append(parent_scope, aml_name_decl("BSEL", aml_int(bsel_val)));
+ notify_method = aml_method("DVNT", 2);
+ }
for (i = 0; i < ARRAY_SIZE(bus->devices); i += PCI_FUNC_MAX) {
DeviceClass *dc;
PCIDeviceClass *pc;
PCIDevice *pdev = bus->devices[i];
int slot = PCI_SLOT(i);
+ bool hotplug_enabled_dev;
bool bridge_in_acpi;
if (!pdev) {
+ if (bsel) { /* add hotplug slots for non present devices */
+ dev = aml_device("S%.02X", PCI_DEVFN(slot, 0));
+ aml_append(dev, aml_name_decl("_SUN", aml_int(slot)));
+ aml_append(dev, aml_name_decl("_ADR", aml_int(slot << 16)));
+ method = aml_method("_EJ0", 1);
+ aml_append(method,
+ aml_call2("PCEJ", aml_name("BSEL"), aml_name("_SUN"))
+ );
+ aml_append(dev, method);
+ aml_append(parent_scope, dev);
+
+ build_append_pcihp_notify_entry(notify_method, slot);
+ }
continue;
}
- set_bit(slot, slot_device_present);
pc = PCI_DEVICE_GET_CLASS(pdev);
dc = DEVICE_GET_CLASS(pdev);
/* When hotplug for bridges is enabled, bridges are
* described in ACPI separately (see build_pci_bus_end).
* In this case they aren't themselves hot-pluggable.
+ * Hotplugged bridges *are* hot-pluggable.
*/
- bridge_in_acpi = pc->is_bridge && child->pcihp_bridge_en;
+ bridge_in_acpi = pc->is_bridge && pcihp_bridge_en &&
+ !DEVICE(pdev)->hotplugged;
- if (pc->class_id == PCI_CLASS_BRIDGE_ISA || bridge_in_acpi) {
- set_bit(slot, slot_device_system);
+ hotplug_enabled_dev = bsel && dc->hotpluggable && !bridge_in_acpi;
+
+ if (pc->class_id == PCI_CLASS_BRIDGE_ISA) {
+ continue;
}
+ /* start to compose PCI slot descriptor */
+ dev = aml_device("S%.02X", PCI_DEVFN(slot, 0));
+ aml_append(dev, aml_name_decl("_ADR", aml_int(slot << 16)));
+
if (pc->class_id == PCI_CLASS_DISPLAY_VGA) {
- set_bit(slot, slot_device_vga);
+ /* add VGA specific AML methods */
+ int s3d;
if (object_dynamic_cast(OBJECT(pdev), "qxl-vga")) {
- set_bit(slot, slot_device_qxl);
+ s3d = 3;
+ } else {
+ s3d = 0;
}
- }
- if (!dc->hotpluggable || bridge_in_acpi) {
- clear_bit(slot, slot_hotplug_enable);
- }
- }
+ method = aml_method("_S1D", 0);
+ aml_append(method, aml_return(aml_int(0)));
+ aml_append(dev, method);
+
+ method = aml_method("_S2D", 0);
+ aml_append(method, aml_return(aml_int(0)));
+ aml_append(dev, method);
+
+ method = aml_method("_S3D", 0);
+ aml_append(method, aml_return(aml_int(s3d)));
+ aml_append(dev, method);
+ } else if (hotplug_enabled_dev) {
+ /* add _SUN/_EJ0 to make slot hotpluggable */
+ aml_append(dev, aml_name_decl("_SUN", aml_int(slot)));
+
+ method = aml_method("_EJ0", 1);
+ aml_append(method,
+ aml_call2("PCEJ", aml_name("BSEL"), aml_name("_SUN"))
+ );
+ aml_append(dev, method);
+
+ if (bsel) {
+ build_append_pcihp_notify_entry(notify_method, slot);
+ }
+ } else if (bridge_in_acpi) {
+ /*
+ * device is coldplugged bridge,
+ * add child device descriptions into its scope
+ */
+ PCIBus *sec_bus = pci_bridge_get_sec_bus(PCI_BRIDGE(pdev));
- /* Append Device object for each slot */
- for (i = 0; i < PCI_SLOT_MAX; i++) {
- bool can_eject = test_bit(i, slot_hotplug_enable);
- bool present = test_bit(i, slot_device_present);
- bool vga = test_bit(i, slot_device_vga);
- bool qxl = test_bit(i, slot_device_qxl);
- bool system = test_bit(i, slot_device_system);
- if (can_eject) {
- void *pcihp = acpi_data_push(bus_table,
- ACPI_PCIHP_SIZEOF);
- memcpy(pcihp, ACPI_PCIHP_AML, ACPI_PCIHP_SIZEOF);
- patch_pcihp(i, pcihp);
- bus_hotplug_support = true;
- } else if (qxl) {
- void *pcihp = acpi_data_push(bus_table,
- ACPI_PCIQXL_SIZEOF);
- memcpy(pcihp, ACPI_PCIQXL_AML, ACPI_PCIQXL_SIZEOF);
- patch_pciqxl(i, pcihp);
- } else if (vga) {
- void *pcihp = acpi_data_push(bus_table,
- ACPI_PCIVGA_SIZEOF);
- memcpy(pcihp, ACPI_PCIVGA_AML, ACPI_PCIVGA_SIZEOF);
- patch_pcivga(i, pcihp);
- } else if (system) {
- /* Nothing to do: system devices are in DSDT or in SSDT above. */
- } else if (present) {
- void *pcihp = acpi_data_push(bus_table,
- ACPI_PCINOHP_SIZEOF);
- memcpy(pcihp, ACPI_PCINOHP_AML, ACPI_PCINOHP_SIZEOF);
- patch_pcinohp(i, pcihp);
+ build_append_pci_bus_devices(dev, sec_bus, pcihp_bridge_en);
}
+ /* slot descriptor has been composed, add it into parent context */
+ aml_append(parent_scope, dev);
}
if (bsel) {
- method = build_alloc_method("DVNT", 2);
-
- for (i = 0; i < PCI_SLOT_MAX; i++) {
- GArray *notify;
- uint8_t op;
-
- if (!test_bit(i, slot_hotplug_enable)) {
- continue;
- }
-
- notify = build_alloc_array();
- op = 0xA0; /* IfOp */
-
- build_append_byte(notify, 0x7B); /* AndOp */
- build_append_byte(notify, 0x68); /* Arg0Op */
- build_append_int(notify, 0x1U << i);
- build_append_byte(notify, 0x00); /* NullName */
- build_append_byte(notify, 0x86); /* NotifyOp */
- build_append_nameseg(notify, "S%.02X", PCI_DEVFN(i, 0));
- build_append_byte(notify, 0x69); /* Arg1Op */
-
- /* Pack it up */
- build_package(notify, op, 0);
-
- build_append_array(method, notify);
-
- build_free_array(notify);
- }
-
- build_append_and_cleanup_method(bus_table, method);
+ aml_append(parent_scope, notify_method);
}
/* Append PCNT method to notify about events on local and child buses.
* Add unconditionally for root since DSDT expects it.
*/
- if (bus_hotplug_support || child->notify_table->len || !bus->parent_dev) {
- method = build_alloc_method("PCNT", 0);
-
- /* If bus supports hotplug select it and notify about local events */
- if (bsel) {
- build_append_byte(method, 0x70); /* StoreOp */
- build_append_int(method, qint_get_int(qobject_to_qint(bsel)));
- build_append_nameseg(method, "BNUM");
- build_append_nameseg(method, "DVNT");
- build_append_nameseg(method, "PCIU");
- build_append_int(method, 1); /* Device Check */
- build_append_nameseg(method, "DVNT");
- build_append_nameseg(method, "PCID");
- build_append_int(method, 3); /* Eject Request */
- }
-
- /* Notify about child bus events in any case */
- build_append_array(method, child->notify_table);
-
- build_append_and_cleanup_method(bus_table, method);
+ method = aml_method("PCNT", 0);
- /* Append description of child buses */
- build_append_array(bus_table, child->device_table);
-
- /* Pack it up */
- if (bus->parent_dev) {
- build_extop_package(bus_table, op);
- } else {
- build_package(bus_table, op, 0);
- }
-
- /* Append our bus description to parent table */
- build_append_array(parent->device_table, bus_table);
-
- /* Also tell parent how to notify us, invoking PCNT method.
- * At the moment this is not needed for root as we have a single root.
- */
- if (bus->parent_dev) {
- build_append_byte(parent->notify_table, '^'); /* ParentPrefixChar */
- build_append_byte(parent->notify_table, 0x2E); /* DualNamePrefix */
- build_append_nameseg(parent->notify_table, "S%.02X",
- bus->parent_dev->devfn);
- build_append_nameseg(parent->notify_table, "PCNT");
- }
+ /* If bus supports hotplug select it and notify about local events */
+ if (bsel) {
+ int64_t bsel_val = qint_get_int(qobject_to_qint(bsel));
+ aml_append(method, aml_store(aml_int(bsel_val), aml_name("BNUM")));
+ aml_append(method,
+ aml_call2("DVNT", aml_name("PCIU"), aml_int(1) /* Device Check */)
+ );
+ aml_append(method,
+ aml_call2("DVNT", aml_name("PCID"), aml_int(3)/* Eject Request */)
+ );
}
- qobject_decref(bsel);
- build_free_array(bus_table);
- build_pci_bus_state_cleanup(child);
- g_free(child);
-}
-
-static void patch_pci_windows(PcPciInfo *pci, uint8_t *start, unsigned size)
-{
- ACPI_BUILD_SET_LE(start, size, acpi_pci32_start[0], 32, pci->w32.begin);
-
- ACPI_BUILD_SET_LE(start, size, acpi_pci32_end[0], 32, pci->w32.end - 1);
+ /* Notify about child bus events in any case */
+ if (pcihp_bridge_en) {
+ QLIST_FOREACH(sec, &bus->child, sibling) {
+ int32_t devfn = sec->parent_dev->devfn;
- if (pci->w64.end || pci->w64.begin) {
- ACPI_BUILD_SET_LE(start, size, acpi_pci64_valid[0], 8, 1);
- ACPI_BUILD_SET_LE(start, size, acpi_pci64_start[0], 64, pci->w64.begin);
- ACPI_BUILD_SET_LE(start, size, acpi_pci64_end[0], 64, pci->w64.end - 1);
- ACPI_BUILD_SET_LE(start, size, acpi_pci64_length[0], 64, pci->w64.end - pci->w64.begin);
- } else {
- ACPI_BUILD_SET_LE(start, size, acpi_pci64_valid[0], 8, 0);
+ aml_append(method, aml_name("^S%.02X.PCNT", devfn));
+ }
}
+ aml_append(parent_scope, method);
}
static void
@@ -1077,112 +658,337 @@ build_ssdt(GArray *table_data, GArray *linker,
MachineState *machine = MACHINE(qdev_get_machine());
uint32_t nr_mem = machine->ram_slots;
unsigned acpi_cpus = guest_info->apic_id_limit;
- int ssdt_start = table_data->len;
- uint8_t *ssdt_ptr;
+ Aml *ssdt, *sb_scope, *scope, *pkg, *dev, *method, *crs, *field, *ifctx;
int i;
+ ssdt = init_aml_allocator();
/* The current AML generator can cover the APIC ID range [0..255],
* inclusive, for VCPU hotplug. */
QEMU_BUILD_BUG_ON(ACPI_CPU_HOTPLUG_ID_LIMIT > 256);
g_assert(acpi_cpus <= ACPI_CPU_HOTPLUG_ID_LIMIT);
- /* Copy header and patch values in the S3_ / S4_ / S5_ packages */
- ssdt_ptr = acpi_data_push(table_data, sizeof(ssdp_misc_aml));
- memcpy(ssdt_ptr, ssdp_misc_aml, sizeof(ssdp_misc_aml));
- if (pm->s3_disabled) {
- ssdt_ptr[acpi_s3_name[0]] = 'X';
+ /* Reserve space for header */
+ acpi_data_push(ssdt->buf, sizeof(AcpiTableHeader));
+
+ scope = aml_scope("\\_SB.PCI0");
+ /* build PCI0._CRS */
+ crs = aml_resource_template();
+ aml_append(crs,
+ aml_word_bus_number(aml_min_fixed, aml_max_fixed, aml_pos_decode,
+ 0x0000, 0x0000, 0x00FF, 0x0000, 0x0100));
+ aml_append(crs, aml_io(aml_decode16, 0x0CF8, 0x0CF8, 0x01, 0x08));
+
+ aml_append(crs,
+ aml_word_io(aml_min_fixed, aml_max_fixed,
+ aml_pos_decode, aml_entire_range,
+ 0x0000, 0x0000, 0x0CF7, 0x0000, 0x0CF8));
+ aml_append(crs,
+ aml_word_io(aml_min_fixed, aml_max_fixed,
+ aml_pos_decode, aml_entire_range,
+ 0x0000, 0x0D00, 0xFFFF, 0x0000, 0xF300));
+ aml_append(crs,
+ aml_dword_memory(aml_pos_decode, aml_min_fixed, aml_max_fixed,
+ aml_cacheable, aml_ReadWrite,
+ 0, 0x000A0000, 0x000BFFFF, 0, 0x00020000));
+ aml_append(crs,
+ aml_dword_memory(aml_pos_decode, aml_min_fixed, aml_max_fixed,
+ aml_non_cacheable, aml_ReadWrite,
+ 0, pci->w32.begin, pci->w32.end - 1, 0,
+ pci->w32.end - pci->w32.begin));
+ if (pci->w64.begin) {
+ aml_append(crs,
+ aml_qword_memory(aml_pos_decode, aml_min_fixed, aml_max_fixed,
+ aml_cacheable, aml_ReadWrite,
+ 0, pci->w64.begin, pci->w64.end - 1, 0,
+ pci->w64.end - pci->w64.begin));
}
- if (pm->s4_disabled) {
- ssdt_ptr[acpi_s4_name[0]] = 'X';
- } else {
- ssdt_ptr[acpi_s4_pkg[0] + 1] = ssdt_ptr[acpi_s4_pkg[0] + 3] =
- pm->s4_val;
+ aml_append(scope, aml_name_decl("_CRS", crs));
+
+ /* reserve GPE0 block resources */
+ dev = aml_device("GPE0");
+ aml_append(dev, aml_name_decl("_HID", aml_string("PNP0A06")));
+ aml_append(dev, aml_name_decl("_UID", aml_string("GPE0 resources")));
+ /* device present, functioning, decoding, not shown in UI */
+ aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
+ crs = aml_resource_template();
+ aml_append(crs,
+ aml_io(aml_decode16, pm->gpe0_blk, pm->gpe0_blk, 1, pm->gpe0_blk_len)
+ );
+ aml_append(dev, aml_name_decl("_CRS", crs));
+ aml_append(scope, dev);
+
+ /* reserve PCIHP resources */
+ if (pm->pcihp_io_len) {
+ dev = aml_device("PHPR");
+ aml_append(dev, aml_name_decl("_HID", aml_string("PNP0A06")));
+ aml_append(dev,
+ aml_name_decl("_UID", aml_string("PCI Hotplug resources")));
+ /* device present, functioning, decoding, not shown in UI */
+ aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
+ crs = aml_resource_template();
+ aml_append(crs,
+ aml_io(aml_decode16, pm->pcihp_io_base, pm->pcihp_io_base, 1,
+ pm->pcihp_io_len)
+ );
+ aml_append(dev, aml_name_decl("_CRS", crs));
+ aml_append(scope, dev);
+ }
+ aml_append(ssdt, scope);
+
+ /* create S3_ / S4_ / S5_ packages if necessary */
+ scope = aml_scope("\\");
+ if (!pm->s3_disabled) {
+ pkg = aml_package(4);
+ aml_append(pkg, aml_int(1)); /* PM1a_CNT.SLP_TYP */
+ aml_append(pkg, aml_int(1)); /* PM1b_CNT.SLP_TYP, FIXME: not impl. */
+ aml_append(pkg, aml_int(0)); /* reserved */
+ aml_append(pkg, aml_int(0)); /* reserved */
+ aml_append(scope, aml_name_decl("_S3", pkg));
}
- patch_pci_windows(pci, ssdt_ptr, sizeof(ssdp_misc_aml));
+ if (!pm->s4_disabled) {
+ pkg = aml_package(4);
+ aml_append(pkg, aml_int(pm->s4_val)); /* PM1a_CNT.SLP_TYP */
+ /* PM1b_CNT.SLP_TYP, FIXME: not impl. */
+ aml_append(pkg, aml_int(pm->s4_val));
+ aml_append(pkg, aml_int(0)); /* reserved */
+ aml_append(pkg, aml_int(0)); /* reserved */
+ aml_append(scope, aml_name_decl("_S4", pkg));
+ }
- ACPI_BUILD_SET_LE(ssdt_ptr, sizeof(ssdp_misc_aml),
- ssdt_isa_pest[0], 16, misc->pvpanic_port);
+ pkg = aml_package(4);
+ aml_append(pkg, aml_int(0)); /* PM1a_CNT.SLP_TYP */
+ aml_append(pkg, aml_int(0)); /* PM1b_CNT.SLP_TYP not impl. */
+ aml_append(pkg, aml_int(0)); /* reserved */
+ aml_append(pkg, aml_int(0)); /* reserved */
+ aml_append(scope, aml_name_decl("_S5", pkg));
+ aml_append(ssdt, scope);
+
+ if (misc->applesmc_io_base) {
+ scope = aml_scope("\\_SB.PCI0.ISA");
+ dev = aml_device("SMC");
+
+ aml_append(dev, aml_name_decl("_HID", aml_eisaid("APP0001")));
+ /* device present, functioning, decoding, not shown in UI */
+ aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
+
+ crs = aml_resource_template();
+ aml_append(crs,
+ aml_io(aml_decode16, misc->applesmc_io_base, misc->applesmc_io_base,
+ 0x01, APPLESMC_MAX_DATA_LENGTH)
+ );
+ aml_append(crs, aml_irq_no_flags(6));
+ aml_append(dev, aml_name_decl("_CRS", crs));
+
+ aml_append(scope, dev);
+ aml_append(ssdt, scope);
+ }
- ACPI_BUILD_SET_LE(ssdt_ptr, sizeof(ssdp_misc_aml),
- ssdt_mctrl_nr_slots[0], 32, nr_mem);
+ if (misc->pvpanic_port) {
+ scope = aml_scope("\\_SB.PCI0.ISA");
- {
- GArray *sb_scope = build_alloc_array();
- uint8_t op = 0x10; /* ScopeOp */
+ dev = aml_device("PEVR");
+ aml_append(dev, aml_name_decl("_HID", aml_string("QEMU0002")));
+
+ crs = aml_resource_template();
+ aml_append(crs,
+ aml_io(aml_decode16, misc->pvpanic_port, misc->pvpanic_port, 1, 1)
+ );
+ aml_append(dev, aml_name_decl("_CRS", crs));
- build_append_nameseg(sb_scope, "_SB");
+ aml_append(dev, aml_operation_region("PEOR", aml_system_io,
+ misc->pvpanic_port, 1));
+ field = aml_field("PEOR", aml_byte_acc);
+ aml_append(field, aml_named_field("PEPT", 8));
+ aml_append(dev, field);
+
+ method = aml_method("RDPT", 0);
+ aml_append(method, aml_store(aml_name("PEPT"), aml_local(0)));
+ aml_append(method, aml_return(aml_local(0)));
+ aml_append(dev, method);
+
+ method = aml_method("WRPT", 1);
+ aml_append(method, aml_store(aml_arg(0), aml_name("PEPT")));
+ aml_append(dev, method);
+
+ aml_append(scope, dev);
+ aml_append(ssdt, scope);
+ }
+
+ sb_scope = aml_scope("_SB");
+ {
+ /* create PCI0.PRES device and its _CRS to reserve CPU hotplug MMIO */
+ dev = aml_device("PCI0." stringify(CPU_HOTPLUG_RESOURCE_DEVICE));
+ aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A06")));
+ aml_append(dev,
+ aml_name_decl("_UID", aml_string("CPU Hotplug resources"))
+ );
+ /* device present, functioning, decoding, not shown in UI */
+ aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
+ crs = aml_resource_template();
+ aml_append(crs,
+ aml_io(aml_decode16, pm->cpu_hp_io_base, pm->cpu_hp_io_base, 1,
+ pm->cpu_hp_io_len)
+ );
+ aml_append(dev, aml_name_decl("_CRS", crs));
+ aml_append(sb_scope, dev);
+ /* declare CPU hotplug MMIO region and PRS field to access it */
+ aml_append(sb_scope, aml_operation_region(
+ "PRST", aml_system_io, pm->cpu_hp_io_base, pm->cpu_hp_io_len));
+ field = aml_field("PRST", aml_byte_acc);
+ aml_append(field, aml_named_field("PRS", 256));
+ aml_append(sb_scope, field);
/* build Processor object for each processor */
for (i = 0; i < acpi_cpus; i++) {
- uint8_t *proc = acpi_data_push(sb_scope, ACPI_PROC_SIZEOF);
- memcpy(proc, ACPI_PROC_AML, ACPI_PROC_SIZEOF);
- proc[ACPI_PROC_OFFSET_CPUHEX] = acpi_get_hex(i >> 4);
- proc[ACPI_PROC_OFFSET_CPUHEX+1] = acpi_get_hex(i);
- proc[ACPI_PROC_OFFSET_CPUID1] = i;
- proc[ACPI_PROC_OFFSET_CPUID2] = i;
+ dev = aml_processor(i, 0, 0, "CP%.02X", i);
+
+ method = aml_method("_MAT", 0);
+ aml_append(method, aml_return(aml_call1("CPMA", aml_int(i))));
+ aml_append(dev, method);
+
+ method = aml_method("_STA", 0);
+ aml_append(method, aml_return(aml_call1("CPST", aml_int(i))));
+ aml_append(dev, method);
+
+ method = aml_method("_EJ0", 1);
+ aml_append(method,
+ aml_return(aml_call2("CPEJ", aml_int(i), aml_arg(0)))
+ );
+ aml_append(dev, method);
+
+ aml_append(sb_scope, dev);
}
/* build this code:
* Method(NTFY, 2) {If (LEqual(Arg0, 0x00)) {Notify(CP00, Arg1)} ...}
*/
/* Arg0 = Processor ID = APIC ID */
- build_append_notify_method(sb_scope, "NTFY", "CP%0.02X", acpi_cpus);
-
- /* build "Name(CPON, Package() { One, One, ..., Zero, Zero, ... })" */
- build_append_byte(sb_scope, 0x08); /* NameOp */
- build_append_nameseg(sb_scope, "CPON");
-
- {
- GArray *package = build_alloc_array();
- uint8_t op;
-
- /*
- * Note: The ability to create variable-sized packages was first introduced in ACPI 2.0. ACPI 1.0 only
- * allowed fixed-size packages with up to 255 elements.
- * Windows guests up to win2k8 fail when VarPackageOp is used.
- */
- if (acpi_cpus <= 255) {
- op = 0x12; /* PackageOp */
- build_append_byte(package, acpi_cpus); /* NumElements */
- } else {
- op = 0x13; /* VarPackageOp */
- build_append_int(package, acpi_cpus); /* VarNumElements */
- }
-
- for (i = 0; i < acpi_cpus; i++) {
- uint8_t b = test_bit(i, cpu->found_cpus) ? 0x01 : 0x00;
- build_append_byte(package, b);
- }
-
- build_package(package, op, 2);
- build_append_array(sb_scope, package);
- build_free_array(package);
+ method = aml_method("NTFY", 2);
+ for (i = 0; i < acpi_cpus; i++) {
+ ifctx = aml_if(aml_equal(aml_arg(0), aml_int(i)));
+ aml_append(ifctx,
+ aml_notify(aml_name("CP%.02X", i), aml_arg(1))
+ );
+ aml_append(method, ifctx);
}
+ aml_append(sb_scope, method);
+
+ /* build "Name(CPON, Package() { One, One, ..., Zero, Zero, ... })"
+ *
+ * Note: The ability to create variable-sized packages was first
+ * introduced in ACPI 2.0. ACPI 1.0 only allowed fixed-size packages
+ * ith up to 255 elements. Windows guests up to win2k8 fail when
+ * VarPackageOp is used.
+ */
+ pkg = acpi_cpus <= 255 ? aml_package(acpi_cpus) :
+ aml_varpackage(acpi_cpus);
- if (nr_mem) {
- assert(nr_mem <= ACPI_MAX_RAM_SLOTS);
- /* build memory devices */
- for (i = 0; i < nr_mem; i++) {
- char id[3];
- uint8_t *mem = acpi_data_push(sb_scope, ACPI_MEM_SIZEOF);
-
- snprintf(id, sizeof(id), "%02X", i);
- memcpy(mem, ACPI_MEM_AML, ACPI_MEM_SIZEOF);
- memcpy(mem + ACPI_MEM_OFFSET_HEX, id, 2);
- memcpy(mem + ACPI_MEM_OFFSET_ID, id, 2);
- }
+ for (i = 0; i < acpi_cpus; i++) {
+ uint8_t b = test_bit(i, cpu->found_cpus) ? 0x01 : 0x00;
+ aml_append(pkg, aml_int(b));
+ }
+ aml_append(sb_scope, aml_name_decl("CPON", pkg));
+
+ /* build memory devices */
+ assert(nr_mem <= ACPI_MAX_RAM_SLOTS);
+ scope = aml_scope("\\_SB.PCI0." stringify(MEMORY_HOTPLUG_DEVICE));
+ aml_append(scope,
+ aml_name_decl(stringify(MEMORY_SLOTS_NUMBER), aml_int(nr_mem))
+ );
+
+ crs = aml_resource_template();
+ aml_append(crs,
+ aml_io(aml_decode16, pm->mem_hp_io_base, pm->mem_hp_io_base, 0,
+ pm->mem_hp_io_len)
+ );
+ aml_append(scope, aml_name_decl("_CRS", crs));
+
+ aml_append(scope, aml_operation_region(
+ stringify(MEMORY_HOTPLUG_IO_REGION), aml_system_io,
+ pm->mem_hp_io_base, pm->mem_hp_io_len)
+ );
+
+ field = aml_field(stringify(MEMORY_HOTPLUG_IO_REGION), aml_dword_acc);
+ aml_append(field, /* read only */
+ aml_named_field(stringify(MEMORY_SLOT_ADDR_LOW), 32));
+ aml_append(field, /* read only */
+ aml_named_field(stringify(MEMORY_SLOT_ADDR_HIGH), 32));
+ aml_append(field, /* read only */
+ aml_named_field(stringify(MEMORY_SLOT_SIZE_LOW), 32));
+ aml_append(field, /* read only */
+ aml_named_field(stringify(MEMORY_SLOT_SIZE_HIGH), 32));
+ aml_append(field, /* read only */
+ aml_named_field(stringify(MEMORY_SLOT_PROXIMITY), 32));
+ aml_append(scope, field);
+
+ field = aml_field(stringify(MEMORY_HOTPLUG_IO_REGION), aml_byte_acc);
+ aml_append(field, aml_reserved_field(160 /* bits, Offset(20) */));
+ aml_append(field, /* 1 if enabled, read only */
+ aml_named_field(stringify(MEMORY_SLOT_ENABLED), 1));
+ aml_append(field,
+ /*(read) 1 if has a insert event. (write) 1 to clear event */
+ aml_named_field(stringify(MEMORY_SLOT_INSERT_EVENT), 1));
+ aml_append(scope, field);
+
+ field = aml_field(stringify(MEMORY_HOTPLUG_IO_REGION), aml_dword_acc);
+ aml_append(field, /* DIMM selector, write only */
+ aml_named_field(stringify(MEMORY_SLOT_SLECTOR), 32));
+ aml_append(field, /* _OST event code, write only */
+ aml_named_field(stringify(MEMORY_SLOT_OST_EVENT), 32));
+ aml_append(field, /* _OST status code, write only */
+ aml_named_field(stringify(MEMORY_SLOT_OST_STATUS), 32));
+ aml_append(scope, field);
+
+ aml_append(sb_scope, scope);
+
+ for (i = 0; i < nr_mem; i++) {
+ #define BASEPATH "\\_SB.PCI0." stringify(MEMORY_HOTPLUG_DEVICE) "."
+ const char *s;
+
+ dev = aml_device("MP%02X", i);
+ aml_append(dev, aml_name_decl("_UID", aml_string("0x%02X", i)));
+ aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0C80")));
+
+ method = aml_method("_CRS", 0);
+ s = BASEPATH stringify(MEMORY_SLOT_CRS_METHOD);
+ aml_append(method, aml_return(aml_call1(s, aml_name("_UID"))));
+ aml_append(dev, method);
+
+ method = aml_method("_STA", 0);
+ s = BASEPATH stringify(MEMORY_SLOT_STATUS_METHOD);
+ aml_append(method, aml_return(aml_call1(s, aml_name("_UID"))));
+ aml_append(dev, method);
+
+ method = aml_method("_PXM", 0);
+ s = BASEPATH stringify(MEMORY_SLOT_PROXIMITY_METHOD);
+ aml_append(method, aml_return(aml_call1(s, aml_name("_UID"))));
+ aml_append(dev, method);
+
+ method = aml_method("_OST", 3);
+ s = BASEPATH stringify(MEMORY_SLOT_OST_METHOD);
+ aml_append(method, aml_return(aml_call4(
+ s, aml_name("_UID"), aml_arg(0), aml_arg(1), aml_arg(2)
+ )));
+ aml_append(dev, method);
+
+ aml_append(sb_scope, dev);
+ }
- /* build Method(MEMORY_SLOT_NOTIFY_METHOD, 2) {
- * If (LEqual(Arg0, 0x00)) {Notify(MP00, Arg1)} ...
- */
- build_append_notify_method(sb_scope,
- stringify(MEMORY_SLOT_NOTIFY_METHOD),
- "MP%0.02X", nr_mem);
+ /* build Method(MEMORY_SLOT_NOTIFY_METHOD, 2) {
+ * If (LEqual(Arg0, 0x00)) {Notify(MP00, Arg1)} ...
+ */
+ method = aml_method(stringify(MEMORY_SLOT_NOTIFY_METHOD), 2);
+ for (i = 0; i < nr_mem; i++) {
+ ifctx = aml_if(aml_equal(aml_arg(0), aml_int(i)));
+ aml_append(ifctx,
+ aml_notify(aml_name("MP%.02X", i), aml_arg(1))
+ );
+ aml_append(method, ifctx);
}
+ aml_append(sb_scope, method);
{
- AcpiBuildPciBusHotplugState hotplug_state;
Object *pci_host;
PCIBus *bus = NULL;
bool ambiguous;
@@ -1192,26 +998,22 @@ build_ssdt(GArray *table_data, GArray *linker,
bus = PCI_HOST_BRIDGE(pci_host)->bus;
}
- build_pci_bus_state_init(&hotplug_state, NULL, pm->pcihp_bridge_en);
-
if (bus) {
+ Aml *scope = aml_scope("PCI0");
/* Scan all PCI buses. Generate tables to support hotplug. */
- pci_for_each_bus_depth_first(bus, build_pci_bus_begin,
- build_pci_bus_end, &hotplug_state);
+ build_append_pci_bus_devices(scope, bus, pm->pcihp_bridge_en);
+ aml_append(sb_scope, scope);
}
-
- build_append_array(sb_scope, hotplug_state.device_table);
- build_pci_bus_state_cleanup(&hotplug_state);
}
-
- build_package(sb_scope, op, 3);
- build_append_array(table_data, sb_scope);
- build_free_array(sb_scope);
+ aml_append(ssdt, sb_scope);
}
+ /* copy AML table into ACPI tables blob and patch header there */
+ g_array_append_vals(table_data, ssdt->buf->data, ssdt->buf->len);
build_header(linker, table_data,
- (void *)(table_data->data + ssdt_start),
- "SSDT", table_data->len - ssdt_start, 1);
+ (void *)(table_data->data + table_data->len - ssdt->buf->len),
+ "SSDT", ssdt->buf->len, 1);
+ free_aml_allocator();
}
static void
@@ -1513,7 +1315,7 @@ static inline void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre)
{
void *linker_data = bios_linker_loader_cleanup(tables->linker);
g_free(linker_data);
- g_array_free(tables->rsdp, mfre);
+ g_array_free(tables->rsdp, true);
g_array_free(tables->table_data, true);
g_array_free(tables->tcpalog, mfre);
}
@@ -1522,10 +1324,12 @@ typedef
struct AcpiBuildState {
/* Copy of table in RAM (for patching). */
ram_addr_t table_ram;
- uint32_t table_size;
/* Is table patched? */
uint8_t patched;
PcGuestInfo *guest_info;
+ void *rsdp;
+ ram_addr_t rsdp_ram;
+ ram_addr_t linker_ram;
} AcpiBuildState;
static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg)
@@ -1574,6 +1378,7 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
PcPciInfo pci;
uint8_t *u;
size_t aml_len = 0;
+ GArray *tables_blob = tables->table_data;
acpi_get_cpu_info(&cpu);
acpi_get_pm_info(&pm);
@@ -1594,74 +1399,72 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
* We place it first since it's the only table that has alignment
* requirements.
*/
- facs = tables->table_data->len;
- build_facs(tables->table_data, tables->linker, guest_info);
+ facs = tables_blob->len;
+ build_facs(tables_blob, tables->linker, guest_info);
/* DSDT is pointed to by FADT */
- dsdt = tables->table_data->len;
- build_dsdt(tables->table_data, tables->linker, &misc);
+ dsdt = tables_blob->len;
+ build_dsdt(tables_blob, tables->linker, &misc);
/* Count the size of the DSDT and SSDT, we will need it for legacy
* sizing of ACPI tables.
*/
- aml_len += tables->table_data->len - dsdt;
+ aml_len += tables_blob->len - dsdt;
/* ACPI tables pointed to by RSDT */
- acpi_add_table(table_offsets, tables->table_data);
- build_fadt(tables->table_data, tables->linker, &pm, facs, dsdt);
+ acpi_add_table(table_offsets, tables_blob);
+ build_fadt(tables_blob, tables->linker, &pm, facs, dsdt);
- ssdt = tables->table_data->len;
- acpi_add_table(table_offsets, tables->table_data);
- build_ssdt(tables->table_data, tables->linker, &cpu, &pm, &misc, &pci,
+ ssdt = tables_blob->len;
+ acpi_add_table(table_offsets, tables_blob);
+ build_ssdt(tables_blob, tables->linker, &cpu, &pm, &misc, &pci,
guest_info);
- aml_len += tables->table_data->len - ssdt;
+ aml_len += tables_blob->len - ssdt;
- acpi_add_table(table_offsets, tables->table_data);
- build_madt(tables->table_data, tables->linker, &cpu, guest_info);
+ acpi_add_table(table_offsets, tables_blob);
+ build_madt(tables_blob, tables->linker, &cpu, guest_info);
if (misc.has_hpet) {
- acpi_add_table(table_offsets, tables->table_data);
- build_hpet(tables->table_data, tables->linker);
+ acpi_add_table(table_offsets, tables_blob);
+ build_hpet(tables_blob, tables->linker);
}
if (misc.has_tpm) {
- acpi_add_table(table_offsets, tables->table_data);
- build_tpm_tcpa(tables->table_data, tables->linker, tables->tcpalog);
+ acpi_add_table(table_offsets, tables_blob);
+ build_tpm_tcpa(tables_blob, tables->linker, tables->tcpalog);
- acpi_add_table(table_offsets, tables->table_data);
- build_tpm_ssdt(tables->table_data, tables->linker);
+ acpi_add_table(table_offsets, tables_blob);
+ build_tpm_ssdt(tables_blob, tables->linker);
}
if (guest_info->numa_nodes) {
- acpi_add_table(table_offsets, tables->table_data);
- build_srat(tables->table_data, tables->linker, guest_info);
+ acpi_add_table(table_offsets, tables_blob);
+ build_srat(tables_blob, tables->linker, guest_info);
}
if (acpi_get_mcfg(&mcfg)) {
- acpi_add_table(table_offsets, tables->table_data);
- build_mcfg_q35(tables->table_data, tables->linker, &mcfg);
+ acpi_add_table(table_offsets, tables_blob);
+ build_mcfg_q35(tables_blob, tables->linker, &mcfg);
}
if (acpi_has_iommu()) {
- acpi_add_table(table_offsets, tables->table_data);
- build_dmar_q35(tables->table_data, tables->linker);
+ acpi_add_table(table_offsets, tables_blob);
+ build_dmar_q35(tables_blob, tables->linker);
}
/* Add tables supplied by user (if any) */
for (u = acpi_table_first(); u; u = acpi_table_next(u)) {
unsigned len = acpi_table_len(u);
- acpi_add_table(table_offsets, tables->table_data);
- g_array_append_vals(tables->table_data, u, len);
+ acpi_add_table(table_offsets, tables_blob);
+ g_array_append_vals(tables_blob, u, len);
}
/* RSDT is pointed to by RSDP */
- rsdt = tables->table_data->len;
- build_rsdt(tables->table_data, tables->linker, table_offsets);
+ rsdt = tables_blob->len;
+ build_rsdt(tables_blob, tables->linker, table_offsets);
/* RSDP is in FSEG memory, so allocate it separately */
build_rsdp(tables->rsdp, tables->linker, rsdt);
/* We'll expose it all to Guest so we want to reduce
* chance of size changes.
- * RSDP is small so it's easy to keep it immutable, no need to
- * bother with alignment.
*
* We used to align the tables to 4k, but of course this would
* too simple to be enough. 4k turned out to be too small an
@@ -1685,23 +1488,23 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
guest_info->legacy_acpi_table_size +
ACPI_BUILD_LEGACY_CPU_AML_SIZE * max_cpus;
int legacy_table_size =
- ROUND_UP(tables->table_data->len - aml_len + legacy_aml_len,
+ ROUND_UP(tables_blob->len - aml_len + legacy_aml_len,
ACPI_BUILD_ALIGN_SIZE);
- if (tables->table_data->len > legacy_table_size) {
+ if (tables_blob->len > legacy_table_size) {
/* Should happen only with PCI bridges and -M pc-i440fx-2.0. */
error_report("Warning: migration may not work.");
}
- g_array_set_size(tables->table_data, legacy_table_size);
+ g_array_set_size(tables_blob, legacy_table_size);
} else {
/* Make sure we have a buffer in case we need to resize the tables. */
- if (tables->table_data->len > ACPI_BUILD_TABLE_SIZE / 2) {
+ if (tables_blob->len > ACPI_BUILD_TABLE_SIZE / 2) {
/* As of QEMU 2.1, this fires with 160 VCPUs and 255 memory slots. */
error_report("Warning: ACPI tables are larger than 64k.");
error_report("Warning: migration may not work.");
error_report("Warning: please remove CPUs, NUMA nodes, "
"memory slots or PCI bridges.");
}
- acpi_align_size(tables->table_data, ACPI_BUILD_TABLE_SIZE);
+ acpi_align_size(tables_blob, ACPI_BUILD_TABLE_SIZE);
}
acpi_align_size(tables->linker, ACPI_BUILD_ALIGN_SIZE);
@@ -1710,6 +1513,17 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
g_array_free(table_offsets, true);
}
+static void acpi_ram_update(ram_addr_t ram, GArray *data)
+{
+ uint32_t size = acpi_data_len(data);
+
+ /* Make sure RAM size is correct - in case it got changed e.g. by migration */
+ qemu_ram_resize(ram, size, &error_abort);
+
+ memcpy(qemu_get_ram_ptr(ram), data->data, size);
+ cpu_physical_memory_set_dirty_range_nocode(ram, size);
+}
+
static void acpi_build_update(void *build_opaque, uint32_t offset)
{
AcpiBuildState *build_state = build_opaque;
@@ -1725,18 +1539,15 @@ static void acpi_build_update(void *build_opaque, uint32_t offset)
acpi_build(build_state->guest_info, &tables);
- assert(acpi_data_len(tables.table_data) == build_state->table_size);
-
- /* Make sure RAM size is correct - in case it got changed by migration */
- qemu_ram_resize(build_state->table_ram, build_state->table_size,
- &error_abort);
+ acpi_ram_update(build_state->table_ram, tables.table_data);
- memcpy(qemu_get_ram_ptr(build_state->table_ram), tables.table_data->data,
- build_state->table_size);
-
- cpu_physical_memory_set_dirty_range_nocode(build_state->table_ram,
- build_state->table_size);
+ if (build_state->rsdp) {
+ memcpy(build_state->rsdp, tables.rsdp->data, acpi_data_len(tables.rsdp));
+ } else {
+ acpi_ram_update(build_state->rsdp_ram, tables.rsdp);
+ }
+ acpi_ram_update(build_state->linker_ram, tables.linker);
acpi_build_tables_cleanup(&tables, true);
}
@@ -1797,19 +1608,31 @@ void acpi_setup(PcGuestInfo *guest_info)
ACPI_BUILD_TABLE_FILE,
ACPI_BUILD_TABLE_MAX_SIZE);
assert(build_state->table_ram != RAM_ADDR_MAX);
- build_state->table_size = acpi_data_len(tables.table_data);
- acpi_add_rom_blob(NULL, tables.linker, "etc/table-loader", 0);
+ build_state->linker_ram =
+ acpi_add_rom_blob(build_state, tables.linker, "etc/table-loader", 0);
fw_cfg_add_file(guest_info->fw_cfg, ACPI_BUILD_TPMLOG_FILE,
tables.tcpalog->data, acpi_data_len(tables.tcpalog));
- /*
- * RSDP is small so it's easy to keep it immutable, no need to
- * bother with ROM blobs.
- */
- fw_cfg_add_file(guest_info->fw_cfg, ACPI_BUILD_RSDP_FILE,
- tables.rsdp->data, acpi_data_len(tables.rsdp));
+ if (!guest_info->rsdp_in_ram) {
+ /*
+ * Keep for compatibility with old machine types.
+ * Though RSDP is small, its contents isn't immutable, so
+ * we'll update it along with the rest of tables on guest access.
+ */
+ uint32_t rsdp_size = acpi_data_len(tables.rsdp);
+
+ build_state->rsdp = g_memdup(tables.rsdp->data, rsdp_size);
+ fw_cfg_add_file_callback(guest_info->fw_cfg, ACPI_BUILD_RSDP_FILE,
+ acpi_build_update, build_state,
+ build_state->rsdp, rsdp_size);
+ build_state->rsdp_ram = (ram_addr_t)-1;
+ } else {
+ build_state->rsdp = NULL;
+ build_state->rsdp_ram = acpi_add_rom_blob(build_state, tables.rsdp,
+ ACPI_BUILD_RSDP_FILE, 0);
+ }
qemu_register_reset(acpi_build_reset, build_state);
acpi_build_reset(build_state);
diff --git a/hw/i386/acpi-dsdt-cpu-hotplug.dsl b/hw/i386/acpi-dsdt-cpu-hotplug.dsl
index 268d870990..1aff74627f 100644
--- a/hw/i386/acpi-dsdt-cpu-hotplug.dsl
+++ b/hw/i386/acpi-dsdt-cpu-hotplug.dsl
@@ -16,12 +16,12 @@
/****************************************************************
* CPU hotplug
****************************************************************/
-#define CPU_HOTPLUG_RESOURCE_DEVICE PRES
Scope(\_SB) {
/* Objects filled in by run-time generated SSDT */
External(NTFY, MethodObj)
External(CPON, PkgObj)
+ External(PRS, FieldUnitObj)
/* Methods called by run-time generated SSDT Processor objects */
Method(CPMA, 1, NotSerialized) {
@@ -54,10 +54,6 @@ Scope(\_SB) {
}
#define CPU_STATUS_LEN ACPI_GPE_PROC_LEN
- OperationRegion(PRST, SystemIO, CPU_STATUS_BASE, CPU_STATUS_LEN)
- Field(PRST, ByteAcc, NoLock, Preserve) {
- PRS, 256
- }
Method(PRSC, 0) {
// Local5 = active cpu bitmap
Store(PRS, Local5)
@@ -91,15 +87,4 @@ Scope(\_SB) {
Increment(Local0)
}
}
-
- Device(CPU_HOTPLUG_RESOURCE_DEVICE) {
- Name(_HID, EisaId("PNP0A06"))
- Name(_UID, "CPU hotplug resources")
-
- Name(_CRS, ResourceTemplate() {
- IO(Decode16, CPU_STATUS_BASE, CPU_STATUS_BASE, 0, CPU_STATUS_LEN)
- })
-
- Name(_STA, 0xB) /* present, functioning, decoding, not shown in UI */
- }
}
diff --git a/hw/i386/acpi-dsdt-isa.dsl b/hw/i386/acpi-dsdt-isa.dsl
index deb37de92e..89caa1649d 100644
--- a/hw/i386/acpi-dsdt-isa.dsl
+++ b/hw/i386/acpi-dsdt-isa.dsl
@@ -16,17 +16,6 @@
/* Common legacy ISA style devices. */
Scope(\_SB.PCI0.ISA) {
- Device (SMC) {
- Name(_HID, EisaId("APP0001"))
- /* _STA will be patched to 0x0B if AppleSMC is present */
- ACPI_EXTRACT_NAME_BYTE_CONST DSDT_APPLESMC_STA
- Name(_STA, 0xF0)
- Name(_CRS, ResourceTemplate () {
- IO (Decode16, 0x0300, 0x0300, 0x01, 0x20)
- IRQNoFlags() { 6 }
- })
- }
-
Device(RTC) {
Name(_HID, EisaId("PNP0B00"))
Name(_CRS, ResourceTemplate() {
diff --git a/hw/i386/acpi-dsdt-mem-hotplug.dsl b/hw/i386/acpi-dsdt-mem-hotplug.dsl
index 2a36c4799e..1e9ec39274 100644
--- a/hw/i386/acpi-dsdt-mem-hotplug.dsl
+++ b/hw/i386/acpi-dsdt-mem-hotplug.dsl
@@ -22,14 +22,16 @@
External(MEMORY_SLOTS_NUMBER, IntObj)
/* Memory hotplug IO registers */
- OperationRegion(MEMORY_HOTPLUG_IO_REGION, SystemIO,
- ACPI_MEMORY_HOTPLUG_BASE,
- ACPI_MEMORY_HOTPLUG_IO_LEN)
-
- Name(_CRS, ResourceTemplate() {
- IO(Decode16, ACPI_MEMORY_HOTPLUG_BASE, ACPI_MEMORY_HOTPLUG_BASE,
- 0, ACPI_MEMORY_HOTPLUG_IO_LEN, IO)
- })
+ External(MEMORY_SLOT_ADDR_LOW, FieldUnitObj) // read only
+ External(MEMORY_SLOT_ADDR_HIGH, FieldUnitObj) // read only
+ External(MEMORY_SLOT_SIZE_LOW, FieldUnitObj) // read only
+ External(MEMORY_SLOT_SIZE_HIGH, FieldUnitObj) // read only
+ External(MEMORY_SLOT_PROXIMITY, FieldUnitObj) // read only
+ External(MEMORY_SLOT_ENABLED, FieldUnitObj) // 1 if enabled, read only
+ External(MEMORY_SLOT_INSERT_EVENT, FieldUnitObj) // (read) 1 if has a insert event. (write) 1 to clear event
+ External(MEMORY_SLOT_SLECTOR, FieldUnitObj) // DIMM selector, write only
+ External(MEMORY_SLOT_OST_EVENT, FieldUnitObj) // _OST event code, write only
+ External(MEMORY_SLOT_OST_STATUS, FieldUnitObj) // _OST status code, write only
Method(_STA, 0) {
If (LEqual(MEMORY_SLOTS_NUMBER, Zero)) {
@@ -39,25 +41,7 @@
Return(0xB)
}
- Field(MEMORY_HOTPLUG_IO_REGION, DWordAcc, NoLock, Preserve) {
- MEMORY_SLOT_ADDR_LOW, 32, // read only
- MEMORY_SLOT_ADDR_HIGH, 32, // read only
- MEMORY_SLOT_SIZE_LOW, 32, // read only
- MEMORY_SLOT_SIZE_HIGH, 32, // read only
- MEMORY_SLOT_PROXIMITY, 32, // read only
- }
- Field(MEMORY_HOTPLUG_IO_REGION, ByteAcc, NoLock, Preserve) {
- Offset(20),
- MEMORY_SLOT_ENABLED, 1, // 1 if enabled, read only
- MEMORY_SLOT_INSERT_EVENT, 1, // (read) 1 if has a insert event. (write) 1 to clear event
- }
-
Mutex (MEMORY_SLOT_LOCK, 0)
- Field (MEMORY_HOTPLUG_IO_REGION, DWordAcc, NoLock, Preserve) {
- MEMORY_SLOT_SLECTOR, 32, // DIMM selector, write only
- MEMORY_SLOT_OST_EVENT, 32, // _OST event code, write only
- MEMORY_SLOT_OST_STATUS, 32, // _OST status code, write only
- }
Method(MEMORY_SLOT_SCAN_METHOD, 0) {
If (LEqual(MEMORY_SLOTS_NUMBER, Zero)) {
diff --git a/hw/i386/acpi-dsdt-pci-crs.dsl b/hw/i386/acpi-dsdt-pci-crs.dsl
deleted file mode 100644
index 4648e90366..0000000000
--- a/hw/i386/acpi-dsdt-pci-crs.dsl
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * 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/>.
- */
-
-/* PCI CRS (current resources) definition. */
-Scope(\_SB.PCI0) {
-
- Name(CRES, ResourceTemplate() {
- WordBusNumber(ResourceProducer, MinFixed, MaxFixed, PosDecode,
- 0x0000, // Address Space Granularity
- 0x0000, // Address Range Minimum
- 0x00FF, // Address Range Maximum
- 0x0000, // Address Translation Offset
- 0x0100, // Address Length
- ,, )
- IO(Decode16,
- 0x0CF8, // Address Range Minimum
- 0x0CF8, // Address Range Maximum
- 0x01, // Address Alignment
- 0x08, // Address Length
- )
- BOARD_SPECIFIC_PCI_RESOURSES
- DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
- 0x00000000, // Address Space Granularity
- 0x000A0000, // Address Range Minimum
- 0x000BFFFF, // Address Range Maximum
- 0x00000000, // Address Translation Offset
- 0x00020000, // Address Length
- ,, , AddressRangeMemory, TypeStatic)
- DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite,
- 0x00000000, // Address Space Granularity
- 0xE0000000, // Address Range Minimum
- 0xFEBFFFFF, // Address Range Maximum
- 0x00000000, // Address Translation Offset
- 0x1EC00000, // Address Length
- ,, PW32, AddressRangeMemory, TypeStatic)
- })
-
- Name(CR64, ResourceTemplate() {
- QWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
- 0x00000000, // Address Space Granularity
- 0x8000000000, // Address Range Minimum
- 0xFFFFFFFFFF, // Address Range Maximum
- 0x00000000, // Address Translation Offset
- 0x8000000000, // Address Length
- ,, PW64, AddressRangeMemory, TypeStatic)
- })
-
- Method(_CRS, 0) {
- /* Fields provided by dynamically created ssdt */
- External(P0S, IntObj)
- External(P0E, IntObj)
- External(P1V, IntObj)
- External(P1S, BuffObj)
- External(P1E, BuffObj)
- External(P1L, BuffObj)
-
- /* fixup 32bit pci io window */
- CreateDWordField(CRES, \_SB.PCI0.PW32._MIN, PS32)
- CreateDWordField(CRES, \_SB.PCI0.PW32._MAX, PE32)
- CreateDWordField(CRES, \_SB.PCI0.PW32._LEN, PL32)
- Store(P0S, PS32)
- Store(P0E, PE32)
- Store(Add(Subtract(P0E, P0S), 1), PL32)
-
- If (LEqual(P1V, Zero)) {
- Return (CRES)
- }
-
- /* fixup 64bit pci io window */
- CreateQWordField(CR64, \_SB.PCI0.PW64._MIN, PS64)
- CreateQWordField(CR64, \_SB.PCI0.PW64._MAX, PE64)
- CreateQWordField(CR64, \_SB.PCI0.PW64._LEN, PL64)
- Store(P1S, PS64)
- Store(P1E, PE64)
- Store(P1L, PL64)
- /* add window and return result */
- ConcatenateResTemplate(CRES, CR64, Local0)
- Return (Local0)
- }
-}
diff --git a/hw/i386/acpi-dsdt.dsl b/hw/i386/acpi-dsdt.dsl
index a611e07ec8..a2d84ecf8f 100644
--- a/hw/i386/acpi-dsdt.dsl
+++ b/hw/i386/acpi-dsdt.dsl
@@ -31,50 +31,6 @@ DefinitionBlock (
#include "acpi-dsdt-dbug.dsl"
-
-/****************************************************************
- * PCI Bus definition
- ****************************************************************/
-#define BOARD_SPECIFIC_PCI_RESOURSES \
- WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, \
- 0x0000, \
- 0x0000, \
- 0x0CF7, \
- 0x0000, \
- 0x0CF8, \
- ,, , TypeStatic) \
- WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, \
- 0x0000, \
- 0x0D00, \
- 0xADFF, \
- 0x0000, \
- 0xA100, \
- ,, , TypeStatic) \
- /* 0xae00-0xae0e hole for PCI hotplug, hw/acpi/piix4.c:PCI_HOTPLUG_ADDR */ \
- WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, \
- 0x0000, \
- 0xAE0F, \
- 0xAEFF, \
- 0x0000, \
- 0x00F1, \
- ,, , TypeStatic) \
- /* 0xaf00-0xaf1f hole for CPU hotplug, hw/acpi/piix4.c:PIIX4_PROC_BASE */ \
- WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, \
- 0x0000, \
- 0xAF20, \
- 0xAFDF, \
- 0x0000, \
- 0x00C0, \
- ,, , TypeStatic) \
- /* 0xafe0-0xafe3 hole for ACPI.GPE0, hw/acpi/piix4.c:GPE_BASE */ \
- WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, \
- 0x0000, \
- 0xAFE4, \
- 0xFFFF, \
- 0x0000, \
- 0x501C, \
- ,, , TypeStatic)
-
Scope(\_SB) {
Device(PCI0) {
Name(_HID, EisaId("PNP0A03"))
@@ -85,7 +41,6 @@ DefinitionBlock (
}
}
-#include "acpi-dsdt-pci-crs.dsl"
#include "acpi-dsdt-hpet.dsl"
@@ -130,7 +85,6 @@ DefinitionBlock (
}
}
-#define DSDT_APPLESMC_STA piix_dsdt_applesmc_sta
#include "acpi-dsdt-isa.dsl"
diff --git a/hw/i386/acpi-dsdt.hex.generated b/hw/i386/acpi-dsdt.hex.generated
index 498b194a0c..ecaa4a5480 100644
--- a/hw/i386/acpi-dsdt.hex.generated
+++ b/hw/i386/acpi-dsdt.hex.generated
@@ -3,12 +3,12 @@ static unsigned char AcpiDsdtAmlCode[] = {
0x53,
0x44,
0x54,
-0x25,
-0xe,
+0x9a,
+0xb,
0x0,
0x0,
0x1,
-0x6c,
+0xf8,
0x42,
0x58,
0x50,
@@ -145,405 +145,6 @@ static unsigned char AcpiDsdtAmlCode[] = {
0x44,
0x1,
0x10,
-0x4e,
-0x18,
-0x2e,
-0x5f,
-0x53,
-0x42,
-0x5f,
-0x50,
-0x43,
-0x49,
-0x30,
-0x8,
-0x43,
-0x52,
-0x45,
-0x53,
-0x11,
-0x42,
-0xa,
-0xa,
-0x9e,
-0x88,
-0xd,
-0x0,
-0x2,
-0xc,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0xff,
-0x0,
-0x0,
-0x0,
-0x0,
-0x1,
-0x47,
-0x1,
-0xf8,
-0xc,
-0xf8,
-0xc,
-0x1,
-0x8,
-0x88,
-0xd,
-0x0,
-0x1,
-0xc,
-0x3,
-0x0,
-0x0,
-0x0,
-0x0,
-0xf7,
-0xc,
-0x0,
-0x0,
-0xf8,
-0xc,
-0x88,
-0xd,
-0x0,
-0x1,
-0xc,
-0x3,
-0x0,
-0x0,
-0x0,
-0xd,
-0xff,
-0xad,
-0x0,
-0x0,
-0x0,
-0xa1,
-0x88,
-0xd,
-0x0,
-0x1,
-0xc,
-0x3,
-0x0,
-0x0,
-0xf,
-0xae,
-0xff,
-0xae,
-0x0,
-0x0,
-0xf1,
-0x0,
-0x88,
-0xd,
-0x0,
-0x1,
-0xc,
-0x3,
-0x0,
-0x0,
-0x20,
-0xaf,
-0xdf,
-0xaf,
-0x0,
-0x0,
-0xc0,
-0x0,
-0x88,
-0xd,
-0x0,
-0x1,
-0xc,
-0x3,
-0x0,
-0x0,
-0xe4,
-0xaf,
-0xff,
-0xff,
-0x0,
-0x0,
-0x1c,
-0x50,
-0x87,
-0x17,
-0x0,
-0x0,
-0xc,
-0x3,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0xa,
-0x0,
-0xff,
-0xff,
-0xb,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x2,
-0x0,
-0x87,
-0x17,
-0x0,
-0x0,
-0xc,
-0x1,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0xe0,
-0xff,
-0xff,
-0xbf,
-0xfe,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0xc0,
-0x1e,
-0x79,
-0x0,
-0x8,
-0x43,
-0x52,
-0x36,
-0x34,
-0x11,
-0x33,
-0xa,
-0x30,
-0x8a,
-0x2b,
-0x0,
-0x0,
-0xc,
-0x3,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x80,
-0x0,
-0x0,
-0x0,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x80,
-0x0,
-0x0,
-0x0,
-0x79,
-0x0,
-0x14,
-0x41,
-0xa,
-0x5f,
-0x43,
-0x52,
-0x53,
-0x0,
-0x8a,
-0x43,
-0x52,
-0x45,
-0x53,
-0xa,
-0x8c,
-0x50,
-0x53,
-0x33,
-0x32,
-0x8a,
-0x43,
-0x52,
-0x45,
-0x53,
-0xa,
-0x90,
-0x50,
-0x45,
-0x33,
-0x32,
-0x8a,
-0x43,
-0x52,
-0x45,
-0x53,
-0xa,
-0x98,
-0x50,
-0x4c,
-0x33,
-0x32,
-0x70,
-0x50,
-0x30,
-0x53,
-0x5f,
-0x50,
-0x53,
-0x33,
-0x32,
-0x70,
-0x50,
-0x30,
-0x45,
-0x5f,
-0x50,
-0x45,
-0x33,
-0x32,
-0x70,
-0x72,
-0x74,
-0x50,
-0x30,
-0x45,
-0x5f,
-0x50,
-0x30,
-0x53,
-0x5f,
-0x0,
-0x1,
-0x0,
-0x50,
-0x4c,
-0x33,
-0x32,
-0xa0,
-0xc,
-0x93,
-0x50,
-0x31,
-0x56,
-0x5f,
-0x0,
-0xa4,
-0x43,
-0x52,
-0x45,
-0x53,
-0x8f,
-0x43,
-0x52,
-0x36,
-0x34,
-0xa,
-0xe,
-0x50,
-0x53,
-0x36,
-0x34,
-0x8f,
-0x43,
-0x52,
-0x36,
-0x34,
-0xa,
-0x16,
-0x50,
-0x45,
-0x36,
-0x34,
-0x8f,
-0x43,
-0x52,
-0x36,
-0x34,
-0xa,
-0x26,
-0x50,
-0x4c,
-0x36,
-0x34,
-0x70,
-0x50,
-0x31,
-0x53,
-0x5f,
-0x50,
-0x53,
-0x36,
-0x34,
-0x70,
-0x50,
-0x31,
-0x45,
-0x5f,
-0x50,
-0x45,
-0x36,
-0x34,
-0x70,
-0x50,
-0x31,
-0x4c,
-0x5f,
-0x50,
-0x4c,
-0x36,
-0x34,
-0x84,
-0x43,
-0x52,
-0x45,
-0x53,
-0x43,
-0x52,
-0x36,
-0x34,
-0x60,
-0xa4,
-0x60,
-0x10,
0x4d,
0x8,
0x5f,
@@ -811,8 +412,8 @@ static unsigned char AcpiDsdtAmlCode[] = {
0x4e,
0x1,
0x10,
-0x4a,
-0x1e,
+0x4c,
+0x1b,
0x2f,
0x3,
0x5f,
@@ -829,52 +430,6 @@ static unsigned char AcpiDsdtAmlCode[] = {
0x5f,
0x5b,
0x82,
-0x2c,
-0x53,
-0x4d,
-0x43,
-0x5f,
-0x8,
-0x5f,
-0x48,
-0x49,
-0x44,
-0xc,
-0x6,
-0x10,
-0x0,
-0x1,
-0x8,
-0x5f,
-0x53,
-0x54,
-0x41,
-0xa,
-0xf0,
-0x8,
-0x5f,
-0x43,
-0x52,
-0x53,
-0x11,
-0x10,
-0xa,
-0xd,
-0x47,
-0x1,
-0x0,
-0x3,
-0x0,
-0x3,
-0x1,
-0x20,
-0x22,
-0x40,
-0x0,
-0x79,
-0x0,
-0x5b,
-0x82,
0x2d,
0x52,
0x54,
@@ -2318,8 +1873,8 @@ static unsigned char AcpiDsdtAmlCode[] = {
0x53,
0x1,
0x10,
-0x4f,
-0x12,
+0x4d,
+0xc,
0x5f,
0x53,
0x42,
@@ -2416,32 +1971,6 @@ static unsigned char AcpiDsdtAmlCode[] = {
0x22,
0xa,
0xc8,
-0x5b,
-0x80,
-0x50,
-0x52,
-0x53,
-0x54,
-0x1,
-0xb,
-0x0,
-0xaf,
-0xa,
-0x20,
-0x5b,
-0x81,
-0xc,
-0x50,
-0x52,
-0x53,
-0x54,
-0x1,
-0x50,
-0x52,
-0x53,
-0x5f,
-0x40,
-0x10,
0x14,
0x4a,
0x6,
@@ -2549,81 +2078,9 @@ static unsigned char AcpiDsdtAmlCode[] = {
0x3,
0x75,
0x60,
-0x5b,
-0x82,
-0x46,
-0x4,
-0x50,
-0x52,
-0x45,
-0x53,
-0x8,
-0x5f,
-0x48,
-0x49,
-0x44,
-0xc,
-0x41,
-0xd0,
-0xa,
-0x6,
-0x8,
-0x5f,
-0x55,
-0x49,
-0x44,
-0xd,
-0x43,
-0x50,
-0x55,
-0x20,
-0x68,
-0x6f,
-0x74,
-0x70,
-0x6c,
-0x75,
-0x67,
-0x20,
-0x72,
-0x65,
-0x73,
-0x6f,
-0x75,
-0x72,
-0x63,
-0x65,
-0x73,
-0x0,
-0x8,
-0x5f,
-0x43,
-0x52,
-0x53,
-0x11,
-0xd,
-0xa,
-0xa,
-0x47,
-0x1,
-0x0,
-0xaf,
-0x0,
-0xaf,
-0x0,
-0x20,
-0x79,
-0x0,
-0x8,
-0x5f,
-0x53,
-0x54,
-0x41,
-0xa,
-0xb,
0x10,
-0x40,
-0x31,
+0x44,
+0x2a,
0x2e,
0x5f,
0x53,
@@ -2635,8 +2092,8 @@ static unsigned char AcpiDsdtAmlCode[] = {
0x30,
0x5b,
0x82,
-0x43,
-0x30,
+0x47,
+0x29,
0x4d,
0x48,
0x50,
@@ -2686,37 +2143,6 @@ static unsigned char AcpiDsdtAmlCode[] = {
0x65,
0x73,
0x0,
-0x5b,
-0x80,
-0x48,
-0x50,
-0x4d,
-0x52,
-0x1,
-0xb,
-0x0,
-0xa,
-0xa,
-0x18,
-0x8,
-0x5f,
-0x43,
-0x52,
-0x53,
-0x11,
-0xd,
-0xa,
-0xa,
-0x47,
-0x1,
-0x0,
-0xa,
-0x0,
-0xa,
-0x0,
-0x18,
-0x79,
-0x0,
0x14,
0x13,
0x5f,
@@ -2738,89 +2164,12 @@ static unsigned char AcpiDsdtAmlCode[] = {
0xa,
0xb,
0x5b,
-0x81,
-0x1f,
-0x48,
-0x50,
-0x4d,
-0x52,
-0x3,
-0x4d,
-0x52,
-0x42,
-0x4c,
-0x20,
-0x4d,
-0x52,
-0x42,
-0x48,
-0x20,
-0x4d,
-0x52,
-0x4c,
-0x4c,
-0x20,
-0x4d,
-0x52,
-0x4c,
-0x48,
-0x20,
-0x4d,
-0x50,
-0x58,
-0x5f,
-0x20,
-0x5b,
-0x81,
-0x13,
-0x48,
-0x50,
-0x4d,
-0x52,
-0x1,
-0x0,
-0x40,
-0xa,
-0x4d,
-0x45,
-0x53,
-0x5f,
-0x1,
-0x4d,
-0x49,
-0x4e,
-0x53,
-0x1,
-0x5b,
0x1,
0x4d,
0x4c,
0x43,
0x4b,
0x0,
-0x5b,
-0x81,
-0x15,
-0x48,
-0x50,
-0x4d,
-0x52,
-0x3,
-0x4d,
-0x53,
-0x45,
-0x4c,
-0x20,
-0x4d,
-0x4f,
-0x45,
-0x56,
-0x20,
-0x4d,
-0x4f,
-0x53,
-0x43,
-0x20,
0x14,
0x4a,
0x4,
@@ -3621,6 +2970,3 @@ static unsigned char AcpiDsdtAmlCode[] = {
0x46,
0x0
};
-static unsigned short piix_dsdt_applesmc_sta[] = {
-0x353
-};
diff --git a/hw/i386/kvm/pci-assign.c b/hw/i386/kvm/pci-assign.c
index bd92c69916..9db7c77605 100644
--- a/hw/i386/kvm/pci-assign.c
+++ b/hw/i386/kvm/pci-assign.c
@@ -1738,7 +1738,7 @@ static void reset_assigned_device(DeviceState *dev)
assigned_dev_pci_write_config(pci_dev, PCI_COMMAND, 0, 1);
}
-static int assigned_initfn(struct PCIDevice *pci_dev)
+static void assigned_realize(struct PCIDevice *pci_dev, Error **errp)
{
AssignedDevice *dev = DO_UPCAST(AssignedDevice, dev, pci_dev);
uint8_t e_intx;
@@ -1821,7 +1821,7 @@ static int assigned_initfn(struct PCIDevice *pci_dev)
assigned_dev_load_option_rom(dev);
- return 0;
+ return;
assigned_out:
deassign_device(dev);
@@ -1831,9 +1831,7 @@ out:
exit_with_error:
assert(local_err);
- qerror_report_err(local_err);
- error_free(local_err);
- return -1;
+ error_propagate(errp, local_err);
}
static void assigned_exitfn(struct PCIDevice *pci_dev)
@@ -1869,7 +1867,7 @@ static void assign_class_init(ObjectClass *klass, void *data)
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
- k->init = assigned_initfn;
+ k->realize = assigned_realize;
k->exit = assigned_exitfn;
k->config_read = assigned_dev_pci_read_config;
k->config_write = assigned_dev_pci_write_config;
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index b229856a26..79eaad5fec 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1241,6 +1241,13 @@ FWCfgState *pc_memory_init(MachineState *machine,
exit(EXIT_FAILURE);
}
+ if (QEMU_ALIGN_UP(machine->maxram_size,
+ TARGET_PAGE_SIZE) != machine->maxram_size) {
+ error_report("maximum memory size must by aligned to multiple of "
+ "%d bytes", TARGET_PAGE_SIZE);
+ exit(EXIT_FAILURE);
+ }
+
pcms->hotplug_memory_base =
ROUND_UP(0x100000000ULL + above_4g_mem_size, 1ULL << 30);
@@ -1666,6 +1673,20 @@ static void pc_machine_device_plug_cb(HotplugHandler *hotplug_dev,
}
}
+static void pc_machine_device_unplug_request_cb(HotplugHandler *hotplug_dev,
+ DeviceState *dev, Error **errp)
+{
+ error_setg(errp, "acpi: device unplug request for not supported device"
+ " type: %s", object_get_typename(OBJECT(dev)));
+}
+
+static void pc_machine_device_unplug_cb(HotplugHandler *hotplug_dev,
+ DeviceState *dev, Error **errp)
+{
+ error_setg(errp, "acpi: device unplug for not supported device"
+ " type: %s", object_get_typename(OBJECT(dev)));
+}
+
static HotplugHandler *pc_get_hotpug_handler(MachineState *machine,
DeviceState *dev)
{
@@ -1795,6 +1816,8 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
pcmc->get_hotplug_handler = mc->get_hotplug_handler;
mc->get_hotplug_handler = pc_get_hotpug_handler;
hc->plug = pc_machine_device_plug_cb;
+ hc->unplug_request = pc_machine_device_unplug_request_cb;
+ hc->unplug = pc_machine_device_unplug_cb;
}
static const TypeInfo pc_machine_info = {
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index de75cf0e87..8eab4ba94d 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -60,6 +60,7 @@ static const int ide_iobase2[MAX_IDE_BUS] = { 0x3f6, 0x376 };
static const int ide_irq[MAX_IDE_BUS] = { 14, 15 };
static bool has_acpi_build = true;
+static bool rsdp_in_ram = true;
static int legacy_acpi_table_size;
static bool smbios_defaults = true;
static bool smbios_legacy_mode;
@@ -168,6 +169,7 @@ static void pc_init1(MachineState *machine,
guest_info->isapc_ram_fw = !pci_enabled;
guest_info->has_reserved_memory = has_reserved_memory;
+ guest_info->rsdp_in_ram = rsdp_in_ram;
if (smbios_defaults) {
MachineClass *mc = MACHINE_GET_CLASS(machine);
@@ -310,6 +312,7 @@ static void pc_init_pci(MachineState *machine)
static void pc_compat_2_2(MachineState *machine)
{
+ rsdp_in_ram = false;
x86_cpu_compat_set_features("kvm64", FEAT_1_EDX, 0, CPUID_VME);
x86_cpu_compat_set_features("kvm32", FEAT_1_EDX, 0, CPUID_VME);
x86_cpu_compat_set_features("Conroe", FEAT_1_EDX, 0, CPUID_VME);
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 63027ee76b..c0f21fe725 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -50,6 +50,7 @@
#define MAX_SATA_PORTS 6
static bool has_acpi_build = true;
+static bool rsdp_in_ram = true;
static bool smbios_defaults = true;
static bool smbios_legacy_mode;
static bool smbios_uuid_encoded = true;
@@ -154,6 +155,7 @@ static void pc_q35_init(MachineState *machine)
guest_info->isapc_ram_fw = false;
guest_info->has_acpi_build = has_acpi_build;
guest_info->has_reserved_memory = has_reserved_memory;
+ guest_info->rsdp_in_ram = rsdp_in_ram;
/* Migration was not supported in 2.0 for Q35, so do not bother
* with this hack (see hw/i386/acpi-build.c).
@@ -289,6 +291,7 @@ static void pc_q35_init(MachineState *machine)
static void pc_compat_2_2(MachineState *machine)
{
+ rsdp_in_ram = false;
x86_cpu_compat_set_features("kvm64", FEAT_1_EDX, 0, CPUID_VME);
x86_cpu_compat_set_features("kvm32", FEAT_1_EDX, 0, CPUID_VME);
x86_cpu_compat_set_features("Conroe", FEAT_1_EDX, 0, CPUID_VME);
diff --git a/hw/i386/q35-acpi-dsdt.dsl b/hw/i386/q35-acpi-dsdt.dsl
index e1cee5d89a..16eaca3fae 100644
--- a/hw/i386/q35-acpi-dsdt.dsl
+++ b/hw/i386/q35-acpi-dsdt.dsl
@@ -48,23 +48,6 @@ DefinitionBlock (
/****************************************************************
* PCI Bus definition
****************************************************************/
-#define BOARD_SPECIFIC_PCI_RESOURSES \
- WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, \
- 0x0000, \
- 0x0000, \
- 0x0CD7, \
- 0x0000, \
- 0x0CD8, \
- ,, , TypeStatic) \
- /* 0xcd8-0xcf7 hole for CPU hotplug, hw/acpi/ich9.c:ICH9_PROC_BASE */ \
- WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, \
- 0x0000, \
- 0x0D00, \
- 0xFFFF, \
- 0x0000, \
- 0xF300, \
- ,, , TypeStatic)
-
Scope(\_SB) {
Device(PCI0) {
Name(_HID, EisaId("PNP0A08"))
@@ -131,7 +114,6 @@ DefinitionBlock (
}
}
-#include "acpi-dsdt-pci-crs.dsl"
#include "acpi-dsdt-hpet.dsl"
@@ -168,7 +150,6 @@ DefinitionBlock (
}
}
-#define DSDT_APPLESMC_STA q35_dsdt_applesmc_sta
#include "acpi-dsdt-isa.dsl"
diff --git a/hw/i386/q35-acpi-dsdt.hex.generated b/hw/i386/q35-acpi-dsdt.hex.generated
index 0d5b133150..ed9a2cc8e0 100644
--- a/hw/i386/q35-acpi-dsdt.hex.generated
+++ b/hw/i386/q35-acpi-dsdt.hex.generated
@@ -3,12 +3,12 @@ static unsigned char Q35AcpiDsdtAmlCode[] = {
0x53,
0x44,
0x54,
-0x13,
-0x20,
+0xb8,
+0x1d,
0x0,
0x0,
0x1,
-0x0,
+0x35,
0x42,
0x58,
0x50,
@@ -360,357 +360,6 @@ static unsigned char Q35AcpiDsdtAmlCode[] = {
0xa4,
0x6b,
0x10,
-0x4e,
-0x15,
-0x2e,
-0x5f,
-0x53,
-0x42,
-0x5f,
-0x50,
-0x43,
-0x49,
-0x30,
-0x8,
-0x43,
-0x52,
-0x45,
-0x53,
-0x11,
-0x42,
-0x7,
-0xa,
-0x6e,
-0x88,
-0xd,
-0x0,
-0x2,
-0xc,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0xff,
-0x0,
-0x0,
-0x0,
-0x0,
-0x1,
-0x47,
-0x1,
-0xf8,
-0xc,
-0xf8,
-0xc,
-0x1,
-0x8,
-0x88,
-0xd,
-0x0,
-0x1,
-0xc,
-0x3,
-0x0,
-0x0,
-0x0,
-0x0,
-0xd7,
-0xc,
-0x0,
-0x0,
-0xd8,
-0xc,
-0x88,
-0xd,
-0x0,
-0x1,
-0xc,
-0x3,
-0x0,
-0x0,
-0x0,
-0xd,
-0xff,
-0xff,
-0x0,
-0x0,
-0x0,
-0xf3,
-0x87,
-0x17,
-0x0,
-0x0,
-0xc,
-0x3,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0xa,
-0x0,
-0xff,
-0xff,
-0xb,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x2,
-0x0,
-0x87,
-0x17,
-0x0,
-0x0,
-0xc,
-0x1,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0xe0,
-0xff,
-0xff,
-0xbf,
-0xfe,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0xc0,
-0x1e,
-0x79,
-0x0,
-0x8,
-0x43,
-0x52,
-0x36,
-0x34,
-0x11,
-0x33,
-0xa,
-0x30,
-0x8a,
-0x2b,
-0x0,
-0x0,
-0xc,
-0x3,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x80,
-0x0,
-0x0,
-0x0,
-0xff,
-0xff,
-0xff,
-0xff,
-0xff,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x80,
-0x0,
-0x0,
-0x0,
-0x79,
-0x0,
-0x14,
-0x41,
-0xa,
-0x5f,
-0x43,
-0x52,
-0x53,
-0x0,
-0x8a,
-0x43,
-0x52,
-0x45,
-0x53,
-0xa,
-0x5c,
-0x50,
-0x53,
-0x33,
-0x32,
-0x8a,
-0x43,
-0x52,
-0x45,
-0x53,
-0xa,
-0x60,
-0x50,
-0x45,
-0x33,
-0x32,
-0x8a,
-0x43,
-0x52,
-0x45,
-0x53,
-0xa,
-0x68,
-0x50,
-0x4c,
-0x33,
-0x32,
-0x70,
-0x50,
-0x30,
-0x53,
-0x5f,
-0x50,
-0x53,
-0x33,
-0x32,
-0x70,
-0x50,
-0x30,
-0x45,
-0x5f,
-0x50,
-0x45,
-0x33,
-0x32,
-0x70,
-0x72,
-0x74,
-0x50,
-0x30,
-0x45,
-0x5f,
-0x50,
-0x30,
-0x53,
-0x5f,
-0x0,
-0x1,
-0x0,
-0x50,
-0x4c,
-0x33,
-0x32,
-0xa0,
-0xc,
-0x93,
-0x50,
-0x31,
-0x56,
-0x5f,
-0x0,
-0xa4,
-0x43,
-0x52,
-0x45,
-0x53,
-0x8f,
-0x43,
-0x52,
-0x36,
-0x34,
-0xa,
-0xe,
-0x50,
-0x53,
-0x36,
-0x34,
-0x8f,
-0x43,
-0x52,
-0x36,
-0x34,
-0xa,
-0x16,
-0x50,
-0x45,
-0x36,
-0x34,
-0x8f,
-0x43,
-0x52,
-0x36,
-0x34,
-0xa,
-0x26,
-0x50,
-0x4c,
-0x36,
-0x34,
-0x70,
-0x50,
-0x31,
-0x53,
-0x5f,
-0x50,
-0x53,
-0x36,
-0x34,
-0x70,
-0x50,
-0x31,
-0x45,
-0x5f,
-0x50,
-0x45,
-0x36,
-0x34,
-0x70,
-0x50,
-0x31,
-0x4c,
-0x5f,
-0x50,
-0x4c,
-0x36,
-0x34,
-0x84,
-0x43,
-0x52,
-0x45,
-0x53,
-0x43,
-0x52,
-0x36,
-0x34,
-0x60,
-0xa4,
-0x60,
-0x10,
0x4d,
0x8,
0x5f,
@@ -978,8 +627,8 @@ static unsigned char Q35AcpiDsdtAmlCode[] = {
0x4e,
0x1,
0x10,
-0x4a,
-0x1e,
+0x4c,
+0x1b,
0x2f,
0x3,
0x5f,
@@ -996,52 +645,6 @@ static unsigned char Q35AcpiDsdtAmlCode[] = {
0x5f,
0x5b,
0x82,
-0x2c,
-0x53,
-0x4d,
-0x43,
-0x5f,
-0x8,
-0x5f,
-0x48,
-0x49,
-0x44,
-0xc,
-0x6,
-0x10,
-0x0,
-0x1,
-0x8,
-0x5f,
-0x53,
-0x54,
-0x41,
-0xa,
-0xf0,
-0x8,
-0x5f,
-0x43,
-0x52,
-0x53,
-0x11,
-0x10,
-0xa,
-0xd,
-0x47,
-0x1,
-0x0,
-0x3,
-0x0,
-0x3,
-0x1,
-0x20,
-0x22,
-0x40,
-0x0,
-0x79,
-0x0,
-0x5b,
-0x82,
0x2d,
0x52,
0x54,
@@ -6959,8 +6562,8 @@ static unsigned char Q35AcpiDsdtAmlCode[] = {
0x53,
0x1,
0x10,
-0x4f,
-0x12,
+0x4d,
+0xc,
0x5f,
0x53,
0x42,
@@ -7057,32 +6660,6 @@ static unsigned char Q35AcpiDsdtAmlCode[] = {
0x22,
0xa,
0xc8,
-0x5b,
-0x80,
-0x50,
-0x52,
-0x53,
-0x54,
-0x1,
-0xb,
-0xd8,
-0xc,
-0xa,
-0x20,
-0x5b,
-0x81,
-0xc,
-0x50,
-0x52,
-0x53,
-0x54,
-0x1,
-0x50,
-0x52,
-0x53,
-0x5f,
-0x40,
-0x10,
0x14,
0x4a,
0x6,
@@ -7190,81 +6767,9 @@ static unsigned char Q35AcpiDsdtAmlCode[] = {
0x3,
0x75,
0x60,
-0x5b,
-0x82,
-0x46,
-0x4,
-0x50,
-0x52,
-0x45,
-0x53,
-0x8,
-0x5f,
-0x48,
-0x49,
-0x44,
-0xc,
-0x41,
-0xd0,
-0xa,
-0x6,
-0x8,
-0x5f,
-0x55,
-0x49,
-0x44,
-0xd,
-0x43,
-0x50,
-0x55,
-0x20,
-0x68,
-0x6f,
-0x74,
-0x70,
-0x6c,
-0x75,
-0x67,
-0x20,
-0x72,
-0x65,
-0x73,
-0x6f,
-0x75,
-0x72,
-0x63,
-0x65,
-0x73,
-0x0,
-0x8,
-0x5f,
-0x43,
-0x52,
-0x53,
-0x11,
-0xd,
-0xa,
-0xa,
-0x47,
-0x1,
-0xd8,
-0xc,
-0xd8,
-0xc,
-0x0,
-0x20,
-0x79,
-0x0,
-0x8,
-0x5f,
-0x53,
-0x54,
-0x41,
-0xa,
-0xb,
0x10,
-0x40,
-0x31,
+0x44,
+0x2a,
0x2e,
0x5f,
0x53,
@@ -7276,8 +6781,8 @@ static unsigned char Q35AcpiDsdtAmlCode[] = {
0x30,
0x5b,
0x82,
-0x43,
-0x30,
+0x47,
+0x29,
0x4d,
0x48,
0x50,
@@ -7327,37 +6832,6 @@ static unsigned char Q35AcpiDsdtAmlCode[] = {
0x65,
0x73,
0x0,
-0x5b,
-0x80,
-0x48,
-0x50,
-0x4d,
-0x52,
-0x1,
-0xb,
-0x0,
-0xa,
-0xa,
-0x18,
-0x8,
-0x5f,
-0x43,
-0x52,
-0x53,
-0x11,
-0xd,
-0xa,
-0xa,
-0x47,
-0x1,
-0x0,
-0xa,
-0x0,
-0xa,
-0x0,
-0x18,
-0x79,
-0x0,
0x14,
0x13,
0x5f,
@@ -7379,89 +6853,12 @@ static unsigned char Q35AcpiDsdtAmlCode[] = {
0xa,
0xb,
0x5b,
-0x81,
-0x1f,
-0x48,
-0x50,
-0x4d,
-0x52,
-0x3,
-0x4d,
-0x52,
-0x42,
-0x4c,
-0x20,
-0x4d,
-0x52,
-0x42,
-0x48,
-0x20,
-0x4d,
-0x52,
-0x4c,
-0x4c,
-0x20,
-0x4d,
-0x52,
-0x4c,
-0x48,
-0x20,
-0x4d,
-0x50,
-0x58,
-0x5f,
-0x20,
-0x5b,
-0x81,
-0x13,
-0x48,
-0x50,
-0x4d,
-0x52,
-0x1,
-0x0,
-0x40,
-0xa,
-0x4d,
-0x45,
-0x53,
-0x5f,
-0x1,
-0x4d,
-0x49,
-0x4e,
-0x53,
-0x1,
-0x5b,
0x1,
0x4d,
0x4c,
0x43,
0x4b,
0x0,
-0x5b,
-0x81,
-0x15,
-0x48,
-0x50,
-0x4d,
-0x52,
-0x3,
-0x4d,
-0x53,
-0x45,
-0x4c,
-0x20,
-0x4d,
-0x4f,
-0x45,
-0x56,
-0x20,
-0x4d,
-0x4f,
-0x53,
-0x43,
-0x20,
0x14,
0x4a,
0x4,
@@ -8211,6 +7608,3 @@ static unsigned char Q35AcpiDsdtAmlCode[] = {
0x46,
0x0
};
-static unsigned short q35_dsdt_applesmc_sta[] = {
-0x3fa
-};
diff --git a/hw/i386/ssdt-mem.dsl b/hw/i386/ssdt-mem.dsl
deleted file mode 100644
index 22ff5ddfc3..0000000000
--- a/hw/i386/ssdt-mem.dsl
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Memory hotplug ACPI DSDT static objects definitions
- *
- * Copyright ProfitBricks GmbH 2012
- * Copyright (C) 2013-2014 Red Hat Inc
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>
- */
-
-/* This file is the basis for the ssdt_mem[] variable in src/acpi.c.
- * It defines the contents of the memory device object. At
- * runtime, a dynamically generated SSDT will contain one copy of this
- * AML snippet for every possible memory device in the system. The
- * objects will be placed in the \_SB_ namespace.
- *
- * In addition to the aml code generated from this file, the
- * src/acpi.c file creates a MTFY method with an entry for each memdevice:
- * Method(MTFY, 2) {
- * If (LEqual(Arg0, 0x00)) { Notify(MP00, Arg1) }
- * If (LEqual(Arg0, 0x01)) { Notify(MP01, Arg1) }
- * ...
- * }
- */
-#include "hw/acpi/pc-hotplug.h"
-
-ACPI_EXTRACT_ALL_CODE ssdm_mem_aml
-
-DefinitionBlock ("ssdt-mem.aml", "SSDT", 0x02, "BXPC", "CSSDT", 0x1)
-{
-
- External(\_SB.PCI0.MEMORY_HOTPLUG_DEVICE.MEMORY_SLOT_CRS_METHOD, MethodObj)
- External(\_SB.PCI0.MEMORY_HOTPLUG_DEVICE.MEMORY_SLOT_STATUS_METHOD, MethodObj)
- External(\_SB.PCI0.MEMORY_HOTPLUG_DEVICE.MEMORY_SLOT_OST_METHOD, MethodObj)
- External(\_SB.PCI0.MEMORY_HOTPLUG_DEVICE.MEMORY_SLOT_PROXIMITY_METHOD, MethodObj)
-
- Scope(\_SB) {
-/* v------------------ DO NOT EDIT ------------------v */
- ACPI_EXTRACT_DEVICE_START ssdt_mem_start
- ACPI_EXTRACT_DEVICE_END ssdt_mem_end
- ACPI_EXTRACT_DEVICE_STRING ssdt_mem_name
- Device(MPAA) {
- ACPI_EXTRACT_NAME_STRING ssdt_mem_id
- Name(_UID, "0xAA")
-/* ^------------------ DO NOT EDIT ------------------^
- * Don't change the above without also updating the C code.
- */
- Name(_HID, EISAID("PNP0C80"))
-
- Method(_CRS, 0) {
- Return(\_SB.PCI0.MEMORY_HOTPLUG_DEVICE.MEMORY_SLOT_CRS_METHOD(_UID))
- }
-
- Method(_STA, 0) {
- Return(\_SB.PCI0.MEMORY_HOTPLUG_DEVICE.MEMORY_SLOT_STATUS_METHOD(_UID))
- }
-
- Method(_PXM, 0) {
- Return(\_SB.PCI0.MEMORY_HOTPLUG_DEVICE.MEMORY_SLOT_PROXIMITY_METHOD(_UID))
- }
-
- Method(_OST, 3) {
- \_SB.PCI0.MEMORY_HOTPLUG_DEVICE.MEMORY_SLOT_OST_METHOD(_UID, Arg0, Arg1, Arg2)
- }
- }
- }
-}
diff --git a/hw/i386/ssdt-mem.hex.generated b/hw/i386/ssdt-mem.hex.generated
deleted file mode 100644
index b3bfbbda09..0000000000
--- a/hw/i386/ssdt-mem.hex.generated
+++ /dev/null
@@ -1,213 +0,0 @@
-static unsigned char ssdt_mem_id[] = {
-0x35
-};
-static unsigned char ssdm_mem_aml[] = {
-0x53,
-0x53,
-0x44,
-0x54,
-0xc7,
-0x0,
-0x0,
-0x0,
-0x2,
-0x66,
-0x42,
-0x58,
-0x50,
-0x43,
-0x0,
-0x0,
-0x43,
-0x53,
-0x53,
-0x44,
-0x54,
-0x0,
-0x0,
-0x0,
-0x1,
-0x0,
-0x0,
-0x0,
-0x49,
-0x4e,
-0x54,
-0x4c,
-0x28,
-0x8,
-0x14,
-0x20,
-0x10,
-0x42,
-0xa,
-0x5c,
-0x5f,
-0x53,
-0x42,
-0x5f,
-0x5b,
-0x82,
-0x49,
-0x9,
-0x4d,
-0x50,
-0x41,
-0x41,
-0x8,
-0x5f,
-0x55,
-0x49,
-0x44,
-0xd,
-0x30,
-0x78,
-0x41,
-0x41,
-0x0,
-0x8,
-0x5f,
-0x48,
-0x49,
-0x44,
-0xc,
-0x41,
-0xd0,
-0xc,
-0x80,
-0x14,
-0x1e,
-0x5f,
-0x43,
-0x52,
-0x53,
-0x0,
-0xa4,
-0x5c,
-0x2f,
-0x4,
-0x5f,
-0x53,
-0x42,
-0x5f,
-0x50,
-0x43,
-0x49,
-0x30,
-0x4d,
-0x48,
-0x50,
-0x44,
-0x4d,
-0x43,
-0x52,
-0x53,
-0x5f,
-0x55,
-0x49,
-0x44,
-0x14,
-0x1e,
-0x5f,
-0x53,
-0x54,
-0x41,
-0x0,
-0xa4,
-0x5c,
-0x2f,
-0x4,
-0x5f,
-0x53,
-0x42,
-0x5f,
-0x50,
-0x43,
-0x49,
-0x30,
-0x4d,
-0x48,
-0x50,
-0x44,
-0x4d,
-0x52,
-0x53,
-0x54,
-0x5f,
-0x55,
-0x49,
-0x44,
-0x14,
-0x1e,
-0x5f,
-0x50,
-0x58,
-0x4d,
-0x0,
-0xa4,
-0x5c,
-0x2f,
-0x4,
-0x5f,
-0x53,
-0x42,
-0x5f,
-0x50,
-0x43,
-0x49,
-0x30,
-0x4d,
-0x48,
-0x50,
-0x44,
-0x4d,
-0x50,
-0x58,
-0x4d,
-0x5f,
-0x55,
-0x49,
-0x44,
-0x14,
-0x20,
-0x5f,
-0x4f,
-0x53,
-0x54,
-0x3,
-0x5c,
-0x2f,
-0x4,
-0x5f,
-0x53,
-0x42,
-0x5f,
-0x50,
-0x43,
-0x49,
-0x30,
-0x4d,
-0x48,
-0x50,
-0x44,
-0x4d,
-0x4f,
-0x53,
-0x54,
-0x5f,
-0x55,
-0x49,
-0x44,
-0x68,
-0x69,
-0x6a
-};
-static unsigned char ssdt_mem_start[] = {
-0x2c
-};
-static unsigned char ssdt_mem_end[] = {
-0xc7
-};
-static unsigned char ssdt_mem_name[] = {
-0x30
-};
diff --git a/hw/i386/ssdt-misc.dsl b/hw/i386/ssdt-misc.dsl
deleted file mode 100644
index 1e3baaed3d..0000000000
--- a/hw/i386/ssdt-misc.dsl
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * 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/>.
- */
-#include "hw/acpi/pc-hotplug.h"
-
-ACPI_EXTRACT_ALL_CODE ssdp_misc_aml
-
-DefinitionBlock ("ssdt-misc.aml", "SSDT", 0x01, "BXPC", "BXSSDTSUSP", 0x1)
-{
-
-/****************************************************************
- * PCI memory ranges
- ****************************************************************/
-
- Scope(\) {
- ACPI_EXTRACT_NAME_DWORD_CONST acpi_pci32_start
- Name(P0S, 0x12345678)
- ACPI_EXTRACT_NAME_DWORD_CONST acpi_pci32_end
- Name(P0E, 0x12345678)
- ACPI_EXTRACT_NAME_BYTE_CONST acpi_pci64_valid
- Name(P1V, 0x12)
- ACPI_EXTRACT_NAME_BUFFER8 acpi_pci64_start
- Name(P1S, Buffer() { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 })
- ACPI_EXTRACT_NAME_BUFFER8 acpi_pci64_end
- Name(P1E, Buffer() { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 })
- ACPI_EXTRACT_NAME_BUFFER8 acpi_pci64_length
- Name(P1L, Buffer() { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 })
- ACPI_EXTRACT_NAME_DWORD_CONST ssdt_mctrl_nr_slots
- Name(MEMORY_SLOTS_NUMBER, 0x12345678)
- }
-
-
-/****************************************************************
- * Suspend
- ****************************************************************/
-
- Scope(\) {
- /*
- * S3 (suspend-to-ram), S4 (suspend-to-disk) and S5 (power-off) type codes:
- * must match piix4 emulation.
- */
-
- ACPI_EXTRACT_NAME_STRING acpi_s3_name
- Name(_S3, Package(0x04) {
- One, /* PM1a_CNT.SLP_TYP */
- One, /* PM1b_CNT.SLP_TYP */
- Zero, /* reserved */
- Zero /* reserved */
- })
- ACPI_EXTRACT_NAME_STRING acpi_s4_name
- ACPI_EXTRACT_PKG_START acpi_s4_pkg
- Name(_S4, Package(0x04) {
- 0x2, /* PM1a_CNT.SLP_TYP */
- 0x2, /* PM1b_CNT.SLP_TYP */
- Zero, /* reserved */
- Zero /* reserved */
- })
- Name(_S5, Package(0x04) {
- Zero, /* PM1a_CNT.SLP_TYP */
- Zero, /* PM1b_CNT.SLP_TYP */
- Zero, /* reserved */
- Zero /* reserved */
- })
- }
-
- External(\_SB.PCI0, DeviceObj)
- External(\_SB.PCI0.ISA, DeviceObj)
-
- Scope(\_SB.PCI0.ISA) {
- Device(PEVT) {
- Name(_HID, "QEMU0001")
- /* PEST will be patched to be Zero if no such device */
- ACPI_EXTRACT_NAME_WORD_CONST ssdt_isa_pest
- Name(PEST, 0xFFFF)
- OperationRegion(PEOR, SystemIO, PEST, 0x01)
- Field(PEOR, ByteAcc, NoLock, Preserve) {
- PEPT, 8,
- }
-
- Method(_STA, 0, NotSerialized) {
- Store(PEST, Local0)
- If (LEqual(Local0, Zero)) {
- Return (0x00)
- } Else {
- Return (0x0F)
- }
- }
-
- Method(RDPT, 0, NotSerialized) {
- Store(PEPT, Local0)
- Return (Local0)
- }
-
- Method(WRPT, 1, NotSerialized) {
- Store(Arg0, PEPT)
- }
-
- Name(_CRS, ResourceTemplate() {
- IO(Decode16, 0x00, 0x00, 0x01, 0x01, IO)
- })
-
- CreateWordField(_CRS, IO._MIN, IOMN)
- CreateWordField(_CRS, IO._MAX, IOMX)
-
- Method(_INI, 0, NotSerialized) {
- Store(PEST, IOMN)
- Store(PEST, IOMX)
- }
- }
- }
-}
diff --git a/hw/i386/ssdt-misc.hex.generated b/hw/i386/ssdt-misc.hex.generated
deleted file mode 100644
index cbcf61dcce..0000000000
--- a/hw/i386/ssdt-misc.hex.generated
+++ /dev/null
@@ -1,399 +0,0 @@
-static unsigned char acpi_pci64_length[] = {
-0x6f
-};
-static unsigned char acpi_s4_pkg[] = {
-0x99
-};
-static unsigned char ssdt_mctrl_nr_slots[] = {
-0x7d
-};
-static unsigned char acpi_s3_name[] = {
-0x86
-};
-static unsigned char acpi_pci32_start[] = {
-0x2f
-};
-static unsigned char acpi_pci64_valid[] = {
-0x43
-};
-static unsigned char ssdp_misc_aml[] = {
-0x53,
-0x53,
-0x44,
-0x54,
-0x6c,
-0x1,
-0x0,
-0x0,
-0x1,
-0x3,
-0x42,
-0x58,
-0x50,
-0x43,
-0x0,
-0x0,
-0x42,
-0x58,
-0x53,
-0x53,
-0x44,
-0x54,
-0x53,
-0x55,
-0x1,
-0x0,
-0x0,
-0x0,
-0x49,
-0x4e,
-0x54,
-0x4c,
-0x28,
-0x8,
-0x14,
-0x20,
-0x10,
-0x4c,
-0x5,
-0x5c,
-0x0,
-0x8,
-0x50,
-0x30,
-0x53,
-0x5f,
-0xc,
-0x78,
-0x56,
-0x34,
-0x12,
-0x8,
-0x50,
-0x30,
-0x45,
-0x5f,
-0xc,
-0x78,
-0x56,
-0x34,
-0x12,
-0x8,
-0x50,
-0x31,
-0x56,
-0x5f,
-0xa,
-0x12,
-0x8,
-0x50,
-0x31,
-0x53,
-0x5f,
-0x11,
-0xb,
-0xa,
-0x8,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x8,
-0x50,
-0x31,
-0x45,
-0x5f,
-0x11,
-0xb,
-0xa,
-0x8,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x8,
-0x50,
-0x31,
-0x4c,
-0x5f,
-0x11,
-0xb,
-0xa,
-0x8,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x8,
-0x4d,
-0x44,
-0x4e,
-0x52,
-0xc,
-0x78,
-0x56,
-0x34,
-0x12,
-0x10,
-0x29,
-0x5c,
-0x0,
-0x8,
-0x5f,
-0x53,
-0x33,
-0x5f,
-0x12,
-0x6,
-0x4,
-0x1,
-0x1,
-0x0,
-0x0,
-0x8,
-0x5f,
-0x53,
-0x34,
-0x5f,
-0x12,
-0x8,
-0x4,
-0xa,
-0x2,
-0xa,
-0x2,
-0x0,
-0x0,
-0x8,
-0x5f,
-0x53,
-0x35,
-0x5f,
-0x12,
-0x6,
-0x4,
-0x0,
-0x0,
-0x0,
-0x0,
-0x10,
-0x40,
-0xc,
-0x5c,
-0x2f,
-0x3,
-0x5f,
-0x53,
-0x42,
-0x5f,
-0x50,
-0x43,
-0x49,
-0x30,
-0x49,
-0x53,
-0x41,
-0x5f,
-0x5b,
-0x82,
-0x4d,
-0xa,
-0x50,
-0x45,
-0x56,
-0x54,
-0x8,
-0x5f,
-0x48,
-0x49,
-0x44,
-0xd,
-0x51,
-0x45,
-0x4d,
-0x55,
-0x30,
-0x30,
-0x30,
-0x31,
-0x0,
-0x8,
-0x50,
-0x45,
-0x53,
-0x54,
-0xb,
-0xff,
-0xff,
-0x5b,
-0x80,
-0x50,
-0x45,
-0x4f,
-0x52,
-0x1,
-0x50,
-0x45,
-0x53,
-0x54,
-0x1,
-0x5b,
-0x81,
-0xb,
-0x50,
-0x45,
-0x4f,
-0x52,
-0x1,
-0x50,
-0x45,
-0x50,
-0x54,
-0x8,
-0x14,
-0x18,
-0x5f,
-0x53,
-0x54,
-0x41,
-0x0,
-0x70,
-0x50,
-0x45,
-0x53,
-0x54,
-0x60,
-0xa0,
-0x6,
-0x93,
-0x60,
-0x0,
-0xa4,
-0x0,
-0xa1,
-0x4,
-0xa4,
-0xa,
-0xf,
-0x14,
-0xe,
-0x52,
-0x44,
-0x50,
-0x54,
-0x0,
-0x70,
-0x50,
-0x45,
-0x50,
-0x54,
-0x60,
-0xa4,
-0x60,
-0x14,
-0xc,
-0x57,
-0x52,
-0x50,
-0x54,
-0x1,
-0x70,
-0x68,
-0x50,
-0x45,
-0x50,
-0x54,
-0x8,
-0x5f,
-0x43,
-0x52,
-0x53,
-0x11,
-0xd,
-0xa,
-0xa,
-0x47,
-0x1,
-0x0,
-0x0,
-0x0,
-0x0,
-0x1,
-0x1,
-0x79,
-0x0,
-0x8b,
-0x5f,
-0x43,
-0x52,
-0x53,
-0xa,
-0x2,
-0x49,
-0x4f,
-0x4d,
-0x4e,
-0x8b,
-0x5f,
-0x43,
-0x52,
-0x53,
-0xa,
-0x4,
-0x49,
-0x4f,
-0x4d,
-0x58,
-0x14,
-0x18,
-0x5f,
-0x49,
-0x4e,
-0x49,
-0x0,
-0x70,
-0x50,
-0x45,
-0x53,
-0x54,
-0x49,
-0x4f,
-0x4d,
-0x4e,
-0x70,
-0x50,
-0x45,
-0x53,
-0x54,
-0x49,
-0x4f,
-0x4d,
-0x58
-};
-static unsigned char ssdt_isa_pest[] = {
-0xda
-};
-static unsigned char acpi_s4_name[] = {
-0x92
-};
-static unsigned char acpi_pci64_start[] = {
-0x4d
-};
-static unsigned char acpi_pci64_end[] = {
-0x5e
-};
-static unsigned char acpi_pci32_end[] = {
-0x39
-};
diff --git a/hw/i386/ssdt-pcihp.dsl b/hw/i386/ssdt-pcihp.dsl
deleted file mode 100644
index ac91c05836..0000000000
--- a/hw/i386/ssdt-pcihp.dsl
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * 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/>.
- */
-
-ACPI_EXTRACT_ALL_CODE ssdp_pcihp_aml
-
-DefinitionBlock ("ssdt-pcihp.aml", "SSDT", 0x01, "BXPC", "BXSSDTPCIHP", 0x1)
-{
-
-/****************************************************************
- * PCI hotplug
- ****************************************************************/
-
- /* Objects supplied by DSDT */
- External(\_SB.PCI0, DeviceObj)
- External(\_SB.PCI0.PCEJ, MethodObj)
- External(BSEL, IntObj)
-
- Scope(\_SB.PCI0) {
-
- /* Bulk generated PCI hotplug devices */
- ACPI_EXTRACT_DEVICE_START ssdt_pcihp_start
- ACPI_EXTRACT_DEVICE_END ssdt_pcihp_end
- ACPI_EXTRACT_DEVICE_STRING ssdt_pcihp_name
-
- // Extract the offsets of the device name, address dword and the slot
- // name byte - we fill them in for each device.
- Device(SAA) {
- ACPI_EXTRACT_NAME_BYTE_CONST ssdt_pcihp_id
- Name(_SUN, 0xAA)
- ACPI_EXTRACT_NAME_DWORD_CONST ssdt_pcihp_adr
- Name(_ADR, 0xAA0000)
- Method(_EJ0, 1) {
- PCEJ(BSEL, _SUN)
- }
- }
-
- ACPI_EXTRACT_DEVICE_START ssdt_pcinohp_start
- ACPI_EXTRACT_DEVICE_END ssdt_pcinohp_end
- ACPI_EXTRACT_DEVICE_STRING ssdt_pcinohp_name
-
- // Extract the offsets of the device name, address dword and the slot
- // name byte - we fill them in for each device.
- Device(SBB) {
- ACPI_EXTRACT_NAME_DWORD_CONST ssdt_pcinohp_adr
- Name(_ADR, 0xAA0000)
- }
-
- ACPI_EXTRACT_DEVICE_START ssdt_pcivga_start
- ACPI_EXTRACT_DEVICE_END ssdt_pcivga_end
- ACPI_EXTRACT_DEVICE_STRING ssdt_pcivga_name
-
- // Extract the offsets of the device name, address dword and the slot
- // name byte - we fill them in for each device.
- Device(SCC) {
- ACPI_EXTRACT_NAME_DWORD_CONST ssdt_pcivga_adr
- Name(_ADR, 0xAA0000)
- Method(_S1D, 0, NotSerialized) {
- Return (0x00)
- }
- Method(_S2D, 0, NotSerialized) {
- Return (0x00)
- }
- Method(_S3D, 0, NotSerialized) {
- Return (0x00)
- }
- }
-
- ACPI_EXTRACT_DEVICE_START ssdt_pciqxl_start
- ACPI_EXTRACT_DEVICE_END ssdt_pciqxl_end
- ACPI_EXTRACT_DEVICE_STRING ssdt_pciqxl_name
-
- // Extract the offsets of the device name, address dword and the slot
- // name byte - we fill them in for each device.
- Device(SDD) {
- ACPI_EXTRACT_NAME_DWORD_CONST ssdt_pciqxl_adr
- Name(_ADR, 0xAA0000)
- Method(_S1D, 0, NotSerialized) {
- Return (0x00)
- }
- Method(_S2D, 0, NotSerialized) {
- Return (0x00)
- }
- Method(_S3D, 0, NotSerialized) {
- Return (0x03) // QXL
- }
- }
- }
-}
diff --git a/hw/i386/ssdt-pcihp.hex.generated b/hw/i386/ssdt-pcihp.hex.generated
deleted file mode 100644
index 72ffa84800..0000000000
--- a/hw/i386/ssdt-pcihp.hex.generated
+++ /dev/null
@@ -1,251 +0,0 @@
-static unsigned char ssdt_pcihp_name[] = {
-0x34
-};
-static unsigned char ssdt_pcivga_end[] = {
-0x99
-};
-static unsigned char ssdt_pcivga_name[] = {
-0x70
-};
-static unsigned char ssdt_pcihp_adr[] = {
-0x45
-};
-static unsigned char ssdt_pcinohp_end[] = {
-0x6d
-};
-static unsigned char ssdt_pcihp_end[] = {
-0x5c
-};
-static unsigned char ssdt_pciqxl_start[] = {
-0x99
-};
-static unsigned char ssdt_pcinohp_name[] = {
-0x5f
-};
-static unsigned char ssdp_pcihp_aml[] = {
-0x53,
-0x53,
-0x44,
-0x54,
-0xc6,
-0x0,
-0x0,
-0x0,
-0x1,
-0x70,
-0x42,
-0x58,
-0x50,
-0x43,
-0x0,
-0x0,
-0x42,
-0x58,
-0x53,
-0x53,
-0x44,
-0x54,
-0x50,
-0x43,
-0x1,
-0x0,
-0x0,
-0x0,
-0x49,
-0x4e,
-0x54,
-0x4c,
-0x15,
-0x11,
-0x13,
-0x20,
-0x10,
-0x41,
-0xa,
-0x5c,
-0x2e,
-0x5f,
-0x53,
-0x42,
-0x5f,
-0x50,
-0x43,
-0x49,
-0x30,
-0x5b,
-0x82,
-0x29,
-0x53,
-0x41,
-0x41,
-0x5f,
-0x8,
-0x5f,
-0x53,
-0x55,
-0x4e,
-0xa,
-0xaa,
-0x8,
-0x5f,
-0x41,
-0x44,
-0x52,
-0xc,
-0x0,
-0x0,
-0xaa,
-0x0,
-0x14,
-0x12,
-0x5f,
-0x45,
-0x4a,
-0x30,
-0x1,
-0x50,
-0x43,
-0x45,
-0x4a,
-0x42,
-0x53,
-0x45,
-0x4c,
-0x5f,
-0x53,
-0x55,
-0x4e,
-0x5b,
-0x82,
-0xf,
-0x53,
-0x42,
-0x42,
-0x5f,
-0x8,
-0x5f,
-0x41,
-0x44,
-0x52,
-0xc,
-0x0,
-0x0,
-0xaa,
-0x0,
-0x5b,
-0x82,
-0x2a,
-0x53,
-0x43,
-0x43,
-0x5f,
-0x8,
-0x5f,
-0x41,
-0x44,
-0x52,
-0xc,
-0x0,
-0x0,
-0xaa,
-0x0,
-0x14,
-0x8,
-0x5f,
-0x53,
-0x31,
-0x44,
-0x0,
-0xa4,
-0x0,
-0x14,
-0x8,
-0x5f,
-0x53,
-0x32,
-0x44,
-0x0,
-0xa4,
-0x0,
-0x14,
-0x8,
-0x5f,
-0x53,
-0x33,
-0x44,
-0x0,
-0xa4,
-0x0,
-0x5b,
-0x82,
-0x2b,
-0x53,
-0x44,
-0x44,
-0x5f,
-0x8,
-0x5f,
-0x41,
-0x44,
-0x52,
-0xc,
-0x0,
-0x0,
-0xaa,
-0x0,
-0x14,
-0x8,
-0x5f,
-0x53,
-0x31,
-0x44,
-0x0,
-0xa4,
-0x0,
-0x14,
-0x8,
-0x5f,
-0x53,
-0x32,
-0x44,
-0x0,
-0xa4,
-0x0,
-0x14,
-0x9,
-0x5f,
-0x53,
-0x33,
-0x44,
-0x0,
-0xa4,
-0xa,
-0x3
-};
-static unsigned char ssdt_pciqxl_adr[] = {
-0xa6
-};
-static unsigned char ssdt_pcinohp_adr[] = {
-0x69
-};
-static unsigned char ssdt_pcivga_adr[] = {
-0x7a
-};
-static unsigned char ssdt_pciqxl_name[] = {
-0x9c
-};
-static unsigned char ssdt_pcivga_start[] = {
-0x6d
-};
-static unsigned char ssdt_pciqxl_end[] = {
-0xc6
-};
-static unsigned char ssdt_pcihp_start[] = {
-0x31
-};
-static unsigned char ssdt_pcihp_id[] = {
-0x3e
-};
-static unsigned char ssdt_pcinohp_start[] = {
-0x5c
-};
diff --git a/hw/i386/ssdt-proc.dsl b/hw/i386/ssdt-proc.dsl
deleted file mode 100644
index 8229bfd702..0000000000
--- a/hw/i386/ssdt-proc.dsl
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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/>.
- */
-
-/* This file is the basis for the ssdt table generated in src/acpi.c.
- * It defines the contents of the per-cpu Processor() object. At
- * runtime, a dynamically generated SSDT will contain one copy of this
- * AML snippet for every possible cpu in the system. The objects will
- * be placed in the \_SB_ namespace.
- *
- * In addition to the aml code generated from this file, the
- * src/acpi.c file creates a NTFY method with an entry for each cpu:
- * Method(NTFY, 2) {
- * If (LEqual(Arg0, 0x00)) { Notify(CP00, Arg1) }
- * If (LEqual(Arg0, 0x01)) { Notify(CP01, Arg1) }
- * ...
- * }
- * and a CPON array with the list of active and inactive cpus:
- * Name(CPON, Package() { One, One, ..., Zero, Zero, ... })
- */
-
-ACPI_EXTRACT_ALL_CODE ssdp_proc_aml
-
-DefinitionBlock ("ssdt-proc.aml", "SSDT", 0x01, "BXPC", "BXSSDT", 0x1)
-{
- ACPI_EXTRACT_PROCESSOR_START ssdt_proc_start
- ACPI_EXTRACT_PROCESSOR_END ssdt_proc_end
- ACPI_EXTRACT_PROCESSOR_STRING ssdt_proc_name
- Processor(CPAA, 0xAA, 0x00000000, 0x0) {
- ACPI_EXTRACT_NAME_BYTE_CONST ssdt_proc_id
- Name(ID, 0xAA)
-/*
- * The src/acpi.c code requires the above ACP_EXTRACT tags so that it can update
- * CPAA and 0xAA with the appropriate CPU id (see
- * SD_OFFSET_CPUHEX/CPUID1/CPUID2). Don't change the above without
- * also updating the C code.
- */
- Name(_HID, "ACPI0007")
- External(CPMA, MethodObj)
- External(CPST, MethodObj)
- External(CPEJ, MethodObj)
- Method(_MAT, 0) {
- Return (CPMA(ID))
- }
- Method(_STA, 0) {
- Return (CPST(ID))
- }
- Method(_EJ0, 1, NotSerialized) {
- CPEJ(ID, Arg0)
- }
- }
-}
diff --git a/hw/i386/ssdt-proc.hex.generated b/hw/i386/ssdt-proc.hex.generated
deleted file mode 100644
index 4df0734c79..0000000000
--- a/hw/i386/ssdt-proc.hex.generated
+++ /dev/null
@@ -1,134 +0,0 @@
-static unsigned char ssdt_proc_name[] = {
-0x28
-};
-static unsigned char ssdp_proc_aml[] = {
-0x53,
-0x53,
-0x44,
-0x54,
-0x78,
-0x0,
-0x0,
-0x0,
-0x1,
-0x7d,
-0x42,
-0x58,
-0x50,
-0x43,
-0x0,
-0x0,
-0x42,
-0x58,
-0x53,
-0x53,
-0x44,
-0x54,
-0x0,
-0x0,
-0x1,
-0x0,
-0x0,
-0x0,
-0x49,
-0x4e,
-0x54,
-0x4c,
-0x15,
-0x11,
-0x13,
-0x20,
-0x5b,
-0x83,
-0x42,
-0x5,
-0x43,
-0x50,
-0x41,
-0x41,
-0xaa,
-0x0,
-0x0,
-0x0,
-0x0,
-0x0,
-0x8,
-0x49,
-0x44,
-0x5f,
-0x5f,
-0xa,
-0xaa,
-0x8,
-0x5f,
-0x48,
-0x49,
-0x44,
-0xd,
-0x41,
-0x43,
-0x50,
-0x49,
-0x30,
-0x30,
-0x30,
-0x37,
-0x0,
-0x14,
-0xf,
-0x5f,
-0x4d,
-0x41,
-0x54,
-0x0,
-0xa4,
-0x43,
-0x50,
-0x4d,
-0x41,
-0x49,
-0x44,
-0x5f,
-0x5f,
-0x14,
-0xf,
-0x5f,
-0x53,
-0x54,
-0x41,
-0x0,
-0xa4,
-0x43,
-0x50,
-0x53,
-0x54,
-0x49,
-0x44,
-0x5f,
-0x5f,
-0x14,
-0xf,
-0x5f,
-0x45,
-0x4a,
-0x30,
-0x1,
-0x43,
-0x50,
-0x45,
-0x4a,
-0x49,
-0x44,
-0x5f,
-0x5f,
-0x68
-};
-static unsigned char ssdt_proc_id[] = {
-0x38
-};
-static unsigned char ssdt_proc_end[] = {
-0x78
-};
-static unsigned char ssdt_proc_start[] = {
-0x24
-};
diff --git a/hw/i386/ssdt-tpm.hex.generated b/hw/i386/ssdt-tpm.hex.generated
index 4a916a8398..e84dc6cfc0 100644
--- a/hw/i386/ssdt-tpm.hex.generated
+++ b/hw/i386/ssdt-tpm.hex.generated
@@ -8,7 +8,7 @@ static unsigned char ssdt_tpm_aml[] = {
0x0,
0x0,
0x1,
-0xf,
+0x1c,
0x42,
0x58,
0x50,
@@ -31,9 +31,9 @@ static unsigned char ssdt_tpm_aml[] = {
0x4e,
0x54,
0x4c,
-0x15,
+0x7,
0x11,
-0x13,
+0x14,
0x20,
0x10,
0x38,
diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
index 0374653471..66fb9d96d5 100644
--- a/hw/ide/cmd646.c
+++ b/hw/ide/cmd646.c
@@ -326,7 +326,7 @@ static void cmd646_pci_config_write(PCIDevice *d, uint32_t addr, uint32_t val,
}
/* CMD646 PCI IDE controller */
-static int pci_cmd646_ide_initfn(PCIDevice *dev)
+static void pci_cmd646_ide_realize(PCIDevice *dev, Error **errp)
{
PCIIDEState *d = PCI_IDE(dev);
uint8_t *pci_conf = dev->config;
@@ -373,7 +373,6 @@ static int pci_cmd646_ide_initfn(PCIDevice *dev)
vmstate_register(DEVICE(dev), 0, &vmstate_ide_pci, d);
qemu_register_reset(cmd646_reset, d);
- return 0;
}
static void pci_cmd646_ide_exitfn(PCIDevice *dev)
@@ -409,7 +408,7 @@ static void cmd646_ide_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- k->init = pci_cmd646_ide_initfn;
+ k->realize = pci_cmd646_ide_realize;
k->exit = pci_cmd646_ide_exitfn;
k->vendor_id = PCI_VENDOR_ID_CMD;
k->device_id = PCI_DEVICE_ID_CMD_646;
diff --git a/hw/ide/ich.c b/hw/ide/ich.c
index fb1d095503..b1d8874671 100644
--- a/hw/ide/ich.c
+++ b/hw/ide/ich.c
@@ -98,7 +98,7 @@ static void pci_ich9_reset(DeviceState *dev)
ahci_reset(&d->ahci);
}
-static int pci_ich9_ahci_init(PCIDevice *dev)
+static void pci_ich9_ahci_realize(PCIDevice *dev, Error **errp)
{
struct AHCIPCIState *d;
int sata_cap_offset;
@@ -123,10 +123,11 @@ static int pci_ich9_ahci_init(PCIDevice *dev)
pci_register_bar(dev, ICH9_MEM_BAR, PCI_BASE_ADDRESS_SPACE_MEMORY,
&d->ahci.mem);
- sata_cap_offset = pci_add_capability(dev, PCI_CAP_ID_SATA,
- ICH9_SATA_CAP_OFFSET, SATA_CAP_SIZE);
+ sata_cap_offset = pci_add_capability2(dev, PCI_CAP_ID_SATA,
+ ICH9_SATA_CAP_OFFSET, SATA_CAP_SIZE,
+ errp);
if (sata_cap_offset < 0) {
- return sata_cap_offset;
+ return;
}
sata_cap = dev->config + sata_cap_offset;
@@ -139,8 +140,6 @@ static int pci_ich9_ahci_init(PCIDevice *dev)
* should be PMCAP, the Intel ICH9 data sheet specifies that the ICH9
* AHCI device puts the MSI capability first, pointing to 0x80. */
msi_init(dev, ICH9_MSI_CAP_OFFSET, 1, true, false);
-
- return 0;
}
static void pci_ich9_uninit(PCIDevice *dev)
@@ -158,7 +157,7 @@ static void ich_ahci_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- k->init = pci_ich9_ahci_init;
+ k->realize = pci_ich9_ahci_realize;
k->exit = pci_ich9_uninit;
k->vendor_id = PCI_VENDOR_ID_INTEL;
k->device_id = PCI_DEVICE_ID_INTEL_82801IR;
diff --git a/hw/ide/pci.c b/hw/ide/pci.c
index fab2abc01a..1b3d1c12ad 100644
--- a/hw/ide/pci.c
+++ b/hw/ide/pci.c
@@ -96,7 +96,7 @@ static int32_t bmdma_prepare_buf(IDEDMA *dma, int is_write)
* This should accommodate the largest ATA transaction
* for LBA48 (65,536 sectors) and 32K sector sizes. */
if (s->sg.size > INT32_MAX) {
- error_report("IDE: sglist describes more than 2GiB.\n");
+ error_report("IDE: sglist describes more than 2GiB.");
break;
}
bm->cur_prd_addr += l;
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index 247dd4f8b0..adb664957c 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -147,7 +147,7 @@ static void pci_piix_init_ports(PCIIDEState *d) {
}
}
-static int pci_piix_ide_initfn(PCIDevice *dev)
+static void pci_piix_ide_realize(PCIDevice *dev, Error **errp)
{
PCIIDEState *d = PCI_IDE(dev);
uint8_t *pci_conf = dev->config;
@@ -162,8 +162,6 @@ static int pci_piix_ide_initfn(PCIDevice *dev)
vmstate_register(DEVICE(dev), 0, &vmstate_ide_pci, d);
pci_piix_init_ports(d);
-
- return 0;
}
int pci_piix3_xen_ide_unplug(DeviceState *dev)
@@ -237,7 +235,7 @@ static void piix3_ide_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- k->init = pci_piix_ide_initfn;
+ k->realize = pci_piix_ide_realize;
k->exit = pci_piix_ide_exitfn;
k->vendor_id = PCI_VENDOR_ID_INTEL;
k->device_id = PCI_DEVICE_ID_INTEL_82371SB_1;
@@ -257,7 +255,7 @@ static void piix3_ide_xen_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- k->init = pci_piix_ide_initfn;
+ k->realize = pci_piix_ide_realize;
k->vendor_id = PCI_VENDOR_ID_INTEL;
k->device_id = PCI_DEVICE_ID_INTEL_82371SB_1;
k->class_id = PCI_CLASS_STORAGE_IDE;
@@ -275,7 +273,7 @@ static void piix4_ide_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- k->init = pci_piix_ide_initfn;
+ k->realize = pci_piix_ide_realize;
k->exit = pci_piix_ide_exitfn;
k->vendor_id = PCI_VENDOR_ID_INTEL;
k->device_id = PCI_DEVICE_ID_INTEL_82371AB;
diff --git a/hw/ide/via.c b/hw/ide/via.c
index fb3d8a0861..e2da9ef71a 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -171,7 +171,7 @@ static void vt82c686b_init_ports(PCIIDEState *d) {
}
/* via ide func */
-static int vt82c686b_ide_initfn(PCIDevice *dev)
+static void vt82c686b_ide_realize(PCIDevice *dev, Error **errp)
{
PCIIDEState *d = PCI_IDE(dev);
uint8_t *pci_conf = dev->config;
@@ -186,8 +186,6 @@ static int vt82c686b_ide_initfn(PCIDevice *dev)
vmstate_register(DEVICE(dev), 0, &vmstate_ide_pci, d);
vt82c686b_init_ports(d);
-
- return 0;
}
static void vt82c686b_ide_exitfn(PCIDevice *dev)
@@ -214,7 +212,7 @@ static void via_ide_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- k->init = vt82c686b_ide_initfn;
+ k->realize = vt82c686b_ide_realize;
k->exit = vt82c686b_ide_exitfn;
k->vendor_id = PCI_VENDOR_ID_VIA;
k->device_id = PCI_DEVICE_ID_VIA_IDE;
diff --git a/hw/input/adb.c b/hw/input/adb.c
index 34c8058fc2..a18eea2652 100644
--- a/hw/input/adb.c
+++ b/hw/input/adb.c
@@ -118,6 +118,17 @@ static const TypeInfo adb_bus_type_info = {
.instance_size = sizeof(ADBBusState),
};
+static const VMStateDescription vmstate_adb_device = {
+ .name = "adb_device",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .fields = (VMStateField[]) {
+ VMSTATE_INT32(devaddr, ADBDevice),
+ VMSTATE_INT32(handler, ADBDevice),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
static void adb_device_realizefn(DeviceState *dev, Error **errp)
{
ADBDevice *d = ADB_DEVICE(dev);
@@ -301,9 +312,10 @@ static int adb_kbd_request(ADBDevice *d, uint8_t *obuf,
static const VMStateDescription vmstate_adb_kbd = {
.name = "adb_kbd",
- .version_id = 1,
- .minimum_version_id = 1,
+ .version_id = 2,
+ .minimum_version_id = 2,
.fields = (VMStateField[]) {
+ VMSTATE_STRUCT(parent_obj, KBDState, 0, vmstate_adb_device, ADBDevice),
VMSTATE_BUFFER(data, KBDState),
VMSTATE_INT32(rptr, KBDState),
VMSTATE_INT32(wptr, KBDState),
@@ -515,9 +527,11 @@ static void adb_mouse_reset(DeviceState *dev)
static const VMStateDescription vmstate_adb_mouse = {
.name = "adb_mouse",
- .version_id = 1,
- .minimum_version_id = 1,
+ .version_id = 2,
+ .minimum_version_id = 2,
.fields = (VMStateField[]) {
+ VMSTATE_STRUCT(parent_obj, MouseState, 0, vmstate_adb_device,
+ ADBDevice),
VMSTATE_INT32(buttons_state, MouseState),
VMSTATE_INT32(last_buttons_state, MouseState),
VMSTATE_INT32(dx, MouseState),
diff --git a/hw/intc/openpic.c b/hw/intc/openpic.c
index 7d1f3b9497..87fe2e865d 100644
--- a/hw/intc/openpic.c
+++ b/hw/intc/openpic.c
@@ -200,11 +200,14 @@ typedef enum IRQType {
IRQ_TYPE_FSLSPECIAL, /* FSL timer/IPI interrupt, edge, no polarity */
} IRQType;
+/* Round up to the nearest 64 IRQs so that the queue length
+ * won't change when moving between 32 and 64 bit hosts.
+ */
+#define IRQQUEUE_SIZE_BITS ((OPENPIC_MAX_IRQ + 63) & ~63)
+
typedef struct IRQQueue {
- /* Round up to the nearest 64 IRQs so that the queue length
- * won't change when moving between 32 and 64 bit hosts.
- */
- unsigned long queue[BITS_TO_LONGS((OPENPIC_MAX_IRQ + 63) & ~63)];
+ unsigned long *queue;
+ int32_t queue_size; /* Only used for VMSTATE_BITMAP */
int next;
int priority;
} IRQQueue;
@@ -240,6 +243,15 @@ typedef struct IRQSource {
#define IDR_EP 0x80000000 /* external pin */
#define IDR_CI 0x40000000 /* critical interrupt */
+typedef struct OpenPICTimer {
+ uint32_t tccr; /* Global timer current count register */
+ uint32_t tbcr; /* Global timer base count register */
+} OpenPICTimer;
+
+typedef struct OpenPICMSI {
+ uint32_t msir; /* Shared Message Signaled Interrupt Register */
+} OpenPICMSI;
+
typedef struct IRQDest {
int32_t ctpr; /* CPU current task priority */
IRQQueue raised;
@@ -288,14 +300,9 @@ typedef struct OpenPICState {
IRQDest dst[MAX_CPU];
uint32_t nb_cpus;
/* Timer registers */
- struct {
- uint32_t tccr; /* Global timer current count register */
- uint32_t tbcr; /* Global timer base count register */
- } timers[OPENPIC_MAX_TMR];
+ OpenPICTimer timers[OPENPIC_MAX_TMR];
/* Shared MSI registers */
- struct {
- uint32_t msir; /* Shared Message Signaled Interrupt Register */
- } msi[MAX_MSI];
+ OpenPICMSI msi[MAX_MSI];
uint32_t max_irq;
uint32_t irq_ipi0;
uint32_t irq_tim0;
@@ -1013,7 +1020,7 @@ static void openpic_cpu_write_internal(void *opaque, hwaddr addr,
DPRINTF("%s: cpu %d addr %#" HWADDR_PRIx " <= 0x%08x\n", __func__, idx,
addr, val);
- if (idx < 0) {
+ if (idx < 0 || idx >= opp->nb_cpus) {
return;
}
@@ -1152,7 +1159,7 @@ static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr,
DPRINTF("%s: cpu %d addr %#" HWADDR_PRIx "\n", __func__, idx, addr);
retval = 0xFFFFFFFF;
- if (idx < 0) {
+ if (idx < 0 || idx >= opp->nb_cpus) {
return retval;
}
@@ -1287,132 +1294,6 @@ static const MemoryRegionOps openpic_summary_ops_be = {
},
};
-static void openpic_save_IRQ_queue(QEMUFile* f, IRQQueue *q)
-{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(q->queue); i++) {
- /* Always put the lower half of a 64-bit long first, in case we
- * restore on a 32-bit host. The least significant bits correspond
- * to lower IRQ numbers in the bitmap.
- */
- qemu_put_be32(f, (uint32_t)q->queue[i]);
-#if LONG_MAX > 0x7FFFFFFF
- qemu_put_be32(f, (uint32_t)(q->queue[i] >> 32));
-#endif
- }
-
- qemu_put_sbe32s(f, &q->next);
- qemu_put_sbe32s(f, &q->priority);
-}
-
-static void openpic_save(QEMUFile* f, void *opaque)
-{
- OpenPICState *opp = (OpenPICState *)opaque;
- unsigned int i;
-
- qemu_put_be32s(f, &opp->gcr);
- qemu_put_be32s(f, &opp->vir);
- qemu_put_be32s(f, &opp->pir);
- qemu_put_be32s(f, &opp->spve);
- qemu_put_be32s(f, &opp->tfrr);
-
- qemu_put_be32s(f, &opp->nb_cpus);
-
- for (i = 0; i < opp->nb_cpus; i++) {
- qemu_put_sbe32s(f, &opp->dst[i].ctpr);
- openpic_save_IRQ_queue(f, &opp->dst[i].raised);
- openpic_save_IRQ_queue(f, &opp->dst[i].servicing);
- qemu_put_buffer(f, (uint8_t *)&opp->dst[i].outputs_active,
- sizeof(opp->dst[i].outputs_active));
- }
-
- for (i = 0; i < OPENPIC_MAX_TMR; i++) {
- qemu_put_be32s(f, &opp->timers[i].tccr);
- qemu_put_be32s(f, &opp->timers[i].tbcr);
- }
-
- for (i = 0; i < opp->max_irq; i++) {
- qemu_put_be32s(f, &opp->src[i].ivpr);
- qemu_put_be32s(f, &opp->src[i].idr);
- qemu_get_be32s(f, &opp->src[i].destmask);
- qemu_put_sbe32s(f, &opp->src[i].last_cpu);
- qemu_put_sbe32s(f, &opp->src[i].pending);
- }
-}
-
-static void openpic_load_IRQ_queue(QEMUFile* f, IRQQueue *q)
-{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(q->queue); i++) {
- unsigned long val;
-
- val = qemu_get_be32(f);
-#if LONG_MAX > 0x7FFFFFFF
- val <<= 32;
- val |= qemu_get_be32(f);
-#endif
-
- q->queue[i] = val;
- }
-
- qemu_get_sbe32s(f, &q->next);
- qemu_get_sbe32s(f, &q->priority);
-}
-
-static int openpic_load(QEMUFile* f, void *opaque, int version_id)
-{
- OpenPICState *opp = (OpenPICState *)opaque;
- unsigned int i, nb_cpus;
-
- if (version_id != 1) {
- return -EINVAL;
- }
-
- qemu_get_be32s(f, &opp->gcr);
- qemu_get_be32s(f, &opp->vir);
- qemu_get_be32s(f, &opp->pir);
- qemu_get_be32s(f, &opp->spve);
- qemu_get_be32s(f, &opp->tfrr);
-
- qemu_get_be32s(f, &nb_cpus);
- if (opp->nb_cpus != nb_cpus) {
- return -EINVAL;
- }
- assert(nb_cpus > 0 && nb_cpus <= MAX_CPU);
-
- for (i = 0; i < opp->nb_cpus; i++) {
- qemu_get_sbe32s(f, &opp->dst[i].ctpr);
- openpic_load_IRQ_queue(f, &opp->dst[i].raised);
- openpic_load_IRQ_queue(f, &opp->dst[i].servicing);
- qemu_get_buffer(f, (uint8_t *)&opp->dst[i].outputs_active,
- sizeof(opp->dst[i].outputs_active));
- }
-
- for (i = 0; i < OPENPIC_MAX_TMR; i++) {
- qemu_get_be32s(f, &opp->timers[i].tccr);
- qemu_get_be32s(f, &opp->timers[i].tbcr);
- }
-
- for (i = 0; i < opp->max_irq; i++) {
- uint32_t val;
-
- val = qemu_get_be32(f);
- write_IRQreg_idr(opp, i, val);
- val = qemu_get_be32(f);
- write_IRQreg_ivpr(opp, i, val);
-
- qemu_get_be32s(f, &opp->src[i].ivpr);
- qemu_get_be32s(f, &opp->src[i].idr);
- qemu_get_be32s(f, &opp->src[i].destmask);
- qemu_get_sbe32s(f, &opp->src[i].last_cpu);
- qemu_get_sbe32s(f, &opp->src[i].pending);
- }
-
- return 0;
-}
-
static void openpic_reset(DeviceState *d)
{
OpenPICState *opp = OPENPIC(d);
@@ -1446,12 +1327,14 @@ static void openpic_reset(DeviceState *d)
write_IRQreg_idr(opp, i, opp->idr_reset);
}
/* Initialise IRQ destinations */
- for (i = 0; i < MAX_CPU; i++) {
+ for (i = 0; i < opp->nb_cpus; i++) {
opp->dst[i].ctpr = 15;
- memset(&opp->dst[i].raised, 0, sizeof(IRQQueue));
opp->dst[i].raised.next = -1;
- memset(&opp->dst[i].servicing, 0, sizeof(IRQQueue));
+ opp->dst[i].raised.priority = 0;
+ bitmap_clear(opp->dst[i].raised.queue, 0, IRQQUEUE_SIZE_BITS);
opp->dst[i].servicing.next = -1;
+ opp->dst[i].servicing.priority = 0;
+ bitmap_clear(opp->dst[i].servicing.queue, 0, IRQQUEUE_SIZE_BITS);
}
/* Initialise timers */
for (i = 0; i < OPENPIC_MAX_TMR; i++) {
@@ -1525,6 +1408,110 @@ static void map_list(OpenPICState *opp, const MemReg *list, int *count)
}
}
+static const VMStateDescription vmstate_openpic_irq_queue = {
+ .name = "openpic_irq_queue",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .fields = (VMStateField[]) {
+ VMSTATE_BITMAP(queue, IRQQueue, 0, queue_size),
+ VMSTATE_INT32(next, IRQQueue),
+ VMSTATE_INT32(priority, IRQQueue),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static const VMStateDescription vmstate_openpic_irqdest = {
+ .name = "openpic_irqdest",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .fields = (VMStateField[]) {
+ VMSTATE_INT32(ctpr, IRQDest),
+ VMSTATE_STRUCT(raised, IRQDest, 0, vmstate_openpic_irq_queue,
+ IRQQueue),
+ VMSTATE_STRUCT(servicing, IRQDest, 0, vmstate_openpic_irq_queue,
+ IRQQueue),
+ VMSTATE_UINT32_ARRAY(outputs_active, IRQDest, OPENPIC_OUTPUT_NB),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static const VMStateDescription vmstate_openpic_irqsource = {
+ .name = "openpic_irqsource",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(ivpr, IRQSource),
+ VMSTATE_UINT32(idr, IRQSource),
+ VMSTATE_UINT32(destmask, IRQSource),
+ VMSTATE_INT32(last_cpu, IRQSource),
+ VMSTATE_INT32(pending, IRQSource),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static const VMStateDescription vmstate_openpic_timer = {
+ .name = "openpic_timer",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(tccr, OpenPICTimer),
+ VMSTATE_UINT32(tbcr, OpenPICTimer),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static const VMStateDescription vmstate_openpic_msi = {
+ .name = "openpic_msi",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(msir, OpenPICMSI),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static int openpic_post_load(void *opaque, int version_id)
+{
+ OpenPICState *opp = (OpenPICState *)opaque;
+ int i;
+
+ /* Update internal ivpr and idr variables */
+ for (i = 0; i < opp->max_irq; i++) {
+ write_IRQreg_idr(opp, i, opp->src[i].idr);
+ write_IRQreg_ivpr(opp, i, opp->src[i].ivpr);
+ }
+
+ return 0;
+}
+
+static const VMStateDescription vmstate_openpic = {
+ .name = "openpic",
+ .version_id = 3,
+ .minimum_version_id = 3,
+ .post_load = openpic_post_load,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32(gcr, OpenPICState),
+ VMSTATE_UINT32(vir, OpenPICState),
+ VMSTATE_UINT32(pir, OpenPICState),
+ VMSTATE_UINT32(spve, OpenPICState),
+ VMSTATE_UINT32(tfrr, OpenPICState),
+ VMSTATE_UINT32(max_irq, OpenPICState),
+ VMSTATE_STRUCT_VARRAY_UINT32(src, OpenPICState, max_irq, 0,
+ vmstate_openpic_irqsource, IRQSource),
+ VMSTATE_UINT32_EQUAL(nb_cpus, OpenPICState),
+ VMSTATE_STRUCT_VARRAY_UINT32(dst, OpenPICState, nb_cpus, 0,
+ vmstate_openpic_irqdest, IRQDest),
+ VMSTATE_STRUCT_ARRAY(timers, OpenPICState, OPENPIC_MAX_TMR, 0,
+ vmstate_openpic_timer, OpenPICTimer),
+ VMSTATE_STRUCT_ARRAY(msi, OpenPICState, MAX_MSI, 0,
+ vmstate_openpic_msi, OpenPICMSI),
+ VMSTATE_UINT32(irq_ipi0, OpenPICState),
+ VMSTATE_UINT32(irq_tim0, OpenPICState),
+ VMSTATE_UINT32(irq_msi, OpenPICState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
static void openpic_init(Object *obj)
{
OpenPICState *opp = OPENPIC(obj);
@@ -1631,10 +1618,12 @@ static void openpic_realize(DeviceState *dev, Error **errp)
for (j = 0; j < OPENPIC_OUTPUT_NB; j++) {
sysbus_init_irq(d, &opp->dst[i].irqs[j]);
}
- }
- register_savevm(dev, "openpic", 0, 2,
- openpic_save, openpic_load, opp);
+ opp->dst[i].raised.queue_size = IRQQUEUE_SIZE_BITS;
+ opp->dst[i].raised.queue = bitmap_new(IRQQUEUE_SIZE_BITS);
+ opp->dst[i].servicing.queue_size = IRQQUEUE_SIZE_BITS;
+ opp->dst[i].servicing.queue = bitmap_new(IRQQUEUE_SIZE_BITS);
+ }
sysbus_init_mmio(d, &opp->mem);
qdev_init_gpio_in(dev, openpic_set_irq, opp->max_irq);
@@ -1653,6 +1642,7 @@ static void openpic_class_init(ObjectClass *oc, void *data)
dc->realize = openpic_realize;
dc->props = openpic_properties;
dc->reset = openpic_reset;
+ dc->vmsd = &vmstate_openpic;
}
static const TypeInfo openpic_info = {
diff --git a/hw/ipack/tpci200.c b/hw/ipack/tpci200.c
index b7031a0b13..1df02ee859 100644
--- a/hw/ipack/tpci200.c
+++ b/hw/ipack/tpci200.c
@@ -573,7 +573,7 @@ static const MemoryRegionOps tpci200_las3_ops = {
}
};
-static int tpci200_initfn(PCIDevice *pci_dev)
+static void tpci200_realize(PCIDevice *pci_dev, Error **errp)
{
TPCI200State *s = TPCI200(pci_dev);
uint8_t *c = s->dev.config;
@@ -609,8 +609,6 @@ static int tpci200_initfn(PCIDevice *pci_dev)
ipack_bus_new_inplace(&s->bus, sizeof(s->bus), DEVICE(pci_dev), NULL,
N_MODULES, tpci200_set_irq);
-
- return 0;
}
static const VMStateDescription vmstate_tpci200 = {
@@ -632,7 +630,7 @@ static void tpci200_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- k->init = tpci200_initfn;
+ k->realize = tpci200_realize;
k->vendor_id = PCI_VENDOR_ID_TEWS;
k->device_id = PCI_DEVICE_ID_TEWS_TPCI200;
k->class_id = PCI_CLASS_BRIDGE_OTHER;
diff --git a/hw/isa/i82378.c b/hw/isa/i82378.c
index 0dc440df5c..9da9dfc4da 100644
--- a/hw/isa/i82378.c
+++ b/hw/isa/i82378.c
@@ -58,7 +58,7 @@ static void i82378_request_pic_irq(void *opaque, int irq, int level)
qemu_set_irq(s->i8259[irq], level);
}
-static int i82378_initfn(PCIDevice *pci)
+static void i82378_realize(PCIDevice *pci, Error **errp)
{
DeviceState *dev = DEVICE(pci);
I82378State *s = I82378(dev);
@@ -107,8 +107,6 @@ static int i82378_initfn(PCIDevice *pci)
/* timer */
isa_create_simple(isabus, "mc146818rtc");
-
- return 0;
}
static void i82378_init(Object *obj)
@@ -125,7 +123,7 @@ static void i82378_class_init(ObjectClass *klass, void *data)
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
- k->init = i82378_initfn;
+ k->realize = i82378_realize;
k->vendor_id = PCI_VENDOR_ID_INTEL;
k->device_id = PCI_DEVICE_ID_INTEL_82378;
k->revision = 0x03;
diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
index 231de74414..dba758595f 100644
--- a/hw/isa/lpc_ich9.c
+++ b/hw/isa/lpc_ich9.c
@@ -610,8 +610,17 @@ static void ich9_device_plug_cb(HotplugHandler *hotplug_dev,
static void ich9_device_unplug_request_cb(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp)
{
- error_setg(errp, "acpi: device unplug request for not supported device"
- " type: %s", object_get_typename(OBJECT(dev)));
+ ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev);
+
+ ich9_pm_device_unplug_request_cb(&lpc->pm, dev, errp);
+}
+
+static void ich9_device_unplug_cb(HotplugHandler *hotplug_dev,
+ DeviceState *dev, Error **errp)
+{
+ ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev);
+
+ ich9_pm_device_unplug_cb(&lpc->pm, dev, errp);
}
static bool ich9_rst_cnt_needed(void *opaque)
@@ -677,6 +686,7 @@ static void ich9_lpc_class_init(ObjectClass *klass, void *data)
dc->cannot_instantiate_with_device_add_yet = true;
hc->plug = ich9_device_plug_cb;
hc->unplug_request = ich9_device_unplug_request_cb;
+ hc->unplug = ich9_device_unplug_cb;
adevc->ospm_status = ich9_pm_ospm_status;
}
diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index a9916df20a..d9522b1f45 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -82,7 +82,7 @@ static const VMStateDescription vmstate_piix4 = {
}
};
-static int piix4_initfn(PCIDevice *dev)
+static void piix4_realize(PCIDevice *dev, Error **errp)
{
PIIX4State *d = DO_UPCAST(PIIX4State, dev, dev);
@@ -90,7 +90,6 @@ static int piix4_initfn(PCIDevice *dev)
pci_address_space_io(dev));
piix4_dev = &d->dev;
qemu_register_reset(piix4_reset, d);
- return 0;
}
int piix4_init(PCIBus *bus, ISABus **isa_bus, int devfn)
@@ -107,7 +106,7 @@ static void piix4_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- k->init = piix4_initfn;
+ k->realize = piix4_realize;
k->vendor_id = PCI_VENDOR_ID_INTEL;
k->device_id = PCI_DEVICE_ID_INTEL_82371AB_0;
k->class_id = PCI_CLASS_BRIDGE_ISA;
diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c
index b223526bde..b8197b115d 100644
--- a/hw/isa/vt82c686.c
+++ b/hw/isa/vt82c686.c
@@ -245,7 +245,7 @@ static const VMStateDescription vmstate_acpi = {
* just register a PCI device now, functionalities will be implemented later.
*/
-static int vt82c686b_ac97_initfn(PCIDevice *dev)
+static void vt82c686b_ac97_realize(PCIDevice *dev, Error **errp)
{
VT686AC97State *s = DO_UPCAST(VT686AC97State, dev, dev);
uint8_t *pci_conf = s->dev.config;
@@ -255,8 +255,6 @@ static int vt82c686b_ac97_initfn(PCIDevice *dev)
pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_CAP_LIST |
PCI_STATUS_DEVSEL_MEDIUM);
pci_set_long(pci_conf + PCI_INTERRUPT_PIN, 0x03);
-
- return 0;
}
void vt82c686b_ac97_init(PCIBus *bus, int devfn)
@@ -272,7 +270,7 @@ static void via_ac97_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- k->init = vt82c686b_ac97_initfn;
+ k->realize = vt82c686b_ac97_realize;
k->vendor_id = PCI_VENDOR_ID_VIA;
k->device_id = PCI_DEVICE_ID_VIA_AC97;
k->revision = 0x50;
@@ -288,7 +286,7 @@ static const TypeInfo via_ac97_info = {
.class_init = via_ac97_class_init,
};
-static int vt82c686b_mc97_initfn(PCIDevice *dev)
+static void vt82c686b_mc97_realize(PCIDevice *dev, Error **errp)
{
VT686MC97State *s = DO_UPCAST(VT686MC97State, dev, dev);
uint8_t *pci_conf = s->dev.config;
@@ -297,8 +295,6 @@ static int vt82c686b_mc97_initfn(PCIDevice *dev)
PCI_COMMAND_VGA_PALETTE);
pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM);
pci_set_long(pci_conf + PCI_INTERRUPT_PIN, 0x03);
-
- return 0;
}
void vt82c686b_mc97_init(PCIBus *bus, int devfn)
@@ -314,7 +310,7 @@ static void via_mc97_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- k->init = vt82c686b_mc97_initfn;
+ k->realize = vt82c686b_mc97_realize;
k->vendor_id = PCI_VENDOR_ID_VIA;
k->device_id = PCI_DEVICE_ID_VIA_MC97;
k->class_id = PCI_CLASS_COMMUNICATION_OTHER;
@@ -331,7 +327,7 @@ static const TypeInfo via_mc97_info = {
};
/* vt82c686 pm init */
-static int vt82c686b_pm_initfn(PCIDevice *dev)
+static void vt82c686b_pm_realize(PCIDevice *dev, Error **errp)
{
VT686PMState *s = DO_UPCAST(VT686PMState, dev, dev);
uint8_t *pci_conf;
@@ -361,8 +357,6 @@ static int vt82c686b_pm_initfn(PCIDevice *dev)
acpi_pm_tmr_init(&s->ar, pm_tmr_timer, &s->io);
acpi_pm1_evt_init(&s->ar, pm_tmr_timer, &s->io);
acpi_pm1_cnt_init(&s->ar, &s->io, 2);
-
- return 0;
}
I2CBus *vt82c686b_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
@@ -391,7 +385,7 @@ static void via_pm_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- k->init = vt82c686b_pm_initfn;
+ k->realize = vt82c686b_pm_realize;
k->config_write = pm_write_config;
k->vendor_id = PCI_VENDOR_ID_VIA;
k->device_id = PCI_DEVICE_ID_VIA_ACPI;
@@ -421,7 +415,7 @@ static const VMStateDescription vmstate_via = {
};
/* init the PCI-to-ISA bridge */
-static int vt82c686b_initfn(PCIDevice *d)
+static void vt82c686b_realize(PCIDevice *d, Error **errp)
{
VT82C686BState *vt82c = DO_UPCAST(VT82C686BState, dev, d);
uint8_t *pci_conf;
@@ -451,8 +445,6 @@ static int vt82c686b_initfn(PCIDevice *d)
&vt82c->superio);
qemu_register_reset(vt82c686b_reset, d);
-
- return 0;
}
ISABus *vt82c686b_init(PCIBus *bus, int devfn)
@@ -469,7 +461,7 @@ static void via_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- k->init = vt82c686b_initfn;
+ k->realize = vt82c686b_realize;
k->config_write = vt82c686b_write_config;
k->vendor_id = PCI_VENDOR_ID_VIA;
k->device_id = PCI_DEVICE_ID_VIA_ISA_BRIDGE;
diff --git a/hw/lm32/milkymist.c b/hw/lm32/milkymist.c
index 256c1029ce..7f622610d2 100644
--- a/hw/lm32/milkymist.c
+++ b/hw/lm32/milkymist.c
@@ -155,6 +155,7 @@ milkymist_init(MachineState *machine)
bios_name);
exit(1);
}
+ g_free(bios_filename);
milkymist_uart_create(0x60000000, irq[0]);
milkymist_sysctl_create(0x60001000, irq[1], irq[2], irq[3],
diff --git a/hw/microblaze/boot.c b/hw/microblaze/boot.c
index a2843cdf99..38c59dbe9d 100644
--- a/hw/microblaze/boot.c
+++ b/hw/microblaze/boot.c
@@ -185,7 +185,7 @@ void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base,
ram_size - initrd_offset);
}
if (initrd_size < 0) {
- error_report("qemu: could not load initrd '%s'\n",
+ error_report("qemu: could not load initrd '%s'",
initrd_filename);
exit(EXIT_FAILURE);
}
diff --git a/hw/misc/applesmc.c b/hw/misc/applesmc.c
index 6a56b07c6b..6bd61e7828 100644
--- a/hw/misc/applesmc.c
+++ b/hw/misc/applesmc.c
@@ -43,7 +43,6 @@
/* command/status port used by Apple SMC */
#define APPLESMC_CMD_PORT 0x4
#define APPLESMC_NR_PORTS 32
-#define APPLESMC_MAX_DATA_LENGTH 32
#define APPLESMC_READ_CMD 0x10
#define APPLESMC_WRITE_CMD 0x11
@@ -249,8 +248,8 @@ static void applesmc_isa_realize(DeviceState *dev, Error **errp)
}
static Property applesmc_isa_properties[] = {
- DEFINE_PROP_UINT32("iobase", AppleSMCState, iobase,
- APPLESMC_DEFAULT_IOBASE),
+ DEFINE_PROP_UINT32(APPLESMC_PROP_IO_BASE, AppleSMCState, iobase,
+ APPLESMC_DEFAULT_IOBASE),
DEFINE_PROP_STRING("osk", AppleSMCState, osk),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
index 47d9771a04..f3984e3a20 100644
--- a/hw/misc/macio/cuda.c
+++ b/hw/misc/macio/cuda.c
@@ -638,8 +638,8 @@ static const VMStateDescription vmstate_cuda_timer = {
static const VMStateDescription vmstate_cuda = {
.name = "cuda",
- .version_id = 1,
- .minimum_version_id = 1,
+ .version_id = 2,
+ .minimum_version_id = 2,
.fields = (VMStateField[]) {
VMSTATE_UINT8(a, CUDAState),
VMSTATE_UINT8(b, CUDAState),
@@ -660,6 +660,7 @@ static const VMStateDescription vmstate_cuda = {
VMSTATE_UINT32(tick_offset, CUDAState),
VMSTATE_STRUCT_ARRAY(timers, CUDAState, 2, 1,
vmstate_cuda_timer, CUDATimer),
+ VMSTATE_TIMER_PTR(adb_poll_timer, CUDAState),
VMSTATE_END_OF_LIST()
}
};
diff --git a/hw/misc/macio/macio.c b/hw/misc/macio/macio.c
index e0f1e88f54..063ad80412 100644
--- a/hw/misc/macio/macio.c
+++ b/hw/misc/macio/macio.c
@@ -273,7 +273,7 @@ static int macio_newworld_initfn(PCIDevice *d)
MacIOState *s = MACIO(d);
NewWorldMacIOState *ns = NEWWORLD_MACIO(d);
SysBusDevice *sysbus_dev;
- MemoryRegion *timer_memory = g_new(MemoryRegion, 1);
+ MemoryRegion *timer_memory = NULL;
int i;
int cur_irq = 0;
int ret = macio_common_initfn(d);
@@ -301,6 +301,7 @@ static int macio_newworld_initfn(PCIDevice *d)
}
/* Timer */
+ timer_memory = g_new(MemoryRegion, 1);
memory_region_init_io(timer_memory, OBJECT(s), &timer_ops, NULL, "timer",
0x1000);
memory_region_add_subregion(&s->bar, 0x15000, timer_memory);
@@ -336,20 +337,44 @@ static void macio_instance_init(Object *obj)
memory_region_add_subregion(&s->bar, 0x08000, dbdma_mem);
}
+static const VMStateDescription vmstate_macio_oldworld = {
+ .name = "macio-oldworld",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .fields = (VMStateField[]) {
+ VMSTATE_PCI_DEVICE(parent_obj.parent, OldWorldMacIOState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
static void macio_oldworld_class_init(ObjectClass *oc, void *data)
{
PCIDeviceClass *pdc = PCI_DEVICE_CLASS(oc);
+ DeviceClass *dc = DEVICE_CLASS(oc);
pdc->init = macio_oldworld_initfn;
pdc->device_id = PCI_DEVICE_ID_APPLE_343S1201;
+ dc->vmsd = &vmstate_macio_oldworld;
}
+static const VMStateDescription vmstate_macio_newworld = {
+ .name = "macio-newworld",
+ .version_id = 0,
+ .minimum_version_id = 0,
+ .fields = (VMStateField[]) {
+ VMSTATE_PCI_DEVICE(parent_obj.parent, NewWorldMacIOState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
static void macio_newworld_class_init(ObjectClass *oc, void *data)
{
PCIDeviceClass *pdc = PCI_DEVICE_CLASS(oc);
+ DeviceClass *dc = DEVICE_CLASS(oc);
pdc->init = macio_newworld_initfn;
pdc->device_id = PCI_DEVICE_ID_APPLE_UNI_N_KEYL;
+ dc->vmsd = &vmstate_macio_newworld;
}
static Property macio_properties[] = {
diff --git a/hw/misc/milkymist-pfpu.c b/hw/misc/milkymist-pfpu.c
index 609f33f9cd..08b604f13f 100644
--- a/hw/misc/milkymist-pfpu.c
+++ b/hw/misc/milkymist-pfpu.c
@@ -362,7 +362,7 @@ static void pfpu_start(MilkymistPFPUState *s)
i = 0;
while (pfpu_decode_insn(s)) {
/* decode at most MICROCODE_WORDS instructions */
- if (i++ >= MICROCODE_WORDS) {
+ if (++i >= MICROCODE_WORDS) {
error_report("milkymist_pfpu: too many instructions "
"executed in microcode. No VECTOUT?");
break;
diff --git a/hw/misc/pci-testdev.c b/hw/misc/pci-testdev.c
index c78a63e3a7..26b9b86178 100644
--- a/hw/misc/pci-testdev.c
+++ b/hw/misc/pci-testdev.c
@@ -233,7 +233,7 @@ static const MemoryRegionOps pci_testdev_pio_ops = {
},
};
-static int pci_testdev_init(PCIDevice *pci_dev)
+static void pci_testdev_realize(PCIDevice *pci_dev, Error **errp)
{
PCITestDevState *d = PCI_TEST_DEV(pci_dev);
uint8_t *pci_conf;
@@ -275,8 +275,6 @@ static int pci_testdev_init(PCIDevice *pci_dev)
assert(r >= 0);
test->hasnotifier = true;
}
-
- return 0;
}
static void
@@ -306,7 +304,7 @@ static void pci_testdev_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- k->init = pci_testdev_init;
+ k->realize = pci_testdev_realize;
k->exit = pci_testdev_uninit;
k->vendor_id = PCI_VENDOR_ID_REDHAT;
k->device_id = PCI_DEVICE_ID_REDHAT_TEST;
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
index a207e21bcf..3405cb9ea0 100644
--- a/hw/net/e1000.c
+++ b/hw/net/e1000.c
@@ -1537,7 +1537,7 @@ static void e1000_write_config(PCIDevice *pci_dev, uint32_t address,
}
-static int pci_e1000_init(PCIDevice *pci_dev)
+static void pci_e1000_realize(PCIDevice *pci_dev, Error **errp)
{
DeviceState *dev = DEVICE(pci_dev);
E1000State *d = E1000(pci_dev);
@@ -1581,8 +1581,6 @@ static int pci_e1000_init(PCIDevice *pci_dev)
d->autoneg_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, e1000_autoneg_timer, d);
d->mit_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, e1000_mit_timer, d);
-
- return 0;
}
static void qdev_e1000_reset(DeviceState *dev)
@@ -1614,7 +1612,7 @@ static void e1000_class_init(ObjectClass *klass, void *data)
E1000BaseClass *e = E1000_DEVICE_CLASS(klass);
const E1000Info *info = data;
- k->init = pci_e1000_init;
+ k->realize = pci_e1000_realize;
k->exit = pci_e1000_uninit;
k->romfile = "efi-e1000.rom";
k->vendor_id = PCI_VENDOR_ID_INTEL;
diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c
index 7a4f9f8a08..c374c1a251 100644
--- a/hw/net/eepro100.c
+++ b/hw/net/eepro100.c
@@ -1848,7 +1848,7 @@ static NetClientInfo net_eepro100_info = {
.receive = nic_receive,
};
-static int e100_nic_init(PCIDevice *pci_dev)
+static void e100_nic_realize(PCIDevice *pci_dev, Error **errp)
{
EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev);
E100PCIDeviceInfo *info = eepro100_get_class(s);
@@ -1892,8 +1892,6 @@ static int e100_nic_init(PCIDevice *pci_dev)
memcpy(s->vmstate, &vmstate_eepro100, sizeof(vmstate_eepro100));
s->vmstate->name = qemu_get_queue(s->nic)->model;
vmstate_register(&pci_dev->qdev, -1, s->vmstate, s);
-
- return 0;
}
static void eepro100_instance_init(Object *obj)
@@ -2083,7 +2081,7 @@ static void eepro100_class_init(ObjectClass *klass, void *data)
k->vendor_id = PCI_VENDOR_ID_INTEL;
k->class_id = PCI_CLASS_NETWORK_ETHERNET;
k->romfile = "pxe-eepro100.rom";
- k->init = e100_nic_init;
+ k->realize = e100_nic_realize;
k->exit = pci_nic_uninit;
k->device_id = info->device_id;
k->revision = info->revision;
diff --git a/hw/net/lance.c b/hw/net/lance.c
index ff7e789563..4baa0169e6 100644
--- a/hw/net/lance.c
+++ b/hw/net/lance.c
@@ -126,7 +126,8 @@ static int lance_init(SysBusDevice *sbd)
s->phys_mem_read = ledma_memory_read;
s->phys_mem_write = ledma_memory_write;
- return pcnet_common_init(dev, s, &net_lance_info);
+ pcnet_common_init(dev, s, &net_lance_info);
+ return 0;
}
static void lance_reset(DeviceState *dev)
diff --git a/hw/net/ne2000.c b/hw/net/ne2000.c
index 4dea70178d..3492db3663 100644
--- a/hw/net/ne2000.c
+++ b/hw/net/ne2000.c
@@ -709,7 +709,7 @@ static NetClientInfo net_ne2000_info = {
.receive = ne2000_receive,
};
-static int pci_ne2000_init(PCIDevice *pci_dev)
+static void pci_ne2000_realize(PCIDevice *pci_dev, Error **errp)
{
PCINE2000State *d = DO_UPCAST(PCINE2000State, dev, pci_dev);
NE2000State *s;
@@ -729,8 +729,6 @@ static int pci_ne2000_init(PCIDevice *pci_dev)
s->nic = qemu_new_nic(&net_ne2000_info, &s->c,
object_get_typename(OBJECT(pci_dev)), pci_dev->qdev.id, s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->c.macaddr.a);
-
- return 0;
}
static void pci_ne2000_exit(PCIDevice *pci_dev)
@@ -763,7 +761,7 @@ static void ne2000_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- k->init = pci_ne2000_init;
+ k->realize = pci_ne2000_realize;
k->exit = pci_ne2000_exit;
k->romfile = "efi-ne2k_pci.rom",
k->vendor_id = PCI_VENDOR_ID_REALTEK;
diff --git a/hw/net/pcnet-pci.c b/hw/net/pcnet-pci.c
index 5df79f0a1f..8305d1bdf2 100644
--- a/hw/net/pcnet-pci.c
+++ b/hw/net/pcnet-pci.c
@@ -278,7 +278,7 @@ static NetClientInfo net_pci_pcnet_info = {
.link_status_changed = pcnet_set_link_status,
};
-static int pci_pcnet_init(PCIDevice *pci_dev)
+static void pci_pcnet_realize(PCIDevice *pci_dev, Error **errp)
{
PCIPCNetState *d = PCI_PCNET(pci_dev);
PCNetState *s = &d->state;
@@ -316,7 +316,7 @@ static int pci_pcnet_init(PCIDevice *pci_dev)
s->phys_mem_write = pci_physical_memory_write;
s->dma_opaque = pci_dev;
- return pcnet_common_init(DEVICE(pci_dev), s, &net_pci_pcnet_info);
+ pcnet_common_init(DEVICE(pci_dev), s, &net_pci_pcnet_info);
}
static void pci_reset(DeviceState *dev)
@@ -346,7 +346,7 @@ static void pcnet_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- k->init = pci_pcnet_init;
+ k->realize = pci_pcnet_realize;
k->exit = pci_pcnet_uninit;
k->romfile = "efi-pcnet.rom",
k->vendor_id = PCI_VENDOR_ID_AMD;
diff --git a/hw/net/pcnet.c b/hw/net/pcnet.c
index 7778b9ad47..bdfd38f4ca 100644
--- a/hw/net/pcnet.c
+++ b/hw/net/pcnet.c
@@ -1712,7 +1712,7 @@ const VMStateDescription vmstate_pcnet = {
}
};
-int pcnet_common_init(DeviceState *dev, PCNetState *s, NetClientInfo *info)
+void pcnet_common_init(DeviceState *dev, PCNetState *s, NetClientInfo *info)
{
int i;
uint16_t checksum;
@@ -1751,6 +1751,4 @@ int pcnet_common_init(DeviceState *dev, PCNetState *s, NetClientInfo *info)
*(uint16_t *)&s->prom[12] = cpu_to_le16(checksum);
s->lnkst = 0x40; /* initial link state: up */
-
- return 0;
}
diff --git a/hw/net/pcnet.h b/hw/net/pcnet.h
index 3f12fe3c13..79c4c84f07 100644
--- a/hw/net/pcnet.h
+++ b/hw/net/pcnet.h
@@ -63,6 +63,6 @@ uint32_t pcnet_bcr_readw(PCNetState *s, uint32_t rap);
int pcnet_can_receive(NetClientState *nc);
ssize_t pcnet_receive(NetClientState *nc, const uint8_t *buf, size_t size_);
void pcnet_set_link_status(NetClientState *nc);
-int pcnet_common_init(DeviceState *dev, PCNetState *s, NetClientInfo *info);
+void pcnet_common_init(DeviceState *dev, PCNetState *s, NetClientInfo *info);
extern const VMStateDescription vmstate_pcnet;
#endif
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
index 2d1be06f41..f868108dfe 100644
--- a/hw/net/rtl8139.c
+++ b/hw/net/rtl8139.c
@@ -3455,7 +3455,7 @@ static NetClientInfo net_rtl8139_info = {
.link_status_changed = rtl8139_set_link_status,
};
-static int pci_rtl8139_init(PCIDevice *dev)
+static void pci_rtl8139_realize(PCIDevice *dev, Error **errp)
{
RTL8139State *s = RTL8139(dev);
DeviceState *d = DEVICE(dev);
@@ -3496,8 +3496,6 @@ static int pci_rtl8139_init(PCIDevice *dev)
s->cplus_txbuffer_offset = 0;
s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, rtl8139_timer, s);
-
- return 0;
}
static void rtl8139_instance_init(Object *obj)
@@ -3519,7 +3517,7 @@ static void rtl8139_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- k->init = pci_rtl8139_init;
+ k->realize = pci_rtl8139_realize;
k->exit = pci_rtl8139_uninit;
k->romfile = "efi-rtl8139.rom";
k->vendor_id = PCI_VENDOR_ID_REALTEK;
diff --git a/hw/net/spapr_llan.c b/hw/net/spapr_llan.c
index c255d925a7..2dd5ec1117 100644
--- a/hw/net/spapr_llan.c
+++ b/hw/net/spapr_llan.c
@@ -203,7 +203,7 @@ static void spapr_vlan_reset(VIOsPAPRDevice *sdev)
dev->isopen = 0;
}
-static int spapr_vlan_init(VIOsPAPRDevice *sdev)
+static void spapr_vlan_realize(VIOsPAPRDevice *sdev, Error **errp)
{
VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(sdev);
@@ -212,8 +212,6 @@ static int spapr_vlan_init(VIOsPAPRDevice *sdev)
dev->nic = qemu_new_nic(&net_spapr_vlan_info, &dev->nicconf,
object_get_typename(OBJECT(sdev)), sdev->qdev.id, dev);
qemu_format_nic_info_str(qemu_get_queue(dev->nic), dev->nicconf.macaddr.a);
-
- return 0;
}
static void spapr_vlan_instance_init(Object *obj)
@@ -534,7 +532,7 @@ static void spapr_vlan_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
VIOsPAPRDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass);
- k->init = spapr_vlan_init;
+ k->realize = spapr_vlan_realize;
k->reset = spapr_vlan_reset;
k->devnode = spapr_vlan_devnode;
k->dt_name = "l-lan";
diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index 4e3a061622..cf23335ba2 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -35,7 +35,7 @@
#include <stdio.h>
-#include "hw/virtio/virtio_ring.h"
+#include "standard-headers/linux/virtio_ring.h"
#include "hw/virtio/vhost.h"
#include "hw/virtio/virtio-bus.h"
@@ -56,7 +56,7 @@ static const int kernel_feature_bits[] = {
};
/* Features supported by others. */
-const int user_feature_bits[] = {
+static const int user_feature_bits[] = {
VIRTIO_F_NOTIFY_ON_EMPTY,
VIRTIO_RING_F_INDIRECT_DESC,
VIRTIO_RING_F_EVENT_IDX,
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 45da34ad61..27adcc5467 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -86,7 +86,7 @@ static void virtio_net_set_config(VirtIODevice *vdev, const uint8_t *config)
memcpy(&netcfg, config, n->config_size);
- if (!(vdev->guest_features >> VIRTIO_NET_F_CTRL_MAC_ADDR & 1) &&
+ if (!virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_MAC_ADDR) &&
memcmp(netcfg.mac, n->mac, ETH_ALEN)) {
memcpy(n->mac, netcfg.mac, ETH_ALEN);
qemu_format_nic_info_str(qemu_get_queue(n->nic), n->mac);
@@ -120,8 +120,8 @@ static void virtio_net_vhost_status(VirtIONet *n, uint8_t status)
return;
}
- if (!!n->vhost_started ==
- (virtio_net_started(n, status) && !nc->peer->link_down)) {
+ if ((virtio_net_started(n, status) && !nc->peer->link_down) ==
+ !!n->vhost_started) {
return;
}
if (!n->vhost_started) {
@@ -305,7 +305,7 @@ static RxFilterInfo *virtio_net_query_rxfilter(NetClientState *nc)
info->multicast_table = str_list;
info->vlan_table = get_vlan_table(n);
- if (!((1 << VIRTIO_NET_F_CTRL_VLAN) & vdev->guest_features)) {
+ if (!virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_VLAN)) {
info->vlan = RX_STATE_ALL;
} else if (!info->vlan_table) {
info->vlan = RX_STATE_NONE;
@@ -446,23 +446,23 @@ static uint32_t virtio_net_get_features(VirtIODevice *vdev, uint32_t features)
VirtIONet *n = VIRTIO_NET(vdev);
NetClientState *nc = qemu_get_queue(n->nic);
- features |= (1 << VIRTIO_NET_F_MAC);
+ virtio_add_feature(&features, VIRTIO_NET_F_MAC);
if (!peer_has_vnet_hdr(n)) {
- features &= ~(0x1 << VIRTIO_NET_F_CSUM);
- features &= ~(0x1 << VIRTIO_NET_F_HOST_TSO4);
- features &= ~(0x1 << VIRTIO_NET_F_HOST_TSO6);
- features &= ~(0x1 << VIRTIO_NET_F_HOST_ECN);
+ virtio_clear_feature(&features, VIRTIO_NET_F_CSUM);
+ virtio_clear_feature(&features, VIRTIO_NET_F_HOST_TSO4);
+ virtio_clear_feature(&features, VIRTIO_NET_F_HOST_TSO6);
+ virtio_clear_feature(&features, VIRTIO_NET_F_HOST_ECN);
- features &= ~(0x1 << VIRTIO_NET_F_GUEST_CSUM);
- features &= ~(0x1 << VIRTIO_NET_F_GUEST_TSO4);
- features &= ~(0x1 << VIRTIO_NET_F_GUEST_TSO6);
- features &= ~(0x1 << VIRTIO_NET_F_GUEST_ECN);
+ virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_CSUM);
+ virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_TSO4);
+ virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_TSO6);
+ virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_ECN);
}
if (!peer_has_vnet_hdr(n) || !peer_has_ufo(n)) {
- features &= ~(0x1 << VIRTIO_NET_F_GUEST_UFO);
- features &= ~(0x1 << VIRTIO_NET_F_HOST_UFO);
+ virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_UFO);
+ virtio_clear_feature(&features, VIRTIO_NET_F_HOST_UFO);
}
if (!get_vhost_net(nc->peer)) {
@@ -477,11 +477,11 @@ static uint32_t virtio_net_bad_features(VirtIODevice *vdev)
/* Linux kernel 2.6.25. It understood MAC (as everyone must),
* but also these: */
- features |= (1 << VIRTIO_NET_F_MAC);
- features |= (1 << VIRTIO_NET_F_CSUM);
- features |= (1 << VIRTIO_NET_F_HOST_TSO4);
- features |= (1 << VIRTIO_NET_F_HOST_TSO6);
- features |= (1 << VIRTIO_NET_F_HOST_ECN);
+ virtio_add_feature(&features, VIRTIO_NET_F_MAC);
+ virtio_add_feature(&features, VIRTIO_NET_F_CSUM);
+ virtio_add_feature(&features, VIRTIO_NET_F_HOST_TSO4);
+ virtio_add_feature(&features, VIRTIO_NET_F_HOST_TSO6);
+ virtio_add_feature(&features, VIRTIO_NET_F_HOST_ECN);
return features;
}
@@ -519,9 +519,12 @@ static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features)
VirtIONet *n = VIRTIO_NET(vdev);
int i;
- virtio_net_set_multiqueue(n, !!(features & (1 << VIRTIO_NET_F_MQ)));
+ virtio_net_set_multiqueue(n,
+ __virtio_has_feature(features, VIRTIO_NET_F_MQ));
- virtio_net_set_mrg_rx_bufs(n, !!(features & (1 << VIRTIO_NET_F_MRG_RXBUF)));
+ virtio_net_set_mrg_rx_bufs(n,
+ __virtio_has_feature(features,
+ VIRTIO_NET_F_MRG_RXBUF));
if (n->has_vnet_hdr) {
n->curr_guest_offloads =
@@ -538,7 +541,7 @@ static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features)
vhost_net_ack_features(get_vhost_net(nc->peer), features);
}
- if ((1 << VIRTIO_NET_F_CTRL_VLAN) & features) {
+ if (__virtio_has_feature(features, VIRTIO_NET_F_CTRL_VLAN)) {
memset(n->vlans, 0, MAX_VLAN >> 3);
} else {
memset(n->vlans, 0xff, MAX_VLAN >> 3);
@@ -585,7 +588,7 @@ static int virtio_net_handle_offloads(VirtIONet *n, uint8_t cmd,
uint64_t offloads;
size_t s;
- if (!((1 << VIRTIO_NET_F_CTRL_GUEST_OFFLOADS) & vdev->guest_features)) {
+ if (!virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS)) {
return VIRTIO_NET_ERR;
}
@@ -1378,7 +1381,7 @@ static void virtio_net_save_device(VirtIODevice *vdev, QEMUFile *f)
}
}
- if ((1 << VIRTIO_NET_F_CTRL_GUEST_OFFLOADS) & vdev->guest_features) {
+ if (virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS)) {
qemu_put_be64(f, n->curr_guest_offloads);
}
}
@@ -1486,7 +1489,7 @@ static int virtio_net_load_device(VirtIODevice *vdev, QEMUFile *f,
}
}
- if ((1 << VIRTIO_NET_F_CTRL_GUEST_OFFLOADS) & vdev->guest_features) {
+ if (virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS)) {
n->curr_guest_offloads = qemu_get_be64(f);
} else {
n->curr_guest_offloads = virtio_net_supported_guest_offloads(n);
@@ -1513,8 +1516,8 @@ static int virtio_net_load_device(VirtIODevice *vdev, QEMUFile *f,
qemu_get_subqueue(n->nic, i)->link_down = link_down;
}
- if (vdev->guest_features & (0x1 << VIRTIO_NET_F_GUEST_ANNOUNCE) &&
- vdev->guest_features & (0x1 << VIRTIO_NET_F_CTRL_VQ)) {
+ if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ANNOUNCE) &&
+ virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_VQ)) {
n->announce_counter = SELF_ANNOUNCE_ROUNDS;
timer_mod(n->announce_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL));
}
@@ -1552,7 +1555,7 @@ static void virtio_net_guest_notifier_mask(VirtIODevice *vdev, int idx,
void virtio_net_set_config_size(VirtIONet *n, uint32_t host_features)
{
int i, config_size = 0;
- host_features |= (1 << VIRTIO_NET_F_MAC);
+ virtio_add_feature(&host_features, VIRTIO_NET_F_MAC);
for (i = 0; feature_sizes[i].flags != 0; i++) {
if (host_features & feature_sizes[i].flags) {
config_size = MAX(feature_sizes[i].end, config_size);
diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
index a83d2a11ff..dfb328debd 100644
--- a/hw/net/vmxnet3.c
+++ b/hw/net/vmxnet3.c
@@ -2125,7 +2125,7 @@ static const MemoryRegionOps b1_ops = {
},
};
-static int vmxnet3_pci_init(PCIDevice *pci_dev)
+static void vmxnet3_pci_realize(PCIDevice *pci_dev, Error **errp)
{
DeviceState *dev = DEVICE(pci_dev);
VMXNET3State *s = VMXNET3(pci_dev);
@@ -2164,8 +2164,6 @@ static int vmxnet3_pci_init(PCIDevice *pci_dev)
register_savevm(dev, "vmxnet3-msix", -1, 1,
vmxnet3_msix_save, vmxnet3_msix_load, s);
-
- return 0;
}
static void vmxnet3_instance_init(Object *obj)
@@ -2501,7 +2499,7 @@ static void vmxnet3_class_init(ObjectClass *class, void *data)
DeviceClass *dc = DEVICE_CLASS(class);
PCIDeviceClass *c = PCI_DEVICE_CLASS(class);
- c->init = vmxnet3_pci_init;
+ c->realize = vmxnet3_pci_realize;
c->exit = vmxnet3_pci_uninit;
c->vendor_id = PCI_VENDOR_ID_VMWARE;
c->device_id = PCI_DEVICE_ID_VMWARE_VMXNET3;
diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c
index 9536f64584..ad6b55306d 100644
--- a/hw/net/xilinx_ethlite.c
+++ b/hw/net/xilinx_ethlite.c
@@ -146,6 +146,7 @@ eth_write(void *opaque, hwaddr addr,
if (!(value & CTRL_S)) {
qemu_flush_queued_packets(qemu_get_queue(s->nic));
}
+ /* fall through */
case R_TX_LEN0:
case R_TX_LEN1:
case R_TX_GIE0:
diff --git a/hw/nvram/spapr_nvram.c b/hw/nvram/spapr_nvram.c
index 35dc6d5684..11332d14ea 100644
--- a/hw/nvram/spapr_nvram.c
+++ b/hw/nvram/spapr_nvram.c
@@ -132,7 +132,7 @@ static void rtas_nvram_store(PowerPCCPU *cpu, sPAPREnvironment *spapr,
rtas_st(rets, 1, (alen < 0) ? 0 : alen);
}
-static int spapr_nvram_init(VIOsPAPRDevice *dev)
+static void spapr_nvram_realize(VIOsPAPRDevice *dev, Error **errp)
{
sPAPRNVRAM *nvram = VIO_SPAPR_NVRAM(dev);
@@ -145,23 +145,22 @@ static int spapr_nvram_init(VIOsPAPRDevice *dev)
nvram->buf = g_malloc0(nvram->size);
if ((nvram->size < MIN_NVRAM_SIZE) || (nvram->size > MAX_NVRAM_SIZE)) {
- fprintf(stderr, "spapr-nvram must be between %d and %d bytes in size\n",
- MIN_NVRAM_SIZE, MAX_NVRAM_SIZE);
- return -1;
+ error_setg(errp, "spapr-nvram must be between %d and %d bytes in size",
+ MIN_NVRAM_SIZE, MAX_NVRAM_SIZE);
+ return;
}
if (nvram->blk) {
int alen = blk_pread(nvram->blk, 0, nvram->buf, nvram->size);
if (alen != nvram->size) {
- return -1;
+ error_setg(errp, "can't read spapr-nvram contents");
+ return;
}
}
spapr_rtas_register(RTAS_NVRAM_FETCH, "nvram-fetch", rtas_nvram_fetch);
spapr_rtas_register(RTAS_NVRAM_STORE, "nvram-store", rtas_nvram_store);
-
- return 0;
}
static int spapr_nvram_devnode(VIOsPAPRDevice *dev, void *fdt, int node_off)
@@ -224,7 +223,7 @@ static void spapr_nvram_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
VIOsPAPRDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass);
- k->init = spapr_nvram_init;
+ k->realize = spapr_nvram_realize;
k->devnode = spapr_nvram_devnode;
k->dt_name = "nvram";
k->dt_type = "nvram";
diff --git a/hw/pci-bridge/dec.c b/hw/pci-bridge/dec.c
index a6ca940d55..28d0ff9c84 100644
--- a/hw/pci-bridge/dec.c
+++ b/hw/pci-bridge/dec.c
@@ -107,10 +107,9 @@ static int pci_dec_21154_device_init(SysBusDevice *dev)
return 0;
}
-static int dec_21154_pci_host_init(PCIDevice *d)
+static void dec_21154_pci_host_realize(PCIDevice *d, Error **errp)
{
/* PCI2PCI bridge same values as PearPC - check this */
- return 0;
}
static void dec_21154_pci_host_class_init(ObjectClass *klass, void *data)
@@ -118,7 +117,7 @@ static void dec_21154_pci_host_class_init(ObjectClass *klass, void *data)
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
- k->init = dec_21154_pci_host_init;
+ k->realize = dec_21154_pci_host_realize;
k->vendor_id = PCI_VENDOR_ID_DEC;
k->device_id = PCI_DEVICE_ID_DEC_21154;
k->revision = 0x02;
diff --git a/hw/pci-host/apb.c b/hw/pci-host/apb.c
index 832b6c7248..312fa703c6 100644
--- a/hw/pci-host/apb.c
+++ b/hw/pci-host/apb.c
@@ -792,14 +792,13 @@ static int pci_pbm_init_device(SysBusDevice *dev)
return 0;
}
-static int pbm_pci_host_init(PCIDevice *d)
+static void pbm_pci_host_realize(PCIDevice *d, Error **errp)
{
pci_set_word(d->config + PCI_COMMAND,
PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
pci_set_word(d->config + PCI_STATUS,
PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ |
PCI_STATUS_DEVSEL_MEDIUM);
- return 0;
}
static void pbm_pci_host_class_init(ObjectClass *klass, void *data)
@@ -807,7 +806,7 @@ static void pbm_pci_host_class_init(ObjectClass *klass, void *data)
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
- k->init = pbm_pci_host_init;
+ k->realize = pbm_pci_host_realize;
k->vendor_id = PCI_VENDOR_ID_SUN;
k->device_id = PCI_DEVICE_ID_SUN_SABRE;
k->class_id = PCI_CLASS_BRIDGE_HOST;
diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c
index 56292adb03..8bdd56922a 100644
--- a/hw/pci-host/bonito.c
+++ b/hw/pci-host/bonito.c
@@ -705,7 +705,7 @@ static int bonito_pcihost_initfn(SysBusDevice *dev)
return 0;
}
-static int bonito_initfn(PCIDevice *dev)
+static void bonito_realize(PCIDevice *dev, Error **errp)
{
PCIBonitoState *s = DO_UPCAST(PCIBonitoState, dev, dev);
SysBusDevice *sysbus = SYS_BUS_DEVICE(s->pcihost);
@@ -766,8 +766,6 @@ static int bonito_initfn(PCIDevice *dev)
pci_set_byte(dev->config + PCI_MAX_LAT, 0x00);
qemu_register_reset(bonito_reset, s);
-
- return 0;
}
PCIBus *bonito_init(qemu_irq *pic)
@@ -799,7 +797,7 @@ static void bonito_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- k->init = bonito_initfn;
+ k->realize = bonito_realize;
k->vendor_id = 0xdf53;
k->device_id = 0x00d5;
k->revision = 0x01;
diff --git a/hw/pci-host/grackle.c b/hw/pci-host/grackle.c
index 6c7cfdbeb2..bfe707a1a1 100644
--- a/hw/pci-host/grackle.c
+++ b/hw/pci-host/grackle.c
@@ -114,10 +114,9 @@ static int pci_grackle_init_device(SysBusDevice *dev)
return 0;
}
-static int grackle_pci_host_init(PCIDevice *d)
+static void grackle_pci_host_realize(PCIDevice *d, Error **errp)
{
d->config[0x09] = 0x01;
- return 0;
}
static void grackle_pci_class_init(ObjectClass *klass, void *data)
@@ -125,7 +124,7 @@ static void grackle_pci_class_init(ObjectClass *klass, void *data)
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
- k->init = grackle_pci_host_init;
+ k->realize = grackle_pci_host_realize;
k->vendor_id = PCI_VENDOR_ID_MOTOROLA;
k->device_id = PCI_DEVICE_ID_MOTOROLA_MPC106;
k->revision = 0x00;
diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index 8ea718e18e..723836fb0e 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -295,14 +295,13 @@ static void i440fx_pcihost_realize(DeviceState *dev, Error **errp)
sysbus_init_ioports(sbd, 0xcfc, 4);
}
-static int i440fx_initfn(PCIDevice *dev)
+static void i440fx_realize(PCIDevice *dev, Error **errp)
{
PCII440FXState *d = I440FX_PCI_DEVICE(dev);
dev->config[I440FX_SMRAM] = 0x02;
cpu_smm_register(&i440fx_set_smm, d);
- return 0;
}
PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
@@ -631,7 +630,7 @@ static const MemoryRegionOps rcr_ops = {
.endianness = DEVICE_LITTLE_ENDIAN
};
-static int piix3_initfn(PCIDevice *dev)
+static void piix3_realize(PCIDevice *dev, Error **errp)
{
PIIX3State *d = DO_UPCAST(PIIX3State, dev, dev);
@@ -644,7 +643,6 @@ static int piix3_initfn(PCIDevice *dev)
&d->rcr_mem, 1);
qemu_register_reset(piix3_reset, d);
- return 0;
}
static void piix3_class_init(ObjectClass *klass, void *data)
@@ -655,7 +653,7 @@ static void piix3_class_init(ObjectClass *klass, void *data)
dc->desc = "ISA bridge";
dc->vmsd = &vmstate_piix3;
dc->hotpluggable = false;
- k->init = piix3_initfn;
+ k->realize = piix3_realize;
k->config_write = piix3_write_config;
k->vendor_id = PCI_VENDOR_ID_INTEL;
/* 82371SB PIIX3 PCI-to-ISA bridge (Step A1) */
@@ -683,7 +681,7 @@ static void piix3_xen_class_init(ObjectClass *klass, void *data)
dc->desc = "ISA bridge";
dc->vmsd = &vmstate_piix3;
dc->hotpluggable = false;
- k->init = piix3_initfn;
+ k->realize = piix3_realize;
k->config_write = piix3_write_config_xen;
k->vendor_id = PCI_VENDOR_ID_INTEL;
/* 82371SB PIIX3 PCI-to-ISA bridge (Step A1) */
@@ -708,7 +706,7 @@ static void i440fx_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- k->init = i440fx_initfn;
+ k->realize = i440fx_realize;
k->config_write = i440fx_write_config;
k->vendor_id = PCI_VENDOR_ID_INTEL;
k->device_id = PCI_DEVICE_ID_INTEL_82441;
diff --git a/hw/pci-host/ppce500.c b/hw/pci-host/ppce500.c
index 574f8b2efb..613ba73c64 100644
--- a/hw/pci-host/ppce500.c
+++ b/hw/pci-host/ppce500.c
@@ -416,7 +416,7 @@ static const VMStateDescription vmstate_ppce500_pci = {
#include "exec/address-spaces.h"
-static int e500_pcihost_bridge_initfn(PCIDevice *d)
+static void e500_pcihost_bridge_realize(PCIDevice *d, Error **errp)
{
PPCE500PCIBridgeState *b = PPC_E500_PCI_BRIDGE(d);
PPCE500CCSRState *ccsr = CCSR(container_get(qdev_get_machine(),
@@ -430,8 +430,6 @@ static int e500_pcihost_bridge_initfn(PCIDevice *d)
memory_region_init_alias(&b->bar0, OBJECT(ccsr), "e500-pci-bar0", &ccsr->ccsr_space,
0, int128_get64(ccsr->ccsr_space.size));
pci_register_bar(d, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &b->bar0);
-
- return 0;
}
static AddressSpace *e500_pcihost_set_iommu(PCIBus *bus, void *opaque,
@@ -500,7 +498,7 @@ static void e500_host_bridge_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- k->init = e500_pcihost_bridge_initfn;
+ k->realize = e500_pcihost_bridge_realize;
k->vendor_id = PCI_VENDOR_ID_FREESCALE;
k->device_id = PCI_DEVICE_ID_MPC8533E;
k->class_id = PCI_CLASS_PROCESSOR_POWERPC;
diff --git a/hw/pci-host/prep.c b/hw/pci-host/prep.c
index 1de3681db9..6cea6ffebb 100644
--- a/hw/pci-host/prep.c
+++ b/hw/pci-host/prep.c
@@ -289,7 +289,7 @@ static void raven_pcihost_initfn(Object *obj)
qdev_prop_set_bit(pci_dev, "multifunction", false);
}
-static int raven_init(PCIDevice *d)
+static void raven_realize(PCIDevice *d, Error **errp)
{
RavenPCIState *s = RAVEN_PCI_DEVICE(d);
char *filename;
@@ -330,8 +330,6 @@ static int raven_init(PCIDevice *d)
g_free(filename);
}
}
-
- return 0;
}
static const VMStateDescription vmstate_raven = {
@@ -349,7 +347,7 @@ static void raven_class_init(ObjectClass *klass, void *data)
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
- k->init = raven_init;
+ k->realize = raven_realize;
k->vendor_id = PCI_VENDOR_ID_MOTOROLA;
k->device_id = PCI_DEVICE_ID_MOTOROLA_RAVEN;
k->revision = 0x00;
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index b20bad8373..df60e61d4f 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -390,7 +390,7 @@ static void mch_init_dmar(MCHPCIState *mch)
pci_setup_iommu(pci_bus, q35_host_dma_iommu, mch->iommu);
}
-static int mch_init(PCIDevice *d)
+static void mch_realize(PCIDevice *d, Error **errp)
{
int i;
MCHPCIState *mch = MCH_PCI_DEVICE(d);
@@ -418,7 +418,6 @@ static int mch_init(PCIDevice *d)
if (qemu_opt_get_bool(qemu_get_machine_opts(), "iommu", false)) {
mch_init_dmar(mch);
}
- return 0;
}
uint64_t mch_mcfg_base(void)
@@ -436,7 +435,7 @@ static void mch_class_init(ObjectClass *klass, void *data)
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
- k->init = mch_init;
+ k->realize = mch_realize;
k->config_write = mch_write_config;
dc->reset = mch_reset;
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c
index 21f805f314..53f2b59ae8 100644
--- a/hw/pci-host/uninorth.c
+++ b/hw/pci-host/uninorth.c
@@ -315,37 +315,33 @@ PCIBus *pci_pmac_u3_init(qemu_irq *pic,
return h->bus;
}
-static int unin_main_pci_host_init(PCIDevice *d)
+static void unin_main_pci_host_realize(PCIDevice *d, Error **errp)
{
d->config[0x0C] = 0x08; // cache_line_size
d->config[0x0D] = 0x10; // latency_timer
d->config[0x34] = 0x00; // capabilities_pointer
- return 0;
}
-static int unin_agp_pci_host_init(PCIDevice *d)
+static void unin_agp_pci_host_realize(PCIDevice *d, Error **errp)
{
d->config[0x0C] = 0x08; // cache_line_size
d->config[0x0D] = 0x10; // latency_timer
// d->config[0x34] = 0x80; // capabilities_pointer
- return 0;
}
-static int u3_agp_pci_host_init(PCIDevice *d)
+static void u3_agp_pci_host_realize(PCIDevice *d, Error **errp)
{
/* cache line size */
d->config[0x0C] = 0x08;
/* latency timer */
d->config[0x0D] = 0x10;
- return 0;
}
-static int unin_internal_pci_host_init(PCIDevice *d)
+static void unin_internal_pci_host_realize(PCIDevice *d, Error **errp)
{
d->config[0x0C] = 0x08; // cache_line_size
d->config[0x0D] = 0x10; // latency_timer
d->config[0x34] = 0x00; // capabilities_pointer
- return 0;
}
static void unin_main_pci_host_class_init(ObjectClass *klass, void *data)
@@ -353,7 +349,7 @@ static void unin_main_pci_host_class_init(ObjectClass *klass, void *data)
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
- k->init = unin_main_pci_host_init;
+ k->realize = unin_main_pci_host_realize;
k->vendor_id = PCI_VENDOR_ID_APPLE;
k->device_id = PCI_DEVICE_ID_APPLE_UNI_N_PCI;
k->revision = 0x00;
@@ -377,7 +373,7 @@ static void u3_agp_pci_host_class_init(ObjectClass *klass, void *data)
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
- k->init = u3_agp_pci_host_init;
+ k->realize = u3_agp_pci_host_realize;
k->vendor_id = PCI_VENDOR_ID_APPLE;
k->device_id = PCI_DEVICE_ID_APPLE_U3_AGP;
k->revision = 0x00;
@@ -401,7 +397,7 @@ static void unin_agp_pci_host_class_init(ObjectClass *klass, void *data)
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
- k->init = unin_agp_pci_host_init;
+ k->realize = unin_agp_pci_host_realize;
k->vendor_id = PCI_VENDOR_ID_APPLE;
k->device_id = PCI_DEVICE_ID_APPLE_UNI_N_AGP;
k->revision = 0x00;
@@ -425,7 +421,7 @@ static void unin_internal_pci_host_class_init(ObjectClass *klass, void *data)
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
- k->init = unin_internal_pci_host_init;
+ k->realize = unin_internal_pci_host_realize;
k->vendor_id = PCI_VENDOR_ID_APPLE;
k->device_id = PCI_DEVICE_ID_APPLE_UNI_N_I_PCI;
k->revision = 0x00;
diff --git a/hw/pci-host/versatile.c b/hw/pci-host/versatile.c
index 71ff0de303..6d23553094 100644
--- a/hw/pci-host/versatile.c
+++ b/hw/pci-host/versatile.c
@@ -456,12 +456,11 @@ static void pci_vpb_realize(DeviceState *dev, Error **errp)
object_property_set_bool(OBJECT(&s->pci_dev), true, "realized", errp);
}
-static int versatile_pci_host_init(PCIDevice *d)
+static void versatile_pci_host_realize(PCIDevice *d, Error **errp)
{
pci_set_word(d->config + PCI_STATUS,
PCI_STATUS_66MHZ | PCI_STATUS_DEVSEL_MEDIUM);
pci_set_byte(d->config + PCI_LATENCY_TIMER, 0x10);
- return 0;
}
static void versatile_pci_host_class_init(ObjectClass *klass, void *data)
@@ -469,7 +468,7 @@ static void versatile_pci_host_class_init(ObjectClass *klass, void *data)
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
- k->init = versatile_pci_host_init;
+ k->realize = versatile_pci_host_realize;
k->vendor_id = PCI_VENDOR_ID_XILINX;
k->device_id = PCI_DEVICE_ID_XILINX_XC2VP30;
k->class_id = PCI_CLASS_PROCESSOR_CO;
diff --git a/hw/pci/Makefile.objs b/hw/pci/Makefile.objs
index 80f8aa69ac..9f905e6344 100644
--- a/hw/pci/Makefile.objs
+++ b/hw/pci/Makefile.objs
@@ -7,5 +7,3 @@ common-obj-$(CONFIG_PCI) += pcie.o pcie_aer.o pcie_port.o
common-obj-$(call lnot,$(CONFIG_PCI)) += pci-stub.o
common-obj-$(CONFIG_ALL) += pci-stub.o
-
-common-obj-$(CONFIG_PCI_HOTPLUG_OLD) += pci-hotplug-old.o
diff --git a/hw/pci/pci-hotplug-old.c b/hw/pci/pci-hotplug-old.c
deleted file mode 100644
index 501a918b89..0000000000
--- a/hw/pci/pci-hotplug-old.c
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
- * Deprecated PCI hotplug interface support
- * This covers the old pci_add / pci_del command, whereas the more general
- * device_add / device_del commands are now preferred.
- *
- * Copyright (c) 2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "hw/hw.h"
-#include "hw/boards.h"
-#include "hw/pci/pci.h"
-#include "net/net.h"
-#include "hw/i386/pc.h"
-#include "monitor/monitor.h"
-#include "hw/scsi/scsi.h"
-#include "hw/virtio/virtio-blk.h"
-#include "qemu/config-file.h"
-#include "sysemu/block-backend.h"
-#include "qapi/error.h"
-
-static int pci_read_devaddr(Monitor *mon, const char *addr,
- int *busp, unsigned *slotp)
-{
- int dom;
-
- /* strip legacy tag */
- if (!strncmp(addr, "pci_addr=", 9)) {
- addr += 9;
- }
- if (pci_parse_devaddr(addr, &dom, busp, slotp, NULL)) {
- monitor_printf(mon, "Invalid pci address\n");
- return -1;
- }
- if (dom != 0) {
- monitor_printf(mon, "Multiple PCI domains not supported, use device_add\n");
- return -1;
- }
- return 0;
-}
-
-static PCIDevice *qemu_pci_hot_add_nic(Monitor *mon,
- const char *devaddr,
- const char *opts_str)
-{
- Error *local_err = NULL;
- QemuOpts *opts;
- PCIBus *root = pci_find_primary_bus();
- PCIBus *bus;
- int ret, devfn;
-
- if (!root) {
- monitor_printf(mon, "no primary PCI bus (if there are multiple"
- " PCI roots, you must use device_add instead)");
- return NULL;
- }
-
- bus = pci_get_bus_devfn(&devfn, root, devaddr);
- if (!bus) {
- monitor_printf(mon, "Invalid PCI device address %s\n", devaddr);
- return NULL;
- }
- if (!qbus_is_hotpluggable(BUS(bus))) {
- monitor_printf(mon, "PCI bus doesn't support hotplug\n");
- return NULL;
- }
-
- opts = qemu_opts_parse(qemu_find_opts("net"), opts_str ? opts_str : "", 0);
- if (!opts) {
- return NULL;
- }
-
- qemu_opt_set(opts, "type", "nic", &error_abort);
-
- ret = net_client_init(opts, 0, &local_err);
- if (local_err) {
- qerror_report_err(local_err);
- error_free(local_err);
- return NULL;
- }
- if (nd_table[ret].devaddr) {
- monitor_printf(mon, "Parameter addr not supported\n");
- return NULL;
- }
- return pci_nic_init(&nd_table[ret], root, "rtl8139", devaddr);
-}
-
-static int scsi_hot_add(Monitor *mon, DeviceState *adapter,
- DriveInfo *dinfo, int printinfo)
-{
- SCSIBus *scsibus;
- SCSIDevice *scsidev;
- Error *local_err = NULL;
-
- scsibus = (SCSIBus *)
- object_dynamic_cast(OBJECT(QLIST_FIRST(&adapter->child_bus)),
- TYPE_SCSI_BUS);
- if (!scsibus) {
- error_report("Device is not a SCSI adapter");
- return -1;
- }
-
- /*
- * drive_init() tries to find a default for dinfo->unit. Doesn't
- * work at all for hotplug though as we assign the device to a
- * specific bus instead of the first bus with spare scsi ids.
- *
- * Ditch the calculated value and reload from option string (if
- * specified).
- */
- dinfo->unit = qemu_opt_get_number(dinfo->opts, "unit", -1);
- dinfo->bus = scsibus->busnr;
- scsidev = scsi_bus_legacy_add_drive(scsibus,
- blk_by_legacy_dinfo(dinfo),
- dinfo->unit, false, -1, NULL,
- &local_err);
- if (!scsidev) {
- error_report_err(local_err);
- return -1;
- }
- dinfo->unit = scsidev->id;
-
- if (printinfo)
- monitor_printf(mon, "OK bus %d, unit %d\n",
- scsibus->busnr, scsidev->id);
- return 0;
-}
-
-int pci_drive_hot_add(Monitor *mon, const QDict *qdict, DriveInfo *dinfo)
-{
- int pci_bus;
- unsigned slot;
- PCIBus *root = pci_find_primary_bus();
- PCIDevice *dev;
- const char *pci_addr = qdict_get_str(qdict, "pci_addr");
-
- switch (dinfo->type) {
- case IF_SCSI:
- if (!root) {
- monitor_printf(mon, "no primary PCI bus (if there are multiple"
- " PCI roots, you must use device_add instead)");
- goto err;
- }
- if (pci_read_devaddr(mon, pci_addr, &pci_bus, &slot)) {
- goto err;
- }
- dev = pci_find_device(root, pci_bus, PCI_DEVFN(slot, 0));
- if (!dev) {
- monitor_printf(mon, "no pci device with address %s\n", pci_addr);
- goto err;
- }
- if (scsi_hot_add(mon, &dev->qdev, dinfo, 1) != 0) {
- goto err;
- }
- break;
- default:
- monitor_printf(mon, "Can't hot-add drive to type %d\n", dinfo->type);
- goto err;
- }
-
- return 0;
-err:
- return -1;
-}
-
-static PCIDevice *qemu_pci_hot_add_storage(Monitor *mon,
- const char *devaddr,
- const char *opts)
-{
- PCIDevice *dev;
- DriveInfo *dinfo = NULL;
- int type = -1;
- char buf[128];
- PCIBus *root = pci_find_primary_bus();
- PCIBus *bus;
- int devfn;
-
- if (get_param_value(buf, sizeof(buf), "if", opts)) {
- if (!strcmp(buf, "scsi"))
- type = IF_SCSI;
- else if (!strcmp(buf, "virtio")) {
- type = IF_VIRTIO;
- } else {
- monitor_printf(mon, "type %s not a hotpluggable PCI device.\n", buf);
- return NULL;
- }
- } else {
- monitor_printf(mon, "no if= specified\n");
- return NULL;
- }
-
- if (get_param_value(buf, sizeof(buf), "file", opts)) {
- dinfo = add_init_drive(opts);
- if (!dinfo)
- return NULL;
- if (dinfo->devaddr) {
- monitor_printf(mon, "Parameter addr not supported\n");
- return NULL;
- }
- } else {
- dinfo = NULL;
- }
-
- if (!root) {
- monitor_printf(mon, "no primary PCI bus (if there are multiple"
- " PCI roots, you must use device_add instead)");
- return NULL;
- }
- bus = pci_get_bus_devfn(&devfn, root, devaddr);
- if (!bus) {
- monitor_printf(mon, "Invalid PCI device address %s\n", devaddr);
- return NULL;
- }
- if (!qbus_is_hotpluggable(BUS(bus))) {
- monitor_printf(mon, "PCI bus doesn't support hotplug\n");
- return NULL;
- }
-
- switch (type) {
- case IF_SCSI:
- dev = pci_create(bus, devfn, "lsi53c895a");
- if (qdev_init(&dev->qdev) < 0)
- dev = NULL;
- if (dev && dinfo) {
- if (scsi_hot_add(mon, &dev->qdev, dinfo, 0) != 0) {
- qdev_unplug(&dev->qdev, NULL);
- dev = NULL;
- }
- }
- break;
- case IF_VIRTIO:
- if (!dinfo) {
- monitor_printf(mon, "virtio requires a backing file/device.\n");
- return NULL;
- }
- dev = pci_create(bus, devfn, "virtio-blk-pci");
- if (qdev_prop_set_drive(&dev->qdev, "drive",
- blk_by_legacy_dinfo(dinfo)) < 0) {
- object_unparent(OBJECT(dev));
- dev = NULL;
- break;
- }
- if (qdev_init(&dev->qdev) < 0)
- dev = NULL;
- break;
- default:
- dev = NULL;
- }
- return dev;
-}
-
-void hmp_pci_add(Monitor *mon, const QDict *qdict)
-{
- PCIDevice *dev = NULL;
- const char *pci_addr = qdict_get_str(qdict, "pci_addr");
- const char *type = qdict_get_str(qdict, "type");
- const char *opts = qdict_get_try_str(qdict, "opts");
-
- /* strip legacy tag */
- if (!strncmp(pci_addr, "pci_addr=", 9)) {
- pci_addr += 9;
- }
-
- if (!opts) {
- opts = "";
- }
-
- if (!strcmp(pci_addr, "auto"))
- pci_addr = NULL;
-
- if (strcmp(type, "nic") == 0) {
- dev = qemu_pci_hot_add_nic(mon, pci_addr, opts);
- } else if (strcmp(type, "storage") == 0) {
- dev = qemu_pci_hot_add_storage(mon, pci_addr, opts);
- } else {
- monitor_printf(mon, "invalid type: %s\n", type);
- }
-
- if (dev) {
- monitor_printf(mon, "OK root bus %s, bus %d, slot %d, function %d\n",
- pci_root_bus_path(dev),
- pci_bus_num(dev->bus), PCI_SLOT(dev->devfn),
- PCI_FUNC(dev->devfn));
- } else
- monitor_printf(mon, "failed to add %s\n", opts);
-}
-
-static int pci_device_hot_remove(Monitor *mon, const char *pci_addr)
-{
- PCIBus *root = pci_find_primary_bus();
- PCIDevice *d;
- int bus;
- unsigned slot;
- Error *local_err = NULL;
-
- if (!root) {
- monitor_printf(mon, "no primary PCI bus (if there are multiple"
- " PCI roots, you must use device_del instead)");
- return -1;
- }
-
- if (pci_read_devaddr(mon, pci_addr, &bus, &slot)) {
- return -1;
- }
-
- d = pci_find_device(root, bus, PCI_DEVFN(slot, 0));
- if (!d) {
- monitor_printf(mon, "slot %d empty\n", slot);
- return -1;
- }
-
- qdev_unplug(&d->qdev, &local_err);
- if (local_err) {
- monitor_printf(mon, "%s\n", error_get_pretty(local_err));
- error_free(local_err);
- return -1;
- }
-
- return 0;
-}
-
-void hmp_pci_del(Monitor *mon, const QDict *qdict)
-{
- pci_device_hot_remove(mon, qdict_get_str(qdict, "pci_addr"));
-}
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 31b222d8c0..cc5d946b8f 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -115,7 +115,7 @@ static const TypeInfo pcie_bus_info = {
static PCIBus *pci_find_bus_nr(PCIBus *bus, int bus_num);
static void pci_update_mappings(PCIDevice *d);
static void pci_irq_handler(void *opaque, int irq_num, int level);
-static int pci_add_option_rom(PCIDevice *pdev, bool is_default_rom);
+static void pci_add_option_rom(PCIDevice *pdev, bool is_default_rom, Error **);
static void pci_del_option_rom(PCIDevice *pdev);
static uint16_t pci_default_sub_vendor_id = PCI_SUBVENDOR_ID_REDHAT_QUMRANET;
@@ -539,8 +539,8 @@ static void pci_set_default_subsystem_id(PCIDevice *pci_dev)
* Parse [[<domain>:]<bus>:]<slot>, return -1 on error if funcp == NULL
* [[<domain>:]<bus>:]<slot>.<func>, return -1 on error
*/
-int pci_parse_devaddr(const char *addr, int *domp, int *busp,
- unsigned int *slotp, unsigned int *funcp)
+static int pci_parse_devaddr(const char *addr, int *domp, int *busp,
+ unsigned int *slotp, unsigned int *funcp)
{
const char *p;
char *e;
@@ -598,7 +598,8 @@ int pci_parse_devaddr(const char *addr, int *domp, int *busp,
return 0;
}
-PCIBus *pci_get_bus_devfn(int *devfnp, PCIBus *root, const char *devaddr)
+static PCIBus *pci_get_bus_devfn(int *devfnp, PCIBus *root,
+ const char *devaddr)
{
int dom, bus;
unsigned slot;
@@ -726,7 +727,7 @@ static void pci_init_mask_bridge(PCIDevice *d)
PCI_PREF_RANGE_TYPE_MASK);
}
-static int pci_init_multifunction(PCIBus *bus, PCIDevice *dev)
+static void pci_init_multifunction(PCIBus *bus, PCIDevice *dev, Error **errp)
{
uint8_t slot = PCI_SLOT(dev->devfn);
uint8_t func;
@@ -752,26 +753,25 @@ static int pci_init_multifunction(PCIBus *bus, PCIDevice *dev)
PCIDevice *f0 = bus->devices[PCI_DEVFN(slot, 0)];
if (f0 && !(f0->cap_present & QEMU_PCI_CAP_MULTIFUNCTION)) {
/* function 0 should set multifunction bit */
- error_report("PCI: single function device can't be populated "
- "in function %x.%x", slot, PCI_FUNC(dev->devfn));
- return -1;
+ error_setg(errp, "PCI: single function device can't be populated "
+ "in function %x.%x", slot, PCI_FUNC(dev->devfn));
+ return;
}
- return 0;
+ return;
}
if (dev->cap_present & QEMU_PCI_CAP_MULTIFUNCTION) {
- return 0;
+ return;
}
/* function 0 indicates single function, so function > 0 must be NULL */
for (func = 1; func < PCI_FUNC_MAX; ++func) {
if (bus->devices[PCI_DEVFN(slot, func)]) {
- error_report("PCI: %x.0 indicates single function, "
- "but %x.%x is already populated.",
- slot, slot, func);
- return -1;
+ error_setg(errp, "PCI: %x.0 indicates single function, "
+ "but %x.%x is already populated.",
+ slot, slot, func);
+ return;
}
}
- return 0;
}
static void pci_config_alloc(PCIDevice *pci_dev)
@@ -804,11 +804,13 @@ static void do_pci_unregister_device(PCIDevice *pci_dev)
/* -1 for devfn means auto assign */
static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
- const char *name, int devfn)
+ const char *name, int devfn,
+ Error **errp)
{
PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pci_dev);
PCIConfigReadFunc *config_read = pc->config_read;
PCIConfigWriteFunc *config_write = pc->config_write;
+ Error *local_err = NULL;
AddressSpace *dma_as;
if (devfn < 0) {
@@ -817,12 +819,15 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
if (!bus->devices[devfn])
goto found;
}
- error_report("PCI: no slot/function available for %s, all in use", name);
+ error_setg(errp, "PCI: no slot/function available for %s, all in use",
+ name);
return NULL;
found: ;
} else if (bus->devices[devfn]) {
- error_report("PCI: slot %d function %d not available for %s, in use by %s",
- PCI_SLOT(devfn), PCI_FUNC(devfn), name, bus->devices[devfn]->name);
+ error_setg(errp, "PCI: slot %d function %d not available for %s,"
+ " in use by %s",
+ PCI_SLOT(devfn), PCI_FUNC(devfn), name,
+ bus->devices[devfn]->name);
return NULL;
}
@@ -866,7 +871,9 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
if (pc->is_bridge) {
pci_init_mask_bridge(pci_dev);
}
- if (pci_init_multifunction(bus, pci_dev)) {
+ pci_init_multifunction(bus, pci_dev, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
do_pci_unregister_device(pci_dev);
return NULL;
}
@@ -897,7 +904,7 @@ static void pci_unregister_io_regions(PCIDevice *pci_dev)
pci_unregister_vga(pci_dev);
}
-static int pci_unregister_device(DeviceState *dev)
+static void pci_qdev_unrealize(DeviceState *dev, Error **errp)
{
PCIDevice *pci_dev = PCI_DEVICE(dev);
PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pci_dev);
@@ -910,7 +917,6 @@ static int pci_unregister_device(DeviceState *dev)
}
do_pci_unregister_device(pci_dev);
- return 0;
}
void pci_register_bar(PCIDevice *pci_dev, int region_num,
@@ -1605,10 +1611,9 @@ static const char * const pci_nic_names[] = {
};
/* Initialize a PCI NIC. */
-/* FIXME callers should check for failure, but don't */
-PCIDevice *pci_nic_init(NICInfo *nd, PCIBus *rootbus,
- const char *default_model,
- const char *default_devaddr)
+static PCIDevice *pci_nic_init(NICInfo *nd, PCIBus *rootbus,
+ const char *default_model,
+ const char *default_devaddr)
{
const char *devaddr = nd->devaddr ? nd->devaddr : default_devaddr;
PCIBus *bus;
@@ -1751,12 +1756,12 @@ PCIDevice *pci_find_device(PCIBus *bus, int bus_num, uint8_t devfn)
return bus->devices[devfn];
}
-static int pci_qdev_init(DeviceState *qdev)
+static void pci_qdev_realize(DeviceState *qdev, Error **errp)
{
PCIDevice *pci_dev = (PCIDevice *)qdev;
PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pci_dev);
+ Error *local_err = NULL;
PCIBus *bus;
- int rc;
bool is_default_rom;
/* initialize cap_present for pci_is_express() and pci_config_size() */
@@ -1767,15 +1772,16 @@ static int pci_qdev_init(DeviceState *qdev)
bus = PCI_BUS(qdev_get_parent_bus(qdev));
pci_dev = do_pci_register_device(pci_dev, bus,
object_get_typename(OBJECT(qdev)),
- pci_dev->devfn);
+ pci_dev->devfn, errp);
if (pci_dev == NULL)
- return -1;
+ return;
- if (pc->init) {
- rc = pc->init(pci_dev);
- if (rc != 0) {
+ if (pc->realize) {
+ pc->realize(pci_dev, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
do_pci_unregister_device(pci_dev);
- return rc;
+ return;
}
}
@@ -1786,13 +1792,24 @@ static int pci_qdev_init(DeviceState *qdev)
is_default_rom = true;
}
- rc = pci_add_option_rom(pci_dev, is_default_rom);
- if (rc != 0) {
- pci_unregister_device(DEVICE(pci_dev));
- return rc;
+ pci_add_option_rom(pci_dev, is_default_rom, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ pci_qdev_unrealize(DEVICE(pci_dev), NULL);
+ return;
}
+}
- return 0;
+static void pci_default_realize(PCIDevice *dev, Error **errp)
+{
+ PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
+
+ if (pc->init) {
+ if (pc->init(dev) < 0) {
+ error_setg(errp, "Device initialization failed");
+ return;
+ }
+ }
}
PCIDevice *pci_create_multifunction(PCIBus *bus, int devfn, bool multifunction,
@@ -1932,7 +1949,8 @@ static void pci_patch_ids(PCIDevice *pdev, uint8_t *ptr, int size)
}
/* Add an option rom for the device */
-static int pci_add_option_rom(PCIDevice *pdev, bool is_default_rom)
+static void pci_add_option_rom(PCIDevice *pdev, bool is_default_rom,
+ Error **errp)
{
int size;
char *path;
@@ -1941,9 +1959,9 @@ static int pci_add_option_rom(PCIDevice *pdev, bool is_default_rom)
const VMStateDescription *vmsd;
if (!pdev->romfile)
- return 0;
+ return;
if (strlen(pdev->romfile) == 0)
- return 0;
+ return;
if (!pdev->rom_bar) {
/*
@@ -1957,7 +1975,9 @@ static int pci_add_option_rom(PCIDevice *pdev, bool is_default_rom)
* if the rom bar is disabled.
*/
if (DEVICE(pdev)->hotplugged) {
- return -1;
+ error_setg(errp, "Hot-plugged device without ROM bar"
+ " can't have an option ROM");
+ return;
}
if (class == 0x0300) {
@@ -1965,7 +1985,7 @@ static int pci_add_option_rom(PCIDevice *pdev, bool is_default_rom)
} else {
rom_add_option(pdev->romfile, -1);
}
- return 0;
+ return;
}
path = qemu_find_file(QEMU_FILE_TYPE_BIOS, pdev->romfile);
@@ -1975,15 +1995,13 @@ static int pci_add_option_rom(PCIDevice *pdev, bool is_default_rom)
size = get_image_size(path);
if (size < 0) {
- error_report("%s: failed to find romfile \"%s\"",
- __func__, pdev->romfile);
+ error_setg(errp, "failed to find romfile \"%s\"", pdev->romfile);
g_free(path);
- return -1;
+ return;
} else if (size == 0) {
- error_report("%s: ignoring empty romfile \"%s\"",
- __func__, pdev->romfile);
+ error_setg(errp, "romfile \"%s\" is empty", pdev->romfile);
g_free(path);
- return -1;
+ return;
}
if (size & (size - 1)) {
size = 1 << qemu_fls(size);
@@ -2009,8 +2027,6 @@ static int pci_add_option_rom(PCIDevice *pdev, bool is_default_rom)
}
pci_register_bar(pdev, PCI_ROM_SLOT, 0, &pdev->rom);
-
- return 0;
}
static void pci_del_option_rom(PCIDevice *pdev)
@@ -2291,10 +2307,13 @@ MemoryRegion *pci_address_space_io(PCIDevice *dev)
static void pci_device_class_init(ObjectClass *klass, void *data)
{
DeviceClass *k = DEVICE_CLASS(klass);
- k->init = pci_qdev_init;
- k->exit = pci_unregister_device;
+ PCIDeviceClass *pc = PCI_DEVICE_CLASS(klass);
+
+ k->realize = pci_qdev_realize;
+ k->unrealize = pci_qdev_unrealize;
k->bus_type = TYPE_PCI_BUS;
k->props = pci_props;
+ pc->realize = pci_default_realize;
}
AddressSpace *pci_device_iommu_address_space(PCIDevice *dev)
diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs
index 19d99200ae..437955d1d5 100644
--- a/hw/ppc/Makefile.objs
+++ b/hw/ppc/Makefile.objs
@@ -3,7 +3,7 @@ obj-y += ppc.o ppc_booke.o
# IBM pSeries (sPAPR)
obj-$(CONFIG_PSERIES) += spapr.o spapr_vio.o spapr_events.o
obj-$(CONFIG_PSERIES) += spapr_hcall.o spapr_iommu.o spapr_rtas.o
-obj-$(CONFIG_PSERIES) += spapr_pci.o
+obj-$(CONFIG_PSERIES) += spapr_pci.o spapr_rtc.o
ifeq ($(CONFIG_PCI)$(CONFIG_PSERIES)$(CONFIG_LINUX), yyy)
obj-y += spapr_pci_vfio.o
endif
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index 7e17d180c6..d51fb60f79 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -308,6 +308,7 @@ static int ppce500_load_device_tree(MachineState *machine,
}
fdt = load_device_tree(filename, &fdt_size);
+ g_free(filename);
if (!fdt) {
goto out;
}
@@ -706,17 +707,19 @@ static DeviceState *ppce500_init_mpic_qemu(PPCE500Params *params,
}
static DeviceState *ppce500_init_mpic_kvm(PPCE500Params *params,
- qemu_irq **irqs)
+ qemu_irq **irqs, Error **errp)
{
+ Error *err = NULL;
DeviceState *dev;
CPUState *cs;
- int r;
dev = qdev_create(NULL, TYPE_KVM_OPENPIC);
qdev_prop_set_uint32(dev, "model", params->mpic_version);
- r = qdev_init(dev);
- if (r) {
+ object_property_set_bool(OBJECT(dev), true, "realized", &err);
+ if (err) {
+ error_propagate(errp, err);
+ object_unparent(OBJECT(dev));
return NULL;
}
@@ -747,15 +750,15 @@ static qemu_irq *ppce500_init_mpic(PPCE500Params *params, MemoryRegion *ccsr,
"kernel_irqchip", true);
bool irqchip_required = qemu_opt_get_bool(machine_opts,
"kernel_irqchip", false);
+ Error *err = NULL;
if (irqchip_allowed) {
- dev = ppce500_init_mpic_kvm(params, irqs);
+ dev = ppce500_init_mpic_kvm(params, irqs, &err);
}
-
if (irqchip_required && !dev) {
- fprintf(stderr, "%s: irqchip requested but unavailable\n",
- __func__);
- abort();
+ error_report("kernel_irqchip requested but unavailable: %s",
+ error_get_pretty(err));
+ exit(1);
}
}
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 23cde20019..4aa979fbbf 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -110,17 +110,20 @@ struct sPAPRMachineState {
sPAPREnvironment *spapr;
static XICSState *try_create_xics(const char *type, int nr_servers,
- int nr_irqs)
+ int nr_irqs, Error **errp)
{
+ Error *err = NULL;
DeviceState *dev;
dev = qdev_create(NULL, type);
qdev_prop_set_uint32(dev, "nr_servers", nr_servers);
qdev_prop_set_uint32(dev, "nr_irqs", nr_irqs);
- if (qdev_init(dev) < 0) {
+ object_property_set_bool(OBJECT(dev), true, "realized", &err);
+ if (err) {
+ error_propagate(errp, err);
+ object_unparent(OBJECT(dev));
return NULL;
}
-
return XICS_COMMON(dev);
}
@@ -134,23 +137,19 @@ static XICSState *xics_system_init(int nr_servers, int nr_irqs)
"kernel_irqchip", true);
bool irqchip_required = qemu_opt_get_bool(machine_opts,
"kernel_irqchip", false);
+ Error *err = NULL;
+
if (irqchip_allowed) {
- icp = try_create_xics(TYPE_KVM_XICS, nr_servers, nr_irqs);
+ icp = try_create_xics(TYPE_KVM_XICS, nr_servers, nr_irqs, &err);
}
-
if (irqchip_required && !icp) {
- perror("Failed to create in-kernel XICS\n");
- abort();
+ error_report("kernel_irqchip requested but unavailable: %s",
+ error_get_pretty(err));
}
}
if (!icp) {
- icp = try_create_xics(TYPE_XICS, nr_servers, nr_irqs);
- }
-
- if (!icp) {
- perror("Failed to create XICS\n");
- abort();
+ icp = try_create_xics(TYPE_XICS, nr_servers, nr_irqs, &error_abort);
}
return icp;
@@ -994,6 +993,17 @@ static void spapr_create_nvram(sPAPREnvironment *spapr)
spapr->nvram = (struct sPAPRNVRAM *)dev;
}
+static void spapr_rtc_create(sPAPREnvironment *spapr)
+{
+ DeviceState *dev = qdev_create(NULL, TYPE_SPAPR_RTC);
+
+ qdev_init_nofail(dev);
+ spapr->rtc = dev;
+
+ object_property_add_alias(qdev_get_machine(), "rtc-time",
+ OBJECT(spapr->rtc), "date", NULL);
+}
+
/* Returns whether we want to use VGA or not */
static int spapr_vga_init(PCIBus *pci_bus)
{
@@ -1011,15 +1021,39 @@ static int spapr_vga_init(PCIBus *pci_bus)
}
}
+static int spapr_post_load(void *opaque, int version_id)
+{
+ sPAPREnvironment *spapr = (sPAPREnvironment *)opaque;
+ int err = 0;
+
+ /* In earlier versions, there was no seperate 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 */
+ if (version_id < 3) {
+ err = spapr_rtc_import_offset(spapr->rtc, spapr->rtc_offset);
+ }
+
+ return err;
+}
+
+static bool version_before_3(void *opaque, int version_id)
+{
+ return version_id < 3;
+}
+
static const VMStateDescription vmstate_spapr = {
.name = "spapr",
- .version_id = 2,
+ .version_id = 3,
.minimum_version_id = 1,
+ .post_load = spapr_post_load,
.fields = (VMStateField[]) {
- VMSTATE_UNUSED(4), /* used to be @next_irq */
+ /* used to be @next_irq */
+ VMSTATE_UNUSED_BUFFER(version_before_3, 0, 4),
/* RTC offset */
- VMSTATE_UINT64(rtc_offset, sPAPREnvironment),
+ VMSTATE_UINT64_TEST(rtc_offset, sPAPREnvironment, version_before_3),
+
VMSTATE_PPC_TIMEBASE_V(tb, sPAPREnvironment, 2),
VMSTATE_END_OF_LIST()
},
@@ -1491,6 +1525,9 @@ static void ppc_spapr_init(MachineState *machine)
/* Set up EPOW events infrastructure */
spapr_events_init(spapr);
+ /* Set up the RTC RTAS interfaces */
+ spapr_rtc_create(spapr);
+
/* Set up VIO bus */
spapr->vio_bus = spapr_vio_bus_init();
@@ -1759,11 +1796,22 @@ static const TypeInfo spapr_machine_info = {
},
};
+#define SPAPR_COMPAT_2_2 \
+ {\
+ .driver = TYPE_SPAPR_PCI_HOST_BRIDGE,\
+ .property = "mem_win_size",\
+ .value = "0x20000000",\
+ }
+
+#define SPAPR_COMPAT_2_1 \
+ SPAPR_COMPAT_2_2
+
static void spapr_machine_2_1_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
static GlobalProperty compat_props[] = {
HW_COMPAT_2_1,
+ SPAPR_COMPAT_2_1,
{ /* end of list */ }
};
@@ -1780,12 +1828,15 @@ static const TypeInfo spapr_machine_2_1_info = {
static void spapr_machine_2_2_class_init(ObjectClass *oc, void *data)
{
+ static GlobalProperty compat_props[] = {
+ SPAPR_COMPAT_2_2,
+ { /* end of list */ }
+ };
MachineClass *mc = MACHINE_CLASS(oc);
mc->name = "pseries-2.2";
mc->desc = "pSeries Logical Partition (PAPR compliant) v2.2";
- mc->alias = "pseries";
- mc->is_default = 1;
+ mc->compat_props = compat_props;
}
static const TypeInfo spapr_machine_2_2_info = {
@@ -1794,11 +1845,28 @@ static const TypeInfo spapr_machine_2_2_info = {
.class_init = spapr_machine_2_2_class_init,
};
+static void spapr_machine_2_3_class_init(ObjectClass *oc, void *data)
+{
+ MachineClass *mc = MACHINE_CLASS(oc);
+
+ mc->name = "pseries-2.3";
+ mc->desc = "pSeries Logical Partition (PAPR compliant) v2.3";
+ mc->alias = "pseries";
+ mc->is_default = 1;
+}
+
+static const TypeInfo spapr_machine_2_3_info = {
+ .name = TYPE_SPAPR_MACHINE "2.3",
+ .parent = TYPE_SPAPR_MACHINE,
+ .class_init = spapr_machine_2_3_class_init,
+};
+
static void spapr_machine_register_types(void)
{
type_register_static(&spapr_machine_info);
type_register_static(&spapr_machine_2_1_info);
type_register_static(&spapr_machine_2_2_info);
+ type_register_static(&spapr_machine_2_3_info);
}
type_init(spapr_machine_register_types)
diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c
index 1b6157dec4..283e96bca1 100644
--- a/hw/ppc/spapr_events.c
+++ b/hw/ppc/spapr_events.c
@@ -246,7 +246,7 @@ static void spapr_powerdown_req(Notifier *n, void *opaque)
maina->hdr.section_id = cpu_to_be16(RTAS_LOG_V6_SECTION_ID_MAINA);
maina->hdr.section_length = cpu_to_be16(sizeof(*maina));
/* FIXME: section version, subtype and creator id? */
- qemu_get_timedate(&tm, spapr->rtc_offset);
+ spapr_rtc_read(spapr->rtc, &tm, NULL);
year = tm.tm_year + 1900;
maina->creation_date = cpu_to_be32((to_bcd(year / 100) << 24)
| (to_bcd(year % 100) << 16)
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 86514472fe..4f76f1cbfe 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -731,12 +731,14 @@ static target_ulong h_set_mode_resource_le(PowerPCCPU *cpu,
CPU_FOREACH(cs) {
set_spr(cs, SPR_LPCR, 0, LPCR_ILE);
}
+ spapr_pci_switch_vga(true);
return H_SUCCESS;
case H_SET_MODE_ENDIAN_LITTLE:
CPU_FOREACH(cs) {
set_spr(cs, SPR_LPCR, LPCR_ILE, LPCR_ILE);
}
+ spapr_pci_switch_vga(false);
return H_SUCCESS;
}
diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c
index ba003da39e..f3990fdc32 100644
--- a/hw/ppc/spapr_iommu.c
+++ b/hw/ppc/spapr_iommu.c
@@ -25,6 +25,7 @@
#include "trace.h"
#include "hw/ppc/spapr.h"
+#include "hw/ppc/spapr_vio.h"
#include <libfdt.h>
@@ -73,9 +74,7 @@ static IOMMUTLBEntry spapr_tce_translate_iommu(MemoryRegion *iommu, hwaddr addr,
.perm = IOMMU_NONE,
};
- if (tcet->bypass) {
- ret.perm = IOMMU_RW;
- } else if ((addr >> tcet->page_shift) < tcet->nb_table) {
+ if ((addr >> tcet->page_shift) < tcet->nb_table) {
/* Check if we are in bound */
hwaddr page_mask = IOMMU_PAGE_MASK(tcet->page_shift);
@@ -91,10 +90,22 @@ static IOMMUTLBEntry spapr_tce_translate_iommu(MemoryRegion *iommu, hwaddr addr,
return ret;
}
+static int spapr_tce_table_post_load(void *opaque, int version_id)
+{
+ sPAPRTCETable *tcet = SPAPR_TCE_TABLE(opaque);
+
+ if (tcet->vdev) {
+ spapr_vio_set_bypass(tcet->vdev, tcet->bypass);
+ }
+
+ return 0;
+}
+
static const VMStateDescription vmstate_spapr_tce_table = {
.name = "spapr_iommu",
.version_id = 2,
.minimum_version_id = 2,
+ .post_load = spapr_tce_table_post_load,
.fields = (VMStateField []) {
/* Sanity check */
VMSTATE_UINT32_EQUAL(liobn, sPAPRTCETable),
@@ -132,7 +143,8 @@ static int spapr_tce_table_realize(DeviceState *dev)
trace_spapr_iommu_new_table(tcet->liobn, tcet, tcet->table, tcet->fd);
memory_region_init_iommu(&tcet->iommu, OBJECT(dev), &spapr_iommu_ops,
- "iommu-spapr", ram_size);
+ "iommu-spapr",
+ (uint64_t)tcet->nb_table << tcet->page_shift);
QLIST_INSERT_HEAD(&spapr_tce_tables, tcet, list);
@@ -192,17 +204,11 @@ MemoryRegion *spapr_tce_get_iommu(sPAPRTCETable *tcet)
return &tcet->iommu;
}
-void spapr_tce_set_bypass(sPAPRTCETable *tcet, bool bypass)
-{
- tcet->bypass = bypass;
-}
-
static void spapr_tce_reset(DeviceState *dev)
{
sPAPRTCETable *tcet = SPAPR_TCE_TABLE(dev);
size_t table_size = tcet->nb_table * sizeof(uint64_t);
- tcet->bypass = false;
memset(tcet->table, 0, table_size);
}
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 21b95b342c..05f4faca6e 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -406,6 +406,258 @@ static void rtas_ibm_query_interrupt_source_number(PowerPCCPU *cpu,
rtas_st(rets, 2, 1);/* 0 == level; 1 == edge */
}
+static void rtas_ibm_set_eeh_option(PowerPCCPU *cpu,
+ sPAPREnvironment *spapr,
+ uint32_t token, uint32_t nargs,
+ target_ulong args, uint32_t nret,
+ target_ulong rets)
+{
+ sPAPRPHBState *sphb;
+ sPAPRPHBClass *spc;
+ uint32_t addr, option;
+ uint64_t buid;
+ int ret;
+
+ if ((nargs != 4) || (nret != 1)) {
+ goto param_error_exit;
+ }
+
+ buid = ((uint64_t)rtas_ld(args, 1) << 32) | rtas_ld(args, 2);
+ addr = rtas_ld(args, 0);
+ option = rtas_ld(args, 3);
+
+ sphb = find_phb(spapr, buid);
+ if (!sphb) {
+ goto param_error_exit;
+ }
+
+ spc = SPAPR_PCI_HOST_BRIDGE_GET_CLASS(sphb);
+ if (!spc->eeh_set_option) {
+ goto param_error_exit;
+ }
+
+ ret = spc->eeh_set_option(sphb, addr, option);
+ rtas_st(rets, 0, ret);
+ return;
+
+param_error_exit:
+ rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
+}
+
+static void rtas_ibm_get_config_addr_info2(PowerPCCPU *cpu,
+ sPAPREnvironment *spapr,
+ uint32_t token, uint32_t nargs,
+ target_ulong args, uint32_t nret,
+ target_ulong rets)
+{
+ sPAPRPHBState *sphb;
+ sPAPRPHBClass *spc;
+ PCIDevice *pdev;
+ uint32_t addr, option;
+ uint64_t buid;
+
+ if ((nargs != 4) || (nret != 2)) {
+ goto param_error_exit;
+ }
+
+ buid = ((uint64_t)rtas_ld(args, 1) << 32) | rtas_ld(args, 2);
+ sphb = find_phb(spapr, buid);
+ if (!sphb) {
+ goto param_error_exit;
+ }
+
+ spc = SPAPR_PCI_HOST_BRIDGE_GET_CLASS(sphb);
+ if (!spc->eeh_set_option) {
+ goto param_error_exit;
+ }
+
+ /*
+ * We always have PE address of form "00BB0001". "BB"
+ * represents the bus number of PE's primary bus.
+ */
+ option = rtas_ld(args, 3);
+ switch (option) {
+ case RTAS_GET_PE_ADDR:
+ addr = rtas_ld(args, 0);
+ pdev = find_dev(spapr, buid, addr);
+ if (!pdev) {
+ goto param_error_exit;
+ }
+
+ rtas_st(rets, 1, (pci_bus_num(pdev->bus) << 16) + 1);
+ break;
+ case RTAS_GET_PE_MODE:
+ rtas_st(rets, 1, RTAS_PE_MODE_SHARED);
+ break;
+ default:
+ goto param_error_exit;
+ }
+
+ rtas_st(rets, 0, RTAS_OUT_SUCCESS);
+ return;
+
+param_error_exit:
+ rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
+}
+
+static void rtas_ibm_read_slot_reset_state2(PowerPCCPU *cpu,
+ sPAPREnvironment *spapr,
+ uint32_t token, uint32_t nargs,
+ target_ulong args, uint32_t nret,
+ target_ulong rets)
+{
+ sPAPRPHBState *sphb;
+ sPAPRPHBClass *spc;
+ uint64_t buid;
+ int state, ret;
+
+ if ((nargs != 3) || (nret != 4 && nret != 5)) {
+ goto param_error_exit;
+ }
+
+ buid = ((uint64_t)rtas_ld(args, 1) << 32) | rtas_ld(args, 2);
+ sphb = find_phb(spapr, buid);
+ if (!sphb) {
+ goto param_error_exit;
+ }
+
+ spc = SPAPR_PCI_HOST_BRIDGE_GET_CLASS(sphb);
+ if (!spc->eeh_get_state) {
+ goto param_error_exit;
+ }
+
+ ret = spc->eeh_get_state(sphb, &state);
+ rtas_st(rets, 0, ret);
+ if (ret != RTAS_OUT_SUCCESS) {
+ return;
+ }
+
+ rtas_st(rets, 1, state);
+ rtas_st(rets, 2, RTAS_EEH_SUPPORT);
+ rtas_st(rets, 3, RTAS_EEH_PE_UNAVAIL_INFO);
+ if (nret >= 5) {
+ rtas_st(rets, 4, RTAS_EEH_PE_RECOVER_INFO);
+ }
+ return;
+
+param_error_exit:
+ rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
+}
+
+static void rtas_ibm_set_slot_reset(PowerPCCPU *cpu,
+ sPAPREnvironment *spapr,
+ uint32_t token, uint32_t nargs,
+ target_ulong args, uint32_t nret,
+ target_ulong rets)
+{
+ sPAPRPHBState *sphb;
+ sPAPRPHBClass *spc;
+ uint32_t option;
+ uint64_t buid;
+ int ret;
+
+ if ((nargs != 4) || (nret != 1)) {
+ goto param_error_exit;
+ }
+
+ buid = ((uint64_t)rtas_ld(args, 1) << 32) | rtas_ld(args, 2);
+ option = rtas_ld(args, 3);
+ sphb = find_phb(spapr, buid);
+ if (!sphb) {
+ goto param_error_exit;
+ }
+
+ spc = SPAPR_PCI_HOST_BRIDGE_GET_CLASS(sphb);
+ if (!spc->eeh_reset) {
+ goto param_error_exit;
+ }
+
+ ret = spc->eeh_reset(sphb, option);
+ rtas_st(rets, 0, ret);
+ return;
+
+param_error_exit:
+ rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
+}
+
+static void rtas_ibm_configure_pe(PowerPCCPU *cpu,
+ sPAPREnvironment *spapr,
+ uint32_t token, uint32_t nargs,
+ target_ulong args, uint32_t nret,
+ target_ulong rets)
+{
+ sPAPRPHBState *sphb;
+ sPAPRPHBClass *spc;
+ uint64_t buid;
+ int ret;
+
+ if ((nargs != 3) || (nret != 1)) {
+ goto param_error_exit;
+ }
+
+ buid = ((uint64_t)rtas_ld(args, 1) << 32) | rtas_ld(args, 2);
+ sphb = find_phb(spapr, buid);
+ if (!sphb) {
+ goto param_error_exit;
+ }
+
+ spc = SPAPR_PCI_HOST_BRIDGE_GET_CLASS(sphb);
+ if (!spc->eeh_configure) {
+ goto param_error_exit;
+ }
+
+ ret = spc->eeh_configure(sphb);
+ rtas_st(rets, 0, ret);
+ return;
+
+param_error_exit:
+ rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
+}
+
+/* To support it later */
+static void rtas_ibm_slot_error_detail(PowerPCCPU *cpu,
+ sPAPREnvironment *spapr,
+ uint32_t token, uint32_t nargs,
+ target_ulong args, uint32_t nret,
+ target_ulong rets)
+{
+ sPAPRPHBState *sphb;
+ sPAPRPHBClass *spc;
+ int option;
+ uint64_t buid;
+
+ if ((nargs != 8) || (nret != 1)) {
+ goto param_error_exit;
+ }
+
+ buid = ((uint64_t)rtas_ld(args, 1) << 32) | rtas_ld(args, 2);
+ sphb = find_phb(spapr, buid);
+ if (!sphb) {
+ goto param_error_exit;
+ }
+
+ spc = SPAPR_PCI_HOST_BRIDGE_GET_CLASS(sphb);
+ if (!spc->eeh_set_option) {
+ goto param_error_exit;
+ }
+
+ option = rtas_ld(args, 7);
+ switch (option) {
+ case RTAS_SLOT_TEMP_ERR_LOG:
+ case RTAS_SLOT_PERM_ERR_LOG:
+ break;
+ default:
+ goto param_error_exit;
+ }
+
+ /* We don't have error log yet */
+ rtas_st(rets, 0, RTAS_OUT_NO_ERRORS_FOUND);
+ return;
+
+param_error_exit:
+ rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
+}
+
static int pci_spapr_swizzle(int slot, int pin)
{
return (slot + pin) % PCI_NUM_PINS;
@@ -501,6 +753,12 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
return;
}
+ if (sphb->index > SPAPR_PCI_MAX_INDEX) {
+ error_setg(errp, "\"index\" for PAPR PHB is too large (max %u)",
+ SPAPR_PCI_MAX_INDEX);
+ return;
+ }
+
sphb->buid = SPAPR_PCI_BASE_BUID + sphb->index;
sphb->dma_liobn = SPAPR_PCI_BASE_LIOBN + sphb->index;
@@ -669,7 +927,7 @@ static void spapr_phb_reset(DeviceState *qdev)
}
static Property spapr_phb_properties[] = {
- DEFINE_PROP_INT32("index", sPAPRPHBState, index, -1),
+ DEFINE_PROP_UINT32("index", sPAPRPHBState, index, -1),
DEFINE_PROP_UINT64("buid", sPAPRPHBState, buid, -1),
DEFINE_PROP_UINT32("liobn", sPAPRPHBState, dma_liobn, -1),
DEFINE_PROP_UINT64("mem_win_addr", sPAPRPHBState, mem_win_addr, -1),
@@ -862,6 +1120,10 @@ int spapr_populate_pci_dt(sPAPRPHBState *phb,
int bus_off, i, j;
char nodename[256];
uint32_t bus_range[] = { cpu_to_be32(0), cpu_to_be32(0xff) };
+ const uint64_t mmiosize = memory_region_size(&phb->memwindow);
+ const uint64_t w32max = (1ULL << 32) - SPAPR_PCI_MEM_WIN_BUS_OFFSET;
+ const uint64_t w32size = MIN(w32max, mmiosize);
+ const uint64_t w64size = (mmiosize > w32size) ? (mmiosize - w32size) : 0;
struct {
uint32_t hi;
uint64_t child;
@@ -876,9 +1138,15 @@ int spapr_populate_pci_dt(sPAPRPHBState *phb,
{
cpu_to_be32(b_ss(2)), cpu_to_be64(SPAPR_PCI_MEM_WIN_BUS_OFFSET),
cpu_to_be64(phb->mem_win_addr),
- cpu_to_be64(memory_region_size(&phb->memwindow)),
+ cpu_to_be64(w32size),
+ },
+ {
+ cpu_to_be32(b_ss(3)), cpu_to_be64(1ULL << 32),
+ cpu_to_be64(phb->mem_win_addr + w32size),
+ cpu_to_be64(w64size)
},
};
+ const unsigned sizeof_ranges = (w64size ? 3 : 2) * sizeof(ranges[0]);
uint64_t bus_reg[] = { cpu_to_be64(phb->buid), 0 };
uint32_t interrupt_map_mask[] = {
cpu_to_be32(b_ddddd(-1)|b_fff(0)), 0x0, 0x0, cpu_to_be32(-1)};
@@ -907,7 +1175,7 @@ int spapr_populate_pci_dt(sPAPRPHBState *phb,
_FDT(fdt_setprop_cell(fdt, bus_off, "#interrupt-cells", 0x1));
_FDT(fdt_setprop(fdt, bus_off, "used-by-rtas", NULL, 0));
_FDT(fdt_setprop(fdt, bus_off, "bus-range", &bus_range, sizeof(bus_range)));
- _FDT(fdt_setprop(fdt, bus_off, "ranges", &ranges, sizeof(ranges)));
+ _FDT(fdt_setprop(fdt, bus_off, "ranges", &ranges, sizeof_ranges));
_FDT(fdt_setprop(fdt, bus_off, "reg", &bus_reg, sizeof(bus_reg)));
_FDT(fdt_setprop_cell(fdt, bus_off, "ibm,pci-config-space-type", 0x1));
_FDT(fdt_setprop_cell(fdt, bus_off, "ibm,pe-total-#msi", XICS_IRQS));
@@ -958,6 +1226,25 @@ void spapr_pci_rtas_init(void)
spapr_rtas_register(RTAS_IBM_CHANGE_MSI, "ibm,change-msi",
rtas_ibm_change_msi);
}
+
+ spapr_rtas_register(RTAS_IBM_SET_EEH_OPTION,
+ "ibm,set-eeh-option",
+ rtas_ibm_set_eeh_option);
+ spapr_rtas_register(RTAS_IBM_GET_CONFIG_ADDR_INFO2,
+ "ibm,get-config-addr-info2",
+ rtas_ibm_get_config_addr_info2);
+ spapr_rtas_register(RTAS_IBM_READ_SLOT_RESET_STATE2,
+ "ibm,read-slot-reset-state2",
+ rtas_ibm_read_slot_reset_state2);
+ spapr_rtas_register(RTAS_IBM_SET_SLOT_RESET,
+ "ibm,set-slot-reset",
+ rtas_ibm_set_slot_reset);
+ spapr_rtas_register(RTAS_IBM_CONFIGURE_PE,
+ "ibm,configure-pe",
+ rtas_ibm_configure_pe);
+ spapr_rtas_register(RTAS_IBM_SLOT_ERROR_DETAIL,
+ "ibm,slot-error-detail",
+ rtas_ibm_slot_error_detail);
}
static void spapr_pci_register_types(void)
@@ -966,3 +1253,31 @@ static void spapr_pci_register_types(void)
}
type_init(spapr_pci_register_types)
+
+static int spapr_switch_one_vga(DeviceState *dev, void *opaque)
+{
+ bool be = *(bool *)opaque;
+
+ if (object_dynamic_cast(OBJECT(dev), "VGA")
+ || object_dynamic_cast(OBJECT(dev), "secondary-vga")) {
+ object_property_set_bool(OBJECT(dev), be, "big-endian-framebuffer",
+ &error_abort);
+ }
+ return 0;
+}
+
+void spapr_pci_switch_vga(bool big_endian)
+{
+ sPAPRPHBState *sphb;
+
+ /*
+ * For backward compatibility with existing guests, we switch
+ * the endianness of the VGA controller when changing the guest
+ * interrupt mode
+ */
+ QLIST_FOREACH(sphb, &spapr->phbs, list) {
+ BusState *bus = &PCI_HOST_BRIDGE(sphb)->bus->qbus;
+ qbus_walk_children(bus, spapr_switch_one_vga, NULL, NULL, NULL,
+ &big_endian);
+ }
+}
diff --git a/hw/ppc/spapr_pci_vfio.c b/hw/ppc/spapr_pci_vfio.c
index 144912bf54..99a1be5113 100644
--- a/hw/ppc/spapr_pci_vfio.c
+++ b/hw/ppc/spapr_pci_vfio.c
@@ -76,6 +76,117 @@ static void spapr_phb_vfio_reset(DeviceState *qdev)
/* Do nothing */
}
+static int spapr_phb_vfio_eeh_set_option(sPAPRPHBState *sphb,
+ unsigned int addr, int option)
+{
+ sPAPRPHBVFIOState *svphb = SPAPR_PCI_VFIO_HOST_BRIDGE(sphb);
+ struct vfio_eeh_pe_op op = { .argsz = sizeof(op) };
+ int ret;
+
+ switch (option) {
+ case RTAS_EEH_DISABLE:
+ op.op = VFIO_EEH_PE_DISABLE;
+ break;
+ case RTAS_EEH_ENABLE: {
+ PCIHostState *phb;
+ PCIDevice *pdev;
+
+ /*
+ * The EEH functionality is enabled on basis of PCI device,
+ * instead of PE. We need check the validity of the PCI
+ * device address.
+ */
+ phb = PCI_HOST_BRIDGE(sphb);
+ pdev = pci_find_device(phb->bus,
+ (addr >> 16) & 0xFF, (addr >> 8) & 0xFF);
+ if (!pdev) {
+ return RTAS_OUT_PARAM_ERROR;
+ }
+
+ op.op = VFIO_EEH_PE_ENABLE;
+ break;
+ }
+ case RTAS_EEH_THAW_IO:
+ op.op = VFIO_EEH_PE_UNFREEZE_IO;
+ break;
+ case RTAS_EEH_THAW_DMA:
+ op.op = VFIO_EEH_PE_UNFREEZE_DMA;
+ break;
+ default:
+ return RTAS_OUT_PARAM_ERROR;
+ }
+
+ ret = vfio_container_ioctl(&svphb->phb.iommu_as, svphb->iommugroupid,
+ VFIO_EEH_PE_OP, &op);
+ if (ret < 0) {
+ return RTAS_OUT_HW_ERROR;
+ }
+
+ return RTAS_OUT_SUCCESS;
+}
+
+static int spapr_phb_vfio_eeh_get_state(sPAPRPHBState *sphb, int *state)
+{
+ sPAPRPHBVFIOState *svphb = SPAPR_PCI_VFIO_HOST_BRIDGE(sphb);
+ struct vfio_eeh_pe_op op = { .argsz = sizeof(op) };
+ int ret;
+
+ op.op = VFIO_EEH_PE_GET_STATE;
+ ret = vfio_container_ioctl(&svphb->phb.iommu_as, svphb->iommugroupid,
+ VFIO_EEH_PE_OP, &op);
+ if (ret < 0) {
+ return RTAS_OUT_PARAM_ERROR;
+ }
+
+ *state = ret;
+ return RTAS_OUT_SUCCESS;
+}
+
+static int spapr_phb_vfio_eeh_reset(sPAPRPHBState *sphb, int option)
+{
+ sPAPRPHBVFIOState *svphb = SPAPR_PCI_VFIO_HOST_BRIDGE(sphb);
+ struct vfio_eeh_pe_op op = { .argsz = sizeof(op) };
+ int ret;
+
+ switch (option) {
+ case RTAS_SLOT_RESET_DEACTIVATE:
+ op.op = VFIO_EEH_PE_RESET_DEACTIVATE;
+ break;
+ case RTAS_SLOT_RESET_HOT:
+ op.op = VFIO_EEH_PE_RESET_HOT;
+ break;
+ case RTAS_SLOT_RESET_FUNDAMENTAL:
+ op.op = VFIO_EEH_PE_RESET_FUNDAMENTAL;
+ break;
+ default:
+ return RTAS_OUT_PARAM_ERROR;
+ }
+
+ ret = vfio_container_ioctl(&svphb->phb.iommu_as, svphb->iommugroupid,
+ VFIO_EEH_PE_OP, &op);
+ if (ret < 0) {
+ return RTAS_OUT_HW_ERROR;
+ }
+
+ return RTAS_OUT_SUCCESS;
+}
+
+static int spapr_phb_vfio_eeh_configure(sPAPRPHBState *sphb)
+{
+ sPAPRPHBVFIOState *svphb = SPAPR_PCI_VFIO_HOST_BRIDGE(sphb);
+ struct vfio_eeh_pe_op op = { .argsz = sizeof(op) };
+ int ret;
+
+ op.op = VFIO_EEH_PE_CONFIGURE;
+ ret = vfio_container_ioctl(&svphb->phb.iommu_as, svphb->iommugroupid,
+ VFIO_EEH_PE_OP, &op);
+ if (ret < 0) {
+ return RTAS_OUT_PARAM_ERROR;
+ }
+
+ return RTAS_OUT_SUCCESS;
+}
+
static void spapr_phb_vfio_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
@@ -84,6 +195,10 @@ static void spapr_phb_vfio_class_init(ObjectClass *klass, void *data)
dc->props = spapr_phb_vfio_properties;
dc->reset = spapr_phb_vfio_reset;
spc->finish_realize = spapr_phb_vfio_finish_realize;
+ spc->eeh_set_option = spapr_phb_vfio_eeh_set_option;
+ spc->eeh_get_state = spapr_phb_vfio_eeh_get_state;
+ spc->eeh_reset = spapr_phb_vfio_eeh_reset;
+ spc->eeh_configure = spapr_phb_vfio_eeh_configure;
}
static const TypeInfo spapr_phb_vfio_info = {
diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index 2ec2a8e4d1..0f1ae55828 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -52,51 +52,6 @@ static void rtas_display_character(PowerPCCPU *cpu, sPAPREnvironment *spapr,
}
}
-static void rtas_get_time_of_day(PowerPCCPU *cpu, sPAPREnvironment *spapr,
- uint32_t token, uint32_t nargs,
- target_ulong args,
- uint32_t nret, target_ulong rets)
-{
- struct tm tm;
-
- if (nret != 8) {
- rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
- return;
- }
-
- qemu_get_timedate(&tm, spapr->rtc_offset);
-
- rtas_st(rets, 0, RTAS_OUT_SUCCESS);
- rtas_st(rets, 1, tm.tm_year + 1900);
- rtas_st(rets, 2, tm.tm_mon + 1);
- rtas_st(rets, 3, tm.tm_mday);
- rtas_st(rets, 4, tm.tm_hour);
- rtas_st(rets, 5, tm.tm_min);
- rtas_st(rets, 6, tm.tm_sec);
- rtas_st(rets, 7, 0); /* we don't do nanoseconds */
-}
-
-static void rtas_set_time_of_day(PowerPCCPU *cpu, sPAPREnvironment *spapr,
- uint32_t token, uint32_t nargs,
- target_ulong args,
- uint32_t nret, target_ulong rets)
-{
- struct tm tm;
-
- tm.tm_year = rtas_ld(args, 0) - 1900;
- tm.tm_mon = rtas_ld(args, 1) - 1;
- tm.tm_mday = rtas_ld(args, 2);
- tm.tm_hour = rtas_ld(args, 3);
- tm.tm_min = rtas_ld(args, 4);
- tm.tm_sec = rtas_ld(args, 5);
-
- /* Just generate a monitor event for the change */
- qapi_event_send_rtc_change(qemu_timedate_diff(&tm), &error_abort);
- spapr->rtc_offset = qemu_timedate_diff(&tm);
-
- rtas_st(rets, 0, RTAS_OUT_SUCCESS);
-}
-
static void rtas_power_off(PowerPCCPU *cpu, sPAPREnvironment *spapr,
uint32_t token, uint32_t nargs, target_ulong args,
uint32_t nret, target_ulong rets)
@@ -400,10 +355,6 @@ static void core_rtas_register_types(void)
{
spapr_rtas_register(RTAS_DISPLAY_CHARACTER, "display-character",
rtas_display_character);
- spapr_rtas_register(RTAS_GET_TIME_OF_DAY, "get-time-of-day",
- rtas_get_time_of_day);
- spapr_rtas_register(RTAS_SET_TIME_OF_DAY, "set-time-of-day",
- rtas_set_time_of_day);
spapr_rtas_register(RTAS_POWER_OFF, "power-off", rtas_power_off);
spapr_rtas_register(RTAS_SYSTEM_REBOOT, "system-reboot",
rtas_system_reboot);
diff --git a/hw/ppc/spapr_rtc.c b/hw/ppc/spapr_rtc.c
new file mode 100644
index 0000000000..83eb7c186f
--- /dev/null
+++ b/hw/ppc/spapr_rtc.c
@@ -0,0 +1,212 @@
+/*
+ * QEMU PowerPC pSeries Logical Partition (aka sPAPR) hardware System Emulator
+ *
+ * RTAS Real Time Clock
+ *
+ * Copyright (c) 2010-2011 David Gibson, IBM Corporation.
+ * Copyright 2014 David Gibson, Red Hat.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+#include "cpu.h"
+#include "sysemu/sysemu.h"
+#include "hw/ppc/spapr.h"
+#include "qapi-event.h"
+
+#define SPAPR_RTC(obj) \
+ OBJECT_CHECK(sPAPRRTCState, (obj), TYPE_SPAPR_RTC)
+
+typedef struct sPAPRRTCState sPAPRRTCState;
+struct sPAPRRTCState {
+ /*< private >*/
+ SysBusDevice parent_obj;
+ int64_t ns_offset;
+};
+
+#define NSEC_PER_SEC 1000000000LL
+
+void spapr_rtc_read(DeviceState *dev, struct tm *tm, uint32_t *ns)
+{
+ sPAPRRTCState *rtc = SPAPR_RTC(dev);
+ int64_t host_ns = qemu_clock_get_ns(rtc_clock);
+ int64_t guest_ns;
+ time_t guest_s;
+
+ assert(rtc);
+
+ guest_ns = host_ns + rtc->ns_offset;
+ guest_s = guest_ns / NSEC_PER_SEC;
+
+ if (tm) {
+ gmtime_r(&guest_s, tm);
+ }
+ if (ns) {
+ *ns = guest_ns;
+ }
+}
+
+int spapr_rtc_import_offset(DeviceState *dev, int64_t legacy_offset)
+{
+ sPAPRRTCState *rtc;
+
+ if (!dev) {
+ return -ENODEV;
+ }
+
+ rtc = SPAPR_RTC(dev);
+
+ rtc->ns_offset = legacy_offset * NSEC_PER_SEC;
+
+ return 0;
+}
+
+static void rtas_get_time_of_day(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+ uint32_t token, uint32_t nargs,
+ target_ulong args,
+ uint32_t nret, target_ulong rets)
+{
+ struct tm tm;
+ uint32_t ns;
+
+ if ((nargs != 0) || (nret != 8)) {
+ rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
+ return;
+ }
+
+ if (!spapr->rtc) {
+ rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
+ return;
+ }
+
+ spapr_rtc_read(spapr->rtc, &tm, &ns);
+
+ rtas_st(rets, 0, RTAS_OUT_SUCCESS);
+ rtas_st(rets, 1, tm.tm_year + 1900);
+ rtas_st(rets, 2, tm.tm_mon + 1);
+ rtas_st(rets, 3, tm.tm_mday);
+ rtas_st(rets, 4, tm.tm_hour);
+ rtas_st(rets, 5, tm.tm_min);
+ rtas_st(rets, 6, tm.tm_sec);
+ rtas_st(rets, 7, ns);
+}
+
+static void rtas_set_time_of_day(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+ uint32_t token, uint32_t nargs,
+ target_ulong args,
+ uint32_t nret, target_ulong rets)
+{
+ sPAPRRTCState *rtc;
+ struct tm tm;
+ time_t new_s;
+ int64_t host_ns;
+
+ if ((nargs != 7) || (nret != 1)) {
+ rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
+ return;
+ }
+
+ if (!spapr->rtc) {
+ rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
+ return;
+ }
+
+ tm.tm_year = rtas_ld(args, 0) - 1900;
+ tm.tm_mon = rtas_ld(args, 1) - 1;
+ tm.tm_mday = rtas_ld(args, 2);
+ tm.tm_hour = rtas_ld(args, 3);
+ tm.tm_min = rtas_ld(args, 4);
+ tm.tm_sec = rtas_ld(args, 5);
+
+ new_s = mktimegm(&tm);
+ if (new_s == -1) {
+ rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
+ return;
+ }
+
+ /* Generate a monitor event for the change */
+ qapi_event_send_rtc_change(qemu_timedate_diff(&tm), &error_abort);
+
+ rtc = SPAPR_RTC(spapr->rtc);
+
+ host_ns = qemu_clock_get_ns(rtc_clock);
+
+ rtc->ns_offset = (new_s * NSEC_PER_SEC) - host_ns;
+
+ rtas_st(rets, 0, RTAS_OUT_SUCCESS);
+}
+
+static void spapr_rtc_qom_date(Object *obj, struct tm *current_tm, Error **errp)
+{
+ spapr_rtc_read(DEVICE(obj), current_tm, NULL);
+}
+
+static void spapr_rtc_realize(DeviceState *dev, Error **errp)
+{
+ sPAPRRTCState *rtc = SPAPR_RTC(dev);
+ struct tm tm;
+ time_t host_s;
+ int64_t rtc_ns;
+
+ /* Initialize the RTAS RTC from host time */
+
+ qemu_get_timedate(&tm, 0);
+ host_s = mktimegm(&tm);
+ rtc_ns = qemu_clock_get_ns(rtc_clock);
+ rtc->ns_offset = host_s * NSEC_PER_SEC - rtc_ns;
+
+ object_property_add_tm(OBJECT(rtc), "date", spapr_rtc_qom_date, NULL);
+}
+
+static const VMStateDescription vmstate_spapr_rtc = {
+ .name = "spapr/rtc",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_INT64(ns_offset, sPAPRRTCState),
+ VMSTATE_END_OF_LIST()
+ },
+};
+
+static void spapr_rtc_class_init(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+
+ dc->realize = spapr_rtc_realize;
+ dc->vmsd = &vmstate_spapr_rtc;
+
+ spapr_rtas_register(RTAS_GET_TIME_OF_DAY, "get-time-of-day",
+ rtas_get_time_of_day);
+ spapr_rtas_register(RTAS_SET_TIME_OF_DAY, "set-time-of-day",
+ rtas_set_time_of_day);
+}
+
+static const TypeInfo spapr_rtc_info = {
+ .name = TYPE_SPAPR_RTC,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(sPAPRRTCState),
+ .class_size = sizeof(XICSStateClass),
+ .class_init = spapr_rtc_class_init,
+};
+
+static void spapr_rtc_register_types(void)
+{
+ type_register_static(&spapr_rtc_info);
+}
+type_init(spapr_rtc_register_types)
diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c
index 032ee1a5f1..1360b97ab0 100644
--- a/hw/ppc/spapr_vio.c
+++ b/hw/ppc/spapr_vio.c
@@ -322,6 +322,18 @@ static void spapr_vio_quiesce_one(VIOsPAPRDevice *dev)
free_crq(dev);
}
+void spapr_vio_set_bypass(VIOsPAPRDevice *dev, bool bypass)
+{
+ if (!dev->tcet) {
+ return;
+ }
+
+ memory_region_set_enabled(&dev->mrbypass, bypass);
+ memory_region_set_enabled(spapr_tce_get_iommu(dev->tcet), !bypass);
+
+ dev->tcet->bypass = bypass;
+}
+
static void rtas_set_tce_bypass(PowerPCCPU *cpu, sPAPREnvironment *spapr,
uint32_t token,
uint32_t nargs, target_ulong args,
@@ -348,7 +360,7 @@ static void rtas_set_tce_bypass(PowerPCCPU *cpu, sPAPREnvironment *spapr,
return;
}
- spapr_tce_set_bypass(dev->tcet, !!enable);
+ spapr_vio_set_bypass(dev, !!enable);
rtas_st(rets, 0, RTAS_OUT_SUCCESS);
}
@@ -407,12 +419,13 @@ static void spapr_vio_busdev_reset(DeviceState *qdev)
dev->signal_state = 0;
+ spapr_vio_set_bypass(dev, false);
if (pc->reset) {
pc->reset(dev);
}
}
-static int spapr_vio_busdev_init(DeviceState *qdev)
+static void spapr_vio_busdev_realize(DeviceState *qdev, Error **errp)
{
VIOsPAPRDevice *dev = (VIOsPAPRDevice *)qdev;
VIOsPAPRDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
@@ -428,11 +441,11 @@ static int spapr_vio_busdev_init(DeviceState *qdev)
VIOsPAPRDevice *other = reg_conflict(dev);
if (other) {
- fprintf(stderr, "vio: %s and %s devices conflict at address %#x\n",
- object_get_typename(OBJECT(qdev)),
- object_get_typename(OBJECT(&other->qdev)),
- dev->reg);
- return -1;
+ error_setg(errp, "%s and %s devices conflict at address %#x",
+ object_get_typename(OBJECT(qdev)),
+ object_get_typename(OBJECT(&other->qdev)),
+ dev->reg);
+ return;
}
} else {
/* Need to assign an address */
@@ -451,20 +464,32 @@ static int spapr_vio_busdev_init(DeviceState *qdev)
dev->irq = xics_alloc(spapr->icp, 0, dev->irq, false);
if (!dev->irq) {
- return -1;
+ error_setg(errp, "can't allocate IRQ");
+ return;
}
if (pc->rtce_window_size) {
uint32_t liobn = SPAPR_VIO_BASE_LIOBN | dev->reg;
+
+ memory_region_init(&dev->mrroot, OBJECT(dev), "iommu-spapr-root",
+ ram_size);
+ memory_region_init_alias(&dev->mrbypass, OBJECT(dev),
+ "iommu-spapr-bypass", get_system_memory(),
+ 0, ram_size);
+ memory_region_add_subregion_overlap(&dev->mrroot, 0, &dev->mrbypass, 1);
+ address_space_init(&dev->as, &dev->mrroot, qdev->id);
+
dev->tcet = spapr_tce_new_table(qdev, liobn,
0,
SPAPR_TCE_PAGE_SHIFT,
pc->rtce_window_size >>
SPAPR_TCE_PAGE_SHIFT, false);
- address_space_init(&dev->as, spapr_tce_get_iommu(dev->tcet), qdev->id);
+ dev->tcet->vdev = dev;
+ memory_region_add_subregion_overlap(&dev->mrroot, 0,
+ spapr_tce_get_iommu(dev->tcet), 2);
}
- return pc->init(dev);
+ pc->realize(dev, errp);
}
static target_ulong h_vio_signal(PowerPCCPU *cpu, sPAPREnvironment *spapr,
@@ -570,7 +595,7 @@ const VMStateDescription vmstate_spapr_vio = {
static void vio_spapr_device_class_init(ObjectClass *klass, void *data)
{
DeviceClass *k = DEVICE_CLASS(klass);
- k->init = spapr_vio_busdev_init;
+ k->realize = spapr_vio_busdev_realize;
k->reset = spapr_vio_busdev_reset;
k->bus_type = TYPE_SPAPR_VIO_BUS;
k->props = spapr_vio_props;
diff --git a/hw/s390x/s390-virtio-bus.h b/hw/s390x/s390-virtio-bus.h
index ffd0df708b..92aa9d0499 100644
--- a/hw/s390x/s390-virtio-bus.h
+++ b/hw/s390x/s390-virtio-bus.h
@@ -19,6 +19,10 @@
#ifndef HW_S390_VIRTIO_BUS_H
#define HW_S390_VIRTIO_BUS_H 1
+#include <stddef.h>
+
+#include "standard-headers/asm-s390/kvm_virtio.h"
+#include "standard-headers/linux/virtio_ring.h"
#include "hw/virtio/virtio-blk.h"
#include "hw/virtio/virtio-net.h"
#include "hw/virtio/virtio-rng.h"
@@ -29,28 +33,26 @@
#include "hw/virtio/vhost-scsi.h"
#endif
-#define VIRTIO_DEV_OFFS_TYPE 0 /* 8 bits */
-#define VIRTIO_DEV_OFFS_NUM_VQ 1 /* 8 bits */
-#define VIRTIO_DEV_OFFS_FEATURE_LEN 2 /* 8 bits */
-#define VIRTIO_DEV_OFFS_CONFIG_LEN 3 /* 8 bits */
-#define VIRTIO_DEV_OFFS_STATUS 4 /* 8 bits */
-#define VIRTIO_DEV_OFFS_CONFIG 5 /* dynamic */
+typedef struct kvm_device_desc KvmDeviceDesc;
+
+#define VIRTIO_DEV_OFFS_TYPE offsetof(KvmDeviceDesc, type)
+#define VIRTIO_DEV_OFFS_NUM_VQ offsetof(KvmDeviceDesc, num_vq)
+#define VIRTIO_DEV_OFFS_FEATURE_LEN offsetof(KvmDeviceDesc, feature_len)
+#define VIRTIO_DEV_OFFS_CONFIG_LEN offsetof(KvmDeviceDesc, config_len)
+#define VIRTIO_DEV_OFFS_STATUS offsetof(KvmDeviceDesc, status)
+#define VIRTIO_DEV_OFFS_CONFIG offsetof(KvmDeviceDesc, config)
-#define VIRTIO_VQCONFIG_OFFS_TOKEN 0 /* 64 bits */
-#define VIRTIO_VQCONFIG_OFFS_ADDRESS 8 /* 64 bits */
-#define VIRTIO_VQCONFIG_OFFS_NUM 16 /* 16 bits */
-#define VIRTIO_VQCONFIG_LEN 24
+typedef struct kvm_vqconfig KvmVqConfig;
+#define VIRTIO_VQCONFIG_OFFS_TOKEN offsetof(KvmVqConfig,token) /* 64 bit */
+#define VIRTIO_VQCONFIG_OFFS_ADDRESS offsetof(KvmVqConfig, address) /* 64 bit */
+#define VIRTIO_VQCONFIG_OFFS_NUM offsetof(KvmVqConfig, num) /* 16 bit */
+#define VIRTIO_VQCONFIG_LEN sizeof(KvmVqConfig)
#define VIRTIO_RING_LEN (TARGET_PAGE_SIZE * 3)
-#define VIRTIO_VRING_AVAIL_IDX_OFFS 2
-#define VIRTIO_VRING_USED_IDX_OFFS 2
+#define VIRTIO_VRING_AVAIL_IDX_OFFS offsetof(struct vring_avail, idx)
+#define VIRTIO_VRING_USED_IDX_OFFS offsetof(struct vring_used, idx)
#define S390_DEVICE_PAGES 512
-#define VIRTIO_PARAM_MASK 0xff
-#define VIRTIO_PARAM_VRING_INTERRUPT 0x0
-#define VIRTIO_PARAM_CONFIG_CHANGED 0x1
-#define VIRTIO_PARAM_DEV_ADD 0x2
-
#define TYPE_VIRTIO_S390_DEVICE "virtio-s390-device"
#define VIRTIO_S390_DEVICE(obj) \
OBJECT_CHECK(VirtIOS390Device, (obj), TYPE_VIRTIO_S390_DEVICE)
diff --git a/hw/s390x/s390-virtio.h b/hw/s390x/s390-virtio.h
index 75b67eda20..c847853957 100644
--- a/hw/s390x/s390-virtio.h
+++ b/hw/s390x/s390-virtio.h
@@ -13,11 +13,8 @@
#define HW_S390_VIRTIO_H 1
#include "hw/nmi.h"
-
-#define KVM_S390_VIRTIO_NOTIFY 0
-#define KVM_S390_VIRTIO_RESET 1
-#define KVM_S390_VIRTIO_SET_STATUS 2
-#define KVM_S390_VIRTIO_CCW_NOTIFY 3
+#include "standard-headers/asm-s390/kvm_virtio.h"
+#include "standard-headers/asm-s390/virtio-ccw.h"
typedef int (*s390_virtio_fn)(const uint64_t *args);
void s390_register_virtio_hypercall(uint64_t code, s390_virtio_fn fn);
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index ea236c9b01..ffbb9c2c89 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -400,8 +400,7 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)
ccw.cda + sizeof(features.features));
features.features = ldl_le_phys(&address_space_memory, ccw.cda);
if (features.index < ARRAY_SIZE(dev->host_features)) {
- virtio_bus_set_vdev_features(&dev->bus, features.features);
- vdev->guest_features = features.features;
+ virtio_set_features(vdev, features.features);
} else {
/*
* If the guest supports more feature bits, assert that it
@@ -744,8 +743,8 @@ static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev)
dev->host_features[0] = virtio_bus_get_vdev_features(&dev->bus,
dev->host_features[0]);
- dev->host_features[0] |= 0x1 << VIRTIO_F_NOTIFY_ON_EMPTY;
- dev->host_features[0] |= 0x1 << VIRTIO_F_BAD_FEATURE;
+ virtio_add_feature(&dev->host_features[0], VIRTIO_F_NOTIFY_ON_EMPTY);
+ virtio_add_feature(&dev->host_features[0], VIRTIO_F_BAD_FEATURE);
css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid,
parent->hotplugged, 1);
@@ -899,9 +898,8 @@ static void balloon_ccw_stats_set_poll_interval(Object *obj, struct Visitor *v,
static void virtio_ccw_balloon_instance_init(Object *obj)
{
VirtIOBalloonCcw *dev = VIRTIO_BALLOON_CCW(obj);
- object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_BALLOON);
- object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
- object_unref(OBJECT(&dev->vdev));
+ virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
+ TYPE_VIRTIO_BALLOON);
object_property_add(obj, "guest-stats", "guest statistics",
balloon_ccw_stats_get_all, NULL, NULL, dev, NULL);
diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c
index 36392359e3..891424fae9 100644
--- a/hw/scsi/spapr_vscsi.c
+++ b/hw/scsi/spapr_vscsi.c
@@ -1212,24 +1212,17 @@ static void spapr_vscsi_reset(VIOsPAPRDevice *dev)
}
}
-static int spapr_vscsi_init(VIOsPAPRDevice *dev)
+static void spapr_vscsi_realize(VIOsPAPRDevice *dev, Error **errp)
{
VSCSIState *s = VIO_SPAPR_VSCSI_DEVICE(dev);
- Error *err = NULL;
dev->crq.SendFunc = vscsi_do_crq;
scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(dev),
&vscsi_scsi_info, NULL);
if (!dev->qdev.hotplugged) {
- scsi_bus_legacy_handle_cmdline(&s->bus, &err);
- if (err != NULL) {
- error_free(err);
- return -1;
- }
+ scsi_bus_legacy_handle_cmdline(&s->bus, errp);
}
-
- return 0;
}
void spapr_vscsi_create(VIOsPAPRBus *bus)
@@ -1281,7 +1274,7 @@ static void spapr_vscsi_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
VIOsPAPRDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass);
- k->init = spapr_vscsi_init;
+ k->realize = spapr_vscsi_realize;
k->reset = spapr_vscsi_reset;
k->devnode = spapr_vscsi_devnode;
k->dt_name = "v-scsi";
diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c
index 618b0af186..335f4429a9 100644
--- a/hw/scsi/vhost-scsi.c
+++ b/hw/scsi/vhost-scsi.c
@@ -83,7 +83,7 @@ static int vhost_scsi_start(VHostSCSI *s)
if (abi_version > VHOST_SCSI_ABI_VERSION) {
error_report("vhost-scsi: The running tcm_vhost kernel abi_version:"
" %d is greater than vhost_scsi userspace supports: %d, please"
- " upgrade your version of QEMU\n", abi_version,
+ " upgrade your version of QEMU", abi_version,
VHOST_SCSI_ABI_VERSION);
return -ENOSYS;
}
@@ -141,7 +141,7 @@ static void vhost_scsi_stop(VHostSCSI *s)
if (k->set_guest_notifiers) {
ret = k->set_guest_notifiers(qbus->parent, s->dev.nvqs, false);
if (ret < 0) {
- error_report("vhost guest notifier cleanup failed: %d\n", ret);
+ error_report("vhost guest notifier cleanup failed: %d", ret);
}
}
assert(ret >= 0);
@@ -186,7 +186,7 @@ static void vhost_scsi_set_status(VirtIODevice *vdev, uint8_t val)
ret = vhost_scsi_start(s);
if (ret < 0) {
- error_report("virtio-scsi: unable to start vhost: %s\n",
+ error_report("virtio-scsi: unable to start vhost: %s",
strerror(-ret));
/* There is no userspace virtio-scsi fallback so exit */
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index 4db3b23ea3..cfb52e8fd9 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -13,6 +13,7 @@
*
*/
+#include "standard-headers/linux/virtio_ids.h"
#include "hw/virtio/virtio-scsi.h"
#include "qemu/error-report.h"
#include "qemu/iov.h"
@@ -144,7 +145,7 @@ static int virtio_scsi_parse_req(VirtIOSCSIReq *req,
*
* TODO: always disable this workaround for virtio 1.0 devices.
*/
- if ((vdev->guest_features & (1 << VIRTIO_F_ANY_LAYOUT)) == 0) {
+ if (!virtio_has_feature(vdev, VIRTIO_F_ANY_LAYOUT)) {
req_size = req->elem.out_sg[0].iov_len;
resp_size = req->elem.in_sg[0].iov_len;
}
@@ -744,7 +745,7 @@ static void virtio_scsi_change(SCSIBus *bus, SCSIDevice *dev, SCSISense sense)
VirtIOSCSI *s = container_of(bus, VirtIOSCSI, bus);
VirtIODevice *vdev = VIRTIO_DEVICE(s);
- if (((vdev->guest_features >> VIRTIO_SCSI_F_CHANGE) & 1) &&
+ if (virtio_has_feature(vdev, VIRTIO_SCSI_F_CHANGE) &&
dev->type != TYPE_ROM) {
virtio_scsi_push_event(s, dev, VIRTIO_SCSI_T_PARAM_CHANGE,
sense.asc | (sense.ascq << 8));
@@ -768,7 +769,7 @@ static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev,
aio_context_release(s->ctx);
}
- if ((vdev->guest_features >> VIRTIO_SCSI_F_HOTPLUG) & 1) {
+ if (virtio_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) {
virtio_scsi_push_event(s, sd,
VIRTIO_SCSI_T_TRANSPORT_RESET,
VIRTIO_SCSI_EVT_RESET_RESCAN);
@@ -782,7 +783,7 @@ static void virtio_scsi_hotunplug(HotplugHandler *hotplug_dev, DeviceState *dev,
VirtIOSCSI *s = VIRTIO_SCSI(vdev);
SCSIDevice *sd = SCSI_DEVICE(dev);
- if ((vdev->guest_features >> VIRTIO_SCSI_F_HOTPLUG) & 1) {
+ if (virtio_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) {
virtio_scsi_push_event(s, sd,
VIRTIO_SCSI_T_TRANSPORT_RESET,
VIRTIO_SCSI_EVT_RESET_REMOVED);
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index 10e5355de7..27b914aa94 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -1220,7 +1220,7 @@ static Property sdhci_properties[] = {
DEFINE_PROP_END_OF_LIST(),
};
-static int sdhci_pci_init(PCIDevice *dev)
+static void sdhci_pci_realize(PCIDevice *dev, Error **errp)
{
SDHCIState *s = PCI_SDHCI(dev);
dev->config[PCI_CLASS_PROG] = 0x01; /* Standard Host supported DMA */
@@ -1232,7 +1232,6 @@ static int sdhci_pci_init(PCIDevice *dev)
memory_region_init_io(&s->iomem, OBJECT(s), &sdhci_mmio_ops, s, "sdhci",
SDHC_REGISTERS_MAP_SIZE);
pci_register_bar(dev, 0, 0, &s->iomem);
- return 0;
}
static void sdhci_pci_exit(PCIDevice *dev)
@@ -1246,7 +1245,7 @@ static void sdhci_pci_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- k->init = sdhci_pci_init;
+ k->realize = sdhci_pci_realize;
k->exit = sdhci_pci_exit;
k->vendor_id = PCI_VENDOR_ID_REDHAT;
k->device_id = PCI_DEVICE_ID_REDHAT_SDHCI;
diff --git a/hw/sparc/leon3.c b/hw/sparc/leon3.c
index 751392e137..e41ec0bf3a 100644
--- a/hw/sparc/leon3.c
+++ b/hw/sparc/leon3.c
@@ -186,6 +186,7 @@ static void leon3_generic_hw_init(MachineState *machine)
fprintf(stderr, "Can't read bios image %s\n", filename);
exit(1);
}
+ g_free(filename);
/* Can directly load an application. */
if (kernel_filename != NULL) {
diff --git a/hw/timer/a9gtimer.c b/hw/timer/a9gtimer.c
index 435142a3c9..b087bbddb8 100644
--- a/hw/timer/a9gtimer.c
+++ b/hw/timer/a9gtimer.c
@@ -289,7 +289,7 @@ static void a9_gtimer_realize(DeviceState *dev, Error **errp)
int i;
if (s->num_cpu < 1 || s->num_cpu > A9_GTIMER_MAX_CPUS) {
- error_setg(errp, "%s: num-cpu must be between 1 and %d\n",
+ error_setg(errp, "%s: num-cpu must be between 1 and %d",
__func__, A9_GTIMER_MAX_CPUS);
return;
}
diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c
index 0600c9a1fa..f2b77fa118 100644
--- a/hw/timer/mc146818rtc.c
+++ b/hw/timer/mc146818rtc.c
@@ -831,49 +831,12 @@ static const MemoryRegionOps cmos_ops = {
.endianness = DEVICE_LITTLE_ENDIAN,
};
-static void rtc_get_date(Object *obj, Visitor *v, void *opaque,
- const char *name, Error **errp)
+static void rtc_get_date(Object *obj, struct tm *current_tm, Error **errp)
{
- Error *err = NULL;
RTCState *s = MC146818_RTC(obj);
- struct tm current_tm;
rtc_update_time(s);
- rtc_get_time(s, &current_tm);
- visit_start_struct(v, NULL, "struct tm", name, 0, &err);
- if (err) {
- goto out;
- }
- visit_type_int32(v, &current_tm.tm_year, "tm_year", &err);
- if (err) {
- goto out_end;
- }
- visit_type_int32(v, &current_tm.tm_mon, "tm_mon", &err);
- if (err) {
- goto out_end;
- }
- visit_type_int32(v, &current_tm.tm_mday, "tm_mday", &err);
- if (err) {
- goto out_end;
- }
- visit_type_int32(v, &current_tm.tm_hour, "tm_hour", &err);
- if (err) {
- goto out_end;
- }
- visit_type_int32(v, &current_tm.tm_min, "tm_min", &err);
- if (err) {
- goto out_end;
- }
- visit_type_int32(v, &current_tm.tm_sec, "tm_sec", &err);
- if (err) {
- goto out_end;
- }
-out_end:
- error_propagate(errp, err);
- err = NULL;
- visit_end_struct(v, errp);
-out:
- error_propagate(errp, err);
+ rtc_get_time(s, current_tm);
}
static void rtc_realizefn(DeviceState *dev, Error **errp)
@@ -932,8 +895,7 @@ static void rtc_realizefn(DeviceState *dev, Error **errp)
qdev_set_legacy_instance_id(dev, base, 3);
qemu_register_reset(rtc_reset, s);
- object_property_add(OBJECT(s), "date", "struct tm",
- rtc_get_date, NULL, NULL, s, NULL);
+ object_property_add_tm(OBJECT(s), "date", rtc_get_date, NULL);
object_property_add_alias(qdev_get_machine(), "rtc-time",
OBJECT(s), "date", NULL);
diff --git a/hw/tpm/tpm_int.h b/hw/tpm/tpm_int.h
index 2f582caaee..2b35fe21ec 100644
--- a/hw/tpm/tpm_int.h
+++ b/hw/tpm/tpm_int.h
@@ -62,6 +62,7 @@ struct tpm_resp_hdr {
#define TPM_FAIL 9
+#define TPM_ORD_ContinueSelfTest 0x53
#define TPM_ORD_GetTicks 0xf1
#endif /* TPM_TPM_INT_H */
diff --git a/hw/tpm/tpm_passthrough.c b/hw/tpm/tpm_passthrough.c
index 2bf3c6fd61..2a45071e36 100644
--- a/hw/tpm/tpm_passthrough.c
+++ b/hw/tpm/tpm_passthrough.c
@@ -112,21 +112,38 @@ static void tpm_write_fatal_error_response(uint8_t *out, uint32_t out_len)
}
}
+static bool tpm_passthrough_is_selftest(const uint8_t *in, uint32_t in_len)
+{
+ struct tpm_req_hdr *hdr = (struct tpm_req_hdr *)in;
+
+ if (in_len >= sizeof(*hdr)) {
+ return (be32_to_cpu(hdr->ordinal) == TPM_ORD_ContinueSelfTest);
+ }
+
+ return false;
+}
+
static int tpm_passthrough_unix_tx_bufs(TPMPassthruState *tpm_pt,
const uint8_t *in, uint32_t in_len,
- uint8_t *out, uint32_t out_len)
+ uint8_t *out, uint32_t out_len,
+ bool *selftest_done)
{
int ret;
+ bool is_selftest;
+ const struct tpm_resp_hdr *hdr;
tpm_pt->tpm_op_canceled = false;
tpm_pt->tpm_executing = true;
+ *selftest_done = false;
+
+ is_selftest = tpm_passthrough_is_selftest(in, in_len);
ret = tpm_passthrough_unix_write(tpm_pt->tpm_fd, in, in_len);
if (ret != in_len) {
if (!tpm_pt->tpm_op_canceled ||
(tpm_pt->tpm_op_canceled && errno != ECANCELED)) {
error_report("tpm_passthrough: error while transmitting data "
- "to TPM: %s (%i)\n",
+ "to TPM: %s (%i)",
strerror(errno), errno);
}
goto err_exit;
@@ -139,14 +156,19 @@ static int tpm_passthrough_unix_tx_bufs(TPMPassthruState *tpm_pt,
if (!tpm_pt->tpm_op_canceled ||
(tpm_pt->tpm_op_canceled && errno != ECANCELED)) {
error_report("tpm_passthrough: error while reading data from "
- "TPM: %s (%i)\n",
+ "TPM: %s (%i)",
strerror(errno), errno);
}
} else if (ret < sizeof(struct tpm_resp_hdr) ||
tpm_passthrough_get_size_from_buffer(out) != ret) {
ret = -1;
error_report("tpm_passthrough: received invalid response "
- "packet from TPM\n");
+ "packet from TPM");
+ }
+
+ if (is_selftest && (ret >= sizeof(struct tpm_resp_hdr))) {
+ hdr = (struct tpm_resp_hdr *)out;
+ *selftest_done = (be32_to_cpu(hdr->errcode) == 0);
}
err_exit:
@@ -160,13 +182,15 @@ err_exit:
}
static int tpm_passthrough_unix_transfer(TPMPassthruState *tpm_pt,
- const TPMLocality *locty_data)
+ const TPMLocality *locty_data,
+ bool *selftest_done)
{
return tpm_passthrough_unix_tx_bufs(tpm_pt,
locty_data->w_buffer.buffer,
locty_data->w_offset,
locty_data->r_buffer.buffer,
- locty_data->r_buffer.size);
+ locty_data->r_buffer.size,
+ selftest_done);
}
static void tpm_passthrough_worker_thread(gpointer data,
@@ -175,16 +199,19 @@ static void tpm_passthrough_worker_thread(gpointer data,
TPMPassthruThreadParams *thr_parms = user_data;
TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(thr_parms->tb);
TPMBackendCmd cmd = (TPMBackendCmd)data;
+ bool selftest_done = false;
DPRINTF("tpm_passthrough: processing command type %d\n", cmd);
switch (cmd) {
case TPM_BACKEND_CMD_PROCESS_CMD:
tpm_passthrough_unix_transfer(tpm_pt,
- thr_parms->tpm_state->locty_data);
+ thr_parms->tpm_state->locty_data,
+ &selftest_done);
thr_parms->recv_data_callback(thr_parms->tpm_state,
- thr_parms->tpm_state->locty_number);
+ thr_parms->tpm_state->locty_number,
+ selftest_done);
break;
case TPM_BACKEND_CMD_INIT:
case TPM_BACKEND_CMD_END:
@@ -282,7 +309,7 @@ static void tpm_passthrough_cancel_cmd(TPMBackend *tb)
if (tpm_pt->cancel_fd >= 0) {
n = write(tpm_pt->cancel_fd, "-", 1);
if (n != 1) {
- error_report("Canceling TPM command failed: %s\n",
+ error_report("Canceling TPM command failed: %s",
strerror(errno));
} else {
tpm_pt->tpm_op_canceled = true;
@@ -413,13 +440,13 @@ static int tpm_passthrough_handle_device_opts(QemuOpts *opts, TPMBackend *tb)
tpm_pt->tpm_fd = qemu_open(tpm_pt->tpm_dev, O_RDWR);
if (tpm_pt->tpm_fd < 0) {
- error_report("Cannot access TPM device using '%s': %s\n",
+ error_report("Cannot access TPM device using '%s': %s",
tpm_pt->tpm_dev, strerror(errno));
goto err_free_parameters;
}
if (tpm_passthrough_test_tpmdev(tpm_pt->tpm_fd)) {
- error_report("'%s' is not a TPM device.\n",
+ error_report("'%s' is not a TPM device.",
tpm_pt->tpm_dev);
goto err_close_tpmdev;
}
diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
index c0e7cd738a..d0bb97f7d9 100644
--- a/hw/tpm/tpm_tis.c
+++ b/hw/tpm/tpm_tis.c
@@ -14,7 +14,7 @@
*
* Implementation of the TIS interface according to specs found at
* http://www.trustedcomputinggroup.org. This implementation currently
- * supports version 1.21, revision 1.0.
+ * supports version 1.3, 21 March 2013
* In the developers menu choose the PC Client section then find the TIS
* specification.
*/
@@ -51,6 +51,8 @@
#define TPM_TIS_REG_INTF_CAPABILITY 0x14
#define TPM_TIS_REG_STS 0x18
#define TPM_TIS_REG_DATA_FIFO 0x24
+#define TPM_TIS_REG_DATA_XFIFO 0x80
+#define TPM_TIS_REG_DATA_XFIFO_END 0xbc
#define TPM_TIS_REG_DID_VID 0xf00
#define TPM_TIS_REG_RID 0xf04
@@ -62,6 +64,7 @@
#define TPM_TIS_STS_TPM_GO (1 << 5)
#define TPM_TIS_STS_DATA_AVAILABLE (1 << 4)
#define TPM_TIS_STS_EXPECT (1 << 3)
+#define TPM_TIS_STS_SELFTEST_DONE (1 << 2)
#define TPM_TIS_STS_RESPONSE_RETRY (1 << 1)
#define TPM_TIS_BURST_COUNT_SHIFT 8
@@ -100,8 +103,15 @@
#endif
+#define TPM_TIS_CAP_INTERFACE_VERSION1_3 (2 << 28)
+#define TPM_TIS_CAP_DATA_TRANSFER_64B (3 << 9)
+#define TPM_TIS_CAP_DATA_TRANSFER_LEGACY (0 << 9)
+#define TPM_TIS_CAP_BURST_COUNT_DYNAMIC (0 << 8)
#define TPM_TIS_CAP_INTERRUPT_LOW_LEVEL (1 << 4) /* support is mandatory */
#define TPM_TIS_CAPABILITIES_SUPPORTED (TPM_TIS_CAP_INTERRUPT_LOW_LEVEL | \
+ TPM_TIS_CAP_BURST_COUNT_DYNAMIC | \
+ TPM_TIS_CAP_DATA_TRANSFER_64B | \
+ TPM_TIS_CAP_INTERFACE_VERSION1_3 | \
TPM_TIS_INTERRUPTS_SUPPORTED)
#define TPM_TIS_TPM_DID 0x0001
@@ -145,6 +155,24 @@ static void tpm_tis_show_buffer(const TPMSizedBuffer *sb, const char *string)
}
/*
+ * Set the given flags in the STS register by clearing the register but
+ * preserving the SELFTEST_DONE flag and then setting the new flags.
+ *
+ * The SELFTEST_DONE flag is acquired from the backend that determines it by
+ * peeking into TPM commands.
+ *
+ * A VM suspend/resume will preserve the flag by storing it into the VM
+ * device state, but the backend will not remember it when QEMU is started
+ * again. Therefore, we cache the flag here. Once set, it will not be unset
+ * except by a reset.
+ */
+static void tpm_tis_sts_set(TPMLocality *l, uint32_t flags)
+{
+ l->sts &= TPM_TIS_STS_SELFTEST_DONE;
+ l->sts |= flags;
+}
+
+/*
* Send a request to the TPM.
*/
static void tpm_tis_tpm_send(TPMState *s, uint8_t locty)
@@ -255,7 +283,8 @@ static void tpm_tis_abort(TPMState *s, uint8_t locty)
*/
if (tis->aborting_locty == tis->next_locty) {
tis->loc[tis->aborting_locty].state = TPM_TIS_STATE_READY;
- tis->loc[tis->aborting_locty].sts = TPM_TIS_STS_COMMAND_READY;
+ tpm_tis_sts_set(&tis->loc[tis->aborting_locty],
+ TPM_TIS_STS_COMMAND_READY);
tpm_tis_raise_irq(s, tis->aborting_locty, TPM_TIS_INT_COMMAND_READY);
}
@@ -300,7 +329,8 @@ static void tpm_tis_receive_bh(void *opaque)
TPMTISEmuState *tis = &s->s.tis;
uint8_t locty = s->locty_number;
- tis->loc[locty].sts = TPM_TIS_STS_VALID | TPM_TIS_STS_DATA_AVAILABLE;
+ tpm_tis_sts_set(&tis->loc[locty],
+ TPM_TIS_STS_VALID | TPM_TIS_STS_DATA_AVAILABLE);
tis->loc[locty].state = TPM_TIS_STATE_COMPLETION;
tis->loc[locty].r_offset = 0;
tis->loc[locty].w_offset = 0;
@@ -320,12 +350,20 @@ static void tpm_tis_receive_bh(void *opaque)
/*
* Callback from the TPM to indicate that the response was received.
*/
-static void tpm_tis_receive_cb(TPMState *s, uint8_t locty)
+static void tpm_tis_receive_cb(TPMState *s, uint8_t locty,
+ bool is_selftest_done)
{
TPMTISEmuState *tis = &s->s.tis;
+ uint8_t l;
assert(s->locty_number == locty);
+ if (is_selftest_done) {
+ for (l = 0; l < TPM_TIS_NUM_LOCALITIES; l++) {
+ tis->loc[locty].sts |= TPM_TIS_STS_SELFTEST_DONE;
+ }
+ }
+
qemu_bh_schedule(tis->bh);
}
@@ -344,7 +382,7 @@ static uint32_t tpm_tis_data_read(TPMState *s, uint8_t locty)
ret = tis->loc[locty].r_buffer.buffer[tis->loc[locty].r_offset++];
if (tis->loc[locty].r_offset >= len) {
/* got last byte */
- tis->loc[locty].sts = TPM_TIS_STS_VALID;
+ tpm_tis_sts_set(&tis->loc[locty], TPM_TIS_STS_VALID);
#ifdef RAISE_STS_IRQ
tpm_tis_raise_irq(s, locty, TPM_TIS_INT_STS_VALID);
#endif
@@ -427,6 +465,7 @@ static uint64_t tpm_tis_mmio_read(void *opaque, hwaddr addr,
uint32_t val = 0xffffffff;
uint8_t locty = tpm_tis_locality_from_addr(addr);
uint32_t avail;
+ uint8_t v;
if (tpm_backend_had_startup_error(s->be_driver)) {
return val;
@@ -475,15 +514,28 @@ static uint64_t tpm_tis_mmio_read(void *opaque, hwaddr addr,
}
break;
case TPM_TIS_REG_DATA_FIFO:
+ case TPM_TIS_REG_DATA_XFIFO ... TPM_TIS_REG_DATA_XFIFO_END:
if (tis->active_locty == locty) {
- switch (tis->loc[locty].state) {
- case TPM_TIS_STATE_COMPLETION:
- val = tpm_tis_data_read(s, locty);
- break;
- default:
- val = TPM_TIS_NO_DATA_BYTE;
- break;
+ if (size > 4 - (addr & 0x3)) {
+ /* prevent access beyond FIFO */
+ size = 4 - (addr & 0x3);
}
+ val = 0;
+ shift = 0;
+ while (size > 0) {
+ switch (tis->loc[locty].state) {
+ case TPM_TIS_STATE_COMPLETION:
+ v = tpm_tis_data_read(s, locty);
+ break;
+ default:
+ v = TPM_TIS_NO_DATA_BYTE;
+ break;
+ }
+ val |= (v << shift);
+ shift += 8;
+ size--;
+ }
+ shift = 0; /* no more adjustments */
}
break;
case TPM_TIS_REG_DID_VID:
@@ -518,11 +570,13 @@ static void tpm_tis_mmio_write_intern(void *opaque, hwaddr addr,
{
TPMState *s = opaque;
TPMTISEmuState *tis = &s->s.tis;
- uint16_t off = addr & 0xfff;
+ uint16_t off = addr & 0xffc;
+ uint8_t shift = (addr & 0x3) * 8;
uint8_t locty = tpm_tis_locality_from_addr(addr);
uint8_t active_locty, l;
int c, set_new_locty = 1;
uint16_t len;
+ uint32_t mask = (size == 1) ? 0xff : ((size == 2) ? 0xffff : ~0);
DPRINTF("tpm_tis: write.%u(%08x) = %08x\n", size, (int)addr, (uint32_t)val);
@@ -535,6 +589,15 @@ static void tpm_tis_mmio_write_intern(void *opaque, hwaddr addr,
return;
}
+ val &= mask;
+
+ if (shift) {
+ val <<= shift;
+ mask <<= shift;
+ }
+
+ mask ^= 0xffffffff;
+
switch (off) {
case TPM_TIS_REG_ACCESS:
@@ -646,9 +709,10 @@ static void tpm_tis_mmio_write_intern(void *opaque, hwaddr addr,
break;
}
- tis->loc[locty].inte = (val & (TPM_TIS_INT_ENABLED |
- TPM_TIS_INT_POLARITY_MASK |
- TPM_TIS_INTERRUPTS_SUPPORTED));
+ tis->loc[locty].inte &= mask;
+ tis->loc[locty].inte |= (val & (TPM_TIS_INT_ENABLED |
+ TPM_TIS_INT_POLARITY_MASK |
+ TPM_TIS_INTERRUPTS_SUPPORTED));
break;
case TPM_TIS_REG_INT_VECTOR:
/* hard wired -- ignore */
@@ -686,7 +750,7 @@ static void tpm_tis_mmio_write_intern(void *opaque, hwaddr addr,
break;
case TPM_TIS_STATE_IDLE:
- tis->loc[locty].sts = TPM_TIS_STS_COMMAND_READY;
+ tpm_tis_sts_set(&tis->loc[locty], TPM_TIS_STS_COMMAND_READY);
tis->loc[locty].state = TPM_TIS_STATE_READY;
tpm_tis_raise_irq(s, locty, TPM_TIS_INT_COMMAND_READY);
break;
@@ -705,7 +769,8 @@ static void tpm_tis_mmio_write_intern(void *opaque, hwaddr addr,
/* shortcut to ready state with C/R set */
tis->loc[locty].state = TPM_TIS_STATE_READY;
if (!(tis->loc[locty].sts & TPM_TIS_STS_COMMAND_READY)) {
- tis->loc[locty].sts = TPM_TIS_STS_COMMAND_READY;
+ tpm_tis_sts_set(&tis->loc[locty],
+ TPM_TIS_STS_COMMAND_READY);
tpm_tis_raise_irq(s, locty, TPM_TIS_INT_COMMAND_READY);
}
tis->loc[locty].sts &= ~(TPM_TIS_STS_DATA_AVAILABLE);
@@ -727,8 +792,9 @@ static void tpm_tis_mmio_write_intern(void *opaque, hwaddr addr,
switch (tis->loc[locty].state) {
case TPM_TIS_STATE_COMPLETION:
tis->loc[locty].r_offset = 0;
- tis->loc[locty].sts = TPM_TIS_STS_VALID |
- TPM_TIS_STS_DATA_AVAILABLE;
+ tpm_tis_sts_set(&tis->loc[locty],
+ TPM_TIS_STS_VALID|
+ TPM_TIS_STS_DATA_AVAILABLE);
break;
default:
/* ignore */
@@ -737,6 +803,7 @@ static void tpm_tis_mmio_write_intern(void *opaque, hwaddr addr,
}
break;
case TPM_TIS_REG_DATA_FIFO:
+ case TPM_TIS_REG_DATA_XFIFO ... TPM_TIS_REG_DATA_XFIFO_END:
/* data fifo */
if (tis->active_locty != locty) {
break;
@@ -747,18 +814,28 @@ static void tpm_tis_mmio_write_intern(void *opaque, hwaddr addr,
tis->loc[locty].state == TPM_TIS_STATE_COMPLETION) {
/* drop the byte */
} else {
- DPRINTF("tpm_tis: Byte to send to TPM: %02x\n", (uint8_t)val);
+ DPRINTF("tpm_tis: Data to send to TPM: %08x (size=%d)\n",
+ val, size);
if (tis->loc[locty].state == TPM_TIS_STATE_READY) {
tis->loc[locty].state = TPM_TIS_STATE_RECEPTION;
- tis->loc[locty].sts = TPM_TIS_STS_EXPECT | TPM_TIS_STS_VALID;
+ tpm_tis_sts_set(&tis->loc[locty],
+ TPM_TIS_STS_EXPECT | TPM_TIS_STS_VALID);
+ }
+
+ val >>= shift;
+ if (size > 4 - (addr & 0x3)) {
+ /* prevent access beyond FIFO */
+ size = 4 - (addr & 0x3);
}
- if ((tis->loc[locty].sts & TPM_TIS_STS_EXPECT)) {
+ while ((tis->loc[locty].sts & TPM_TIS_STS_EXPECT) && size > 0) {
if (tis->loc[locty].w_offset < tis->loc[locty].w_buffer.size) {
tis->loc[locty].w_buffer.
buffer[tis->loc[locty].w_offset++] = (uint8_t)val;
+ val >>= 8;
+ size--;
} else {
- tis->loc[locty].sts = TPM_TIS_STS_VALID;
+ tpm_tis_sts_set(&tis->loc[locty], TPM_TIS_STS_VALID);
}
}
@@ -771,11 +848,11 @@ static void tpm_tis_mmio_write_intern(void *opaque, hwaddr addr,
#endif
len = tpm_tis_get_size_from_buffer(&tis->loc[locty].w_buffer);
if (len > tis->loc[locty].w_offset) {
- tis->loc[locty].sts = TPM_TIS_STS_EXPECT |
- TPM_TIS_STS_VALID;
+ tpm_tis_sts_set(&tis->loc[locty],
+ TPM_TIS_STS_EXPECT | TPM_TIS_STS_VALID);
} else {
/* packet complete */
- tis->loc[locty].sts = TPM_TIS_STS_VALID;
+ tpm_tis_sts_set(&tis->loc[locty], TPM_TIS_STS_VALID);
}
#ifdef RAISE_STS_IRQ
if (needIrq) {
diff --git a/hw/tpm/tpm_tis.h b/hw/tpm/tpm_tis.h
index 1a0db23367..db78d51e4f 100644
--- a/hw/tpm/tpm_tis.h
+++ b/hw/tpm/tpm_tis.h
@@ -41,7 +41,7 @@ typedef enum {
typedef struct TPMLocality {
TPMTISState state;
uint8_t access;
- uint8_t sts;
+ uint32_t sts;
uint32_t inte;
uint32_t ints;
diff --git a/hw/usb/hcd-ehci-pci.c b/hw/usb/hcd-ehci-pci.c
index 490f2b6af9..4c80707f85 100644
--- a/hw/usb/hcd-ehci-pci.c
+++ b/hw/usb/hcd-ehci-pci.c
@@ -26,7 +26,7 @@ typedef struct EHCIPCIInfo {
bool companion;
} EHCIPCIInfo;
-static int usb_ehci_pci_initfn(PCIDevice *dev)
+static void usb_ehci_pci_realize(PCIDevice *dev, Error **errp)
{
EHCIPCIState *i = PCI_EHCI(dev);
EHCIState *s = &i->ehci;
@@ -66,8 +66,6 @@ static int usb_ehci_pci_initfn(PCIDevice *dev)
usb_ehci_realize(s, DEVICE(dev), NULL);
pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mem);
-
- return 0;
}
static void usb_ehci_pci_init(Object *obj)
@@ -139,7 +137,7 @@ static void ehci_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- k->init = usb_ehci_pci_initfn;
+ k->realize = usb_ehci_pci_realize;
k->exit = usb_ehci_pci_exit;
k->class_id = PCI_CLASS_SERIAL_USB;
k->config_write = usb_ehci_pci_write_config;
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 828c2a7d78..ba15ae0019 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -3576,7 +3576,7 @@ static void usb_xhci_init(XHCIState *xhci)
}
}
-static int usb_xhci_initfn(struct PCIDevice *dev)
+static void usb_xhci_realize(struct PCIDevice *dev, Error **errp)
{
int i, ret;
@@ -3655,8 +3655,6 @@ static int usb_xhci_initfn(struct PCIDevice *dev)
&xhci->mem, 0, OFF_MSIX_PBA,
0x90);
}
-
- return 0;
}
static void usb_xhci_exit(PCIDevice *dev)
@@ -3896,7 +3894,7 @@ static void xhci_class_init(ObjectClass *klass, void *data)
dc->props = xhci_properties;
dc->reset = xhci_reset;
set_bit(DEVICE_CATEGORY_USB, dc->categories);
- k->init = usb_xhci_initfn;
+ k->realize = usb_xhci_realize;
k->exit = usb_xhci_exit;
k->vendor_id = PCI_VENDOR_ID_NEC;
k->device_id = PCI_DEVICE_ID_NEC_UPD720200;
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 9db7d8da17..b01262063d 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -201,7 +201,7 @@ static int vfio_dma_unmap(VFIOContainer *container,
};
if (ioctl(container->fd, VFIO_IOMMU_UNMAP_DMA, &unmap)) {
- error_report("VFIO_UNMAP_DMA: %d\n", -errno);
+ error_report("VFIO_UNMAP_DMA: %d", -errno);
return -errno;
}
@@ -234,7 +234,7 @@ static int vfio_dma_map(VFIOContainer *container, hwaddr iova,
return 0;
}
- error_report("VFIO_MAP_DMA: %d\n", -errno);
+ error_report("VFIO_MAP_DMA: %d", -errno);
return -errno;
}
@@ -274,7 +274,7 @@ static void vfio_iommu_map_notify(Notifier *n, void *data)
iotlb->translated_addr,
&xlat, &len, iotlb->perm & IOMMU_WO);
if (!memory_region_is_ram(mr)) {
- error_report("iommu map to non memory area %"HWADDR_PRIx"\n",
+ error_report("iommu map to non memory area %"HWADDR_PRIx"",
xlat);
return;
}
@@ -283,7 +283,7 @@ static void vfio_iommu_map_notify(Notifier *n, void *data)
* check that it did not truncate too much.
*/
if (len & iotlb->addr_mask) {
- error_report("iommu has granularity incompatible with target AS\n");
+ error_report("iommu has granularity incompatible with target AS");
return;
}
@@ -566,7 +566,7 @@ static void vfio_kvm_device_add_group(VFIOGroup *group)
};
if (kvm_vm_ioctl(kvm_state, KVM_CREATE_DEVICE, &cd)) {
- error_report("Failed to create KVM VFIO device: %m\n");
+ error_report("Failed to create KVM VFIO device: %m");
return;
}
@@ -949,6 +949,7 @@ int vfio_container_ioctl(AddressSpace *as, int32_t groupid,
switch (req) {
case VFIO_CHECK_EXTENSION:
case VFIO_IOMMU_SPAPR_TCE_GET_INFO:
+ case VFIO_EEH_PE_OP:
break;
default:
/* Return an error on unknown requests */
diff --git a/hw/virtio/dataplane/vring.c b/hw/virtio/dataplane/vring.c
index 0936f659e5..5c7b8c20fa 100644
--- a/hw/virtio/dataplane/vring.c
+++ b/hw/virtio/dataplane/vring.c
@@ -105,7 +105,7 @@ void vring_teardown(Vring *vring, VirtIODevice *vdev, int n)
/* Disable guest->host notifies */
void vring_disable_notification(VirtIODevice *vdev, Vring *vring)
{
- if (!(vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX))) {
+ if (!virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) {
vring_set_used_flags(vdev, vring, VRING_USED_F_NO_NOTIFY);
}
}
@@ -116,7 +116,7 @@ void vring_disable_notification(VirtIODevice *vdev, Vring *vring)
*/
bool vring_enable_notification(VirtIODevice *vdev, Vring *vring)
{
- if (vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) {
+ if (virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) {
vring_avail_event(&vring->vr) = vring->vr.avail->idx;
} else {
vring_clear_used_flags(vdev, vring, VRING_USED_F_NO_NOTIFY);
@@ -135,12 +135,12 @@ bool vring_should_notify(VirtIODevice *vdev, Vring *vring)
* interrupts. */
smp_mb();
- if ((vdev->guest_features & (1 << VIRTIO_F_NOTIFY_ON_EMPTY)) &&
+ if (virtio_has_feature(vdev, VIRTIO_F_NOTIFY_ON_EMPTY) &&
unlikely(!vring_more_avail(vdev, vring))) {
return true;
}
- if (!(vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX))) {
+ if (!virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) {
return !(vring_get_avail_flags(vdev, vring) &
VRING_AVAIL_F_NO_INTERRUPT);
}
@@ -401,7 +401,7 @@ int vring_pop(VirtIODevice *vdev, Vring *vring,
/* On success, increment avail index. */
vring->last_avail_idx++;
- if (vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) {
+ if (virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) {
vring_avail_event(&vring->vr) = vring->last_avail_idx;
}
diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c
index ff4f2001bb..4d68a27658 100644
--- a/hw/virtio/vhost-backend.c
+++ b/hw/virtio/vhost-backend.c
@@ -61,7 +61,7 @@ int vhost_set_backend_type(struct vhost_dev *dev, VhostBackendType backend_type)
dev->vhost_ops = &user_ops;
break;
default:
- error_report("Unknown vhost backend type\n");
+ error_report("Unknown vhost backend type");
r = -1;
}
diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
index 8a48d2a178..95b0643448 100644
--- a/hw/virtio/virtio-balloon.c
+++ b/hw/virtio/virtio-balloon.c
@@ -70,7 +70,7 @@ static inline void reset_stats(VirtIOBalloon *dev)
static bool balloon_stats_supported(const VirtIOBalloon *s)
{
VirtIODevice *vdev = VIRTIO_DEVICE(s);
- return vdev->guest_features & (1 << VIRTIO_BALLOON_F_STATS_VQ);
+ return virtio_has_feature(vdev, VIRTIO_BALLOON_F_STATS_VQ);
}
static bool balloon_stats_enabled(const VirtIOBalloon *s)
diff --git a/hw/virtio/virtio-bus.c b/hw/virtio/virtio-bus.c
index dfd2d8c772..be886e75af 100644
--- a/hw/virtio/virtio-bus.c
+++ b/hw/virtio/virtio-bus.c
@@ -109,20 +109,6 @@ uint32_t virtio_bus_get_vdev_features(VirtioBusState *bus,
return k->get_features(vdev, requested_features);
}
-/* Set the features of the plugged device. */
-void virtio_bus_set_vdev_features(VirtioBusState *bus,
- uint32_t requested_features)
-{
- VirtIODevice *vdev = virtio_bus_get_device(bus);
- VirtioDeviceClass *k;
-
- assert(vdev != NULL);
- k = VIRTIO_DEVICE_GET_CLASS(vdev);
- if (k->set_features != NULL) {
- k->set_features(vdev, requested_features);
- }
-}
-
/* Get bad features of the plugged device. */
uint32_t virtio_bus_get_vdev_bad_features(VirtioBusState *bus)
{
diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
index 2450c13747..10123f34b2 100644
--- a/hw/virtio/virtio-mmio.c
+++ b/hw/virtio/virtio-mmio.c
@@ -349,7 +349,7 @@ static void virtio_mmio_device_plugged(DeviceState *opaque)
{
VirtIOMMIOProxy *proxy = VIRTIO_MMIO(opaque);
- proxy->host_features |= (0x1 << VIRTIO_F_NOTIFY_ON_EMPTY);
+ virtio_add_feature(&proxy->host_features, VIRTIO_F_NOTIFY_ON_EMPTY);
proxy->host_features = virtio_bus_get_vdev_features(&proxy->bus,
proxy->host_features);
}
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 604cb5b749..e7baf7b5e8 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -17,6 +17,7 @@
#include <inttypes.h>
+#include "standard-headers/linux/virtio_pci.h"
#include "hw/virtio/virtio.h"
#include "hw/virtio/virtio-blk.h"
#include "hw/virtio/virtio-net.h"
@@ -35,56 +36,11 @@
#include "hw/virtio/virtio-bus.h"
#include "qapi/visitor.h"
-/* from Linux's linux/virtio_pci.h */
-
-/* A 32-bit r/o bitmask of the features supported by the host */
-#define VIRTIO_PCI_HOST_FEATURES 0
-
-/* A 32-bit r/w bitmask of features activated by the guest */
-#define VIRTIO_PCI_GUEST_FEATURES 4
-
-/* A 32-bit r/w PFN for the currently selected queue */
-#define VIRTIO_PCI_QUEUE_PFN 8
-
-/* A 16-bit r/o queue size for the currently selected queue */
-#define VIRTIO_PCI_QUEUE_NUM 12
-
-/* A 16-bit r/w queue selector */
-#define VIRTIO_PCI_QUEUE_SEL 14
-
-/* A 16-bit r/w queue notifier */
-#define VIRTIO_PCI_QUEUE_NOTIFY 16
-
-/* An 8-bit device status register. */
-#define VIRTIO_PCI_STATUS 18
-
-/* An 8-bit r/o interrupt status register. Reading the value will return the
- * current contents of the ISR and will also clear it. This is effectively
- * a read-and-acknowledge. */
-#define VIRTIO_PCI_ISR 19
-
-/* MSI-X registers: only enabled if MSI-X is enabled. */
-/* A 16-bit vector for configuration changes. */
-#define VIRTIO_MSI_CONFIG_VECTOR 20
-/* A 16-bit vector for selected queue notifications. */
-#define VIRTIO_MSI_QUEUE_VECTOR 22
-
-/* Config space size */
-#define VIRTIO_PCI_CONFIG_NOMSI 20
-#define VIRTIO_PCI_CONFIG_MSI 24
-#define VIRTIO_PCI_REGION_SIZE(dev) (msix_present(dev) ? \
- VIRTIO_PCI_CONFIG_MSI : \
- VIRTIO_PCI_CONFIG_NOMSI)
+#define VIRTIO_PCI_REGION_SIZE(dev) VIRTIO_PCI_CONFIG_OFF(msix_present(dev))
/* The remaining space is defined by each driver as the per-driver
* configuration space */
-#define VIRTIO_PCI_CONFIG(dev) (msix_enabled(dev) ? \
- VIRTIO_PCI_CONFIG_MSI : \
- VIRTIO_PCI_CONFIG_NOMSI)
-
-/* How many bits to shift physical queue address written to QUEUE_PFN.
- * 12 is historical, and due to x86 page size. */
-#define VIRTIO_PCI_QUEUE_ADDR_SHIFT 12
+#define VIRTIO_PCI_CONFIG_SIZE(dev) VIRTIO_PCI_CONFIG_OFF(msix_enabled(dev))
static void virtio_pci_bus_new(VirtioBusState *bus, size_t bus_size,
VirtIOPCIProxy *dev);
@@ -392,7 +348,7 @@ static uint64_t virtio_pci_config_read(void *opaque, hwaddr addr,
{
VirtIOPCIProxy *proxy = opaque;
VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
- uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
+ uint32_t config = VIRTIO_PCI_CONFIG_SIZE(&proxy->pci_dev);
uint64_t val = 0;
if (addr < config) {
return virtio_ioport_read(proxy, addr);
@@ -423,7 +379,7 @@ static void virtio_pci_config_write(void *opaque, hwaddr addr,
uint64_t val, unsigned size)
{
VirtIOPCIProxy *proxy = opaque;
- uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
+ uint32_t config = VIRTIO_PCI_CONFIG_SIZE(&proxy->pci_dev);
VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
if (addr < config) {
virtio_ioport_write(proxy, addr, val);
@@ -996,8 +952,8 @@ static void virtio_pci_device_plugged(DeviceState *d)
proxy->flags &= ~VIRTIO_PCI_FLAG_USE_IOEVENTFD;
}
- proxy->host_features |= 0x1 << VIRTIO_F_NOTIFY_ON_EMPTY;
- proxy->host_features |= 0x1 << VIRTIO_F_BAD_FEATURE;
+ virtio_add_feature(&proxy->host_features, VIRTIO_F_NOTIFY_ON_EMPTY);
+ virtio_add_feature(&proxy->host_features, VIRTIO_F_BAD_FEATURE);
proxy->host_features = virtio_bus_get_vdev_features(bus,
proxy->host_features);
}
@@ -1318,9 +1274,8 @@ static void virtio_balloon_pci_class_init(ObjectClass *klass, void *data)
static void virtio_balloon_pci_instance_init(Object *obj)
{
VirtIOBalloonPCI *dev = VIRTIO_BALLOON_PCI(obj);
- object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_BALLOON);
- object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
- object_unref(OBJECT(&dev->vdev));
+ virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
+ TYPE_VIRTIO_BALLOON);
object_property_add(obj, "guest-stats", "guest statistics",
balloon_pci_stats_get_all, NULL, NULL, dev,
NULL);
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index d735343ca8..3c6e430048 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -155,7 +155,7 @@ static inline uint16_t vring_avail_ring(VirtQueue *vq, int i)
return virtio_lduw_phys(vq->vdev, pa);
}
-static inline uint16_t vring_used_event(VirtQueue *vq)
+static inline uint16_t vring_get_used_event(VirtQueue *vq)
{
return vring_avail_ring(vq, vq->vring.num);
}
@@ -204,7 +204,7 @@ static inline void vring_used_flags_unset_bit(VirtQueue *vq, int mask)
virtio_stw_phys(vdev, pa, virtio_lduw_phys(vdev, pa) & ~mask);
}
-static inline void vring_avail_event(VirtQueue *vq, uint16_t val)
+static inline void vring_set_avail_event(VirtQueue *vq, uint16_t val)
{
hwaddr pa;
if (!vq->notification) {
@@ -217,8 +217,8 @@ static inline void vring_avail_event(VirtQueue *vq, uint16_t val)
void virtio_queue_set_notification(VirtQueue *vq, int enable)
{
vq->notification = enable;
- if (vq->vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) {
- vring_avail_event(vq, vring_avail_idx(vq));
+ if (virtio_has_feature(vq->vdev, VIRTIO_RING_F_EVENT_IDX)) {
+ vring_set_avail_event(vq, vring_avail_idx(vq));
} else if (enable) {
vring_used_flags_unset_bit(vq, VRING_USED_F_NO_NOTIFY);
} else {
@@ -468,8 +468,8 @@ int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem)
max = vq->vring.num;
i = head = virtqueue_get_head(vq, vq->last_avail_idx++);
- if (vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) {
- vring_avail_event(vq, vq->last_avail_idx);
+ if (virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) {
+ vring_set_avail_event(vq, vq->last_avail_idx);
}
if (vring_desc_flags(vdev, desc_pa, i) & VRING_DESC_F_INDIRECT) {
@@ -819,19 +819,6 @@ void virtio_irq(VirtQueue *vq)
virtio_notify_vector(vq->vdev, vq->vector);
}
-/* Assuming a given event_idx value from the other size, if
- * we have just incremented index from old to new_idx,
- * should we trigger an event? */
-static inline int vring_need_event(uint16_t event, uint16_t new, uint16_t old)
-{
- /* Note: Xen has similar logic for notification hold-off
- * in include/xen/interface/io/ring.h with req_event and req_prod
- * corresponding to event_idx + 1 and new respectively.
- * Note also that req_event and req_prod in Xen start at 1,
- * event indexes in virtio start at 0. */
- return (uint16_t)(new - event - 1) < (uint16_t)(new - old);
-}
-
static bool vring_notify(VirtIODevice *vdev, VirtQueue *vq)
{
uint16_t old, new;
@@ -839,12 +826,12 @@ static bool vring_notify(VirtIODevice *vdev, VirtQueue *vq)
/* We need to expose used array entries before checking used event. */
smp_mb();
/* Always notify when queue is empty (when feature acknowledge) */
- if (((vdev->guest_features & (1 << VIRTIO_F_NOTIFY_ON_EMPTY)) &&
- !vq->inuse && vring_avail_idx(vq) == vq->last_avail_idx)) {
+ if (virtio_has_feature(vdev, VIRTIO_F_NOTIFY_ON_EMPTY) &&
+ !vq->inuse && vring_avail_idx(vq) == vq->last_avail_idx) {
return true;
}
- if (!(vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX))) {
+ if (!virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) {
return !(vring_avail_flags(vq) & VRING_AVAIL_F_NO_INTERRUPT);
}
@@ -852,7 +839,7 @@ static bool vring_notify(VirtIODevice *vdev, VirtQueue *vq)
vq->signalled_used_valid = true;
old = vq->signalled_used;
new = vq->signalled_used = vring_used_idx(vq);
- return !v || vring_need_event(vring_used_event(vq), new, old);
+ return !v || vring_need_event(vring_get_used_event(vq), new, old);
}
void virtio_notify(VirtIODevice *vdev, VirtQueue *vq)
diff --git a/hw/watchdog/wdt_i6300esb.c b/hw/watchdog/wdt_i6300esb.c
index 33dd6d43c0..b2d158f7ba 100644
--- a/hw/watchdog/wdt_i6300esb.c
+++ b/hw/watchdog/wdt_i6300esb.c
@@ -408,7 +408,7 @@ static const VMStateDescription vmstate_i6300esb = {
}
};
-static int i6300esb_init(PCIDevice *dev)
+static void i6300esb_realize(PCIDevice *dev, Error **errp)
{
I6300State *d = DO_UPCAST(I6300State, dev, dev);
@@ -421,8 +421,6 @@ static int i6300esb_init(PCIDevice *dev)
"i6300esb", 0x10);
pci_register_bar(&d->dev, 0, 0, &d->io_mem);
/* qemu_register_coalesced_mmio (addr, 0x10); ? */
-
- return 0;
}
static WatchdogTimerModel model = {
@@ -437,7 +435,7 @@ static void i6300esb_class_init(ObjectClass *klass, void *data)
k->config_read = i6300esb_config_read;
k->config_write = i6300esb_config_write;
- k->init = i6300esb_init;
+ k->realize = i6300esb_realize;
k->vendor_id = PCI_VENDOR_ID_INTEL;
k->device_id = PCI_DEVICE_ID_INTEL_ESB_9;
k->class_id = PCI_CLASS_SYSTEM_OTHER;
diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c
index de9a20f437..d99c22ef2f 100644
--- a/hw/xen/xen_pt_config_init.c
+++ b/hw/xen/xen_pt_config_init.c
@@ -360,15 +360,13 @@ static uint64_t xen_pt_get_bar_size(PCIIORegion *r)
}
static XenPTBarFlag xen_pt_bar_reg_parse(XenPCIPassthroughState *s,
- XenPTRegInfo *reg)
+ int index)
{
PCIDevice *d = &s->dev;
XenPTRegion *region = NULL;
PCIIORegion *r;
- int index = 0;
/* check 64bit BAR */
- index = xen_pt_bar_offset_to_index(reg->offset);
if ((0 < index) && (index < PCI_ROM_SLOT)) {
int type = s->real_device.io_regions[index - 1].type;
@@ -422,7 +420,7 @@ static int xen_pt_bar_reg_init(XenPCIPassthroughState *s, XenPTRegInfo *reg,
}
/* set BAR flag */
- s->bases[index].bar_flag = xen_pt_bar_reg_parse(s, reg);
+ s->bases[index].bar_flag = xen_pt_bar_reg_parse(s, index);
if (s->bases[index].bar_flag == XEN_PT_BAR_FLAG_UNUSED) {
reg_field = XEN_PT_INVALID_REG;
}
@@ -440,7 +438,7 @@ static int xen_pt_bar_reg_read(XenPCIPassthroughState *s, XenPTReg *cfg_entry,
/* get BAR index */
index = xen_pt_bar_offset_to_index(reg->offset);
- if (index < 0 || index >= PCI_NUM_REGIONS) {
+ if (index < 0 || index >= PCI_NUM_REGIONS - 1) {
XEN_PT_ERR(&s->dev, "Internal error: Invalid BAR index [%d].\n", index);
return -1;
}
diff --git a/hw/xtensa/sim.c b/hw/xtensa/sim.c
index 37ea9ae9c2..328d20975d 100644
--- a/hw/xtensa/sim.c
+++ b/hw/xtensa/sim.c
@@ -64,7 +64,7 @@ static void xtensa_sim_init(MachineState *machine)
for (n = 0; n < smp_cpus; n++) {
cpu = cpu_xtensa_init(cpu_model);
if (cpu == NULL) {
- error_report("unable to find CPU definition '%s'\n",
+ error_report("unable to find CPU definition '%s'",
cpu_model);
exit(EXIT_FAILURE);
}
diff --git a/hw/xtensa/xtfpga.c b/hw/xtensa/xtfpga.c
index d441c024c2..ab4d0e4127 100644
--- a/hw/xtensa/xtfpga.c
+++ b/hw/xtensa/xtfpga.c
@@ -207,7 +207,7 @@ static void lx_init(const LxBoardDesc *board, MachineState *machine)
for (n = 0; n < smp_cpus; n++) {
cpu = cpu_xtensa_init(cpu_model);
if (cpu == NULL) {
- error_report("unable to find CPU definition '%s'\n",
+ error_report("unable to find CPU definition '%s'",
cpu_model);
exit(EXIT_FAILURE);
}
@@ -253,7 +253,7 @@ static void lx_init(const LxBoardDesc *board, MachineState *machine)
board->flash_size / board->flash_sector_size,
4, 0x0000, 0x0000, 0x0000, 0x0000, be);
if (flash == NULL) {
- error_report("unable to mount pflash\n");
+ error_report("unable to mount pflash");
exit(EXIT_FAILURE);
}
}
@@ -305,7 +305,7 @@ static void lx_init(const LxBoardDesc *board, MachineState *machine)
uint32_t dtb_addr = tswap32(cur_lowmem);
if (!fdt) {
- error_report("could not load DTB '%s'\n", dtb_filename);
+ error_report("could not load DTB '%s'", dtb_filename);
exit(EXIT_FAILURE);
}
@@ -325,7 +325,7 @@ static void lx_init(const LxBoardDesc *board, MachineState *machine)
lowmem_end - cur_lowmem);
}
if (initrd_size < 0) {
- error_report("could not load initrd '%s'\n", initrd_filename);
+ error_report("could not load initrd '%s'", initrd_filename);
exit(EXIT_FAILURE);
}
initrd_location.start = tswap32(cur_lowmem);
@@ -351,7 +351,7 @@ static void lx_init(const LxBoardDesc *board, MachineState *machine)
if (success > 0 && is_linux) {
entry_point = ep;
} else {
- error_report("could not load kernel '%s'\n",
+ error_report("could not load kernel '%s'",
kernel_filename);
exit(EXIT_FAILURE);
}