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);
74 void acpi_build_madt(GArray
*table_data
, BIOSLinker
*linker
,
75 X86MachineState
*x86ms
, AcpiDeviceIf
*adev
)
77 MachineClass
*mc
= MACHINE_GET_CLASS(x86ms
);
78 const CPUArchIdList
*apic_ids
= mc
->possible_cpu_arch_ids(MACHINE(x86ms
));
79 int madt_start
= table_data
->len
;
80 AcpiDeviceIfClass
*adevc
= ACPI_DEVICE_IF_GET_CLASS(adev
);
81 bool x2apic_mode
= false;
83 AcpiMultipleApicTable
*madt
;
84 AcpiMadtIoApic
*io_apic
;
85 AcpiMadtIntsrcovr
*intsrcovr
;
88 madt
= acpi_data_push(table_data
, sizeof *madt
);
89 madt
->local_apic_address
= cpu_to_le32(APIC_DEFAULT_ADDRESS
);
90 madt
->flags
= cpu_to_le32(1);
92 for (i
= 0; i
< apic_ids
->len
; i
++) {
93 adevc
->madt_cpu(adev
, i
, apic_ids
, table_data
);
94 if (apic_ids
->cpus
[i
].arch_id
> 254) {
99 io_apic
= acpi_data_push(table_data
, sizeof *io_apic
);
100 io_apic
->type
= ACPI_APIC_IO
;
101 io_apic
->length
= sizeof(*io_apic
);
102 io_apic
->io_apic_id
= ACPI_BUILD_IOAPIC_ID
;
103 io_apic
->address
= cpu_to_le32(IO_APIC_DEFAULT_ADDRESS
);
104 io_apic
->interrupt
= cpu_to_le32(0);
106 if (x86ms
->ioapic2
) {
107 AcpiMadtIoApic
*io_apic2
;
108 io_apic2
= acpi_data_push(table_data
, sizeof *io_apic
);
109 io_apic2
->type
= ACPI_APIC_IO
;
110 io_apic2
->length
= sizeof(*io_apic
);
111 io_apic2
->io_apic_id
= ACPI_BUILD_IOAPIC_ID
+ 1;
112 io_apic2
->address
= cpu_to_le32(IO_APIC_SECONDARY_ADDRESS
);
113 io_apic2
->interrupt
= cpu_to_le32(IO_APIC_SECONDARY_IRQBASE
);
116 if (x86ms
->apic_xrupt_override
) {
117 intsrcovr
= acpi_data_push(table_data
, sizeof *intsrcovr
);
118 intsrcovr
->type
= ACPI_APIC_XRUPT_OVERRIDE
;
119 intsrcovr
->length
= sizeof(*intsrcovr
);
120 intsrcovr
->source
= 0;
121 intsrcovr
->gsi
= cpu_to_le32(2);
122 intsrcovr
->flags
= cpu_to_le16(0); /* conforms to bus specifications */
125 for (i
= 1; i
< 16; i
++) {
126 if (!(x86ms
->pci_irq_mask
& (1 << i
))) {
127 /* No need for a INT source override structure. */
130 intsrcovr
= acpi_data_push(table_data
, sizeof *intsrcovr
);
131 intsrcovr
->type
= ACPI_APIC_XRUPT_OVERRIDE
;
132 intsrcovr
->length
= sizeof(*intsrcovr
);
133 intsrcovr
->source
= i
;
134 intsrcovr
->gsi
= cpu_to_le32(i
);
135 intsrcovr
->flags
= cpu_to_le16(0xd); /* active high, level triggered */
139 AcpiMadtLocalX2ApicNmi
*local_nmi
;
141 local_nmi
= acpi_data_push(table_data
, sizeof *local_nmi
);
142 local_nmi
->type
= ACPI_APIC_LOCAL_X2APIC_NMI
;
143 local_nmi
->length
= sizeof(*local_nmi
);
144 local_nmi
->uid
= 0xFFFFFFFF; /* all processors */
145 local_nmi
->flags
= cpu_to_le16(0);
146 local_nmi
->lint
= 1; /* ACPI_LINT1 */
148 AcpiMadtLocalNmi
*local_nmi
;
150 local_nmi
= acpi_data_push(table_data
, sizeof *local_nmi
);
151 local_nmi
->type
= ACPI_APIC_LOCAL_NMI
;
152 local_nmi
->length
= sizeof(*local_nmi
);
153 local_nmi
->processor_id
= 0xff; /* all processors */
154 local_nmi
->flags
= cpu_to_le16(0);
155 local_nmi
->lint
= 1; /* ACPI_LINT1 */
158 build_header(linker
, table_data
,
159 (void *)(table_data
->data
+ madt_start
), "APIC",
160 table_data
->len
- madt_start
, 1, NULL
, NULL
);