]> git.proxmox.com Git - mirror_qemu.git/blame - hw/i386/acpi-build.c
range: remove useless inclusions
[mirror_qemu.git] / hw / i386 / acpi-build.c
CommitLineData
72c194f7
MT
1/* Support for generating ACPI tables and passing them to Guests
2 *
3 * Copyright (C) 2008-2010 Kevin O'Connor <kevin@koconnor.net>
4 * Copyright (C) 2006 Fabrice Bellard
5 * Copyright (C) 2013 Red Hat Inc
6 *
7 * Author: Michael S. Tsirkin <mst@redhat.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, see <http://www.gnu.org/licenses/>.
21 */
22
23#include "acpi-build.h"
24#include <stddef.h>
25#include <glib.h>
26#include "qemu-common.h"
27#include "qemu/bitmap.h"
07fb6176 28#include "qemu/osdep.h"
07fb6176 29#include "qemu/error-report.h"
72c194f7
MT
30#include "hw/pci/pci.h"
31#include "qom/cpu.h"
32#include "hw/i386/pc.h"
33#include "target-i386/cpu.h"
34#include "hw/timer/hpet.h"
35#include "hw/i386/acpi-defs.h"
36#include "hw/acpi/acpi.h"
37#include "hw/nvram/fw_cfg.h"
0058ae1d 38#include "hw/acpi/bios-linker-loader.h"
72c194f7 39#include "hw/loader.h"
15bce1b7 40#include "hw/isa/isa.h"
bef3492d 41#include "hw/acpi/memory_hotplug.h"
711b20b4
SB
42#include "sysemu/tpm.h"
43#include "hw/acpi/tpm.h"
72c194f7
MT
44
45/* Supported chipsets: */
46#include "hw/acpi/piix4.h"
99fd437d 47#include "hw/acpi/pcihp.h"
72c194f7
MT
48#include "hw/i386/ich9.h"
49#include "hw/pci/pci_bus.h"
50#include "hw/pci-host/q35.h"
d4eb9119 51#include "hw/i386/intel_iommu.h"
72c194f7
MT
52
53#include "hw/i386/q35-acpi-dsdt.hex"
54#include "hw/i386/acpi-dsdt.hex"
55
19934e0e
IM
56#include "hw/acpi/aml-build.h"
57
72c194f7
MT
58#include "qapi/qmp/qint.h"
59#include "qom/qom-qobject.h"
60
07fb6176
PB
61/* These are used to size the ACPI tables for -M pc-i440fx-1.7 and
62 * -M pc-i440fx-2.0. Even if the actual amount of AML generated grows
63 * a little bit, there should be plenty of free space since the DSDT
64 * shrunk by ~1.5k between QEMU 2.0 and QEMU 2.1.
65 */
66#define ACPI_BUILD_LEGACY_CPU_AML_SIZE 97
67#define ACPI_BUILD_ALIGN_SIZE 0x1000
68
868270f2 69#define ACPI_BUILD_TABLE_SIZE 0x20000
18045fb9 70
a1666142
MT
71/* Reserve RAM space for tables: add another order of magnitude. */
72#define ACPI_BUILD_TABLE_MAX_SIZE 0x200000
73
8b310fc4
GA
74/* #define DEBUG_ACPI_BUILD */
75#ifdef DEBUG_ACPI_BUILD
76#define ACPI_BUILD_DPRINTF(fmt, ...) \
77 do {printf("ACPI_BUILD: " fmt, ## __VA_ARGS__); } while (0)
78#else
79#define ACPI_BUILD_DPRINTF(fmt, ...)
80#endif
81
72c194f7 82typedef struct AcpiCpuInfo {
798325ed 83 DECLARE_BITMAP(found_cpus, ACPI_CPU_HOTPLUG_ID_LIMIT);
72c194f7
MT
84} AcpiCpuInfo;
85
86typedef struct AcpiMcfgInfo {
87 uint64_t mcfg_base;
88 uint32_t mcfg_size;
89} AcpiMcfgInfo;
90
91typedef struct AcpiPmInfo {
92 bool s3_disabled;
93 bool s4_disabled;
133a2da4 94 bool pcihp_bridge_en;
72c194f7
MT
95 uint8_t s4_val;
96 uint16_t sci_int;
97 uint8_t acpi_enable_cmd;
98 uint8_t acpi_disable_cmd;
99 uint32_t gpe0_blk;
100 uint32_t gpe0_blk_len;
101 uint32_t io_base;
ddf1ec2f
IM
102 uint16_t cpu_hp_io_base;
103 uint16_t cpu_hp_io_len;
2c6b94d8
IM
104 uint16_t mem_hp_io_base;
105 uint16_t mem_hp_io_len;
500b11ea
IM
106 uint16_t pcihp_io_base;
107 uint16_t pcihp_io_len;
72c194f7
MT
108} AcpiPmInfo;
109
110typedef struct AcpiMiscInfo {
111 bool has_hpet;
711b20b4 112 bool has_tpm;
72c194f7
MT
113 const unsigned char *dsdt_code;
114 unsigned dsdt_size;
115 uint16_t pvpanic_port;
8ac6f7a6 116 uint16_t applesmc_io_base;
72c194f7
MT
117} AcpiMiscInfo;
118
99fd437d
MT
119typedef struct AcpiBuildPciBusHotplugState {
120 GArray *device_table;
121 GArray *notify_table;
122 struct AcpiBuildPciBusHotplugState *parent;
133a2da4 123 bool pcihp_bridge_en;
99fd437d
MT
124} AcpiBuildPciBusHotplugState;
125
72c194f7
MT
126static void acpi_get_dsdt(AcpiMiscInfo *info)
127{
128 Object *piix = piix4_pm_find();
129 Object *lpc = ich9_lpc_find();
130 assert(!!piix != !!lpc);
131
132 if (piix) {
133 info->dsdt_code = AcpiDsdtAmlCode;
134 info->dsdt_size = sizeof AcpiDsdtAmlCode;
135 }
136 if (lpc) {
137 info->dsdt_code = Q35AcpiDsdtAmlCode;
138 info->dsdt_size = sizeof Q35AcpiDsdtAmlCode;
139 }
140}
141
142static
143int acpi_add_cpu_info(Object *o, void *opaque)
144{
145 AcpiCpuInfo *cpu = opaque;
146 uint64_t apic_id;
147
148 if (object_dynamic_cast(o, TYPE_CPU)) {
149 apic_id = object_property_get_int(o, "apic-id", NULL);
798325ed 150 assert(apic_id < ACPI_CPU_HOTPLUG_ID_LIMIT);
72c194f7
MT
151
152 set_bit(apic_id, cpu->found_cpus);
153 }
154
155 object_child_foreach(o, acpi_add_cpu_info, opaque);
156 return 0;
157}
158
159static void acpi_get_cpu_info(AcpiCpuInfo *cpu)
160{
161 Object *root = object_get_root();
162
163 memset(cpu->found_cpus, 0, sizeof cpu->found_cpus);
164 object_child_foreach(root, acpi_add_cpu_info, cpu);
165}
166
167static void acpi_get_pm_info(AcpiPmInfo *pm)
168{
169 Object *piix = piix4_pm_find();
170 Object *lpc = ich9_lpc_find();
171 Object *obj = NULL;
172 QObject *o;
173
500b11ea
IM
174 pm->pcihp_io_base = 0;
175 pm->pcihp_io_len = 0;
72c194f7
MT
176 if (piix) {
177 obj = piix;
ddf1ec2f 178 pm->cpu_hp_io_base = PIIX4_CPU_HOTPLUG_IO_BASE;
500b11ea
IM
179 pm->pcihp_io_base =
180 object_property_get_int(obj, ACPI_PCIHP_IO_BASE_PROP, NULL);
181 pm->pcihp_io_len =
182 object_property_get_int(obj, ACPI_PCIHP_IO_LEN_PROP, NULL);
72c194f7
MT
183 }
184 if (lpc) {
185 obj = lpc;
ddf1ec2f 186 pm->cpu_hp_io_base = ICH9_CPU_HOTPLUG_IO_BASE;
72c194f7
MT
187 }
188 assert(obj);
189
ddf1ec2f 190 pm->cpu_hp_io_len = ACPI_GPE_PROC_LEN;
2c6b94d8
IM
191 pm->mem_hp_io_base = ACPI_MEMORY_HOTPLUG_BASE;
192 pm->mem_hp_io_len = ACPI_MEMORY_HOTPLUG_IO_LEN;
193
72c194f7
MT
194 /* Fill in optional s3/s4 related properties */
195 o = object_property_get_qobject(obj, ACPI_PM_PROP_S3_DISABLED, NULL);
196 if (o) {
197 pm->s3_disabled = qint_get_int(qobject_to_qint(o));
198 } else {
199 pm->s3_disabled = false;
200 }
097a97a6 201 qobject_decref(o);
72c194f7
MT
202 o = object_property_get_qobject(obj, ACPI_PM_PROP_S4_DISABLED, NULL);
203 if (o) {
204 pm->s4_disabled = qint_get_int(qobject_to_qint(o));
205 } else {
206 pm->s4_disabled = false;
207 }
097a97a6 208 qobject_decref(o);
72c194f7
MT
209 o = object_property_get_qobject(obj, ACPI_PM_PROP_S4_VAL, NULL);
210 if (o) {
211 pm->s4_val = qint_get_int(qobject_to_qint(o));
212 } else {
213 pm->s4_val = false;
214 }
097a97a6 215 qobject_decref(o);
72c194f7
MT
216
217 /* Fill in mandatory properties */
218 pm->sci_int = object_property_get_int(obj, ACPI_PM_PROP_SCI_INT, NULL);
219
220 pm->acpi_enable_cmd = object_property_get_int(obj,
221 ACPI_PM_PROP_ACPI_ENABLE_CMD,
222 NULL);
223 pm->acpi_disable_cmd = object_property_get_int(obj,
224 ACPI_PM_PROP_ACPI_DISABLE_CMD,
225 NULL);
226 pm->io_base = object_property_get_int(obj, ACPI_PM_PROP_PM_IO_BASE,
227 NULL);
228 pm->gpe0_blk = object_property_get_int(obj, ACPI_PM_PROP_GPE0_BLK,
229 NULL);
230 pm->gpe0_blk_len = object_property_get_int(obj, ACPI_PM_PROP_GPE0_BLK_LEN,
231 NULL);
133a2da4
IM
232 pm->pcihp_bridge_en =
233 object_property_get_bool(obj, "acpi-pci-hotplug-with-bridge-support",
234 NULL);
72c194f7
MT
235}
236
72c194f7
MT
237static void acpi_get_misc_info(AcpiMiscInfo *info)
238{
239 info->has_hpet = hpet_find();
711b20b4 240 info->has_tpm = tpm_find();
72c194f7 241 info->pvpanic_port = pvpanic_port();
8ac6f7a6 242 info->applesmc_io_base = applesmc_port();
72c194f7
MT
243}
244
245static void acpi_get_pci_info(PcPciInfo *info)
246{
247 Object *pci_host;
248 bool ambiguous;
249
250 pci_host = object_resolve_path_type("", TYPE_PCI_HOST_BRIDGE, &ambiguous);
251 g_assert(!ambiguous);
252 g_assert(pci_host);
253
254 info->w32.begin = object_property_get_int(pci_host,
255 PCI_HOST_PROP_PCI_HOLE_START,
256 NULL);
257 info->w32.end = object_property_get_int(pci_host,
258 PCI_HOST_PROP_PCI_HOLE_END,
259 NULL);
260 info->w64.begin = object_property_get_int(pci_host,
261 PCI_HOST_PROP_PCI_HOLE64_START,
262 NULL);
263 info->w64.end = object_property_get_int(pci_host,
264 PCI_HOST_PROP_PCI_HOLE64_END,
265 NULL);
266}
267
268#define ACPI_BUILD_APPNAME "Bochs"
269#define ACPI_BUILD_APPNAME6 "BOCHS "
270#define ACPI_BUILD_APPNAME4 "BXPC"
271
72c194f7
MT
272#define ACPI_BUILD_TABLE_FILE "etc/acpi/tables"
273#define ACPI_BUILD_RSDP_FILE "etc/acpi/rsdp"
42a5b308 274#define ACPI_BUILD_TPMLOG_FILE "etc/tpm/log"
72c194f7
MT
275
276static void
277build_header(GArray *linker, GArray *table_data,
821e3227 278 AcpiTableHeader *h, const char *sig, int len, uint8_t rev)
72c194f7 279{
821e3227 280 memcpy(&h->signature, sig, 4);
72c194f7
MT
281 h->length = cpu_to_le32(len);
282 h->revision = rev;
283 memcpy(h->oem_id, ACPI_BUILD_APPNAME6, 6);
284 memcpy(h->oem_table_id, ACPI_BUILD_APPNAME4, 4);
821e3227 285 memcpy(h->oem_table_id + 4, sig, 4);
72c194f7
MT
286 h->oem_revision = cpu_to_le32(1);
287 memcpy(h->asl_compiler_id, ACPI_BUILD_APPNAME4, 4);
288 h->asl_compiler_revision = cpu_to_le32(1);
289 h->checksum = 0;
290 /* Checksum to be filled in by Guest linker */
291 bios_linker_loader_add_checksum(linker, ACPI_BUILD_TABLE_FILE,
292 table_data->data, h, len, &h->checksum);
293}
294
99fd437d 295/* End here */
72c194f7
MT
296#define ACPI_PORT_SMI_CMD 0x00b2 /* TODO: this is APM_CNT_IOPORT */
297
298static inline void *acpi_data_push(GArray *table_data, unsigned size)
299{
300 unsigned off = table_data->len;
301 g_array_set_size(table_data, off + size);
302 return table_data->data + off;
303}
304
305static unsigned acpi_data_len(GArray *table)
306{
134d42d6 307#if GLIB_CHECK_VERSION(2, 22, 0)
b15654c2
MT
308 assert(g_array_get_element_size(table) == 1);
309#endif
310 return table->len;
72c194f7
MT
311}
312
313static void acpi_align_size(GArray *blob, unsigned align)
314{
315 /* Align size to multiple of given size. This reduces the chance
316 * we need to change size in the future (breaking cross version migration).
317 */
134d42d6 318 g_array_set_size(blob, ROUND_UP(acpi_data_len(blob), align));
72c194f7
MT
319}
320
72c194f7
MT
321static inline void acpi_add_table(GArray *table_offsets, GArray *table_data)
322{
323 uint32_t offset = cpu_to_le32(table_data->len);
324 g_array_append_val(table_offsets, offset);
325}
326
327/* FACS */
328static void
329build_facs(GArray *table_data, GArray *linker, PcGuestInfo *guest_info)
330{
331 AcpiFacsDescriptorRev1 *facs = acpi_data_push(table_data, sizeof *facs);
821e3227 332 memcpy(&facs->signature, "FACS", 4);
72c194f7
MT
333 facs->length = cpu_to_le32(sizeof(*facs));
334}
335
336/* Load chipset information in FADT */
337static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm)
338{
339 fadt->model = 1;
340 fadt->reserved1 = 0;
341 fadt->sci_int = cpu_to_le16(pm->sci_int);
342 fadt->smi_cmd = cpu_to_le32(ACPI_PORT_SMI_CMD);
343 fadt->acpi_enable = pm->acpi_enable_cmd;
344 fadt->acpi_disable = pm->acpi_disable_cmd;
345 /* EVT, CNT, TMR offset matches hw/acpi/core.c */
346 fadt->pm1a_evt_blk = cpu_to_le32(pm->io_base);
347 fadt->pm1a_cnt_blk = cpu_to_le32(pm->io_base + 0x04);
348 fadt->pm_tmr_blk = cpu_to_le32(pm->io_base + 0x08);
349 fadt->gpe0_blk = cpu_to_le32(pm->gpe0_blk);
350 /* EVT, CNT, TMR length matches hw/acpi/core.c */
351 fadt->pm1_evt_len = 4;
352 fadt->pm1_cnt_len = 2;
353 fadt->pm_tmr_len = 4;
354 fadt->gpe0_blk_len = pm->gpe0_blk_len;
355 fadt->plvl2_lat = cpu_to_le16(0xfff); /* C2 state not supported */
356 fadt->plvl3_lat = cpu_to_le16(0xfff); /* C3 state not supported */
357 fadt->flags = cpu_to_le32((1 << ACPI_FADT_F_WBINVD) |
358 (1 << ACPI_FADT_F_PROC_C1) |
359 (1 << ACPI_FADT_F_SLP_BUTTON) |
360 (1 << ACPI_FADT_F_RTC_S4));
361 fadt->flags |= cpu_to_le32(1 << ACPI_FADT_F_USE_PLATFORM_CLOCK);
07b81ed9
HZ
362 /* APIC destination mode ("Flat Logical") has an upper limit of 8 CPUs
363 * For more than 8 CPUs, "Clustered Logical" mode has to be used
364 */
365 if (max_cpus > 8) {
366 fadt->flags |= cpu_to_le32(1 << ACPI_FADT_F_FORCE_APIC_CLUSTER_MODEL);
367 }
72c194f7
MT
368}
369
370
371/* FADT */
372static void
373build_fadt(GArray *table_data, GArray *linker, AcpiPmInfo *pm,
374 unsigned facs, unsigned dsdt)
375{
376 AcpiFadtDescriptorRev1 *fadt = acpi_data_push(table_data, sizeof(*fadt));
377
378 fadt->firmware_ctrl = cpu_to_le32(facs);
379 /* FACS address to be filled by Guest linker */
380 bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE,
381 ACPI_BUILD_TABLE_FILE,
382 table_data, &fadt->firmware_ctrl,
383 sizeof fadt->firmware_ctrl);
384
385 fadt->dsdt = cpu_to_le32(dsdt);
386 /* DSDT address to be filled by Guest linker */
387 bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE,
388 ACPI_BUILD_TABLE_FILE,
389 table_data, &fadt->dsdt,
390 sizeof fadt->dsdt);
391
392 fadt_setup(fadt, pm);
393
394 build_header(linker, table_data,
821e3227 395 (void *)fadt, "FACP", sizeof(*fadt), 1);
72c194f7
MT
396}
397
398static void
399build_madt(GArray *table_data, GArray *linker, AcpiCpuInfo *cpu,
400 PcGuestInfo *guest_info)
401{
402 int madt_start = table_data->len;
403
404 AcpiMultipleApicTable *madt;
405 AcpiMadtIoApic *io_apic;
406 AcpiMadtIntsrcovr *intsrcovr;
407 AcpiMadtLocalNmi *local_nmi;
408 int i;
409
410 madt = acpi_data_push(table_data, sizeof *madt);
411 madt->local_apic_address = cpu_to_le32(APIC_DEFAULT_ADDRESS);
412 madt->flags = cpu_to_le32(1);
413
414 for (i = 0; i < guest_info->apic_id_limit; i++) {
415 AcpiMadtProcessorApic *apic = acpi_data_push(table_data, sizeof *apic);
416 apic->type = ACPI_APIC_PROCESSOR;
417 apic->length = sizeof(*apic);
418 apic->processor_id = i;
419 apic->local_apic_id = i;
420 if (test_bit(i, cpu->found_cpus)) {
421 apic->flags = cpu_to_le32(1);
422 } else {
423 apic->flags = cpu_to_le32(0);
424 }
425 }
426 io_apic = acpi_data_push(table_data, sizeof *io_apic);
427 io_apic->type = ACPI_APIC_IO;
428 io_apic->length = sizeof(*io_apic);
429#define ACPI_BUILD_IOAPIC_ID 0x0
430 io_apic->io_apic_id = ACPI_BUILD_IOAPIC_ID;
431 io_apic->address = cpu_to_le32(IO_APIC_DEFAULT_ADDRESS);
432 io_apic->interrupt = cpu_to_le32(0);
433
434 if (guest_info->apic_xrupt_override) {
435 intsrcovr = acpi_data_push(table_data, sizeof *intsrcovr);
436 intsrcovr->type = ACPI_APIC_XRUPT_OVERRIDE;
437 intsrcovr->length = sizeof(*intsrcovr);
438 intsrcovr->source = 0;
439 intsrcovr->gsi = cpu_to_le32(2);
440 intsrcovr->flags = cpu_to_le16(0); /* conforms to bus specifications */
441 }
442 for (i = 1; i < 16; i++) {
443#define ACPI_BUILD_PCI_IRQS ((1<<5) | (1<<9) | (1<<10) | (1<<11))
444 if (!(ACPI_BUILD_PCI_IRQS & (1 << i))) {
445 /* No need for a INT source override structure. */
446 continue;
447 }
448 intsrcovr = acpi_data_push(table_data, sizeof *intsrcovr);
449 intsrcovr->type = ACPI_APIC_XRUPT_OVERRIDE;
450 intsrcovr->length = sizeof(*intsrcovr);
451 intsrcovr->source = i;
452 intsrcovr->gsi = cpu_to_le32(i);
453 intsrcovr->flags = cpu_to_le16(0xd); /* active high, level triggered */
454 }
455
456 local_nmi = acpi_data_push(table_data, sizeof *local_nmi);
457 local_nmi->type = ACPI_APIC_LOCAL_NMI;
458 local_nmi->length = sizeof(*local_nmi);
459 local_nmi->processor_id = 0xff; /* all processors */
460 local_nmi->flags = cpu_to_le16(0);
461 local_nmi->lint = 1; /* ACPI_LINT1 */
462
463 build_header(linker, table_data,
821e3227 464 (void *)(table_data->data + madt_start), "APIC",
72c194f7
MT
465 table_data->len - madt_start, 1);
466}
467
711b20b4 468#include "hw/i386/ssdt-tpm.hex"
72c194f7 469
99fd437d
MT
470/* Assign BSEL property to all buses. In the future, this can be changed
471 * to only assign to buses that support hotplug.
472 */
473static void *acpi_set_bsel(PCIBus *bus, void *opaque)
474{
475 unsigned *bsel_alloc = opaque;
476 unsigned *bus_bsel;
477
39b888bd 478 if (qbus_is_hotpluggable(BUS(bus))) {
99fd437d
MT
479 bus_bsel = g_malloc(sizeof *bus_bsel);
480
481 *bus_bsel = (*bsel_alloc)++;
482 object_property_add_uint32_ptr(OBJECT(bus), ACPI_PCIHP_PROP_BSEL,
483 bus_bsel, NULL);
484 }
485
486 return bsel_alloc;
487}
488
489static void acpi_set_pci_info(void)
490{
491 PCIBus *bus = find_i440fx(); /* TODO: Q35 support */
492 unsigned bsel_alloc = 0;
493
494 if (bus) {
495 /* Scan all PCI buses. Set property to enable acpi based hotplug. */
496 pci_for_each_bus_depth_first(bus, acpi_set_bsel, NULL, &bsel_alloc);
497 }
498}
499
62b52c26 500static void build_append_pcihp_notify_entry(Aml *method, int slot)
99fd437d 501{
62b52c26
IM
502 Aml *if_ctx;
503 int32_t devfn = PCI_DEVFN(slot, 0);
504
505 if_ctx = aml_if(aml_and(aml_arg(0), aml_int(0x1U << slot)));
506 aml_append(if_ctx, aml_notify(aml_name("S%.02X", devfn), aml_arg(1)));
507 aml_append(method, if_ctx);
99fd437d
MT
508}
509
62b52c26 510static void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus,
b23046ab 511 bool pcihp_bridge_en)
99fd437d 512{
62b52c26 513 Aml *dev, *notify_method, *method;
99fd437d 514 QObject *bsel;
b23046ab
IM
515 PCIBus *sec;
516 int i;
133a2da4 517
99fd437d
MT
518 bsel = object_property_get_qobject(OBJECT(bus), ACPI_PCIHP_PROP_BSEL, NULL);
519 if (bsel) {
62b52c26
IM
520 int64_t bsel_val = qint_get_int(qobject_to_qint(bsel));
521
522 aml_append(parent_scope, aml_name_decl("BSEL", aml_int(bsel_val)));
523 notify_method = aml_method("DVNT", 2);
8dcf525a 524 }
99fd437d 525
8dcf525a
MT
526 for (i = 0; i < ARRAY_SIZE(bus->devices); i += PCI_FUNC_MAX) {
527 DeviceClass *dc;
528 PCIDeviceClass *pc;
529 PCIDevice *pdev = bus->devices[i];
530 int slot = PCI_SLOT(i);
b23046ab 531 bool hotplug_enabled_dev;
093a35e5 532 bool bridge_in_acpi;
99fd437d 533
8dcf525a 534 if (!pdev) {
b23046ab 535 if (bsel) { /* add hotplug slots for non present devices */
62b52c26
IM
536 dev = aml_device("S%.02X", PCI_DEVFN(slot, 0));
537 aml_append(dev, aml_name_decl("_SUN", aml_int(slot)));
538 aml_append(dev, aml_name_decl("_ADR", aml_int(slot << 16)));
539 method = aml_method("_EJ0", 1);
540 aml_append(method,
541 aml_call2("PCEJ", aml_name("BSEL"), aml_name("_SUN"))
542 );
543 aml_append(dev, method);
544 aml_append(parent_scope, dev);
545
546 build_append_pcihp_notify_entry(notify_method, slot);
b23046ab 547 }
8dcf525a
MT
548 continue;
549 }
99fd437d 550
8dcf525a
MT
551 pc = PCI_DEVICE_GET_CLASS(pdev);
552 dc = DEVICE_GET_CLASS(pdev);
99fd437d 553
093a35e5
MT
554 /* When hotplug for bridges is enabled, bridges are
555 * described in ACPI separately (see build_pci_bus_end).
556 * In this case they aren't themselves hot-pluggable.
a20275fa 557 * Hotplugged bridges *are* hot-pluggable.
093a35e5 558 */
b23046ab
IM
559 bridge_in_acpi = pc->is_bridge && pcihp_bridge_en &&
560 !DEVICE(pdev)->hotplugged;
561
562 hotplug_enabled_dev = bsel && dc->hotpluggable && !bridge_in_acpi;
093a35e5 563
b23046ab
IM
564 if (pc->class_id == PCI_CLASS_BRIDGE_ISA) {
565 continue;
99fd437d
MT
566 }
567
62b52c26
IM
568 /* start to compose PCI slot descriptor */
569 dev = aml_device("S%.02X", PCI_DEVFN(slot, 0));
570 aml_append(dev, aml_name_decl("_ADR", aml_int(slot << 16)));
571
8dcf525a 572 if (pc->class_id == PCI_CLASS_DISPLAY_VGA) {
62b52c26
IM
573 /* add VGA specific AML methods */
574 int s3d;
575
8dcf525a 576 if (object_dynamic_cast(OBJECT(pdev), "qxl-vga")) {
62b52c26 577 s3d = 3;
b23046ab 578 } else {
62b52c26 579 s3d = 0;
99fd437d 580 }
62b52c26
IM
581
582 method = aml_method("_S1D", 0);
583 aml_append(method, aml_return(aml_int(0)));
584 aml_append(dev, method);
585
586 method = aml_method("_S2D", 0);
587 aml_append(method, aml_return(aml_int(0)));
588 aml_append(dev, method);
589
590 method = aml_method("_S3D", 0);
591 aml_append(method, aml_return(aml_int(s3d)));
592 aml_append(dev, method);
b23046ab 593 } else if (hotplug_enabled_dev) {
62b52c26
IM
594 /* add _SUN/_EJ0 to make slot hotpluggable */
595 aml_append(dev, aml_name_decl("_SUN", aml_int(slot)));
99fd437d 596
62b52c26
IM
597 method = aml_method("_EJ0", 1);
598 aml_append(method,
599 aml_call2("PCEJ", aml_name("BSEL"), aml_name("_SUN"))
600 );
601 aml_append(dev, method);
602
603 if (bsel) {
604 build_append_pcihp_notify_entry(notify_method, slot);
605 }
b23046ab 606 } else if (bridge_in_acpi) {
62b52c26
IM
607 /*
608 * device is coldplugged bridge,
609 * add child device descriptions into its scope
610 */
b23046ab 611 PCIBus *sec_bus = pci_bridge_get_sec_bus(PCI_BRIDGE(pdev));
b23046ab 612
62b52c26 613 build_append_pci_bus_devices(dev, sec_bus, pcihp_bridge_en);
8dcf525a 614 }
62b52c26
IM
615 /* slot descriptor has been composed, add it into parent context */
616 aml_append(parent_scope, dev);
8dcf525a
MT
617 }
618
619 if (bsel) {
62b52c26 620 aml_append(parent_scope, notify_method);
99fd437d
MT
621 }
622
623 /* Append PCNT method to notify about events on local and child buses.
624 * Add unconditionally for root since DSDT expects it.
72c194f7 625 */
62b52c26 626 method = aml_method("PCNT", 0);
99fd437d 627
b23046ab
IM
628 /* If bus supports hotplug select it and notify about local events */
629 if (bsel) {
62b52c26
IM
630 int64_t bsel_val = qint_get_int(qobject_to_qint(bsel));
631 aml_append(method, aml_store(aml_int(bsel_val), aml_name("BNUM")));
632 aml_append(method,
633 aml_call2("DVNT", aml_name("PCIU"), aml_int(1) /* Device Check */)
634 );
635 aml_append(method,
636 aml_call2("DVNT", aml_name("PCID"), aml_int(3)/* Eject Request */)
637 );
b23046ab 638 }
99fd437d 639
b23046ab
IM
640 /* Notify about child bus events in any case */
641 if (pcihp_bridge_en) {
642 QLIST_FOREACH(sec, &bus->child, sibling) {
62b52c26
IM
643 int32_t devfn = sec->parent_dev->devfn;
644
645 aml_append(method, aml_name("^S%.02X.PCNT", devfn));
99fd437d 646 }
72c194f7 647 }
62b52c26 648 aml_append(parent_scope, method);
72c194f7
MT
649}
650
72c194f7
MT
651static void
652build_ssdt(GArray *table_data, GArray *linker,
653 AcpiCpuInfo *cpu, AcpiPmInfo *pm, AcpiMiscInfo *misc,
654 PcPciInfo *pci, PcGuestInfo *guest_info)
655{
bef3492d
IM
656 MachineState *machine = MACHINE(qdev_get_machine());
657 uint32_t nr_mem = machine->ram_slots;
2fd71f1b 658 unsigned acpi_cpus = guest_info->apic_id_limit;
20843d16 659 Aml *ssdt, *sb_scope, *scope, *pkg, *dev, *method, *crs, *field, *ifctx;
72c194f7
MT
660 int i;
661
011bb749 662 ssdt = init_aml_allocator();
2fd71f1b
LE
663 /* The current AML generator can cover the APIC ID range [0..255],
664 * inclusive, for VCPU hotplug. */
665 QEMU_BUILD_BUG_ON(ACPI_CPU_HOTPLUG_ID_LIMIT > 256);
666 g_assert(acpi_cpus <= ACPI_CPU_HOTPLUG_ID_LIMIT);
667
4ec8d2b3
IM
668 /* Reserve space for header */
669 acpi_data_push(ssdt->buf, sizeof(AcpiTableHeader));
72c194f7 670
500b11ea 671 scope = aml_scope("\\_SB.PCI0");
60efd429
IM
672 /* build PCI0._CRS */
673 crs = aml_resource_template();
674 aml_append(crs,
675 aml_word_bus_number(aml_min_fixed, aml_max_fixed, aml_pos_decode,
676 0x0000, 0x0000, 0x00FF, 0x0000, 0x0100));
677 aml_append(crs, aml_io(aml_decode16, 0x0CF8, 0x0CF8, 0x01, 0x08));
678
679 aml_append(crs,
680 aml_word_io(aml_min_fixed, aml_max_fixed,
681 aml_pos_decode, aml_entire_range,
682 0x0000, 0x0000, 0x0CF7, 0x0000, 0x0CF8));
d31c909e
IM
683 aml_append(crs,
684 aml_word_io(aml_min_fixed, aml_max_fixed,
685 aml_pos_decode, aml_entire_range,
686 0x0000, 0x0D00, 0xFFFF, 0x0000, 0xF300));
60efd429
IM
687 aml_append(crs,
688 aml_dword_memory(aml_pos_decode, aml_min_fixed, aml_max_fixed,
689 aml_cacheable, aml_ReadWrite,
690 0, 0x000A0000, 0x000BFFFF, 0, 0x00020000));
691 aml_append(crs,
692 aml_dword_memory(aml_pos_decode, aml_min_fixed, aml_max_fixed,
693 aml_non_cacheable, aml_ReadWrite,
694 0, pci->w32.begin, pci->w32.end - 1, 0,
695 pci->w32.end - pci->w32.begin));
696 if (pci->w64.begin) {
697 aml_append(crs,
698 aml_qword_memory(aml_pos_decode, aml_min_fixed, aml_max_fixed,
699 aml_cacheable, aml_ReadWrite,
700 0, pci->w64.begin, pci->w64.end - 1, 0,
701 pci->w64.end - pci->w64.begin));
702 }
703 aml_append(scope, aml_name_decl("_CRS", crs));
704
d31c909e
IM
705 /* reserve GPE0 block resources */
706 dev = aml_device("GPE0");
707 aml_append(dev, aml_name_decl("_HID", aml_string("PNP0A06")));
708 aml_append(dev, aml_name_decl("_UID", aml_string("GPE0 resources")));
709 /* device present, functioning, decoding, not shown in UI */
710 aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
711 crs = aml_resource_template();
712 aml_append(crs,
713 aml_io(aml_decode16, pm->gpe0_blk, pm->gpe0_blk, 1, pm->gpe0_blk_len)
714 );
715 aml_append(dev, aml_name_decl("_CRS", crs));
716 aml_append(scope, dev);
717
500b11ea
IM
718 /* reserve PCIHP resources */
719 if (pm->pcihp_io_len) {
720 dev = aml_device("PHPR");
721 aml_append(dev, aml_name_decl("_HID", aml_string("PNP0A06")));
722 aml_append(dev,
723 aml_name_decl("_UID", aml_string("PCI Hotplug resources")));
724 /* device present, functioning, decoding, not shown in UI */
725 aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
726 crs = aml_resource_template();
727 aml_append(crs,
728 aml_io(aml_decode16, pm->pcihp_io_base, pm->pcihp_io_base, 1,
729 pm->pcihp_io_len)
730 );
731 aml_append(dev, aml_name_decl("_CRS", crs));
732 aml_append(scope, dev);
733 }
734 aml_append(ssdt, scope);
735
ebc3028f
IM
736 /* create S3_ / S4_ / S5_ packages if necessary */
737 scope = aml_scope("\\");
738 if (!pm->s3_disabled) {
739 pkg = aml_package(4);
740 aml_append(pkg, aml_int(1)); /* PM1a_CNT.SLP_TYP */
741 aml_append(pkg, aml_int(1)); /* PM1b_CNT.SLP_TYP, FIXME: not impl. */
742 aml_append(pkg, aml_int(0)); /* reserved */
743 aml_append(pkg, aml_int(0)); /* reserved */
744 aml_append(scope, aml_name_decl("_S3", pkg));
745 }
746
747 if (!pm->s4_disabled) {
748 pkg = aml_package(4);
749 aml_append(pkg, aml_int(pm->s4_val)); /* PM1a_CNT.SLP_TYP */
750 /* PM1b_CNT.SLP_TYP, FIXME: not impl. */
751 aml_append(pkg, aml_int(pm->s4_val));
752 aml_append(pkg, aml_int(0)); /* reserved */
753 aml_append(pkg, aml_int(0)); /* reserved */
754 aml_append(scope, aml_name_decl("_S4", pkg));
755 }
756
757 pkg = aml_package(4);
758 aml_append(pkg, aml_int(0)); /* PM1a_CNT.SLP_TYP */
759 aml_append(pkg, aml_int(0)); /* PM1b_CNT.SLP_TYP not impl. */
760 aml_append(pkg, aml_int(0)); /* reserved */
761 aml_append(pkg, aml_int(0)); /* reserved */
762 aml_append(scope, aml_name_decl("_S5", pkg));
763 aml_append(ssdt, scope);
764
8ac6f7a6
IM
765 if (misc->applesmc_io_base) {
766 scope = aml_scope("\\_SB.PCI0.ISA");
767 dev = aml_device("SMC");
768
769 aml_append(dev, aml_name_decl("_HID", aml_eisaid("APP0001")));
770 /* device present, functioning, decoding, not shown in UI */
771 aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
772
773 crs = aml_resource_template();
774 aml_append(crs,
775 aml_io(aml_decode16, misc->applesmc_io_base, misc->applesmc_io_base,
776 0x01, APPLESMC_MAX_DATA_LENGTH)
777 );
778 aml_append(crs, aml_irq_no_flags(6));
779 aml_append(dev, aml_name_decl("_CRS", crs));
780
781 aml_append(scope, dev);
782 aml_append(ssdt, scope);
783 }
784
cd61cb2e
IM
785 if (misc->pvpanic_port) {
786 scope = aml_scope("\\_SB.PCI0.ISA");
787
788 dev = aml_device("PEVR");
e65bef69 789 aml_append(dev, aml_name_decl("_HID", aml_string("QEMU0001")));
cd61cb2e
IM
790
791 crs = aml_resource_template();
792 aml_append(crs,
793 aml_io(aml_decode16, misc->pvpanic_port, misc->pvpanic_port, 1, 1)
794 );
795 aml_append(dev, aml_name_decl("_CRS", crs));
796
797 aml_append(dev, aml_operation_region("PEOR", aml_system_io,
798 misc->pvpanic_port, 1));
799 field = aml_field("PEOR", aml_byte_acc);
800 aml_append(field, aml_named_field("PEPT", 8));
801 aml_append(dev, field);
802
803 method = aml_method("RDPT", 0);
804 aml_append(method, aml_store(aml_name("PEPT"), aml_local(0)));
805 aml_append(method, aml_return(aml_local(0)));
806 aml_append(dev, method);
807
808 method = aml_method("WRPT", 1);
809 aml_append(method, aml_store(aml_arg(0), aml_name("PEPT")));
810 aml_append(dev, method);
811
812 aml_append(scope, dev);
813 aml_append(ssdt, scope);
814 }
815
011bb749 816 sb_scope = aml_scope("_SB");
72c194f7 817 {
ddf1ec2f
IM
818 /* create PCI0.PRES device and its _CRS to reserve CPU hotplug MMIO */
819 dev = aml_device("PCI0." stringify(CPU_HOTPLUG_RESOURCE_DEVICE));
820 aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A06")));
821 aml_append(dev,
822 aml_name_decl("_UID", aml_string("CPU Hotplug resources"))
823 );
824 /* device present, functioning, decoding, not shown in UI */
825 aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
826 crs = aml_resource_template();
827 aml_append(crs,
828 aml_io(aml_decode16, pm->cpu_hp_io_base, pm->cpu_hp_io_base, 1,
829 pm->cpu_hp_io_len)
830 );
831 aml_append(dev, aml_name_decl("_CRS", crs));
832 aml_append(sb_scope, dev);
833 /* declare CPU hotplug MMIO region and PRS field to access it */
834 aml_append(sb_scope, aml_operation_region(
835 "PRST", aml_system_io, pm->cpu_hp_io_base, pm->cpu_hp_io_len));
836 field = aml_field("PRST", aml_byte_acc);
837 aml_append(field, aml_named_field("PRS", 256));
838 aml_append(sb_scope, field);
839
72c194f7
MT
840 /* build Processor object for each processor */
841 for (i = 0; i < acpi_cpus; i++) {
20843d16
IM
842 dev = aml_processor(i, 0, 0, "CP%.02X", i);
843
844 method = aml_method("_MAT", 0);
845 aml_append(method, aml_return(aml_call1("CPMA", aml_int(i))));
846 aml_append(dev, method);
847
848 method = aml_method("_STA", 0);
849 aml_append(method, aml_return(aml_call1("CPST", aml_int(i))));
850 aml_append(dev, method);
851
852 method = aml_method("_EJ0", 1);
853 aml_append(method,
854 aml_return(aml_call2("CPEJ", aml_int(i), aml_arg(0)))
855 );
856 aml_append(dev, method);
857
858 aml_append(sb_scope, dev);
72c194f7
MT
859 }
860
861 /* build this code:
862 * Method(NTFY, 2) {If (LEqual(Arg0, 0x00)) {Notify(CP00, Arg1)} ...}
863 */
864 /* Arg0 = Processor ID = APIC ID */
20843d16
IM
865 method = aml_method("NTFY", 2);
866 for (i = 0; i < acpi_cpus; i++) {
867 ifctx = aml_if(aml_equal(aml_arg(0), aml_int(i)));
868 aml_append(ifctx,
869 aml_notify(aml_name("CP%.02X", i), aml_arg(1))
870 );
871 aml_append(method, ifctx);
872 }
873 aml_append(sb_scope, method);
874
875 /* build "Name(CPON, Package() { One, One, ..., Zero, Zero, ... })"
876 *
877 * Note: The ability to create variable-sized packages was first
e71fd764 878 * introduced in ACPI 2.0. ACPI 1.0 only allowed fixed-size packages
20843d16
IM
879 * ith up to 255 elements. Windows guests up to win2k8 fail when
880 * VarPackageOp is used.
881 */
882 pkg = acpi_cpus <= 255 ? aml_package(acpi_cpus) :
883 aml_varpackage(acpi_cpus);
72c194f7 884
20843d16
IM
885 for (i = 0; i < acpi_cpus; i++) {
886 uint8_t b = test_bit(i, cpu->found_cpus) ? 0x01 : 0x00;
887 aml_append(pkg, aml_int(b));
72c194f7 888 }
20843d16 889 aml_append(sb_scope, aml_name_decl("CPON", pkg));
72c194f7 890
8698c0c0
IM
891 /* build memory devices */
892 assert(nr_mem <= ACPI_MAX_RAM_SLOTS);
2c6b94d8
IM
893 scope = aml_scope("\\_SB.PCI0." stringify(MEMORY_HOTPLUG_DEVICE));
894 aml_append(scope,
895 aml_name_decl(stringify(MEMORY_SLOTS_NUMBER), aml_int(nr_mem))
896 );
897
898 crs = aml_resource_template();
899 aml_append(crs,
900 aml_io(aml_decode16, pm->mem_hp_io_base, pm->mem_hp_io_base, 0,
901 pm->mem_hp_io_len)
902 );
903 aml_append(scope, aml_name_decl("_CRS", crs));
904
905 aml_append(scope, aml_operation_region(
906 stringify(MEMORY_HOTPLUG_IO_REGION), aml_system_io,
907 pm->mem_hp_io_base, pm->mem_hp_io_len)
908 );
909
910 field = aml_field(stringify(MEMORY_HOTPLUG_IO_REGION), aml_dword_acc);
911 aml_append(field, /* read only */
912 aml_named_field(stringify(MEMORY_SLOT_ADDR_LOW), 32));
913 aml_append(field, /* read only */
914 aml_named_field(stringify(MEMORY_SLOT_ADDR_HIGH), 32));
915 aml_append(field, /* read only */
916 aml_named_field(stringify(MEMORY_SLOT_SIZE_LOW), 32));
917 aml_append(field, /* read only */
918 aml_named_field(stringify(MEMORY_SLOT_SIZE_HIGH), 32));
919 aml_append(field, /* read only */
920 aml_named_field(stringify(MEMORY_SLOT_PROXIMITY), 32));
921 aml_append(scope, field);
922
923 field = aml_field(stringify(MEMORY_HOTPLUG_IO_REGION), aml_byte_acc);
924 aml_append(field, aml_reserved_field(160 /* bits, Offset(20) */));
925 aml_append(field, /* 1 if enabled, read only */
926 aml_named_field(stringify(MEMORY_SLOT_ENABLED), 1));
927 aml_append(field,
928 /*(read) 1 if has a insert event. (write) 1 to clear event */
929 aml_named_field(stringify(MEMORY_SLOT_INSERT_EVENT), 1));
930 aml_append(scope, field);
931
932 field = aml_field(stringify(MEMORY_HOTPLUG_IO_REGION), aml_dword_acc);
933 aml_append(field, /* DIMM selector, write only */
934 aml_named_field(stringify(MEMORY_SLOT_SLECTOR), 32));
935 aml_append(field, /* _OST event code, write only */
936 aml_named_field(stringify(MEMORY_SLOT_OST_EVENT), 32));
937 aml_append(field, /* _OST status code, write only */
938 aml_named_field(stringify(MEMORY_SLOT_OST_STATUS), 32));
939 aml_append(scope, field);
940
941 aml_append(sb_scope, scope);
8698c0c0
IM
942
943 for (i = 0; i < nr_mem; i++) {
944 #define BASEPATH "\\_SB.PCI0." stringify(MEMORY_HOTPLUG_DEVICE) "."
945 const char *s;
946
947 dev = aml_device("MP%02X", i);
948 aml_append(dev, aml_name_decl("_UID", aml_string("0x%02X", i)));
949 aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0C80")));
bef3492d 950
8698c0c0
IM
951 method = aml_method("_CRS", 0);
952 s = BASEPATH stringify(MEMORY_SLOT_CRS_METHOD);
953 aml_append(method, aml_return(aml_call1(s, aml_name("_UID"))));
954 aml_append(dev, method);
955
956 method = aml_method("_STA", 0);
957 s = BASEPATH stringify(MEMORY_SLOT_STATUS_METHOD);
958 aml_append(method, aml_return(aml_call1(s, aml_name("_UID"))));
959 aml_append(dev, method);
960
961 method = aml_method("_PXM", 0);
962 s = BASEPATH stringify(MEMORY_SLOT_PROXIMITY_METHOD);
963 aml_append(method, aml_return(aml_call1(s, aml_name("_UID"))));
964 aml_append(dev, method);
965
966 method = aml_method("_OST", 3);
967 s = BASEPATH stringify(MEMORY_SLOT_OST_METHOD);
968 aml_append(method, aml_return(aml_call4(
969 s, aml_name("_UID"), aml_arg(0), aml_arg(1), aml_arg(2)
970 )));
971 aml_append(dev, method);
972
973 aml_append(sb_scope, dev);
bef3492d
IM
974 }
975
8698c0c0
IM
976 /* build Method(MEMORY_SLOT_NOTIFY_METHOD, 2) {
977 * If (LEqual(Arg0, 0x00)) {Notify(MP00, Arg1)} ...
978 */
979 method = aml_method(stringify(MEMORY_SLOT_NOTIFY_METHOD), 2);
980 for (i = 0; i < nr_mem; i++) {
981 ifctx = aml_if(aml_equal(aml_arg(0), aml_int(i)));
982 aml_append(ifctx,
983 aml_notify(aml_name("MP%.02X", i), aml_arg(1))
984 );
985 aml_append(method, ifctx);
986 }
987 aml_append(sb_scope, method);
988
72c194f7 989 {
8dcf525a
MT
990 Object *pci_host;
991 PCIBus *bus = NULL;
992 bool ambiguous;
993
994 pci_host = object_resolve_path_type("", TYPE_PCI_HOST_BRIDGE, &ambiguous);
995 if (!ambiguous && pci_host) {
996 bus = PCI_HOST_BRIDGE(pci_host)->bus;
997 }
72c194f7 998
99fd437d 999 if (bus) {
62b52c26 1000 Aml *scope = aml_scope("PCI0");
99fd437d 1001 /* Scan all PCI buses. Generate tables to support hotplug. */
62b52c26
IM
1002 build_append_pci_bus_devices(scope, bus, pm->pcihp_bridge_en);
1003 aml_append(sb_scope, scope);
72c194f7 1004 }
72c194f7 1005 }
011bb749 1006 aml_append(ssdt, sb_scope);
72c194f7
MT
1007 }
1008
011bb749
IM
1009 /* copy AML table into ACPI tables blob and patch header there */
1010 g_array_append_vals(table_data, ssdt->buf->data, ssdt->buf->len);
72c194f7 1011 build_header(linker, table_data,
011bb749
IM
1012 (void *)(table_data->data + table_data->len - ssdt->buf->len),
1013 "SSDT", ssdt->buf->len, 1);
1014 free_aml_allocator();
72c194f7
MT
1015}
1016
1017static void
1018build_hpet(GArray *table_data, GArray *linker)
1019{
1020 Acpi20Hpet *hpet;
1021
1022 hpet = acpi_data_push(table_data, sizeof(*hpet));
1023 /* Note timer_block_id value must be kept in sync with value advertised by
1024 * emulated hpet
1025 */
1026 hpet->timer_block_id = cpu_to_le32(0x8086a201);
1027 hpet->addr.address = cpu_to_le64(HPET_BASE);
1028 build_header(linker, table_data,
821e3227 1029 (void *)hpet, "HPET", sizeof(*hpet), 1);
72c194f7
MT
1030}
1031
711b20b4 1032static void
42a5b308 1033build_tpm_tcpa(GArray *table_data, GArray *linker, GArray *tcpalog)
711b20b4
SB
1034{
1035 Acpi20Tcpa *tcpa = acpi_data_push(table_data, sizeof *tcpa);
42a5b308 1036 uint64_t log_area_start_address = acpi_data_len(tcpalog);
711b20b4
SB
1037
1038 tcpa->platform_class = cpu_to_le16(TPM_TCPA_ACPI_CLASS_CLIENT);
1039 tcpa->log_area_minimum_length = cpu_to_le32(TPM_LOG_AREA_MINIMUM_SIZE);
1040 tcpa->log_area_start_address = cpu_to_le64(log_area_start_address);
1041
42a5b308
SB
1042 bios_linker_loader_alloc(linker, ACPI_BUILD_TPMLOG_FILE, 1,
1043 false /* high memory */);
1044
711b20b4
SB
1045 /* log area start address to be filled by Guest linker */
1046 bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE,
42a5b308 1047 ACPI_BUILD_TPMLOG_FILE,
711b20b4
SB
1048 table_data, &tcpa->log_area_start_address,
1049 sizeof(tcpa->log_area_start_address));
1050
1051 build_header(linker, table_data,
1052 (void *)tcpa, "TCPA", sizeof(*tcpa), 2);
1053
42a5b308 1054 acpi_data_push(tcpalog, TPM_LOG_AREA_MINIMUM_SIZE);
711b20b4
SB
1055}
1056
1057static void
1058build_tpm_ssdt(GArray *table_data, GArray *linker)
1059{
1060 void *tpm_ptr;
1061
1062 tpm_ptr = acpi_data_push(table_data, sizeof(ssdt_tpm_aml));
1063 memcpy(tpm_ptr, ssdt_tpm_aml, sizeof(ssdt_tpm_aml));
1064}
1065
04ed3ea8
IM
1066typedef enum {
1067 MEM_AFFINITY_NOFLAGS = 0,
1068 MEM_AFFINITY_ENABLED = (1 << 0),
1069 MEM_AFFINITY_HOTPLUGGABLE = (1 << 1),
1070 MEM_AFFINITY_NON_VOLATILE = (1 << 2),
1071} MemoryAffinityFlags;
1072
72c194f7 1073static void
04ed3ea8
IM
1074acpi_build_srat_memory(AcpiSratMemoryAffinity *numamem, uint64_t base,
1075 uint64_t len, int node, MemoryAffinityFlags flags)
72c194f7
MT
1076{
1077 numamem->type = ACPI_SRAT_MEMORY;
1078 numamem->length = sizeof(*numamem);
1079 memset(numamem->proximity, 0, 4);
1080 numamem->proximity[0] = node;
04ed3ea8 1081 numamem->flags = cpu_to_le32(flags);
72c194f7
MT
1082 numamem->base_addr = cpu_to_le64(base);
1083 numamem->range_length = cpu_to_le64(len);
1084}
1085
1086static void
dd0247e0 1087build_srat(GArray *table_data, GArray *linker, PcGuestInfo *guest_info)
72c194f7
MT
1088{
1089 AcpiSystemResourceAffinityTable *srat;
1090 AcpiSratProcessorAffinity *core;
1091 AcpiSratMemoryAffinity *numamem;
1092
1093 int i;
1094 uint64_t curnode;
1095 int srat_start, numa_start, slots;
1096 uint64_t mem_len, mem_base, next_base;
cec65193
IM
1097 PCMachineState *pcms = PC_MACHINE(qdev_get_machine());
1098 ram_addr_t hotplugabble_address_space_size =
1099 object_property_get_int(OBJECT(pcms), PC_MACHINE_MEMHP_REGION_SIZE,
1100 NULL);
72c194f7
MT
1101
1102 srat_start = table_data->len;
1103
1104 srat = acpi_data_push(table_data, sizeof *srat);
1105 srat->reserved1 = cpu_to_le32(1);
1106 core = (void *)(srat + 1);
1107
1108 for (i = 0; i < guest_info->apic_id_limit; ++i) {
1109 core = acpi_data_push(table_data, sizeof *core);
1110 core->type = ACPI_SRAT_PROCESSOR;
1111 core->length = sizeof(*core);
1112 core->local_apic_id = i;
1113 curnode = guest_info->node_cpu[i];
1114 core->proximity_lo = curnode;
1115 memset(core->proximity_hi, 0, 3);
1116 core->local_sapic_eid = 0;
dd0247e0 1117 core->flags = cpu_to_le32(1);
72c194f7
MT
1118 }
1119
1120
1121 /* the memory map is a bit tricky, it contains at least one hole
1122 * from 640k-1M and possibly another one from 3.5G-4G.
1123 */
1124 next_base = 0;
1125 numa_start = table_data->len;
1126
1127 numamem = acpi_data_push(table_data, sizeof *numamem);
04ed3ea8 1128 acpi_build_srat_memory(numamem, 0, 640*1024, 0, MEM_AFFINITY_ENABLED);
72c194f7
MT
1129 next_base = 1024 * 1024;
1130 for (i = 1; i < guest_info->numa_nodes + 1; ++i) {
1131 mem_base = next_base;
1132 mem_len = guest_info->node_mem[i - 1];
1133 if (i == 1) {
1134 mem_len -= 1024 * 1024;
1135 }
1136 next_base = mem_base + mem_len;
1137
1138 /* Cut out the ACPI_PCI hole */
4c8a949b
EH
1139 if (mem_base <= guest_info->ram_size_below_4g &&
1140 next_base > guest_info->ram_size_below_4g) {
1141 mem_len -= next_base - guest_info->ram_size_below_4g;
72c194f7
MT
1142 if (mem_len > 0) {
1143 numamem = acpi_data_push(table_data, sizeof *numamem);
04ed3ea8
IM
1144 acpi_build_srat_memory(numamem, mem_base, mem_len, i - 1,
1145 MEM_AFFINITY_ENABLED);
72c194f7
MT
1146 }
1147 mem_base = 1ULL << 32;
4c8a949b
EH
1148 mem_len = next_base - guest_info->ram_size_below_4g;
1149 next_base += (1ULL << 32) - guest_info->ram_size_below_4g;
72c194f7
MT
1150 }
1151 numamem = acpi_data_push(table_data, sizeof *numamem);
04ed3ea8
IM
1152 acpi_build_srat_memory(numamem, mem_base, mem_len, i - 1,
1153 MEM_AFFINITY_ENABLED);
72c194f7
MT
1154 }
1155 slots = (table_data->len - numa_start) / sizeof *numamem;
1156 for (; slots < guest_info->numa_nodes + 2; slots++) {
1157 numamem = acpi_data_push(table_data, sizeof *numamem);
04ed3ea8 1158 acpi_build_srat_memory(numamem, 0, 0, 0, MEM_AFFINITY_NOFLAGS);
72c194f7
MT
1159 }
1160
cec65193
IM
1161 /*
1162 * Entry is required for Windows to enable memory hotplug in OS.
1163 * Memory devices may override proximity set by this entry,
1164 * providing _PXM method if necessary.
1165 */
1166 if (hotplugabble_address_space_size) {
1167 numamem = acpi_data_push(table_data, sizeof *numamem);
1168 acpi_build_srat_memory(numamem, pcms->hotplug_memory_base,
1169 hotplugabble_address_space_size, 0,
1170 MEM_AFFINITY_HOTPLUGGABLE |
1171 MEM_AFFINITY_ENABLED);
1172 }
1173
72c194f7
MT
1174 build_header(linker, table_data,
1175 (void *)(table_data->data + srat_start),
821e3227 1176 "SRAT",
72c194f7
MT
1177 table_data->len - srat_start, 1);
1178}
1179
1180static void
1181build_mcfg_q35(GArray *table_data, GArray *linker, AcpiMcfgInfo *info)
1182{
1183 AcpiTableMcfg *mcfg;
821e3227 1184 const char *sig;
72c194f7
MT
1185 int len = sizeof(*mcfg) + 1 * sizeof(mcfg->allocation[0]);
1186
1187 mcfg = acpi_data_push(table_data, len);
1188 mcfg->allocation[0].address = cpu_to_le64(info->mcfg_base);
1189 /* Only a single allocation so no need to play with segments */
1190 mcfg->allocation[0].pci_segment = cpu_to_le16(0);
1191 mcfg->allocation[0].start_bus_number = 0;
1192 mcfg->allocation[0].end_bus_number = PCIE_MMCFG_BUS(info->mcfg_size - 1);
1193
1194 /* MCFG is used for ECAM which can be enabled or disabled by guest.
1195 * To avoid table size changes (which create migration issues),
1196 * always create the table even if there are no allocations,
1197 * but set the signature to a reserved value in this case.
1198 * ACPI spec requires OSPMs to ignore such tables.
1199 */
1200 if (info->mcfg_base == PCIE_BASE_ADDR_UNMAPPED) {
821e3227
MT
1201 /* Reserved signature: ignored by OSPM */
1202 sig = "QEMU";
72c194f7 1203 } else {
821e3227 1204 sig = "MCFG";
72c194f7
MT
1205 }
1206 build_header(linker, table_data, (void *)mcfg, sig, len, 1);
1207}
1208
d4eb9119
LT
1209static void
1210build_dmar_q35(GArray *table_data, GArray *linker)
1211{
1212 int dmar_start = table_data->len;
1213
1214 AcpiTableDmar *dmar;
1215 AcpiDmarHardwareUnit *drhd;
1216
1217 dmar = acpi_data_push(table_data, sizeof(*dmar));
1218 dmar->host_address_width = VTD_HOST_ADDRESS_WIDTH - 1;
1219 dmar->flags = 0; /* No intr_remap for now */
1220
1221 /* DMAR Remapping Hardware Unit Definition structure */
1222 drhd = acpi_data_push(table_data, sizeof(*drhd));
1223 drhd->type = cpu_to_le16(ACPI_DMAR_TYPE_HARDWARE_UNIT);
1224 drhd->length = cpu_to_le16(sizeof(*drhd)); /* No device scope now */
1225 drhd->flags = ACPI_DMAR_INCLUDE_PCI_ALL;
1226 drhd->pci_segment = cpu_to_le16(0);
1227 drhd->address = cpu_to_le64(Q35_HOST_BRIDGE_IOMMU_ADDR);
1228
1229 build_header(linker, table_data, (void *)(table_data->data + dmar_start),
1230 "DMAR", table_data->len - dmar_start, 1);
1231}
1232
72c194f7
MT
1233static void
1234build_dsdt(GArray *table_data, GArray *linker, AcpiMiscInfo *misc)
1235{
53db092a
MT
1236 AcpiTableHeader *dsdt;
1237
72c194f7 1238 assert(misc->dsdt_code && misc->dsdt_size);
53db092a 1239
72c194f7
MT
1240 dsdt = acpi_data_push(table_data, misc->dsdt_size);
1241 memcpy(dsdt, misc->dsdt_code, misc->dsdt_size);
53db092a
MT
1242
1243 memset(dsdt, 0, sizeof *dsdt);
821e3227 1244 build_header(linker, table_data, dsdt, "DSDT",
53db092a 1245 misc->dsdt_size, 1);
72c194f7
MT
1246}
1247
1248/* Build final rsdt table */
1249static void
1250build_rsdt(GArray *table_data, GArray *linker, GArray *table_offsets)
1251{
1252 AcpiRsdtDescriptorRev1 *rsdt;
1253 size_t rsdt_len;
1254 int i;
1255
1256 rsdt_len = sizeof(*rsdt) + sizeof(uint32_t) * table_offsets->len;
1257 rsdt = acpi_data_push(table_data, rsdt_len);
1258 memcpy(rsdt->table_offset_entry, table_offsets->data,
1259 sizeof(uint32_t) * table_offsets->len);
1260 for (i = 0; i < table_offsets->len; ++i) {
1261 /* rsdt->table_offset_entry to be filled by Guest linker */
1262 bios_linker_loader_add_pointer(linker,
1263 ACPI_BUILD_TABLE_FILE,
1264 ACPI_BUILD_TABLE_FILE,
1265 table_data, &rsdt->table_offset_entry[i],
1266 sizeof(uint32_t));
1267 }
1268 build_header(linker, table_data,
821e3227 1269 (void *)rsdt, "RSDT", rsdt_len, 1);
72c194f7
MT
1270}
1271
1272static GArray *
1273build_rsdp(GArray *rsdp_table, GArray *linker, unsigned rsdt)
1274{
1275 AcpiRsdpDescriptor *rsdp = acpi_data_push(rsdp_table, sizeof *rsdp);
1276
d67aadcc 1277 bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, 16,
72c194f7
MT
1278 true /* fseg memory */);
1279
821e3227 1280 memcpy(&rsdp->signature, "RSD PTR ", 8);
72c194f7
MT
1281 memcpy(rsdp->oem_id, ACPI_BUILD_APPNAME6, 6);
1282 rsdp->rsdt_physical_address = cpu_to_le32(rsdt);
1283 /* Address to be filled by Guest linker */
1284 bios_linker_loader_add_pointer(linker, ACPI_BUILD_RSDP_FILE,
1285 ACPI_BUILD_TABLE_FILE,
1286 rsdp_table, &rsdp->rsdt_physical_address,
1287 sizeof rsdp->rsdt_physical_address);
1288 rsdp->checksum = 0;
1289 /* Checksum to be filled by Guest linker */
1290 bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE,
1291 rsdp, rsdp, sizeof *rsdp, &rsdp->checksum);
1292
1293 return rsdp_table;
1294}
1295
1296typedef
1297struct AcpiBuildTables {
1298 GArray *table_data;
1299 GArray *rsdp;
42a5b308 1300 GArray *tcpalog;
72c194f7
MT
1301 GArray *linker;
1302} AcpiBuildTables;
1303
1304static inline void acpi_build_tables_init(AcpiBuildTables *tables)
1305{
1306 tables->rsdp = g_array_new(false, true /* clear */, 1);
1307 tables->table_data = g_array_new(false, true /* clear */, 1);
42a5b308 1308 tables->tcpalog = g_array_new(false, true /* clear */, 1);
72c194f7
MT
1309 tables->linker = bios_linker_loader_init();
1310}
1311
1312static inline void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre)
1313{
1314 void *linker_data = bios_linker_loader_cleanup(tables->linker);
ac369a77 1315 g_free(linker_data);
afaa2e4b 1316 g_array_free(tables->rsdp, true);
ac369a77 1317 g_array_free(tables->table_data, true);
42a5b308 1318 g_array_free(tables->tcpalog, mfre);
72c194f7
MT
1319}
1320
1321typedef
1322struct AcpiBuildState {
1323 /* Copy of table in RAM (for patching). */
339240b5 1324 MemoryRegion *table_mr;
72c194f7
MT
1325 /* Is table patched? */
1326 uint8_t patched;
1327 PcGuestInfo *guest_info;
d70414a5 1328 void *rsdp;
339240b5
PB
1329 MemoryRegion *rsdp_mr;
1330 MemoryRegion *linker_mr;
72c194f7
MT
1331} AcpiBuildState;
1332
1333static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg)
1334{
1335 Object *pci_host;
1336 QObject *o;
1337 bool ambiguous;
1338
1339 pci_host = object_resolve_path_type("", TYPE_PCI_HOST_BRIDGE, &ambiguous);
1340 g_assert(!ambiguous);
1341 g_assert(pci_host);
1342
1343 o = object_property_get_qobject(pci_host, PCIE_HOST_MCFG_BASE, NULL);
1344 if (!o) {
1345 return false;
1346 }
1347 mcfg->mcfg_base = qint_get_int(qobject_to_qint(o));
097a97a6 1348 qobject_decref(o);
72c194f7
MT
1349
1350 o = object_property_get_qobject(pci_host, PCIE_HOST_MCFG_SIZE, NULL);
1351 assert(o);
1352 mcfg->mcfg_size = qint_get_int(qobject_to_qint(o));
097a97a6 1353 qobject_decref(o);
72c194f7
MT
1354 return true;
1355}
1356
d4eb9119
LT
1357static bool acpi_has_iommu(void)
1358{
1359 bool ambiguous;
1360 Object *intel_iommu;
1361
1362 intel_iommu = object_resolve_path_type("", TYPE_INTEL_IOMMU_DEVICE,
1363 &ambiguous);
1364 return intel_iommu && !ambiguous;
1365}
1366
72c194f7
MT
1367static
1368void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
1369{
1370 GArray *table_offsets;
07fb6176 1371 unsigned facs, ssdt, dsdt, rsdt;
72c194f7
MT
1372 AcpiCpuInfo cpu;
1373 AcpiPmInfo pm;
1374 AcpiMiscInfo misc;
1375 AcpiMcfgInfo mcfg;
1376 PcPciInfo pci;
1377 uint8_t *u;
07fb6176 1378 size_t aml_len = 0;
7c2c1fa5 1379 GArray *tables_blob = tables->table_data;
72c194f7
MT
1380
1381 acpi_get_cpu_info(&cpu);
1382 acpi_get_pm_info(&pm);
1383 acpi_get_dsdt(&misc);
72c194f7
MT
1384 acpi_get_misc_info(&misc);
1385 acpi_get_pci_info(&pci);
1386
1387 table_offsets = g_array_new(false, true /* clear */,
1388 sizeof(uint32_t));
8b310fc4 1389 ACPI_BUILD_DPRINTF("init ACPI tables\n");
72c194f7
MT
1390
1391 bios_linker_loader_alloc(tables->linker, ACPI_BUILD_TABLE_FILE,
1392 64 /* Ensure FACS is aligned */,
1393 false /* high memory */);
1394
1395 /*
1396 * FACS is pointed to by FADT.
1397 * We place it first since it's the only table that has alignment
1398 * requirements.
1399 */
7c2c1fa5
IM
1400 facs = tables_blob->len;
1401 build_facs(tables_blob, tables->linker, guest_info);
72c194f7
MT
1402
1403 /* DSDT is pointed to by FADT */
7c2c1fa5
IM
1404 dsdt = tables_blob->len;
1405 build_dsdt(tables_blob, tables->linker, &misc);
72c194f7 1406
07fb6176
PB
1407 /* Count the size of the DSDT and SSDT, we will need it for legacy
1408 * sizing of ACPI tables.
1409 */
7c2c1fa5 1410 aml_len += tables_blob->len - dsdt;
07fb6176 1411
72c194f7 1412 /* ACPI tables pointed to by RSDT */
7c2c1fa5
IM
1413 acpi_add_table(table_offsets, tables_blob);
1414 build_fadt(tables_blob, tables->linker, &pm, facs, dsdt);
72c194f7 1415
7c2c1fa5
IM
1416 ssdt = tables_blob->len;
1417 acpi_add_table(table_offsets, tables_blob);
1418 build_ssdt(tables_blob, tables->linker, &cpu, &pm, &misc, &pci,
72c194f7 1419 guest_info);
7c2c1fa5 1420 aml_len += tables_blob->len - ssdt;
72c194f7 1421
7c2c1fa5
IM
1422 acpi_add_table(table_offsets, tables_blob);
1423 build_madt(tables_blob, tables->linker, &cpu, guest_info);
9ac1c4c0 1424
72c194f7 1425 if (misc.has_hpet) {
7c2c1fa5
IM
1426 acpi_add_table(table_offsets, tables_blob);
1427 build_hpet(tables_blob, tables->linker);
711b20b4
SB
1428 }
1429 if (misc.has_tpm) {
7c2c1fa5
IM
1430 acpi_add_table(table_offsets, tables_blob);
1431 build_tpm_tcpa(tables_blob, tables->linker, tables->tcpalog);
711b20b4 1432
7c2c1fa5
IM
1433 acpi_add_table(table_offsets, tables_blob);
1434 build_tpm_ssdt(tables_blob, tables->linker);
72c194f7
MT
1435 }
1436 if (guest_info->numa_nodes) {
7c2c1fa5
IM
1437 acpi_add_table(table_offsets, tables_blob);
1438 build_srat(tables_blob, tables->linker, guest_info);
72c194f7
MT
1439 }
1440 if (acpi_get_mcfg(&mcfg)) {
7c2c1fa5
IM
1441 acpi_add_table(table_offsets, tables_blob);
1442 build_mcfg_q35(tables_blob, tables->linker, &mcfg);
72c194f7 1443 }
d4eb9119 1444 if (acpi_has_iommu()) {
7c2c1fa5
IM
1445 acpi_add_table(table_offsets, tables_blob);
1446 build_dmar_q35(tables_blob, tables->linker);
d4eb9119 1447 }
72c194f7
MT
1448
1449 /* Add tables supplied by user (if any) */
1450 for (u = acpi_table_first(); u; u = acpi_table_next(u)) {
1451 unsigned len = acpi_table_len(u);
1452
7c2c1fa5
IM
1453 acpi_add_table(table_offsets, tables_blob);
1454 g_array_append_vals(tables_blob, u, len);
72c194f7
MT
1455 }
1456
1457 /* RSDT is pointed to by RSDP */
7c2c1fa5
IM
1458 rsdt = tables_blob->len;
1459 build_rsdt(tables_blob, tables->linker, table_offsets);
72c194f7
MT
1460
1461 /* RSDP is in FSEG memory, so allocate it separately */
1462 build_rsdp(tables->rsdp, tables->linker, rsdt);
1463
07fb6176 1464 /* We'll expose it all to Guest so we want to reduce
72c194f7 1465 * chance of size changes.
07fb6176
PB
1466 *
1467 * We used to align the tables to 4k, but of course this would
1468 * too simple to be enough. 4k turned out to be too small an
1469 * alignment very soon, and in fact it is almost impossible to
1470 * keep the table size stable for all (max_cpus, max_memory_slots)
1471 * combinations. So the table size is always 64k for pc-i440fx-2.1
1472 * and we give an error if the table grows beyond that limit.
1473 *
1474 * We still have the problem of migrating from "-M pc-i440fx-2.0". For
1475 * that, we exploit the fact that QEMU 2.1 generates _smaller_ tables
1476 * than 2.0 and we can always pad the smaller tables with zeros. We can
1477 * then use the exact size of the 2.0 tables.
1478 *
1479 * All this is for PIIX4, since QEMU 2.0 didn't support Q35 migration.
72c194f7 1480 */
07fb6176
PB
1481 if (guest_info->legacy_acpi_table_size) {
1482 /* Subtracting aml_len gives the size of fixed tables. Then add the
1483 * size of the PIIX4 DSDT/SSDT in QEMU 2.0.
1484 */
1485 int legacy_aml_len =
1486 guest_info->legacy_acpi_table_size +
1487 ACPI_BUILD_LEGACY_CPU_AML_SIZE * max_cpus;
1488 int legacy_table_size =
7c2c1fa5 1489 ROUND_UP(tables_blob->len - aml_len + legacy_aml_len,
07fb6176 1490 ACPI_BUILD_ALIGN_SIZE);
7c2c1fa5 1491 if (tables_blob->len > legacy_table_size) {
07fb6176 1492 /* Should happen only with PCI bridges and -M pc-i440fx-2.0. */
868270f2 1493 error_report("Warning: migration may not work.");
07fb6176 1494 }
7c2c1fa5 1495 g_array_set_size(tables_blob, legacy_table_size);
07fb6176 1496 } else {
868270f2 1497 /* Make sure we have a buffer in case we need to resize the tables. */
7c2c1fa5 1498 if (tables_blob->len > ACPI_BUILD_TABLE_SIZE / 2) {
18045fb9 1499 /* As of QEMU 2.1, this fires with 160 VCPUs and 255 memory slots. */
868270f2
MT
1500 error_report("Warning: ACPI tables are larger than 64k.");
1501 error_report("Warning: migration may not work.");
1502 error_report("Warning: please remove CPUs, NUMA nodes, "
1503 "memory slots or PCI bridges.");
18045fb9 1504 }
7c2c1fa5 1505 acpi_align_size(tables_blob, ACPI_BUILD_TABLE_SIZE);
07fb6176 1506 }
72c194f7 1507
07fb6176 1508 acpi_align_size(tables->linker, ACPI_BUILD_ALIGN_SIZE);
72c194f7
MT
1509
1510 /* Cleanup memory that's no longer used. */
1511 g_array_free(table_offsets, true);
1512}
1513
339240b5 1514static void acpi_ram_update(MemoryRegion *mr, GArray *data)
42d85900
MT
1515{
1516 uint32_t size = acpi_data_len(data);
1517
1518 /* Make sure RAM size is correct - in case it got changed e.g. by migration */
339240b5 1519 memory_region_ram_resize(mr, size, &error_abort);
42d85900 1520
339240b5
PB
1521 memcpy(memory_region_get_ram_ptr(mr), data->data, size);
1522 memory_region_set_dirty(mr, 0, size);
42d85900
MT
1523}
1524
72c194f7
MT
1525static void acpi_build_update(void *build_opaque, uint32_t offset)
1526{
1527 AcpiBuildState *build_state = build_opaque;
1528 AcpiBuildTables tables;
1529
1530 /* No state to update or already patched? Nothing to do. */
1531 if (!build_state || build_state->patched) {
1532 return;
1533 }
1534 build_state->patched = 1;
1535
1536 acpi_build_tables_init(&tables);
1537
1538 acpi_build(build_state->guest_info, &tables);
1539
339240b5 1540 acpi_ram_update(build_state->table_mr, tables.table_data);
a1666142 1541
42d85900
MT
1542 if (build_state->rsdp) {
1543 memcpy(build_state->rsdp, tables.rsdp->data, acpi_data_len(tables.rsdp));
1544 } else {
339240b5 1545 acpi_ram_update(build_state->rsdp_mr, tables.rsdp);
42d85900 1546 }
ad5b88b1 1547
339240b5 1548 acpi_ram_update(build_state->linker_mr, tables.linker);
72c194f7
MT
1549 acpi_build_tables_cleanup(&tables, true);
1550}
1551
1552static void acpi_build_reset(void *build_opaque)
1553{
1554 AcpiBuildState *build_state = build_opaque;
1555 build_state->patched = 0;
1556}
1557
339240b5
PB
1558static MemoryRegion *acpi_add_rom_blob(AcpiBuildState *build_state,
1559 GArray *blob, const char *name,
1560 uint64_t max_size)
72c194f7 1561{
a1666142
MT
1562 return rom_add_blob(name, blob->data, acpi_data_len(blob), max_size, -1,
1563 name, acpi_build_update, build_state);
72c194f7
MT
1564}
1565
1566static const VMStateDescription vmstate_acpi_build = {
1567 .name = "acpi_build",
1568 .version_id = 1,
1569 .minimum_version_id = 1,
d49805ae 1570 .fields = (VMStateField[]) {
72c194f7
MT
1571 VMSTATE_UINT8(patched, AcpiBuildState),
1572 VMSTATE_END_OF_LIST()
1573 },
1574};
1575
1576void acpi_setup(PcGuestInfo *guest_info)
1577{
1578 AcpiBuildTables tables;
1579 AcpiBuildState *build_state;
1580
1581 if (!guest_info->fw_cfg) {
8b310fc4 1582 ACPI_BUILD_DPRINTF("No fw cfg. Bailing out.\n");
72c194f7
MT
1583 return;
1584 }
1585
1586 if (!guest_info->has_acpi_build) {
8b310fc4 1587 ACPI_BUILD_DPRINTF("ACPI build disabled. Bailing out.\n");
72c194f7
MT
1588 return;
1589 }
1590
81adc513 1591 if (!acpi_enabled) {
8b310fc4 1592 ACPI_BUILD_DPRINTF("ACPI disabled. Bailing out.\n");
81adc513
MT
1593 return;
1594 }
1595
72c194f7
MT
1596 build_state = g_malloc0(sizeof *build_state);
1597
1598 build_state->guest_info = guest_info;
1599
99fd437d
MT
1600 acpi_set_pci_info();
1601
72c194f7
MT
1602 acpi_build_tables_init(&tables);
1603 acpi_build(build_state->guest_info, &tables);
1604
1605 /* Now expose it all to Guest */
339240b5 1606 build_state->table_mr = acpi_add_rom_blob(build_state, tables.table_data,
a1666142
MT
1607 ACPI_BUILD_TABLE_FILE,
1608 ACPI_BUILD_TABLE_MAX_SIZE);
339240b5 1609 assert(build_state->table_mr != NULL);
72c194f7 1610
339240b5 1611 build_state->linker_mr =
6e00619b 1612 acpi_add_rom_blob(build_state, tables.linker, "etc/table-loader", 0);
72c194f7 1613
42a5b308
SB
1614 fw_cfg_add_file(guest_info->fw_cfg, ACPI_BUILD_TPMLOG_FILE,
1615 tables.tcpalog->data, acpi_data_len(tables.tcpalog));
1616
384fb32e 1617 if (!guest_info->rsdp_in_ram) {
358774d7
IM
1618 /*
1619 * Keep for compatibility with old machine types.
1620 * Though RSDP is small, its contents isn't immutable, so
afaa2e4b 1621 * we'll update it along with the rest of tables on guest access.
358774d7 1622 */
afaa2e4b
MT
1623 uint32_t rsdp_size = acpi_data_len(tables.rsdp);
1624
1625 build_state->rsdp = g_memdup(tables.rsdp->data, rsdp_size);
358774d7
IM
1626 fw_cfg_add_file_callback(guest_info->fw_cfg, ACPI_BUILD_RSDP_FILE,
1627 acpi_build_update, build_state,
afaa2e4b 1628 build_state->rsdp, rsdp_size);
339240b5 1629 build_state->rsdp_mr = NULL;
358774d7 1630 } else {
42d85900 1631 build_state->rsdp = NULL;
339240b5 1632 build_state->rsdp_mr = acpi_add_rom_blob(build_state, tables.rsdp,
42d85900 1633 ACPI_BUILD_RSDP_FILE, 0);
358774d7 1634 }
72c194f7
MT
1635
1636 qemu_register_reset(acpi_build_reset, build_state);
1637 acpi_build_reset(build_state);
1638 vmstate_register(NULL, 0, &vmstate_acpi_build, build_state);
1639
1640 /* Cleanup tables but don't free the memory: we track it
1641 * in build_state.
1642 */
1643 acpi_build_tables_cleanup(&tables, false);
1644}