From 16771613a89838020ee6d84be40b46c6a8180824 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Wed, 28 Jan 2015 18:18:50 +0200 Subject: [PATCH 001/130] acpi-build: fix memory leak with bridge hp off When bridge hotplug is disabled for old machine types, we never free memory allocated for temporary tables. Fix this up. Cc: qemu-stable@nongnu.org Signed-off-by: Michael S. Tsirkin --- hw/i386/acpi-build.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 4944249b84..74586f346f 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -859,6 +859,9 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state) * to make acpi tables compatible with legacy machine types. */ if (!child->pcihp_bridge_en && bus->parent_dev) { + build_free_array(bus_table); + build_pci_bus_state_cleanup(child); + g_free(child); return; } From 12e63900f01ce54702745d83f985e26042adda9b Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Sun, 1 Feb 2015 11:54:26 +0200 Subject: [PATCH 002/130] bios linker: validate pointer within table buios linker assumes pointer parameter it gets is within table, validate this. Signed-off-by: Michael S. Tsirkin --- hw/acpi/bios-linker-loader.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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); From 19934e0e3d0f70eefe8d9e51e71c1cb80f4659d0 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Fri, 30 Jan 2015 13:29:36 +0000 Subject: [PATCH 003/130] acpi: move generic aml building helpers into dedictated file the will be later used for composing AML primitives and all that could be reused later for ARM machines as well. Signed-off-by: Igor Mammedov Acked-by: Marcel Apfelbaum Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/Makefile.objs | 1 + hw/acpi/aml-build.c | 187 ++++++++++++++++++++++++++++++++++++ hw/i386/acpi-build.c | 162 +------------------------------ include/hw/acpi/aml-build.h | 23 +++++ 4 files changed, 213 insertions(+), 160 deletions(-) create mode 100644 hw/acpi/aml-build.c create mode 100644 include/hw/acpi/aml-build.h 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..b28c1f41a5 --- /dev/null +++ b/hw/acpi/aml-build.c @@ -0,0 +1,187 @@ +/* Support for generating ACPI tables and passing them to Guests + * + * Copyright (C) 2015 Red Hat Inc + * + * Author: Michael S. Tsirkin + * Author: Igor Mammedov + * + * 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 . + */ + +#include +#include +#include +#include +#include "hw/acpi/aml-build.h" + +GArray *build_alloc_array(void) +{ + return g_array_new(false, true /* clear */, 1); +} + +void build_free_array(GArray *array) +{ + g_array_free(array, true); +} + +void build_prepend_byte(GArray *array, uint8_t val) +{ + g_array_prepend_val(array, val); +} + +void build_append_byte(GArray *array, uint8_t val) +{ + g_array_append_val(array, val); +} + +void build_append_array(GArray *array, GArray *val) +{ + g_array_append_vals(array, val->data, val->len); +} + +#define ACPI_NAMESEG_LEN 4 + +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, +}; + +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); +} + +void build_package(GArray *package, uint8_t op, unsigned min_bytes) +{ + build_prepend_package_length(package, min_bytes); + build_prepend_byte(package, op); +} + +void build_extop_package(GArray *package, uint8_t op) +{ + build_package(package, op, 1); + build_prepend_byte(package, 0x5B); /* ExtOpPrefix */ +} + +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; + } +} + +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); + } +} + diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 74586f346f..cc638a9ab0 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" @@ -280,166 +282,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(); diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h new file mode 100644 index 0000000000..e6a0b28990 --- /dev/null +++ b/include/hw/acpi/aml-build.h @@ -0,0 +1,23 @@ +#ifndef HW_ACPI_GEN_UTILS_H +#define HW_ACPI_GEN_UTILS_H + +#include +#include +#include "qemu/compiler.h" + +GArray *build_alloc_array(void); +void build_free_array(GArray *array); +void build_prepend_byte(GArray *array, uint8_t val); +void build_append_byte(GArray *array, uint8_t val); +void build_append_array(GArray *array, GArray *val); + +void GCC_FMT_ATTR(2, 3) +build_append_nameseg(GArray *array, const char *format, ...); + +void build_prepend_package_length(GArray *package, unsigned min_bytes); +void build_package(GArray *package, uint8_t op, unsigned min_bytes); +void build_append_value(GArray *table, uint32_t value, int size); +void build_append_int(GArray *table, uint32_t value); +void build_extop_package(GArray *package, uint8_t op); + +#endif From eae8bded9a1a19561054654f5113aeb978d7b4c1 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Fri, 30 Jan 2015 13:29:37 +0000 Subject: [PATCH 004/130] acpi: add build_append_namestring() helper Use build_append_namestring() instead of build_append_nameseg() So user won't have to care whether name is NameSeg, NamePath or NameString. See for reference ACPI 5.0: 20.2.2 Name Objects Encoding Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/aml-build.c | 96 +++++++++++++++++++++++++++++++++---- hw/i386/acpi-build.c | 37 +++++++------- include/hw/acpi/aml-build.h | 2 +- 3 files changed, 105 insertions(+), 30 deletions(-) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index b28c1f41a5..6a02474e17 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "hw/acpi/aml-build.h" GArray *build_alloc_array(void) @@ -52,25 +53,102 @@ void build_append_array(GArray *array, GArray *val) #define ACPI_NAMESEG_LEN 4 -void GCC_FMT_ATTR(2, 3) -build_append_nameseg(GArray *array, const char *format, ...) +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 */ - char s[] = "XXXX"; int len; - va_list args; - - va_start(args, format); - len = vsnprintf(s, sizeof s, format, args); - va_end(args); + len = strlen(seg); assert(len <= ACPI_NAMESEG_LEN); - g_array_append_vals(array, s, 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); +} + +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. */ diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index cc638a9ab0..df2bad0a3b 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -286,7 +286,7 @@ 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_namestring(method, "%s", name); build_append_byte(method, arg_count); /* MethodFlags: ArgCount */ return method; @@ -578,7 +578,7 @@ build_append_notify_method(GArray *device, const char *name, for (i = 0; i < count; i++) { GArray *target = build_alloc_array(); - build_append_nameseg(target, format, i); + build_append_namestring(target, format, i); assert(i < 256); /* Fits in 1 byte */ build_append_notify_target_ifequal(method, target, i, 1); build_free_array(target); @@ -709,24 +709,24 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state) if (bus->parent_dev) { op = 0x82; /* DeviceOp */ - build_append_nameseg(bus_table, "S%.02X", + build_append_namestring(bus_table, "S%.02X", bus->parent_dev->devfn); build_append_byte(bus_table, 0x08); /* NameOp */ - build_append_nameseg(bus_table, "_SUN"); + build_append_namestring(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_namestring(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"); + build_append_namestring(bus_table, "PCI0"); } 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_namestring(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 { @@ -829,7 +829,7 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state) 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_namestring(notify, "S%.02X", PCI_DEVFN(i, 0)); build_append_byte(notify, 0x69); /* Arg1Op */ /* Pack it up */ @@ -853,12 +853,12 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state) 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_namestring(method, "BNUM"); + build_append_namestring(method, "DVNT"); + build_append_namestring(method, "PCIU"); build_append_int(method, 1); /* Device Check */ - build_append_nameseg(method, "DVNT"); - build_append_nameseg(method, "PCID"); + build_append_namestring(method, "DVNT"); + build_append_namestring(method, "PCID"); build_append_int(method, 3); /* Eject Request */ } @@ -884,11 +884,8 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state) * 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"); + build_append_namestring(parent->notify_table, "^PCNT.S%.02X", + bus->parent_dev->devfn); } } @@ -956,7 +953,7 @@ build_ssdt(GArray *table_data, GArray *linker, GArray *sb_scope = build_alloc_array(); uint8_t op = 0x10; /* ScopeOp */ - build_append_nameseg(sb_scope, "_SB"); + build_append_namestring(sb_scope, "_SB"); /* build Processor object for each processor */ for (i = 0; i < acpi_cpus; i++) { @@ -976,7 +973,7 @@ build_ssdt(GArray *table_data, GArray *linker, /* build "Name(CPON, Package() { One, One, ..., Zero, Zero, ... })" */ build_append_byte(sb_scope, 0x08); /* NameOp */ - build_append_nameseg(sb_scope, "CPON"); + build_append_namestring(sb_scope, "CPON"); { GArray *package = build_alloc_array(); diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index e6a0b28990..fd506252bd 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -12,7 +12,7 @@ void build_append_byte(GArray *array, uint8_t val); void build_append_array(GArray *array, GArray *val); void GCC_FMT_ATTR(2, 3) -build_append_nameseg(GArray *array, const char *format, ...); +build_append_namestring(GArray *array, const char *format, ...); void build_prepend_package_length(GArray *package, unsigned min_bytes); void build_package(GArray *package, uint8_t op, unsigned min_bytes); From 661875e948ece4723ebe4e7628060c27cad06df1 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Fri, 30 Jan 2015 13:29:38 +0000 Subject: [PATCH 005/130] acpi: drop min-bytes in build_package() Signed-off-by: Igor Mammedov Reviewed-by: Claudio Fontana Reviewed-by: Marcel Apfelbaum Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/aml-build.c | 14 ++++---------- hw/i386/acpi-build.c | 13 ++++++------- include/hw/acpi/aml-build.h | 4 ++-- 3 files changed, 12 insertions(+), 19 deletions(-) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index 6a02474e17..bcb288eab4 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -157,7 +157,7 @@ enum { PACKAGE_LENGTH_4BYTE_SHIFT = 20, }; -void build_prepend_package_length(GArray *package, unsigned min_bytes) +void build_prepend_package_length(GArray *package) { uint8_t byte; unsigned length = package->len; @@ -173,11 +173,6 @@ void build_prepend_package_length(GArray *package, unsigned min_bytes) 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; @@ -210,15 +205,15 @@ void build_prepend_package_length(GArray *package, unsigned min_bytes) build_prepend_byte(package, byte); } -void build_package(GArray *package, uint8_t op, unsigned min_bytes) +void build_package(GArray *package, uint8_t op) { - build_prepend_package_length(package, min_bytes); + build_prepend_package_length(package); build_prepend_byte(package, op); } void build_extop_package(GArray *package, uint8_t op) { - build_package(package, op, 1); + build_package(package, op); build_prepend_byte(package, 0x5B); /* ExtOpPrefix */ } @@ -262,4 +257,3 @@ void build_append_int(GArray *table, uint32_t value) build_append_value(table, value, 4); } } - diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index df2bad0a3b..5737ed061c 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -296,7 +296,7 @@ static void build_append_and_cleanup_method(GArray *device, GArray *method) { uint8_t op = 0x14; /* MethodOp */ - build_package(method, op, 0); + build_package(method, op); build_append_array(device, method); build_free_array(method); @@ -317,7 +317,7 @@ static void build_append_notify_target_ifequal(GArray *method, build_append_byte(notify, 0x69); /* Arg1Op */ /* Pack it up */ - build_package(notify, op, 1); + build_package(notify, op); build_append_array(method, notify); @@ -833,7 +833,7 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state) build_append_byte(notify, 0x69); /* Arg1Op */ /* Pack it up */ - build_package(notify, op, 0); + build_package(notify, op); build_append_array(method, notify); @@ -874,7 +874,7 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state) if (bus->parent_dev) { build_extop_package(bus_table, op); } else { - build_package(bus_table, op, 0); + build_package(bus_table, op); } /* Append our bus description to parent table */ @@ -997,7 +997,7 @@ build_ssdt(GArray *table_data, GArray *linker, build_append_byte(package, b); } - build_package(package, op, 2); + build_package(package, op); build_append_array(sb_scope, package); build_free_array(package); } @@ -1045,8 +1045,7 @@ build_ssdt(GArray *table_data, GArray *linker, build_append_array(sb_scope, hotplug_state.device_table); build_pci_bus_state_cleanup(&hotplug_state); } - - build_package(sb_scope, op, 3); + build_package(sb_scope, op); build_append_array(table_data, sb_scope); build_free_array(sb_scope); } diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index fd506252bd..199f003265 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -14,8 +14,8 @@ void build_append_array(GArray *array, GArray *val); void GCC_FMT_ATTR(2, 3) build_append_namestring(GArray *array, const char *format, ...); -void build_prepend_package_length(GArray *package, unsigned min_bytes); -void build_package(GArray *package, uint8_t op, unsigned min_bytes); +void build_prepend_package_length(GArray *package); +void build_package(GArray *package, uint8_t op); void build_append_value(GArray *table, uint32_t value, int size); void build_append_int(GArray *table, uint32_t value); void build_extop_package(GArray *package, uint8_t op); From 133e9b228df16d11de01529c217417e78d1d9370 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Mon, 19 Jan 2015 15:52:28 +0100 Subject: [PATCH 006/130] pci: Convert core to realize Implement DeviceClass methods realize() and unrealize() instead of init() and exit(). The core's initialization errors now get propagated properly, and QMP sends them instead of an unspecific "Device initialization failed" error. Unrealize can't fail, so no change there. PCIDeviceClass is unchanged: it still provides init() and exit(). Therefore, device models' errors are still not propagated. Signed-off-by: Markus Armbruster Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Gonglei --- hw/pci/pci.c | 93 +++++++++++++++++++++++++++------------------------- 1 file changed, 49 insertions(+), 44 deletions(-) diff --git a/hw/pci/pci.c b/hw/pci/pci.c index 31b222d8c0..fe697b1544 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; @@ -726,7 +726,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 +752,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 +803,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 +818,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 +870,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 +903,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 +916,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, @@ -1751,10 +1756,11 @@ 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; @@ -1767,15 +1773,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) { do_pci_unregister_device(pci_dev); - return rc; + error_setg(errp, "Device initialization failed"); + return; } } @@ -1786,13 +1793,12 @@ 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; } PCIDevice *pci_create_multifunction(PCIBus *bus, int devfn, bool multifunction, @@ -1932,7 +1938,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 +1948,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 +1964,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 +1974,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 +1984,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 +2016,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,8 +2296,8 @@ 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; + k->realize = pci_qdev_realize; + k->unrealize = pci_qdev_unrealize; k->bus_type = TYPE_PCI_BUS; k->props = pci_props; } From 7ee6c1e182cca6ccf5253569fca3d05826efb4e9 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Mon, 19 Jan 2015 15:52:29 +0100 Subject: [PATCH 007/130] pci: Permit incremental conversion of device models to realize Call the new PCIDeviceClass method realize(). Default it to pci_default_realize(), which calls old method init(). To convert a device model, make it implement realize() rather than init(). Signed-off-by: Markus Armbruster Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Gonglei --- hw/pci/pci.c | 24 +++++++++++++++++++----- include/hw/pci/pci.h | 3 ++- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/hw/pci/pci.c b/hw/pci/pci.c index fe697b1544..b1f3cea9af 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -1762,7 +1762,6 @@ static void pci_qdev_realize(DeviceState *qdev, Error **errp) 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() */ @@ -1777,11 +1776,11 @@ static void pci_qdev_realize(DeviceState *qdev, Error **errp) if (pci_dev == NULL) 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); - error_setg(errp, "Device initialization failed"); return; } } @@ -1801,6 +1800,18 @@ static void pci_qdev_realize(DeviceState *qdev, Error **errp) } } +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, const char *name) { @@ -2296,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); + 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/include/hw/pci/pci.h b/include/hw/pci/pci.h index bdee464e61..3164fc3a4f 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -185,7 +185,8 @@ typedef struct PCIINTxRoute { typedef struct PCIDeviceClass { DeviceClass parent_class; - int (*init)(PCIDevice *dev); + void (*realize)(PCIDevice *dev, Error **errp); + int (*init)(PCIDevice *dev);/* TODO convert to realize() and remove */ PCIUnregisterFunc *exit; PCIConfigReadFunc *config_read; PCIConfigWriteFunc *config_write; From 9af21dbee14c5165598d17115ade63184ec0dd8b Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Mon, 19 Jan 2015 15:52:30 +0100 Subject: [PATCH 008/130] pci: Trivial device model conversions to realize Convert the device models where initialization obviously can't fail. Signed-off-by: Markus Armbruster Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Gonglei --- hw/acpi/piix4.c | 5 ++--- hw/audio/ac97.c | 5 ++--- hw/audio/es1370.c | 5 ++--- hw/audio/intel-hda.c | 6 ++---- hw/display/vga-pci.c | 11 ++++------- hw/display/vmware_vga.c | 6 ++---- hw/i2c/smbus_ich9.c | 5 ++--- hw/ide/cmd646.c | 5 ++--- hw/ide/piix.c | 10 ++++------ hw/ide/via.c | 6 ++---- hw/ipack/tpci200.c | 6 ++---- hw/isa/i82378.c | 6 ++---- hw/isa/piix4.c | 5 ++--- hw/isa/vt82c686.c | 24 ++++++++---------------- hw/misc/pci-testdev.c | 6 ++---- hw/net/e1000.c | 6 ++---- hw/net/eepro100.c | 6 ++---- hw/net/ne2000.c | 6 ++---- hw/net/rtl8139.c | 6 ++---- hw/net/vmxnet3.c | 6 ++---- hw/pci-bridge/dec.c | 5 ++--- hw/pci-host/apb.c | 5 ++--- hw/pci-host/bonito.c | 6 ++---- hw/pci-host/grackle.c | 5 ++--- hw/pci-host/piix.c | 12 +++++------- hw/pci-host/ppce500.c | 6 ++---- hw/pci-host/prep.c | 6 ++---- hw/pci-host/q35.c | 5 ++--- hw/pci-host/uninorth.c | 20 ++++++++------------ hw/pci-host/versatile.c | 5 ++--- hw/sd/sdhci.c | 5 ++--- hw/usb/hcd-ehci-pci.c | 6 ++---- hw/usb/hcd-xhci.c | 6 ++---- hw/watchdog/wdt_i6300esb.c | 6 ++---- 34 files changed, 87 insertions(+), 152 deletions(-) diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c index 184e7e49b9..017510b791 100644 --- a/hw/acpi/piix4.c +++ b/hw/acpi/piix4.c @@ -420,7 +420,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 +470,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) @@ -593,7 +592,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; 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/display/vga-pci.c b/hw/display/vga-pci.c index 53739e4f79..d67f748af4 100644 --- a/hw/display/vga-pci.c +++ b/hw/display/vga-pci.c @@ -189,7 +189,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 +232,9 @@ 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 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; @@ -268,7 +266,6 @@ 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_reset(DeviceState *dev) @@ -298,7 +295,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 +311,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; 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/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/ide/cmd646.c b/hw/ide/cmd646.c index c8b0322155..dafa9ec7c7 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; @@ -374,7 +374,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) @@ -410,7 +409,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/piix.c b/hw/ide/piix.c index b0172fbf59..ab930843e8 100644 --- a/hw/ide/piix.c +++ b/hw/ide/piix.c @@ -148,7 +148,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; @@ -163,8 +163,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) @@ -238,7 +236,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; @@ -258,7 +256,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; @@ -276,7 +274,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 4d8089de75..7a5151c5c1 100644 --- a/hw/ide/via.c +++ b/hw/ide/via.c @@ -172,7 +172,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; @@ -187,8 +187,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) @@ -215,7 +213,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/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/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/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/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/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/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/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/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/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 776699b44e..09eaa1fe88 100644 --- a/hw/usb/hcd-xhci.c +++ b/hw/usb/hcd-xhci.c @@ -3567,7 +3567,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; @@ -3646,8 +3646,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) @@ -3887,7 +3885,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/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; From 4c3b22459d3589cf84d1ccadc6b09e586497820d Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Mon, 19 Jan 2015 15:52:31 +0100 Subject: [PATCH 009/130] pcnet: pcnet_common_init() always returns 0, change to void The next commit will exploit the fact it never fails. This one makes it obvious. Signed-off-by: Markus Armbruster Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Gonglei --- hw/net/lance.c | 3 ++- hw/net/pcnet-pci.c | 3 ++- hw/net/pcnet.c | 4 +--- hw/net/pcnet.h | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) 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/pcnet-pci.c b/hw/net/pcnet-pci.c index 5df79f0a1f..9677c1215a 100644 --- a/hw/net/pcnet-pci.c +++ b/hw/net/pcnet-pci.c @@ -316,7 +316,8 @@ 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); + return 0; } static void pci_reset(DeviceState *dev) 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 From eb1bef94b4067b19abac91fec001c690a58b2174 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Mon, 19 Jan 2015 15:52:32 +0100 Subject: [PATCH 010/130] pcnet: Convert to realize Signed-off-by: Markus Armbruster Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Gonglei --- hw/net/pcnet-pci.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/hw/net/pcnet-pci.c b/hw/net/pcnet-pci.c index 9677c1215a..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; @@ -317,7 +317,6 @@ static int pci_pcnet_init(PCIDevice *pci_dev) s->dma_opaque = pci_dev; pcnet_common_init(DEVICE(pci_dev), s, &net_pci_pcnet_info); - return 0; } static void pci_reset(DeviceState *dev) @@ -347,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; From 28d85904daafda4e099d6a61371ab8e5c1f395bd Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Mon, 19 Jan 2015 15:52:33 +0100 Subject: [PATCH 011/130] serial-pci: Convert to realize Signed-off-by: Markus Armbruster Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Gonglei --- hw/char/serial-pci.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) 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; From b8a2dac04aea1f6c801bbb6c44a33ee7cd4ff533 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Mon, 19 Jan 2015 15:52:34 +0100 Subject: [PATCH 012/130] ide/ich: Convert to realize Signed-off-by: Markus Armbruster Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Gonglei --- hw/ide/ich.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) 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; From f409edf74360805e53e16e6a51ca766e8891f3b7 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Mon, 19 Jan 2015 15:52:35 +0100 Subject: [PATCH 013/130] cirrus-vga: Convert to realize Signed-off-by: Markus Armbruster Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Gonglei --- hw/display/cirrus_vga.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) 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; From 042a24db0a6051313220e161bf1a19c545540d08 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Mon, 19 Jan 2015 15:52:36 +0100 Subject: [PATCH 014/130] qxl: Convert to realize Signed-off-by: Markus Armbruster Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Gonglei --- hw/display/qxl.c | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/hw/display/qxl.c b/hw/display/qxl.c index 61df477264..208346d274 100644 --- a/hw/display/qxl.c +++ b/hw/display/qxl.c @@ -1916,7 +1916,7 @@ static void qxl_init_ramsize(PCIQXLDevice *qxl) qxl->vram_size = msb_mask(qxl->vram_size * 2 - 1); } -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; @@ -1948,9 +1948,9 @@ static int qxl_init_common(PCIQXLDevice *qxl) io_size = msb_mask(QXL_IO_RANGE_SIZE * 2 - 1); 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); @@ -2014,9 +2014,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); @@ -2025,15 +2025,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); @@ -2050,18 +2048,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); @@ -2074,7 +2072,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) @@ -2287,7 +2285,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; @@ -2312,7 +2310,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; From d313858dfc2b0b5e6c126f1920863fe43dc9d5b6 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Mon, 19 Jan 2015 15:52:37 +0100 Subject: [PATCH 015/130] pci-assign: Convert to realize Signed-off-by: Markus Armbruster Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Gonglei --- hw/i386/kvm/pci-assign.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) 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; From 25f8dd96598042a88fdd970d5531584b589b10e4 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Tue, 20 Jan 2015 10:04:07 +0100 Subject: [PATCH 016/130] qdev: Don't exit when running into bad -global -global lets you set a nice booby-trap for yourself: $ qemu-system-x86_64 -nodefaults -S -display none -usb -monitor stdio -global usb-mouse.usb_version=l QEMU 2.1.94 monitor - type 'help' for more information (qemu) device_add usb-mouse Parameter 'usb_version' expects an int64 value or range $ echo $? 1 Not nice. Until commit 3196270 we even abort()ed. The same error triggers if you manage to screw up a machine type's compat_props. To demonstrate, change HW_COMPAT_2_1's entry to .driver = "usb-mouse",\ .property = "usb_version",\ .value = "1", \ Then run $ qemu-system-x86_64 -usb -M pc-i440fx-2.1 -device usb-mouse upstream-qemu: -device usb-mouse: Parameter 'usb_version' expects an int64 value or range $ echo $? 1 One of our creatively cruel error messages. Since this is actually a coding error, we *should* abort() here. Replace the error by an assertion failure in this case. But turn the fatal error into a mere warning when the faulty GlobalProperty comes from the user. Looks like this: $ qemu-system-x86_64 -nodefaults -S -display none -usb -monitor stdio -global usb-mouse.usb_version=l QEMU 2.1.94 monitor - type 'help' for more information (qemu) device_add usb-mouse Warning: global usb-mouse.usb_version=l ignored (Parameter 'usb_version' expects an int64 value or range) (qemu) This is consistent with how we handle similarly unusable -global in qdev_prop_check_globals(). You could argue that the error should make device_add fail. Would be harder, because we're running within TypeInfo's instance_post_init() method device_post_init(), which can't fail. Signed-off-by: Markus Armbruster Acked-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Eric Blake Reviewed-by: Eduardo Habkost --- hw/core/qdev-properties.c | 21 +++++++++------------ hw/core/qdev.c | 8 +------- include/hw/qdev-properties.h | 4 +--- 3 files changed, 11 insertions(+), 22 deletions(-) diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c index 2e47f70eb4..5a4e4d5ec8 100644 --- a/hw/core/qdev-properties.c +++ b/hw/core/qdev-properties.c @@ -990,8 +990,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; @@ -1004,25 +1004,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 44c6b93727..5f63c5bbde 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -1186,13 +1186,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/include/hw/qdev-properties.h b/include/hw/qdev-properties.h index 070006c715..57ee363b89 100644 --- a/include/hw/qdev-properties.h +++ b/include/hw/qdev-properties.h @@ -180,9 +180,7 @@ void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value); void qdev_prop_register_global(GlobalProperty *prop); void qdev_prop_register_global_list(GlobalProperty *props); int qdev_prop_check_globals(void); -void qdev_prop_set_globals(DeviceState *dev, Error **errp); -void qdev_prop_set_globals_for_type(DeviceState *dev, const char *typename, - Error **errp); +void qdev_prop_set_globals(DeviceState *dev); void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev, Property *prop, const char *value); From d9c5c5b8a81433921a75390a9951436424b5c4c5 Mon Sep 17 00:00:00 2001 From: Tang Chen Date: Wed, 28 Jan 2015 15:45:37 +0800 Subject: [PATCH 017/130] acpi, pc: Add hotunplug request cb for pc machine. Memory and CPU hot unplug are both asynchronous procedures. They both need unplug request callback to initiate unplug operation. Add unplug handler to pc machine that will be used by following CPU and memory unplug patches. Reviewed-by: Igor Mammedov Signed-off-by: Tang Chen Signed-off-by: Zhu Guihua Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/pc.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 05008cbf6a..ba0b04e963 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1679,6 +1679,13 @@ 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 HotplugHandler *pc_get_hotpug_handler(MachineState *machine, DeviceState *dev) { @@ -1808,6 +1815,7 @@ 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; } static const TypeInfo pc_machine_info = { From 469b8ad283d748648960e2260a4a3c415b1b3956 Mon Sep 17 00:00:00 2001 From: Tang Chen Date: Wed, 28 Jan 2015 15:45:38 +0800 Subject: [PATCH 018/130] acpi, ich9: Add hotunplug request cb for ich9. Memory and CPU hot unplug are both asynchronous procedures. They both need unplug request cb when the unplug operation happens. This patch adds hotunplug request cb for ich9, and memory and CPU hot unplug will share it. Reviewed-by: Igor Mammedov Signed-off-by: Tang Chen Signed-off-by: Zhu Guihua Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/ich9.c | 7 +++++++ hw/isa/lpc_ich9.c | 5 +++-- include/hw/acpi/ich9.h | 2 ++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c index 884dab3d45..5fe1eb86ff 100644 --- a/hw/acpi/ich9.c +++ b/hw/acpi/ich9.c @@ -397,6 +397,13 @@ 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_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list) { ICH9LPCState *s = ICH9_LPC_DEVICE(adev); diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c index 231de74414..9b43cf46de 100644 --- a/hw/isa/lpc_ich9.c +++ b/hw/isa/lpc_ich9.c @@ -610,8 +610,9 @@ 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 bool ich9_rst_cnt_needed(void *opaque) diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h index 12d7a7af5f..eaef0c34f5 100644 --- a/include/hw/acpi/ich9.h +++ b/include/hw/acpi/ich9.h @@ -63,6 +63,8 @@ extern const VMStateDescription vmstate_ich9_pm; void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm, Error **errp); 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); void ich9_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list); #endif /* HW_ACPI_ICH9_H */ From 232391c19ec69e6781667c53cb3c3bc57932bb95 Mon Sep 17 00:00:00 2001 From: Tang Chen Date: Wed, 28 Jan 2015 15:45:39 +0800 Subject: [PATCH 019/130] acpi, pc: Add unplug cb for pc machine. Memory and CPU hot unplug are both asynchronous procedures. When the unplug operation happens, unplug request cb is called first. And when guest OS finished handling unplug, unplug cb will be called to do the real removal of device. This patch adds hotunplug cb to pc machine, which memory and CPU hot unplug will use it. Reviewed-by: Igor Mammedov Signed-off-by: Tang Chen Signed-off-by: Zhu Guihua Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/pc.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index ba0b04e963..60d4e02847 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1686,6 +1686,13 @@ static void pc_machine_device_unplug_request_cb(HotplugHandler *hotplug_dev, " 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) { @@ -1816,6 +1823,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) 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 = { From 91a734a6fa0fcd03a7ffc32a7b45a3c2735d82be Mon Sep 17 00:00:00 2001 From: Tang Chen Date: Wed, 28 Jan 2015 15:45:40 +0800 Subject: [PATCH 020/130] acpi, ich9: Add unplug cb for ich9. Memory and CPU hot unplug are both asynchronous procedures. When the unplug operation happens, unplug request cb is called first. And when guest OS finished handling unplug, unplug cb will be called to do the real removal of device. This patch adds hotunplug cb to ich9, which memory and CPU hot unplug will use it. Reviewed-by: Igor Mammedov Signed-off-by: Tang Chen Signed-off-by: Zhu Guihua Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/ich9.c | 7 +++++++ hw/isa/lpc_ich9.c | 9 +++++++++ include/hw/acpi/ich9.h | 2 ++ 3 files changed, 18 insertions(+) diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c index 5fe1eb86ff..5352e197cb 100644 --- a/hw/acpi/ich9.c +++ b/hw/acpi/ich9.c @@ -404,6 +404,13 @@ void ich9_pm_device_unplug_request_cb(ICH9LPCPMRegs *pm, DeviceState *dev, " 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/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c index 9b43cf46de..dba758595f 100644 --- a/hw/isa/lpc_ich9.c +++ b/hw/isa/lpc_ich9.c @@ -615,6 +615,14 @@ static void ich9_device_unplug_request_cb(HotplugHandler *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) { ICH9LPCState *lpc = opaque; @@ -678,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/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h index eaef0c34f5..c2d3dba0c7 100644 --- a/include/hw/acpi/ich9.h +++ b/include/hw/acpi/ich9.h @@ -65,6 +65,8 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm, Error **errp); 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); +void ich9_pm_device_unplug_cb(ICH9LPCPMRegs *pm, DeviceState *dev, + Error **errp); void ich9_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list); #endif /* HW_ACPI_ICH9_H */ From c0e57a6022fdb2b00e7946bbfa2ad1f9515527cd Mon Sep 17 00:00:00 2001 From: Tang Chen Date: Wed, 28 Jan 2015 15:45:41 +0800 Subject: [PATCH 021/130] acpi, piix4: Add unplug cb for piix4. Memory and CPU hot unplug are both asynchronous procedures. When the unplug operation happens, unplug request cb is called first. And when guest OS finished handling unplug, unplug cb will be called to do the real removal of device. This patch adds hotunplug cb to piix4, which memory and CPU hot unplug will use it. Reviewed-by: Igor Mammedov Signed-off-by: Tang Chen Signed-off-by: Zhu Guihua Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/piix4.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c index 017510b791..766f1b8552 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; @@ -609,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; } From 214224adb4ebc9f3d211b867f588413e13f05bb3 Mon Sep 17 00:00:00 2001 From: Peter Krempa Date: Thu, 29 Jan 2015 14:48:40 +0100 Subject: [PATCH 022/130] vl.c: Fix error messages when parsing maxmem parameters Produce more human readable error messages and fix few spelling mistakes. Also remove a redundant check for the max memory size. Signed-off-by: Peter Krempa Acked-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Signed-off-by: Peter Krempa --- vl.c | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/vl.c b/vl.c index e1ffd0a96a..908128c2ba 100644 --- a/vl.c +++ b/vl.c @@ -2693,29 +2693,27 @@ static void set_memory_options(uint64_t *ram_slots, ram_addr_t *maxram_size) uint64_t slots; sz = qemu_opt_get_size(opts, "maxmem", 0); - if (sz < ram_size) { - error_report("invalid -m option value: maxmem " - "(0x%" PRIx64 ") <= initial memory (0x" - RAM_ADDR_FMT ")", sz, ram_size); - exit(EXIT_FAILURE); - } - slots = qemu_opt_get_number(opts, "slots", 0); - if ((sz > ram_size) && !slots) { - error_report("invalid -m option value: maxmem " - "(0x%" PRIx64 ") more than initial memory (0x" - RAM_ADDR_FMT ") but no hotplug slots where " - "specified", sz, ram_size); + if (sz < ram_size) { + error_report("invalid value of -m option maxmem: " + "maximum memory size (0x%" PRIx64 ") must be at least " + "the initial memory size (0x" RAM_ADDR_FMT ")", + sz, ram_size); + exit(EXIT_FAILURE); + } else if (sz > ram_size) { + if (!slots) { + error_report("invalid value of -m option: maxmem was " + "specified, but no hotplug slots were specified"); + exit(EXIT_FAILURE); + } + } else if (slots) { + error_report("invalid value of -m option maxmem: " + "memory slots were specified but maximum memory size " + "(0x%" PRIx64 ") is equal to the initial memory size " + "(0x" RAM_ADDR_FMT ")", sz, ram_size); exit(EXIT_FAILURE); } - if ((sz <= ram_size) && slots) { - error_report("invalid -m option value: %" - PRIu64 " hotplug slots where specified but " - "maxmem (0x%" PRIx64 ") <= initial memory (0x" - RAM_ADDR_FMT ")", slots, sz, ram_size); - exit(EXIT_FAILURE); - } *maxram_size = sz; *ram_slots = slots; } else if ((!maxmem_str && slots_str) || From f2c385220598523c8b9fefbfff1a6754cfd8232a Mon Sep 17 00:00:00 2001 From: Peter Krempa Date: Thu, 29 Jan 2015 14:48:41 +0100 Subject: [PATCH 023/130] pc: memory: Validate alignment of maxram_size to page size If the maxram_size is not aligned and dimm devices were added on the command line qemu would terminate with a rather unhelpful message: ERROR:hw/mem/pc-dimm.c:150:pc_dimm_get_free_addr: assertion failed: (QEMU_ALIGN_UP(address_space_size, align) == address_space_size) In case no dimm device was originally added on the commandline qemu exits on the assertion failure. Signed-off-by: Peter Krempa Reviewed-by: Eric Blake Acked-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Signed-off-by: Peter Krempa Reviewed-by: Eric Blake --- hw/i386/pc.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 60d4e02847..ae3ef0af4f 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1245,6 +1245,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); From d70414a5788c3d51f8ce4d2f437e669e6b99dc59 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 9 Feb 2015 13:59:53 +0000 Subject: [PATCH 024/130] acpi: update RSDP on guest access RSDT offset can change across reboots and that makes immutable RSDP, which is build at startup, point to incorrect place in ACPI table blob. That results in BIOS corrupting tables and guest OS failing to find ACPI tables. We really should have put it in a ROM region, but we can't change that for old machine types, let's just set the callback and update it explicitly. Signed-off-by: Michael S. Tsirkin Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Marcel Apfelbaum --- hw/i386/acpi-build.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 5737ed061c..d9b99bcf13 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -1367,6 +1367,7 @@ struct AcpiBuildState { /* Is table patched? */ uint8_t patched; PcGuestInfo *guest_info; + void *rsdp; } AcpiBuildState; static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg) @@ -1501,8 +1502,6 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables) /* 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 @@ -1574,6 +1573,7 @@ static void acpi_build_update(void *build_opaque, uint32_t offset) memcpy(qemu_get_ram_ptr(build_state->table_ram), tables.table_data->data, build_state->table_size); + memcpy(build_state->rsdp, tables.rsdp->data, acpi_data_len(tables.rsdp)); cpu_physical_memory_set_dirty_range_nocode(build_state->table_ram, build_state->table_size); @@ -1646,11 +1646,14 @@ void acpi_setup(PcGuestInfo *guest_info) 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. + * Though RSDP is small, its contents isn't immutable, so + * update it along with the rest of tables on guest access. */ - fw_cfg_add_file(guest_info->fw_cfg, ACPI_BUILD_RSDP_FILE, - tables.rsdp->data, acpi_data_len(tables.rsdp)); + fw_cfg_add_file_callback(guest_info->fw_cfg, ACPI_BUILD_RSDP_FILE, + acpi_build_update, build_state, + tables.rsdp->data, acpi_data_len(tables.rsdp)); + + build_state->rsdp = tables.rsdp->data; qemu_register_reset(acpi_build_reset, build_state); acpi_build_reset(build_state); From 6e00619b1eb2050bf2c75d52edfe7b4566704922 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Mon, 9 Feb 2015 13:59:54 +0000 Subject: [PATCH 025/130] pc: acpi-build: update linker on guest access Linker table is build only once, so if later during tables rebuild sizes of other ACPI tables change pointers will be patched incorrectly due to wrong offsets in linker. Resulting in guest not being able to find ACPI tables. Fix it by updating 'linker' table with the rest of tables when firmware reads it. Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Marcel Apfelbaum --- hw/i386/acpi-build.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index d9b99bcf13..47368c92f2 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -1368,6 +1368,8 @@ struct AcpiBuildState { uint8_t patched; PcGuestInfo *guest_info; void *rsdp; + ram_addr_t linker_ram; + uint32_t linker_size; } AcpiBuildState; static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg) @@ -1574,6 +1576,8 @@ static void acpi_build_update(void *build_opaque, uint32_t offset) memcpy(qemu_get_ram_ptr(build_state->table_ram), tables.table_data->data, build_state->table_size); memcpy(build_state->rsdp, tables.rsdp->data, acpi_data_len(tables.rsdp)); + memcpy(qemu_get_ram_ptr(build_state->linker_ram), tables.linker->data, + build_state->linker_size); cpu_physical_memory_set_dirty_range_nocode(build_state->table_ram, build_state->table_size); @@ -1640,7 +1644,9 @@ void acpi_setup(PcGuestInfo *guest_info) 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); + build_state->linker_size = acpi_data_len(tables.linker); fw_cfg_add_file(guest_info->fw_cfg, ACPI_BUILD_TPMLOG_FILE, tables.tcpalog->data, acpi_data_len(tables.tcpalog)); From 358774d780ee8f91429323f44bef1f53afa448bf Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Mon, 9 Feb 2015 13:59:55 +0000 Subject: [PATCH 026/130] pc: acpi-build: migrate RSDP table Makes sure that RSDP stays the same /i.e. matches ACPI tables blob in source/ if guest is migrated during RSDP reading or has been already shadowed by firmware. Fix applies only to new machine types starting from 2.3, so it won't break migration for old machine types. Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Marcel Apfelbaum --- hw/i386/acpi-build.c | 24 +++++++++++++++--------- hw/i386/pc_piix.c | 3 +++ hw/i386/pc_q35.c | 3 +++ include/hw/i386/pc.h | 1 + 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 47368c92f2..693f44730a 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -1651,15 +1651,21 @@ void acpi_setup(PcGuestInfo *guest_info) fw_cfg_add_file(guest_info->fw_cfg, ACPI_BUILD_TPMLOG_FILE, tables.tcpalog->data, acpi_data_len(tables.tcpalog)); - /* - * Though RSDP is small, its contents isn't immutable, so - * update it along with the rest of tables on guest access. - */ - fw_cfg_add_file_callback(guest_info->fw_cfg, ACPI_BUILD_RSDP_FILE, - acpi_build_update, build_state, - tables.rsdp->data, acpi_data_len(tables.rsdp)); - - build_state->rsdp = tables.rsdp->data; + if (guest_info->has_immutable_rsdp) { + /* + * Keep for compatibility with old machine types. + * Though RSDP is small, its contents isn't immutable, so + * update it along with the rest of tables on guest access. + */ + fw_cfg_add_file_callback(guest_info->fw_cfg, ACPI_BUILD_RSDP_FILE, + acpi_build_update, build_state, + tables.rsdp->data, acpi_data_len(tables.rsdp)); + build_state->rsdp = tables.rsdp->data; + } else { + build_state->rsdp = qemu_get_ram_ptr( + 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/pc_piix.c b/hw/i386/pc_piix.c index de75cf0e87..76744cf4f5 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 has_immutable_rsdp; 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->has_immutable_rsdp = has_immutable_rsdp; 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) { + has_immutable_rsdp = true; 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..6151f2ffbe 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 has_immutable_rsdp; 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->has_immutable_rsdp = has_immutable_rsdp; /* 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) { + has_immutable_rsdp = true; 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/include/hw/i386/pc.h b/include/hw/i386/pc.h index dddd255389..85cc86a74f 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -104,6 +104,7 @@ struct PcGuestInfo { int legacy_acpi_table_size; bool has_acpi_build; bool has_reserved_memory; + bool has_immutable_rsdp; }; /* parallel.c */ From 129ddaf31be583fb7c97812e07e028661005ce42 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Tue, 17 Feb 2015 10:15:30 +0100 Subject: [PATCH 027/130] exec: round up size on MR resize Block size must fundamentally be a multiple of target page size. Aligning automatically removes need to worry about the alignment from callers. Note: the only caller of qemu_ram_resize (acpi) already happens to have size padded to a power of 2, but we would like to drop the padding in ACPI core, and don't want to expose target page size knowledge to ACPI. Signed-off-by: Michael S. Tsirkin Acked-by: Paolo Bonzini --- exec.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/exec.c b/exec.c index c85321a38b..6a5adab502 100644 --- a/exec.c +++ b/exec.c @@ -1347,6 +1347,8 @@ int qemu_ram_resize(ram_addr_t base, ram_addr_t newsize, Error **errp) assert(block); + newsize = TARGET_PAGE_ALIGN(newsize); + if (block->used_length == newsize) { return 0; } From 42d859001d180ea788aa2d34a7be021ac8c447f2 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Sun, 15 Feb 2015 17:12:11 +0100 Subject: [PATCH 028/130] acpi-build: fix ACPI RAM management This fixes multiple issues around ACPI RAM management: RSDP and linker RAM aren't currently marked dirty on update, so they won't be migrated correctly. Let's handle all tables in the same way: set correct size (assert if too big), update, mark RAM dirty. This also drops assert checking that table size didn't change: table size is fundamentally dynamic and depends on hw configuration, just set the correct size and use that (memory core asserts if size is too large). This also means we can drop tracking table size, memory core does this for us now. Signed-off-by: Michael S. Tsirkin --- hw/i386/acpi-build.c | 43 +++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 693f44730a..031f88d5ca 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -1363,13 +1363,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; - uint32_t linker_size; } AcpiBuildState; static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg) @@ -1552,6 +1551,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; @@ -1567,21 +1577,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); + acpi_ram_update(build_state->table_ram, tables.table_data); - /* 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); - - memcpy(qemu_get_ram_ptr(build_state->table_ram), tables.table_data->data, - build_state->table_size); - memcpy(build_state->rsdp, tables.rsdp->data, acpi_data_len(tables.rsdp)); - memcpy(qemu_get_ram_ptr(build_state->linker_ram), tables.linker->data, - build_state->linker_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); } @@ -1642,11 +1646,9 @@ 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); build_state->linker_ram = acpi_add_rom_blob(build_state, tables.linker, "etc/table-loader", 0); - build_state->linker_size = acpi_data_len(tables.linker); fw_cfg_add_file(guest_info->fw_cfg, ACPI_BUILD_TPMLOG_FILE, tables.tcpalog->data, acpi_data_len(tables.tcpalog)); @@ -1661,10 +1663,11 @@ void acpi_setup(PcGuestInfo *guest_info) acpi_build_update, build_state, tables.rsdp->data, acpi_data_len(tables.rsdp)); build_state->rsdp = tables.rsdp->data; + build_state->rsdp_ram = (ram_addr_t)-1; } else { - build_state->rsdp = qemu_get_ram_ptr( - acpi_add_rom_blob(build_state, tables.rsdp, ACPI_BUILD_RSDP_FILE, 0) - ); + 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); From 384fb32ea7984ed6e5fdcea0bbc3d5b01238806b Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Tue, 17 Feb 2015 10:04:40 +0100 Subject: [PATCH 029/130] acpi: has_immutable_rsdp->!rsdp_in_ram As comment in acpi-build.c notes, RSDP is not really immutable. So it's really a question of whether it's in RAM, name the variable accordingly. Signed-off-by: Michael S. Tsirkin Reviewed-by: Igor Mammedov --- hw/i386/acpi-build.c | 2 +- hw/i386/pc_piix.c | 6 +++--- hw/i386/pc_q35.c | 6 +++--- include/hw/i386/pc.h | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 031f88d5ca..409229f602 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -1653,7 +1653,7 @@ void acpi_setup(PcGuestInfo *guest_info) fw_cfg_add_file(guest_info->fw_cfg, ACPI_BUILD_TPMLOG_FILE, tables.tcpalog->data, acpi_data_len(tables.tcpalog)); - if (guest_info->has_immutable_rsdp) { + if (!guest_info->rsdp_in_ram) { /* * Keep for compatibility with old machine types. * Though RSDP is small, its contents isn't immutable, so diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 76744cf4f5..8eab4ba94d 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -60,7 +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 has_immutable_rsdp; +static bool rsdp_in_ram = true; static int legacy_acpi_table_size; static bool smbios_defaults = true; static bool smbios_legacy_mode; @@ -169,7 +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->has_immutable_rsdp = has_immutable_rsdp; + guest_info->rsdp_in_ram = rsdp_in_ram; if (smbios_defaults) { MachineClass *mc = MACHINE_GET_CLASS(machine); @@ -312,7 +312,7 @@ static void pc_init_pci(MachineState *machine) static void pc_compat_2_2(MachineState *machine) { - has_immutable_rsdp = true; + 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 6151f2ffbe..c0f21fe725 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -50,7 +50,7 @@ #define MAX_SATA_PORTS 6 static bool has_acpi_build = true; -static bool has_immutable_rsdp; +static bool rsdp_in_ram = true; static bool smbios_defaults = true; static bool smbios_legacy_mode; static bool smbios_uuid_encoded = true; @@ -155,7 +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->has_immutable_rsdp = has_immutable_rsdp; + 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). @@ -291,7 +291,7 @@ static void pc_q35_init(MachineState *machine) static void pc_compat_2_2(MachineState *machine) { - has_immutable_rsdp = true; + 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/include/hw/i386/pc.h b/include/hw/i386/pc.h index 85cc86a74f..3b999668e2 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -104,7 +104,7 @@ struct PcGuestInfo { int legacy_acpi_table_size; bool has_acpi_build; bool has_reserved_memory; - bool has_immutable_rsdp; + bool rsdp_in_ram; }; /* parallel.c */ From afaa2e4bc4e17360307cb86fbb1d5d350ae22961 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Tue, 17 Feb 2015 10:40:30 +0100 Subject: [PATCH 030/130] acpi-build: simplify rsdp management for legacy For legacy machine types, rsdp is not in RAM, so we need a copy of rsdp for fw cfg. We previously used g_array_free with false parameter, but this seems to confuse people. This also wastes a bit of memory as the buffer is unused for new machine types. Let's just use plain g_memdup, and free original memory together with the array. TODO: rationalize tcpalog memory management, and get rid of the mfre parameter. Signed-off-by: Michael S. Tsirkin Reviewed-by: Igor Mammedov --- hw/i386/acpi-build.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 409229f602..9b11c927b5 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -1354,7 +1354,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); } @@ -1657,12 +1657,14 @@ void acpi_setup(PcGuestInfo *guest_info) /* * Keep for compatibility with old machine types. * Though RSDP is small, its contents isn't immutable, so - * update it along with the rest of tables on guest access. + * 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, - tables.rsdp->data, acpi_data_len(tables.rsdp)); - build_state->rsdp = tables.rsdp->data; + build_state->rsdp, rsdp_size); build_state->rsdp_ram = (ram_addr_t)-1; } else { build_state->rsdp = NULL; From 1ff0b555d3c6ba291adf0c4c76e222acfeb52f1d Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 16 Feb 2015 22:35:25 +0100 Subject: [PATCH 031/130] scripts/update-linux-headers.sh: pull virtio hdrs It doesn't make sense to copy values manually: the only issue with getting headers from linux seems to be dealing with linux/types, we can easily fix that automatically while importing. Signed-off-by: Michael S. Tsirkin Reviewed-by: Thomas Huth --- scripts/update-linux-headers.sh | 41 +++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh index c8e026d37e..8926dec57f 100755 --- a/scripts/update-linux-headers.sh +++ b/scripts/update-linux-headers.sh @@ -28,6 +28,36 @@ if [ -z "$output" ]; then output="$PWD" fi +cp_virtio() { + from=$1 + to=$2 + virtio=$(find "$from" -name '*virtio*h') + if [ "$virtio" ]; then + rm -rf "$to" + mkdir -p "$to" + for f in $virtio; do + if + grep '#include' "$f" | grep -v -e 'linux/virtio' \ + -e 'linux/types' \ + -e 'linux/if_ether' \ + > /dev/null + then + echo "Unexpected #include in input file $f". + exit 2 + fi + + header=$(basename "$f"); + sed -e 's/__u\([0-9][0-9]*\)/uint\1_t/g' \ + -e 's/__le\([0-9][0-9]*\)/uint\1_t/g' \ + -e 's/__be\([0-9][0-9]*\)/uint\1_t/g' \ + -e 's/]*\)>/"standard-headers\/linux\/\1"/' \ + -e 's/__bitwise__//' \ + -e 's/__attribute__((packed))/QEMU_PACKED/' \ + "$f" > "$to/$header"; + done + fi +} + # This will pick up non-directories too (eg "Kconfig") but we will # ignore them in the next loop. ARCHLIST=$(cd "$linux/arch" && echo *) @@ -76,4 +106,15 @@ else cp "$linux/COPYING" "$output/linux-headers" fi + +cp_virtio "$tmpdir/include/linux/" "$output/include/standard-headers/linux" + +cat <$output/include/standard-headers/linux/types.h +#include +#include "qemu/compiler.h" +EOF +cat <$output/include/standard-headers/linux/if_ether.h +#define ETH_ALEN 6 +EOF + rm -rf "$tmpdir" From 9fbe302b2a4c349c1a8fa93a3f79f08e7007d80c Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 16 Feb 2015 22:35:31 +0100 Subject: [PATCH 032/130] include: import virtio headers from linux 4.0 Add files imported from linux-next (what will become linux 4.0) using scripts/update-linux-headers.sh Signed-off-by: Michael S. Tsirkin --- include/standard-headers/linux/if_ether.h | 1 + include/standard-headers/linux/types.h | 2 + include/standard-headers/linux/virtio_9p.h | 44 ++++ .../standard-headers/linux/virtio_balloon.h | 59 +++++ include/standard-headers/linux/virtio_blk.h | 143 +++++++++++ .../standard-headers/linux/virtio_config.h | 64 +++++ .../standard-headers/linux/virtio_console.h | 78 ++++++ include/standard-headers/linux/virtio_ids.h | 43 ++++ include/standard-headers/linux/virtio_net.h | 233 ++++++++++++++++++ include/standard-headers/linux/virtio_pci.h | 193 +++++++++++++++ include/standard-headers/linux/virtio_ring.h | 171 +++++++++++++ include/standard-headers/linux/virtio_rng.h | 8 + include/standard-headers/linux/virtio_scsi.h | 164 ++++++++++++ include/standard-headers/linux/virtio_types.h | 46 ++++ 14 files changed, 1249 insertions(+) create mode 100644 include/standard-headers/linux/if_ether.h create mode 100644 include/standard-headers/linux/types.h create mode 100644 include/standard-headers/linux/virtio_9p.h create mode 100644 include/standard-headers/linux/virtio_balloon.h create mode 100644 include/standard-headers/linux/virtio_blk.h create mode 100644 include/standard-headers/linux/virtio_config.h create mode 100644 include/standard-headers/linux/virtio_console.h create mode 100644 include/standard-headers/linux/virtio_ids.h create mode 100644 include/standard-headers/linux/virtio_net.h create mode 100644 include/standard-headers/linux/virtio_pci.h create mode 100644 include/standard-headers/linux/virtio_ring.h create mode 100644 include/standard-headers/linux/virtio_rng.h create mode 100644 include/standard-headers/linux/virtio_scsi.h create mode 100644 include/standard-headers/linux/virtio_types.h diff --git a/include/standard-headers/linux/if_ether.h b/include/standard-headers/linux/if_ether.h new file mode 100644 index 0000000000..91cf735fb5 --- /dev/null +++ b/include/standard-headers/linux/if_ether.h @@ -0,0 +1 @@ +#define ETH_ALEN 6 diff --git a/include/standard-headers/linux/types.h b/include/standard-headers/linux/types.h new file mode 100644 index 0000000000..7d42ac6f3c --- /dev/null +++ b/include/standard-headers/linux/types.h @@ -0,0 +1,2 @@ +#include +#include "qemu/compiler.h" diff --git a/include/standard-headers/linux/virtio_9p.h b/include/standard-headers/linux/virtio_9p.h new file mode 100644 index 0000000000..e68f71dbe6 --- /dev/null +++ b/include/standard-headers/linux/virtio_9p.h @@ -0,0 +1,44 @@ +#ifndef _LINUX_VIRTIO_9P_H +#define _LINUX_VIRTIO_9P_H +/* This header is BSD licensed so anyone can use the definitions to implement + * compatible drivers/servers. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of IBM nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. */ +#include "standard-headers/linux/types.h" +#include "standard-headers/linux/virtio_ids.h" +#include "standard-headers/linux/virtio_config.h" + +/* The feature bitmap for virtio 9P */ + +/* The mount point is specified in a config variable */ +#define VIRTIO_9P_MOUNT_TAG 0 + +struct virtio_9p_config { + /* length of the tag name */ + uint16_t tag_len; + /* non-NULL terminated tag name */ + uint8_t tag[0]; +} QEMU_PACKED; + +#endif /* _LINUX_VIRTIO_9P_H */ diff --git a/include/standard-headers/linux/virtio_balloon.h b/include/standard-headers/linux/virtio_balloon.h new file mode 100644 index 0000000000..799376d414 --- /dev/null +++ b/include/standard-headers/linux/virtio_balloon.h @@ -0,0 +1,59 @@ +#ifndef _LINUX_VIRTIO_BALLOON_H +#define _LINUX_VIRTIO_BALLOON_H +/* This header is BSD licensed so anyone can use the definitions to implement + * compatible drivers/servers. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of IBM nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. */ +#include "standard-headers/linux/virtio_ids.h" +#include "standard-headers/linux/virtio_config.h" + +/* The feature bitmap for virtio balloon */ +#define VIRTIO_BALLOON_F_MUST_TELL_HOST 0 /* Tell before reclaiming pages */ +#define VIRTIO_BALLOON_F_STATS_VQ 1 /* Memory Stats virtqueue */ +#define VIRTIO_BALLOON_F_DEFLATE_ON_OOM 2 /* Deflate balloon on OOM */ + +/* Size of a PFN in the balloon interface. */ +#define VIRTIO_BALLOON_PFN_SHIFT 12 + +struct virtio_balloon_config { + /* Number of pages host wants Guest to give up. */ + uint32_t num_pages; + /* Number of pages we've actually got in balloon. */ + uint32_t actual; +}; + +#define VIRTIO_BALLOON_S_SWAP_IN 0 /* Amount of memory swapped in */ +#define VIRTIO_BALLOON_S_SWAP_OUT 1 /* Amount of memory swapped out */ +#define VIRTIO_BALLOON_S_MAJFLT 2 /* Number of major faults */ +#define VIRTIO_BALLOON_S_MINFLT 3 /* Number of minor faults */ +#define VIRTIO_BALLOON_S_MEMFREE 4 /* Total amount of free memory */ +#define VIRTIO_BALLOON_S_MEMTOT 5 /* Total amount of memory */ +#define VIRTIO_BALLOON_S_NR 6 + +struct virtio_balloon_stat { + uint16_t tag; + uint64_t val; +} QEMU_PACKED; + +#endif /* _LINUX_VIRTIO_BALLOON_H */ diff --git a/include/standard-headers/linux/virtio_blk.h b/include/standard-headers/linux/virtio_blk.h new file mode 100644 index 0000000000..12016b47f3 --- /dev/null +++ b/include/standard-headers/linux/virtio_blk.h @@ -0,0 +1,143 @@ +#ifndef _LINUX_VIRTIO_BLK_H +#define _LINUX_VIRTIO_BLK_H +/* This header is BSD licensed so anyone can use the definitions to implement + * compatible drivers/servers. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of IBM nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. */ +#include "standard-headers/linux/types.h" +#include "standard-headers/linux/virtio_ids.h" +#include "standard-headers/linux/virtio_config.h" +#include "standard-headers/linux/virtio_types.h" + +/* Feature bits */ +#define VIRTIO_BLK_F_SIZE_MAX 1 /* Indicates maximum segment size */ +#define VIRTIO_BLK_F_SEG_MAX 2 /* Indicates maximum # of segments */ +#define VIRTIO_BLK_F_GEOMETRY 4 /* Legacy geometry available */ +#define VIRTIO_BLK_F_RO 5 /* Disk is read-only */ +#define VIRTIO_BLK_F_BLK_SIZE 6 /* Block size of disk is available*/ +#define VIRTIO_BLK_F_TOPOLOGY 10 /* Topology information is available */ +#define VIRTIO_BLK_F_MQ 12 /* support more than one vq */ + +/* Legacy feature bits */ +#ifndef VIRTIO_BLK_NO_LEGACY +#define VIRTIO_BLK_F_BARRIER 0 /* Does host support barriers? */ +#define VIRTIO_BLK_F_SCSI 7 /* Supports scsi command passthru */ +#define VIRTIO_BLK_F_WCE 9 /* Writeback mode enabled after reset */ +#define VIRTIO_BLK_F_CONFIG_WCE 11 /* Writeback mode available in config */ +/* Old (deprecated) name for VIRTIO_BLK_F_WCE. */ +#define VIRTIO_BLK_F_FLUSH VIRTIO_BLK_F_WCE +#endif /* !VIRTIO_BLK_NO_LEGACY */ + +#define VIRTIO_BLK_ID_BYTES 20 /* ID string length */ + +struct virtio_blk_config { + /* The capacity (in 512-byte sectors). */ + uint64_t capacity; + /* The maximum segment size (if VIRTIO_BLK_F_SIZE_MAX) */ + uint32_t size_max; + /* The maximum number of segments (if VIRTIO_BLK_F_SEG_MAX) */ + uint32_t seg_max; + /* geometry the device (if VIRTIO_BLK_F_GEOMETRY) */ + struct virtio_blk_geometry { + uint16_t cylinders; + uint8_t heads; + uint8_t sectors; + } geometry; + + /* block size of device (if VIRTIO_BLK_F_BLK_SIZE) */ + uint32_t blk_size; + + /* the next 4 entries are guarded by VIRTIO_BLK_F_TOPOLOGY */ + /* exponent for physical block per logical block. */ + uint8_t physical_block_exp; + /* alignment offset in logical blocks. */ + uint8_t alignment_offset; + /* minimum I/O size without performance penalty in logical blocks. */ + uint16_t min_io_size; + /* optimal sustained I/O size in logical blocks. */ + uint32_t opt_io_size; + + /* writeback mode (if VIRTIO_BLK_F_CONFIG_WCE) */ + uint8_t wce; + uint8_t unused; + + /* number of vqs, only available when VIRTIO_BLK_F_MQ is set */ + uint16_t num_queues; +} QEMU_PACKED; + +/* + * Command types + * + * Usage is a bit tricky as some bits are used as flags and some are not. + * + * Rules: + * VIRTIO_BLK_T_OUT may be combined with VIRTIO_BLK_T_SCSI_CMD or + * VIRTIO_BLK_T_BARRIER. VIRTIO_BLK_T_FLUSH is a command of its own + * and may not be combined with any of the other flags. + */ + +/* These two define direction. */ +#define VIRTIO_BLK_T_IN 0 +#define VIRTIO_BLK_T_OUT 1 + +#ifndef VIRTIO_BLK_NO_LEGACY +/* This bit says it's a scsi command, not an actual read or write. */ +#define VIRTIO_BLK_T_SCSI_CMD 2 +#endif /* VIRTIO_BLK_NO_LEGACY */ + +/* Cache flush command */ +#define VIRTIO_BLK_T_FLUSH 4 + +/* Get device ID command */ +#define VIRTIO_BLK_T_GET_ID 8 + +#ifndef VIRTIO_BLK_NO_LEGACY +/* Barrier before this op. */ +#define VIRTIO_BLK_T_BARRIER 0x80000000 +#endif /* !VIRTIO_BLK_NO_LEGACY */ + +/* This is the first element of the read scatter-gather list. */ +struct virtio_blk_outhdr { + /* VIRTIO_BLK_T* */ + __virtio32 type; + /* io priority. */ + __virtio32 ioprio; + /* Sector (ie. 512 byte offset) */ + __virtio64 sector; +}; + +#ifndef VIRTIO_BLK_NO_LEGACY +struct virtio_scsi_inhdr { + __virtio32 errors; + __virtio32 data_len; + __virtio32 sense_len; + __virtio32 residual; +}; +#endif /* !VIRTIO_BLK_NO_LEGACY */ + +/* And this is the final byte of the write scatter-gather list. */ +#define VIRTIO_BLK_S_OK 0 +#define VIRTIO_BLK_S_IOERR 1 +#define VIRTIO_BLK_S_UNSUPP 2 +#endif /* _LINUX_VIRTIO_BLK_H */ diff --git a/include/standard-headers/linux/virtio_config.h b/include/standard-headers/linux/virtio_config.h new file mode 100644 index 0000000000..bcc445b3d8 --- /dev/null +++ b/include/standard-headers/linux/virtio_config.h @@ -0,0 +1,64 @@ +#ifndef _LINUX_VIRTIO_CONFIG_H +#define _LINUX_VIRTIO_CONFIG_H +/* This header, excluding the #ifdef __KERNEL__ part, is BSD licensed so + * anyone can use the definitions to implement compatible drivers/servers. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of IBM nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. */ + +/* Virtio devices use a standardized configuration space to define their + * features and pass configuration information, but each implementation can + * store and access that space differently. */ +#include "standard-headers/linux/types.h" + +/* Status byte for guest to report progress, and synchronize features. */ +/* We have seen device and processed generic fields (VIRTIO_CONFIG_F_VIRTIO) */ +#define VIRTIO_CONFIG_S_ACKNOWLEDGE 1 +/* We have found a driver for the device. */ +#define VIRTIO_CONFIG_S_DRIVER 2 +/* Driver has used its parts of the config, and is happy */ +#define VIRTIO_CONFIG_S_DRIVER_OK 4 +/* Driver has finished configuring features */ +#define VIRTIO_CONFIG_S_FEATURES_OK 8 +/* We've given up on this device. */ +#define VIRTIO_CONFIG_S_FAILED 0x80 + +/* Some virtio feature bits (currently bits 28 through 32) are reserved for the + * transport being used (eg. virtio_ring), the rest are per-device feature + * bits. */ +#define VIRTIO_TRANSPORT_F_START 28 +#define VIRTIO_TRANSPORT_F_END 33 + +#ifndef VIRTIO_CONFIG_NO_LEGACY +/* Do we get callbacks when the ring is completely used, even if we've + * suppressed them? */ +#define VIRTIO_F_NOTIFY_ON_EMPTY 24 + +/* Can the device handle any descriptor layout? */ +#define VIRTIO_F_ANY_LAYOUT 27 +#endif /* VIRTIO_CONFIG_NO_LEGACY */ + +/* v1.0 compliant. */ +#define VIRTIO_F_VERSION_1 32 + +#endif /* _LINUX_VIRTIO_CONFIG_H */ diff --git a/include/standard-headers/linux/virtio_console.h b/include/standard-headers/linux/virtio_console.h new file mode 100644 index 0000000000..0dedc9e6f5 --- /dev/null +++ b/include/standard-headers/linux/virtio_console.h @@ -0,0 +1,78 @@ +/* + * This header, excluding the #ifdef __KERNEL__ part, is BSD licensed so + * anyone can use the definitions to implement compatible drivers/servers: + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of IBM nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Copyright (C) Red Hat, Inc., 2009, 2010, 2011 + * Copyright (C) Amit Shah , 2009, 2010, 2011 + */ +#ifndef _LINUX_VIRTIO_CONSOLE_H +#define _LINUX_VIRTIO_CONSOLE_H +#include "standard-headers/linux/types.h" +#include "standard-headers/linux/virtio_types.h" +#include "standard-headers/linux/virtio_ids.h" +#include "standard-headers/linux/virtio_config.h" + +/* Feature bits */ +#define VIRTIO_CONSOLE_F_SIZE 0 /* Does host provide console size? */ +#define VIRTIO_CONSOLE_F_MULTIPORT 1 /* Does host provide multiple ports? */ +#define VIRTIO_CONSOLE_F_EMERG_WRITE 2 /* Does host support emergency write? */ + +#define VIRTIO_CONSOLE_BAD_ID (~(uint32_t)0) + +struct virtio_console_config { + /* colums of the screens */ + uint16_t cols; + /* rows of the screens */ + uint16_t rows; + /* max. number of ports this device can hold */ + uint32_t max_nr_ports; + /* emergency write register */ + uint32_t emerg_wr; +} QEMU_PACKED; + +/* + * A message that's passed between the Host and the Guest for a + * particular port. + */ +struct virtio_console_control { + __virtio32 id; /* Port number */ + __virtio16 event; /* The kind of control event (see below) */ + __virtio16 value; /* Extra information for the key */ +}; + +/* Some events for control messages */ +#define VIRTIO_CONSOLE_DEVICE_READY 0 +#define VIRTIO_CONSOLE_PORT_ADD 1 +#define VIRTIO_CONSOLE_PORT_REMOVE 2 +#define VIRTIO_CONSOLE_PORT_READY 3 +#define VIRTIO_CONSOLE_CONSOLE_PORT 4 +#define VIRTIO_CONSOLE_RESIZE 5 +#define VIRTIO_CONSOLE_PORT_OPEN 6 +#define VIRTIO_CONSOLE_PORT_NAME 7 + + +#endif /* _LINUX_VIRTIO_CONSOLE_H */ diff --git a/include/standard-headers/linux/virtio_ids.h b/include/standard-headers/linux/virtio_ids.h new file mode 100644 index 0000000000..284fc3a05f --- /dev/null +++ b/include/standard-headers/linux/virtio_ids.h @@ -0,0 +1,43 @@ +#ifndef _LINUX_VIRTIO_IDS_H +#define _LINUX_VIRTIO_IDS_H +/* + * Virtio IDs + * + * This header is BSD licensed so anyone can use the definitions to implement + * compatible drivers/servers. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of IBM nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. */ + +#define VIRTIO_ID_NET 1 /* virtio net */ +#define VIRTIO_ID_BLOCK 2 /* virtio block */ +#define VIRTIO_ID_CONSOLE 3 /* virtio console */ +#define VIRTIO_ID_RNG 4 /* virtio rng */ +#define VIRTIO_ID_BALLOON 5 /* virtio balloon */ +#define VIRTIO_ID_RPMSG 7 /* virtio remote processor messaging */ +#define VIRTIO_ID_SCSI 8 /* virtio scsi */ +#define VIRTIO_ID_9P 9 /* 9p virtio console */ +#define VIRTIO_ID_RPROC_SERIAL 11 /* virtio remoteproc serial link */ +#define VIRTIO_ID_CAIF 12 /* Virtio caif */ + +#endif /* _LINUX_VIRTIO_IDS_H */ diff --git a/include/standard-headers/linux/virtio_net.h b/include/standard-headers/linux/virtio_net.h new file mode 100644 index 0000000000..95faf67b48 --- /dev/null +++ b/include/standard-headers/linux/virtio_net.h @@ -0,0 +1,233 @@ +#ifndef _LINUX_VIRTIO_NET_H +#define _LINUX_VIRTIO_NET_H +/* This header is BSD licensed so anyone can use the definitions to implement + * compatible drivers/servers. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of IBM nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. */ +#include "standard-headers/linux/types.h" +#include "standard-headers/linux/virtio_ids.h" +#include "standard-headers/linux/virtio_config.h" +#include "standard-headers/linux/virtio_types.h" +#include "standard-headers/linux/if_ether.h" + +/* The feature bitmap for virtio net */ +#define VIRTIO_NET_F_CSUM 0 /* Host handles pkts w/ partial csum */ +#define VIRTIO_NET_F_GUEST_CSUM 1 /* Guest handles pkts w/ partial csum */ +#define VIRTIO_NET_F_MAC 5 /* Host has given MAC address. */ +#define VIRTIO_NET_F_GUEST_TSO4 7 /* Guest can handle TSOv4 in. */ +#define VIRTIO_NET_F_GUEST_TSO6 8 /* Guest can handle TSOv6 in. */ +#define VIRTIO_NET_F_GUEST_ECN 9 /* Guest can handle TSO[6] w/ ECN in. */ +#define VIRTIO_NET_F_GUEST_UFO 10 /* Guest can handle UFO in. */ +#define VIRTIO_NET_F_HOST_TSO4 11 /* Host can handle TSOv4 in. */ +#define VIRTIO_NET_F_HOST_TSO6 12 /* Host can handle TSOv6 in. */ +#define VIRTIO_NET_F_HOST_ECN 13 /* Host can handle TSO[6] w/ ECN in. */ +#define VIRTIO_NET_F_HOST_UFO 14 /* Host can handle UFO in. */ +#define VIRTIO_NET_F_MRG_RXBUF 15 /* Host can merge receive buffers. */ +#define VIRTIO_NET_F_STATUS 16 /* virtio_net_config.status available */ +#define VIRTIO_NET_F_CTRL_VQ 17 /* Control channel available */ +#define VIRTIO_NET_F_CTRL_RX 18 /* Control channel RX mode support */ +#define VIRTIO_NET_F_CTRL_VLAN 19 /* Control channel VLAN filtering */ +#define VIRTIO_NET_F_CTRL_RX_EXTRA 20 /* Extra RX mode control support */ +#define VIRTIO_NET_F_GUEST_ANNOUNCE 21 /* Guest can announce device on the + * network */ +#define VIRTIO_NET_F_MQ 22 /* Device supports Receive Flow + * Steering */ +#define VIRTIO_NET_F_CTRL_MAC_ADDR 23 /* Set MAC address */ + +#ifndef VIRTIO_NET_NO_LEGACY +#define VIRTIO_NET_F_GSO 6 /* Host handles pkts w/ any GSO type */ +#endif /* VIRTIO_NET_NO_LEGACY */ + +#define VIRTIO_NET_S_LINK_UP 1 /* Link is up */ +#define VIRTIO_NET_S_ANNOUNCE 2 /* Announcement is needed */ + +struct virtio_net_config { + /* The config defining mac address (if VIRTIO_NET_F_MAC) */ + uint8_t mac[ETH_ALEN]; + /* See VIRTIO_NET_F_STATUS and VIRTIO_NET_S_* above */ + uint16_t status; + /* Maximum number of each of transmit and receive queues; + * see VIRTIO_NET_F_MQ and VIRTIO_NET_CTRL_MQ. + * Legal values are between 1 and 0x8000 + */ + uint16_t max_virtqueue_pairs; +} QEMU_PACKED; + +#ifndef VIRTIO_NET_NO_LEGACY +/* This header comes first in the scatter-gather list. + * For legacy virtio, if VIRTIO_F_ANY_LAYOUT is not negotiated, it must + * be the first element of the scatter-gather list. If you don't + * specify GSO or CSUM features, you can simply ignore the header. */ +struct virtio_net_hdr { +#define VIRTIO_NET_HDR_F_NEEDS_CSUM 1 // Use csum_start, csum_offset +#define VIRTIO_NET_HDR_F_DATA_VALID 2 // Csum is valid + uint8_t flags; +#define VIRTIO_NET_HDR_GSO_NONE 0 // Not a GSO frame +#define VIRTIO_NET_HDR_GSO_TCPV4 1 // GSO frame, IPv4 TCP (TSO) +#define VIRTIO_NET_HDR_GSO_UDP 3 // GSO frame, IPv4 UDP (UFO) +#define VIRTIO_NET_HDR_GSO_TCPV6 4 // GSO frame, IPv6 TCP +#define VIRTIO_NET_HDR_GSO_ECN 0x80 // TCP has ECN set + uint8_t gso_type; + __virtio16 hdr_len; /* Ethernet + IP + tcp/udp hdrs */ + __virtio16 gso_size; /* Bytes to append to hdr_len per frame */ + __virtio16 csum_start; /* Position to start checksumming from */ + __virtio16 csum_offset; /* Offset after that to place checksum */ +}; + +/* This is the version of the header to use when the MRG_RXBUF + * feature has been negotiated. */ +struct virtio_net_hdr_mrg_rxbuf { + struct virtio_net_hdr hdr; + __virtio16 num_buffers; /* Number of merged rx buffers */ +}; +#else /* ... VIRTIO_NET_NO_LEGACY */ +/* + * This header comes first in the scatter-gather list. If you don't + * specify GSO or CSUM features, you can simply ignore the header. + * + * This is bitwise-equivalent to the legacy struct virtio_net_hdr_mrg_rxbuf. + */ +struct virtio_net_hdr_v1 { +#define VIRTIO_NET_HDR_F_NEEDS_CSUM 1 /* Use csum_start, csum_offset */ +#define VIRTIO_NET_HDR_F_DATA_VALID 2 /* Csum is valid */ + uint8_t flags; +#define VIRTIO_NET_HDR_GSO_NONE 0 /* Not a GSO frame */ +#define VIRTIO_NET_HDR_GSO_TCPV4 1 /* GSO frame, IPv4 TCP (TSO) */ +#define VIRTIO_NET_HDR_GSO_UDP 3 /* GSO frame, IPv4 UDP (UFO) */ +#define VIRTIO_NET_HDR_GSO_TCPV6 4 /* GSO frame, IPv6 TCP */ +#define VIRTIO_NET_HDR_GSO_ECN 0x80 /* TCP has ECN set */ + uint8_t gso_type; + __virtio16 hdr_len; /* Ethernet + IP + tcp/udp hdrs */ + __virtio16 gso_size; /* Bytes to append to hdr_len per frame */ + __virtio16 csum_start; /* Position to start checksumming from */ + __virtio16 csum_offset; /* Offset after that to place checksum */ + __virtio16 num_buffers; /* Number of merged rx buffers */ +}; +#endif /* ...VIRTIO_NET_NO_LEGACY */ + +/* + * Control virtqueue data structures + * + * The control virtqueue expects a header in the first sg entry + * and an ack/status response in the last entry. Data for the + * command goes in between. + */ +struct virtio_net_ctrl_hdr { + uint8_t class; + uint8_t cmd; +} QEMU_PACKED; + +typedef uint8_t virtio_net_ctrl_ack; + +#define VIRTIO_NET_OK 0 +#define VIRTIO_NET_ERR 1 + +/* + * Control the RX mode, ie. promisucous, allmulti, etc... + * All commands require an "out" sg entry containing a 1 byte + * state value, zero = disable, non-zero = enable. Commands + * 0 and 1 are supported with the VIRTIO_NET_F_CTRL_RX feature. + * Commands 2-5 are added with VIRTIO_NET_F_CTRL_RX_EXTRA. + */ +#define VIRTIO_NET_CTRL_RX 0 + #define VIRTIO_NET_CTRL_RX_PROMISC 0 + #define VIRTIO_NET_CTRL_RX_ALLMULTI 1 + #define VIRTIO_NET_CTRL_RX_ALLUNI 2 + #define VIRTIO_NET_CTRL_RX_NOMULTI 3 + #define VIRTIO_NET_CTRL_RX_NOUNI 4 + #define VIRTIO_NET_CTRL_RX_NOBCAST 5 + +/* + * Control the MAC + * + * The MAC filter table is managed by the hypervisor, the guest should + * assume the size is infinite. Filtering should be considered + * non-perfect, ie. based on hypervisor resources, the guest may + * received packets from sources not specified in the filter list. + * + * In addition to the class/cmd header, the TABLE_SET command requires + * two out scatterlists. Each contains a 4 byte count of entries followed + * by a concatenated byte stream of the ETH_ALEN MAC addresses. The + * first sg list contains unicast addresses, the second is for multicast. + * This functionality is present if the VIRTIO_NET_F_CTRL_RX feature + * is available. + * + * The ADDR_SET command requests one out scatterlist, it contains a + * 6 bytes MAC address. This functionality is present if the + * VIRTIO_NET_F_CTRL_MAC_ADDR feature is available. + */ +struct virtio_net_ctrl_mac { + __virtio32 entries; + uint8_t macs[][ETH_ALEN]; +} QEMU_PACKED; + +#define VIRTIO_NET_CTRL_MAC 1 + #define VIRTIO_NET_CTRL_MAC_TABLE_SET 0 + #define VIRTIO_NET_CTRL_MAC_ADDR_SET 1 + +/* + * Control VLAN filtering + * + * The VLAN filter table is controlled via a simple ADD/DEL interface. + * VLAN IDs not added may be filterd by the hypervisor. Del is the + * opposite of add. Both commands expect an out entry containing a 2 + * byte VLAN ID. VLAN filterting is available with the + * VIRTIO_NET_F_CTRL_VLAN feature bit. + */ +#define VIRTIO_NET_CTRL_VLAN 2 + #define VIRTIO_NET_CTRL_VLAN_ADD 0 + #define VIRTIO_NET_CTRL_VLAN_DEL 1 + +/* + * Control link announce acknowledgement + * + * The command VIRTIO_NET_CTRL_ANNOUNCE_ACK is used to indicate that + * driver has recevied the notification; device would clear the + * VIRTIO_NET_S_ANNOUNCE bit in the status field after it receives + * this command. + */ +#define VIRTIO_NET_CTRL_ANNOUNCE 3 + #define VIRTIO_NET_CTRL_ANNOUNCE_ACK 0 + +/* + * Control Receive Flow Steering + * + * The command VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET + * enables Receive Flow Steering, specifying the number of the transmit and + * receive queues that will be used. After the command is consumed and acked by + * the device, the device will not steer new packets on receive virtqueues + * other than specified nor read from transmit virtqueues other than specified. + * Accordingly, driver should not transmit new packets on virtqueues other than + * specified. + */ +struct virtio_net_ctrl_mq { + __virtio16 virtqueue_pairs; +}; + +#define VIRTIO_NET_CTRL_MQ 4 + #define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET 0 + #define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN 1 + #define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX 0x8000 + +#endif /* _LINUX_VIRTIO_NET_H */ diff --git a/include/standard-headers/linux/virtio_pci.h b/include/standard-headers/linux/virtio_pci.h new file mode 100644 index 0000000000..ecdc133d59 --- /dev/null +++ b/include/standard-headers/linux/virtio_pci.h @@ -0,0 +1,193 @@ +/* + * Virtio PCI driver + * + * This module allows virtio devices to be used over a virtual PCI device. + * This can be used with QEMU based VMMs like KVM or Xen. + * + * Copyright IBM Corp. 2007 + * + * Authors: + * Anthony Liguori + * + * This header is BSD licensed so anyone can use the definitions to implement + * compatible drivers/servers. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of IBM nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _LINUX_VIRTIO_PCI_H +#define _LINUX_VIRTIO_PCI_H + +#include "standard-headers/linux/types.h" + +#ifndef VIRTIO_PCI_NO_LEGACY + +/* 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 + +/* The remaining space is defined by each driver as the per-driver + * configuration space */ +#define VIRTIO_PCI_CONFIG_OFF(msix_enabled) ((msix_enabled) ? 24 : 20) +/* Deprecated: please use VIRTIO_PCI_CONFIG_OFF instead */ +#define VIRTIO_PCI_CONFIG(dev) VIRTIO_PCI_CONFIG_OFF((dev)->msix_enabled) + +/* Virtio ABI version, this must match exactly */ +#define VIRTIO_PCI_ABI_VERSION 0 + +/* 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 + +/* The alignment to use between consumer and producer parts of vring. + * x86 pagesize again. */ +#define VIRTIO_PCI_VRING_ALIGN 4096 + +#endif /* VIRTIO_PCI_NO_LEGACY */ + +/* The bit of the ISR which indicates a device configuration change. */ +#define VIRTIO_PCI_ISR_CONFIG 0x2 +/* Vector value used to disable MSI for queue */ +#define VIRTIO_MSI_NO_VECTOR 0xffff + +#ifndef VIRTIO_PCI_NO_MODERN + +/* IDs for different capabilities. Must all exist. */ + +/* Common configuration */ +#define VIRTIO_PCI_CAP_COMMON_CFG 1 +/* Notifications */ +#define VIRTIO_PCI_CAP_NOTIFY_CFG 2 +/* ISR access */ +#define VIRTIO_PCI_CAP_ISR_CFG 3 +/* Device specific configuration */ +#define VIRTIO_PCI_CAP_DEVICE_CFG 4 +/* PCI configuration access */ +#define VIRTIO_PCI_CAP_PCI_CFG 5 + +/* This is the PCI capability header: */ +struct virtio_pci_cap { + uint8_t cap_vndr; /* Generic PCI field: PCI_CAP_ID_VNDR */ + uint8_t cap_next; /* Generic PCI field: next ptr. */ + uint8_t cap_len; /* Generic PCI field: capability length */ + uint8_t cfg_type; /* Identifies the structure. */ + uint8_t bar; /* Where to find it. */ + uint8_t padding[3]; /* Pad to full dword. */ + uint32_t offset; /* Offset within bar. */ + uint32_t length; /* Length of the structure, in bytes. */ +}; + +struct virtio_pci_notify_cap { + struct virtio_pci_cap cap; + uint32_t notify_off_multiplier; /* Multiplier for queue_notify_off. */ +}; + +/* Fields in VIRTIO_PCI_CAP_COMMON_CFG: */ +struct virtio_pci_common_cfg { + /* About the whole device. */ + uint32_t device_feature_select; /* read-write */ + uint32_t device_feature; /* read-only */ + uint32_t guest_feature_select; /* read-write */ + uint32_t guest_feature; /* read-write */ + uint16_t msix_config; /* read-write */ + uint16_t num_queues; /* read-only */ + uint8_t device_status; /* read-write */ + uint8_t config_generation; /* read-only */ + + /* About a specific virtqueue. */ + uint16_t queue_select; /* read-write */ + uint16_t queue_size; /* read-write, power of 2. */ + uint16_t queue_msix_vector; /* read-write */ + uint16_t queue_enable; /* read-write */ + uint16_t queue_notify_off; /* read-only */ + uint32_t queue_desc_lo; /* read-write */ + uint32_t queue_desc_hi; /* read-write */ + uint32_t queue_avail_lo; /* read-write */ + uint32_t queue_avail_hi; /* read-write */ + uint32_t queue_used_lo; /* read-write */ + uint32_t queue_used_hi; /* read-write */ +}; + +/* Macro versions of offsets for the Old Timers! */ +#define VIRTIO_PCI_CAP_VNDR 0 +#define VIRTIO_PCI_CAP_NEXT 1 +#define VIRTIO_PCI_CAP_LEN 2 +#define VIRTIO_PCI_CAP_CFG_TYPE 3 +#define VIRTIO_PCI_CAP_BAR 4 +#define VIRTIO_PCI_CAP_OFFSET 8 +#define VIRTIO_PCI_CAP_LENGTH 12 + +#define VIRTIO_PCI_NOTIFY_CAP_MULT 16 + +#define VIRTIO_PCI_COMMON_DFSELECT 0 +#define VIRTIO_PCI_COMMON_DF 4 +#define VIRTIO_PCI_COMMON_GFSELECT 8 +#define VIRTIO_PCI_COMMON_GF 12 +#define VIRTIO_PCI_COMMON_MSIX 16 +#define VIRTIO_PCI_COMMON_NUMQ 18 +#define VIRTIO_PCI_COMMON_STATUS 20 +#define VIRTIO_PCI_COMMON_CFGGENERATION 21 +#define VIRTIO_PCI_COMMON_Q_SELECT 22 +#define VIRTIO_PCI_COMMON_Q_SIZE 24 +#define VIRTIO_PCI_COMMON_Q_MSIX 26 +#define VIRTIO_PCI_COMMON_Q_ENABLE 28 +#define VIRTIO_PCI_COMMON_Q_NOFF 30 +#define VIRTIO_PCI_COMMON_Q_DESCLO 32 +#define VIRTIO_PCI_COMMON_Q_DESCHI 36 +#define VIRTIO_PCI_COMMON_Q_AVAILLO 40 +#define VIRTIO_PCI_COMMON_Q_AVAILHI 44 +#define VIRTIO_PCI_COMMON_Q_USEDLO 48 +#define VIRTIO_PCI_COMMON_Q_USEDHI 52 + +#endif /* VIRTIO_PCI_NO_MODERN */ + +#endif diff --git a/include/standard-headers/linux/virtio_ring.h b/include/standard-headers/linux/virtio_ring.h new file mode 100644 index 0000000000..2bd19a8d25 --- /dev/null +++ b/include/standard-headers/linux/virtio_ring.h @@ -0,0 +1,171 @@ +#ifndef _LINUX_VIRTIO_RING_H +#define _LINUX_VIRTIO_RING_H +/* An interface for efficient virtio implementation, currently for use by KVM + * and lguest, but hopefully others soon. Do NOT change this since it will + * break existing servers and clients. + * + * This header is BSD licensed so anyone can use the definitions to implement + * compatible drivers/servers. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of IBM nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Copyright Rusty Russell IBM Corporation 2007. */ +#include "standard-headers/linux/types.h" +#include "standard-headers/linux/virtio_types.h" + +/* This marks a buffer as continuing via the next field. */ +#define VRING_DESC_F_NEXT 1 +/* This marks a buffer as write-only (otherwise read-only). */ +#define VRING_DESC_F_WRITE 2 +/* This means the buffer contains a list of buffer descriptors. */ +#define VRING_DESC_F_INDIRECT 4 + +/* The Host uses this in used->flags to advise the Guest: don't kick me when + * you add a buffer. It's unreliable, so it's simply an optimization. Guest + * will still kick if it's out of buffers. */ +#define VRING_USED_F_NO_NOTIFY 1 +/* The Guest uses this in avail->flags to advise the Host: don't interrupt me + * when you consume a buffer. It's unreliable, so it's simply an + * optimization. */ +#define VRING_AVAIL_F_NO_INTERRUPT 1 + +/* We support indirect buffer descriptors */ +#define VIRTIO_RING_F_INDIRECT_DESC 28 + +/* The Guest publishes the used index for which it expects an interrupt + * at the end of the avail ring. Host should ignore the avail->flags field. */ +/* The Host publishes the avail index for which it expects a kick + * at the end of the used ring. Guest should ignore the used->flags field. */ +#define VIRTIO_RING_F_EVENT_IDX 29 + +/* Virtio ring descriptors: 16 bytes. These can chain together via "next". */ +struct vring_desc { + /* Address (guest-physical). */ + __virtio64 addr; + /* Length. */ + __virtio32 len; + /* The flags as indicated above. */ + __virtio16 flags; + /* We chain unused descriptors via this, too */ + __virtio16 next; +}; + +struct vring_avail { + __virtio16 flags; + __virtio16 idx; + __virtio16 ring[]; +}; + +/* u32 is used here for ids for padding reasons. */ +struct vring_used_elem { + /* Index of start of used descriptor chain. */ + __virtio32 id; + /* Total length of the descriptor chain which was used (written to) */ + __virtio32 len; +}; + +struct vring_used { + __virtio16 flags; + __virtio16 idx; + struct vring_used_elem ring[]; +}; + +struct vring { + unsigned int num; + + struct vring_desc *desc; + + struct vring_avail *avail; + + struct vring_used *used; +}; + +/* Alignment requirements for vring elements. + * When using pre-virtio 1.0 layout, these fall out naturally. + */ +#define VRING_AVAIL_ALIGN_SIZE 2 +#define VRING_USED_ALIGN_SIZE 4 +#define VRING_DESC_ALIGN_SIZE 16 + +/* The standard layout for the ring is a continuous chunk of memory which looks + * like this. We assume num is a power of 2. + * + * struct vring + * { + * // The actual descriptors (16 bytes each) + * struct vring_desc desc[num]; + * + * // A ring of available descriptor heads with free-running index. + * __virtio16 avail_flags; + * __virtio16 avail_idx; + * __virtio16 available[num]; + * __virtio16 used_event_idx; + * + * // Padding to the next align boundary. + * char pad[]; + * + * // A ring of used descriptor heads with free-running index. + * __virtio16 used_flags; + * __virtio16 used_idx; + * struct vring_used_elem used[num]; + * __virtio16 avail_event_idx; + * }; + */ +/* We publish the used event index at the end of the available ring, and vice + * versa. They are at the end for backwards compatibility. */ +#define vring_used_event(vr) ((vr)->avail->ring[(vr)->num]) +#define vring_avail_event(vr) (*(__virtio16 *)&(vr)->used->ring[(vr)->num]) + +static __inline__ void vring_init(struct vring *vr, unsigned int num, void *p, + unsigned long align) +{ + vr->num = num; + vr->desc = p; + vr->avail = p + num*sizeof(struct vring_desc); + vr->used = (void *)(((unsigned long)&vr->avail->ring[num] + sizeof(__virtio16) + + align-1) & ~(align - 1)); +} + +static __inline__ unsigned vring_size(unsigned int num, unsigned long align) +{ + return ((sizeof(struct vring_desc) * num + sizeof(__virtio16) * (3 + num) + + align - 1) & ~(align - 1)) + + sizeof(__virtio16) * 3 + sizeof(struct vring_used_elem) * num; +} + +/* The following is used with USED_EVENT_IDX and AVAIL_EVENT_IDX */ +/* 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_idx, uint16_t new_idx, 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_idx 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_idx - event_idx - 1) < (uint16_t)(new_idx - old); +} + +#endif /* _LINUX_VIRTIO_RING_H */ diff --git a/include/standard-headers/linux/virtio_rng.h b/include/standard-headers/linux/virtio_rng.h new file mode 100644 index 0000000000..60fc798bde --- /dev/null +++ b/include/standard-headers/linux/virtio_rng.h @@ -0,0 +1,8 @@ +#ifndef _LINUX_VIRTIO_RNG_H +#define _LINUX_VIRTIO_RNG_H +/* This header is BSD licensed so anyone can use the definitions to implement + * compatible drivers/servers. */ +#include "standard-headers/linux/virtio_ids.h" +#include "standard-headers/linux/virtio_config.h" + +#endif /* _LINUX_VIRTIO_RNG_H */ diff --git a/include/standard-headers/linux/virtio_scsi.h b/include/standard-headers/linux/virtio_scsi.h new file mode 100644 index 0000000000..78ba9d3635 --- /dev/null +++ b/include/standard-headers/linux/virtio_scsi.h @@ -0,0 +1,164 @@ +/* + * This header is BSD licensed so anyone can use the definitions to implement + * compatible drivers/servers. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _LINUX_VIRTIO_SCSI_H +#define _LINUX_VIRTIO_SCSI_H + +#include "standard-headers/linux/virtio_types.h" + +#define VIRTIO_SCSI_CDB_SIZE 32 +#define VIRTIO_SCSI_SENSE_SIZE 96 + +/* SCSI command request, followed by data-out */ +struct virtio_scsi_cmd_req { + uint8_t lun[8]; /* Logical Unit Number */ + __virtio64 tag; /* Command identifier */ + uint8_t task_attr; /* Task attribute */ + uint8_t prio; /* SAM command priority field */ + uint8_t crn; + uint8_t cdb[VIRTIO_SCSI_CDB_SIZE]; +} QEMU_PACKED; + +/* SCSI command request, followed by protection information */ +struct virtio_scsi_cmd_req_pi { + uint8_t lun[8]; /* Logical Unit Number */ + __virtio64 tag; /* Command identifier */ + uint8_t task_attr; /* Task attribute */ + uint8_t prio; /* SAM command priority field */ + uint8_t crn; + __virtio32 pi_bytesout; /* DataOUT PI Number of bytes */ + __virtio32 pi_bytesin; /* DataIN PI Number of bytes */ + uint8_t cdb[VIRTIO_SCSI_CDB_SIZE]; +} QEMU_PACKED; + +/* Response, followed by sense data and data-in */ +struct virtio_scsi_cmd_resp { + __virtio32 sense_len; /* Sense data length */ + __virtio32 resid; /* Residual bytes in data buffer */ + __virtio16 status_qualifier; /* Status qualifier */ + uint8_t status; /* Command completion status */ + uint8_t response; /* Response values */ + uint8_t sense[VIRTIO_SCSI_SENSE_SIZE]; +} QEMU_PACKED; + +/* Task Management Request */ +struct virtio_scsi_ctrl_tmf_req { + __virtio32 type; + __virtio32 subtype; + uint8_t lun[8]; + __virtio64 tag; +} QEMU_PACKED; + +struct virtio_scsi_ctrl_tmf_resp { + uint8_t response; +} QEMU_PACKED; + +/* Asynchronous notification query/subscription */ +struct virtio_scsi_ctrl_an_req { + __virtio32 type; + uint8_t lun[8]; + __virtio32 event_requested; +} QEMU_PACKED; + +struct virtio_scsi_ctrl_an_resp { + __virtio32 event_actual; + uint8_t response; +} QEMU_PACKED; + +struct virtio_scsi_event { + __virtio32 event; + uint8_t lun[8]; + __virtio32 reason; +} QEMU_PACKED; + +struct virtio_scsi_config { + uint32_t num_queues; + uint32_t seg_max; + uint32_t max_sectors; + uint32_t cmd_per_lun; + uint32_t event_info_size; + uint32_t sense_size; + uint32_t cdb_size; + uint16_t max_channel; + uint16_t max_target; + uint32_t max_lun; +} QEMU_PACKED; + +/* Feature Bits */ +#define VIRTIO_SCSI_F_INOUT 0 +#define VIRTIO_SCSI_F_HOTPLUG 1 +#define VIRTIO_SCSI_F_CHANGE 2 +#define VIRTIO_SCSI_F_T10_PI 3 + +/* Response codes */ +#define VIRTIO_SCSI_S_OK 0 +#define VIRTIO_SCSI_S_OVERRUN 1 +#define VIRTIO_SCSI_S_ABORTED 2 +#define VIRTIO_SCSI_S_BAD_TARGET 3 +#define VIRTIO_SCSI_S_RESET 4 +#define VIRTIO_SCSI_S_BUSY 5 +#define VIRTIO_SCSI_S_TRANSPORT_FAILURE 6 +#define VIRTIO_SCSI_S_TARGET_FAILURE 7 +#define VIRTIO_SCSI_S_NEXUS_FAILURE 8 +#define VIRTIO_SCSI_S_FAILURE 9 +#define VIRTIO_SCSI_S_FUNCTION_SUCCEEDED 10 +#define VIRTIO_SCSI_S_FUNCTION_REJECTED 11 +#define VIRTIO_SCSI_S_INCORRECT_LUN 12 + +/* Controlq type codes. */ +#define VIRTIO_SCSI_T_TMF 0 +#define VIRTIO_SCSI_T_AN_QUERY 1 +#define VIRTIO_SCSI_T_AN_SUBSCRIBE 2 + +/* Valid TMF subtypes. */ +#define VIRTIO_SCSI_T_TMF_ABORT_TASK 0 +#define VIRTIO_SCSI_T_TMF_ABORT_TASK_SET 1 +#define VIRTIO_SCSI_T_TMF_CLEAR_ACA 2 +#define VIRTIO_SCSI_T_TMF_CLEAR_TASK_SET 3 +#define VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET 4 +#define VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET 5 +#define VIRTIO_SCSI_T_TMF_QUERY_TASK 6 +#define VIRTIO_SCSI_T_TMF_QUERY_TASK_SET 7 + +/* Events. */ +#define VIRTIO_SCSI_T_EVENTS_MISSED 0x80000000 +#define VIRTIO_SCSI_T_NO_EVENT 0 +#define VIRTIO_SCSI_T_TRANSPORT_RESET 1 +#define VIRTIO_SCSI_T_ASYNC_NOTIFY 2 +#define VIRTIO_SCSI_T_PARAM_CHANGE 3 + +/* Reasons of transport reset event */ +#define VIRTIO_SCSI_EVT_RESET_HARD 0 +#define VIRTIO_SCSI_EVT_RESET_RESCAN 1 +#define VIRTIO_SCSI_EVT_RESET_REMOVED 2 + +#define VIRTIO_SCSI_S_SIMPLE 0 +#define VIRTIO_SCSI_S_ORDERED 1 +#define VIRTIO_SCSI_S_HEAD 2 +#define VIRTIO_SCSI_S_ACA 3 + + +#endif /* _LINUX_VIRTIO_SCSI_H */ diff --git a/include/standard-headers/linux/virtio_types.h b/include/standard-headers/linux/virtio_types.h new file mode 100644 index 0000000000..fd0d3511ff --- /dev/null +++ b/include/standard-headers/linux/virtio_types.h @@ -0,0 +1,46 @@ +#ifndef _LINUX_VIRTIO_TYPES_H +#define _LINUX_VIRTIO_TYPES_H +/* Type definitions for virtio implementations. + * + * This header is BSD licensed so anyone can use the definitions to implement + * compatible drivers/servers. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of IBM nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Copyright (C) 2014 Red Hat, Inc. + * Author: Michael S. Tsirkin + */ +#include "standard-headers/linux/types.h" + +/* + * __virtio{16,32,64} have the following meaning: + * - __u{16,32,64} for virtio devices in legacy mode, accessed in native endian + * - __le{16,32,64} for standard-compliant virtio devices + */ + +typedef uint16_t __virtio16; +typedef uint32_t __virtio32; +typedef uint64_t __virtio64; + +#endif /* _LINUX_VIRTIO_TYPES_H */ From 4fbe0f322d5413482efbf9c0d2329fdc32bea6d1 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 16 Feb 2015 22:35:40 +0100 Subject: [PATCH 033/130] virtio: use standard virtio_ring.h Switch to virtio_ring.h from standard headers. Signed-off-by: Michael S. Tsirkin --- hw/net/vhost_net.c | 2 +- include/hw/virtio/dataplane/vring-accessors.h | 2 +- include/hw/virtio/dataplane/vring.h | 2 +- include/hw/virtio/virtio_ring.h | 167 ------------------ 4 files changed, 3 insertions(+), 170 deletions(-) delete mode 100644 include/hw/virtio/virtio_ring.h diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c index 4e3a061622..2ea1ef1dd0 100644 --- a/hw/net/vhost_net.c +++ b/hw/net/vhost_net.c @@ -35,7 +35,7 @@ #include -#include "hw/virtio/virtio_ring.h" +#include "standard-headers/linux/virtio_ring.h" #include "hw/virtio/vhost.h" #include "hw/virtio/virtio-bus.h" diff --git a/include/hw/virtio/dataplane/vring-accessors.h b/include/hw/virtio/dataplane/vring-accessors.h index b508b87900..815c19b6ef 100644 --- a/include/hw/virtio/dataplane/vring-accessors.h +++ b/include/hw/virtio/dataplane/vring-accessors.h @@ -1,7 +1,7 @@ #ifndef VRING_ACCESSORS_H #define VRING_ACCESSORS_H -#include "hw/virtio/virtio_ring.h" +#include "standard-headers/linux/virtio_ring.h" #include "hw/virtio/virtio.h" #include "hw/virtio/virtio-access.h" diff --git a/include/hw/virtio/dataplane/vring.h b/include/hw/virtio/dataplane/vring.h index e42c0fc9cc..8d97db9e2d 100644 --- a/include/hw/virtio/dataplane/vring.h +++ b/include/hw/virtio/dataplane/vring.h @@ -18,7 +18,7 @@ #define VRING_H #include "qemu-common.h" -#include "hw/virtio/virtio_ring.h" +#include "standard-headers/linux/virtio_ring.h" #include "hw/virtio/virtio.h" typedef struct { diff --git a/include/hw/virtio/virtio_ring.h b/include/hw/virtio/virtio_ring.h deleted file mode 100644 index 0b42e6eae5..0000000000 --- a/include/hw/virtio/virtio_ring.h +++ /dev/null @@ -1,167 +0,0 @@ -#ifndef _LINUX_VIRTIO_RING_H -#define _LINUX_VIRTIO_RING_H -/* - * This file is copied from /usr/include/linux while converting __uNN types - * to uXX_t, __inline__ to inline, and tab to spaces. - * */ - -/* An interface for efficient virtio implementation, currently for use by KVM - * and lguest, but hopefully others soon. Do NOT change this since it will - * break existing servers and clients. - * - * This header is BSD licensed so anyone can use the definitions to implement - * compatible drivers/servers. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of IBM nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * Copyright Rusty Russell IBM Corporation 2007. */ - -/* This marks a buffer as continuing via the next field. */ -#define VRING_DESC_F_NEXT 1 -/* This marks a buffer as write-only (otherwise read-only). */ -#define VRING_DESC_F_WRITE 2 -/* This means the buffer contains a list of buffer descriptors. */ -#define VRING_DESC_F_INDIRECT 4 - -/* The Host uses this in used->flags to advise the Guest: don't kick me when - * you add a buffer. It's unreliable, so it's simply an optimization. Guest - * will still kick if it's out of buffers. */ -#define VRING_USED_F_NO_NOTIFY 1 -/* The Guest uses this in avail->flags to advise the Host: don't interrupt me - * when you consume a buffer. It's unreliable, so it's simply an - * optimization. */ -#define VRING_AVAIL_F_NO_INTERRUPT 1 - -/* We support indirect buffer descriptors */ -#define VIRTIO_RING_F_INDIRECT_DESC 28 - -/* The Guest publishes the used index for which it expects an interrupt - * at the end of the avail ring. Host should ignore the avail->flags field. */ -/* The Host publishes the avail index for which it expects a kick - * at the end of the used ring. Guest should ignore the used->flags field. */ -#define VIRTIO_RING_F_EVENT_IDX 29 - -/* Virtio ring descriptors: 16 bytes. These can chain together via "next". */ -struct vring_desc { - /* Address (guest-physical). */ - uint64_t addr; - /* Length. */ - uint32_t len; - /* The flags as indicated above. */ - uint16_t flags; - /* We chain unused descriptors via this, too */ - uint16_t next; -}; - -struct vring_avail { - uint16_t flags; - uint16_t idx; - uint16_t ring[]; -}; - -/* u32 is used here for ids for padding reasons. */ -struct vring_used_elem { - /* Index of start of used descriptor chain. */ - uint32_t id; - /* Total length of the descriptor chain which was used (written to) */ - uint32_t len; -}; - -struct vring_used { - uint16_t flags; - uint16_t idx; - struct vring_used_elem ring[]; -}; - -struct vring { - unsigned int num; - - struct vring_desc *desc; - - struct vring_avail *avail; - - struct vring_used *used; -}; - -/* The standard layout for the ring is a continuous chunk of memory which looks - * like this. We assume num is a power of 2. - * - * struct vring - * { - * // The actual descriptors (16 bytes each) - * struct vring_desc desc[num]; - * - * // A ring of available descriptor heads with free-running index. - * uint16_t avail_flags; - * uint16_t avail_idx; - * uint16_t available[num]; - * uint16_t used_event_idx; - * - * // Padding to the next align boundary. - * char pad[]; - * - * // A ring of used descriptor heads with free-running index. - * uint16_t used_flags; - * uint16_t used_idx; - * struct vring_used_elem used[num]; - * uint16_t avail_event_idx; - * }; - */ -/* We publish the used event index at the end of the available ring, and vice - * versa. They are at the end for backwards compatibility. */ -#define vring_used_event(vr) ((vr)->avail->ring[(vr)->num]) -#define vring_avail_event(vr) (*(uint16_t *)&(vr)->used->ring[(vr)->num]) - -static inline void vring_init(struct vring *vr, unsigned int num, void *p, - unsigned long align) -{ - vr->num = num; - vr->desc = p; - vr->avail = p + num*sizeof(struct vring_desc); - vr->used = (void *)(((uintptr_t)&vr->avail->ring[num] + sizeof(uint16_t) - + align - 1) & ~(align - 1)); -} - -static inline unsigned vring_size(unsigned int num, unsigned long align) -{ - return ((sizeof(struct vring_desc) * num + sizeof(uint16_t) * (3 + num) - + align - 1) & ~(align - 1)) - + sizeof(uint16_t) * 3 + sizeof(struct vring_used_elem) * num; -} - -/* The following is used with USED_EVENT_IDX and AVAIL_EVENT_IDX */ -/* 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_idx, uint16_t new_idx, 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_idx 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_idx - event_idx - 1) < (uint16_t)(new_idx - old); -} - -#endif /* _LINUX_VIRTIO_RING_H */ From e9600c6ca9e9ecc123105e1e3660314fe821a4cb Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 16 Feb 2015 22:35:46 +0100 Subject: [PATCH 034/130] virtio: use standard-headers Drop a bunch of code duplicated from virtio_config.h and virtio_ring.h. This makes us rename event index accessors which conflict, as reusing the ones from virtio_ring.h isn't trivial. Signed-off-by: Michael S. Tsirkin Reviewed-by: Thomas Huth --- hw/9pfs/virtio-9p.h | 1 + hw/virtio/virtio.c | 23 ++++-------------- include/hw/virtio/virtio.h | 48 ++------------------------------------ 3 files changed, 8 insertions(+), 64 deletions(-) diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h index 2c3603aed0..0776424d79 100644 --- a/hw/9pfs/virtio-9p.h +++ b/hw/9pfs/virtio-9p.h @@ -8,6 +8,7 @@ #include #include #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" diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index d735343ca8..f783f31b09 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) { @@ -218,7 +218,7 @@ 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)); + vring_set_avail_event(vq, vring_avail_idx(vq)); } else if (enable) { vring_used_flags_unset_bit(vq, VRING_USED_F_NO_NOTIFY); } else { @@ -469,7 +469,7 @@ int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem) 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); + 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; @@ -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/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index f24997d218..d1b416b7ce 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -19,56 +19,12 @@ #include "hw/qdev.h" #include "sysemu/sysemu.h" #include "qemu/event_notifier.h" -#ifdef CONFIG_VIRTFS -#include "hw/virtio/virtio-9p.h" -#endif +#include "standard-headers/linux/virtio_config.h" +#include "standard-headers/linux/virtio_ring.h" -/* from Linux's linux/virtio_config.h */ - -/* Status byte for guest to report progress, and synchronize features. */ -/* We have seen device and processed generic fields (VIRTIO_CONFIG_F_VIRTIO) */ -#define VIRTIO_CONFIG_S_ACKNOWLEDGE 1 -/* We have found a driver for the device. */ -#define VIRTIO_CONFIG_S_DRIVER 2 -/* Driver has used its parts of the config, and is happy */ -#define VIRTIO_CONFIG_S_DRIVER_OK 4 -/* We've given up on this device. */ -#define VIRTIO_CONFIG_S_FAILED 0x80 - -/* Some virtio feature bits (currently bits 28 through 31) are reserved for the - * transport being used (eg. virtio_ring), the rest are per-device feature bits. */ -#define VIRTIO_TRANSPORT_F_START 28 -#define VIRTIO_TRANSPORT_F_END 32 - -/* We notify when the ring is completely used, even if the guest is suppressing - * callbacks */ -#define VIRTIO_F_NOTIFY_ON_EMPTY 24 -/* Can the device handle any descriptor layout? */ -#define VIRTIO_F_ANY_LAYOUT 27 -/* We support indirect buffer descriptors */ -#define VIRTIO_RING_F_INDIRECT_DESC 28 -/* The Guest publishes the used index for which it expects an interrupt - * at the end of the avail ring. Host should ignore the avail->flags field. */ -/* The Host publishes the avail index for which it expects a kick - * at the end of the used ring. Guest should ignore the used->flags field. */ -#define VIRTIO_RING_F_EVENT_IDX 29 /* A guest should never accept this. It implies negotiation is broken. */ #define VIRTIO_F_BAD_FEATURE 30 -/* from Linux's linux/virtio_ring.h */ - -/* This marks a buffer as continuing via the next field. */ -#define VRING_DESC_F_NEXT 1 -/* This marks a buffer as write-only (otherwise read-only). */ -#define VRING_DESC_F_WRITE 2 -/* This means the buffer contains a list of buffer descriptors. */ -#define VRING_DESC_F_INDIRECT 4 - -/* This means don't notify other side when buffer added. */ -#define VRING_USED_F_NO_NOTIFY 1 -/* This means don't interrupt guest when buffer consumed. */ -#define VRING_AVAIL_F_NO_INTERRUPT 1 - struct VirtQueue; static inline hwaddr vring_align(hwaddr addr, From 73706bd1275bef2e7b3962d1be18a20cb8df7f66 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 16 Feb 2015 22:35:52 +0100 Subject: [PATCH 035/130] virtio-balloon: use standard headers Drop code duplicated from standard headers. Signed-off-by: Michael S. Tsirkin Reviewed-by: Thomas Huth Reviewed-by: Thomas Huth --- include/hw/virtio/virtio-balloon.h | 35 ++---------------------------- 1 file changed, 2 insertions(+), 33 deletions(-) diff --git a/include/hw/virtio/virtio-balloon.h b/include/hw/virtio/virtio-balloon.h index f863bfe27a..4ab8f541b0 100644 --- a/include/hw/virtio/virtio-balloon.h +++ b/include/hw/virtio/virtio-balloon.h @@ -15,6 +15,7 @@ #ifndef _QEMU_VIRTIO_BALLOON_H #define _QEMU_VIRTIO_BALLOON_H +#include "standard-headers/linux/virtio_balloon.h" #include "hw/virtio/virtio.h" #include "hw/pci/pci.h" @@ -22,39 +23,7 @@ #define VIRTIO_BALLOON(obj) \ OBJECT_CHECK(VirtIOBalloon, (obj), TYPE_VIRTIO_BALLOON) -/* from Linux's linux/virtio_balloon.h */ - -/* The ID for virtio_balloon */ -#define VIRTIO_ID_BALLOON 5 - -/* The feature bitmap for virtio balloon */ -#define VIRTIO_BALLOON_F_MUST_TELL_HOST 0 /* Tell before reclaiming pages */ -#define VIRTIO_BALLOON_F_STATS_VQ 1 /* Memory stats virtqueue */ - -/* Size of a PFN in the balloon interface. */ -#define VIRTIO_BALLOON_PFN_SHIFT 12 - -struct virtio_balloon_config -{ - /* Number of pages host wants Guest to give up. */ - uint32_t num_pages; - /* Number of pages we've actually got in balloon. */ - uint32_t actual; -}; - -/* Memory Statistics */ -#define VIRTIO_BALLOON_S_SWAP_IN 0 /* Amount of memory swapped in */ -#define VIRTIO_BALLOON_S_SWAP_OUT 1 /* Amount of memory swapped out */ -#define VIRTIO_BALLOON_S_MAJFLT 2 /* Number of major faults */ -#define VIRTIO_BALLOON_S_MINFLT 3 /* Number of minor faults */ -#define VIRTIO_BALLOON_S_MEMFREE 4 /* Total amount of free memory */ -#define VIRTIO_BALLOON_S_MEMTOT 5 /* Total amount of memory */ -#define VIRTIO_BALLOON_S_NR 6 - -typedef struct VirtIOBalloonStat { - uint16_t tag; - uint64_t val; -} QEMU_PACKED VirtIOBalloonStat; +typedef struct virtio_balloon_stat VirtIOBalloonStat; typedef struct VirtIOBalloon { VirtIODevice parent_obj; From 8744a6a8d500d3509de1f5e33b8cd7d22ec37cf1 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 16 Feb 2015 22:35:57 +0100 Subject: [PATCH 036/130] virtio-9p: use standard headers Drop code duplicated from standard headers. Signed-off-by: Michael S. Tsirkin Reviewed-by: Thomas Huth Reviewed-by: Thomas Huth --- hw/9pfs/virtio-9p.h | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h index 0776424d79..58dafa9e14 100644 --- a/hw/9pfs/virtio-9p.h +++ b/hw/9pfs/virtio-9p.h @@ -7,6 +7,7 @@ #include #include #include +#include "standard-headers/linux/virtio_9p.h" #include "hw/virtio/virtio.h" #include "hw/virtio/virtio-9p.h" #include "fsdev/file-op-9p.h" @@ -14,10 +15,6 @@ #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, @@ -145,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 @@ -278,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; From 907eb3e5b6fad79308977ec7f885ef549e64daca Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 16 Feb 2015 22:36:03 +0100 Subject: [PATCH 037/130] virtio-blk: switch to standard-headers Drop duplicated code. Minor codechanges were required as geometry is a sub-structure now. Signed-off-by: Michael S. Tsirkin Reviewed-by: Thomas Huth --- hw/block/virtio-blk.c | 8 ++-- include/hw/virtio/virtio-blk.h | 77 +--------------------------------- 2 files changed, 5 insertions(+), 80 deletions(-) diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c index cb71772f95..7cf31cb536 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); diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h index fc7d311a43..b3ffcd96b8 100644 --- a/include/hw/virtio/virtio-blk.h +++ b/include/hw/virtio/virtio-blk.h @@ -14,6 +14,7 @@ #ifndef _QEMU_VIRTIO_BLK_H #define _QEMU_VIRTIO_BLK_H +#include "standard-headers/linux/virtio_blk.h" #include "hw/virtio/virtio.h" #include "hw/block/block.h" #include "sysemu/iothread.h" @@ -23,88 +24,12 @@ #define VIRTIO_BLK(obj) \ OBJECT_CHECK(VirtIOBlock, (obj), TYPE_VIRTIO_BLK) -/* from Linux's linux/virtio_blk.h */ - -/* The ID for virtio_block */ -#define VIRTIO_ID_BLOCK 2 - -/* Feature bits */ -#define VIRTIO_BLK_F_BARRIER 0 /* Does host support barriers? */ -#define VIRTIO_BLK_F_SIZE_MAX 1 /* Indicates maximum segment size */ -#define VIRTIO_BLK_F_SEG_MAX 2 /* Indicates maximum # of segments */ -#define VIRTIO_BLK_F_GEOMETRY 4 /* Indicates support of legacy geometry */ -#define VIRTIO_BLK_F_RO 5 /* Disk is read-only */ -#define VIRTIO_BLK_F_BLK_SIZE 6 /* Block size of disk is available*/ -#define VIRTIO_BLK_F_SCSI 7 /* Supports scsi command passthru */ -/* #define VIRTIO_BLK_F_IDENTIFY 8 ATA IDENTIFY supported, DEPRECATED */ -#define VIRTIO_BLK_F_WCE 9 /* write cache enabled */ -#define VIRTIO_BLK_F_TOPOLOGY 10 /* Topology information is available */ -#define VIRTIO_BLK_F_CONFIG_WCE 11 /* write cache configurable */ - -#define VIRTIO_BLK_ID_BYTES 20 /* ID string length */ - -struct virtio_blk_config -{ - uint64_t capacity; - uint32_t size_max; - uint32_t seg_max; - uint16_t cylinders; - uint8_t heads; - uint8_t sectors; - uint32_t blk_size; - uint8_t physical_block_exp; - uint8_t alignment_offset; - uint16_t min_io_size; - uint32_t opt_io_size; - uint8_t wce; -} QEMU_PACKED; - -/* These two define direction. */ -#define VIRTIO_BLK_T_IN 0 -#define VIRTIO_BLK_T_OUT 1 - -/* This bit says it's a scsi command, not an actual read or write. */ -#define VIRTIO_BLK_T_SCSI_CMD 2 - -/* Flush the volatile write cache */ -#define VIRTIO_BLK_T_FLUSH 4 - -/* return the device ID string */ -#define VIRTIO_BLK_T_GET_ID 8 - -/* Barrier before this op. */ -#define VIRTIO_BLK_T_BARRIER 0x80000000 - -/* This is the first element of the read scatter-gather list. */ -struct virtio_blk_outhdr -{ - /* VIRTIO_BLK_T* */ - uint32_t type; - /* io priority. */ - uint32_t ioprio; - /* Sector (ie. 512 byte offset) */ - uint64_t sector; -}; - -#define VIRTIO_BLK_S_OK 0 -#define VIRTIO_BLK_S_IOERR 1 -#define VIRTIO_BLK_S_UNSUPP 2 - /* This is the last element of the write scatter-gather list */ struct virtio_blk_inhdr { unsigned char status; }; -/* SCSI pass-through header */ -struct virtio_scsi_inhdr -{ - uint32_t errors; - uint32_t data_len; - uint32_t sense_len; - uint32_t residual; -}; - struct VirtIOBlkConf { BlockConf conf; From b93a5ba3d1e840feef70a9cd367c6818ac63911e Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 16 Feb 2015 22:36:09 +0100 Subject: [PATCH 038/130] virtio-net,tap: use standard-headers Drop duplicated code. Signed-off-by: Michael S. Tsirkin Reviewed-by: Thomas Huth --- include/hw/virtio/virtio-net.h | 151 +-------------------------------- include/net/tap.h | 24 +----- 2 files changed, 2 insertions(+), 173 deletions(-) diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h index 6ceb5aa92e..4c2fe83b6b 100644 --- a/include/hw/virtio/virtio-net.h +++ b/include/hw/virtio/virtio-net.h @@ -14,49 +14,15 @@ #ifndef _QEMU_VIRTIO_NET_H #define _QEMU_VIRTIO_NET_H +#include "standard-headers/linux/virtio_net.h" #include "hw/virtio/virtio.h" -#include "hw/pci/pci.h" #define TYPE_VIRTIO_NET "virtio-net-device" #define VIRTIO_NET(obj) \ OBJECT_CHECK(VirtIONet, (obj), TYPE_VIRTIO_NET) -#define ETH_ALEN 6 - -/* from Linux's virtio_net.h */ - -/* The ID for virtio_net */ -#define VIRTIO_ID_NET 1 - -/* The feature bitmap for virtio net */ -#define VIRTIO_NET_F_CSUM 0 /* Host handles pkts w/ partial csum */ -#define VIRTIO_NET_F_GUEST_CSUM 1 /* Guest handles pkts w/ partial csum */ #define VIRTIO_NET_F_CTRL_GUEST_OFFLOADS 2 /* Control channel offload * configuration support */ -#define VIRTIO_NET_F_MAC 5 /* Host has given MAC address. */ -#define VIRTIO_NET_F_GSO 6 /* Host handles pkts w/ any GSO type */ -#define VIRTIO_NET_F_GUEST_TSO4 7 /* Guest can handle TSOv4 in. */ -#define VIRTIO_NET_F_GUEST_TSO6 8 /* Guest can handle TSOv6 in. */ -#define VIRTIO_NET_F_GUEST_ECN 9 /* Guest can handle TSO[6] w/ ECN in. */ -#define VIRTIO_NET_F_GUEST_UFO 10 /* Guest can handle UFO in. */ -#define VIRTIO_NET_F_HOST_TSO4 11 /* Host can handle TSOv4 in. */ -#define VIRTIO_NET_F_HOST_TSO6 12 /* Host can handle TSOv6 in. */ -#define VIRTIO_NET_F_HOST_ECN 13 /* Host can handle TSO[6] w/ ECN in. */ -#define VIRTIO_NET_F_HOST_UFO 14 /* Host can handle UFO in. */ -#define VIRTIO_NET_F_MRG_RXBUF 15 /* Host can merge receive buffers. */ -#define VIRTIO_NET_F_STATUS 16 /* virtio_net_config.status available */ -#define VIRTIO_NET_F_CTRL_VQ 17 /* Control channel available */ -#define VIRTIO_NET_F_CTRL_RX 18 /* Control channel RX mode support */ -#define VIRTIO_NET_F_CTRL_VLAN 19 /* Control channel VLAN filtering */ -#define VIRTIO_NET_F_CTRL_RX_EXTRA 20 /* Extra RX mode control support */ -#define VIRTIO_NET_F_GUEST_ANNOUNCE 21 /* Guest can announce itself */ -#define VIRTIO_NET_F_MQ 22 /* Device supports Receive Flow - * Steering */ - -#define VIRTIO_NET_F_CTRL_MAC_ADDR 23 /* Set MAC address */ - -#define VIRTIO_NET_S_LINK_UP 1 /* Link is up */ -#define VIRTIO_NET_S_ANNOUNCE 2 /* Announcement is needed */ #define TX_TIMER_INTERVAL 150000 /* 150 us */ @@ -77,72 +43,6 @@ typedef struct virtio_net_conf /* Maximum packet size we can receive from tap device: header + 64k */ #define VIRTIO_NET_MAX_BUFSIZE (sizeof(struct virtio_net_hdr) + (64 << 10)) -struct virtio_net_config -{ - /* The config defining mac address ($ETH_ALEN bytes) */ - uint8_t mac[ETH_ALEN]; - /* See VIRTIO_NET_F_STATUS and VIRTIO_NET_S_* above */ - uint16_t status; - /* Max virtqueue pairs supported by the device */ - uint16_t max_virtqueue_pairs; -} QEMU_PACKED; - -/* - * Control virtqueue data structures - * - * The control virtqueue expects a header in the first sg entry - * and an ack/status response in the last entry. Data for the - * command goes in between. - */ -struct virtio_net_ctrl_hdr { - uint8_t class; - uint8_t cmd; -}; - -typedef uint8_t virtio_net_ctrl_ack; - -#define VIRTIO_NET_OK 0 -#define VIRTIO_NET_ERR 1 - -/* - * Control the RX mode, ie. promisucous, allmulti, etc... - * All commands require an "out" sg entry containing a 1 byte - * state value, zero = disable, non-zero = enable. Commands - * 0 and 1 are supported with the VIRTIO_NET_F_CTRL_RX feature. - * Commands 2-5 are added with VIRTIO_NET_F_CTRL_RX_EXTRA. - */ -#define VIRTIO_NET_CTRL_RX 0 - #define VIRTIO_NET_CTRL_RX_PROMISC 0 - #define VIRTIO_NET_CTRL_RX_ALLMULTI 1 - #define VIRTIO_NET_CTRL_RX_ALLUNI 2 - #define VIRTIO_NET_CTRL_RX_NOMULTI 3 - #define VIRTIO_NET_CTRL_RX_NOUNI 4 - #define VIRTIO_NET_CTRL_RX_NOBCAST 5 - -/* - * Control the MAC - * - * The MAC filter table is managed by the hypervisor, the guest should - * assume the size is infinite. Filtering should be considered - * non-perfect, ie. based on hypervisor resources, the guest may - * received packets from sources not specified in the filter list. - * - * In addition to the class/cmd header, the TABLE_SET command requires - * two out scatterlists. Each contains a 4 byte count of entries followed - * by a concatenated byte stream of the ETH_ALEN MAC addresses. The - * first sg list contains unicast addresses, the second is for multicast. - * This functionality is present if the VIRTIO_NET_F_CTRL_RX feature - * is available. - * - * The ADDR_SET command requests one out scatterlist, it contains a - * 6 bytes MAC address. This functionality is present if the - * VIRTIO_NET_F_CTRL_MAC_ADDR feature is available. - */ -struct virtio_net_ctrl_mac { - uint32_t entries; - uint8_t macs[][ETH_ALEN]; -}; - typedef struct VirtIONetQueue { VirtQueue *rx_vq; VirtQueue *tx_vq; @@ -199,55 +99,6 @@ typedef struct VirtIONet { int announce_counter; } VirtIONet; -#define VIRTIO_NET_CTRL_MAC 1 - #define VIRTIO_NET_CTRL_MAC_TABLE_SET 0 - #define VIRTIO_NET_CTRL_MAC_ADDR_SET 1 - -/* - * Control VLAN filtering - * - * The VLAN filter table is controlled via a simple ADD/DEL interface. - * VLAN IDs not added may be filterd by the hypervisor. Del is the - * opposite of add. Both commands expect an out entry containing a 2 - * byte VLAN ID. VLAN filterting is available with the - * VIRTIO_NET_F_CTRL_VLAN feature bit. - */ -#define VIRTIO_NET_CTRL_VLAN 2 - #define VIRTIO_NET_CTRL_VLAN_ADD 0 - #define VIRTIO_NET_CTRL_VLAN_DEL 1 - -/* - * Control link announce acknowledgement - * - * VIRTIO_NET_S_ANNOUNCE bit in the status field requests link announcement from - * guest driver. The driver is notified by config space change interrupt. The - * command VIRTIO_NET_CTRL_ANNOUNCE_ACK is used to indicate that the driver has - * received the notification. It makes the device clear the bit - * VIRTIO_NET_S_ANNOUNCE in the status field. - */ -#define VIRTIO_NET_CTRL_ANNOUNCE 3 - #define VIRTIO_NET_CTRL_ANNOUNCE_ACK 0 - -/* - * Control Multiqueue - * - * The command VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET - * enables multiqueue, specifying the number of the transmit and - * receive queues that will be used. After the command is consumed and acked by - * the device, the device will not steer new packets on receive virtqueues - * other than specified nor read from transmit virtqueues other than specified. - * Accordingly, driver should not transmit new packets on virtqueues other than - * specified. - */ -struct virtio_net_ctrl_mq { - uint16_t virtqueue_pairs; -}; - -#define VIRTIO_NET_CTRL_MQ 4 - #define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET 0 - #define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN 1 - #define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX 0x8000 - /* * Control network offloads * diff --git a/include/net/tap.h b/include/net/tap.h index 6daeb42b0f..5da4edc692 100644 --- a/include/net/tap.h +++ b/include/net/tap.h @@ -28,6 +28,7 @@ #include "qemu-common.h" #include "qapi-types.h" +#include "standard-headers/linux/virtio_net.h" int tap_enable(NetClientState *nc); int tap_disable(NetClientState *nc); @@ -37,27 +38,4 @@ int tap_get_fd(NetClientState *nc); struct vhost_net; struct vhost_net *tap_get_vhost_net(NetClientState *nc); -struct virtio_net_hdr -{ -#define VIRTIO_NET_HDR_F_NEEDS_CSUM 1 // Use csum_start, csum_offset -#define VIRTIO_NET_HDR_F_DATA_VALID 2 // Csum is valid - uint8_t flags; -#define VIRTIO_NET_HDR_GSO_NONE 0 // Not a GSO frame -#define VIRTIO_NET_HDR_GSO_TCPV4 1 // GSO frame, IPv4 TCP (TSO) -#define VIRTIO_NET_HDR_GSO_UDP 3 // GSO frame, IPv4 UDP (UFO) -#define VIRTIO_NET_HDR_GSO_TCPV6 4 // GSO frame, IPv6 TCP -#define VIRTIO_NET_HDR_GSO_ECN 0x80 // TCP has ECN set - uint8_t gso_type; - uint16_t hdr_len; - uint16_t gso_size; - uint16_t csum_start; - uint16_t csum_offset; -}; - -struct virtio_net_hdr_mrg_rxbuf -{ - struct virtio_net_hdr hdr; - uint16_t num_buffers; /* Number of merged rx buffers */ -}; - #endif /* QEMU_NET_TAP_H */ From 3e96b2db080db986b813b58228e2553621b4b675 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 16 Feb 2015 22:36:15 +0100 Subject: [PATCH 039/130] virtio-rng: use standard-headers Drop duplicated code. Signed-off-by: Michael S. Tsirkin Reviewed-by: Thomas Huth --- include/hw/virtio/virtio-rng.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/include/hw/virtio/virtio-rng.h b/include/hw/virtio/virtio-rng.h index 14e85a5a3a..7702ff4749 100644 --- a/include/hw/virtio/virtio-rng.h +++ b/include/hw/virtio/virtio-rng.h @@ -14,6 +14,7 @@ #include "sysemu/rng.h" #include "sysemu/rng-random.h" +#include "standard-headers/linux/virtio_rng.h" #define TYPE_VIRTIO_RNG "virtio-rng-device" #define VIRTIO_RNG(obj) \ @@ -21,9 +22,6 @@ #define VIRTIO_RNG_GET_PARENT_CLASS(obj) \ OBJECT_GET_PARENT_CLASS(obj, TYPE_VIRTIO_RNG) -/* The Virtio ID for the virtio rng device */ -#define VIRTIO_ID_RNG 4 - struct VirtIORNGConf { RngBackend *rng; uint64_t max_bytes; From 019adbd3715e98b5a09fab1370cc2c6904f79b6d Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 16 Feb 2015 22:36:20 +0100 Subject: [PATCH 040/130] virtio-scsi: use standard-headers Drop duplicated code. Signed-off-by: Michael S. Tsirkin Acked-by: Paolo Bonzini --- hw/scsi/virtio-scsi.c | 1 + include/hw/virtio/virtio-scsi.h | 120 +++----------------------------- 2 files changed, 10 insertions(+), 111 deletions(-) diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index 9e2c718be7..d18654eec4 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" diff --git a/include/hw/virtio/virtio-scsi.h b/include/hw/virtio/virtio-scsi.h index c122e7ae5c..de2c739d22 100644 --- a/include/hw/virtio/virtio-scsi.h +++ b/include/hw/virtio/virtio-scsi.h @@ -14,6 +14,7 @@ #ifndef _QEMU_VIRTIO_SCSI_H #define _QEMU_VIRTIO_SCSI_H +#include "standard-headers/linux/virtio_scsi.h" #include "hw/virtio/virtio.h" #include "hw/pci/pci.h" #include "hw/scsi/scsi.h" @@ -28,15 +29,6 @@ #define VIRTIO_SCSI(obj) \ OBJECT_CHECK(VirtIOSCSI, (obj), TYPE_VIRTIO_SCSI) - -/* The ID for virtio_scsi */ -#define VIRTIO_ID_SCSI 8 - -/* Feature Bits */ -#define VIRTIO_SCSI_F_INOUT 0 -#define VIRTIO_SCSI_F_HOTPLUG 1 -#define VIRTIO_SCSI_F_CHANGE 2 - #define VIRTIO_SCSI_VQ_SIZE 128 #define VIRTIO_SCSI_CDB_SIZE 32 #define VIRTIO_SCSI_SENSE_SIZE 96 @@ -44,108 +36,14 @@ #define VIRTIO_SCSI_MAX_TARGET 255 #define VIRTIO_SCSI_MAX_LUN 16383 -/* Response codes */ -#define VIRTIO_SCSI_S_OK 0 -#define VIRTIO_SCSI_S_OVERRUN 1 -#define VIRTIO_SCSI_S_ABORTED 2 -#define VIRTIO_SCSI_S_BAD_TARGET 3 -#define VIRTIO_SCSI_S_RESET 4 -#define VIRTIO_SCSI_S_BUSY 5 -#define VIRTIO_SCSI_S_TRANSPORT_FAILURE 6 -#define VIRTIO_SCSI_S_TARGET_FAILURE 7 -#define VIRTIO_SCSI_S_NEXUS_FAILURE 8 -#define VIRTIO_SCSI_S_FAILURE 9 -#define VIRTIO_SCSI_S_FUNCTION_SUCCEEDED 10 -#define VIRTIO_SCSI_S_FUNCTION_REJECTED 11 -#define VIRTIO_SCSI_S_INCORRECT_LUN 12 - -/* Controlq type codes. */ -#define VIRTIO_SCSI_T_TMF 0 -#define VIRTIO_SCSI_T_AN_QUERY 1 -#define VIRTIO_SCSI_T_AN_SUBSCRIBE 2 - -/* Valid TMF subtypes. */ -#define VIRTIO_SCSI_T_TMF_ABORT_TASK 0 -#define VIRTIO_SCSI_T_TMF_ABORT_TASK_SET 1 -#define VIRTIO_SCSI_T_TMF_CLEAR_ACA 2 -#define VIRTIO_SCSI_T_TMF_CLEAR_TASK_SET 3 -#define VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET 4 -#define VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET 5 -#define VIRTIO_SCSI_T_TMF_QUERY_TASK 6 -#define VIRTIO_SCSI_T_TMF_QUERY_TASK_SET 7 - -/* Events. */ -#define VIRTIO_SCSI_T_EVENTS_MISSED 0x80000000 -#define VIRTIO_SCSI_T_NO_EVENT 0 -#define VIRTIO_SCSI_T_TRANSPORT_RESET 1 -#define VIRTIO_SCSI_T_ASYNC_NOTIFY 2 -#define VIRTIO_SCSI_T_PARAM_CHANGE 3 - -/* Reasons for transport reset event */ -#define VIRTIO_SCSI_EVT_RESET_HARD 0 -#define VIRTIO_SCSI_EVT_RESET_RESCAN 1 -#define VIRTIO_SCSI_EVT_RESET_REMOVED 2 - -/* SCSI command request, followed by CDB and data-out */ -typedef struct { - uint8_t lun[8]; /* Logical Unit Number */ - uint64_t tag; /* Command identifier */ - uint8_t task_attr; /* Task attribute */ - uint8_t prio; - uint8_t crn; -} QEMU_PACKED VirtIOSCSICmdReq; - -/* Response, followed by sense data and data-in */ -typedef struct { - uint32_t sense_len; /* Sense data length */ - uint32_t resid; /* Residual bytes in data buffer */ - uint16_t status_qualifier; /* Status qualifier */ - uint8_t status; /* Command completion status */ - uint8_t response; /* Response values */ -} QEMU_PACKED VirtIOSCSICmdResp; - -/* Task Management Request */ -typedef struct { - uint32_t type; - uint32_t subtype; - uint8_t lun[8]; - uint64_t tag; -} QEMU_PACKED VirtIOSCSICtrlTMFReq; - -typedef struct { - uint8_t response; -} QEMU_PACKED VirtIOSCSICtrlTMFResp; - -/* Asynchronous notification query/subscription */ -typedef struct { - uint32_t type; - uint8_t lun[8]; - uint32_t event_requested; -} QEMU_PACKED VirtIOSCSICtrlANReq; - -typedef struct { - uint32_t event_actual; - uint8_t response; -} QEMU_PACKED VirtIOSCSICtrlANResp; - -typedef struct { - uint32_t event; - uint8_t lun[8]; - uint32_t reason; -} QEMU_PACKED VirtIOSCSIEvent; - -typedef struct { - uint32_t num_queues; - uint32_t seg_max; - uint32_t max_sectors; - uint32_t cmd_per_lun; - uint32_t event_info_size; - uint32_t sense_size; - uint32_t cdb_size; - uint16_t max_channel; - uint16_t max_target; - uint32_t max_lun; -} QEMU_PACKED VirtIOSCSIConfig; +typedef struct virtio_scsi_cmd_req VirtIOSCSICmdReq; +typedef struct virtio_scsi_cmd_resp VirtIOSCSICmdResp; +typedef struct virtio_scsi_ctrl_tmf_req VirtIOSCSICtrlTMFReq; +typedef struct virtio_scsi_ctrl_tmf_resp VirtIOSCSICtrlTMFResp; +typedef struct virtio_scsi_ctrl_an_req VirtIOSCSICtrlANReq; +typedef struct virtio_scsi_ctrl_an_resp VirtIOSCSICtrlANResp; +typedef struct virtio_scsi_event VirtIOSCSIEvent; +typedef struct virtio_scsi_config VirtIOSCSIConfig; struct VirtIOSCSIConf { uint32_t num_queues; From 9b70c1790acacae54d559d38ca69186a85040bb8 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 16 Feb 2015 22:36:26 +0100 Subject: [PATCH 041/130] virtio-serial: switch to standard-headers Drop duplicate code. Signed-off-by: Michael S. Tsirkin --- hw/char/virtio-serial-bus.c | 1 + include/hw/virtio/virtio-serial.h | 40 +------------------------------ 2 files changed, 2 insertions(+), 39 deletions(-) diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c index 47fbb34bdd..a2bac9b4a9 100644 --- a/hw/char/virtio-serial-bus.c +++ b/hw/char/virtio-serial-bus.c @@ -18,6 +18,7 @@ * GNU GPL, version 2 or (at your option) any later version. */ +#include "standard-headers/linux/virtio_ids.h" #include "qemu/iov.h" #include "monitor/monitor.h" #include "qemu/queue.h" diff --git a/include/hw/virtio/virtio-serial.h b/include/hw/virtio/virtio-serial.h index 11af978a96..ccf8459829 100644 --- a/include/hw/virtio/virtio-serial.h +++ b/include/hw/virtio/virtio-serial.h @@ -15,53 +15,15 @@ #ifndef _QEMU_VIRTIO_SERIAL_H #define _QEMU_VIRTIO_SERIAL_H +#include "standard-headers/linux/virtio_console.h" #include "hw/qdev.h" #include "hw/virtio/virtio.h" -/* == Interface shared between the guest kernel and qemu == */ - -/* The Virtio ID for virtio console / serial ports */ -#define VIRTIO_ID_CONSOLE 3 - -/* Features supported */ -#define VIRTIO_CONSOLE_F_MULTIPORT 1 - -#define VIRTIO_CONSOLE_BAD_ID (~(uint32_t)0) - -struct virtio_console_config { - /* - * These two fields are used by VIRTIO_CONSOLE_F_SIZE which - * isn't implemented here yet - */ - uint16_t cols; - uint16_t rows; - - uint32_t max_nr_ports; -} QEMU_PACKED; - -struct virtio_console_control { - uint32_t id; /* Port number */ - uint16_t event; /* The kind of control event (see below) */ - uint16_t value; /* Extra information for the key */ -}; - struct virtio_serial_conf { /* Max. number of ports we can have for a virtio-serial device */ uint32_t max_virtserial_ports; }; -/* Some events for the internal messages (control packets) */ -#define VIRTIO_CONSOLE_DEVICE_READY 0 -#define VIRTIO_CONSOLE_PORT_ADD 1 -#define VIRTIO_CONSOLE_PORT_REMOVE 2 -#define VIRTIO_CONSOLE_PORT_READY 3 -#define VIRTIO_CONSOLE_CONSOLE_PORT 4 -#define VIRTIO_CONSOLE_RESIZE 5 -#define VIRTIO_CONSOLE_PORT_OPEN 6 -#define VIRTIO_CONSOLE_PORT_NAME 7 - -/* == In-qemu interface == */ - #define TYPE_VIRTIO_SERIAL_PORT "virtio-serial-port" #define VIRTIO_SERIAL_PORT(obj) \ OBJECT_CHECK(VirtIOSerialPort, (obj), TYPE_VIRTIO_SERIAL_PORT) From 05e492b0dbe42232b2ee9edffb016c68e6519a61 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 16 Feb 2015 22:36:32 +0100 Subject: [PATCH 042/130] update-linux-headers: use standard-headers Drop the linux-specific virtio headers, use the copy from standard-headers instead. Signed-off-by: Michael S. Tsirkin --- scripts/update-linux-headers.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh index 8926dec57f..5ab391496f 100755 --- a/scripts/update-linux-headers.sh +++ b/scripts/update-linux-headers.sh @@ -91,7 +91,7 @@ done rm -rf "$output/linux-headers/linux" mkdir -p "$output/linux-headers/linux" -for header in kvm.h kvm_para.h vfio.h vhost.h virtio_config.h virtio_ring.h \ +for header in kvm.h kvm_para.h vfio.h vhost.h \ psci.h; do cp "$tmpdir/include/linux/$header" "$output/linux-headers/linux" done @@ -106,6 +106,12 @@ else cp "$linux/COPYING" "$output/linux-headers" fi +cat <$output/linux-headers/linux/virtio_config.h +#include "standard-headers/linux/virtio_config.h" +EOF +cat <$output/linux-headers/linux/virtio_ring.h +#include "standard-headers/linux/virtio_ring.h" +EOF cp_virtio "$tmpdir/include/linux/" "$output/include/standard-headers/linux" From aa2e69fe2dd69ac2008b066c4c558a4b5c6a7e10 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 16 Feb 2015 22:36:37 +0100 Subject: [PATCH 043/130] linux-headers: use standard-headers Drop duplicated code. Signed-off-by: Michael S. Tsirkin --- linux-headers/linux/virtio_config.h | 58 +--------- linux-headers/linux/virtio_ring.h | 164 +--------------------------- 2 files changed, 2 insertions(+), 220 deletions(-) diff --git a/linux-headers/linux/virtio_config.h b/linux-headers/linux/virtio_config.h index 75dc20ba6f..5590f7d4a6 100644 --- a/linux-headers/linux/virtio_config.h +++ b/linux-headers/linux/virtio_config.h @@ -1,57 +1 @@ -#ifndef _LINUX_VIRTIO_CONFIG_H -#define _LINUX_VIRTIO_CONFIG_H -/* This header, excluding the #ifdef __KERNEL__ part, is BSD licensed so - * anyone can use the definitions to implement compatible drivers/servers. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of IBM nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. */ - -/* Virtio devices use a standardized configuration space to define their - * features and pass configuration information, but each implementation can - * store and access that space differently. */ -#include - -/* Status byte for guest to report progress, and synchronize features. */ -/* We have seen device and processed generic fields (VIRTIO_CONFIG_F_VIRTIO) */ -#define VIRTIO_CONFIG_S_ACKNOWLEDGE 1 -/* We have found a driver for the device. */ -#define VIRTIO_CONFIG_S_DRIVER 2 -/* Driver has used its parts of the config, and is happy */ -#define VIRTIO_CONFIG_S_DRIVER_OK 4 -/* We've given up on this device. */ -#define VIRTIO_CONFIG_S_FAILED 0x80 - -/* Some virtio feature bits (currently bits 28 through 31) are reserved for the - * transport being used (eg. virtio_ring), the rest are per-device feature - * bits. */ -#define VIRTIO_TRANSPORT_F_START 28 -#define VIRTIO_TRANSPORT_F_END 32 - -/* Do we get callbacks when the ring is completely used, even if we've - * suppressed them? */ -#define VIRTIO_F_NOTIFY_ON_EMPTY 24 - -/* Can the device handle any descriptor layout? */ -#define VIRTIO_F_ANY_LAYOUT 27 - -#endif /* _LINUX_VIRTIO_CONFIG_H */ +#include "standard-headers/linux/virtio_config.h" diff --git a/linux-headers/linux/virtio_ring.h b/linux-headers/linux/virtio_ring.h index 1b333e2536..c6f0fb6cd9 100644 --- a/linux-headers/linux/virtio_ring.h +++ b/linux-headers/linux/virtio_ring.h @@ -1,163 +1 @@ -#ifndef _LINUX_VIRTIO_RING_H -#define _LINUX_VIRTIO_RING_H -/* An interface for efficient virtio implementation, currently for use by KVM - * and lguest, but hopefully others soon. Do NOT change this since it will - * break existing servers and clients. - * - * This header is BSD licensed so anyone can use the definitions to implement - * compatible drivers/servers. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of IBM nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * Copyright Rusty Russell IBM Corporation 2007. */ -#include - -/* This marks a buffer as continuing via the next field. */ -#define VRING_DESC_F_NEXT 1 -/* This marks a buffer as write-only (otherwise read-only). */ -#define VRING_DESC_F_WRITE 2 -/* This means the buffer contains a list of buffer descriptors. */ -#define VRING_DESC_F_INDIRECT 4 - -/* The Host uses this in used->flags to advise the Guest: don't kick me when - * you add a buffer. It's unreliable, so it's simply an optimization. Guest - * will still kick if it's out of buffers. */ -#define VRING_USED_F_NO_NOTIFY 1 -/* The Guest uses this in avail->flags to advise the Host: don't interrupt me - * when you consume a buffer. It's unreliable, so it's simply an - * optimization. */ -#define VRING_AVAIL_F_NO_INTERRUPT 1 - -/* We support indirect buffer descriptors */ -#define VIRTIO_RING_F_INDIRECT_DESC 28 - -/* The Guest publishes the used index for which it expects an interrupt - * at the end of the avail ring. Host should ignore the avail->flags field. */ -/* The Host publishes the avail index for which it expects a kick - * at the end of the used ring. Guest should ignore the used->flags field. */ -#define VIRTIO_RING_F_EVENT_IDX 29 - -/* Virtio ring descriptors: 16 bytes. These can chain together via "next". */ -struct vring_desc { - /* Address (guest-physical). */ - __u64 addr; - /* Length. */ - __u32 len; - /* The flags as indicated above. */ - __u16 flags; - /* We chain unused descriptors via this, too */ - __u16 next; -}; - -struct vring_avail { - __u16 flags; - __u16 idx; - __u16 ring[]; -}; - -/* u32 is used here for ids for padding reasons. */ -struct vring_used_elem { - /* Index of start of used descriptor chain. */ - __u32 id; - /* Total length of the descriptor chain which was used (written to) */ - __u32 len; -}; - -struct vring_used { - __u16 flags; - __u16 idx; - struct vring_used_elem ring[]; -}; - -struct vring { - unsigned int num; - - struct vring_desc *desc; - - struct vring_avail *avail; - - struct vring_used *used; -}; - -/* The standard layout for the ring is a continuous chunk of memory which looks - * like this. We assume num is a power of 2. - * - * struct vring - * { - * // The actual descriptors (16 bytes each) - * struct vring_desc desc[num]; - * - * // A ring of available descriptor heads with free-running index. - * __u16 avail_flags; - * __u16 avail_idx; - * __u16 available[num]; - * __u16 used_event_idx; - * - * // Padding to the next align boundary. - * char pad[]; - * - * // A ring of used descriptor heads with free-running index. - * __u16 used_flags; - * __u16 used_idx; - * struct vring_used_elem used[num]; - * __u16 avail_event_idx; - * }; - */ -/* We publish the used event index at the end of the available ring, and vice - * versa. They are at the end for backwards compatibility. */ -#define vring_used_event(vr) ((vr)->avail->ring[(vr)->num]) -#define vring_avail_event(vr) (*(__u16 *)&(vr)->used->ring[(vr)->num]) - -static __inline__ void vring_init(struct vring *vr, unsigned int num, void *p, - unsigned long align) -{ - vr->num = num; - vr->desc = p; - vr->avail = p + num*sizeof(struct vring_desc); - vr->used = (void *)(((unsigned long)&vr->avail->ring[num] + sizeof(__u16) - + align-1) & ~(align - 1)); -} - -static __inline__ unsigned vring_size(unsigned int num, unsigned long align) -{ - return ((sizeof(struct vring_desc) * num + sizeof(__u16) * (3 + num) - + align - 1) & ~(align - 1)) - + sizeof(__u16) * 3 + sizeof(struct vring_used_elem) * num; -} - -/* The following is used with USED_EVENT_IDX and AVAIL_EVENT_IDX */ -/* 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(__u16 event_idx, __u16 new_idx, __u16 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_idx respectively. - * Note also that req_event and req_prod in Xen start at 1, - * event indexes in virtio start at 0. */ - return (__u16)(new_idx - event_idx - 1) < (__u16)(new_idx - old); -} - -#endif /* _LINUX_VIRTIO_RING_H */ +#include "standard-headers/linux/virtio_ring.h" From cbbe4f50a028ff49e983a2a8d82c8b0ae49bc756 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 16 Feb 2015 22:36:43 +0100 Subject: [PATCH 044/130] virtio-pci: use standard headers Drop duplicate code. Signed-off-by: Michael S. Tsirkin --- hw/virtio/virtio-pci.c | 54 ++++-------------------------------------- 1 file changed, 5 insertions(+), 49 deletions(-) diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index 604cb5b749..927997680e 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -17,6 +17,7 @@ #include +#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); From 44fb1dd4cef6d8be87cef7437fb350d0ebf2f837 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 16 Feb 2015 22:36:48 +0100 Subject: [PATCH 045/130] scripts: add arch specific standard-headers Copy arch specific virtio headers. ATM this applies to s390 only. Signed-off-by: Michael S. Tsirkin --- scripts/update-linux-headers.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh index 5ab391496f..9680e2711a 100755 --- a/scripts/update-linux-headers.sh +++ b/scripts/update-linux-headers.sh @@ -87,6 +87,8 @@ for arch in $ARCHLIST; do if [ $arch = powerpc ]; then cp "$tmpdir/include/asm/epapr_hcalls.h" "$output/linux-headers/asm-powerpc/" fi + + cp_virtio "$tmpdir/include/asm" "$output/include/standard-headers/asm-$arch" done rm -rf "$output/linux-headers/linux" From 9abd373c645050c958763d66107685f1512f843c Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 16 Feb 2015 22:36:53 +0100 Subject: [PATCH 046/130] standard-headers: add s390 virtio headers Signed-off-by: Michael S. Tsirkin --- .../standard-headers/asm-s390/kvm_virtio.h | 64 +++++++++++++++++++ .../standard-headers/asm-s390/virtio-ccw.h | 21 ++++++ 2 files changed, 85 insertions(+) create mode 100644 include/standard-headers/asm-s390/kvm_virtio.h create mode 100644 include/standard-headers/asm-s390/virtio-ccw.h diff --git a/include/standard-headers/asm-s390/kvm_virtio.h b/include/standard-headers/asm-s390/kvm_virtio.h new file mode 100644 index 0000000000..daad3249d2 --- /dev/null +++ b/include/standard-headers/asm-s390/kvm_virtio.h @@ -0,0 +1,64 @@ +/* + * definition for virtio for kvm on s390 + * + * Copyright IBM Corp. 2008 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License (version 2 only) + * as published by the Free Software Foundation. + * + * Author(s): Christian Borntraeger + */ + +#ifndef __KVM_S390_VIRTIO_H +#define __KVM_S390_VIRTIO_H + +#include "standard-headers/linux/types.h" + +struct kvm_device_desc { + /* The device type: console, network, disk etc. Type 0 terminates. */ + uint8_t type; + /* The number of virtqueues (first in config array) */ + uint8_t num_vq; + /* + * The number of bytes of feature bits. Multiply by 2: one for host + * features and one for guest acknowledgements. + */ + uint8_t feature_len; + /* The number of bytes of the config array after virtqueues. */ + uint8_t config_len; + /* A status byte, written by the Guest. */ + uint8_t status; + uint8_t config[0]; +}; + +/* + * This is how we expect the device configuration field for a virtqueue + * to be laid out in config space. + */ +struct kvm_vqconfig { + /* The token returned with an interrupt. Set by the guest */ + uint64_t token; + /* The address of the virtio ring */ + uint64_t address; + /* The number of entries in the virtio_ring */ + uint16_t num; + +}; + +#define KVM_S390_VIRTIO_NOTIFY 0 +#define KVM_S390_VIRTIO_RESET 1 +#define KVM_S390_VIRTIO_SET_STATUS 2 + +/* The alignment to use between consumer and producer parts of vring. + * This is pagesize for historical reasons. */ +#define KVM_S390_VIRTIO_RING_ALIGN 4096 + + +/* These values are supposed to be in ext_params on an interrupt */ +#define VIRTIO_PARAM_MASK 0xff +#define VIRTIO_PARAM_VRING_INTERRUPT 0x0 +#define VIRTIO_PARAM_CONFIG_CHANGED 0x1 +#define VIRTIO_PARAM_DEV_ADD 0x2 + +#endif diff --git a/include/standard-headers/asm-s390/virtio-ccw.h b/include/standard-headers/asm-s390/virtio-ccw.h new file mode 100644 index 0000000000..a9a4ebf79f --- /dev/null +++ b/include/standard-headers/asm-s390/virtio-ccw.h @@ -0,0 +1,21 @@ +/* + * Definitions for virtio-ccw devices. + * + * Copyright IBM Corp. 2013 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License (version 2 only) + * as published by the Free Software Foundation. + * + * Author(s): Cornelia Huck + */ +#ifndef __KVM_VIRTIO_CCW_H +#define __KVM_VIRTIO_CCW_H + +/* Alignment of vring buffers. */ +#define KVM_VIRTIO_CCW_RING_ALIGN 4096 + +/* Subcode for diagnose 500 (virtio hypercall). */ +#define KVM_S390_VIRTIO_CCW_NOTIFY 3 + +#endif From ad67a0f278ff9ad036a986384f1e3e94717af08e Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 16 Feb 2015 22:36:58 +0100 Subject: [PATCH 047/130] s390: use standard headers Drop duplicated macros in favor of values from standard headers. Tested-by: Cornelia Huck Signed-off-by: Michael S. Tsirkin --- hw/s390x/s390-virtio-bus.h | 36 +++++++++++++++++++----------------- hw/s390x/s390-virtio.h | 7 ++----- 2 files changed, 21 insertions(+), 22 deletions(-) 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 + +#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_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 +#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) + +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); From a590fd5ba8f01724eee169f097f65603f0c3a8f8 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Thu, 11 Dec 2014 14:25:04 +0100 Subject: [PATCH 048/130] virtio: cull virtio_bus_set_vdev_features The only user of this function was virtio-ccw, and it should use virtio_set_features() like everybody else: We need to make sure that bad features are masked out properly, which this function did not do. Reviewed-by: Thomas Huth Signed-off-by: Cornelia Huck Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/s390x/virtio-ccw.c | 3 +-- hw/virtio/virtio-bus.c | 14 -------------- include/hw/virtio/virtio-bus.h | 3 --- 3 files changed, 1 insertion(+), 19 deletions(-) diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index ea236c9b01..84f17bcf43 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 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/include/hw/virtio/virtio-bus.h b/include/hw/virtio/virtio-bus.h index 0756545d4d..0d2e7b49b2 100644 --- a/include/hw/virtio/virtio-bus.h +++ b/include/hw/virtio/virtio-bus.h @@ -84,9 +84,6 @@ size_t virtio_bus_get_vdev_config_len(VirtioBusState *bus); /* Get the features of the plugged device. */ uint32_t virtio_bus_get_vdev_features(VirtioBusState *bus, uint32_t requested_features); -/* Set the features of the plugged device. */ -void virtio_bus_set_vdev_features(VirtioBusState *bus, - uint32_t requested_features); /* Get bad features of the plugged device. */ uint32_t virtio_bus_get_vdev_bad_features(VirtioBusState *bus); /* Get config of the plugged device. */ From 0cd09c3a6cc2230ba38c462fc410b4acce59eb6f Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Thu, 11 Dec 2014 14:25:05 +0100 Subject: [PATCH 049/130] virtio: feature bit manipulation helpers Add virtio_{add,clear}_feature helper functions for manipulating a feature bits variable. This has some benefits over open coding: - add check that the bit is in a sane range - make it obvious at a glance what is going on - have a central point to change when we want to extend feature bits Convert existing code manipulating features to use the new helpers. Signed-off-by: Cornelia Huck Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/9pfs/virtio-9p-device.c | 2 +- hw/block/virtio-blk.c | 16 ++++++++-------- hw/char/virtio-serial-bus.c | 2 +- hw/net/virtio-net.c | 34 +++++++++++++++++----------------- hw/s390x/virtio-ccw.c | 4 ++-- hw/virtio/virtio-mmio.c | 2 +- hw/virtio/virtio-pci.c | 4 ++-- include/hw/virtio/virtio.h | 12 ++++++++++++ 8 files changed, 44 insertions(+), 32 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/block/virtio-blk.c b/hw/block/virtio-blk.c index 7cf31cb536..6decebf2ef 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -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; diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c index a2bac9b4a9..2365336393 100644 --- a/hw/char/virtio-serial-bus.c +++ b/hw/char/virtio-serial-bus.c @@ -475,7 +475,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/net/virtio-net.c b/hw/net/virtio-net.c index 45da34ad61..f901952b86 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -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; } @@ -1552,7 +1552,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/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index 84f17bcf43..3fee4aa345 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -743,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); 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 927997680e..6dd41b992f 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -952,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); } diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index d1b416b7ce..85e72d6fd9 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -219,6 +219,18 @@ void virtio_queue_set_host_notifier_fd_handler(VirtQueue *vq, bool assign, void virtio_queue_notify_vq(VirtQueue *vq); void virtio_irq(VirtQueue *vq); +static inline void virtio_add_feature(uint32_t *features, unsigned int fbit) +{ + assert(fbit < 32); + *features |= (1 << fbit); +} + +static inline void virtio_clear_feature(uint32_t *features, unsigned int fbit) +{ + assert(fbit < 32); + *features &= ~(1 << fbit); +} + static inline bool virtio_is_big_endian(VirtIODevice *vdev) { assert(vdev->device_endian != VIRTIO_DEVICE_ENDIAN_UNKNOWN); From ef546f1275f6563e8934dd5e338d29d9f9909ca6 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Thu, 11 Dec 2014 14:25:06 +0100 Subject: [PATCH 050/130] virtio: add feature checking helpers Add a helper function for checking whether a bit is set in the guest features for a vdev as well as one that works on a feature bit set. Convert code that open-coded this: It cleans up the code and makes it easier to extend the guest feature bits. Signed-off-by: Cornelia Huck Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/block/virtio-blk.c | 7 ++----- hw/char/virtio-serial-bus.c | 2 +- hw/net/virtio-net.c | 23 +++++++++++++---------- hw/scsi/virtio-scsi.c | 8 ++++---- hw/virtio/dataplane/vring.c | 10 +++++----- hw/virtio/virtio-balloon.c | 2 +- hw/virtio/virtio.c | 10 +++++----- include/hw/virtio/virtio.h | 11 +++++++++++ 8 files changed, 42 insertions(+), 31 deletions(-) diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c index 6decebf2ef..1e5b918620 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -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/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c index 2365336393..ba4cf2e3d0 100644 --- a/hw/char/virtio-serial-bus.c +++ b/hw/char/virtio-serial-bus.c @@ -76,7 +76,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, diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index f901952b86..1187ab813b 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); @@ -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; @@ -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)); } diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index d18654eec4..c5d910995f 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -145,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; } @@ -749,7 +749,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)); @@ -770,7 +770,7 @@ static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev, blk_op_block_all(sd->conf.blk, s->blocker); } - 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); @@ -784,7 +784,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/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/virtio-balloon.c b/hw/virtio/virtio-balloon.c index 7bfbb75ad3..21e449af8f 100644 --- a/hw/virtio/virtio-balloon.c +++ b/hw/virtio/virtio-balloon.c @@ -69,7 +69,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.c b/hw/virtio/virtio.c index f783f31b09..3c6e430048 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -217,7 +217,7 @@ static inline void vring_set_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)) { + 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); @@ -468,7 +468,7 @@ 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)) { + if (virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) { vring_set_avail_event(vq, vq->last_avail_idx); } @@ -826,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); } diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index 85e72d6fd9..d95f8b6d50 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -231,6 +231,17 @@ static inline void virtio_clear_feature(uint32_t *features, unsigned int fbit) *features &= ~(1 << fbit); } +static inline bool __virtio_has_feature(uint32_t features, unsigned int fbit) +{ + assert(fbit < 32); + return !!(features & (1 << fbit)); +} + +static inline bool virtio_has_feature(VirtIODevice *vdev, unsigned int fbit) +{ + return __virtio_has_feature(vdev->guest_features, fbit); +} + static inline bool virtio_is_big_endian(VirtIODevice *vdev) { assert(vdev->device_endian != VIRTIO_DEVICE_ENDIAN_UNKNOWN); From a20275fa502f57a50517d31c6b770e0eeff8feca Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Wed, 28 Jan 2015 18:30:38 +0200 Subject: [PATCH 051/130] acpi-build: skip hotplugged bridges hotplugged bridges don't get bsel allocated so acpi hotplug doesn't work for them anyway. OTOH adding them in ACPI creates a host of problems, e.g. they can't be hot-unplugged themselves which is surprising to users. So let's just skip these. Signed-off-by: Michael S. Tsirkin --- hw/i386/acpi-build.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 9b11c927b5..fa7e52a4d0 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -699,8 +699,10 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state) /* * Skip bridge subtree creation if bridge hotplug is disabled * to make acpi tables compatible with legacy machine types. + * Skip creation for hotplugged bridges as well. */ - if (!child->pcihp_bridge_en && bus->parent_dev) { + if (bus->parent_dev && (!child->pcihp_bridge_en || + DEVICE(bus->parent_dev)->hotplugged)) { build_free_array(bus_table); build_pci_bus_state_cleanup(child); g_free(child); @@ -757,8 +759,10 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state) /* 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 && child->pcihp_bridge_en && + !DEVICE(pdev)->hotplugged; if (pc->class_id == PCI_CLASS_BRIDGE_ISA || bridge_in_acpi) { set_bit(slot, slot_device_system); From 7c2c1fa5f428b7087721f7312ee82b9de05da6ca Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Mon, 9 Feb 2015 10:53:24 +0000 Subject: [PATCH 052/130] pc: acpi: use local var for accessing ACPI tables blob in acpi_build() except of shortening of lines and making code a bit more readable, it will reduce renaming noise when changing tables blob from GArray* to Aml* type. Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/acpi-build.c | 69 ++++++++++++++++++++++---------------------- 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index fa7e52a4d0..5e4b333dcf 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -1421,6 +1421,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); @@ -1441,66 +1442,66 @@ 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); @@ -1530,23 +1531,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); From c16758cb4f273f72606cd9002fa31c2651822fcd Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Wed, 18 Feb 2015 16:37:35 +0100 Subject: [PATCH 053/130] update-linux-headers.sh: s/__inline__/inline/ Thomas Huth noticed that some linux headers use __inline__, change to inline to be consistent with the rest of QEMU. Reported-by: Thomas Huth Signed-off-by: Michael S. Tsirkin --- scripts/update-linux-headers.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh index 9680e2711a..f208ec9c51 100755 --- a/scripts/update-linux-headers.sh +++ b/scripts/update-linux-headers.sh @@ -53,6 +53,7 @@ cp_virtio() { -e 's/]*\)>/"standard-headers\/linux\/\1"/' \ -e 's/__bitwise__//' \ -e 's/__attribute__((packed))/QEMU_PACKED/' \ + -e 's/__inline__/inline/' \ "$f" > "$to/$header"; done fi From 6a19cd34b175bfc99bf5aa877e6e8eda636848f9 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Wed, 18 Feb 2015 16:42:30 +0100 Subject: [PATCH 054/130] virtio-serial-bus.c: drop virtio_ids.h virtio-serial.h pulls that in already. Reported-by: Thomas Huth Signed-off-by: Michael S. Tsirkin --- hw/char/virtio-serial-bus.c | 1 - 1 file changed, 1 deletion(-) diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c index ba4cf2e3d0..9a029d2130 100644 --- a/hw/char/virtio-serial-bus.c +++ b/hw/char/virtio-serial-bus.c @@ -18,7 +18,6 @@ * GNU GPL, version 2 or (at your option) any later version. */ -#include "standard-headers/linux/virtio_ids.h" #include "qemu/iov.h" #include "monitor/monitor.h" #include "qemu/queue.h" From 714e601379e125cde88bea6d4a3ea8f78ffbdf62 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Wed, 18 Feb 2015 16:44:35 +0100 Subject: [PATCH 055/130] standard-headers: include stdint.h The importing script got it right already, I just forgot to re-run it. Reported-by: Thomas Huth Signed-off-by: Michael S. Tsirkin --- include/standard-headers/linux/types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/standard-headers/linux/types.h b/include/standard-headers/linux/types.h index 7d42ac6f3c..0526c2b87c 100644 --- a/include/standard-headers/linux/types.h +++ b/include/standard-headers/linux/types.h @@ -1,2 +1,2 @@ -#include +#include #include "qemu/compiler.h" From e0d2be2ad6461ccdcf3e3930742a6b18a7ee5eb8 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Wed, 18 Feb 2015 16:37:35 +0100 Subject: [PATCH 056/130] virtio_ring.h: s/__inline__/inline/ Thomas Huth noticed that some linux headers use __inline__, change to inline to be consistent with the rest of QEMU. Reported-by: Thomas Huth Signed-off-by: Michael S. Tsirkin --- include/standard-headers/linux/virtio_ring.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/standard-headers/linux/virtio_ring.h b/include/standard-headers/linux/virtio_ring.h index 2bd19a8d25..cc647d61fc 100644 --- a/include/standard-headers/linux/virtio_ring.h +++ b/include/standard-headers/linux/virtio_ring.h @@ -137,7 +137,7 @@ struct vring { #define vring_used_event(vr) ((vr)->avail->ring[(vr)->num]) #define vring_avail_event(vr) (*(__virtio16 *)&(vr)->used->ring[(vr)->num]) -static __inline__ void vring_init(struct vring *vr, unsigned int num, void *p, +static inline void vring_init(struct vring *vr, unsigned int num, void *p, unsigned long align) { vr->num = num; @@ -147,7 +147,7 @@ static __inline__ void vring_init(struct vring *vr, unsigned int num, void *p, + align-1) & ~(align - 1)); } -static __inline__ unsigned vring_size(unsigned int num, unsigned long align) +static inline unsigned vring_size(unsigned int num, unsigned long align) { return ((sizeof(struct vring_desc) * num + sizeof(__virtio16) * (3 + num) + align - 1) & ~(align - 1)) @@ -158,7 +158,7 @@ static __inline__ unsigned vring_size(unsigned int num, unsigned long align) /* 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_idx, uint16_t new_idx, uint16_t old) +static inline int vring_need_event(uint16_t event_idx, uint16_t new_idx, 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 From 0f2707e4e733614f2cd566e7210c1cff6f3b5b42 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 18 Feb 2015 19:14:14 +0000 Subject: [PATCH 057/130] acpi: introduce AML composer aml_append() Adds for dynamic AML creation, which will be used for piecing ASL/AML primitives together and hiding from user/caller details about how nested context should be closed/packed leaving less space for mistakes and necessity to know how AML should be encoded, allowing user to concentrate on ASL representation instead. For example it will allow to create AML like this: init_aml_allocator(); ... Aml *scope = aml_scope("PCI0") Aml *dev = aml_device("PM") aml_append(dev, aml_name_decl("_ADR", aml_int(addr))) aml_append(scope, dev); ... free_aml_allocator(); Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/aml-build.c | 78 +++++++++++++++++++++++++++++++++++++ include/hw/acpi/aml-build.h | 55 ++++++++++++++++++++++++++ 2 files changed, 133 insertions(+) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index bcb288eab4..caf792b5d2 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -25,6 +25,7 @@ #include #include #include "hw/acpi/aml-build.h" +#include "qemu/bswap.h" GArray *build_alloc_array(void) { @@ -257,3 +258,80 @@ void build_append_int(GArray *table, uint32_t value) build_append_value(table, value, 4); } } + +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 void aml_free(gpointer 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_with_free_func(aml_free); + var = aml_alloc(); + return var; +} + +void free_aml_allocator(void) +{ + 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); +} diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index 199f003265..1e1b03bc4e 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -5,6 +5,61 @@ #include #include "qemu/compiler.h" +typedef enum { + AML_NO_OPCODE = 0,/* has only data */ + AML_OPCODE, /* has opcode optionally followed by data */ + AML_PACKAGE, /* has opcode and uses PkgLength for its length */ + AML_EXT_PACKAGE, /* ame as AML_PACKAGE but also has 'ExOpPrefix' */ + AML_BUFFER, /* data encoded as 'DefBuffer' */ + AML_RES_TEMPLATE, /* encoded as ResourceTemplate macro */ +} AmlBlockFlags; + +struct Aml { + GArray *buf; + + /*< private >*/ + uint8_t op; + AmlBlockFlags block_flags; +}; +typedef struct Aml Aml; + +/** + * init_aml_allocator: + * + * Called for initializing API allocator which allow to use + * AML API. + * Returns: toplevel container which accumulates all other + * AML elements for a table. + */ +Aml *init_aml_allocator(void); + +/** + * free_aml_allocator: + * + * Releases all elements used by AML API, frees associated memory + * and invalidates AML allocator. After this call @init_aml_allocator + * should be called again if AML API is to be used again. + */ +void free_aml_allocator(void); + +/** + * aml_append: + * @parent_ctx: context to which @child element is added + * @child: element that is copied into @parent_ctx context + * + * Joins Aml elements together and helps to construct AML tables + * Examle of usage: + * Aml *table = aml_def_block("SSDT", ...); + * Aml *sb = aml_scope("\_SB"); + * Aml *dev = aml_device("PCI0"); + * + * aml_append(dev, aml_name_decl("HID", aml_eisaid("PNP0A03"))); + * aml_append(sb, dev); + * aml_append(table, sb); + */ +void aml_append(Aml *parent_ctx, Aml *child); + +/* other helpers */ GArray *build_alloc_array(void); void build_free_array(GArray *array); void build_prepend_byte(GArray *array, uint8_t val); From 2ef7c27b78c663557771076b45e6f4be1b3c78d6 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 18 Feb 2015 19:14:15 +0000 Subject: [PATCH 058/130] acpi: add aml_scope() term Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/aml-build.c | 20 ++++++++++++++++++++ include/hw/acpi/aml-build.h | 3 +++ 2 files changed, 23 insertions(+) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index caf792b5d2..f891406d5f 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -271,6 +271,15 @@ static Aml *aml_alloc(void) 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) { Aml *var = data; @@ -335,3 +344,14 @@ void aml_append(Aml *parent_ctx, Aml *child) } 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; +} diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index 1e1b03bc4e..05dd3fcbb2 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -59,6 +59,9 @@ void free_aml_allocator(void); */ void aml_append(Aml *parent_ctx, Aml *child); +/* Block AML object primitives */ +Aml *aml_scope(const char *name_format, ...) GCC_FMT_ATTR(1, 2); + /* other helpers */ GArray *build_alloc_array(void); void build_free_array(GArray *array); From 011bb7490bf32d84e644d79570f603651e4f80cb Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 18 Feb 2015 19:14:16 +0000 Subject: [PATCH 059/130] pc: acpi-build: use aml_scope() for \_SB scope prepares for incremental conversion of SSDT content to AML API Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/acpi-build.c | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 5e4b333dcf..c66fe568c1 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -923,17 +923,18 @@ 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; 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)); + ssdt_ptr = acpi_data_push(ssdt->buf, 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'; @@ -953,15 +954,11 @@ build_ssdt(GArray *table_data, GArray *linker, ACPI_BUILD_SET_LE(ssdt_ptr, sizeof(ssdp_misc_aml), ssdt_mctrl_nr_slots[0], 32, nr_mem); + sb_scope = aml_scope("_SB"); { - GArray *sb_scope = build_alloc_array(); - uint8_t op = 0x10; /* ScopeOp */ - - build_append_namestring(sb_scope, "_SB"); - /* build Processor object for each processor */ for (i = 0; i < acpi_cpus; i++) { - uint8_t *proc = acpi_data_push(sb_scope, ACPI_PROC_SIZEOF); + uint8_t *proc = acpi_data_push(sb_scope->buf, 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); @@ -973,11 +970,12 @@ build_ssdt(GArray *table_data, GArray *linker, * 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_append_notify_method(sb_scope->buf, "NTFY", + "CP%0.02X", acpi_cpus); /* build "Name(CPON, Package() { One, One, ..., Zero, Zero, ... })" */ - build_append_byte(sb_scope, 0x08); /* NameOp */ - build_append_namestring(sb_scope, "CPON"); + build_append_byte(sb_scope->buf, 0x08); /* NameOp */ + build_append_namestring(sb_scope->buf, "CPON"); { GArray *package = build_alloc_array(); @@ -1002,7 +1000,7 @@ build_ssdt(GArray *table_data, GArray *linker, } build_package(package, op); - build_append_array(sb_scope, package); + build_append_array(sb_scope->buf, package); build_free_array(package); } @@ -1011,7 +1009,7 @@ build_ssdt(GArray *table_data, GArray *linker, /* build memory devices */ for (i = 0; i < nr_mem; i++) { char id[3]; - uint8_t *mem = acpi_data_push(sb_scope, ACPI_MEM_SIZEOF); + uint8_t *mem = acpi_data_push(sb_scope->buf, ACPI_MEM_SIZEOF); snprintf(id, sizeof(id), "%02X", i); memcpy(mem, ACPI_MEM_AML, ACPI_MEM_SIZEOF); @@ -1022,7 +1020,7 @@ build_ssdt(GArray *table_data, GArray *linker, /* build Method(MEMORY_SLOT_NOTIFY_METHOD, 2) { * If (LEqual(Arg0, 0x00)) {Notify(MP00, Arg1)} ... */ - build_append_notify_method(sb_scope, + build_append_notify_method(sb_scope->buf, stringify(MEMORY_SLOT_NOTIFY_METHOD), "MP%0.02X", nr_mem); } @@ -1046,17 +1044,18 @@ build_ssdt(GArray *table_data, GArray *linker, build_pci_bus_end, &hotplug_state); } - build_append_array(sb_scope, hotplug_state.device_table); + build_append_array(sb_scope->buf, hotplug_state.device_table); build_pci_bus_state_cleanup(&hotplug_state); } - build_package(sb_scope, op); - 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 From be06ebd0a4d42ccd3d79fae24e48c264be377356 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 18 Feb 2015 19:14:17 +0000 Subject: [PATCH 060/130] acpi: add aml_device() term Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/aml-build.c | 11 +++++++++++ include/hw/acpi/aml-build.h | 1 + 2 files changed, 12 insertions(+) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index f891406d5f..c955d664ae 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -355,3 +355,14 @@ Aml *aml_scope(const char *name_format, ...) va_end(ap); 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; +} diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index 05dd3fcbb2..004fa05cdc 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -61,6 +61,7 @@ void aml_append(Aml *parent_ctx, Aml *child); /* Block AML object primitives */ Aml *aml_scope(const char *name_format, ...) GCC_FMT_ATTR(1, 2); +Aml *aml_device(const char *name_format, ...) GCC_FMT_ATTR(1, 2); /* other helpers */ GArray *build_alloc_array(void); From ea2407d7e8adae1ab6cd0ca0366752d101d2344f Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 18 Feb 2015 19:14:18 +0000 Subject: [PATCH 061/130] acpi: add aml_method() term Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/aml-build.c | 9 +++++++++ include/hw/acpi/aml-build.h | 1 + 2 files changed, 10 insertions(+) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index c955d664ae..4e0685e37a 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -356,6 +356,15 @@ Aml *aml_scope(const char *name_format, ...) 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, ...) { diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index 004fa05cdc..97e210a1f3 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -62,6 +62,7 @@ void aml_append(Aml *parent_ctx, Aml *child); /* Block AML object primitives */ Aml *aml_scope(const char *name_format, ...) GCC_FMT_ATTR(1, 2); Aml *aml_device(const char *name_format, ...) GCC_FMT_ATTR(1, 2); +Aml *aml_method(const char *name, int arg_count); /* other helpers */ GArray *build_alloc_array(void); From 32acac9eb3478cb1229654883f938ab21d28d998 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 18 Feb 2015 19:14:19 +0000 Subject: [PATCH 062/130] acpi: add aml_if() term Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/aml-build.c | 8 ++++++++ include/hw/acpi/aml-build.h | 1 + 2 files changed, 9 insertions(+) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index 4e0685e37a..d19d1fb74a 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -356,6 +356,14 @@ Aml *aml_scope(const char *name_format, ...) 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) { diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index 97e210a1f3..13cc9e9db9 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -63,6 +63,7 @@ void aml_append(Aml *parent_ctx, Aml *child); Aml *aml_scope(const char *name_format, ...) GCC_FMT_ATTR(1, 2); Aml *aml_device(const char *name_format, ...) GCC_FMT_ATTR(1, 2); Aml *aml_method(const char *name, int arg_count); +Aml *aml_if(Aml *predicate); /* other helpers */ GArray *build_alloc_array(void); From 3c054bd51a132a69e5180f8c6ffa9d46724e4a50 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 18 Feb 2015 19:14:20 +0000 Subject: [PATCH 063/130] acpi: add aml_name() & aml_name_decl() term Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/aml-build.c | 32 ++++++++++++++++++++++++++++++++ include/hw/acpi/aml-build.h | 4 ++++ 2 files changed, 36 insertions(+) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index d19d1fb74a..cb00a1ba80 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -271,6 +271,15 @@ static Aml *aml_alloc(void) 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(); @@ -356,6 +365,29 @@ Aml *aml_scope(const char *name_format, ...) 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.5.3 Type 1 Opcodes Encoding: DefIfElse */ Aml *aml_if(Aml *predicate) { diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index 13cc9e9db9..946aece4ba 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -59,6 +59,10 @@ void free_aml_allocator(void); */ void aml_append(Aml *parent_ctx, Aml *child); +/* non block AML object primitives */ +Aml *aml_name(const char *name_format, ...) GCC_FMT_ATTR(1, 2); +Aml *aml_name_decl(const char *name, Aml *val); + /* Block AML object primitives */ Aml *aml_scope(const char *name_format, ...) GCC_FMT_ATTR(1, 2); Aml *aml_device(const char *name_format, ...) GCC_FMT_ATTR(1, 2); From 295a515df0df655a902df6ebfc301096a3ee88ed Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 18 Feb 2015 19:14:21 +0000 Subject: [PATCH 064/130] acpi: add aml_int() term * factor out ACPI const int packing out of build_append_value() and rename build_append_value() to build_append_int_noprefix() it will be reused for adding a plain integer value into AML. will be used by is aml_processor() and CRS macro helpers * extend build_append_int{_noprefix}() to support 64-bit values it will be used PCI for generating 64bit _CRS entries Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/aml-build.c | 43 +++++++++++++++++++------------------ hw/i386/acpi-build.c | 12 +++++------ include/hw/acpi/aml-build.h | 4 ++-- 3 files changed, 30 insertions(+), 29 deletions(-) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index cb00a1ba80..aaa80e575c 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -218,44 +218,34 @@ void build_extop_package(GArray *package, uint8_t op) build_prepend_byte(package, 0x5B); /* ExtOpPrefix */ } -void build_append_value(GArray *table, uint32_t value, int size) +static void build_append_int_noprefix(GArray *table, uint64_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; } } -void build_append_int(GArray *table, uint32_t value) +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_value(table, value, 1); + build_append_byte(table, 0x0A); /* BytePrefix */ + build_append_int_noprefix(table, value, 1); } else if (value <= 0xFFFF) { - build_append_value(table, value, 2); + 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_value(table, value, 4); + build_append_byte(table, 0x0E); /* QWordPrefix */ + build_append_int_noprefix(table, value, 8); } } @@ -365,6 +355,17 @@ Aml *aml_scope(const char *name_format, ...) 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 diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index c66fe568c1..bf344151f5 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -304,14 +304,14 @@ static void build_append_and_cleanup_method(GArray *device, GArray *method) static void build_append_notify_target_ifequal(GArray *method, GArray *target_name, - uint32_t value, int size) + uint32_t value) { 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_int(notify, value); build_append_byte(notify, 0x86); /* NotifyOp */ build_append_array(notify, target_name); build_append_byte(notify, 0x69); /* Arg1Op */ @@ -580,7 +580,7 @@ build_append_notify_method(GArray *device, const char *name, GArray *target = build_alloc_array(); build_append_namestring(target, format, i); assert(i < 256); /* Fits in 1 byte */ - build_append_notify_target_ifequal(method, target, i, 1); + build_append_notify_target_ifequal(method, target, i); build_free_array(target); } @@ -715,11 +715,11 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state) bus->parent_dev->devfn); build_append_byte(bus_table, 0x08); /* NameOp */ build_append_namestring(bus_table, "_SUN"); - build_append_value(bus_table, PCI_SLOT(bus->parent_dev->devfn), 1); + build_append_int(bus_table, PCI_SLOT(bus->parent_dev->devfn)); build_append_byte(bus_table, 0x08); /* NameOp */ build_append_namestring(bus_table, "_ADR"); - build_append_value(bus_table, (PCI_SLOT(bus->parent_dev->devfn) << 16) | - PCI_FUNC(bus->parent_dev->devfn), 4); + build_append_int(bus_table, (PCI_SLOT(bus->parent_dev->devfn) << 16) | + PCI_FUNC(bus->parent_dev->devfn)); } else { op = 0x10; /* ScopeOp */; build_append_namestring(bus_table, "PCI0"); diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index 946aece4ba..a385132b8e 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -62,6 +62,7 @@ void aml_append(Aml *parent_ctx, Aml *child); /* non block AML object primitives */ Aml *aml_name(const char *name_format, ...) GCC_FMT_ATTR(1, 2); Aml *aml_name_decl(const char *name, Aml *val); +Aml *aml_int(const uint64_t val); /* Block AML object primitives */ Aml *aml_scope(const char *name_format, ...) GCC_FMT_ATTR(1, 2); @@ -81,8 +82,7 @@ build_append_namestring(GArray *array, const char *format, ...); void build_prepend_package_length(GArray *package); void build_package(GArray *package, uint8_t op); -void build_append_value(GArray *table, uint32_t value, int size); -void build_append_int(GArray *table, uint32_t value); +void build_append_int(GArray *table, uint64_t value); void build_extop_package(GArray *package, uint8_t op); #endif From b25af5ad5953c9587e59c82cc668e574384f5245 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 18 Feb 2015 19:14:22 +0000 Subject: [PATCH 065/130] acpi: add aml_return() term Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/aml-build.c | 8 ++++++++ include/hw/acpi/aml-build.h | 1 + 2 files changed, 9 insertions(+) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index aaa80e575c..8207d9c057 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -355,6 +355,14 @@ Aml *aml_scope(const char *name_format, ...) 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 diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index a385132b8e..e7fa9771b1 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -62,6 +62,7 @@ void aml_append(Aml *parent_ctx, Aml *child); /* non block AML object primitives */ Aml *aml_name(const char *name_format, ...) GCC_FMT_ATTR(1, 2); Aml *aml_name_decl(const char *name, Aml *val); +Aml *aml_return(Aml *val); Aml *aml_int(const uint64_t val); /* Block AML object primitives */ From 7193f3a67ee4794096255396eeac99f9624144e1 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 18 Feb 2015 19:14:23 +0000 Subject: [PATCH 066/130] acpi: add aml_arg() term Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/aml-build.c | 11 +++++++++++ include/hw/acpi/aml-build.h | 1 + 2 files changed, 12 insertions(+) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index 8207d9c057..99d213c182 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -397,6 +397,17 @@ Aml *aml_name_decl(const char *name, Aml *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.3 Type 1 Opcodes Encoding: DefIfElse */ Aml *aml_if(Aml *predicate) { diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index e7fa9771b1..63e9754ad6 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -64,6 +64,7 @@ Aml *aml_name(const char *name_format, ...) GCC_FMT_ATTR(1, 2); Aml *aml_name_decl(const char *name, Aml *val); Aml *aml_return(Aml *val); Aml *aml_int(const uint64_t val); +Aml *aml_arg(int pos); /* Block AML object primitives */ Aml *aml_scope(const char *name_format, ...) GCC_FMT_ATTR(1, 2); From c263b3f754325ae76946a5ea0e1df9368fe289bd Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 18 Feb 2015 19:14:24 +0000 Subject: [PATCH 067/130] acpi: add aml_store() term Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/aml-build.c | 9 +++++++++ include/hw/acpi/aml-build.h | 1 + 2 files changed, 10 insertions(+) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index 99d213c182..57e3176c62 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -408,6 +408,15 @@ Aml *aml_arg(int pos) 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.3 Type 1 Opcodes Encoding: DefIfElse */ Aml *aml_if(Aml *predicate) { diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index 63e9754ad6..6ad76ddc62 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -65,6 +65,7 @@ Aml *aml_name_decl(const char *name, Aml *val); Aml *aml_return(Aml *val); Aml *aml_int(const uint64_t val); Aml *aml_arg(int pos); +Aml *aml_store(Aml *val, Aml *target); /* Block AML object primitives */ Aml *aml_scope(const char *name_format, ...) GCC_FMT_ATTR(1, 2); From 926f5aaefad164dabcdd771f4c15c9773383d9e9 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 18 Feb 2015 19:14:25 +0000 Subject: [PATCH 068/130] acpi: add aml_and() term Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/aml-build.c | 10 ++++++++++ include/hw/acpi/aml-build.h | 1 + 2 files changed, 11 insertions(+) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index 57e3176c62..bb1fbbce44 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -417,6 +417,16 @@ Aml *aml_store(Aml *val, Aml *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: DefIfElse */ Aml *aml_if(Aml *predicate) { diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index 6ad76ddc62..2fca361e7c 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -66,6 +66,7 @@ Aml *aml_return(Aml *val); Aml *aml_int(const uint64_t val); Aml *aml_arg(int pos); Aml *aml_store(Aml *val, Aml *target); +Aml *aml_and(Aml *arg1, Aml *arg2); /* Block AML object primitives */ Aml *aml_scope(const char *name_format, ...) GCC_FMT_ATTR(1, 2); From 34189453f1783c934d3824ff4636684f3ab20810 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 18 Feb 2015 19:14:26 +0000 Subject: [PATCH 069/130] acpi: add aml_notify() term Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/aml-build.c | 9 +++++++++ include/hw/acpi/aml-build.h | 1 + 2 files changed, 10 insertions(+) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index bb1fbbce44..3e187fabce 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -427,6 +427,15 @@ Aml *aml_and(Aml *arg1, Aml *arg2) 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; +} + /* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefIfElse */ Aml *aml_if(Aml *predicate) { diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index 2fca361e7c..cbef2368d2 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -67,6 +67,7 @@ Aml *aml_int(const uint64_t val); Aml *aml_arg(int pos); Aml *aml_store(Aml *val, Aml *target); Aml *aml_and(Aml *arg1, Aml *arg2); +Aml *aml_notify(Aml *arg1, Aml *arg2); /* Block AML object primitives */ Aml *aml_scope(const char *name_format, ...) GCC_FMT_ATTR(1, 2); From 3f3992b7c4ed9850e7f5502a1294cd017a891b38 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 18 Feb 2015 19:14:27 +0000 Subject: [PATCH 070/130] acpi: add aml_call1(), aml_call2(), aml_call3(), aml_call4() helpers Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/aml-build.c | 42 +++++++++++++++++++++++++++++++++++++ include/hw/acpi/aml-build.h | 4 ++++ 2 files changed, 46 insertions(+) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index 3e187fabce..18427b6407 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -436,6 +436,48 @@ Aml *aml_notify(Aml *arg1, Aml *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: 16.2.5.3 Type 1 Opcodes Encoding: DefIfElse */ Aml *aml_if(Aml *predicate) { diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index cbef2368d2..5f00b07c30 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -68,6 +68,10 @@ Aml *aml_arg(int pos); Aml *aml_store(Aml *val, Aml *target); Aml *aml_and(Aml *arg1, Aml *arg2); Aml *aml_notify(Aml *arg1, Aml *arg2); +Aml *aml_call1(const char *method, Aml *arg1); +Aml *aml_call2(const char *method, Aml *arg1, Aml *arg2); +Aml *aml_call3(const char *method, Aml *arg1, Aml *arg2, Aml *arg3); +Aml *aml_call4(const char *method, Aml *arg1, Aml *arg2, Aml *arg3, Aml *arg4); /* Block AML object primitives */ Aml *aml_scope(const char *name_format, ...) GCC_FMT_ATTR(1, 2); From 3bfa74a7e8c0787877e0f23a873413ad8817c66c Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 18 Feb 2015 19:14:28 +0000 Subject: [PATCH 071/130] acpi: add aml_package() term Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/aml-build.c | 8 ++++++++ include/hw/acpi/aml-build.h | 1 + 2 files changed, 9 insertions(+) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index 18427b6407..fdeeacc993 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -505,3 +505,11 @@ Aml *aml_device(const char *name_format, ...) va_end(ap); 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; +} diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index 5f00b07c30..92097b5945 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -78,6 +78,7 @@ Aml *aml_scope(const char *name_format, ...) GCC_FMT_ATTR(1, 2); Aml *aml_device(const char *name_format, ...) GCC_FMT_ATTR(1, 2); Aml *aml_method(const char *name, int arg_count); Aml *aml_if(Aml *predicate); +Aml *aml_package(uint8_t num_elements); /* other helpers */ GArray *build_alloc_array(void); From ebc3028f7a2a164e442d734868e4168aa6040c81 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 18 Feb 2015 19:14:29 +0000 Subject: [PATCH 072/130] pc: acpi-build: generate _S[345] packages dynamically Replaces template patching with packages composed using AML API. Note on behavior change: If S3 or S4 is disabled, respective packages won't be created and put into SSDT. Which saves us some space in SSDT and doesn't confuse guest OS with mangled package names as it was done originally. Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/acpi-build.c | 40 ++++++++++++++++++++++++++++++---------- hw/i386/ssdt-misc.dsl | 33 --------------------------------- 2 files changed, 30 insertions(+), 43 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index bf344151f5..4536fba0ab 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -924,7 +924,7 @@ build_ssdt(GArray *table_data, GArray *linker, uint32_t nr_mem = machine->ram_slots; unsigned acpi_cpus = guest_info->apic_id_limit; uint8_t *ssdt_ptr; - Aml *ssdt, *sb_scope; + Aml *ssdt, *sb_scope, *scope, *pkg; int i; ssdt = init_aml_allocator(); @@ -936,15 +936,6 @@ build_ssdt(GArray *table_data, GArray *linker, /* Copy header and patch values in the S3_ / S4_ / S5_ packages */ ssdt_ptr = acpi_data_push(ssdt->buf, 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'; - } - 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; - } patch_pci_windows(pci, ssdt_ptr, sizeof(ssdp_misc_aml)); @@ -954,6 +945,35 @@ build_ssdt(GArray *table_data, GArray *linker, ACPI_BUILD_SET_LE(ssdt_ptr, sizeof(ssdp_misc_aml), ssdt_mctrl_nr_slots[0], 32, nr_mem); + /* 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)); + } + + 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)); + } + + 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); + sb_scope = aml_scope("_SB"); { /* build Processor object for each processor */ diff --git a/hw/i386/ssdt-misc.dsl b/hw/i386/ssdt-misc.dsl index 1e3baaed3d..26b9241544 100644 --- a/hw/i386/ssdt-misc.dsl +++ b/hw/i386/ssdt-misc.dsl @@ -41,39 +41,6 @@ DefinitionBlock ("ssdt-misc.aml", "SSDT", 0x01, "BXPC", "BXSSDTSUSP", 0x1) } -/**************************************************************** - * 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) From 04b8da543dd16afaea014032939db4cb54b15459 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 18 Feb 2015 19:14:30 +0000 Subject: [PATCH 073/130] acpi: add aml_buffer() term Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/aml-build.c | 7 +++++++ include/hw/acpi/aml-build.h | 1 + 2 files changed, 8 insertions(+) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index fdeeacc993..98b1540bbb 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -506,6 +506,13 @@ Aml *aml_device(const char *name_format, ...) 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) { diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index 92097b5945..5fe66c68da 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -79,6 +79,7 @@ Aml *aml_device(const char *name_format, ...) GCC_FMT_ATTR(1, 2); Aml *aml_method(const char *name, int arg_count); Aml *aml_if(Aml *predicate); Aml *aml_package(uint8_t num_elements); +Aml *aml_buffer(void); /* other helpers */ GArray *build_alloc_array(void); From ad4a80bc6f4aa7ce8e67e924574521f04b8b19a4 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 18 Feb 2015 19:14:31 +0000 Subject: [PATCH 074/130] acpi: add aml_resource_template() helper Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/aml-build.c | 8 ++++++++ include/hw/acpi/aml-build.h | 1 + 2 files changed, 9 insertions(+) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index 98b1540bbb..070ca81110 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -506,6 +506,14 @@ Aml *aml_device(const char *name_format, ...) 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) { diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index 5fe66c68da..2810b4c43f 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -80,6 +80,7 @@ Aml *aml_method(const char *name, int arg_count); Aml *aml_if(Aml *predicate); Aml *aml_package(uint8_t num_elements); Aml *aml_buffer(void); +Aml *aml_resource_template(void); /* other helpers */ GArray *build_alloc_array(void); From 52fa397c58667080979e8aa64177c0f69b1851b7 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 18 Feb 2015 19:14:32 +0000 Subject: [PATCH 075/130] acpi: add aml_io() helper Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/aml-build.c | 16 ++++++++++++++++ include/hw/acpi/aml-build.h | 7 +++++++ 2 files changed, 23 insertions(+) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index 070ca81110..d7edda1097 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -478,6 +478,22 @@ Aml *aml_call4(const char *method, Aml *arg1, Aml *arg2, Aml *arg3, Aml *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: 16.2.5.3 Type 1 Opcodes Encoding: DefIfElse */ Aml *aml_if(Aml *predicate) { diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index 2810b4c43f..298e2ef3b1 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -23,6 +23,11 @@ struct Aml { }; typedef struct Aml Aml; +typedef enum { + aml_decode10 = 0, + aml_decode16 = 1, +} AmlIODecode; + /** * init_aml_allocator: * @@ -72,6 +77,8 @@ Aml *aml_call1(const char *method, Aml *arg1); Aml *aml_call2(const char *method, Aml *arg1, Aml *arg2); Aml *aml_call3(const char *method, Aml *arg1, Aml *arg2, Aml *arg3); Aml *aml_call4(const char *method, Aml *arg1, Aml *arg2, Aml *arg3, Aml *arg4); +Aml *aml_io(AmlIODecode dec, uint16_t min_base, uint16_t max_base, + uint8_t aln, uint8_t len); /* Block AML object primitives */ Aml *aml_scope(const char *name_format, ...) GCC_FMT_ATTR(1, 2); From 19fff2d405d3bcc88fd7b860ec47797b3f7af977 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 18 Feb 2015 19:14:33 +0000 Subject: [PATCH 076/130] acpi: include PkgLength size only when requested Named/Reserved{Field} definition uses PkgLength [1] encoding to specify field length, however it doesn't include size of PkgLength field itself, while other block objects that have explicit length of its body account for PkgLength size while encoding it [2]. This special casing isn't mentioned in ACPI spec, but that's what 'iasl' compiles NamedField to so add extra argument to build_prepend_pkg_length() to allow it handle the case. -- 1. ACPI Spec 5.0, 20.2.5.2 Named Objects Encoding, page 822 2. ACPI Spec 5.0, 5.4 Definition Block Encoding Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/aml-build.c | 20 +++++++++++++++----- include/hw/acpi/aml-build.h | 3 ++- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index d7edda1097..cc883ccb95 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -158,10 +158,10 @@ enum { PACKAGE_LENGTH_4BYTE_SHIFT = 20, }; -void build_prepend_package_length(GArray *package) +void +build_prepend_package_length(GArray *package, unsigned length, bool incl_self) { uint8_t byte; - unsigned length = package->len; unsigned length_bytes; if (length + 1 < (1 << PACKAGE_LENGTH_1BYTE_SHIFT)) { @@ -174,8 +174,18 @@ void build_prepend_package_length(GArray *package) length_bytes = 4; } - /* PkgLength is the length of the inclusive length of the data. */ - length += length_bytes; + /* + * 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: @@ -208,7 +218,7 @@ void build_prepend_package_length(GArray *package) void build_package(GArray *package, uint8_t op) { - build_prepend_package_length(package); + build_prepend_package_length(package, package->len, true); build_prepend_byte(package, op); } diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index 298e2ef3b1..b7f491ef02 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -99,7 +99,8 @@ void build_append_array(GArray *array, GArray *val); void GCC_FMT_ATTR(2, 3) build_append_namestring(GArray *array, const char *format, ...); -void build_prepend_package_length(GArray *package); +void +build_prepend_package_length(GArray *package, unsigned length, bool incl_self); void build_package(GArray *package, uint8_t op); void build_append_int(GArray *table, uint64_t value); void build_extop_package(GArray *package, uint8_t op); From 31127938f496f56eb05dc407a31e4c5941fb436a Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 18 Feb 2015 19:14:34 +0000 Subject: [PATCH 077/130] acpi: add aml_operation_region() term Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/aml-build.c | 14 ++++++++++++++ include/hw/acpi/aml-build.h | 7 +++++++ 2 files changed, 21 insertions(+) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index cc883ccb95..d72d5b45c8 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -554,3 +554,17 @@ Aml *aml_package(uint8_t num_elements) 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; +} diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index b7f491ef02..57926e5b7f 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -28,6 +28,11 @@ typedef enum { aml_decode16 = 1, } AmlIODecode; +typedef enum { + aml_system_memory = 0x00, + aml_system_io = 0x01, +} AmlRegionSpace; + /** * init_aml_allocator: * @@ -79,6 +84,8 @@ Aml *aml_call3(const char *method, Aml *arg1, Aml *arg2, Aml *arg3); Aml *aml_call4(const char *method, Aml *arg1, Aml *arg2, Aml *arg3, Aml *arg4); Aml *aml_io(AmlIODecode dec, uint16_t min_base, uint16_t max_base, uint8_t aln, uint8_t len); +Aml *aml_operation_region(const char *name, AmlRegionSpace rs, + uint32_t offset, uint32_t len); /* Block AML object primitives */ Aml *aml_scope(const char *name_format, ...) GCC_FMT_ATTR(1, 2); From 214ae59f8e1c33db0f3fbbc4347bb3dacc6ce876 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 18 Feb 2015 19:14:35 +0000 Subject: [PATCH 078/130] acpi: add aml_field() & aml_named_field() terms Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/aml-build.c | 28 ++++++++++++++++++++++++++++ include/hw/acpi/aml-build.h | 6 ++++++ 2 files changed, 34 insertions(+) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index d72d5b45c8..b91141e320 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -216,6 +216,16 @@ build_prepend_package_length(GArray *package, unsigned length, bool incl_self) 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); +} + void build_package(GArray *package, uint8_t op) { build_prepend_package_length(package, package->len, true); @@ -568,3 +578,21 @@ Aml *aml_operation_region(const char *name, AmlRegionSpace rs, 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: 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; +} diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index 57926e5b7f..2bb5f3938c 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -28,6 +28,10 @@ typedef enum { aml_decode16 = 1, } AmlIODecode; +typedef enum { + aml_byte_acc = 1, +} AmlFieldFlags; + typedef enum { aml_system_memory = 0x00, aml_system_io = 0x01, @@ -86,6 +90,7 @@ Aml *aml_io(AmlIODecode dec, uint16_t min_base, uint16_t max_base, uint8_t aln, uint8_t len); Aml *aml_operation_region(const char *name, AmlRegionSpace rs, uint32_t offset, uint32_t len); +Aml *aml_named_field(const char *name, unsigned length); /* Block AML object primitives */ Aml *aml_scope(const char *name_format, ...) GCC_FMT_ATTR(1, 2); @@ -95,6 +100,7 @@ Aml *aml_if(Aml *predicate); Aml *aml_package(uint8_t num_elements); Aml *aml_buffer(void); Aml *aml_resource_template(void); +Aml *aml_field(const char *name, AmlFieldFlags flags); /* other helpers */ GArray *build_alloc_array(void); From b8a5d6894d94c8f7e815c64adff78b0d28a98ca6 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 18 Feb 2015 19:14:36 +0000 Subject: [PATCH 079/130] acpi: add aml_local() term Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/aml-build.c | 11 +++++++++++ include/hw/acpi/aml-build.h | 1 + 2 files changed, 12 insertions(+) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index b91141e320..fabd0adf28 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -596,3 +596,14 @@ Aml *aml_field(const char *name, AmlFieldFlags flags) build_append_byte(var->buf, flags); 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; +} diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index 2bb5f3938c..de081d6805 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -91,6 +91,7 @@ Aml *aml_io(AmlIODecode dec, uint16_t min_base, uint16_t max_base, Aml *aml_operation_region(const char *name, AmlRegionSpace rs, uint32_t offset, uint32_t len); Aml *aml_named_field(const char *name, unsigned length); +Aml *aml_local(int num); /* Block AML object primitives */ Aml *aml_scope(const char *name_format, ...) GCC_FMT_ATTR(1, 2); From d5e5830f56452d857f9c26c06a886f09056482c1 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 18 Feb 2015 19:14:37 +0000 Subject: [PATCH 080/130] acpi: add aml_string() term Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/aml-build.c | 25 +++++++++++++++++++++++++ include/hw/acpi/aml-build.h | 1 + 2 files changed, 26 insertions(+) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index fabd0adf28..57a65dd695 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -597,6 +597,31 @@ Aml *aml_field(const char *name, AmlFieldFlags 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) { diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index de081d6805..b1eab3c126 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -92,6 +92,7 @@ Aml *aml_operation_region(const char *name, AmlRegionSpace rs, uint32_t offset, uint32_t len); Aml *aml_named_field(const char *name, unsigned length); Aml *aml_local(int num); +Aml *aml_string(const char *name_format, ...) GCC_FMT_ATTR(1, 2); /* Block AML object primitives */ Aml *aml_scope(const char *name_format, ...) GCC_FMT_ATTR(1, 2); From cd61cb2e2c02c5c257a15a52b3d0616474e52997 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 18 Feb 2015 19:14:38 +0000 Subject: [PATCH 081/130] pc: acpi-build: generate pvpanic device description dynamically Drops AML template patching and allows to save some space in SSDT if pvpanic device doesn't exist by not including disabled device description into SSDT. It also makes device description smaller by replacing _STA method with named value and dropping _INI method. Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/acpi-build.c | 36 +++++++++++++++++++++++++++++---- hw/i386/ssdt-misc.dsl | 47 ------------------------------------------- 2 files changed, 32 insertions(+), 51 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 4536fba0ab..2c581ef717 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -924,7 +924,7 @@ build_ssdt(GArray *table_data, GArray *linker, uint32_t nr_mem = machine->ram_slots; unsigned acpi_cpus = guest_info->apic_id_limit; uint8_t *ssdt_ptr; - Aml *ssdt, *sb_scope, *scope, *pkg; + Aml *ssdt, *sb_scope, *scope, *pkg, *dev, *method, *crs, *field; int i; ssdt = init_aml_allocator(); @@ -939,9 +939,6 @@ build_ssdt(GArray *table_data, GArray *linker, patch_pci_windows(pci, ssdt_ptr, sizeof(ssdp_misc_aml)); - ACPI_BUILD_SET_LE(ssdt_ptr, sizeof(ssdp_misc_aml), - ssdt_isa_pest[0], 16, misc->pvpanic_port); - ACPI_BUILD_SET_LE(ssdt_ptr, sizeof(ssdp_misc_aml), ssdt_mctrl_nr_slots[0], 32, nr_mem); @@ -974,6 +971,37 @@ build_ssdt(GArray *table_data, GArray *linker, aml_append(scope, aml_name_decl("_S5", pkg)); aml_append(ssdt, scope); + if (misc->pvpanic_port) { + scope = aml_scope("\\_SB.PCI0.ISA"); + + 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)); + + 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"); { /* build Processor object for each processor */ diff --git a/hw/i386/ssdt-misc.dsl b/hw/i386/ssdt-misc.dsl index 26b9241544..81be858b85 100644 --- a/hw/i386/ssdt-misc.dsl +++ b/hw/i386/ssdt-misc.dsl @@ -39,51 +39,4 @@ DefinitionBlock ("ssdt-misc.aml", "SSDT", 0x01, "BXPC", "BXSSDTSUSP", 0x1) ACPI_EXTRACT_NAME_DWORD_CONST ssdt_mctrl_nr_slots Name(MEMORY_SLOTS_NUMBER, 0x12345678) } - - - 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) - } - } - } } From a678508e46ac806d81bd401a483aef1b98734ae4 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 18 Feb 2015 19:14:39 +0000 Subject: [PATCH 082/130] acpi: add aml_varpackage() term Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/aml-build.c | 8 ++++++++ include/hw/acpi/aml-build.h | 1 + 2 files changed, 9 insertions(+) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index 57a65dd695..36aafe4bfb 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -632,3 +632,11 @@ Aml *aml_local(int num) 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; +} diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index b1eab3c126..7f3886fc8f 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -103,6 +103,7 @@ Aml *aml_package(uint8_t num_elements); Aml *aml_buffer(void); Aml *aml_resource_template(void); Aml *aml_field(const char *name, AmlFieldFlags flags); +Aml *aml_varpackage(uint32_t num_elements); /* other helpers */ GArray *build_alloc_array(void); From 15e44e56d7da9d4569c10aa8de5f109a71570670 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 18 Feb 2015 19:14:40 +0000 Subject: [PATCH 083/130] acpi: add aml_equal() term Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/aml-build.c | 10 ++++++++++ include/hw/acpi/aml-build.h | 1 + 2 files changed, 11 insertions(+) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index 36aafe4bfb..97b027c380 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -514,6 +514,16 @@ Aml *aml_io(AmlIODecode dec, uint16_t min_base, uint16_t max_base, 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) { diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index 7f3886fc8f..5e2b43498b 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -93,6 +93,7 @@ Aml *aml_operation_region(const char *name, AmlRegionSpace rs, Aml *aml_named_field(const char *name, unsigned length); Aml *aml_local(int num); Aml *aml_string(const char *name_format, ...) GCC_FMT_ATTR(1, 2); +Aml *aml_equal(Aml *arg1, Aml *arg2); /* Block AML object primitives */ Aml *aml_scope(const char *name_format, ...) GCC_FMT_ATTR(1, 2); From 3dd156435369153c1c1d890b9ef525f1d033a971 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 18 Feb 2015 19:14:41 +0000 Subject: [PATCH 084/130] acpi: add aml_processor() term Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/aml-build.c | 15 +++++++++++++++ include/hw/acpi/aml-build.h | 2 ++ 2 files changed, 17 insertions(+) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index 97b027c380..9081b49358 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -650,3 +650,18 @@ Aml *aml_varpackage(uint32_t num_elements) 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; +} diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index 5e2b43498b..58bbbfead1 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -94,6 +94,8 @@ Aml *aml_named_field(const char *name, unsigned length); Aml *aml_local(int num); Aml *aml_string(const char *name_format, ...) GCC_FMT_ATTR(1, 2); Aml *aml_equal(Aml *arg1, Aml *arg2); +Aml *aml_processor(uint8_t proc_id, uint32_t pblk_addr, uint8_t pblk_len, + const char *name_format, ...) GCC_FMT_ATTR(4, 5); /* Block AML object primitives */ Aml *aml_scope(const char *name_format, ...) GCC_FMT_ATTR(1, 2); From a7891dacadebb9c02e027c456a1d17ea0bdf6df8 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 18 Feb 2015 19:14:42 +0000 Subject: [PATCH 085/130] acpi: add aml_eisaid() term Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/aml-build.c | 29 +++++++++++++++++++++++++++++ include/hw/acpi/aml-build.h | 1 + 2 files changed, 30 insertions(+) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index 9081b49358..eeb006f416 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -665,3 +665,32 @@ Aml *aml_processor(uint8_t proc_id, uint32_t pblk_addr, uint8_t pblk_len, 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; +} diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index 58bbbfead1..bf94155316 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -96,6 +96,7 @@ Aml *aml_string(const char *name_format, ...) GCC_FMT_ATTR(1, 2); Aml *aml_equal(Aml *arg1, Aml *arg2); Aml *aml_processor(uint8_t proc_id, uint32_t pblk_addr, uint8_t pblk_len, const char *name_format, ...) GCC_FMT_ATTR(4, 5); +Aml *aml_eisaid(const char *str); /* Block AML object primitives */ Aml *aml_scope(const char *name_format, ...) GCC_FMT_ATTR(1, 2); From 20843d16632c4da3d3d35ddc8d5eb047167693ce Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 18 Feb 2015 19:14:43 +0000 Subject: [PATCH 086/130] pc: acpi-build: drop template patching and CPU hotplug objects dynamically in addition it saves us ~400LOC and makes it one binary blob less stored in QEMU source tree by removing need to keep and update hw/i386/ssdt-proc.hex.generated file there. Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/Makefile.objs | 7 ++-- hw/i386/acpi-build.c | 90 ++++++++++++++++++++----------------------- hw/i386/ssdt-proc.dsl | 63 ------------------------------ 3 files changed, 46 insertions(+), 114 deletions(-) delete mode 100644 hw/i386/ssdt-proc.dsl diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs index 2b678ef2a6..c9af7bac3e 100644 --- a/hw/i386/Makefile.objs +++ b/hw/i386/Makefile.objs @@ -7,10 +7,11 @@ 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-pcihp.hex \ + hw/i386/ssdt-misc.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 2c581ef717..c6910dac9a 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -522,15 +522,6 @@ static inline char acpi_get_hex(uint32_t val) 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) @@ -924,7 +915,7 @@ build_ssdt(GArray *table_data, GArray *linker, uint32_t nr_mem = machine->ram_slots; unsigned acpi_cpus = guest_info->apic_id_limit; uint8_t *ssdt_ptr; - Aml *ssdt, *sb_scope, *scope, *pkg, *dev, *method, *crs, *field; + Aml *ssdt, *sb_scope, *scope, *pkg, *dev, *method, *crs, *field, *ifctx; int i; ssdt = init_aml_allocator(); @@ -1006,51 +997,54 @@ build_ssdt(GArray *table_data, GArray *linker, { /* build Processor object for each processor */ for (i = 0; i < acpi_cpus; i++) { - uint8_t *proc = acpi_data_push(sb_scope->buf, 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->buf, "NTFY", - "CP%0.02X", acpi_cpus); - - /* build "Name(CPON, Package() { One, One, ..., Zero, Zero, ... })" */ - build_append_byte(sb_scope->buf, 0x08); /* NameOp */ - build_append_namestring(sb_scope->buf, "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); - build_append_array(sb_scope->buf, 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 + * ntroduced 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); + + 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)); if (nr_mem) { assert(nr_mem <= ACPI_MAX_RAM_SLOTS); 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 . - */ - -/* 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) - } - } -} From ddf1ec2ffe30bd6bb34acc020622741eafc16b79 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 18 Feb 2015 19:14:44 +0000 Subject: [PATCH 087/130] pc: acpi-build: create CPU hotplug IO region dynamically it replaces a static complied in DSDT MMIO region for CPU hotplug with one created at runtime leaving only truly static CPU hotplug related ASL bits in DSDT. It also puts CPU_HOTPLUG_RESOURCE_DEVICE into PCI0 scope and reserves resources from it, preparing for dropping manual hole punching in PCI0._CRS. Later it also would make easier to reuse current ACPI CPU hotplug on other targets. Also later it would be possible to move remaining CPU hotplug ASL methods into build_ssdt() and add all CPU hotplug related AML into SSDT only when CPU hotplug is enabled, further reducing ACPI tables blob if CPU hotplug isn't used. impl. detail: Windows XP can't handle /BSODs/ OperationRegion declaration in DSDT when variable from SSDT is used for specifying its address/length and also when Field declared in DSDT with OperationRegion from SSDT if DSDT is being parsed before SSDT. But it works just fine when referencing named fields from another table. Hence OperationRegion and Field declaration are moved to SSDT to make XP based editions work. PS: Later Windows editions seem to be fine with above conditions. Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/acpi-build.c | 27 +++++++++++++++++++++++++++ hw/i386/acpi-dsdt-cpu-hotplug.dsl | 17 +---------------- include/hw/acpi/pc-hotplug.h | 1 + 3 files changed, 29 insertions(+), 16 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index c6910dac9a..4f1c251d8d 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -101,6 +101,8 @@ 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; } AcpiPmInfo; typedef struct AcpiMiscInfo { @@ -176,12 +178,15 @@ static void acpi_get_pm_info(AcpiPmInfo *pm) if (piix) { obj = piix; + pm->cpu_hp_io_base = PIIX4_CPU_HOTPLUG_IO_BASE; } 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; /* Fill in optional s3/s4 related properties */ o = object_property_get_qobject(obj, ACPI_PM_PROP_S3_DISABLED, NULL); if (o) { @@ -995,6 +1000,28 @@ build_ssdt(GArray *table_data, GArray *linker, 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++) { dev = aml_processor(i, 0, 0, "CP%.02X", i); 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/include/hw/acpi/pc-hotplug.h b/include/hw/acpi/pc-hotplug.h index b9db29576c..efa6ed7b7b 100644 --- a/include/hw/acpi/pc-hotplug.h +++ b/include/hw/acpi/pc-hotplug.h @@ -28,6 +28,7 @@ #define ICH9_CPU_HOTPLUG_IO_BASE 0x0CD8 #define PIIX4_CPU_HOTPLUG_IO_BASE 0xaf00 +#define CPU_HOTPLUG_RESOURCE_DEVICE PRES #define ACPI_MEMORY_HOTPLUG_IO_LEN 24 #define ACPI_MEMORY_HOTPLUG_BASE 0x0a00 From e2ea299b01fbd9d4d0262cfbfcbdbd02ada984a5 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 18 Feb 2015 19:14:45 +0000 Subject: [PATCH 088/130] acpi: add aml_reserved_field() term Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/aml-build.c | 10 ++++++++++ include/hw/acpi/aml-build.h | 6 ++++++ 2 files changed, 16 insertions(+) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index eeb006f416..9d9b978e13 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -598,6 +598,16 @@ Aml *aml_named_field(const char *name, unsigned length) 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) { diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index bf94155316..ea3ece316b 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -29,7 +29,12 @@ typedef enum { } AmlIODecode; typedef enum { + aml_any_acc = 0, aml_byte_acc = 1, + aml_word_acc = 2, + aml_dword_acc = 3, + aml_qword_acc = 4, + aml_buffer_acc = 5, } AmlFieldFlags; typedef enum { @@ -91,6 +96,7 @@ Aml *aml_io(AmlIODecode dec, uint16_t min_base, uint16_t max_base, Aml *aml_operation_region(const char *name, AmlRegionSpace rs, uint32_t offset, uint32_t len); Aml *aml_named_field(const char *name, unsigned length); +Aml *aml_reserved_field(unsigned length); Aml *aml_local(int num); Aml *aml_string(const char *name_format, ...) GCC_FMT_ATTR(1, 2); Aml *aml_equal(Aml *arg1, Aml *arg2); From 8698c0c0ed1ff3751ef91b61c0006620d5431be4 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 18 Feb 2015 19:14:46 +0000 Subject: [PATCH 089/130] pc: acpi-build: drop template patching and memory hotplug objects dynamically in addition it saves us ~330LOC and makes it one binary blob less stored in QEMU source tree by removing need to keep and update hw/i386/ssdt-mem.hex.generated file there. Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/Makefile.objs | 1 - hw/i386/acpi-build.c | 110 +++++++++++++++++------------------------- hw/i386/ssdt-mem.dsl | 77 ----------------------------- 3 files changed, 45 insertions(+), 143 deletions(-) delete mode 100644 hw/i386/ssdt-mem.dsl diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs index c9af7bac3e..45b90a8374 100644 --- a/hw/i386/Makefile.objs +++ b/hw/i386/Makefile.objs @@ -11,7 +11,6 @@ hw/i386/acpi-build.o: hw/i386/acpi-build.c \ hw/i386/acpi-dsdt.hex hw/i386/q35-acpi-dsdt.hex \ hw/i386/ssdt-pcihp.hex \ hw/i386/ssdt-misc.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 4f1c251d8d..377dd72ea6 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -307,28 +307,6 @@ static void build_append_and_cleanup_method(GArray *device, GArray *method) build_free_array(method); } -static void build_append_notify_target_ifequal(GArray *method, - GArray *target_name, - uint32_t value) -{ - GArray *notify = build_alloc_array(); - uint8_t op = 0xA0; /* IfOp */ - - build_append_byte(notify, 0x93); /* LEqualOp */ - build_append_byte(notify, 0x68); /* Arg0Op */ - build_append_int(notify, value); - 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); - - build_append_array(method, notify); - - build_free_array(notify); -} - /* End here */ #define ACPI_PORT_SMI_CMD 0x00b2 /* TODO: this is APM_CNT_IOPORT */ @@ -550,14 +528,6 @@ static inline char acpi_get_hex(uint32_t val) #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 @@ -565,24 +535,6 @@ static inline char acpi_get_hex(uint32_t val) #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_namestring(target, format, i); - assert(i < 256); /* Fits in 1 byte */ - build_append_notify_target_ifequal(method, target, i); - 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); @@ -1073,27 +1025,55 @@ build_ssdt(GArray *table_data, GArray *linker, } aml_append(sb_scope, aml_name_decl("CPON", pkg)); - 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->buf, ACPI_MEM_SIZEOF); + /* build memory devices */ + assert(nr_mem <= ACPI_MAX_RAM_SLOTS); - 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 < nr_mem; i++) { + #define BASEPATH "\\_SB.PCI0." stringify(MEMORY_HOTPLUG_DEVICE) "." + const char *s; - /* build Method(MEMORY_SLOT_NOTIFY_METHOD, 2) { - * If (LEqual(Arg0, 0x00)) {Notify(MP00, Arg1)} ... - */ - build_append_notify_method(sb_scope->buf, - stringify(MEMORY_SLOT_NOTIFY_METHOD), - "MP%0.02X", nr_mem); + 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)} ... + */ + 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; 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 - */ - -/* 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) - } - } - } -} From 2c6b94d84e3677a40905c42604cf4cd4ef6f3a8e Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 18 Feb 2015 19:14:47 +0000 Subject: [PATCH 090/130] pc: acpi-build: create memory hotplug IO region dynamically it replaces a static complied in DSDT MMIO region for memory hotplug with one created at runtime leaving only truly static memory hotplug related ASL bits in DSDT. And replaces template patching of MEMORY_SLOTS_NUMBER value with ASL API created named value. Later it also would make easier to reuse current ACPI memory hotplug on other targets. Also later it would be possible to move remaining memory hotplug ASL methods into build_ssdt() and add all memory hotplug related AML into SSDT only when memory hotplug is enabled, further reducing ACPI tables blob if memory hotplug isn't used. Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/acpi-build.c | 57 +++++++++++++++++++++++++++++-- hw/i386/acpi-dsdt-mem-hotplug.dsl | 36 ++++++------------- hw/i386/ssdt-misc.dsl | 2 -- 3 files changed, 64 insertions(+), 31 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 377dd72ea6..98553f8acb 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -103,6 +103,8 @@ typedef struct AcpiPmInfo { 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; } AcpiPmInfo; typedef struct AcpiMiscInfo { @@ -187,6 +189,9 @@ static void acpi_get_pm_info(AcpiPmInfo *pm) 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) { @@ -887,9 +892,6 @@ build_ssdt(GArray *table_data, GArray *linker, patch_pci_windows(pci, ssdt_ptr, sizeof(ssdp_misc_aml)); - ACPI_BUILD_SET_LE(ssdt_ptr, sizeof(ssdp_misc_aml), - ssdt_mctrl_nr_slots[0], 32, nr_mem); - /* create S3_ / S4_ / S5_ packages if necessary */ scope = aml_scope("\\"); if (!pm->s3_disabled) { @@ -1027,6 +1029,55 @@ build_ssdt(GArray *table_data, GArray *linker, /* 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) "." 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/ssdt-misc.dsl b/hw/i386/ssdt-misc.dsl index 81be858b85..2588e30e19 100644 --- a/hw/i386/ssdt-misc.dsl +++ b/hw/i386/ssdt-misc.dsl @@ -36,7 +36,5 @@ DefinitionBlock ("ssdt-misc.aml", "SSDT", 0x01, "BXPC", "BXSSDTSUSP", 0x1) 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) } } From 6ece7053d6a4a502d2ea5d24ecf512caaa1437c7 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 18 Feb 2015 19:14:48 +0000 Subject: [PATCH 091/130] acpi: add aml_word_bus_number(), aml_word_io(), aml_dword_memory(), aml_qword_memory() terms Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/aml-build.c | 161 ++++++++++++++++++++++++++++++++++++ include/hw/acpi/aml-build.h | 72 ++++++++++++++++ 2 files changed, 233 insertions(+) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index 9d9b978e13..d793775d93 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -704,3 +704,164 @@ Aml *aml_eisaid(const char *str) 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/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index ea3ece316b..d2b2c354fa 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -42,6 +42,57 @@ typedef enum { aml_system_io = 0x01, } AmlRegionSpace; +typedef enum { + aml_memory_range = 0, + aml_io_range = 1, + aml_bus_number_range = 2, +} AmlResourceType; + +typedef enum { + aml_sub_decode = 1 << 1, + aml_pos_decode = 0 +} AmlDecode; + +typedef enum { + aml_max_fixed = 1 << 3, + aml_max_not_fixed = 0, +} AmlMaxFixed; + +typedef enum { + aml_min_fixed = 1 << 2, + aml_min_not_fixed = 0 +} AmlMinFixed; + +/* + * ACPI 1.0b: Table 6-26 I/O Resource Flag (Resource Type = 1) Definitions + * _RNG field definition + */ +typedef enum { + aml_isa_only = 1, + aml_non_isa_only = 2, + aml_entire_range = 3, +} AmlISARanges; + +/* + * ACPI 1.0b: Table 6-25 Memory Resource Flag (Resource Type = 0) Definitions + * _MEM field definition + */ +typedef enum { + aml_non_cacheable = 0, + aml_cacheable = 1, + aml_write_combining = 2, + aml_prefetchable = 3, +} AmlCacheble; + +/* + * ACPI 1.0b: Table 6-25 Memory Resource Flag (Resource Type = 0) Definitions + * _RW field definition + */ +typedef enum { + aml_ReadOnly = 0, + aml_ReadWrite = 1, +} AmlReadAndWrite; + /** * init_aml_allocator: * @@ -103,6 +154,27 @@ Aml *aml_equal(Aml *arg1, Aml *arg2); Aml *aml_processor(uint8_t proc_id, uint32_t pblk_addr, uint8_t pblk_len, const char *name_format, ...) GCC_FMT_ATTR(4, 5); Aml *aml_eisaid(const char *str); +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); +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); +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); +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); /* Block AML object primitives */ Aml *aml_scope(const char *name_format, ...) GCC_FMT_ATTR(1, 2); From 78c2d8722b9118509e3d4ed8bae67c3e4eaa443e Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 18 Feb 2015 19:14:49 +0000 Subject: [PATCH 092/130] pc: pcihp: expose MMIO base and len as properties it will be used later to dynamically reserve MMIO region instead of manually punching holes in PCI0._CRS Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/pcihp.c | 18 ++++++++++++------ hw/acpi/piix4.c | 2 +- include/hw/acpi/pcihp.h | 7 ++++++- 3 files changed, 19 insertions(+), 8 deletions(-) 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 766f1b8552..d1f11793a0 100644 --- a/hw/acpi/piix4.c +++ b/hw/acpi/piix4.c @@ -562,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, diff --git a/include/hw/acpi/pcihp.h b/include/hw/acpi/pcihp.h index 9323838319..f3526d4aaf 100644 --- a/include/hw/acpi/pcihp.h +++ b/include/hw/acpi/pcihp.h @@ -32,6 +32,9 @@ #include "hw/acpi/acpi.h" #include "migration/vmstate.h" +#define ACPI_PCIHP_IO_BASE_PROP "acpi-pcihp-io-base" +#define ACPI_PCIHP_IO_LEN_PROP "acpi-pcihp-io-len" + typedef struct AcpiPciHpPciStatus { uint32_t up; uint32_t down; @@ -48,9 +51,11 @@ typedef struct AcpiPciHpState { PCIBus *root; MemoryRegion io; bool legacy_piix; + uint16_t io_base; + uint16_t io_len; } AcpiPciHpState; -void acpi_pcihp_init(AcpiPciHpState *, PCIBus *root, +void acpi_pcihp_init(Object *owner, AcpiPciHpState *, PCIBus *root, MemoryRegion *address_space_io, bool bridges_enabled); void acpi_pcihp_device_plug_cb(ACPIREGS *ar, qemu_irq irq, AcpiPciHpState *s, From 500b11ea5095ae77da5ddd6dd12f6c485b516a91 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 18 Feb 2015 19:14:50 +0000 Subject: [PATCH 093/130] pc: acpi-build: reserve PCIHP MMIO resources Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/acpi-build.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 98553f8acb..4d5d7e3d18 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -105,6 +105,8 @@ typedef struct AcpiPmInfo { 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 { @@ -178,9 +180,15 @@ 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; @@ -892,6 +900,25 @@ build_ssdt(GArray *table_data, GArray *linker, patch_pci_windows(pci, ssdt_ptr, sizeof(ssdp_misc_aml)); + scope = aml_scope("\\_SB.PCI0"); + /* 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) { From 7ff3bc2e112514f001cb24f3ec16bda8ba7826fc Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Wed, 18 Feb 2015 21:43:48 +0100 Subject: [PATCH 094/130] acpi: update generated hex files Used for IASL builds. Signed-off-by: Michael S. Tsirkin --- hw/i386/acpi-dsdt.hex.generated | 224 +---------------------- hw/i386/q35-acpi-dsdt.hex.generated | 224 +---------------------- hw/i386/ssdt-misc.hex.generated | 274 +--------------------------- 3 files changed, 25 insertions(+), 697 deletions(-) diff --git a/hw/i386/acpi-dsdt.hex.generated b/hw/i386/acpi-dsdt.hex.generated index 498b194a0c..a71e0cd1d8 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, +0x57, +0xd, 0x0, 0x0, 0x1, -0x6c, +0x26, 0x42, 0x58, 0x50, @@ -2318,8 +2318,8 @@ static unsigned char AcpiDsdtAmlCode[] = { 0x53, 0x1, 0x10, -0x4f, -0x12, +0x4d, +0xc, 0x5f, 0x53, 0x42, @@ -2416,32 +2416,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 +2523,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 +2537,8 @@ static unsigned char AcpiDsdtAmlCode[] = { 0x30, 0x5b, 0x82, -0x43, -0x30, +0x47, +0x29, 0x4d, 0x48, 0x50, @@ -2686,37 +2588,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 +2609,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, diff --git a/hw/i386/q35-acpi-dsdt.hex.generated b/hw/i386/q35-acpi-dsdt.hex.generated index 0d5b133150..28769d4753 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, +0x45, +0x1f, 0x0, 0x0, 0x1, -0x0, +0x59, 0x42, 0x58, 0x50, @@ -6959,8 +6959,8 @@ static unsigned char Q35AcpiDsdtAmlCode[] = { 0x53, 0x1, 0x10, -0x4f, -0x12, +0x4d, +0xc, 0x5f, 0x53, 0x42, @@ -7057,32 +7057,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 +7164,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 +7178,8 @@ static unsigned char Q35AcpiDsdtAmlCode[] = { 0x30, 0x5b, 0x82, -0x43, -0x30, +0x47, +0x29, 0x4d, 0x48, 0x50, @@ -7327,37 +7229,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 +7250,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, diff --git a/hw/i386/ssdt-misc.hex.generated b/hw/i386/ssdt-misc.hex.generated index cbcf61dcce..0b77ed443d 100644 --- a/hw/i386/ssdt-misc.hex.generated +++ b/hw/i386/ssdt-misc.hex.generated @@ -1,15 +1,6 @@ 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 }; @@ -21,12 +12,12 @@ static unsigned char ssdp_misc_aml[] = { 0x53, 0x44, 0x54, -0x6c, -0x1, +0x77, +0x0, 0x0, 0x0, 0x1, -0x3, +0x40, 0x42, 0x58, 0x50, @@ -49,12 +40,12 @@ static unsigned char ssdp_misc_aml[] = { 0x4e, 0x54, 0x4c, -0x28, -0x8, +0x7, +0x11, 0x14, 0x20, 0x10, -0x4c, +0x42, 0x5, 0x5c, 0x0, @@ -135,258 +126,7 @@ static unsigned char ssdp_misc_aml[] = { 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 +0x0 }; static unsigned char acpi_pci64_start[] = { 0x4d From dd6b6b0c833ec7333056c55dbb8e518241aceefd Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Wed, 18 Feb 2015 21:45:11 +0100 Subject: [PATCH 095/130] acpi: drop unused generated files drop ssdt-mem.hex.generated and ssdt-proc.hex.generated: dsl files have been removed previously. Signed-off-by: Michael S. Tsirkin --- hw/i386/ssdt-mem.hex.generated | 213 -------------------------------- hw/i386/ssdt-proc.hex.generated | 134 -------------------- 2 files changed, 347 deletions(-) delete mode 100644 hw/i386/ssdt-mem.hex.generated delete mode 100644 hw/i386/ssdt-proc.hex.generated 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-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 -}; From dc33c0293505db9c747a6e27487a808ab2b62a6f Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Wed, 18 Feb 2015 22:29:26 +0100 Subject: [PATCH 096/130] acpi-test: update expected files A bunch of code moved from dsdt to ssdt, plus we got trivial changes like 0->Zero which our test dosn't recognize as identity yet. Update expected files to suppress test warning. Signed-off-by: Michael S. Tsirkin --- tests/acpi-test-data/pc/DSDT | Bin 3621 -> 3415 bytes tests/acpi-test-data/pc/SSDT | Bin 2279 -> 2374 bytes tests/acpi-test-data/q35/DSDT | Bin 8211 -> 8005 bytes tests/acpi-test-data/q35/SSDT | Bin 560 -> 578 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/tests/acpi-test-data/pc/DSDT b/tests/acpi-test-data/pc/DSDT index 010d74603f09430d65fae1ce2a0d867c1964a1a8..ad12cb35d9dafc4d50002873f5c4ca04552b36df 100644 GIT binary patch delta 84 zcmZ1~b6twdCDi8%x9)$o`NRYiil^pgNOUO@r^O;jRxc4b#El^cxd5_CP=^wIgHN{ ztYC%o$#QlyZ9FM)v}mNt%FY6Z$L6f{iPIY^VeS7}*RV#$1fm%Wc!)Bv#zr*H#vqHR zyH3L}6uk}wjMFx>%7DbqgoK$GSV-*vu1Inlo0o#*jAiSFm|8$$fT`*a6e)ke zKd|x{{SD%V?L4l|J?E#t>M^aQSy2GeowI#%H9r{b&_t$r8vy3Nhtsq6!_kJ-1B*g& zr6XIsCJf^nL+z!Kol%@zbIy-}Vyul1P|PsSa^e^%Ui^Q8hK74qn+PV(DVJM|5-Rv= zRV)a*xkTd(G-XwW?b{p;nT#E$Q!8@a>o9gf>Ow%sGkiLUc`8fN2DWN=SI4VVHSx|` z|8d6d#}l~z#oJ(0Am=UyfGTM%gJwh|P}L(&APj608K?v%kvj;3({<@u(54Y=Jmf@R hJalv%_EU3y?=Ahsn8CY?f20Dlv@h$b-_rB8{{RBhShxTH diff --git a/tests/acpi-test-data/q35/DSDT b/tests/acpi-test-data/q35/DSDT index 8ac32efc0316daeed23e9002aa8bb05fb0fe483f..de430e2a68e203518384b1db75baaefc02f2aa33 100644 GIT binary patch delta 67 zcmbR2aMX^=CDn_;uM>>DNkc;^zx delta 292 zcmX?VH`#&9CD3oF>oW7nlzKY&}1X&1gYqTfS}+IM(!ItTnf>RJYWuxh<6Z} zJV`n`BD%?qB_PN(m?Pf9(}l&!E;gMg9poUx3BqJ^2T!vK-p5|R zgLw8Cd;*Vq0pG)9q6z%@e&PE*e)*_;R)~~A=9d7_`;zP-e|d05>(;QPq^|^v-DPpO z2zCwSPu)t(Jc%@vSVeI_y)RP5Y7hrCCI(J4xxc%eUpv#$Y%-r-jb?zA%sgUY#ZtLd zBjgmV>6#+v0rE$Y$_!a+N}Rl)8_=QJ_5Asm3DDw^ zfRJWh>>DWaZtC|Op8AoFo~e4e5*JE~Z*SV6O?W63;&CETUhMpi$x!$9!*d;yId+vB J!PPhF{s5KbTzCKg delta 357 zcmXX>J5Iwu5S@A8w8)@A6@QU$O?Llxx$LGl4O z13l-V#S=5t`;6Ya`S!j%VN7gg4}kqF#6G)T983gHOPN}SJ~D$H(QhzmxI7<+~fl0;AEY1Tonh4*c|&U6<~*7^<^ zJ9PlmzpO`_3ZhhOe{Q;yqSb6{e From a6027b0f4bb4d8c8f14ac5fd8cbf05f5f7c6a503 Mon Sep 17 00:00:00 2001 From: "Denis V. Lunev" Date: Thu, 29 Jan 2015 17:24:41 +0300 Subject: [PATCH 097/130] balloon: call qdev_alias_all_properties for proxy dev in balloon class init The idea is that all other virtio devices are calling this helper to merge properties of the proxy device. This is the only difference in between this helper and code in inside virtio_instance_init_common. The patch should not cause any harm as property list in generic balloon code is empty. This also allows to avoid some dummy errors like fixed by this commit 91ba21208839643603e7f7fa5864723c3f371ebe Author: Gonglei Date: Tue Sep 30 14:10:35 2014 +0800 virtio-balloon: fix virtio-balloon child refcount in transports Signed-off-by: Denis V. Lunev Signed-off-by: Raushaniya Maksudova Revieved-by: Cornelia Huck CC: Christian Borntraeger CC: Anthony Liguori CC: Michael S. Tsirkin Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/s390x/virtio-ccw.c | 5 ++--- hw/virtio/virtio-pci.c | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index 3fee4aa345..ffbb9c2c89 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -898,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/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index 6dd41b992f..e7baf7b5e8 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -1274,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); From 9fdc694635ebf275763aa2eee721f69e556fba5e Mon Sep 17 00:00:00 2001 From: Stefan Berger Date: Mon, 23 Feb 2015 09:27:16 -0500 Subject: [PATCH 098/130] tpm: Extend sts register to 32 bit More recent TIS specs extend the STS register to 32 bit. While we don't store the TIS interface state, yet, we can extend it without sideeffects. Signed-off-by: Stefan Berger Acked-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/tpm/tpm_tis.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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; From feeb755fde70e34dbec9709f3dab439172cf5153 Mon Sep 17 00:00:00 2001 From: Stefan Berger Date: Mon, 23 Feb 2015 09:27:17 -0500 Subject: [PATCH 099/130] tpm: Allow 32 & 16 bit accesses to the registers Improve the access to the registers with 32 and 16 bit reads and writes. Also enable access to a non-base register address, such as reads of the 2nd byte of a register. Map the FIFO byte access to any byte within its 4 byte register (following specs). Signed-off-by: Stefan Berger Acked-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/tpm/tpm_tis.c | 60 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 47 insertions(+), 13 deletions(-) diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c index c0e7cd738a..617069372f 100644 --- a/hw/tpm/tpm_tis.c +++ b/hw/tpm/tpm_tis.c @@ -427,6 +427,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; @@ -476,14 +477,26 @@ static uint64_t tpm_tis_mmio_read(void *opaque, hwaddr addr, break; case TPM_TIS_REG_DATA_FIFO: 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 +531,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 +550,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 +670,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 */ @@ -747,16 +772,25 @@ 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; } - if ((tis->loc[locty].sts & TPM_TIS_STS_EXPECT)) { + val >>= shift; + if (size > 4 - (addr & 0x3)) { + /* prevent access beyond FIFO */ + size = 4 - (addr & 0x3); + } + + 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; } From 2eae8c7516a99c1309199df8d88c0f0749fce2cb Mon Sep 17 00:00:00 2001 From: Stefan Berger Date: Mon, 23 Feb 2015 09:27:18 -0500 Subject: [PATCH 100/130] tpm: Support for XFIFO register Support for the XFIFO register (range) of the TIS 1.3 specification. We support a range of 64 bytes. Signed-off-by: Stefan Berger Acked-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/tpm/tpm_tis.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c index 617069372f..a37c7ce052 100644 --- a/hw/tpm/tpm_tis.c +++ b/hw/tpm/tpm_tis.c @@ -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 @@ -476,6 +478,7 @@ 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) { if (size > 4 - (addr & 0x3)) { /* prevent access beyond FIFO */ @@ -762,6 +765,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; From fd859081453f94c3cbd6527289e41b7fddbf645f Mon Sep 17 00:00:00 2001 From: Stefan Berger Date: Mon, 23 Feb 2015 09:27:19 -0500 Subject: [PATCH 101/130] tpm: Support for TIS selftest done flag Extend the backend to check whether the TPM_ContinueSelfTest finished successfully and provide a flag to the TIS front-end if it successfully finished. The TIS then sets a flag in all localities in the STS register and keeps it until the next reset. Signed-off-by: Stefan Berger Acked-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/tpm/tpm_int.h | 1 + hw/tpm/tpm_passthrough.c | 37 +++++++++++++++++++---- hw/tpm/tpm_tis.c | 58 ++++++++++++++++++++++++++++-------- include/sysemu/tpm_backend.h | 2 +- 4 files changed, 79 insertions(+), 19 deletions(-) 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..a94c7c5a24 100644 --- a/hw/tpm/tpm_passthrough.c +++ b/hw/tpm/tpm_passthrough.c @@ -112,14 +112,31 @@ 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) { @@ -149,6 +166,11 @@ static int tpm_passthrough_unix_tx_bufs(TPMPassthruState *tpm_pt, "packet from TPM\n"); } + 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: if (ret < 0) { tpm_write_fatal_error_response(out, out_len); @@ -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: diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c index a37c7ce052..61186c5e03 100644 --- a/hw/tpm/tpm_tis.c +++ b/hw/tpm/tpm_tis.c @@ -64,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 @@ -146,6 +147,24 @@ static void tpm_tis_show_buffer(const TPMSizedBuffer *sb, const char *string) #endif } +/* + * 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. */ @@ -257,7 +276,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); } @@ -302,7 +322,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; @@ -322,12 +343,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); } @@ -346,7 +375,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 @@ -714,7 +743,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; @@ -733,7 +762,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); @@ -755,8 +785,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 */ @@ -780,7 +811,8 @@ static void tpm_tis_mmio_write_intern(void *opaque, hwaddr addr, 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; @@ -796,7 +828,7 @@ static void tpm_tis_mmio_write_intern(void *opaque, hwaddr addr, val >>= 8; size--; } else { - tis->loc[locty].sts = TPM_TIS_STS_VALID; + tpm_tis_sts_set(&tis->loc[locty], TPM_TIS_STS_VALID); } } @@ -809,11 +841,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/include/sysemu/tpm_backend.h b/include/sysemu/tpm_backend.h index 825f33bdc3..540ee25477 100644 --- a/include/sysemu/tpm_backend.h +++ b/include/sysemu/tpm_backend.h @@ -56,7 +56,7 @@ struct TPMBackend { QLIST_ENTRY(TPMBackend) list; }; -typedef void (TPMRecvDataCB)(TPMState *, uint8_t locty); +typedef void (TPMRecvDataCB)(TPMState *, uint8_t locty, bool selftest_done); typedef struct TPMSizedBuffer { uint32_t size; From 9dd5c40ddfe332d8a03034d8e01208e5e1a4f5f7 Mon Sep 17 00:00:00 2001 From: Stefan Berger Date: Mon, 23 Feb 2015 09:27:20 -0500 Subject: [PATCH 102/130] tpm: Support for capability flags of TIS 1.3 Provide the TIS 1.3 capability flags. The interface now looks like a TIS 1.3 interface. It's fully compatible with previous TIS 1.2 and drivers written for TIS 1.2 continue to work. Signed-off-by: Stefan Berger Acked-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/tpm/tpm_tis.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c index 61186c5e03..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. */ @@ -103,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 From 60efd4297d44a1ac41ae46485098919376fdcab4 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Fri, 20 Feb 2015 18:22:05 +0000 Subject: [PATCH 103/130] pc: acpi-build: create PCI0._CRS dynamically Replace template patching and runtime calculation in _CRS() method with static _CRS defined in SSDT. No functional change except of as mentined above and _CRS being moved from DSDT to SSDT. Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/acpi-build.c | 88 +++++++++++++++++++-------------- hw/i386/acpi-dsdt-pci-crs.dsl | 92 ----------------------------------- hw/i386/acpi-dsdt.dsl | 45 ----------------- hw/i386/q35-acpi-dsdt.dsl | 18 ------- hw/i386/ssdt-misc.dsl | 19 -------- 5 files changed, 52 insertions(+), 210 deletions(-) delete mode 100644 hw/i386/acpi-dsdt-pci-crs.dsl diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 4d5d7e3d18..355f9b7f21 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -346,24 +346,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); @@ -860,22 +842,6 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state) 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); - - 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); - } -} - static void build_ssdt(GArray *table_data, GArray *linker, AcpiCpuInfo *cpu, AcpiPmInfo *pm, AcpiMiscInfo *misc, @@ -898,9 +864,59 @@ build_ssdt(GArray *table_data, GArray *linker, ssdt_ptr = acpi_data_push(ssdt->buf, sizeof(ssdp_misc_aml)); memcpy(ssdt_ptr, ssdp_misc_aml, sizeof(ssdp_misc_aml)); - patch_pci_windows(pci, ssdt_ptr, sizeof(ssdp_misc_aml)); - 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)); + if (ich9_lpc_find()) { /* Q35 */ + aml_append(crs, + aml_word_io(aml_min_fixed, aml_max_fixed, + aml_pos_decode, aml_entire_range, + 0x0000, 0x0D00, 0xFFFF, 0x0000, 0xF300)); + } else { /* piix4 */ + aml_append(crs, + aml_word_io(aml_min_fixed, aml_max_fixed, + aml_pos_decode, aml_entire_range, + 0x0000, 0x0D00, 0xADFF, 0x0000, 0xA100)); + aml_append(crs, + aml_word_io(aml_min_fixed, aml_max_fixed, + aml_pos_decode, aml_entire_range, + 0x0000, 0xAE0F, 0xAEFF, 0x0000, 0x00F1)); + aml_append(crs, + aml_word_io(aml_min_fixed, aml_max_fixed, + aml_pos_decode, aml_entire_range, + 0x0000, 0xAF20, 0xAFDF, 0x0000, 0x00C0)); + aml_append(crs, + aml_word_io(aml_min_fixed, aml_max_fixed, + aml_pos_decode, aml_entire_range, + 0x0000, 0xAFE4, 0xFFFF, 0x0000, 0x501C)); + } + 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)); + } + aml_append(scope, aml_name_decl("_CRS", crs)); + /* reserve PCIHP resources */ if (pm->pcihp_io_len) { dev = aml_device("PHPR"); 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 . - */ - -/* 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..09b68f0ed2 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" diff --git a/hw/i386/q35-acpi-dsdt.dsl b/hw/i386/q35-acpi-dsdt.dsl index e1cee5d89a..3fb4b2f076 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" diff --git a/hw/i386/ssdt-misc.dsl b/hw/i386/ssdt-misc.dsl index 2588e30e19..8d61f21873 100644 --- a/hw/i386/ssdt-misc.dsl +++ b/hw/i386/ssdt-misc.dsl @@ -18,23 +18,4 @@ 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 }) - } } From 8bec1a0a78203d2555b7446efa7ebe5d2601f79a Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Fri, 20 Feb 2015 18:22:06 +0000 Subject: [PATCH 104/130] pc: acpi: drop manual hole punching for PCI hotplug resources Drops manual hole punching in PCI0._CRS for PIIX4 machine type. Resources will be consumed by Device(PHPR) that cwis attached to PCI bus. The same way how it currently works for mem hotlpug. Manual hole in PIIX4 _CRS wasn't correct anyway since it was legacy size 0xF while current PCIHP MMIO region is of size 0x14. Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/acpi-build.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 355f9b7f21..02e2597cd6 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -885,11 +885,7 @@ build_ssdt(GArray *table_data, GArray *linker, aml_append(crs, aml_word_io(aml_min_fixed, aml_max_fixed, aml_pos_decode, aml_entire_range, - 0x0000, 0x0D00, 0xADFF, 0x0000, 0xA100)); - aml_append(crs, - aml_word_io(aml_min_fixed, aml_max_fixed, - aml_pos_decode, aml_entire_range, - 0x0000, 0xAE0F, 0xAEFF, 0x0000, 0x00F1)); + 0x0000, 0x0D00, 0xAEFF, 0x0000, 0xA200)); aml_append(crs, aml_word_io(aml_min_fixed, aml_max_fixed, aml_pos_decode, aml_entire_range, From c2d9c595ade376ad4c94c8c2cab23fd6f50805f7 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Fri, 20 Feb 2015 18:22:07 +0000 Subject: [PATCH 105/130] pc: acpi: drop manual hole punching for CPU hotplug resources Drops manual hole punching in PCI0._CRS on PIIX4 machine type for CPU hotplug resources. Resources will be consumed by Device(PRES) that is attached to PCI bus. The same way how it currently works for mem hotlpug. Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/acpi-build.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 02e2597cd6..0de261a536 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -885,11 +885,7 @@ build_ssdt(GArray *table_data, GArray *linker, aml_append(crs, aml_word_io(aml_min_fixed, aml_max_fixed, aml_pos_decode, aml_entire_range, - 0x0000, 0x0D00, 0xAEFF, 0x0000, 0xA200)); - aml_append(crs, - aml_word_io(aml_min_fixed, aml_max_fixed, - aml_pos_decode, aml_entire_range, - 0x0000, 0xAF20, 0xAFDF, 0x0000, 0x00C0)); + 0x0000, 0x0D00, 0xAFDF, 0x0000, 0xA2E0)); aml_append(crs, aml_word_io(aml_min_fixed, aml_max_fixed, aml_pos_decode, aml_entire_range, From d31c909e57a131dec7a1e620f36573f2f5fca9e5 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Fri, 20 Feb 2015 18:22:08 +0000 Subject: [PATCH 106/130] pc: acpi: drop manual hole punching for GPE0 resources Drops manual hole punching in PCI0._CRS on PIIX4 machine type for GPE0 resources. Resources will be consumed by Device(GPE0) that is attached to PCI namespace. There is GPE device with HID ACPI0006 since ACPI2.0 that should be used for this purpose but none of Windows versions support it and show it as "unknown device", so reserve resource in old fashioned way with PNP0A06 device to make windows happy and actually reserve resources. Along with last hole _CRS layout of PIIX4 machine becomes the same as Q35 one, so merge them together and use the same _CRS for both machine types. Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/acpi-build.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 0de261a536..2700154602 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -876,21 +876,10 @@ build_ssdt(GArray *table_data, GArray *linker, aml_word_io(aml_min_fixed, aml_max_fixed, aml_pos_decode, aml_entire_range, 0x0000, 0x0000, 0x0CF7, 0x0000, 0x0CF8)); - if (ich9_lpc_find()) { /* Q35 */ - aml_append(crs, - aml_word_io(aml_min_fixed, aml_max_fixed, - aml_pos_decode, aml_entire_range, - 0x0000, 0x0D00, 0xFFFF, 0x0000, 0xF300)); - } else { /* piix4 */ - aml_append(crs, - aml_word_io(aml_min_fixed, aml_max_fixed, - aml_pos_decode, aml_entire_range, - 0x0000, 0x0D00, 0xAFDF, 0x0000, 0xA2E0)); - aml_append(crs, - aml_word_io(aml_min_fixed, aml_max_fixed, - aml_pos_decode, aml_entire_range, - 0x0000, 0xAFE4, 0xFFFF, 0x0000, 0x501C)); - } + 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, @@ -909,6 +898,19 @@ build_ssdt(GArray *table_data, GArray *linker, } 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"); From 4ec8d2b3f54dd1dcd9e2a80e529feff4e2603288 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Fri, 20 Feb 2015 18:22:09 +0000 Subject: [PATCH 107/130] pc: acpi-build: drop remaining ssdt_misc template It drops empty ssdt_misc templete. It also hides from user almost all pointer arithmetic when building SSDT which makes resulting code a bit cleaner and concentrating only on composing ASL construct /i.e. a task build_ssdt() should be doing/. Also it makes one binary blob less stored in QEMU source tree by removing need to keep and update hw/i386/ssdt-misc.hex.generated file here in total saving us ~430LOC. Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/Makefile.objs | 1 - hw/i386/acpi-build.c | 7 ++----- hw/i386/ssdt-misc.dsl | 21 --------------------- 3 files changed, 2 insertions(+), 27 deletions(-) delete mode 100644 hw/i386/ssdt-misc.dsl diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs index 45b90a8374..9b005680cb 100644 --- a/hw/i386/Makefile.objs +++ b/hw/i386/Makefile.objs @@ -10,7 +10,6 @@ obj-y += acpi-build.o hw/i386/acpi-build.o: hw/i386/acpi-build.c \ hw/i386/acpi-dsdt.hex hw/i386/q35-acpi-dsdt.hex \ hw/i386/ssdt-pcihp.hex \ - hw/i386/ssdt-misc.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 2700154602..01d988cfd3 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -526,7 +526,6 @@ static inline char acpi_get_hex(uint32_t val) #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" @@ -850,7 +849,6 @@ 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; - uint8_t *ssdt_ptr; Aml *ssdt, *sb_scope, *scope, *pkg, *dev, *method, *crs, *field, *ifctx; int i; @@ -860,9 +858,8 @@ build_ssdt(GArray *table_data, GArray *linker, 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(ssdt->buf, sizeof(ssdp_misc_aml)); - memcpy(ssdt_ptr, ssdp_misc_aml, sizeof(ssdp_misc_aml)); + /* Reserve space for header */ + acpi_data_push(ssdt->buf, sizeof(AcpiTableHeader)); scope = aml_scope("\\_SB.PCI0"); /* build PCI0._CRS */ diff --git a/hw/i386/ssdt-misc.dsl b/hw/i386/ssdt-misc.dsl deleted file mode 100644 index 8d61f21873..0000000000 --- a/hw/i386/ssdt-misc.dsl +++ /dev/null @@ -1,21 +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 . - */ -#include "hw/acpi/pc-hotplug.h" - -ACPI_EXTRACT_ALL_CODE ssdp_misc_aml - -DefinitionBlock ("ssdt-misc.aml", "SSDT", 0x01, "BXPC", "BXSSDTSUSP", 0x1) -{ -} From 7056045332b997a8cd298e3bf231ecf690accdf4 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Fri, 20 Feb 2015 18:22:10 +0000 Subject: [PATCH 108/130] acpi: add acpi_irq_no_flags() term Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/aml-build.c | 21 +++++++++++++++++++++ include/hw/acpi/aml-build.h | 1 + 2 files changed, 22 insertions(+) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index d793775d93..60245e7ded 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -514,6 +514,27 @@ Aml *aml_io(AmlIODecode dec, uint16_t min_base, uint16_t max_base, 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) { diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index d2b2c354fa..11871970ca 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -146,6 +146,7 @@ Aml *aml_io(AmlIODecode dec, uint16_t min_base, uint16_t max_base, uint8_t aln, uint8_t len); Aml *aml_operation_region(const char *name, AmlRegionSpace rs, uint32_t offset, uint32_t len); +Aml *aml_irq_no_flags(uint8_t irq); Aml *aml_named_field(const char *name, unsigned length); Aml *aml_reserved_field(unsigned length); Aml *aml_local(int num); From 1142e45ffdc5bf76ae920a25495e13223f5d5ed2 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Fri, 20 Feb 2015 18:22:11 +0000 Subject: [PATCH 109/130] pc: export applesmc IO port/len IO port and length will be used in following patch to correctly generate SMC ACPI device in SSDT. Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/acpi-build.c | 2 +- hw/misc/applesmc.c | 5 ++--- include/hw/isa/isa.h | 11 +++++++++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 01d988cfd3..badfa73fe4 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -145,7 +145,7 @@ static void acpi_get_dsdt(AcpiMiscInfo *info) /* Patch in appropriate value for AppleSMC _STA */ *(uint8_t *)(info->dsdt_code + *applesmc_sta) = - applesmc_find() ? 0x0b : 0x00; + applesmc_port() ? 0x0b : 0x00; } static 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/include/hw/isa/isa.h b/include/hw/isa/isa.h index cf7bd343c7..f21ceaafc6 100644 --- a/include/hw/isa/isa.h +++ b/include/hw/isa/isa.h @@ -21,10 +21,17 @@ #define ISA_BUS(obj) OBJECT_CHECK(ISABus, (obj), TYPE_ISA_BUS) #define TYPE_APPLE_SMC "isa-applesmc" +#define APPLESMC_MAX_DATA_LENGTH 32 +#define APPLESMC_PROP_IO_BASE "iobase" -static inline bool applesmc_find(void) +static inline uint16_t applesmc_port(void) { - return object_resolve_path_type("", TYPE_APPLE_SMC, NULL); + Object *obj = object_resolve_path_type("", TYPE_APPLE_SMC, NULL); + + if (obj) { + return object_property_get_int(obj, APPLESMC_PROP_IO_BASE, NULL); + } + return 0; } typedef struct ISADeviceClass { From 8ac6f7a6d64386426daa6c34676d296cafe19a80 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Fri, 20 Feb 2015 18:22:12 +0000 Subject: [PATCH 110/130] pc: acpi-build: drop template patching and create Device(SMC) dynamically patch moves SMC device into SSDT and creates it only when device is present, which makes ACPI tables smaller in default case when device is not present. Also it fixes wrong IO range in CRS if "iobase" property is set to a non default value. PS: Testing with XP shows that current default "iobase" used SMC device conflicts with floppy controller IO, but it's topic for another patch and I'd leave it to SMC device author for resolving conflict. Signed-off-by: Igor Mammedov CC: agraf@suse.de Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/acpi-build.c | 29 ++++++++++++++++++++++------- hw/i386/acpi-dsdt-isa.dsl | 11 ----------- hw/i386/acpi-dsdt.dsl | 1 - hw/i386/q35-acpi-dsdt.dsl | 1 - 4 files changed, 22 insertions(+), 20 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index badfa73fe4..05eb80a277 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -116,6 +116,7 @@ typedef struct AcpiMiscInfo { const unsigned char *dsdt_code; unsigned dsdt_size; uint16_t pvpanic_port; + uint16_t applesmc_io_base; } AcpiMiscInfo; typedef struct AcpiBuildPciBusHotplugState { @@ -127,7 +128,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); @@ -135,17 +135,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_port() ? 0x0b : 0x00; } static @@ -248,6 +242,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) @@ -955,6 +950,26 @@ build_ssdt(GArray *table_data, GArray *linker, 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); + } + if (misc->pvpanic_port) { scope = aml_scope("\\_SB.PCI0.ISA"); 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.dsl b/hw/i386/acpi-dsdt.dsl index 09b68f0ed2..a2d84ecf8f 100644 --- a/hw/i386/acpi-dsdt.dsl +++ b/hw/i386/acpi-dsdt.dsl @@ -85,7 +85,6 @@ DefinitionBlock ( } } -#define DSDT_APPLESMC_STA piix_dsdt_applesmc_sta #include "acpi-dsdt-isa.dsl" diff --git a/hw/i386/q35-acpi-dsdt.dsl b/hw/i386/q35-acpi-dsdt.dsl index 3fb4b2f076..16eaca3fae 100644 --- a/hw/i386/q35-acpi-dsdt.dsl +++ b/hw/i386/q35-acpi-dsdt.dsl @@ -150,7 +150,6 @@ DefinitionBlock ( } } -#define DSDT_APPLESMC_STA q35_dsdt_applesmc_sta #include "acpi-dsdt-isa.dsl" From 194c8615d7d819887180f196675ba987c4bf43bc Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Fri, 20 Feb 2015 18:22:13 +0000 Subject: [PATCH 111/130] tests: ACPI test blobs update due to PCI0._CRS changes PCI0._CRS was moved into SSDT and became the same for PIIX4/Q35 machines. Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- tests/acpi-test-data/pc/DSDT | Bin 3415 -> 2970 bytes tests/acpi-test-data/pc/SSDT | Bin 2374 -> 2480 bytes tests/acpi-test-data/q35/DSDT | Bin 8005 -> 7608 bytes tests/acpi-test-data/q35/SSDT | Bin 578 -> 685 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/tests/acpi-test-data/pc/DSDT b/tests/acpi-test-data/pc/DSDT index ad12cb35d9dafc4d50002873f5c4ca04552b36df..1693c3783b34cfb5473e7ef65ba6f8deee390898 100644 GIT binary patch delta 45 zcmcaEHA|e!CDR}W5h(Rj?Icp+>8P~()!Ht!A|i3&YlLI!H)5pvzXs<0ss&x B3^@P* delta 471 zcmX|;PfG$p7{=dmA=YWu6e24^q(i4D|FOqtT^BPf21n}9Vf+XZ5qMG}P$DSt5*?zz zt4j0%@>_JQL)Q+S^3*i1+xi}6e$Vp^54_BM{B4yMM4@_Y0g&@9?KBUUx1`8R?v_%f zTk%9JPw7L)f)E27g$F5;37artYM(Fztsfmv*i2h$pv|X1FAUWX;2Q#+9KDYK#xwmn zQo4AJx8pW|UkE@!sd?s;9E~_! z*g2nDf*&XeN1j}4iUU`ga<5ci gb5S6s6jg_UiQB}Y)G87%z#z%>UA^VYfP97j0NTcIKL7v# diff --git a/tests/acpi-test-data/pc/SSDT b/tests/acpi-test-data/pc/SSDT index d0103368a0b9e3d5410372f1f589df4eeeebaf03..dc5be2497b6c2015d7cbabb1ff0cd13e02b3e0e4 100644 GIT binary patch delta 200 zcmX>mv_Y6FIM^j*11AFmq_(Y5Qb-R5RY{u3HX5oqF7jo=Ho~s1TU8(Mxrd)V52Z8Q%Mk;R1pa%HWv8< z7OCtcjh#0B1}*&$HmO{9?mVa1edc|Kmz{mtf3Jy#Zgj&90DO8Dgrk#{UD9<@L96Hn zolxiM3*zD~11Skyh7WAwT+SuBR!8Zu^kMB!`QK*@4}RaS0mMFl0Am(;)K&^22jdRD zjCuWuIsH}`f*VXIzdpLQlHvLrOD@)juczaO!UVTfyXp;8i6bN6$OziR)|eAG zpf~N!`Y5q>RM>NpFKua`&Te+}aX>B|wi+^>1$0SweE}}7lgo-s6TtxoH@6P#nzM1r G%l`r~K4Uik diff --git a/tests/acpi-test-data/q35/SSDT b/tests/acpi-test-data/q35/SSDT index f86643da45ad89a97a652233cb090516afde7b31..749f368e3034bfb491dcd8ced37936e0dcbba02a 100644 GIT binary patch delta 200 zcmX@avX+%AIM^j*EfWI+NY;4}o2modBDslh- delta 117 zcmZ3>dWeN9IM^k`iHU)MaoI#J={P6W7zU02gWz}`1_p)$K$dGf&;S4X|8WEuhQ)IM or3{1P1-ZF6fU;l!6mUfs@Ies};EvIY4|a+VaP~CV_-;QV0J~ckEdT%j From 3a9c86df2169881978e697109ae9bb8a6ce41e92 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Fri, 20 Feb 2015 18:22:14 +0000 Subject: [PATCH 112/130] tests: bios-tables-test: add support for testing bridges Adds alternative ACPI table blob selection for testing non default QEMU configurations. If blob file for test variant is not present, fallback to default blob. With this change implement testing with a coldplugged bridge. Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- tests/bios-tables-test.c | 45 +++++++++++++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/tests/bios-tables-test.c b/tests/bios-tables-test.c index 4d0fa848b1..735ac610be 100644 --- a/tests/bios-tables-test.c +++ b/tests/bios-tables-test.c @@ -40,6 +40,7 @@ typedef struct { typedef struct { const char *machine; + const char *variant; uint32_t rsdp_addr; AcpiRsdpDescriptor rsdp_table; AcpiRsdtDescriptorRev1 rsdt_table; @@ -396,13 +397,14 @@ static void dump_aml_files(test_data *data, bool rebuild) int i; for (i = 0; i < data->tables->len; ++i) { + const char *ext = data->variant ? data->variant : ""; sdt = &g_array_index(data->tables, AcpiSdtTable, i); g_assert(sdt->aml); if (rebuild) { uint32_t signature = cpu_to_le32(sdt->header.signature); - aml_file = g_strdup_printf("%s/%s/%.4s", data_dir, data->machine, - (gchar *)&signature); + aml_file = g_strdup_printf("%s/%s/%.4s%s", data_dir, data->machine, + (gchar *)&signature, ext); fd = g_open(aml_file, O_WRONLY|O_TRUNC|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH); } else { @@ -509,7 +511,7 @@ static GArray *load_expected_aml(test_data *data) { int i; AcpiSdtTable *sdt; - gchar *aml_file; + gchar *aml_file = NULL; GError *error = NULL; gboolean ret; @@ -517,6 +519,7 @@ static GArray *load_expected_aml(test_data *data) for (i = 0; i < data->tables->len; ++i) { AcpiSdtTable exp_sdt; uint32_t signature; + const char *ext = data->variant ? data->variant : ""; sdt = &g_array_index(data->tables, AcpiSdtTable, i); @@ -524,8 +527,15 @@ static GArray *load_expected_aml(test_data *data) exp_sdt.header.signature = sdt->header.signature; signature = cpu_to_le32(sdt->header.signature); - aml_file = g_strdup_printf("%s/%s/%.4s", data_dir, data->machine, - (gchar *)&signature); + +try_again: + aml_file = g_strdup_printf("%s/%s/%.4s%s", data_dir, data->machine, + (gchar *)&signature, ext); + if (data->variant && !g_file_test(aml_file, G_FILE_TEST_EXISTS)) { + g_free(aml_file); + ext = ""; + goto try_again; + } exp_sdt.aml_file = aml_file; g_assert(g_file_test(aml_file, G_FILE_TEST_EXISTS)); ret = g_file_get_contents(aml_file, &exp_sdt.aml, @@ -778,6 +788,17 @@ static void test_acpi_piix4_tcg(void) free_test_data(&data); } +static void test_acpi_piix4_tcg_bridge(void) +{ + test_data data; + + memset(&data, 0, sizeof(data)); + data.machine = MACHINE_PC; + data.variant = ".bridge"; + test_acpi_one("-machine accel=tcg -device pci-bridge,chassis_nr=1", &data); + free_test_data(&data); +} + static void test_acpi_q35_tcg(void) { test_data data; @@ -788,6 +809,18 @@ static void test_acpi_q35_tcg(void) free_test_data(&data); } +static void test_acpi_q35_tcg_bridge(void) +{ + test_data data; + + memset(&data, 0, sizeof(data)); + data.machine = MACHINE_Q35; + data.variant = ".bridge"; + test_acpi_one("-machine q35,accel=tcg -device pci-bridge,chassis_nr=1", + &data); + free_test_data(&data); +} + int main(int argc, char *argv[]) { const char *arch = qtest_get_arch(); @@ -805,7 +838,9 @@ int main(int argc, char *argv[]) if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) { qtest_add_func("acpi/piix4/tcg", test_acpi_piix4_tcg); + qtest_add_func("acpi/piix4/tcg/bridge", test_acpi_piix4_tcg_bridge); qtest_add_func("acpi/q35/tcg", test_acpi_q35_tcg); + qtest_add_func("acpi/q35/tcg/bridge", test_acpi_q35_tcg_bridge); } ret = g_test_run(); unlink(disk); From 71096d6cc5b4341e9b7ee59f10594d5f36ce12b9 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Fri, 20 Feb 2015 18:22:15 +0000 Subject: [PATCH 113/130] tests: add ACPI blobs for qemu with bridge cases Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- tests/acpi-test-data/pc/SSDT.bridge | Bin 0 -> 4352 bytes tests/acpi-test-data/q35/SSDT.bridge | Bin 0 -> 702 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/acpi-test-data/pc/SSDT.bridge create mode 100644 tests/acpi-test-data/q35/SSDT.bridge diff --git a/tests/acpi-test-data/pc/SSDT.bridge b/tests/acpi-test-data/pc/SSDT.bridge new file mode 100644 index 0000000000000000000000000000000000000000..b807ac92dde72719fe3861c710b555fe3dd62583 GIT binary patch literal 4352 zcmeH}&2HO96ov0ljLlF~Ov!ZYIC0FayGZCbaon9GlCk_ln$S=|3K`*|2&w=@6C@3a zz#H2I)b6`4vdB7mg!U2o2-)-r3bgK~>b<0{9afL;WU`qh{+?%Kep^v1D1pfBjGC)xWFkv_>6N(=V@(T4xA7eQD>93;s^Y3q=d+zJINr?To z_JT?hCtkzb1|#dBqWkWvXRlwpdG-0T*LYK=4YOQ~v|^gO;^W}sK5Koy#Reefqez3%ye zeuo}m(hg-l0;}=GYb7CU-#ETo z;`NVONnk`l+{OvhPRO4xuA>PnG^$n-wQ*FYxzasbCsB&p%|jP2Exa63>kwPXlMIKw znA1=k|DB3;bXi=-*x698lT(d$Z-U6&bMR-rz-t}wcyMA`KQqc>D&z^y~*fJ6&kYZ zEklO6m-x1D-N^N%Zj;7+&viG~lX{&r?qIH;=6X`kXN-H1>-Z<5 zFa1k(nlKJT&mN|aes{KF6m44I%-_$as8Au)}4*Sk5hOF&A1cMs$p(*#HbON zrKk8$AWr4x4*o4T{D!`ZC@S#|D1ku%Bq)9Il%t@+%;m6C1eM1|f>AMTE0Jp+mE@{1 ziitTr{-zC2fzCp87OJyQorUWECRF3KB2>#KJ&H#>Ym4Nhq`=d(5EK)5UKWBf0#C$3 T%yO7={=b{U>qQO=MGpTBc|!Xx literal 0 HcmV?d00001 diff --git a/tests/acpi-test-data/q35/SSDT.bridge b/tests/acpi-test-data/q35/SSDT.bridge new file mode 100644 index 0000000000000000000000000000000000000000..c552782f5bcc57094a7d1375b67979b2efa48f1c GIT binary patch literal 702 zcmaJ<&2G~`5T12{vDO=5f)N!Le1$`C2}PVx?X`*1#?H#?q9RAy1F9%eMNvx+y^$aR zcV2))p96RVj(HCb7a943`XL`SL@n(6Z z5+_fJ5=W%hYj=XX=deayWhyV33!JajvpYmOc^QubG#Q#Pp)n%0XRz%XZ8mK2Jk^Hf zqe8QKc5_vwQ_P*D&(LTY_;ybHc{^8Vf%W{F4nyOZC@I@tQ_t_|@bRUCfsgy&NZ`B$ U4=%uf02OciE4IM5l`Jaw0}NP~0RR91 literal 0 HcmV?d00001 From b23046abe78f48498a423b802d6d86ba0172d57f Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Fri, 20 Feb 2015 18:22:16 +0000 Subject: [PATCH 114/130] pc: acpi-build: simplify PCI bus tree generation it basicaly does the same as original approach, * just without bus/notify tables tracking (less obscure) which is easier to follow. * drops unnecessary loops and bitmaps, creating devices and notification method in the same loop. * saves us ~100LOC Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/acpi-build.c | 274 ++++++++++++++----------------------------- 1 file changed, 85 insertions(+), 189 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 05eb80a277..ba056f0c21 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -112,7 +112,6 @@ typedef struct 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; @@ -591,74 +590,37 @@ static void acpi_set_pci_info(void) } } -static void build_pci_bus_state_init(AcpiBuildPciBusHotplugState *state, - AcpiBuildPciBusHotplugState *parent, - bool pcihp_bridge_en) +static void build_append_pcihp_notify_entry(GArray *method, int slot) { - state->parent = parent; - state->device_table = build_alloc_array(); - state->notify_table = build_alloc_array(); - state->pcihp_bridge_en = pcihp_bridge_en; + GArray *ifctx; + + ifctx = build_alloc_array(); + build_append_byte(ifctx, 0x7B); /* AndOp */ + build_append_byte(ifctx, 0x68); /* Arg0Op */ + build_append_int(ifctx, 0x1U << slot); + build_append_byte(ifctx, 0x00); /* NullName */ + build_append_byte(ifctx, 0x86); /* NotifyOp */ + build_append_namestring(ifctx, "S%.02X", PCI_DEVFN(slot, 0)); + build_append_byte(ifctx, 0x69); /* Arg1Op */ + + /* Pack it up */ + build_package(ifctx, 0xA0 /* IfOp */); + build_append_array(method, ifctx); + build_free_array(ifctx); } -static void build_pci_bus_state_cleanup(AcpiBuildPciBusHotplugState *state) +static void build_append_pci_bus_devices(GArray *parent_scope, PCIBus *bus, + bool pcihp_bridge_en) { - 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); - - return child; -} - -static void build_pci_bus_end(PCIBus *bus, void *bus_state) -{ - 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; + GArray *method = NULL; 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. - * Skip creation for hotplugged bridges as well. - */ - if (bus->parent_dev && (!child->pcihp_bridge_en || - DEVICE(bus->parent_dev)->hotplugged)) { - build_free_array(bus_table); - build_pci_bus_state_cleanup(child); - g_free(child); - return; - } + PCIBus *sec; + int i; if (bus->parent_dev) { - op = 0x82; /* DeviceOp */ - build_append_namestring(bus_table, "S%.02X", - bus->parent_dev->devfn); - build_append_byte(bus_table, 0x08); /* NameOp */ - build_append_namestring(bus_table, "_SUN"); - build_append_int(bus_table, PCI_SLOT(bus->parent_dev->devfn)); - build_append_byte(bus_table, 0x08); /* NameOp */ - build_append_namestring(bus_table, "_ADR"); - build_append_int(bus_table, (PCI_SLOT(bus->parent_dev->devfn) << 16) | - PCI_FUNC(bus->parent_dev->devfn)); + build_append_namestring(bus_table, "S%.02X_", bus->parent_dev->devfn); } else { - op = 0x10; /* ScopeOp */; build_append_namestring(bus_table, "PCI0"); } @@ -667,29 +629,28 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state) build_append_byte(bus_table, 0x08); /* NameOp */ build_append_namestring(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); + method = build_alloc_method("DVNT", 2); } - 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); - 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 */ + void *pcihp = acpi_data_push(bus_table, ACPI_PCIHP_SIZEOF); + memcpy(pcihp, ACPI_PCIHP_AML, ACPI_PCIHP_SIZEOF); + patch_pcihp(slot, pcihp); + + build_append_pcihp_notify_entry(method, slot); + } continue; } - set_bit(slot, slot_device_present); pc = PCI_DEVICE_GET_CLASS(pdev); dc = DEVICE_GET_CLASS(pdev); @@ -698,142 +659,83 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state) * In this case they aren't themselves hot-pluggable. * Hotplugged bridges *are* hot-pluggable. */ - bridge_in_acpi = pc->is_bridge && child->pcihp_bridge_en && - !DEVICE(pdev)->hotplugged; + 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; } if (pc->class_id == PCI_CLASS_DISPLAY_VGA) { - set_bit(slot, slot_device_vga); - if (object_dynamic_cast(OBJECT(pdev), "qxl-vga")) { - set_bit(slot, slot_device_qxl); + void *pcihp = acpi_data_push(bus_table, + ACPI_PCIQXL_SIZEOF); + memcpy(pcihp, ACPI_PCIQXL_AML, ACPI_PCIQXL_SIZEOF); + patch_pciqxl(slot, pcihp); + } else { + void *pcihp = acpi_data_push(bus_table, + ACPI_PCIVGA_SIZEOF); + memcpy(pcihp, ACPI_PCIVGA_AML, ACPI_PCIVGA_SIZEOF); + patch_pcivga(slot, pcihp); } - } + } else if (hotplug_enabled_dev) { + void *pcihp = acpi_data_push(bus_table, ACPI_PCIHP_SIZEOF); - if (!dc->hotpluggable || bridge_in_acpi) { - clear_bit(slot, slot_hotplug_enable); - } - } - - /* 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); + patch_pcihp(slot, pcihp); + build_append_pcihp_notify_entry(method, slot); + } else if (bridge_in_acpi) { + PCIBus *sec_bus = pci_bridge_get_sec_bus(PCI_BRIDGE(pdev)); + void *pcihp = acpi_data_push(bus_table, ACPI_PCINOHP_SIZEOF); + memcpy(pcihp, ACPI_PCINOHP_AML, ACPI_PCINOHP_SIZEOF); - patch_pcinohp(i, pcihp); + patch_pcinohp(slot, pcihp); + build_append_pci_bus_devices(bus_table, sec_bus, pcihp_bridge_en); + } else { /* non hotpluggable present devices */ + void *pcihp = acpi_data_push(bus_table, ACPI_PCINOHP_SIZEOF); + + memcpy(pcihp, ACPI_PCINOHP_AML, ACPI_PCINOHP_SIZEOF); + patch_pcinohp(slot, pcihp); } } 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_namestring(notify, "S%.02X", PCI_DEVFN(i, 0)); - build_append_byte(notify, 0x69); /* Arg1Op */ - - /* Pack it up */ - build_package(notify, op); - - build_append_array(method, notify); - - build_free_array(notify); - } - build_append_and_cleanup_method(bus_table, 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); + 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_namestring(method, "BNUM"); - build_append_namestring(method, "DVNT"); - build_append_namestring(method, "PCIU"); - build_append_int(method, 1); /* Device Check */ - build_append_namestring(method, "DVNT"); - build_append_namestring(method, "PCID"); - build_append_int(method, 3); /* Eject Request */ - } + /* 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_namestring(method, "BNUM"); + build_append_namestring(method, "DVNT"); + build_append_namestring(method, "PCIU"); + build_append_int(method, 1); /* Device Check */ + build_append_namestring(method, "DVNT"); + build_append_namestring(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); - - /* 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); - } - - /* 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_namestring(parent->notify_table, "^PCNT.S%.02X", - bus->parent_dev->devfn); + /* Notify about child bus events in any case */ + if (pcihp_bridge_en) { + QLIST_FOREACH(sec, &bus->child, sibling) { + build_append_namestring(method, "^S%.02X.PCNT", + sec->parent_dev->devfn); } } - qobject_decref(bsel); + build_append_and_cleanup_method(bus_table, method); + + build_package(bus_table, 0x10); /* ScopeOp */ + build_append_array(parent_scope, bus_table); build_free_array(bus_table); - build_pci_bus_state_cleanup(child); - g_free(child); } static void @@ -1175,7 +1077,6 @@ build_ssdt(GArray *table_data, GArray *linker, aml_append(sb_scope, method); { - AcpiBuildPciBusHotplugState hotplug_state; Object *pci_host; PCIBus *bus = NULL; bool ambiguous; @@ -1185,16 +1086,11 @@ 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) { /* 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(sb_scope->buf, bus, + pm->pcihp_bridge_en); } - - build_append_array(sb_scope->buf, hotplug_state.device_table); - build_pci_bus_state_cleanup(&hotplug_state); } aml_append(ssdt, sb_scope); } From 752bba815ec5b67e2aa6d7c86fd2be80e45c203b Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Fri, 20 Feb 2015 18:22:17 +0000 Subject: [PATCH 115/130] tests: ACPI: update pc/SSDT.bridge due to new alg of PCI tree creation Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- tests/acpi-test-data/pc/SSDT.bridge | Bin 4352 -> 4351 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/tests/acpi-test-data/pc/SSDT.bridge b/tests/acpi-test-data/pc/SSDT.bridge index b807ac92dde72719fe3861c710b555fe3dd62583..ca7f63cb4e48bd95418f68daf1b7e254d5bcf8c2 100644 GIT binary patch delta 79 zcmZor`me|p9PASEUx0yu@ybT7Xhue_&1sCDjEoMGH!yjL@dq1P#B;vA+>;M#S6CwZr From 62b52c266582d3241a468dc08dbaa81e337cb03f Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Fri, 20 Feb 2015 18:22:18 +0000 Subject: [PATCH 116/130] pc: acpi-build: drop template patching and create PCI bus tree dynamically Replace AML template patching with direct composing of PCI device entries in C. It allows to simplify PCI tree generation further and saves us about 400LOC scattered through different files, confining tree generation to one C function which is much easier to deal with. Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/Makefile.objs | 1 - hw/i386/acpi-build.c | 231 ++++++++++++++--------------------------- hw/i386/ssdt-pcihp.dsl | 100 ------------------ 3 files changed, 78 insertions(+), 254 deletions(-) delete mode 100644 hw/i386/ssdt-pcihp.dsl diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs index 9b005680cb..e058a39147 100644 --- a/hw/i386/Makefile.objs +++ b/hw/i386/Makefile.objs @@ -9,7 +9,6 @@ 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/q35-acpi-dsdt.hex \ - hw/i386/ssdt-pcihp.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 ba056f0c21..b94e47e734 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -294,26 +294,6 @@ build_header(GArray *linker, GArray *table_data, table_data->data, h, len, &h->checksum); } -static GArray *build_alloc_method(const char *name, uint8_t arg_count) -{ - GArray *method = build_alloc_array(); - - build_append_namestring(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); - - build_append_array(device, method); - build_free_array(method); -} - /* End here */ #define ACPI_PORT_SMI_CMD 0x00b2 /* TODO: this is APM_CNT_IOPORT */ @@ -494,71 +474,12 @@ static inline char acpi_get_hex(uint32_t val) return (val <= 9) ? ('0' + val) : ('A' + val - 10); } -/* 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) #define ACPI_SSDT_SIGNATURE 0x54445353 /* SSDT */ #define ACPI_SSDT_HEADER_LENGTH 36 -#include "hw/i386/ssdt-pcihp.hex" #include "hw/i386/ssdt-tpm.hex" -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. @@ -590,46 +511,30 @@ static void acpi_set_pci_info(void) } } -static void build_append_pcihp_notify_entry(GArray *method, int slot) +static void build_append_pcihp_notify_entry(Aml *method, int slot) { - GArray *ifctx; + Aml *if_ctx; + int32_t devfn = PCI_DEVFN(slot, 0); - ifctx = build_alloc_array(); - build_append_byte(ifctx, 0x7B); /* AndOp */ - build_append_byte(ifctx, 0x68); /* Arg0Op */ - build_append_int(ifctx, 0x1U << slot); - build_append_byte(ifctx, 0x00); /* NullName */ - build_append_byte(ifctx, 0x86); /* NotifyOp */ - build_append_namestring(ifctx, "S%.02X", PCI_DEVFN(slot, 0)); - build_append_byte(ifctx, 0x69); /* Arg1Op */ - - /* Pack it up */ - build_package(ifctx, 0xA0 /* IfOp */); - build_append_array(method, ifctx); - build_free_array(ifctx); + 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_append_pci_bus_devices(GArray *parent_scope, PCIBus *bus, +static void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus, bool pcihp_bridge_en) { - GArray *bus_table = build_alloc_array(); - GArray *method = NULL; + Aml *dev, *notify_method, *method; QObject *bsel; PCIBus *sec; int i; - if (bus->parent_dev) { - build_append_namestring(bus_table, "S%.02X_", bus->parent_dev->devfn); - } else { - build_append_namestring(bus_table, "PCI0"); - } - bsel = object_property_get_qobject(OBJECT(bus), ACPI_PCIHP_PROP_BSEL, NULL); if (bsel) { - build_append_byte(bus_table, 0x08); /* NameOp */ - build_append_namestring(bus_table, "BSEL"); - build_append_int(bus_table, qint_get_int(qobject_to_qint(bsel))); - method = build_alloc_method("DVNT", 2); + int64_t bsel_val = qint_get_int(qobject_to_qint(bsel)); + + 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) { @@ -642,11 +547,17 @@ static void build_append_pci_bus_devices(GArray *parent_scope, PCIBus *bus, if (!pdev) { if (bsel) { /* add hotplug slots for non present devices */ - void *pcihp = acpi_data_push(bus_table, ACPI_PCIHP_SIZEOF); - memcpy(pcihp, ACPI_PCIHP_AML, ACPI_PCIHP_SIZEOF); - patch_pcihp(slot, pcihp); + 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(method, slot); + build_append_pcihp_notify_entry(notify_method, slot); } continue; } @@ -668,74 +579,87 @@ static void build_append_pci_bus_devices(GArray *parent_scope, PCIBus *bus, 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) { + /* add VGA specific AML methods */ + int s3d; + if (object_dynamic_cast(OBJECT(pdev), "qxl-vga")) { - void *pcihp = acpi_data_push(bus_table, - ACPI_PCIQXL_SIZEOF); - memcpy(pcihp, ACPI_PCIQXL_AML, ACPI_PCIQXL_SIZEOF); - patch_pciqxl(slot, pcihp); + s3d = 3; } else { - void *pcihp = acpi_data_push(bus_table, - ACPI_PCIVGA_SIZEOF); - memcpy(pcihp, ACPI_PCIVGA_AML, ACPI_PCIVGA_SIZEOF); - patch_pcivga(slot, pcihp); + s3d = 0; } + + 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) { - void *pcihp = acpi_data_push(bus_table, ACPI_PCIHP_SIZEOF); + /* add _SUN/_EJ0 to make slot hotpluggable */ + aml_append(dev, aml_name_decl("_SUN", aml_int(slot))); - memcpy(pcihp, ACPI_PCIHP_AML, ACPI_PCIHP_SIZEOF); - patch_pcihp(slot, pcihp); - build_append_pcihp_notify_entry(method, 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)); - void *pcihp = acpi_data_push(bus_table, ACPI_PCINOHP_SIZEOF); - memcpy(pcihp, ACPI_PCINOHP_AML, ACPI_PCINOHP_SIZEOF); - patch_pcinohp(slot, pcihp); - build_append_pci_bus_devices(bus_table, sec_bus, pcihp_bridge_en); - } else { /* non hotpluggable present devices */ - void *pcihp = acpi_data_push(bus_table, ACPI_PCINOHP_SIZEOF); - - memcpy(pcihp, ACPI_PCINOHP_AML, ACPI_PCINOHP_SIZEOF); - patch_pcinohp(slot, 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) { - 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. */ - method = build_alloc_method("PCNT", 0); + method = aml_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_namestring(method, "BNUM"); - build_append_namestring(method, "DVNT"); - build_append_namestring(method, "PCIU"); - build_append_int(method, 1); /* Device Check */ - build_append_namestring(method, "DVNT"); - build_append_namestring(method, "PCID"); - build_append_int(method, 3); /* Eject Request */ + 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 */) + ); } /* Notify about child bus events in any case */ if (pcihp_bridge_en) { QLIST_FOREACH(sec, &bus->child, sibling) { - build_append_namestring(method, "^S%.02X.PCNT", - sec->parent_dev->devfn); + int32_t devfn = sec->parent_dev->devfn; + + aml_append(method, aml_name("^S%.02X.PCNT", devfn)); } } - - build_append_and_cleanup_method(bus_table, method); - - build_package(bus_table, 0x10); /* ScopeOp */ - build_append_array(parent_scope, bus_table); - build_free_array(bus_table); + aml_append(parent_scope, method); } static void @@ -1087,9 +1011,10 @@ build_ssdt(GArray *table_data, GArray *linker, } if (bus) { + Aml *scope = aml_scope("PCI0"); /* Scan all PCI buses. Generate tables to support hotplug. */ - build_append_pci_bus_devices(sb_scope->buf, bus, - pm->pcihp_bridge_en); + build_append_pci_bus_devices(scope, bus, pm->pcihp_bridge_en); + aml_append(sb_scope, scope); } } aml_append(ssdt, sb_scope); 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 . - */ - -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 - } - } - } -} From 72f15d6e53485e8d1754e56e0013bed2e5816fa8 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Fri, 20 Feb 2015 18:22:19 +0000 Subject: [PATCH 117/130] pc: acpi: remove not used anymore ssdt-[misc|pcihp].hex.generated blobs Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/ssdt-misc.hex.generated | 139 ----------------- hw/i386/ssdt-pcihp.hex.generated | 251 ------------------------------- 2 files changed, 390 deletions(-) delete mode 100644 hw/i386/ssdt-misc.hex.generated delete mode 100644 hw/i386/ssdt-pcihp.hex.generated diff --git a/hw/i386/ssdt-misc.hex.generated b/hw/i386/ssdt-misc.hex.generated deleted file mode 100644 index 0b77ed443d..0000000000 --- a/hw/i386/ssdt-misc.hex.generated +++ /dev/null @@ -1,139 +0,0 @@ -static unsigned char acpi_pci64_length[] = { -0x6f -}; -static unsigned char acpi_pci32_start[] = { -0x2f -}; -static unsigned char acpi_pci64_valid[] = { -0x43 -}; -static unsigned char ssdp_misc_aml[] = { -0x53, -0x53, -0x44, -0x54, -0x77, -0x0, -0x0, -0x0, -0x1, -0x40, -0x42, -0x58, -0x50, -0x43, -0x0, -0x0, -0x42, -0x58, -0x53, -0x53, -0x44, -0x54, -0x53, -0x55, -0x1, -0x0, -0x0, -0x0, -0x49, -0x4e, -0x54, -0x4c, -0x7, -0x11, -0x14, -0x20, -0x10, -0x42, -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 -}; -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.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 -}; From af59b35ce1aa3e69488e7308b632d5af2ac54948 Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Fri, 20 Feb 2015 18:22:20 +0000 Subject: [PATCH 118/130] acpi: make build_*() routines static to aml-build.c build_*() routines were used for composing AML structures manually in acpi-build.c but after conversion to AML API they are not used outside of aml-build.c anymore, so hide them from external users. Signed-off-by: Igor Mammedov Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/aml-build.c | 20 ++++++++++---------- include/hw/acpi/aml-build.h | 16 ---------------- 2 files changed, 10 insertions(+), 26 deletions(-) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index 60245e7ded..3e5949be10 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -27,27 +27,27 @@ #include "hw/acpi/aml-build.h" #include "qemu/bswap.h" -GArray *build_alloc_array(void) +static GArray *build_alloc_array(void) { return g_array_new(false, true /* clear */, 1); } -void build_free_array(GArray *array) +static void build_free_array(GArray *array) { g_array_free(array, true); } -void build_prepend_byte(GArray *array, uint8_t val) +static void build_prepend_byte(GArray *array, uint8_t val) { g_array_prepend_val(array, val); } -void build_append_byte(GArray *array, uint8_t val) +static void build_append_byte(GArray *array, uint8_t val) { g_array_append_val(array, val); } -void build_append_array(GArray *array, GArray *val) +static void build_append_array(GArray *array, GArray *val) { g_array_append_vals(array, val->data, val->len); } @@ -141,7 +141,7 @@ build_append_namestringv(GArray *array, const char *format, va_list ap) g_strfreev(segs); } -void build_append_namestring(GArray *array, const char *format, ...) +static void build_append_namestring(GArray *array, const char *format, ...) { va_list ap; @@ -158,7 +158,7 @@ enum { PACKAGE_LENGTH_4BYTE_SHIFT = 20, }; -void +static void build_prepend_package_length(GArray *package, unsigned length, bool incl_self) { uint8_t byte; @@ -226,13 +226,13 @@ build_append_pkg_length(GArray *array, unsigned length, bool incl_self) build_free_array(tmp); } -void build_package(GArray *package, uint8_t op) +static void build_package(GArray *package, uint8_t op) { build_prepend_package_length(package, package->len, true); build_prepend_byte(package, op); } -void build_extop_package(GArray *package, uint8_t op) +static void build_extop_package(GArray *package, uint8_t op) { build_package(package, op); build_prepend_byte(package, 0x5B); /* ExtOpPrefix */ @@ -248,7 +248,7 @@ static void build_append_int_noprefix(GArray *table, uint64_t value, int size) } } -void build_append_int(GArray *table, uint64_t value) +static void build_append_int(GArray *table, uint64_t value) { if (value == 0x00) { build_append_byte(table, 0x00); /* ZeroOp */ diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index 11871970ca..f6735eaac2 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -188,20 +188,4 @@ Aml *aml_resource_template(void); Aml *aml_field(const char *name, AmlFieldFlags flags); Aml *aml_varpackage(uint32_t num_elements); -/* other helpers */ -GArray *build_alloc_array(void); -void build_free_array(GArray *array); -void build_prepend_byte(GArray *array, uint8_t val); -void build_append_byte(GArray *array, uint8_t val); -void build_append_array(GArray *array, GArray *val); - -void GCC_FMT_ATTR(2, 3) -build_append_namestring(GArray *array, const char *format, ...); - -void -build_prepend_package_length(GArray *package, unsigned length, bool incl_self); -void build_package(GArray *package, uint8_t op); -void build_append_int(GArray *table, uint64_t value); -void build_extop_package(GArray *package, uint8_t op); - #endif From 6dbcb81956b16d794c9c0257b94bd4c6feba713f Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Thu, 26 Feb 2015 17:21:14 +0100 Subject: [PATCH 119/130] pci: Give a few helpers internal linkage None of them should be used in new code. Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/pci/pci.c | 14 +++++++------- include/hw/pci/pci.h | 7 ------- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/hw/pci/pci.c b/hw/pci/pci.c index b1f3cea9af..cc5d946b8f 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -539,8 +539,8 @@ static void pci_set_default_subsystem_id(PCIDevice *pci_dev) * Parse [[:]:], return -1 on error if funcp == NULL * [[:]:]., 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; @@ -1610,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; diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index 3164fc3a4f..be2d9b8703 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -371,9 +371,6 @@ void pci_device_set_intx_routing_notifier(PCIDevice *dev, PCIINTxRoutingNotifier notifier); void pci_device_reset(PCIDevice *dev); -PCIDevice *pci_nic_init(NICInfo *nd, PCIBus *rootbus, - const char *default_model, - const char *default_devaddr); PCIDevice *pci_nic_init_nofail(NICInfo *nd, PCIBus *rootbus, const char *default_model, const char *default_devaddr); @@ -403,12 +400,8 @@ PCIBus *pci_device_root_bus(const PCIDevice *d); const char *pci_root_bus_path(PCIDevice *dev); PCIDevice *pci_find_device(PCIBus *bus, int bus_num, uint8_t devfn); int pci_qdev_find_device(const char *id, PCIDevice **pdev); -PCIBus *pci_get_bus_devfn(int *devfnp, PCIBus *root, const char *devaddr); void pci_bus_get_w64_range(PCIBus *bus, Range *range); -int pci_parse_devaddr(const char *addr, int *domp, int *busp, - unsigned int *slotp, unsigned int *funcp); - void pci_device_deassert_intx(PCIDevice *dev); typedef AddressSpace *(*PCIIOMMUFunc)(PCIBus *, void *, int); From f51074cdc6e750daa3b6df727d83449a7e42b391 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Thu, 26 Feb 2015 17:21:13 +0100 Subject: [PATCH 120/130] pci-hotplug-old: Has been dead for five major releases, bury Commit 79ca616 (v1.6.0) accidentally disabled legacy x86-only HMP commands pci_add, pci_del: it defined CONFIG_PCI_HOTPLUG only as make variable, not as preprocessor macro, killing the code conditional on defined(CONFIG_PCI_HOTPLUG_OLD). In all this time, nobody reported the loss. I only noticed it when I tried to test some error reporting change that forced me to touch this old crap again. Fun: git-log hw/pci/pci-hotplug-old.c shows our faith in the backward compatibility god has been strong enough to sacrifice at its altar about a dozen times, but not strong enough to even once verify the legacy feature's still there, let alone works. Remove the commands along with the code backing them. Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- default-configs/i386-softmmu.mak | 1 - default-configs/x86_64-softmmu.mak | 1 - device-hotplug.c | 7 +- hmp-commands.hx | 32 --- hw/pci/Makefile.objs | 2 - hw/pci/pci-hotplug-old.c | 342 ----------------------------- include/sysemu/blockdev.h | 2 - include/sysemu/sysemu.h | 5 - stubs/Makefile.objs | 1 - stubs/pci-drive-hot-add.c | 10 - 10 files changed, 3 insertions(+), 400 deletions(-) delete mode 100644 hw/pci/pci-hotplug-old.c delete mode 100644 stubs/pci-drive-hot-add.c diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak index bd99af9942..f5634bf7a3 100644 --- a/default-configs/i386-softmmu.mak +++ b/default-configs/i386-softmmu.mak @@ -26,7 +26,6 @@ CONFIG_APPLESMC=y CONFIG_I8259=y CONFIG_PFLASH_CFI01=y CONFIG_TPM_TIS=$(CONFIG_TPM) -CONFIG_PCI_HOTPLUG_OLD=y CONFIG_MC146818RTC=y CONFIG_PAM=y CONFIG_PCI_PIIX=y diff --git a/default-configs/x86_64-softmmu.mak b/default-configs/x86_64-softmmu.mak index e7c273417b..41990f7af0 100644 --- a/default-configs/x86_64-softmmu.mak +++ b/default-configs/x86_64-softmmu.mak @@ -26,7 +26,6 @@ CONFIG_APPLESMC=y CONFIG_I8259=y CONFIG_PFLASH_CFI01=y CONFIG_TPM_TIS=$(CONFIG_TPM) -CONFIG_PCI_HOTPLUG_OLD=y CONFIG_MC146818RTC=y CONFIG_PAM=y CONFIG_PCI_PIIX=y diff --git a/device-hotplug.c b/device-hotplug.c index 833d8748d5..68b94967c5 100644 --- a/device-hotplug.c +++ b/device-hotplug.c @@ -30,7 +30,7 @@ #include "sysemu/sysemu.h" #include "monitor/monitor.h" -DriveInfo *add_init_drive(const char *optstr) +static DriveInfo *add_init_drive(const char *optstr) { DriveInfo *dinfo; QemuOpts *opts; @@ -69,9 +69,8 @@ void hmp_drive_add(Monitor *mon, const QDict *qdict) monitor_printf(mon, "OK\n"); break; default: - if (pci_drive_hot_add(mon, qdict, dinfo)) { - goto err; - } + monitor_printf(mon, "Can't hot-add drive to type %d\n", dinfo->type); + goto err; } return; diff --git a/hmp-commands.hx b/hmp-commands.hx index 81f276b209..d5022d843c 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1147,38 +1147,6 @@ STEXI @item drive_add @findex drive_add Add drive to PCI storage controller. -ETEXI - -#if defined(CONFIG_PCI_HOTPLUG_OLD) - { - .name = "pci_add", - .args_type = "pci_addr:s,type:s,opts:s?", - .params = "auto|[[:]:] nic|storage [[vlan=n][,macaddr=addr][,model=type]] [file=file][,if=type][,bus=nr]...", - .help = "hot-add PCI device", - .mhandler.cmd = hmp_pci_add, - }, -#endif - -STEXI -@item pci_add -@findex pci_add -Hot-add PCI device. -ETEXI - -#if defined(CONFIG_PCI_HOTPLUG_OLD) - { - .name = "pci_del", - .args_type = "pci_addr:s", - .params = "[[:]:]", - .help = "hot remove PCI device", - .mhandler.cmd = hmp_pci_del, - }, -#endif - -STEXI -@item pci_del -@findex pci_del -Hot remove PCI device. ETEXI { 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 beea6d2b02..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"); - - 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/include/sysemu/blockdev.h b/include/sysemu/blockdev.h index 0c6264391e..7ca59b5070 100644 --- a/include/sysemu/blockdev.h +++ b/include/sysemu/blockdev.h @@ -63,8 +63,6 @@ DriveInfo *drive_new(QemuOpts *arg, BlockInterfaceType block_default_type); /* device-hotplug */ -DriveInfo *add_init_drive(const char *opts); - void qmp_change_blockdev(const char *device, const char *filename, const char *format, Error **errp); void hmp_commit(Monitor *mon, const QDict *qdict); diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index 1ab7063ef8..e7135e1ccc 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -174,11 +174,6 @@ extern int nb_option_roms; extern const char *prom_envs[MAX_PROM_ENVS]; extern unsigned int nb_prom_envs; -/* pci-hotplug */ -void hmp_pci_add(Monitor *mon, const QDict *qdict); -int pci_drive_hot_add(Monitor *mon, const QDict *qdict, DriveInfo *dinfo); -void hmp_pci_del(Monitor *mon, const QDict *qdict); - /* generic hotplug */ void hmp_drive_add(Monitor *mon, const QDict *qdict); diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs index 5e347d04bd..8beff4c732 100644 --- a/stubs/Makefile.objs +++ b/stubs/Makefile.objs @@ -24,7 +24,6 @@ stub-obj-y += mon-printf.o stub-obj-y += mon-set-error.o stub-obj-y += monitor-init.o stub-obj-y += notify-event.o -stub-obj-y += pci-drive-hot-add.o stub-obj-$(CONFIG_SPICE) += qemu-chr-open-spice.o stub-obj-y += qtest.o stub-obj-y += reset.o diff --git a/stubs/pci-drive-hot-add.c b/stubs/pci-drive-hot-add.c deleted file mode 100644 index 1d98145802..0000000000 --- a/stubs/pci-drive-hot-add.c +++ /dev/null @@ -1,10 +0,0 @@ -#include -#include -#include - -int pci_drive_hot_add(Monitor *mon, const QDict *qdict, DriveInfo *dinfo) -{ - /* On non-x86 we don't do PCI hotplug */ - monitor_printf(mon, "Can't hot-add drive to type %d\n", dinfo->type); - return -1; -} From 1d51570166171cd85dfcd08b2eac2f02a3fda6fe Mon Sep 17 00:00:00 2001 From: Tang Chen Date: Thu, 26 Feb 2015 09:16:43 +0800 Subject: [PATCH 121/130] acpi, mem-hotplug: use PC_DIMM_SLOT_PROP in acpi_memory_plug_cb(). Replace string "slot" in acpi_memory_plug_cb() with macro PC_DIMM_SLOT_PROP. Reviewed-by: Igor Mammedov Signed-off-by: Tang Chen Signed-off-by: Zhu Guihua Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/acpi/memory_hotplug.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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); From e32dccddb0b1fa335bf251c155e907f9d47accfd Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Sun, 1 Mar 2015 19:39:36 +0100 Subject: [PATCH 122/130] acpi-test-data: update after pci rewrite more trivial changes as more code has been rewritten in C. we also got rid of extra Scope operators. Signed-off-by: Michael S. Tsirkin --- tests/acpi-test-data/pc/SSDT | Bin 2480 -> 2476 bytes tests/acpi-test-data/pc/SSDT.bridge | Bin 4351 -> 4335 bytes tests/acpi-test-data/q35/SSDT | Bin 685 -> 681 bytes tests/acpi-test-data/q35/SSDT.bridge | Bin 702 -> 698 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/tests/acpi-test-data/pc/SSDT b/tests/acpi-test-data/pc/SSDT index dc5be2497b6c2015d7cbabb1ff0cd13e02b3e0e4..87c3e9fc0271f2b5826877a9f931c2428838f8a7 100644 GIT binary patch delta 56 zcmdlWyhfNSIM^j*4JQKwBj-l0Xhuf&&1sCDj1s>20nVNV98STmJ`B-K+`$G0@f`7v MEWdtGD<%UaP~Cda0+(yVTf+x4>mA}=ZJT7 z3F2X3V3>TIN#B@1*w6wl#LOVzT?Q5aX<&?Q(u8OT4)x<=KmywwqxGN F3jplmASnO< diff --git a/tests/acpi-test-data/q35/SSDT b/tests/acpi-test-data/q35/SSDT index 749f368e3034bfb491dcd8ced37936e0dcbba02a..6a5c0423b93dd9eda038dc4fd4af283f6bba9745 100644 GIT binary patch delta 49 zcmZ3>x{{SEIM^j*B@+V!g3b delta 53 zcmZ3g3b diff --git a/tests/acpi-test-data/q35/SSDT.bridge b/tests/acpi-test-data/q35/SSDT.bridge index c552782f5bcc57094a7d1375b67979b2efa48f1c..5fc83a034002df64500970fa64f07b58bc15f3ea 100644 GIT binary patch delta 49 zcmdnTx{H-7IM^j*7ZU>mW86kAenv*e%~Fh>j6&|L0nVNV(M{aJ1_tpQ@s2J*lPj5A E0V{qC00000 delta 53 zcmdnRx{sABIM^j*9}@!uqtiw%env*u%~Fh>jAGub0nVNV(M|lp1_tpQ@s2J*JPZsB IlS`Rg0aS_%00000 From 92144c70939d9d029807c10a038acd07289f71bd Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 19 Feb 2015 08:48:52 +0100 Subject: [PATCH 123/130] Makefile.target: binary depends on config-devices relink binary whenever config-devices.mak changes: this makes sense as we are adding/removing devices, so binary has to be relinked to be up to date. Signed-off-by: Michael S. Tsirkin --- Makefile.target | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Makefile.target b/Makefile.target index 58c6ae1d69..2262d89354 100644 --- a/Makefile.target +++ b/Makefile.target @@ -175,9 +175,11 @@ all-obj-y += $(common-obj-y) all-obj-y += $(target-obj-y) all-obj-$(CONFIG_SOFTMMU) += $(block-obj-y) +$(QEMU_PROG_BUILD): config-devices.mak + # build either PROG or PROGW $(QEMU_PROG_BUILD): $(all-obj-y) ../libqemuutil.a ../libqemustub.a - $(call LINK,$^) + $(call LINK, $(filter-out %.mak, $^)) gdbstub-xml.c: $(TARGET_XML_FILES) $(SRC_PATH)/scripts/feature_to_c.sh $(call quiet-command,rm -f $@ && $(SHELL) $(SRC_PATH)/scripts/feature_to_c.sh $@ $(TARGET_XML_FILES)," GEN $(TARGET_DIR)$@") From 48ce35b7645154eff6b685b3178aacf33f2ff871 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 2 Mar 2015 16:14:33 +0100 Subject: [PATCH 124/130] acpi: update generated files Fixes up build on systems without iasl. Signed-off-by: Michael S. Tsirkin --- hw/i386/acpi-dsdt.hex.generated | 195 ++++++++++++++++++++++++++-- hw/i386/q35-acpi-dsdt.hex.generated | 193 +++++++++++++++++++++++++-- hw/i386/ssdt-tpm.hex.generated | 6 +- 3 files changed, 374 insertions(+), 20 deletions(-) diff --git a/hw/i386/acpi-dsdt.hex.generated b/hw/i386/acpi-dsdt.hex.generated index a71e0cd1d8..1d35fb1402 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, -0x57, -0xd, +0x8, +0xe, 0x0, 0x0, 0x1, -0x26, +0x14, 0x42, 0x58, 0x50, @@ -2318,8 +2318,8 @@ static unsigned char AcpiDsdtAmlCode[] = { 0x53, 0x1, 0x10, -0x4d, -0xc, +0x42, +0x11, 0x5f, 0x53, 0x42, @@ -2416,6 +2416,32 @@ 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, @@ -2523,9 +2549,52 @@ static unsigned char AcpiDsdtAmlCode[] = { 0x3, 0x75, 0x60, -0x10, +0x5b, +0x82, +0x29, +0x50, +0x52, +0x45, +0x53, +0x8, +0x5f, +0x48, +0x49, 0x44, -0x2a, +0xc, +0x41, +0xd0, +0xa, +0x6, +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, 0x2e, 0x5f, 0x53, @@ -2537,8 +2606,8 @@ static unsigned char AcpiDsdtAmlCode[] = { 0x30, 0x5b, 0x82, -0x47, -0x29, +0x43, +0x30, 0x4d, 0x48, 0x50, @@ -2588,6 +2657,37 @@ 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, @@ -2609,12 +2709,89 @@ 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, diff --git a/hw/i386/q35-acpi-dsdt.hex.generated b/hw/i386/q35-acpi-dsdt.hex.generated index 28769d4753..0203b4b32e 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, -0x45, +0xf6, 0x1f, 0x0, 0x0, 0x1, -0x59, +0xa9, 0x42, 0x58, 0x50, @@ -6959,8 +6959,8 @@ static unsigned char Q35AcpiDsdtAmlCode[] = { 0x53, 0x1, 0x10, -0x4d, -0xc, +0x42, +0x11, 0x5f, 0x53, 0x42, @@ -7057,6 +7057,32 @@ 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, @@ -7164,9 +7190,52 @@ static unsigned char Q35AcpiDsdtAmlCode[] = { 0x3, 0x75, 0x60, -0x10, +0x5b, +0x82, +0x29, +0x50, +0x52, +0x45, +0x53, +0x8, +0x5f, +0x48, +0x49, 0x44, -0x2a, +0xc, +0x41, +0xd0, +0xa, +0x6, +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, 0x2e, 0x5f, 0x53, @@ -7178,8 +7247,8 @@ static unsigned char Q35AcpiDsdtAmlCode[] = { 0x30, 0x5b, 0x82, -0x47, -0x29, +0x43, +0x30, 0x4d, 0x48, 0x50, @@ -7229,6 +7298,37 @@ 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, @@ -7250,12 +7350,89 @@ 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, 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, From 2e5feadbf8133b9b108919a2f576943b448a1a06 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Tue, 3 Mar 2015 17:40:45 +0100 Subject: [PATCH 125/130] aml-build: fix build for glib < 2.22 g_ptr_array_new_with_free_func is there since glib 2.22, use the older g_ptr_array_foreach instead. Reported-by: Peter Maydell Signed-off-by: Michael S. Tsirkin --- hw/acpi/aml-build.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index 3e5949be10..876cada4b2 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -299,7 +299,7 @@ static Aml *aml_bundle(uint8_t op, AmlBlockFlags flags) return var; } -static void aml_free(gpointer data) +static void aml_free(gpointer data, gpointer user_data) { Aml *var = data; build_free_array(var->buf); @@ -310,13 +310,14 @@ Aml *init_aml_allocator(void) Aml *var; assert(!alloc_list); - alloc_list = g_ptr_array_new_with_free_func(aml_free); + 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; } From 24f938a682d934b133863eb421aac33592f7a09e Mon Sep 17 00:00:00 2001 From: Haifeng Gao Date: Sat, 28 Feb 2015 17:02:02 +0800 Subject: [PATCH 126/130] vhost user:support vhost user nic for non msi guests Currently, vhost user nic doesn't support non msi guests(like pxe stage) by default. Vhost user nic can't fall back to qemu like normal vhost net nic does. So we should enable it for non msi guests. Signed-off-by: Haifeng Gao Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- net/vhost-user.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/net/vhost-user.c b/net/vhost-user.c index 24e050c772..2435b0f826 100644 --- a/net/vhost-user.c +++ b/net/vhost-user.c @@ -18,7 +18,6 @@ typedef struct VhostUserState { NetClientState nc; CharDriverState *chr; - bool vhostforce; VHostNetState *vhost_net; } VhostUserState; @@ -51,7 +50,7 @@ static int vhost_user_start(VhostUserState *s) options.backend_type = VHOST_BACKEND_TYPE_USER; options.net_backend = &s->nc; options.opaque = s->chr; - options.force = s->vhostforce; + options.force = true; s->vhost_net = vhost_net_init(&options); @@ -133,8 +132,7 @@ static void net_vhost_user_event(void *opaque, int event) } static int net_vhost_user_init(NetClientState *peer, const char *device, - const char *name, CharDriverState *chr, - bool vhostforce) + const char *name, CharDriverState *chr) { NetClientState *nc; VhostUserState *s; @@ -149,7 +147,6 @@ static int net_vhost_user_init(NetClientState *peer, const char *device, /* We don't provide a receive callback */ s->nc.receive_disabled = 1; s->chr = chr; - s->vhostforce = vhostforce; qemu_chr_add_handlers(s->chr, NULL, NULL, net_vhost_user_event, s); @@ -230,7 +227,6 @@ int net_init_vhost_user(const NetClientOptions *opts, const char *name, { const NetdevVhostUserOptions *vhost_user_opts; CharDriverState *chr; - bool vhostforce; assert(opts->kind == NET_CLIENT_OPTIONS_KIND_VHOST_USER); vhost_user_opts = opts->vhost_user; @@ -247,12 +243,6 @@ int net_init_vhost_user(const NetClientOptions *opts, const char *name, return -1; } - /* vhostforce for non-MSIX */ - if (vhost_user_opts->has_vhostforce) { - vhostforce = vhost_user_opts->vhostforce; - } else { - vhostforce = false; - } - return net_vhost_user_init(peer, "vhost_user", name, chr, vhostforce); + return net_vhost_user_init(peer, "vhost_user", name, chr); } From 09d219a31cf87ed98150c0a9e772e54f470f2a01 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Wed, 4 Mar 2015 16:05:32 +0100 Subject: [PATCH 127/130] acpi: update generated files Fixes up build on systems without iasl. Signed-off-by: Michael S. Tsirkin --- hw/i386/acpi-dsdt.hex.generated | 647 +--------------------------- hw/i386/q35-acpi-dsdt.hex.generated | 599 +------------------------ 2 files changed, 22 insertions(+), 1224 deletions(-) diff --git a/hw/i386/acpi-dsdt.hex.generated b/hw/i386/acpi-dsdt.hex.generated index 1d35fb1402..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, -0x8, -0xe, +0x9a, +0xb, 0x0, 0x0, 0x1, -0x14, +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, -0x42, -0x11, +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,52 +2078,9 @@ static unsigned char AcpiDsdtAmlCode[] = { 0x3, 0x75, 0x60, -0x5b, -0x82, -0x29, -0x50, -0x52, -0x45, -0x53, -0x8, -0x5f, -0x48, -0x49, -0x44, -0xc, -0x41, -0xd0, -0xa, -0x6, -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, @@ -2606,8 +2092,8 @@ static unsigned char AcpiDsdtAmlCode[] = { 0x30, 0x5b, 0x82, -0x43, -0x30, +0x47, +0x29, 0x4d, 0x48, 0x50, @@ -2657,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, @@ -2709,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, @@ -3592,6 +2970,3 @@ static unsigned char AcpiDsdtAmlCode[] = { 0x46, 0x0 }; -static unsigned short piix_dsdt_applesmc_sta[] = { -0x353 -}; diff --git a/hw/i386/q35-acpi-dsdt.hex.generated b/hw/i386/q35-acpi-dsdt.hex.generated index 0203b4b32e..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, -0xf6, -0x1f, +0xb8, +0x1d, 0x0, 0x0, 0x1, -0xa9, +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, -0x42, -0x11, +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,52 +6767,9 @@ static unsigned char Q35AcpiDsdtAmlCode[] = { 0x3, 0x75, 0x60, -0x5b, -0x82, -0x29, -0x50, -0x52, -0x45, -0x53, -0x8, -0x5f, -0x48, -0x49, -0x44, -0xc, -0x41, -0xd0, -0xa, -0x6, -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, @@ -7247,8 +6781,8 @@ static unsigned char Q35AcpiDsdtAmlCode[] = { 0x30, 0x5b, 0x82, -0x43, -0x30, +0x47, +0x29, 0x4d, 0x48, 0x50, @@ -7298,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, @@ -7350,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, @@ -8182,6 +7608,3 @@ static unsigned char Q35AcpiDsdtAmlCode[] = { 0x46, 0x0 }; -static unsigned short q35_dsdt_applesmc_sta[] = { -0x3fa -}; From e71fd76454ac78f8feee69acb301263f2bc7a55c Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Sun, 8 Mar 2015 10:24:42 +0100 Subject: [PATCH 128/130] acpi-build: fix typo in comment Signed-off-by: Michael S. Tsirkin --- hw/i386/acpi-build.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index b94e47e734..d5e101641a 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -889,7 +889,7 @@ build_ssdt(GArray *table_data, GArray *linker, /* build "Name(CPON, Package() { One, One, ..., Zero, Zero, ... })" * * Note: The ability to create variable-sized packages was first - * ntroduced in ACPI 2.0. ACPI 1.0 only allowed fixed-size packages + * 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. */ From 56521fb88f7e3d2e3c7cf87d5f85e17e563c0df7 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Sun, 8 Mar 2015 10:36:52 +0100 Subject: [PATCH 129/130] aml-build: comment fix Signed-off-by: Michael S. Tsirkin --- include/hw/acpi/aml-build.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index f6735eaac2..17d3beb5a3 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -9,7 +9,7 @@ typedef enum { AML_NO_OPCODE = 0,/* has only data */ AML_OPCODE, /* has opcode optionally followed by data */ AML_PACKAGE, /* has opcode and uses PkgLength for its length */ - AML_EXT_PACKAGE, /* ame as AML_PACKAGE but also has 'ExOpPrefix' */ + AML_EXT_PACKAGE, /* Same as AML_PACKAGE but also has 'ExOpPrefix' */ AML_BUFFER, /* data encoded as 'DefBuffer' */ AML_RES_TEMPLATE, /* encoded as ResourceTemplate macro */ } AmlBlockFlags; From 59ea3e7532a85b15bd551335b27fa97db48efa8d Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Sun, 8 Mar 2015 11:49:21 +0100 Subject: [PATCH 130/130] acpi: drop unused code Recent changes left acpi_get_hex unused, and clag is unhappy about it: error: unused function 'acpi_get_hex' Drop it, as well as some unused macros. Signer-off-by: Michael S. Tsirkin --- hw/i386/acpi-build.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index d5e101641a..d0a5c85e10 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -467,20 +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); -} - - -#define ACPI_SSDT_SIGNATURE 0x54445353 /* SSDT */ -#define ACPI_SSDT_HEADER_LENGTH 36 - #include "hw/i386/ssdt-tpm.hex" - /* Assign BSEL property to all buses. In the future, this can be changed * to only assign to buses that support hotplug. */