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
->apic_xrupt_override
) {
107 intsrcovr
= acpi_data_push(table_data
, sizeof *intsrcovr
);
108 intsrcovr
->type
= ACPI_APIC_XRUPT_OVERRIDE
;
109 intsrcovr
->length
= sizeof(*intsrcovr
);
110 intsrcovr
->source
= 0;
111 intsrcovr
->gsi
= cpu_to_le32(2);
112 intsrcovr
->flags
= cpu_to_le16(0); /* conforms to bus specifications */
115 for (i
= 1; i
< 16; i
++) {
116 if (!(x86ms
->pci_irq_mask
& (1 << i
))) {
117 /* No need for a INT source override structure. */
120 intsrcovr
= acpi_data_push(table_data
, sizeof *intsrcovr
);
121 intsrcovr
->type
= ACPI_APIC_XRUPT_OVERRIDE
;
122 intsrcovr
->length
= sizeof(*intsrcovr
);
123 intsrcovr
->source
= i
;
124 intsrcovr
->gsi
= cpu_to_le32(i
);
125 intsrcovr
->flags
= cpu_to_le16(0xd); /* active high, level triggered */
129 AcpiMadtLocalX2ApicNmi
*local_nmi
;
131 local_nmi
= acpi_data_push(table_data
, sizeof *local_nmi
);
132 local_nmi
->type
= ACPI_APIC_LOCAL_X2APIC_NMI
;
133 local_nmi
->length
= sizeof(*local_nmi
);
134 local_nmi
->uid
= 0xFFFFFFFF; /* all processors */
135 local_nmi
->flags
= cpu_to_le16(0);
136 local_nmi
->lint
= 1; /* ACPI_LINT1 */
138 AcpiMadtLocalNmi
*local_nmi
;
140 local_nmi
= acpi_data_push(table_data
, sizeof *local_nmi
);
141 local_nmi
->type
= ACPI_APIC_LOCAL_NMI
;
142 local_nmi
->length
= sizeof(*local_nmi
);
143 local_nmi
->processor_id
= 0xff; /* all processors */
144 local_nmi
->flags
= cpu_to_le16(0);
145 local_nmi
->lint
= 1; /* ACPI_LINT1 */
148 build_header(linker
, table_data
,
149 (void *)(table_data
->data
+ madt_start
), "APIC",
150 table_data
->len
- madt_start
, 1, NULL
, NULL
);