aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2016-06-07 15:30:25 +0100
committerPeter Maydell <peter.maydell@linaro.org>2016-06-07 15:30:25 +0100
commit79cecb3520606c55f427752c0a7a4add8afe2413 (patch)
treead4688ed599b845865b07150cd003a47406a2b25 /hw
parentd5aebef884cabf197d51d2066a5beee8d0c721d4 (diff)
parentc02d7030c3c538312c7f464cb79b72c29a20df74 (diff)
downloadqemu-79cecb3520606c55f427752c0a7a4add8afe2413.zip
qemu-79cecb3520606c55f427752c0a7a4add8afe2413.tar.gz
qemu-79cecb3520606c55f427752c0a7a4add8afe2413.tar.bz2
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
pc, pci, virtio: new features, cleanups, fixes This includes some infrastructure for ipmi smbios tables. Beginning of acpi hotplug rework by Igor for supporting >255 CPUs. Misc cleanups and fixes. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> # gpg: Signature made Tue 07 Jun 2016 13:55:22 BST # gpg: using RSA key 0x281F0DB8D28D5469 # gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>" # gpg: aka "Michael S. Tsirkin <mst@redhat.com>" * remotes/mst/tags/for_upstream: (25 commits) virtio: move bi-endian target support to a single location pc-dimm: introduce realize callback pc-dimm: get memory region from ->get_memory_region() acpi: make bios_linker_loader_add_checksum() API offset based acpi: make bios_linker_loader_add_pointer() API offset based tpm: apci: cleanup TCPA table initialization acpi: cleanup bios_linker_loader_cleanup() acpi: simplify bios_linker API by removing redundant 'table' argument acpi: convert linker from GArray to BIOSLinker structure pc: use AcpiDeviceIfClass.send_event to issue GPE events acpi: extend ACPI interface to provide send_event hook pc: Postpone SMBIOS table installation to post machine init ipmi: rework the fwinfo to be fetched from the interface tests: acpi: update tables with consolidated legacy cpu-hotplug AML pc: acpi: cpuhp-legacy: switch ProcessorID to possible_cpus idx pc: acpi: simplify build_legacy_cpu_hotplug_aml() signature pc: acpi: consolidate legacy CPU hotplug in one file pc: acpi: mark current CPU hotplug functions as legacy pc: acpi: cpu-hotplug: make AML CPU_foo defines local to cpu_hotplug_acpi_table.c pc: acpi: consolidate \GPE._E02 with the rest of CPU hotplug AML ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r--hw/acpi/Makefile.objs2
-rw-r--r--hw/acpi/acpi_interface.c9
-rw-r--r--hw/acpi/aml-build.c52
-rw-r--r--hw/acpi/bios-linker-loader.c180
-rw-r--r--hw/acpi/core.c2
-rw-r--r--hw/acpi/cpu_hotplug.c246
-rw-r--r--hw/acpi/cpu_hotplug_acpi_table.c136
-rw-r--r--hw/acpi/ich9.c36
-rw-r--r--hw/acpi/memory_hotplug.c12
-rw-r--r--hw/acpi/nvdimm.c22
-rw-r--r--hw/acpi/pcihp.c10
-rw-r--r--hw/acpi/piix4.c23
-rw-r--r--hw/arm/virt-acpi-build.c56
-rw-r--r--hw/i386/acpi-build.c229
-rw-r--r--hw/i386/pc.c5
-rw-r--r--hw/ipmi/ipmi.c34
-rw-r--r--hw/ipmi/isa_ipmi_bt.c57
-rw-r--r--hw/ipmi/isa_ipmi_kcs.c56
-rw-r--r--hw/isa/lpc_ich9.c38
-rw-r--r--hw/mem/pc-dimm.c8
-rw-r--r--hw/virtio/vhost.c4
21 files changed, 620 insertions, 597 deletions
diff --git a/hw/acpi/Makefile.objs b/hw/acpi/Makefile.objs
index faee86c..66bd727 100644
--- a/hw/acpi/Makefile.objs
+++ b/hw/acpi/Makefile.objs
@@ -1,6 +1,6 @@
common-obj-$(CONFIG_ACPI_X86) += core.o piix4.o pcihp.o
common-obj-$(CONFIG_ACPI_X86_ICH) += ich9.o tco.o
-common-obj-$(CONFIG_ACPI_CPU_HOTPLUG) += cpu_hotplug.o cpu_hotplug_acpi_table.o
+common-obj-$(CONFIG_ACPI_CPU_HOTPLUG) += cpu_hotplug.o
common-obj-$(CONFIG_ACPI_MEMORY_HOTPLUG) += memory_hotplug.o memory_hotplug_acpi_table.o
obj-$(CONFIG_ACPI_NVDIMM) += nvdimm.o
common-obj-$(CONFIG_ACPI) += acpi_interface.o
diff --git a/hw/acpi/acpi_interface.c b/hw/acpi/acpi_interface.c
index d821313..6583917 100644
--- a/hw/acpi/acpi_interface.c
+++ b/hw/acpi/acpi_interface.c
@@ -2,6 +2,15 @@
#include "hw/acpi/acpi_dev_interface.h"
#include "qemu/module.h"
+void acpi_send_event(DeviceState *dev, AcpiEventStatusBits event)
+{
+ AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_GET_CLASS(dev);
+ if (adevc->send_event) {
+ AcpiDeviceIf *adev = ACPI_DEVICE_IF(dev);
+ adevc->send_event(adev, event);
+ }
+}
+
static void register_types(void)
{
static const TypeInfo acpi_dev_if_info = {
diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index cedb74e..123160a 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -24,7 +24,6 @@
#include "hw/acpi/aml-build.h"
#include "qemu/bswap.h"
#include "qemu/bitops.h"
-#include "hw/acpi/bios-linker-loader.h"
static GArray *build_alloc_array(void)
{
@@ -406,6 +405,15 @@ Aml *aml_return(Aml *val)
return var;
}
+/* ACPI 1.0b: 16.2.6.3 Debug Objects Encoding: DebugObj */
+Aml *aml_debug(void)
+{
+ Aml *var = aml_alloc();
+ build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
+ build_append_byte(var->buf, 0x31); /* DebugOp */
+ return var;
+}
+
/*
* ACPI 1.0b: 16.2.3 Data Objects Encoding:
* encodes: ByteConst, WordConst, DWordConst, QWordConst, ZeroOp, OneOp
@@ -1407,6 +1415,14 @@ Aml *aml_unicode(const char *str)
return var;
}
+/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefRefOf */
+Aml *aml_refof(Aml *arg)
+{
+ Aml *var = aml_opcode(0x71 /* RefOfOp */);
+ aml_append(var, arg);
+ return var;
+}
+
/* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefDerefOf */
Aml *aml_derefof(Aml *arg)
{
@@ -1473,10 +1489,12 @@ Aml *aml_concatenate(Aml *source1, Aml *source2, Aml *target)
}
void
-build_header(GArray *linker, GArray *table_data,
+build_header(BIOSLinker *linker, GArray *table_data,
AcpiTableHeader *h, const char *sig, int len, uint8_t rev,
const char *oem_id, const char *oem_table_id)
{
+ unsigned tbl_offset = (char *)h - table_data->data;
+ unsigned checksum_offset = (char *)&h->checksum - table_data->data;
memcpy(&h->signature, sig, 4);
h->length = cpu_to_le32(len);
h->revision = rev;
@@ -1497,10 +1515,9 @@ build_header(GArray *linker, GArray *table_data,
h->oem_revision = cpu_to_le32(1);
memcpy(h->asl_compiler_id, ACPI_BUILD_APPNAME4, 4);
h->asl_compiler_revision = cpu_to_le32(1);
- h->checksum = 0;
/* Checksum to be filled in by Guest linker */
bios_linker_loader_add_checksum(linker, ACPI_BUILD_TABLE_FILE,
- table_data, h, len, &h->checksum);
+ tbl_offset, len, checksum_offset);
}
void *acpi_data_push(GArray *table_data, unsigned size)
@@ -1518,7 +1535,7 @@ unsigned acpi_data_len(GArray *table)
void acpi_add_table(GArray *table_offsets, GArray *table_data)
{
- uint32_t offset = cpu_to_le32(table_data->len);
+ uint32_t offset = table_data->len;
g_array_append_val(table_offsets, offset);
}
@@ -1532,8 +1549,7 @@ void acpi_build_tables_init(AcpiBuildTables *tables)
void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre)
{
- void *linker_data = bios_linker_loader_cleanup(tables->linker);
- g_free(linker_data);
+ bios_linker_loader_cleanup(tables->linker);
g_array_free(tables->rsdp, true);
g_array_free(tables->table_data, true);
g_array_free(tables->tcpalog, mfre);
@@ -1541,24 +1557,26 @@ void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre)
/* Build rsdt table */
void
-build_rsdt(GArray *table_data, GArray *linker, GArray *table_offsets,
+build_rsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets,
const char *oem_id, const char *oem_table_id)
{
- AcpiRsdtDescriptorRev1 *rsdt;
- size_t rsdt_len;
int i;
- const int table_data_len = (sizeof(uint32_t) * table_offsets->len);
+ unsigned rsdt_entries_offset;
+ AcpiRsdtDescriptorRev1 *rsdt;
+ const unsigned table_data_len = (sizeof(uint32_t) * table_offsets->len);
+ const unsigned rsdt_entry_size = sizeof(rsdt->table_offset_entry[0]);
+ const size_t rsdt_len = sizeof(*rsdt) + table_data_len;
- rsdt_len = sizeof(*rsdt) + table_data_len;
rsdt = acpi_data_push(table_data, rsdt_len);
- memcpy(rsdt->table_offset_entry, table_offsets->data, table_data_len);
+ rsdt_entries_offset = (char *)rsdt->table_offset_entry - table_data->data;
for (i = 0; i < table_offsets->len; ++i) {
+ uint32_t ref_tbl_offset = g_array_index(table_offsets, uint32_t, i);
+ uint32_t rsdt_entry_offset = rsdt_entries_offset + rsdt_entry_size * i;
+
/* rsdt->table_offset_entry to be filled by Guest linker */
bios_linker_loader_add_pointer(linker,
- ACPI_BUILD_TABLE_FILE,
- ACPI_BUILD_TABLE_FILE,
- table_data, &rsdt->table_offset_entry[i],
- sizeof(uint32_t));
+ ACPI_BUILD_TABLE_FILE, rsdt_entry_offset, rsdt_entry_size,
+ ACPI_BUILD_TABLE_FILE, ref_tbl_offset);
}
build_header(linker, table_data,
(void *)rsdt, "RSDT", rsdt_len, 1, oem_id, oem_table_id);
diff --git a/hw/acpi/bios-linker-loader.c b/hw/acpi/bios-linker-loader.c
index 5153ab1..d963ebe 100644
--- a/hw/acpi/bios-linker-loader.c
+++ b/hw/acpi/bios-linker-loader.c
@@ -96,134 +96,170 @@ enum {
};
/*
- * bios_linker_loader_init: allocate a new linker file blob array.
+ * BiosLinkerFileEntry:
+ *
+ * An internal type used for book-keeping file entries
+ */
+typedef struct BiosLinkerFileEntry {
+ char *name; /* file name */
+ GArray *blob; /* data accosiated with @name */
+} BiosLinkerFileEntry;
+
+/*
+ * bios_linker_loader_init: allocate a new linker object instance.
*
* After initialization, linker commands can be added, and will
- * be stored in the array.
+ * be stored in the linker.cmd_blob array.
*/
-GArray *bios_linker_loader_init(void)
+BIOSLinker *bios_linker_loader_init(void)
{
- return g_array_new(false, true /* clear */, 1);
+ BIOSLinker *linker = g_new(BIOSLinker, 1);
+
+ linker->cmd_blob = g_array_new(false, true /* clear */, 1);
+ linker->file_list = g_array_new(false, true /* clear */,
+ sizeof(BiosLinkerFileEntry));
+ return linker;
}
-/* Free linker wrapper and return the linker array. */
-void *bios_linker_loader_cleanup(GArray *linker)
+/* Free linker wrapper */
+void bios_linker_loader_cleanup(BIOSLinker *linker)
{
- return g_array_free(linker, false);
+ int i;
+ BiosLinkerFileEntry *entry;
+
+ g_array_free(linker->cmd_blob, true);
+
+ for (i = 0; i < linker->file_list->len; i++) {
+ entry = &g_array_index(linker->file_list, BiosLinkerFileEntry, i);
+ g_free(entry->name);
+ }
+ g_array_free(linker->file_list, true);
+ g_free(linker);
+}
+
+static const BiosLinkerFileEntry *
+bios_linker_find_file(const BIOSLinker *linker, const char *name)
+{
+ int i;
+ BiosLinkerFileEntry *entry;
+
+ for (i = 0; i < linker->file_list->len; i++) {
+ entry = &g_array_index(linker->file_list, BiosLinkerFileEntry, i);
+ if (!strcmp(entry->name, name)) {
+ return entry;
+ }
+ }
+ return NULL;
}
/*
* bios_linker_loader_alloc: ask guest to load file into guest memory.
*
- * @linker: linker file blob array
- * @file: file to be loaded
+ * @linker: linker object instance
+ * @file_name: name of the file blob to be loaded
+ * @file_blob: pointer to blob corresponding to @file_name
* @alloc_align: required minimal alignment in bytes. Must be a power of 2.
* @alloc_fseg: request allocation in FSEG zone (useful for the RSDP ACPI table)
*
* Note: this command must precede any other linker command using this file.
*/
-void bios_linker_loader_alloc(GArray *linker,
- const char *file,
+void bios_linker_loader_alloc(BIOSLinker *linker,
+ const char *file_name,
+ GArray *file_blob,
uint32_t alloc_align,
bool alloc_fseg)
{
BiosLinkerLoaderEntry entry;
+ BiosLinkerFileEntry file = { g_strdup(file_name), file_blob};
assert(!(alloc_align & (alloc_align - 1)));
+ assert(!bios_linker_find_file(linker, file_name));
+ g_array_append_val(linker->file_list, file);
+
memset(&entry, 0, sizeof entry);
- strncpy(entry.alloc.file, file, sizeof entry.alloc.file - 1);
+ strncpy(entry.alloc.file, file_name, sizeof entry.alloc.file - 1);
entry.command = cpu_to_le32(BIOS_LINKER_LOADER_COMMAND_ALLOCATE);
entry.alloc.align = cpu_to_le32(alloc_align);
entry.alloc.zone = alloc_fseg ? BIOS_LINKER_LOADER_ALLOC_ZONE_FSEG :
BIOS_LINKER_LOADER_ALLOC_ZONE_HIGH;
/* Alloc entries must come first, so prepend them */
- g_array_prepend_vals(linker, &entry, sizeof entry);
+ g_array_prepend_vals(linker->cmd_blob, &entry, sizeof entry);
}
/*
- * bios_linker_loader_add_checksum: ask guest to add checksum of file data
- * into (same) file at the specified pointer.
+ * bios_linker_loader_add_checksum: ask guest to add checksum of ACPI
+ * table in the specified file at the specified offset.
*
* Checksum calculation simply sums -X for each byte X in the range
* using 8-bit math (i.e. ACPI checksum).
*
- * @linker: linker file blob array
+ * @linker: linker object instance
* @file: file that includes the checksum to be calculated
* and the data to be checksummed
- * @table: @file blob contents
- * @start, @size: range of data to checksum
- * @checksum: location of the checksum to be patched within file blob
- *
- * Notes:
- * - checksum byte initial value must have been pushed into @table
- * and reside at address @checksum.
- * - @size bytes must have been pushed into @table and reside at address
- * @start.
- * - Guest calculates checksum of specified range of data, result is added to
- * initial value at @checksum into copy of @file in Guest memory.
- * - Range might include the checksum itself.
- * - To avoid confusion, caller must always put 0x0 at @checksum.
- * - @file must be loaded into Guest memory using bios_linker_loader_alloc
+ * @start_offset, @size: range of data in the file to checksum,
+ * relative to the start of file blob
+ * @checksum_offset: location of the checksum to be patched within file blob,
+ * relative to the start of file blob
*/
-void bios_linker_loader_add_checksum(GArray *linker, const char *file,
- GArray *table,
- void *start, unsigned size,
- uint8_t *checksum)
+void bios_linker_loader_add_checksum(BIOSLinker *linker, const char *file_name,
+ unsigned start_offset, unsigned size,
+ unsigned checksum_offset)
{
BiosLinkerLoaderEntry entry;
- ptrdiff_t checksum_offset = (gchar *)checksum - table->data;
- ptrdiff_t start_offset = (gchar *)start - table->data;
+ const BiosLinkerFileEntry *file = bios_linker_find_file(linker, file_name);
- assert(checksum_offset >= 0);
- assert(start_offset >= 0);
- assert(checksum_offset + 1 <= table->len);
- assert(start_offset + size <= table->len);
- assert(*checksum == 0x0);
+ assert(file);
+ assert(start_offset < file->blob->len);
+ assert(start_offset + size <= file->blob->len);
+ assert(checksum_offset >= start_offset);
+ assert(checksum_offset + 1 <= start_offset + size);
+ *(file->blob->data + checksum_offset) = 0;
memset(&entry, 0, sizeof entry);
- strncpy(entry.cksum.file, file, sizeof entry.cksum.file - 1);
+ strncpy(entry.cksum.file, file_name, sizeof entry.cksum.file - 1);
entry.command = cpu_to_le32(BIOS_LINKER_LOADER_COMMAND_ADD_CHECKSUM);
entry.cksum.offset = cpu_to_le32(checksum_offset);
entry.cksum.start = cpu_to_le32(start_offset);
entry.cksum.length = cpu_to_le32(size);
- g_array_append_vals(linker, &entry, sizeof entry);
+ g_array_append_vals(linker->cmd_blob, &entry, sizeof entry);
}
/*
- * bios_linker_loader_add_pointer: ask guest to add address of source file
- * into destination file at the specified pointer.
+ * bios_linker_loader_add_pointer: ask guest to patch address in
+ * destination file with a pointer to source file
*
- * @linker: linker file blob array
+ * @linker: linker object instance
* @dest_file: destination file that must be changed
+ * @dst_patched_offset: location within destination file blob to be patched
+ * with the pointer to @src_file+@src_offset (i.e. source
+ * blob allocated in guest memory + @src_offset), in bytes
+ * @dst_patched_offset_size: size of the pointer to be patched
+ * at @dst_patched_offset in @dest_file blob, in bytes
* @src_file: source file who's address must be taken
- * @table: @dest_file blob contents array
- * @pointer: location of the pointer to be patched within destination file blob
- * @pointer_size: size of pointer to be patched, in bytes
- *
- * Notes:
- * - @pointer_size bytes must have been pushed into @table
- * and reside at address @pointer.
- * - Guest address is added to initial value at @pointer
- * into copy of @dest_file in Guest memory.
- * e.g. to get start of src_file in guest memory, put 0x0 there
- * to get address of a field at offset 0x10 in src_file, put 0x10 there
- * - Both @dest_file and @src_file must be
- * loaded into Guest memory using bios_linker_loader_alloc
+ * @src_offset: location within source file blob to which
+ * @dest_file+@dst_patched_offset will point to after
+ * firmware's executed ADD_POINTER command
*/
-void bios_linker_loader_add_pointer(GArray *linker,
+void bios_linker_loader_add_pointer(BIOSLinker *linker,
const char *dest_file,
+ uint32_t dst_patched_offset,
+ uint8_t dst_patched_size,
const char *src_file,
- GArray *table, void *pointer,
- uint8_t pointer_size)
+ uint32_t src_offset)
{
+ uint64_t le_src_offset;
BiosLinkerLoaderEntry entry;
- ptrdiff_t offset = (gchar *)pointer - table->data;
+ const BiosLinkerFileEntry *dst_file =
+ bios_linker_find_file(linker, dest_file);
+ const BiosLinkerFileEntry *source_file =
+ bios_linker_find_file(linker, src_file);
- assert(offset >= 0);
- assert(offset + pointer_size <= table->len);
+ assert(dst_patched_offset < dst_file->blob->len);
+ assert(dst_patched_offset + dst_patched_size <= dst_file->blob->len);
+ assert(src_offset < source_file->blob->len);
memset(&entry, 0, sizeof entry);
strncpy(entry.pointer.dest_file, dest_file,
@@ -231,10 +267,14 @@ 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(offset);
- entry.pointer.size = pointer_size;
- assert(pointer_size == 1 || pointer_size == 2 ||
- pointer_size == 4 || pointer_size == 8);
+ entry.pointer.offset = cpu_to_le32(dst_patched_offset);
+ entry.pointer.size = dst_patched_size;
+ assert(dst_patched_size == 1 || dst_patched_size == 2 ||
+ dst_patched_size == 4 || dst_patched_size == 8);
+
+ le_src_offset = cpu_to_le64(src_offset);
+ memcpy(dst_file->blob->data + dst_patched_offset,
+ &le_src_offset, dst_patched_size);
- g_array_append_vals(linker, &entry, sizeof entry);
+ g_array_append_vals(linker->cmd_blob, &entry, sizeof entry);
}
diff --git a/hw/acpi/core.c b/hw/acpi/core.c
index 1ffd155..d24b9a9 100644
--- a/hw/acpi/core.c
+++ b/hw/acpi/core.c
@@ -698,7 +698,7 @@ uint32_t acpi_gpe_ioport_readb(ACPIREGS *ar, uint32_t addr)
}
void acpi_send_gpe_event(ACPIREGS *ar, qemu_irq irq,
- AcpiGPEStatusBits status)
+ AcpiEventStatusBits status)
{
ar->gpe.sts[0] |= status;
acpi_update_sci(ar, irq);
diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
index 4d86743..fe75bd9 100644
--- a/hw/acpi/cpu_hotplug.c
+++ b/hw/acpi/cpu_hotplug.c
@@ -14,6 +14,14 @@
#include "hw/acpi/cpu_hotplug.h"
#include "qapi/error.h"
#include "qom/cpu.h"
+#include "hw/i386/pc.h"
+
+#define CPU_EJECT_METHOD "CPEJ"
+#define CPU_MAT_METHOD "CPMA"
+#define CPU_ON_BITMAP "CPON"
+#define CPU_STATUS_METHOD "CPST"
+#define CPU_STATUS_MAP "PRS"
+#define CPU_SCAN_METHOD "PRSC"
static uint64_t cpu_status_read(void *opaque, hwaddr addr, unsigned int size)
{
@@ -54,19 +62,18 @@ static void acpi_set_cpu_present_bit(AcpiCpuHotplug *g, CPUState *cpu,
g->sts[cpu_id / 8] |= (1 << (cpu_id % 8));
}
-void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
- AcpiCpuHotplug *g, DeviceState *dev, Error **errp)
+void legacy_acpi_cpu_plug_cb(HotplugHandler *hotplug_dev,
+ AcpiCpuHotplug *g, DeviceState *dev, Error **errp)
{
acpi_set_cpu_present_bit(g, CPU(dev), errp);
if (*errp != NULL) {
return;
}
-
- acpi_send_gpe_event(ar, irq, ACPI_CPU_HOTPLUG_STATUS);
+ acpi_send_event(DEVICE(hotplug_dev), ACPI_CPU_HOTPLUG_STATUS);
}
-void acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner,
- AcpiCpuHotplug *gpe_cpu, uint16_t base)
+void legacy_acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner,
+ AcpiCpuHotplug *gpe_cpu, uint16_t base)
{
CPUState *cpu;
@@ -77,3 +84,230 @@ void acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner,
gpe_cpu, "acpi-cpu-hotplug", ACPI_GPE_PROC_LEN);
memory_region_add_subregion(parent, base, &gpe_cpu->io);
}
+
+void build_legacy_cpu_hotplug_aml(Aml *ctx, MachineState *machine,
+ uint16_t io_base)
+{
+ Aml *dev;
+ Aml *crs;
+ Aml *pkg;
+ Aml *field;
+ Aml *method;
+ Aml *if_ctx;
+ Aml *else_ctx;
+ int i, apic_idx;
+ Aml *sb_scope = aml_scope("_SB");
+ uint8_t madt_tmpl[8] = {0x00, 0x08, 0x00, 0x00, 0x00, 0, 0, 0};
+ Aml *cpu_id = aml_arg(1);
+ Aml *apic_id = aml_arg(0);
+ Aml *cpu_on = aml_local(0);
+ Aml *madt = aml_local(1);
+ Aml *cpus_map = aml_name(CPU_ON_BITMAP);
+ Aml *zero = aml_int(0);
+ Aml *one = aml_int(1);
+ MachineClass *mc = MACHINE_GET_CLASS(machine);
+ CPUArchIdList *apic_ids = mc->possible_cpu_arch_ids(machine);
+ PCMachineState *pcms = PC_MACHINE(machine);
+
+ /*
+ * _MAT method - creates an madt apic buffer
+ * apic_id = Arg0 = Local APIC ID
+ * cpu_id = Arg1 = Processor ID
+ * cpu_on = Local0 = CPON flag for this cpu
+ * madt = Local1 = Buffer (in madt apic form) to return
+ */
+ method = aml_method(CPU_MAT_METHOD, 2, AML_NOTSERIALIZED);
+ aml_append(method,
+ aml_store(aml_derefof(aml_index(cpus_map, apic_id)), cpu_on));
+ aml_append(method,
+ aml_store(aml_buffer(sizeof(madt_tmpl), madt_tmpl), madt));
+ /* Update the processor id, lapic id, and enable/disable status */
+ aml_append(method, aml_store(cpu_id, aml_index(madt, aml_int(2))));
+ aml_append(method, aml_store(apic_id, aml_index(madt, aml_int(3))));
+ aml_append(method, aml_store(cpu_on, aml_index(madt, aml_int(4))));
+ aml_append(method, aml_return(madt));
+ aml_append(sb_scope, method);
+
+ /*
+ * _STA method - return ON status of cpu
+ * apic_id = Arg0 = Local APIC ID
+ * cpu_on = Local0 = CPON flag for this cpu
+ */
+ method = aml_method(CPU_STATUS_METHOD, 1, AML_NOTSERIALIZED);
+ aml_append(method,
+ aml_store(aml_derefof(aml_index(cpus_map, apic_id)), cpu_on));
+ if_ctx = aml_if(cpu_on);
+ {
+ aml_append(if_ctx, aml_return(aml_int(0xF)));
+ }
+ aml_append(method, if_ctx);
+ else_ctx = aml_else();
+ {
+ aml_append(else_ctx, aml_return(zero));
+ }
+ aml_append(method, else_ctx);
+ aml_append(sb_scope, method);
+
+ method = aml_method(CPU_EJECT_METHOD, 2, AML_NOTSERIALIZED);
+ aml_append(method, aml_sleep(200));
+ aml_append(sb_scope, method);
+
+ method = aml_method(CPU_SCAN_METHOD, 0, AML_NOTSERIALIZED);
+ {
+ Aml *while_ctx, *if_ctx2, *else_ctx2;
+ Aml *bus_check_evt = aml_int(1);
+ Aml *remove_evt = aml_int(3);
+ Aml *status_map = aml_local(5); /* Local5 = active cpu bitmap */
+ Aml *byte = aml_local(2); /* Local2 = last read byte from bitmap */
+ Aml *idx = aml_local(0); /* Processor ID / APIC ID iterator */
+ Aml *is_cpu_on = aml_local(1); /* Local1 = CPON flag for cpu */
+ Aml *status = aml_local(3); /* Local3 = active state for cpu */
+
+ aml_append(method, aml_store(aml_name(CPU_STATUS_MAP), status_map));
+ aml_append(method, aml_store(zero, byte));
+ aml_append(method, aml_store(zero, idx));
+
+ /* While (idx < SizeOf(CPON)) */
+ while_ctx = aml_while(aml_lless(idx, aml_sizeof(cpus_map)));
+ aml_append(while_ctx,
+ aml_store(aml_derefof(aml_index(cpus_map, idx)), is_cpu_on));
+
+ if_ctx = aml_if(aml_and(idx, aml_int(0x07), NULL));
+ {
+ /* Shift down previously read bitmap byte */
+ aml_append(if_ctx, aml_shiftright(byte, one, byte));
+ }
+ aml_append(while_ctx, if_ctx);
+
+ else_ctx = aml_else();
+ {
+ /* Read next byte from cpu bitmap */
+ aml_append(else_ctx, aml_store(aml_derefof(aml_index(status_map,
+ aml_shiftright(idx, aml_int(3), NULL))), byte));
+ }
+ aml_append(while_ctx, else_ctx);
+
+ aml_append(while_ctx, aml_store(aml_and(byte, one, NULL), status));
+ if_ctx = aml_if(aml_lnot(aml_equal(is_cpu_on, status)));
+ {
+ /* State change - update CPON with new state */
+ aml_append(if_ctx, aml_store(status, aml_index(cpus_map, idx)));
+ if_ctx2 = aml_if(aml_equal(status, one));
+ {
+ aml_append(if_ctx2,
+ aml_call2(AML_NOTIFY_METHOD, idx, bus_check_evt));
+ }
+ aml_append(if_ctx, if_ctx2);
+ else_ctx2 = aml_else();
+ {
+ aml_append(else_ctx2,
+ aml_call2(AML_NOTIFY_METHOD, idx, remove_evt));
+ }
+ }
+ aml_append(if_ctx, else_ctx2);
+ aml_append(while_ctx, if_ctx);
+
+ aml_append(while_ctx, aml_increment(idx)); /* go to next cpu */
+ aml_append(method, while_ctx);
+ }
+ aml_append(sb_scope, method);
+
+ /* 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(pcms->apic_id_limit <= ACPI_CPU_HOTPLUG_ID_LIMIT);
+
+ /* 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, io_base, io_base, 1, ACPI_GPE_PROC_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, aml_int(io_base), ACPI_GPE_PROC_LEN));
+ field = aml_field("PRST", AML_BYTE_ACC, AML_NOLOCK, AML_PRESERVE);
+ aml_append(field, aml_named_field("PRS", 256));
+ aml_append(sb_scope, field);
+
+ /* build Processor object for each processor */
+ for (i = 0; i < apic_ids->len; i++) {
+ int apic_id = apic_ids->cpus[i].arch_id;
+
+ assert(apic_id < ACPI_CPU_HOTPLUG_ID_LIMIT);
+
+ dev = aml_processor(i, 0, 0, "CP%.02X", apic_id);
+
+ method = aml_method("_MAT", 0, AML_NOTSERIALIZED);
+ aml_append(method,
+ aml_return(aml_call2(CPU_MAT_METHOD, aml_int(apic_id), aml_int(i))
+ ));
+ aml_append(dev, method);
+
+ method = aml_method("_STA", 0, AML_NOTSERIALIZED);
+ aml_append(method,
+ aml_return(aml_call1(CPU_STATUS_METHOD, aml_int(apic_id))));
+ aml_append(dev, method);
+
+ method = aml_method("_EJ0", 1, AML_NOTSERIALIZED);
+ aml_append(method,
+ aml_return(aml_call2(CPU_EJECT_METHOD, aml_int(apic_id),
+ 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 = APIC ID */
+ method = aml_method(AML_NOTIFY_METHOD, 2, AML_NOTSERIALIZED);
+ for (i = 0; i < apic_ids->len; i++) {
+ int apic_id = apic_ids->cpus[i].arch_id;
+
+ if_ctx = aml_if(aml_equal(aml_arg(0), aml_int(apic_id)));
+ aml_append(if_ctx,
+ aml_notify(aml_name("CP%.02X", apic_id), aml_arg(1))
+ );
+ aml_append(method, if_ctx);
+ }
+ aml_append(sb_scope, method);
+
+ /* build "Name(CPON, Package() { One, One, ..., Zero, Zero, ... })"
+ *
+ * Note: The ability to create variable-sized packages was first
+ * introduced in ACPI 2.0. ACPI 1.0 only allowed fixed-size packages
+ * ith up to 255 elements. Windows guests up to win2k8 fail when
+ * VarPackageOp is used.
+ */
+ pkg = pcms->apic_id_limit <= 255 ? aml_package(pcms->apic_id_limit) :
+ aml_varpackage(pcms->apic_id_limit);
+
+ for (i = 0, apic_idx = 0; i < apic_ids->len; i++) {
+ int apic_id = apic_ids->cpus[i].arch_id;
+
+ for (; apic_idx < apic_id; apic_idx++) {
+ aml_append(pkg, aml_int(0));
+ }
+ aml_append(pkg, aml_int(apic_ids->cpus[i].cpu ? 1 : 0));
+ apic_idx = apic_id + 1;
+ }
+ aml_append(sb_scope, aml_name_decl(CPU_ON_BITMAP, pkg));
+ g_free(apic_ids);
+
+ aml_append(ctx, sb_scope);
+
+ method = aml_method("\\_GPE._E02", 0, AML_NOTSERIALIZED);
+ aml_append(method, aml_call0("\\_SB." CPU_SCAN_METHOD));
+ aml_append(ctx, method);
+}
diff --git a/hw/acpi/cpu_hotplug_acpi_table.c b/hw/acpi/cpu_hotplug_acpi_table.c
deleted file mode 100644
index 97bb109..0000000
--- a/hw/acpi/cpu_hotplug_acpi_table.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-#include "hw/acpi/cpu_hotplug.h"
-
-void build_cpu_hotplug_aml(Aml *ctx)
-{
- Aml *method;
- Aml *if_ctx;
- Aml *else_ctx;
- Aml *sb_scope = aml_scope("_SB");
- uint8_t madt_tmpl[8] = {0x00, 0x08, 0x00, 0x00, 0x00, 0, 0, 0};
- Aml *cpu_id = aml_arg(0);
- Aml *cpu_on = aml_local(0);
- Aml *madt = aml_local(1);
- Aml *cpus_map = aml_name(CPU_ON_BITMAP);
- Aml *zero = aml_int(0);
- Aml *one = aml_int(1);
-
- /*
- * _MAT method - creates an madt apic buffer
- * cpu_id = Arg0 = Processor ID = Local APIC ID
- * cpu_on = Local0 = CPON flag for this cpu
- * madt = Local1 = Buffer (in madt apic form) to return
- */
- method = aml_method(CPU_MAT_METHOD, 1, AML_NOTSERIALIZED);
- aml_append(method,
- aml_store(aml_derefof(aml_index(cpus_map, cpu_id)), cpu_on));
- aml_append(method,
- aml_store(aml_buffer(sizeof(madt_tmpl), madt_tmpl), madt));
- /* Update the processor id, lapic id, and enable/disable status */
- aml_append(method, aml_store(cpu_id, aml_index(madt, aml_int(2))));
- aml_append(method, aml_store(cpu_id, aml_index(madt, aml_int(3))));
- aml_append(method, aml_store(cpu_on, aml_index(madt, aml_int(4))));
- aml_append(method, aml_return(madt));
- aml_append(sb_scope, method);
-
- /*
- * _STA method - return ON status of cpu
- * cpu_id = Arg0 = Processor ID = Local APIC ID
- * cpu_on = Local0 = CPON flag for this cpu
- */
- method = aml_method(CPU_STATUS_METHOD, 1, AML_NOTSERIALIZED);
- aml_append(method,
- aml_store(aml_derefof(aml_index(cpus_map, cpu_id)), cpu_on));
- if_ctx = aml_if(cpu_on);
- {
- aml_append(if_ctx, aml_return(aml_int(0xF)));
- }
- aml_append(method, if_ctx);
- else_ctx = aml_else();
- {
- aml_append(else_ctx, aml_return(zero));
- }
- aml_append(method, else_ctx);
- aml_append(sb_scope, method);
-
- method = aml_method(CPU_EJECT_METHOD, 2, AML_NOTSERIALIZED);
- aml_append(method, aml_sleep(200));
- aml_append(sb_scope, method);
-
- method = aml_method(CPU_SCAN_METHOD, 0, AML_NOTSERIALIZED);
- {
- Aml *while_ctx, *if_ctx2, *else_ctx2;
- Aml *bus_check_evt = aml_int(1);
- Aml *remove_evt = aml_int(3);
- Aml *status_map = aml_local(5); /* Local5 = active cpu bitmap */
- Aml *byte = aml_local(2); /* Local2 = last read byte from bitmap */
- Aml *idx = aml_local(0); /* Processor ID / APIC ID iterator */
- Aml *is_cpu_on = aml_local(1); /* Local1 = CPON flag for cpu */
- Aml *status = aml_local(3); /* Local3 = active state for cpu */
-
- aml_append(method, aml_store(aml_name(CPU_STATUS_MAP), status_map));
- aml_append(method, aml_store(zero, byte));
- aml_append(method, aml_store(zero, idx));
-
- /* While (idx < SizeOf(CPON)) */
- while_ctx = aml_while(aml_lless(idx, aml_sizeof(cpus_map)));
- aml_append(while_ctx,
- aml_store(aml_derefof(aml_index(cpus_map, idx)), is_cpu_on));
-
- if_ctx = aml_if(aml_and(idx, aml_int(0x07), NULL));
- {
- /* Shift down previously read bitmap byte */
- aml_append(if_ctx, aml_shiftright(byte, one, byte));
- }
- aml_append(while_ctx, if_ctx);
-
- else_ctx = aml_else();
- {
- /* Read next byte from cpu bitmap */
- aml_append(else_ctx, aml_store(aml_derefof(aml_index(status_map,
- aml_shiftright(idx, aml_int(3), NULL))), byte));
- }
- aml_append(while_ctx, else_ctx);
-
- aml_append(while_ctx, aml_store(aml_and(byte, one, NULL), status));
- if_ctx = aml_if(aml_lnot(aml_equal(is_cpu_on, status)));
- {
- /* State change - update CPON with new state */
- aml_append(if_ctx, aml_store(status, aml_index(cpus_map, idx)));
- if_ctx2 = aml_if(aml_equal(status, one));
- {
- aml_append(if_ctx2,
- aml_call2(AML_NOTIFY_METHOD, idx, bus_check_evt));
- }
- aml_append(if_ctx, if_ctx2);
- else_ctx2 = aml_else();
- {
- aml_append(else_ctx2,
- aml_call2(AML_NOTIFY_METHOD, idx, remove_evt));
- }
- }
- aml_append(if_ctx, else_ctx2);
- aml_append(while_ctx, if_ctx);
-
- aml_append(while_ctx, aml_increment(idx)); /* go to next cpu */
- aml_append(method, while_ctx);
- }
- aml_append(sb_scope, method);
-
- aml_append(ctx, sb_scope);
-}
diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 27e978f..853c9c4 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -273,8 +273,8 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
pm->powerdown_notifier.notify = pm_powerdown_req;
qemu_register_powerdown_notifier(&pm->powerdown_notifier);
- acpi_cpu_hotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci),
- &pm->gpe_cpu, ICH9_CPU_HOTPLUG_IO_BASE);
+ legacy_acpi_cpu_hotplug_init(pci_address_space_io(lpc_pci),
+ OBJECT(lpc_pci), &pm->gpe_cpu, ICH9_CPU_HOTPLUG_IO_BASE);
if (pm->acpi_memory_hotplug.is_enabled) {
acpi_memory_hotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci),
@@ -430,39 +430,47 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm, Error **errp)
NULL);
}
-void ich9_pm_device_plug_cb(ICH9LPCPMRegs *pm, DeviceState *dev, Error **errp)
+void ich9_pm_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
+ Error **errp)
{
- if (pm->acpi_memory_hotplug.is_enabled &&
+ ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev);
+
+ if (lpc->pm.acpi_memory_hotplug.is_enabled &&
object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
- acpi_memory_plug_cb(&pm->acpi_regs, pm->irq, &pm->acpi_memory_hotplug,
+ acpi_memory_plug_cb(hotplug_dev, &lpc->pm.acpi_memory_hotplug,
dev, errp);
} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
- acpi_cpu_plug_cb(&pm->acpi_regs, pm->irq, &pm->gpe_cpu, dev, errp);
+ legacy_acpi_cpu_plug_cb(hotplug_dev, &lpc->pm.gpe_cpu, dev, errp);
} else {
error_setg(errp, "acpi: device plug request for not supported device"
" type: %s", object_get_typename(OBJECT(dev)));
}
}
-void ich9_pm_device_unplug_request_cb(ICH9LPCPMRegs *pm, DeviceState *dev,
- Error **errp)
+void ich9_pm_device_unplug_request_cb(HotplugHandler *hotplug_dev,
+ DeviceState *dev, Error **errp)
{
- if (pm->acpi_memory_hotplug.is_enabled &&
+ ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev);
+
+ if (lpc->pm.acpi_memory_hotplug.is_enabled &&
object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
- acpi_memory_unplug_request_cb(&pm->acpi_regs, pm->irq,
- &pm->acpi_memory_hotplug, dev, errp);
+ acpi_memory_unplug_request_cb(hotplug_dev,
+ &lpc->pm.acpi_memory_hotplug, dev,
+ errp);
} else {
error_setg(errp, "acpi: device unplug request for not supported device"
" type: %s", object_get_typename(OBJECT(dev)));
}
}
-void ich9_pm_device_unplug_cb(ICH9LPCPMRegs *pm, DeviceState *dev,
+void ich9_pm_device_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
Error **errp)
{
- if (pm->acpi_memory_hotplug.is_enabled &&
+ ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev);
+
+ if (lpc->pm.acpi_memory_hotplug.is_enabled &&
object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
- acpi_memory_unplug_cb(&pm->acpi_memory_hotplug, dev, errp);
+ acpi_memory_unplug_cb(&lpc->pm.acpi_memory_hotplug, dev, errp);
} else {
error_setg(errp, "acpi: device unplug for not supported device"
" type: %s", object_get_typename(OBJECT(dev)));
diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c
index f65a3a2..ec4e64b 100644
--- a/hw/acpi/memory_hotplug.c
+++ b/hw/acpi/memory_hotplug.c
@@ -228,7 +228,7 @@ acpi_memory_slot_status(MemHotplugState *mem_st,
return &mem_st->devs[slot];
}
-void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st,
+void acpi_memory_plug_cb(HotplugHandler *hotplug_dev, MemHotplugState *mem_st,
DeviceState *dev, Error **errp)
{
MemStatus *mdev;
@@ -247,13 +247,11 @@ void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st,
mdev->is_enabled = true;
if (dev->hotplugged) {
mdev->is_inserting = true;
-
- /* do ACPI magic */
- acpi_send_gpe_event(ar, irq, ACPI_MEMORY_HOTPLUG_STATUS);
+ acpi_send_event(DEVICE(hotplug_dev), ACPI_MEMORY_HOTPLUG_STATUS);
}
}
-void acpi_memory_unplug_request_cb(ACPIREGS *ar, qemu_irq irq,
+void acpi_memory_unplug_request_cb(HotplugHandler *hotplug_dev,
MemHotplugState *mem_st,
DeviceState *dev, Error **errp)
{
@@ -265,9 +263,7 @@ void acpi_memory_unplug_request_cb(ACPIREGS *ar, qemu_irq irq,
}
mdev->is_removing = true;
-
- /* Do ACPI magic */
- acpi_send_gpe_event(ar, irq, ACPI_MEMORY_HOTPLUG_STATUS);
+ acpi_send_event(DEVICE(hotplug_dev), ACPI_MEMORY_HOTPLUG_STATUS);
}
void acpi_memory_unplug_cb(MemHotplugState *mem_st,
diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c
index fb925dc..b4c2262 100644
--- a/hw/acpi/nvdimm.c
+++ b/hw/acpi/nvdimm.c
@@ -353,7 +353,7 @@ static GArray *nvdimm_build_device_structure(GSList *device_list)
}
static void nvdimm_build_nfit(GSList *device_list, GArray *table_offsets,
- GArray *table_data, GArray *linker)
+ GArray *table_data, BIOSLinker *linker)
{
GArray *structures = nvdimm_build_device_structure(device_list);
unsigned int header;
@@ -579,7 +579,8 @@ static void nvdimm_build_nvdimm_devices(GSList *device_list, Aml *root_dev)
}
static void nvdimm_build_ssdt(GSList *device_list, GArray *table_offsets,
- GArray *table_data, GArray *linker)
+ GArray *table_data, BIOSLinker *linker,
+ GArray *dsm_dma_arrea)
{
Aml *ssdt, *sb_scope, *dev, *field;
int mem_addr_offset, nvdimm_ssdt;
@@ -678,12 +679,12 @@ static void nvdimm_build_ssdt(GSList *device_list, GArray *table_offsets,
mem_addr_offset = build_append_named_dword(table_data,
NVDIMM_ACPI_MEM_ADDR);
- bios_linker_loader_alloc(linker, NVDIMM_DSM_MEM_FILE, sizeof(NvdimmDsmIn),
- false /* high memory */);
- bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE,
- NVDIMM_DSM_MEM_FILE, table_data,
- table_data->data + mem_addr_offset,
- sizeof(uint32_t));
+ bios_linker_loader_alloc(linker,
+ NVDIMM_DSM_MEM_FILE, dsm_dma_arrea,
+ sizeof(NvdimmDsmIn), false /* high memory */);
+ bios_linker_loader_add_pointer(linker,
+ ACPI_BUILD_TABLE_FILE, mem_addr_offset, sizeof(uint32_t),
+ NVDIMM_DSM_MEM_FILE, 0);
build_header(linker, table_data,
(void *)(table_data->data + nvdimm_ssdt),
"SSDT", table_data->len - nvdimm_ssdt, 1, NULL, "NVDIMM");
@@ -691,7 +692,7 @@ static void nvdimm_build_ssdt(GSList *device_list, GArray *table_offsets,
}
void nvdimm_build_acpi(GArray *table_offsets, GArray *table_data,
- GArray *linker)
+ BIOSLinker *linker, GArray *dsm_dma_arrea)
{
GSList *device_list;
@@ -701,6 +702,7 @@ void nvdimm_build_acpi(GArray *table_offsets, GArray *table_data,
return;
}
nvdimm_build_nfit(device_list, table_offsets, table_data, linker);
- nvdimm_build_ssdt(device_list, table_offsets, table_data, linker);
+ nvdimm_build_ssdt(device_list, table_offsets, table_data, linker,
+ dsm_dma_arrea);
g_slist_free(device_list);
}
diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
index 71f4c4e..d957d1e 100644
--- a/hw/acpi/pcihp.c
+++ b/hw/acpi/pcihp.c
@@ -182,7 +182,7 @@ void acpi_pcihp_reset(AcpiPciHpState *s)
acpi_pcihp_update(s);
}
-void acpi_pcihp_device_plug_cb(ACPIREGS *ar, qemu_irq irq, AcpiPciHpState *s,
+void acpi_pcihp_device_plug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
DeviceState *dev, Error **errp)
{
PCIDevice *pdev = PCI_DEVICE(dev);
@@ -202,11 +202,10 @@ void acpi_pcihp_device_plug_cb(ACPIREGS *ar, qemu_irq irq, AcpiPciHpState *s,
}
s->acpi_pcihp_pci_status[bsel].up |= (1U << slot);
-
- acpi_send_gpe_event(ar, irq, ACPI_PCI_HOTPLUG_STATUS);
+ acpi_send_event(DEVICE(hotplug_dev), ACPI_PCI_HOTPLUG_STATUS);
}
-void acpi_pcihp_device_unplug_cb(ACPIREGS *ar, qemu_irq irq, AcpiPciHpState *s,
+void acpi_pcihp_device_unplug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s,
DeviceState *dev, Error **errp)
{
PCIDevice *pdev = PCI_DEVICE(dev);
@@ -219,8 +218,7 @@ void acpi_pcihp_device_unplug_cb(ACPIREGS *ar, qemu_irq irq, AcpiPciHpState *s,
}
s->acpi_pcihp_pci_status[bsel].down |= (1U << slot);
-
- acpi_send_gpe_event(ar, irq, ACPI_PCI_HOTPLUG_STATUS);
+ acpi_send_event(DEVICE(hotplug_dev), ACPI_PCI_HOTPLUG_STATUS);
}
static uint64_t pci_read(void *opaque, hwaddr addr, unsigned int size)
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index b3e3bb3..c48cb1b 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -348,12 +348,11 @@ static void piix4_device_plug_cb(HotplugHandler *hotplug_dev,
if (s->acpi_memory_hotplug.is_enabled &&
object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
- acpi_memory_plug_cb(&s->ar, s->irq, &s->acpi_memory_hotplug, dev, errp);
+ acpi_memory_plug_cb(hotplug_dev, &s->acpi_memory_hotplug, dev, errp);
} else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
- acpi_pcihp_device_plug_cb(&s->ar, s->irq, &s->acpi_pci_hotplug, dev,
- errp);
+ acpi_pcihp_device_plug_cb(hotplug_dev, &s->acpi_pci_hotplug, dev, errp);
} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
- acpi_cpu_plug_cb(&s->ar, s->irq, &s->gpe_cpu, dev, errp);
+ legacy_acpi_cpu_plug_cb(hotplug_dev, &s->gpe_cpu, dev, errp);
} else {
error_setg(errp, "acpi: device plug request for not supported device"
" type: %s", object_get_typename(OBJECT(dev)));
@@ -367,10 +366,10 @@ static void piix4_device_unplug_request_cb(HotplugHandler *hotplug_dev,
if (s->acpi_memory_hotplug.is_enabled &&
object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
- acpi_memory_unplug_request_cb(&s->ar, s->irq, &s->acpi_memory_hotplug,
+ acpi_memory_unplug_request_cb(hotplug_dev, &s->acpi_memory_hotplug,
dev, errp);
} else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
- acpi_pcihp_device_unplug_cb(&s->ar, s->irq, &s->acpi_pci_hotplug, dev,
+ acpi_pcihp_device_unplug_cb(hotplug_dev, &s->acpi_pci_hotplug, dev,
errp);
} else {
error_setg(errp, "acpi: device unplug request for not supported device"
@@ -571,8 +570,8 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion *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,
- PIIX4_CPU_HOTPLUG_IO_BASE);
+ legacy_acpi_cpu_hotplug_init(parent, OBJECT(s), &s->gpe_cpu,
+ PIIX4_CPU_HOTPLUG_IO_BASE);
if (s->acpi_memory_hotplug.is_enabled) {
acpi_memory_hotplug_init(parent, OBJECT(s), &s->acpi_memory_hotplug);
@@ -586,6 +585,13 @@ static void piix4_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list)
acpi_memory_ospm_status(&s->acpi_memory_hotplug, list);
}
+static void piix4_send_gpe(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
+{
+ PIIX4PMState *s = PIIX4_PM(adev);
+
+ acpi_send_gpe_event(&s->ar, s->irq, ev);
+}
+
static Property piix4_pm_properties[] = {
DEFINE_PROP_UINT32("smb_io_base", PIIX4PMState, smb_io_base, 0),
DEFINE_PROP_UINT8(ACPI_PM_PROP_S3_DISABLED, PIIX4PMState, disable_s3, 0),
@@ -624,6 +630,7 @@ static void piix4_pm_class_init(ObjectClass *klass, void *data)
hc->unplug_request = piix4_device_unplug_request_cb;
hc->unplug = piix4_device_unplug_cb;
adevc->ospm_status = piix4_ospm_status;
+ adevc->send_event = piix4_send_gpe;
}
static const TypeInfo piix4_pm_info = {
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 83a5420..735ab86 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -354,11 +354,14 @@ static void acpi_dsdt_add_power_button(Aml *scope)
/* RSDP */
static GArray *
-build_rsdp(GArray *rsdp_table, GArray *linker, unsigned rsdt)
+build_rsdp(GArray *rsdp_table, BIOSLinker *linker, unsigned rsdt_tbl_offset)
{
AcpiRsdpDescriptor *rsdp = acpi_data_push(rsdp_table, sizeof *rsdp);
+ unsigned rsdt_pa_size = sizeof(rsdp->rsdt_physical_address);
+ unsigned rsdt_pa_offset =
+ (char *)&rsdp->rsdt_physical_address - rsdp_table->data;
- bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, 16,
+ bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, rsdp_table, 16,
true /* fseg memory */);
memcpy(&rsdp->signature, "RSD PTR ", sizeof(rsdp->signature));
@@ -366,24 +369,21 @@ build_rsdp(GArray *rsdp_table, GArray *linker, unsigned rsdt)
rsdp->length = cpu_to_le32(sizeof(*rsdp));
rsdp->revision = 0x02;
- /* Point to RSDT */
- rsdp->rsdt_physical_address = cpu_to_le32(rsdt);
/* Address to be filled by Guest linker */
- bios_linker_loader_add_pointer(linker, ACPI_BUILD_RSDP_FILE,
- ACPI_BUILD_TABLE_FILE,
- rsdp_table, &rsdp->rsdt_physical_address,
- sizeof rsdp->rsdt_physical_address);
- rsdp->checksum = 0;
+ bios_linker_loader_add_pointer(linker,
+ ACPI_BUILD_RSDP_FILE, rsdt_pa_offset, rsdt_pa_size,
+ ACPI_BUILD_TABLE_FILE, rsdt_tbl_offset);
+
/* Checksum to be filled by Guest linker */
bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE,
- rsdp_table, rsdp, sizeof *rsdp,
- &rsdp->checksum);
+ (char *)rsdp - rsdp_table->data, sizeof *rsdp,
+ (char *)&rsdp->checksum - rsdp_table->data);
return rsdp_table;
}
static void
-build_spcr(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
+build_spcr(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
{
AcpiSerialPortConsoleRedirection *spcr;
const MemMapEntry *uart_memmap = &guest_info->memmap[VIRT_UART];
@@ -416,7 +416,7 @@ build_spcr(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
}
static void
-build_srat(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
+build_srat(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
{
AcpiSystemResourceAffinityTable *srat;
AcpiSratProcessorGiccAffinity *core;
@@ -456,13 +456,12 @@ build_srat(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
mem_base += numa_info[i].node_mem;
}
- build_header(linker, table_data,
- (void *)(table_data->data + srat_start), "SRAT",
+ build_header(linker, table_data, (void *)srat, "SRAT",
table_data->len - srat_start, 3, NULL, NULL);
}
static void
-build_mcfg(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
+build_mcfg(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
{
AcpiTableMcfg *mcfg;
const MemMapEntry *memmap = guest_info->memmap;
@@ -482,7 +481,7 @@ build_mcfg(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
/* GTDT */
static void
-build_gtdt(GArray *table_data, GArray *linker)
+build_gtdt(GArray *table_data, BIOSLinker *linker)
{
int gtdt_start = table_data->len;
AcpiGenericTimerTable *gtdt;
@@ -508,7 +507,7 @@ build_gtdt(GArray *table_data, GArray *linker)
/* MADT */
static void
-build_madt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
+build_madt(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
{
int madt_start = table_data->len;
const MemMapEntry *memmap = guest_info->memmap;
@@ -567,9 +566,10 @@ build_madt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
/* FADT */
static void
-build_fadt(GArray *table_data, GArray *linker, unsigned dsdt)
+build_fadt(GArray *table_data, BIOSLinker *linker, unsigned dsdt_tbl_offset)
{
AcpiFadtDescriptorRev5_1 *fadt = acpi_data_push(table_data, sizeof(*fadt));
+ unsigned dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data;
/* Hardware Reduced = 1 and use PSCI 0.2+ and with HVC */
fadt->flags = cpu_to_le32(1 << ACPI_FADT_F_HW_REDUCED_ACPI);
@@ -579,12 +579,10 @@ build_fadt(GArray *table_data, GArray *linker, unsigned dsdt)
/* ACPI v5.1 (fadt->revision.fadt->minor_revision) */
fadt->minor_revision = 0x1;
- fadt->dsdt = cpu_to_le32(dsdt);
/* DSDT address to be filled by Guest linker */
- bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE,
- ACPI_BUILD_TABLE_FILE,
- table_data, &fadt->dsdt,
- sizeof fadt->dsdt);
+ bios_linker_loader_add_pointer(linker,
+ ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->dsdt),
+ ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
build_header(linker, table_data,
(void *)fadt, "FACP", sizeof(*fadt), 5, NULL, NULL);
@@ -592,7 +590,7 @@ build_fadt(GArray *table_data, GArray *linker, unsigned dsdt)
/* DSDT */
static void
-build_dsdt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
+build_dsdt(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
{
Aml *scope, *dsdt;
const MemMapEntry *memmap = guest_info->memmap;
@@ -652,7 +650,8 @@ void virt_acpi_build(VirtGuestInfo *guest_info, AcpiBuildTables *tables)
table_offsets = g_array_new(false, true /* clear */,
sizeof(uint32_t));
- bios_linker_loader_alloc(tables->linker, ACPI_BUILD_TABLE_FILE,
+ bios_linker_loader_alloc(tables->linker,
+ ACPI_BUILD_TABLE_FILE, tables_blob,
64, false /* high memory */);
/*
@@ -731,7 +730,7 @@ static void virt_acpi_build_update(void *build_opaque)
acpi_ram_update(build_state->table_mr, tables.table_data);
acpi_ram_update(build_state->rsdp_mr, tables.rsdp);
- acpi_ram_update(build_state->linker_mr, tables.linker);
+ acpi_ram_update(build_state->linker_mr, tables.linker->cmd_blob);
acpi_build_tables_cleanup(&tables, true);
@@ -789,7 +788,8 @@ void virt_acpi_setup(VirtGuestInfo *guest_info)
assert(build_state->table_mr != NULL);
build_state->linker_mr =
- acpi_add_rom_blob(build_state, tables.linker, "etc/table-loader", 0);
+ acpi_add_rom_blob(build_state, tables.linker->cmd_blob,
+ "etc/table-loader", 0);
fw_cfg_add_file(guest_info->fw_cfg, ACPI_BUILD_TPMLOG_FILE,
tables.tcpalog->data, acpi_data_len(tables.tcpalog));
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 279f0d7..06d6204 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -94,7 +94,6 @@ typedef struct AcpiPmInfo {
uint32_t gpe0_blk_len;
uint32_t io_base;
uint16_t cpu_hp_io_base;
- uint16_t cpu_hp_io_len;
uint16_t mem_hp_io_base;
uint16_t mem_hp_io_len;
uint16_t pcihp_io_base;
@@ -142,7 +141,6 @@ 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;
@@ -262,7 +260,7 @@ static void acpi_align_size(GArray *blob, unsigned align)
/* FACS */
static void
-build_facs(GArray *table_data, GArray *linker)
+build_facs(GArray *table_data, BIOSLinker *linker)
{
AcpiFacsDescriptorRev1 *facs = acpi_data_push(table_data, sizeof *facs);
memcpy(&facs->signature, "FACS", 4);
@@ -307,34 +305,31 @@ static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
/* FADT */
static void
-build_fadt(GArray *table_data, GArray *linker, AcpiPmInfo *pm,
- unsigned facs, unsigned dsdt,
+build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm,
+ unsigned facs_tbl_offset, unsigned dsdt_tbl_offset,
const char *oem_id, const char *oem_table_id)
{
AcpiFadtDescriptorRev1 *fadt = acpi_data_push(table_data, sizeof(*fadt));
+ unsigned fw_ctrl_offset = (char *)&fadt->firmware_ctrl - table_data->data;
+ unsigned dsdt_entry_offset = (char *)&fadt->dsdt - table_data->data;
- fadt->firmware_ctrl = cpu_to_le32(facs);
/* FACS address to be filled by Guest linker */
- bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE,
- ACPI_BUILD_TABLE_FILE,
- table_data, &fadt->firmware_ctrl,
- sizeof fadt->firmware_ctrl);
+ bios_linker_loader_add_pointer(linker,
+ ACPI_BUILD_TABLE_FILE, fw_ctrl_offset, sizeof(fadt->firmware_ctrl),
+ ACPI_BUILD_TABLE_FILE, facs_tbl_offset);
- fadt->dsdt = cpu_to_le32(dsdt);
/* DSDT address to be filled by Guest linker */
- bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE,
- ACPI_BUILD_TABLE_FILE,
- table_data, &fadt->dsdt,
- sizeof fadt->dsdt);
-
fadt_setup(fadt, pm);
+ bios_linker_loader_add_pointer(linker,
+ ACPI_BUILD_TABLE_FILE, dsdt_entry_offset, sizeof(fadt->dsdt),
+ ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
build_header(linker, table_data,
(void *)fadt, "FACP", sizeof(*fadt), 1, oem_id, oem_table_id);
}
static void
-build_madt(GArray *table_data, GArray *linker, PCMachineState *pcms)
+build_madt(GArray *table_data, BIOSLinker *linker, PCMachineState *pcms)
{
MachineClass *mc = MACHINE_GET_CLASS(pcms);
CPUArchIdList *apic_ids = mc->possible_cpu_arch_ids(MACHINE(pcms));
@@ -356,7 +351,7 @@ build_madt(GArray *table_data, GArray *linker, PCMachineState *pcms)
apic->type = ACPI_APIC_PROCESSOR;
apic->length = sizeof(*apic);
- apic->processor_id = apic_id;
+ apic->processor_id = i;
apic->local_apic_id = apic_id;
if (apic_ids->cpus[i].cpu != NULL) {
apic->flags = cpu_to_le32(1);
@@ -943,114 +938,6 @@ static Aml *build_crs(PCIHostState *host,
return crs;
}
-static void build_processor_devices(Aml *sb_scope, MachineState *machine,
- AcpiPmInfo *pm)
-{
- int i, apic_idx;
- Aml *dev;
- Aml *crs;
- Aml *pkg;
- Aml *field;
- Aml *ifctx;
- Aml *method;
- MachineClass *mc = MACHINE_GET_CLASS(machine);
- CPUArchIdList *apic_ids = mc->possible_cpu_arch_ids(machine);
- PCMachineState *pcms = PC_MACHINE(machine);
-
- /* 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(pcms->apic_id_limit <= ACPI_CPU_HOTPLUG_ID_LIMIT);
-
- /* 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, aml_int(pm->cpu_hp_io_base), pm->cpu_hp_io_len));
- field = aml_field("PRST", AML_BYTE_ACC, AML_NOLOCK, AML_PRESERVE);
- aml_append(field, aml_named_field("PRS", 256));
- aml_append(sb_scope, field);
-
- /* build Processor object for each processor */
- for (i = 0; i < apic_ids->len; i++) {
- int apic_id = apic_ids->cpus[i].arch_id;
-
- assert(apic_id < ACPI_CPU_HOTPLUG_ID_LIMIT);
-
- dev = aml_processor(apic_id, 0, 0, "CP%.02X", apic_id);
-
- method = aml_method("_MAT", 0, AML_NOTSERIALIZED);
- aml_append(method,
- aml_return(aml_call1(CPU_MAT_METHOD, aml_int(apic_id))));
- aml_append(dev, method);
-
- method = aml_method("_STA", 0, AML_NOTSERIALIZED);
- aml_append(method,
- aml_return(aml_call1(CPU_STATUS_METHOD, aml_int(apic_id))));
- aml_append(dev, method);
-
- method = aml_method("_EJ0", 1, AML_NOTSERIALIZED);
- aml_append(method,
- aml_return(aml_call2(CPU_EJECT_METHOD, aml_int(apic_id),
- 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 */
- method = aml_method(AML_NOTIFY_METHOD, 2, AML_NOTSERIALIZED);
- for (i = 0; i < apic_ids->len; i++) {
- int apic_id = apic_ids->cpus[i].arch_id;
-
- ifctx = aml_if(aml_equal(aml_arg(0), aml_int(apic_id)));
- aml_append(ifctx,
- aml_notify(aml_name("CP%.02X", apic_id), aml_arg(1))
- );
- aml_append(method, ifctx);
- }
- aml_append(sb_scope, method);
-
- /* build "Name(CPON, Package() { One, One, ..., Zero, Zero, ... })"
- *
- * Note: The ability to create variable-sized packages was first
- * introduced in ACPI 2.0. ACPI 1.0 only allowed fixed-size packages
- * ith up to 255 elements. Windows guests up to win2k8 fail when
- * VarPackageOp is used.
- */
- pkg = pcms->apic_id_limit <= 255 ? aml_package(pcms->apic_id_limit) :
- aml_varpackage(pcms->apic_id_limit);
-
- for (i = 0, apic_idx = 0; i < apic_ids->len; i++) {
- int apic_id = apic_ids->cpus[i].arch_id;
-
- for (; apic_idx < apic_id; apic_idx++) {
- aml_append(pkg, aml_int(0));
- }
- aml_append(pkg, aml_int(apic_ids->cpus[i].cpu ? 1 : 0));
- apic_idx = apic_id + 1;
- }
- aml_append(sb_scope, aml_name_decl(CPU_ON_BITMAP, pkg));
- g_free(apic_ids);
-}
-
static void build_memory_devices(Aml *sb_scope, int nr_mem,
uint16_t io_base, uint16_t io_len)
{
@@ -1979,7 +1866,7 @@ static Aml *build_q35_osc_method(void)
}
static void
-build_dsdt(GArray *table_data, GArray *linker,
+build_dsdt(GArray *table_data, BIOSLinker *linker,
AcpiPmInfo *pm, AcpiMiscInfo *misc,
PcPciInfo *pci, MachineState *machine)
{
@@ -2043,7 +1930,7 @@ build_dsdt(GArray *table_data, GArray *linker,
build_q35_pci0_int(dsdt);
}
- build_cpu_hotplug_aml(dsdt);
+ build_legacy_cpu_hotplug_aml(dsdt, machine, pm->cpu_hp_io_base);
build_memory_hotplug_aml(dsdt, nr_mem, pm->mem_hp_io_base,
pm->mem_hp_io_len);
@@ -2051,8 +1938,6 @@ build_dsdt(GArray *table_data, GArray *linker,
{
aml_append(scope, aml_name_decl("_HID", aml_string("ACPI0006")));
- aml_append(scope, aml_method("_L00", 0, AML_NOTSERIALIZED));
-
if (misc->is_piix4) {
method = aml_method("_E01", 0, AML_NOTSERIALIZED);
aml_append(method,
@@ -2060,30 +1945,11 @@ build_dsdt(GArray *table_data, GArray *linker,
aml_append(method, aml_call0("\\_SB.PCI0.PCNT"));
aml_append(method, aml_release(aml_name("\\_SB.PCI0.BLCK")));
aml_append(scope, method);
- } else {
- aml_append(scope, aml_method("_L01", 0, AML_NOTSERIALIZED));
}
- method = aml_method("_E02", 0, AML_NOTSERIALIZED);
- aml_append(method, aml_call0("\\_SB." CPU_SCAN_METHOD));
- aml_append(scope, method);
-
method = aml_method("_E03", 0, AML_NOTSERIALIZED);
aml_append(method, aml_call0(MEMORY_HOTPLUG_HANDLER_PATH));
aml_append(scope, method);
-
- aml_append(scope, aml_method("_L04", 0, AML_NOTSERIALIZED));
- aml_append(scope, aml_method("_L05", 0, AML_NOTSERIALIZED));
- aml_append(scope, aml_method("_L06", 0, AML_NOTSERIALIZED));
- aml_append(scope, aml_method("_L07", 0, AML_NOTSERIALIZED));
- aml_append(scope, aml_method("_L08", 0, AML_NOTSERIALIZED));
- aml_append(scope, aml_method("_L09", 0, AML_NOTSERIALIZED));
- aml_append(scope, aml_method("_L0A", 0, AML_NOTSERIALIZED));
- aml_append(scope, aml_method("_L0B", 0, AML_NOTSERIALIZED));
- aml_append(scope, aml_method("_L0C", 0, AML_NOTSERIALIZED));
- aml_append(scope, aml_method("_L0D", 0, AML_NOTSERIALIZED));
- aml_append(scope, aml_method("_L0E", 0, AML_NOTSERIALIZED));
- aml_append(scope, aml_method("_L0F", 0, AML_NOTSERIALIZED));
}
aml_append(dsdt, scope);
@@ -2322,8 +2188,6 @@ build_dsdt(GArray *table_data, GArray *linker,
sb_scope = aml_scope("\\_SB");
{
- build_processor_devices(sb_scope, machine, pm);
-
build_memory_devices(sb_scope, nr_mem, pm->mem_hp_io_base,
pm->mem_hp_io_len);
@@ -2373,7 +2237,7 @@ build_dsdt(GArray *table_data, GArray *linker,
}
static void
-build_hpet(GArray *table_data, GArray *linker)
+build_hpet(GArray *table_data, BIOSLinker *linker)
{
Acpi20Hpet *hpet;
@@ -2388,32 +2252,31 @@ build_hpet(GArray *table_data, GArray *linker)
}
static void
-build_tpm_tcpa(GArray *table_data, GArray *linker, GArray *tcpalog)
+build_tpm_tcpa(GArray *table_data, BIOSLinker *linker, GArray *tcpalog)
{
Acpi20Tcpa *tcpa = acpi_data_push(table_data, sizeof *tcpa);
- uint64_t log_area_start_address = acpi_data_len(tcpalog);
+ unsigned log_addr_size = sizeof(tcpa->log_area_start_address);
+ unsigned log_addr_offset =
+ (char *)&tcpa->log_area_start_address - table_data->data;
tcpa->platform_class = cpu_to_le16(TPM_TCPA_ACPI_CLASS_CLIENT);
tcpa->log_area_minimum_length = cpu_to_le32(TPM_LOG_AREA_MINIMUM_SIZE);
- tcpa->log_area_start_address = cpu_to_le64(log_area_start_address);
+ acpi_data_push(tcpalog, le32_to_cpu(tcpa->log_area_minimum_length));
- bios_linker_loader_alloc(linker, ACPI_BUILD_TPMLOG_FILE, 1,
+ bios_linker_loader_alloc(linker, ACPI_BUILD_TPMLOG_FILE, tcpalog, 1,
false /* high memory */);
/* log area start address to be filled by Guest linker */
- bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE,
- ACPI_BUILD_TPMLOG_FILE,
- table_data, &tcpa->log_area_start_address,
- sizeof(tcpa->log_area_start_address));
+ bios_linker_loader_add_pointer(linker,
+ ACPI_BUILD_TABLE_FILE, log_addr_offset, log_addr_size,
+ ACPI_BUILD_TPMLOG_FILE, 0);
build_header(linker, table_data,
(void *)tcpa, "TCPA", sizeof(*tcpa), 2, NULL, NULL);
-
- acpi_data_push(tcpalog, TPM_LOG_AREA_MINIMUM_SIZE);
}
static void
-build_tpm2(GArray *table_data, GArray *linker)
+build_tpm2(GArray *table_data, BIOSLinker *linker)
{
Acpi20TPM2 *tpm2_ptr;
@@ -2428,7 +2291,7 @@ build_tpm2(GArray *table_data, GArray *linker)
}
static void
-build_srat(GArray *table_data, GArray *linker, MachineState *machine)
+build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
{
AcpiSystemResourceAffinityTable *srat;
AcpiSratProcessorAffinity *core;
@@ -2525,7 +2388,7 @@ build_srat(GArray *table_data, GArray *linker, MachineState *machine)
}
static void
-build_mcfg_q35(GArray *table_data, GArray *linker, AcpiMcfgInfo *info)
+build_mcfg_q35(GArray *table_data, BIOSLinker *linker, AcpiMcfgInfo *info)
{
AcpiTableMcfg *mcfg;
const char *sig;
@@ -2554,7 +2417,7 @@ build_mcfg_q35(GArray *table_data, GArray *linker, AcpiMcfgInfo *info)
}
static void
-build_dmar_q35(GArray *table_data, GArray *linker)
+build_dmar_q35(GArray *table_data, BIOSLinker *linker)
{
int dmar_start = table_data->len;
@@ -2578,26 +2441,27 @@ build_dmar_q35(GArray *table_data, GArray *linker)
}
static GArray *
-build_rsdp(GArray *rsdp_table, GArray *linker, unsigned rsdt)
+build_rsdp(GArray *rsdp_table, BIOSLinker *linker, unsigned rsdt_tbl_offset)
{
AcpiRsdpDescriptor *rsdp = acpi_data_push(rsdp_table, sizeof *rsdp);
+ unsigned rsdt_pa_size = sizeof(rsdp->rsdt_physical_address);
+ unsigned rsdt_pa_offset =
+ (char *)&rsdp->rsdt_physical_address - rsdp_table->data;
- bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, 16,
+ bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, rsdp_table, 16,
true /* fseg memory */);
memcpy(&rsdp->signature, "RSD PTR ", 8);
memcpy(rsdp->oem_id, ACPI_BUILD_APPNAME6, 6);
- rsdp->rsdt_physical_address = cpu_to_le32(rsdt);
/* Address to be filled by Guest linker */
- bios_linker_loader_add_pointer(linker, ACPI_BUILD_RSDP_FILE,
- ACPI_BUILD_TABLE_FILE,
- rsdp_table, &rsdp->rsdt_physical_address,
- sizeof rsdp->rsdt_physical_address);
- rsdp->checksum = 0;
+ bios_linker_loader_add_pointer(linker,
+ ACPI_BUILD_RSDP_FILE, rsdt_pa_offset, rsdt_pa_size,
+ ACPI_BUILD_TABLE_FILE, rsdt_tbl_offset);
+
/* Checksum to be filled by Guest linker */
bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE,
- rsdp_table, rsdp, sizeof *rsdp,
- &rsdp->checksum);
+ (char *)rsdp - rsdp_table->data, sizeof *rsdp,
+ (char *)&rsdp->checksum - rsdp_table->data);
return rsdp_table;
}
@@ -2670,7 +2534,8 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine)
sizeof(uint32_t));
ACPI_BUILD_DPRINTF("init ACPI tables\n");
- bios_linker_loader_alloc(tables->linker, ACPI_BUILD_TABLE_FILE,
+ bios_linker_loader_alloc(tables->linker,
+ ACPI_BUILD_TABLE_FILE, tables_blob,
64 /* Ensure FACS is aligned */,
false /* high memory */);
@@ -2727,7 +2592,8 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine)
build_dmar_q35(tables_blob, tables->linker);
}
if (pcms->acpi_nvdimm_state.is_enabled) {
- nvdimm_build_acpi(table_offsets, tables_blob, tables->linker);
+ nvdimm_build_acpi(table_offsets, tables_blob, tables->linker,
+ pcms->acpi_nvdimm_state.dsm_mem);
}
/* Add tables supplied by user (if any) */
@@ -2790,7 +2656,7 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine)
acpi_align_size(tables_blob, ACPI_BUILD_TABLE_SIZE);
}
- acpi_align_size(tables->linker, ACPI_BUILD_ALIGN_SIZE);
+ acpi_align_size(tables->linker->cmd_blob, ACPI_BUILD_ALIGN_SIZE);
/* Cleanup memory that's no longer used. */
g_array_free(table_offsets, true);
@@ -2830,7 +2696,7 @@ static void acpi_build_update(void *build_opaque)
acpi_ram_update(build_state->rsdp_mr, tables.rsdp);
}
- acpi_ram_update(build_state->linker_mr, tables.linker);
+ acpi_ram_update(build_state->linker_mr, tables.linker->cmd_blob);
acpi_build_tables_cleanup(&tables, true);
}
@@ -2894,7 +2760,8 @@ void acpi_setup(void)
assert(build_state->table_mr != NULL);
build_state->linker_mr =
- acpi_add_rom_blob(build_state, tables.linker, "etc/table-loader", 0);
+ acpi_add_rom_blob(build_state, tables.linker->cmd_blob,
+ "etc/table-loader", 0);
fw_cfg_add_file(pcms->fw_cfg, ACPI_BUILD_TPMLOG_FILE,
tables.tcpalog->data, acpi_data_len(tables.tcpalog));
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index e29ccc8..92125a8 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -765,8 +765,6 @@ static FWCfgState *bochs_bios_init(AddressSpace *as, PCMachineState *pcms)
acpi_tables, acpi_tables_len);
fw_cfg_add_i32(fw_cfg, FW_CFG_IRQ0_OVERRIDE, kvm_allows_irq0_override());
- pc_build_smbios(fw_cfg);
-
fw_cfg_add_bytes(fw_cfg, FW_CFG_E820_TABLE,
&e820_reserve, sizeof(e820_reserve));
fw_cfg_add_file(fw_cfg, "etc/e820", e820_table,
@@ -1182,6 +1180,9 @@ void pc_machine_done(Notifier *notifier, void *data)
}
acpi_setup();
+ if (pcms->fw_cfg) {
+ pc_build_smbios(pcms->fw_cfg);
+ }
}
void pc_guest_info_init(PCMachineState *pcms)
diff --git a/hw/ipmi/ipmi.c b/hw/ipmi/ipmi.c
index 6adec1e..f09f217 100644
--- a/hw/ipmi/ipmi.c
+++ b/hw/ipmi/ipmi.c
@@ -30,6 +30,13 @@
#include "qom/object_interfaces.h"
#include "qapi/visitor.h"
+static uint32_t ipmi_current_uuid = 1;
+
+uint32_t ipmi_next_uuid(void)
+{
+ return ipmi_current_uuid++;
+}
+
static int ipmi_do_hw_op(IPMIInterface *s, enum ipmi_op op, int checkonly)
{
switch (op) {
@@ -122,30 +129,3 @@ static void ipmi_register_types(void)
}
type_init(ipmi_register_types)
-
-static IPMIFwInfo *ipmi_fw_info;
-static unsigned int ipmi_fw_info_len;
-
-static uint32_t current_uuid = 1;
-
-void ipmi_add_fwinfo(IPMIFwInfo *info, Error **errp)
-{
- info->uuid = current_uuid++;
- ipmi_fw_info = g_realloc(ipmi_fw_info,
- sizeof(*ipmi_fw_info) * (ipmi_fw_info_len + 1));
- ipmi_fw_info[ipmi_fw_info_len] = *info;
-}
-
-IPMIFwInfo *ipmi_first_fwinfo(void)
-{
- return ipmi_fw_info;
-}
-
-IPMIFwInfo *ipmi_next_fwinfo(IPMIFwInfo *current)
-{
- current++;
- if (current >= &ipmi_fw_info[ipmi_fw_info_len]) {
- return NULL;
- }
- return current;
-}
diff --git a/hw/ipmi/isa_ipmi_bt.c b/hw/ipmi/isa_ipmi_bt.c
index aaea12e..f036617 100644
--- a/hw/ipmi/isa_ipmi_bt.c
+++ b/hw/ipmi/isa_ipmi_bt.c
@@ -390,16 +390,6 @@ static void ipmi_bt_init(IPMIInterface *ii, Error **errp)
memory_region_init_io(&ib->io, NULL, &ipmi_bt_io_ops, ii, "ipmi-bt", 3);
}
-static void ipmi_bt_class_init(IPMIInterfaceClass *iic)
-{
- iic->init = ipmi_bt_init;
- iic->set_atn = ipmi_bt_set_atn;
- iic->handle_rsp = ipmi_bt_handle_rsp;
- iic->handle_if_event = ipmi_bt_handle_event;
- iic->set_irq_enable = ipmi_bt_set_irq_enable;
- iic->reset = ipmi_bt_handle_reset;
-}
-
#define TYPE_ISA_IPMI_BT "isa-ipmi-bt"
#define ISA_IPMI_BT(obj) OBJECT_CHECK(ISAIPMIBTDevice, (obj), \
@@ -409,9 +399,38 @@ typedef struct ISAIPMIBTDevice {
ISADevice dev;
int32_t isairq;
IPMIBT bt;
- IPMIFwInfo fwinfo;
+ uint32_t uuid;
} ISAIPMIBTDevice;
+static void ipmi_bt_get_fwinfo(struct IPMIInterface *ii, IPMIFwInfo *info)
+{
+ ISAIPMIBTDevice *iib = ISA_IPMI_BT(ii);
+
+ info->interface_name = "bt";
+ info->interface_type = IPMI_SMBIOS_BT;
+ info->ipmi_spec_major_revision = 2;
+ info->ipmi_spec_minor_revision = 0;
+ info->base_address = iib->bt.io_base;
+ info->register_length = iib->bt.io_length;
+ info->register_spacing = 1;
+ info->memspace = IPMI_MEMSPACE_IO;
+ info->irq_type = IPMI_LEVEL_IRQ;
+ info->interrupt_number = iib->isairq;
+ info->i2c_slave_address = iib->bt.bmc->slave_addr;
+ info->uuid = iib->uuid;
+}
+
+static void ipmi_bt_class_init(IPMIInterfaceClass *iic)
+{
+ iic->init = ipmi_bt_init;
+ iic->set_atn = ipmi_bt_set_atn;
+ iic->handle_rsp = ipmi_bt_handle_rsp;
+ iic->handle_if_event = ipmi_bt_handle_event;
+ iic->set_irq_enable = ipmi_bt_set_irq_enable;
+ iic->reset = ipmi_bt_handle_reset;
+ iic->get_fwinfo = ipmi_bt_get_fwinfo;
+}
+
static void isa_ipmi_bt_realize(DeviceState *dev, Error **errp)
{
ISADevice *isadev = ISA_DEVICE(dev);
@@ -424,6 +443,8 @@ static void isa_ipmi_bt_realize(DeviceState *dev, Error **errp)
return;
}
+ iib->uuid = ipmi_next_uuid();
+
iib->bt.bmc->intf = ii;
iic->init(ii, errp);
@@ -438,20 +459,6 @@ static void isa_ipmi_bt_realize(DeviceState *dev, Error **errp)
qdev_set_legacy_instance_id(dev, iib->bt.io_base, iib->bt.io_length);
isa_register_ioport(isadev, &iib->bt.io, iib->bt.io_base);
-
- iib->fwinfo.interface_name = "bt";
- iib->fwinfo.interface_type = IPMI_SMBIOS_BT;
- iib->fwinfo.ipmi_spec_major_revision = 2;
- iib->fwinfo.ipmi_spec_minor_revision = 0;
- iib->fwinfo.base_address = iib->bt.io_base;
- iib->fwinfo.register_length = iib->bt.io_length;
- iib->fwinfo.register_spacing = 1;
- iib->fwinfo.memspace = IPMI_MEMSPACE_IO;
- iib->fwinfo.irq_type = IPMI_LEVEL_IRQ;
- iib->fwinfo.interrupt_number = iib->isairq;
- iib->fwinfo.acpi_parent = "\\_SB.PCI0.ISA";
- iib->fwinfo.i2c_slave_address = iib->bt.bmc->slave_addr;
- ipmi_add_fwinfo(&iib->fwinfo, errp);
}
static const VMStateDescription vmstate_ISAIPMIBTDevice = {
diff --git a/hw/ipmi/isa_ipmi_kcs.c b/hw/ipmi/isa_ipmi_kcs.c
index 2742ce0..9a38f8a 100644
--- a/hw/ipmi/isa_ipmi_kcs.c
+++ b/hw/ipmi/isa_ipmi_kcs.c
@@ -354,16 +354,6 @@ static void ipmi_kcs_init(IPMIInterface *ii, Error **errp)
memory_region_init_io(&ik->io, NULL, &ipmi_kcs_io_ops, ii, "ipmi-kcs", 2);
}
-static void ipmi_kcs_class_init(IPMIInterfaceClass *iic)
-{
- iic->init = ipmi_kcs_init;
- iic->set_atn = ipmi_kcs_set_atn;
- iic->handle_rsp = ipmi_kcs_handle_rsp;
- iic->handle_if_event = ipmi_kcs_handle_event;
- iic->set_irq_enable = ipmi_kcs_set_irq_enable;
-}
-
-
#define TYPE_ISA_IPMI_KCS "isa-ipmi-kcs"
#define ISA_IPMI_KCS(obj) OBJECT_CHECK(ISAIPMIKCSDevice, (obj), \
TYPE_ISA_IPMI_KCS)
@@ -372,9 +362,37 @@ typedef struct ISAIPMIKCSDevice {
ISADevice dev;
int32_t isairq;
IPMIKCS kcs;
- IPMIFwInfo fwinfo;
+ uint32_t uuid;
} ISAIPMIKCSDevice;
+static void ipmi_kcs_get_fwinfo(IPMIInterface *ii, IPMIFwInfo *info)
+{
+ ISAIPMIKCSDevice *iik = ISA_IPMI_KCS(ii);
+
+ info->interface_name = "kcs";
+ info->interface_type = IPMI_SMBIOS_KCS;
+ info->ipmi_spec_major_revision = 2;
+ info->ipmi_spec_minor_revision = 0;
+ info->base_address = iik->kcs.io_base;
+ info->i2c_slave_address = iik->kcs.bmc->slave_addr;
+ info->register_length = iik->kcs.io_length;
+ info->register_spacing = 1;
+ info->memspace = IPMI_MEMSPACE_IO;
+ info->irq_type = IPMI_LEVEL_IRQ;
+ info->interrupt_number = iik->isairq;
+ info->uuid = iik->uuid;
+}
+
+static void ipmi_kcs_class_init(IPMIInterfaceClass *iic)
+{
+ iic->init = ipmi_kcs_init;
+ iic->set_atn = ipmi_kcs_set_atn;
+ iic->handle_rsp = ipmi_kcs_handle_rsp;
+ iic->handle_if_event = ipmi_kcs_handle_event;
+ iic->set_irq_enable = ipmi_kcs_set_irq_enable;
+ iic->get_fwinfo = ipmi_kcs_get_fwinfo;
+}
+
static void ipmi_isa_realize(DeviceState *dev, Error **errp)
{
ISADevice *isadev = ISA_DEVICE(dev);
@@ -387,6 +405,8 @@ static void ipmi_isa_realize(DeviceState *dev, Error **errp)
return;
}
+ iik->uuid = ipmi_next_uuid();
+
iik->kcs.bmc->intf = ii;
iic->init(ii, errp);
@@ -401,20 +421,6 @@ static void ipmi_isa_realize(DeviceState *dev, Error **errp)
qdev_set_legacy_instance_id(dev, iik->kcs.io_base, iik->kcs.io_length);
isa_register_ioport(isadev, &iik->kcs.io, iik->kcs.io_base);
-
- iik->fwinfo.interface_name = "kcs";
- iik->fwinfo.interface_type = IPMI_SMBIOS_KCS;
- iik->fwinfo.ipmi_spec_major_revision = 2;
- iik->fwinfo.ipmi_spec_minor_revision = 0;
- iik->fwinfo.base_address = iik->kcs.io_base;
- iik->fwinfo.i2c_slave_address = iik->kcs.bmc->slave_addr;
- iik->fwinfo.register_length = iik->kcs.io_length;
- iik->fwinfo.register_spacing = 1;
- iik->fwinfo.memspace = IPMI_MEMSPACE_IO;
- iik->fwinfo.irq_type = IPMI_LEVEL_IRQ;
- iik->fwinfo.interrupt_number = iik->isairq;
- iik->fwinfo.acpi_parent = "\\_SB.PCI0.ISA";
- ipmi_add_fwinfo(&iik->fwinfo, errp);
}
const VMStateDescription vmstate_ISAIPMIKCSDevice = {
diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
index 4f8ca45..2a2d52e 100644
--- a/hw/isa/lpc_ich9.c
+++ b/hw/isa/lpc_ich9.c
@@ -637,30 +637,6 @@ static void ich9_lpc_realize(PCIDevice *d, Error **errp)
1);
}
-static void ich9_device_plug_cb(HotplugHandler *hotplug_dev,
- DeviceState *dev, Error **errp)
-{
- ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev);
-
- ich9_pm_device_plug_cb(&lpc->pm, dev, errp);
-}
-
-static void ich9_device_unplug_request_cb(HotplugHandler *hotplug_dev,
- DeviceState *dev, Error **errp)
-{
- ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev);
-
- ich9_pm_device_unplug_request_cb(&lpc->pm, dev, errp);
-}
-
-static void ich9_device_unplug_cb(HotplugHandler *hotplug_dev,
- DeviceState *dev, Error **errp)
-{
- ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev);
-
- ich9_pm_device_unplug_cb(&lpc->pm, dev, errp);
-}
-
static bool ich9_rst_cnt_needed(void *opaque)
{
ICH9LPCState *lpc = opaque;
@@ -703,6 +679,13 @@ static Property ich9_lpc_properties[] = {
DEFINE_PROP_END_OF_LIST(),
};
+static void ich9_send_gpe(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
+{
+ ICH9LPCState *s = ICH9_LPC_DEVICE(adev);
+
+ acpi_send_gpe_event(&s->pm.acpi_regs, s->pm.irq, ev);
+}
+
static void ich9_lpc_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
@@ -726,10 +709,11 @@ static void ich9_lpc_class_init(ObjectClass *klass, void *data)
* pc_q35_init()
*/
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;
+ hc->plug = ich9_pm_device_plug_cb;
+ hc->unplug_request = ich9_pm_device_unplug_request_cb;
+ hc->unplug = ich9_pm_device_unplug_cb;
adevc->ospm_status = ich9_pm_ospm_status;
+ adevc->send_event = ich9_send_gpe;
}
static const TypeInfo ich9_lpc_info = {
diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c
index 9e7de56..6de2275 100644
--- a/hw/mem/pc-dimm.c
+++ b/hw/mem/pc-dimm.c
@@ -354,8 +354,9 @@ static void pc_dimm_get_size(Object *obj, Visitor *v, const char *name,
int64_t value;
MemoryRegion *mr;
PCDIMMDevice *dimm = PC_DIMM(obj);
+ PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(obj);
- mr = host_memory_backend_get_memory(dimm->hostmem, errp);
+ mr = ddc->get_memory_region(dimm);
value = memory_region_size(mr);
visit_type_int(v, name, &value, errp);
@@ -399,6 +400,7 @@ static void pc_dimm_init(Object *obj)
static void pc_dimm_realize(DeviceState *dev, Error **errp)
{
PCDIMMDevice *dimm = PC_DIMM(dev);
+ PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm);
if (!dimm->hostmem) {
error_setg(errp, "'" PC_DIMM_MEMDEV_PROP "' property is not set");
@@ -411,6 +413,10 @@ static void pc_dimm_realize(DeviceState *dev, Error **errp)
dimm->node, nb_numa_nodes ? nb_numa_nodes : 1);
return;
}
+
+ if (ddc->realize) {
+ ddc->realize(dimm, errp);
+ }
}
static MemoryRegion *pc_dimm_get_memory_region(PCDIMMDevice *dimm)
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 4400718..81cc5b0 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -767,15 +767,11 @@ static inline bool vhost_needs_vring_endian(VirtIODevice *vdev)
if (virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1)) {
return false;
}
-#ifdef TARGET_IS_BIENDIAN
#ifdef HOST_WORDS_BIGENDIAN
return vdev->device_endian == VIRTIO_DEVICE_ENDIAN_LITTLE;
#else
return vdev->device_endian == VIRTIO_DEVICE_ENDIAN_BIG;
#endif
-#else
- return false;
-#endif
}
static int vhost_virtqueue_set_vring_endian_legacy(struct vhost_dev *dev,