1 /* Support for generating ACPI tables and passing them to Guests
3 * Copyright (C) 2008-2010 Kevin O'Connor <kevin@koconnor.net>
4 * Copyright (C) 2006 Fabrice Bellard
5 * Copyright (C) 2013 Red Hat Inc
7 * Author: Michael S. Tsirkin <mst@redhat.com>
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.
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.
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/>.
23 #include "qemu/osdep.h"
24 #include "qapi/error.h"
26 #include "exec/memory.h"
27 #include "hw/acpi/acpi.h"
28 #include "hw/acpi/aml-build.h"
29 #include "hw/acpi/utils.h"
30 #include "hw/i386/pc.h"
31 #include "target/i386/cpu.h"
33 #include "acpi-build.h"
34 #include "acpi-common.h"
36 void pc_madt_cpu_entry(AcpiDeviceIf
*adev
, int uid
,
37 const CPUArchIdList
*apic_ids
, GArray
*entry
)
39 uint32_t apic_id
= apic_ids
->cpus
[uid
].arch_id
;
41 /* ACPI spec says that LAPIC entry for non present
42 * CPU may be omitted from MADT or it must be marked
43 * as disabled. However omitting non present CPU from
44 * MADT breaks hotplug on linux. So possible CPUs
45 * should be put in MADT but kept disabled.
48 AcpiMadtProcessorApic
*apic
= acpi_data_push(entry
, sizeof *apic
);
50 apic
->type
= ACPI_APIC_PROCESSOR
;
51 apic
->length
= sizeof(*apic
);
52 apic
->processor_id
= uid
;
53 apic
->local_apic_id
= apic_id
;
54 if (apic_ids
->cpus
[uid
].cpu
!= NULL
) {
55 apic
->flags
= cpu_to_le32(1);
57 apic
->flags
= cpu_to_le32(0);
60 AcpiMadtProcessorX2Apic
*apic
= acpi_data_push(entry
, sizeof *apic
);
62 apic
->type
= ACPI_APIC_LOCAL_X2APIC
;
63 apic
->length
= sizeof(*apic
);
64 apic
->uid
= cpu_to_le32(uid
);
65 apic
->x2apic_id
= cpu_to_le32(apic_id
);
66 if (apic_ids
->cpus
[uid
].cpu
!= NULL
) {
67 apic
->flags
= cpu_to_le32(1);
69 apic
->flags
= cpu_to_le32(0);
75 * ACPI spec, Revision 1.0b
76 * 5.2.8 Multiple APIC Description Table
78 void acpi_build_madt(GArray
*table_data
, BIOSLinker
*linker
,
79 X86MachineState
*x86ms
, AcpiDeviceIf
*adev
,
80 const char *oem_id
, const char *oem_table_id
)
82 MachineClass
*mc
= MACHINE_GET_CLASS(x86ms
);
83 const CPUArchIdList
*apic_ids
= mc
->possible_cpu_arch_ids(MACHINE(x86ms
));
84 AcpiDeviceIfClass
*adevc
= ACPI_DEVICE_IF_GET_CLASS(adev
);
85 bool x2apic_mode
= false;
87 AcpiMadtIoApic
*io_apic
;
88 AcpiMadtIntsrcovr
*intsrcovr
;
90 AcpiTable table
= { .sig
= "APIC", .rev
= 1, .oem_id
= oem_id
,
91 .oem_table_id
= oem_table_id
};
93 acpi_table_begin(&table
, table_data
);
94 /* Local APIC Address */
95 build_append_int_noprefix(table_data
, APIC_DEFAULT_ADDRESS
, 4);
96 build_append_int_noprefix(table_data
, 1 /* PCAT_COMPAT */, 4); /* Flags */
98 for (i
= 0; i
< apic_ids
->len
; i
++) {
99 adevc
->madt_cpu(adev
, i
, apic_ids
, table_data
);
100 if (apic_ids
->cpus
[i
].arch_id
> 254) {
105 io_apic
= acpi_data_push(table_data
, sizeof *io_apic
);
106 io_apic
->type
= ACPI_APIC_IO
;
107 io_apic
->length
= sizeof(*io_apic
);
108 io_apic
->io_apic_id
= ACPI_BUILD_IOAPIC_ID
;
109 io_apic
->address
= cpu_to_le32(IO_APIC_DEFAULT_ADDRESS
);
110 io_apic
->interrupt
= cpu_to_le32(0);
112 if (x86ms
->ioapic2
) {
113 AcpiMadtIoApic
*io_apic2
;
114 io_apic2
= acpi_data_push(table_data
, sizeof *io_apic
);
115 io_apic2
->type
= ACPI_APIC_IO
;
116 io_apic2
->length
= sizeof(*io_apic
);
117 io_apic2
->io_apic_id
= ACPI_BUILD_IOAPIC_ID
+ 1;
118 io_apic2
->address
= cpu_to_le32(IO_APIC_SECONDARY_ADDRESS
);
119 io_apic2
->interrupt
= cpu_to_le32(IO_APIC_SECONDARY_IRQBASE
);
122 if (x86ms
->apic_xrupt_override
) {
123 intsrcovr
= acpi_data_push(table_data
, sizeof *intsrcovr
);
124 intsrcovr
->type
= ACPI_APIC_XRUPT_OVERRIDE
;
125 intsrcovr
->length
= sizeof(*intsrcovr
);
126 intsrcovr
->source
= 0;
127 intsrcovr
->gsi
= cpu_to_le32(2);
128 intsrcovr
->flags
= cpu_to_le16(0); /* conforms to bus specifications */
131 for (i
= 1; i
< 16; i
++) {
132 if (!(x86ms
->pci_irq_mask
& (1 << i
))) {
133 /* No need for a INT source override structure. */
136 intsrcovr
= acpi_data_push(table_data
, sizeof *intsrcovr
);
137 intsrcovr
->type
= ACPI_APIC_XRUPT_OVERRIDE
;
138 intsrcovr
->length
= sizeof(*intsrcovr
);
139 intsrcovr
->source
= i
;
140 intsrcovr
->gsi
= cpu_to_le32(i
);
141 intsrcovr
->flags
= cpu_to_le16(0xd); /* active high, level triggered */
145 AcpiMadtLocalX2ApicNmi
*local_nmi
;
147 local_nmi
= acpi_data_push(table_data
, sizeof *local_nmi
);
148 local_nmi
->type
= ACPI_APIC_LOCAL_X2APIC_NMI
;
149 local_nmi
->length
= sizeof(*local_nmi
);
150 local_nmi
->uid
= 0xFFFFFFFF; /* all processors */
151 local_nmi
->flags
= cpu_to_le16(0);
152 local_nmi
->lint
= 1; /* ACPI_LINT1 */
154 AcpiMadtLocalNmi
*local_nmi
;
156 local_nmi
= acpi_data_push(table_data
, sizeof *local_nmi
);
157 local_nmi
->type
= ACPI_APIC_LOCAL_NMI
;
158 local_nmi
->length
= sizeof(*local_nmi
);
159 local_nmi
->processor_id
= 0xff; /* all processors */
160 local_nmi
->flags
= cpu_to_le16(0);
161 local_nmi
->lint
= 1; /* ACPI_LINT1 */
164 acpi_table_end(linker
, &table
);