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
,
78 MachineClass
*mc
= MACHINE_GET_CLASS(x86ms
);
79 const CPUArchIdList
*apic_ids
= mc
->possible_cpu_arch_ids(MACHINE(x86ms
));
80 int madt_start
= table_data
->len
;
81 AcpiDeviceIfClass
*adevc
= ACPI_DEVICE_IF_GET_CLASS(adev
);
82 bool x2apic_mode
= false;
84 AcpiMultipleApicTable
*madt
;
85 AcpiMadtIoApic
*io_apic
;
86 AcpiMadtIntsrcovr
*intsrcovr
;
89 madt
= acpi_data_push(table_data
, sizeof *madt
);
90 madt
->local_apic_address
= cpu_to_le32(APIC_DEFAULT_ADDRESS
);
91 madt
->flags
= cpu_to_le32(1);
93 for (i
= 0; i
< apic_ids
->len
; i
++) {
94 adevc
->madt_cpu(adev
, i
, apic_ids
, table_data
);
95 if (apic_ids
->cpus
[i
].arch_id
> 254) {
100 io_apic
= acpi_data_push(table_data
, sizeof *io_apic
);
101 io_apic
->type
= ACPI_APIC_IO
;
102 io_apic
->length
= sizeof(*io_apic
);
103 io_apic
->io_apic_id
= ACPI_BUILD_IOAPIC_ID
;
104 io_apic
->address
= cpu_to_le32(IO_APIC_DEFAULT_ADDRESS
);
105 io_apic
->interrupt
= cpu_to_le32(0);
107 if (x86ms
->apic_xrupt_override
) {
108 intsrcovr
= acpi_data_push(table_data
, sizeof *intsrcovr
);
109 intsrcovr
->type
= ACPI_APIC_XRUPT_OVERRIDE
;
110 intsrcovr
->length
= sizeof(*intsrcovr
);
111 intsrcovr
->source
= 0;
112 intsrcovr
->gsi
= cpu_to_le32(2);
113 intsrcovr
->flags
= cpu_to_le16(0); /* conforms to bus specifications */
117 for (i
= 1; i
< 16; i
++) {
118 #define ACPI_BUILD_PCI_IRQS ((1<<5) | (1<<9) | (1<<10) | (1<<11))
119 if (!(ACPI_BUILD_PCI_IRQS
& (1 << i
))) {
120 /* No need for a INT source override structure. */
123 intsrcovr
= acpi_data_push(table_data
, sizeof *intsrcovr
);
124 intsrcovr
->type
= ACPI_APIC_XRUPT_OVERRIDE
;
125 intsrcovr
->length
= sizeof(*intsrcovr
);
126 intsrcovr
->source
= i
;
127 intsrcovr
->gsi
= cpu_to_le32(i
);
128 intsrcovr
->flags
= cpu_to_le16(0xd); /* active high, level triggered */
133 AcpiMadtLocalX2ApicNmi
*local_nmi
;
135 local_nmi
= acpi_data_push(table_data
, sizeof *local_nmi
);
136 local_nmi
->type
= ACPI_APIC_LOCAL_X2APIC_NMI
;
137 local_nmi
->length
= sizeof(*local_nmi
);
138 local_nmi
->uid
= 0xFFFFFFFF; /* all processors */
139 local_nmi
->flags
= cpu_to_le16(0);
140 local_nmi
->lint
= 1; /* ACPI_LINT1 */
142 AcpiMadtLocalNmi
*local_nmi
;
144 local_nmi
= acpi_data_push(table_data
, sizeof *local_nmi
);
145 local_nmi
->type
= ACPI_APIC_LOCAL_NMI
;
146 local_nmi
->length
= sizeof(*local_nmi
);
147 local_nmi
->processor_id
= 0xff; /* all processors */
148 local_nmi
->flags
= cpu_to_le16(0);
149 local_nmi
->lint
= 1; /* ACPI_LINT1 */
152 build_header(linker
, table_data
,
153 (void *)(table_data
->data
+ madt_start
), "APIC",
154 table_data
->len
- madt_start
, 1, NULL
, NULL
);