qemu/hw/i386/acpi-common.c
Peter Maydell 3d54cbf269 Misc HW patch queue
- Remove sysbus_add_io (Phil)
 - Build PPC 4xx PCI host bridges once (Phil)
 - Display QOM path while debugging SMBus targets (Joe)
 - Simplify x86 PC code (Bernhard)
 - Remove qemu_[un]register_reset() calls in x86 PC CMOS (Peter)
 - Fix wiring of ICH9 LPC interrupts (Bernhard)
 - Split core IDE as device / bus / dma (Thomas)
 - Prefer QDev API over QOM for devices (Phil)
 - Fix invalid use of DO_UPCAST() in Leon3 (Thomas)
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmXXQ1IACgkQ4+MsLN6t
 wN4e2xAAig55EJh/JwpdGx55rFUab3Ay22jgXrExmBir8hzhyzssY+RUj2ALRa5e
 T26kxCEqiuT549FtWm/ci6kVax0QD6bqz/6/j451XB9469Z/3BDOV5rhsqF6zlr5
 BMbyC8PKnMUluG8v1ZuRjC3m2lK3ZvkVnZtj7SZUR50ssEnR32fVIziN14/OYkts
 2B24sLrnLBfvyatMRsuFqGWrcbtMdnwNpjenGfDPOTF33W1sxTQ8GSvx1RV32l69
 Yr/iCVoCl+rGxbLLP1TwqtOwzk32p8RsbIt6rWMqVMv/p5F6ezFeiOk7VHnnEJRH
 e7TPxt4XeLGPARMQLT3gQh0MGIIodanSHePRBkczuNmKYTJrz+5jMu2Qg4MmMUE/
 TV0fKgdjh/edhAOHzJgZqLmNV71icl8WBjfsw2qT4ZwgJzWq7YM2/XZKkeWhk2nQ
 whLxfgiU4PNJ6vHhebJNjOovCYQTK2FbXR+PvVn5FEbH4CuFr8mqkYc+vNYM9dLA
 b7uMk1H8kcb5+kqfPPU2lVd1wO7uqhxYOYU2O9nYq8aw7ioLoLeEdj2IicLtrA/H
 GMtyA5cYeabeRzSXF30tM2AR1uQ/e4Z7oNxW6z3GVK1NrQtKilqPgMKut8uWYvva
 crJLpRQhGiY3sDrIkkCcAHzv256dZaJNLR1KPViaHOyVPZV+x2s=
 =+h2O
 -----END PGP SIGNATURE-----

Merge tag 'hw-misc-20240222' of https://github.com/philmd/qemu into staging

Misc HW patch queue

- Remove sysbus_add_io (Phil)
- Build PPC 4xx PCI host bridges once (Phil)
- Display QOM path while debugging SMBus targets (Joe)
- Simplify x86 PC code (Bernhard)
- Remove qemu_[un]register_reset() calls in x86 PC CMOS (Peter)
- Fix wiring of ICH9 LPC interrupts (Bernhard)
- Split core IDE as device / bus / dma (Thomas)
- Prefer QDev API over QOM for devices (Phil)
- Fix invalid use of DO_UPCAST() in Leon3 (Thomas)

# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmXXQ1IACgkQ4+MsLN6t
# wN4e2xAAig55EJh/JwpdGx55rFUab3Ay22jgXrExmBir8hzhyzssY+RUj2ALRa5e
# T26kxCEqiuT549FtWm/ci6kVax0QD6bqz/6/j451XB9469Z/3BDOV5rhsqF6zlr5
# BMbyC8PKnMUluG8v1ZuRjC3m2lK3ZvkVnZtj7SZUR50ssEnR32fVIziN14/OYkts
# 2B24sLrnLBfvyatMRsuFqGWrcbtMdnwNpjenGfDPOTF33W1sxTQ8GSvx1RV32l69
# Yr/iCVoCl+rGxbLLP1TwqtOwzk32p8RsbIt6rWMqVMv/p5F6ezFeiOk7VHnnEJRH
# e7TPxt4XeLGPARMQLT3gQh0MGIIodanSHePRBkczuNmKYTJrz+5jMu2Qg4MmMUE/
# TV0fKgdjh/edhAOHzJgZqLmNV71icl8WBjfsw2qT4ZwgJzWq7YM2/XZKkeWhk2nQ
# whLxfgiU4PNJ6vHhebJNjOovCYQTK2FbXR+PvVn5FEbH4CuFr8mqkYc+vNYM9dLA
# b7uMk1H8kcb5+kqfPPU2lVd1wO7uqhxYOYU2O9nYq8aw7ioLoLeEdj2IicLtrA/H
# GMtyA5cYeabeRzSXF30tM2AR1uQ/e4Z7oNxW6z3GVK1NrQtKilqPgMKut8uWYvva
# crJLpRQhGiY3sDrIkkCcAHzv256dZaJNLR1KPViaHOyVPZV+x2s=
# =+h2O
# -----END PGP SIGNATURE-----
# gpg: Signature made Thu 22 Feb 2024 12:51:30 GMT
# gpg:                using RSA key FAABE75E12917221DCFD6BB2E3E32C2CDEADC0DE
# gpg: Good signature from "Philippe Mathieu-Daudé (F4BUG) <f4bug@amsat.org>" [full]
# Primary key fingerprint: FAAB E75E 1291 7221 DCFD  6BB2 E3E3 2C2C DEAD C0DE

* tag 'hw-misc-20240222' of https://github.com/philmd/qemu: (32 commits)
  hw/sparc/leon3: Fix wrong usage of DO_UPCAST macro
  hw/ide: Stop exposing internal.h to non-IDE files
  hw/ide: Remove the include/hw/ide.h legacy file
  hw/ide: Move IDE bus related definitions to a new header ide-bus.h
  hw/ide: Move IDE device related definitions to ide-dev.h
  hw/ide: Move IDE DMA related definitions to a separate header ide-dma.h
  hw/ide: Split qdev.c into ide-bus.c and ide-dev.c
  hw/ide: Add the possibility to disable the CompactFlash device in the build
  hw/acpi/ich9_tco: Include missing 'migration/vmstate.h' header
  hw/acpi/cpu: Use CPUState typedef
  hw/acpi: Include missing 'qapi/qapi-types-acpi.h' generated header
  hw/isa/meson.build: Sort alphabetically
  hw/i386/pc_q35: Populate interrupt handlers before realizing LPC PCI function
  hw/i386/pc_sysfw: Use qdev_is_realized() instead of QOM API
  hw/i386/pc_sysfw: Inline pc_system_flash_create() and remove it
  hw/i386/pc: Confine system flash handling to pc_sysfw
  hw/i386/pc: Defer smbios_set_defaults() to machine_done
  hw/i386/pc: Merge pc_guest_info_init() into pc_machine_initfn()
  hw/i386/x86: Turn apic_xrupt_override into class attribute
  hw/i386/pc: Do pc_cmos_init_late() from pc_machine_done()
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

# Conflicts:
#	include/hw/i386/pc.h
2024-02-22 15:44:29 +00:00

164 lines
6.4 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* Support for generating ACPI tables and passing them to Guests
*
* Copyright (C) 2008-2010 Kevin O'Connor <kevin@koconnor.net>
* Copyright (C) 2006 Fabrice Bellard
* Copyright (C) 2013 Red Hat Inc
*
* Author: Michael S. Tsirkin <mst@redhat.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License along
* with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "exec/memory.h"
#include "hw/acpi/acpi.h"
#include "hw/acpi/aml-build.h"
#include "hw/acpi/utils.h"
#include "target/i386/cpu.h"
#include "acpi-build.h"
#include "acpi-common.h"
void pc_madt_cpu_entry(int uid, const CPUArchIdList *apic_ids,
GArray *entry, bool force_enabled)
{
uint32_t apic_id = apic_ids->cpus[uid].arch_id;
/* Flags Local APIC Flags */
uint32_t flags = apic_ids->cpus[uid].cpu != NULL || force_enabled ?
1 /* Enabled */ : 0;
/* ACPI spec says that LAPIC entry for non present
* CPU may be omitted from MADT or it must be marked
* as disabled. However omitting non present CPU from
* MADT breaks hotplug on linux. So possible CPUs
* should be put in MADT but kept disabled.
*/
if (apic_id < 255) {
/* Rev 1.0b, Table 5-13 Processor Local APIC Structure */
build_append_int_noprefix(entry, 0, 1); /* Type */
build_append_int_noprefix(entry, 8, 1); /* Length */
build_append_int_noprefix(entry, uid, 1); /* ACPI Processor ID */
build_append_int_noprefix(entry, apic_id, 1); /* APIC ID */
build_append_int_noprefix(entry, flags, 4); /* Flags */
} else {
/* Rev 4.0, 5.2.12.12 Processor Local x2APIC Structure */
build_append_int_noprefix(entry, 9, 1); /* Type */
build_append_int_noprefix(entry, 16, 1); /* Length */
build_append_int_noprefix(entry, 0, 2); /* Reserved */
build_append_int_noprefix(entry, apic_id, 4); /* X2APIC ID */
build_append_int_noprefix(entry, flags, 4); /* Flags */
build_append_int_noprefix(entry, uid, 4); /* ACPI Processor UID */
}
}
static void build_ioapic(GArray *entry, uint8_t id, uint32_t addr, uint32_t irq)
{
/* Rev 1.0b, 5.2.8.2 IO APIC */
build_append_int_noprefix(entry, 1, 1); /* Type */
build_append_int_noprefix(entry, 12, 1); /* Length */
build_append_int_noprefix(entry, id, 1); /* IO APIC ID */
build_append_int_noprefix(entry, 0, 1); /* Reserved */
build_append_int_noprefix(entry, addr, 4); /* IO APIC Address */
build_append_int_noprefix(entry, irq, 4); /* System Vector Base */
}
static void
build_xrupt_override(GArray *entry, uint8_t src, uint32_t gsi, uint16_t flags)
{
/* Rev 1.0b, 5.2.8.3.1 Interrupt Source Overrides */
build_append_int_noprefix(entry, 2, 1); /* Type */
build_append_int_noprefix(entry, 10, 1); /* Length */
build_append_int_noprefix(entry, 0, 1); /* Bus */
build_append_int_noprefix(entry, src, 1); /* Source */
/* Global System Interrupt Vector */
build_append_int_noprefix(entry, gsi, 4);
build_append_int_noprefix(entry, flags, 2); /* Flags */
}
/*
* ACPI spec, Revision 1.0b
* 5.2.8 Multiple APIC Description Table
*/
void acpi_build_madt(GArray *table_data, BIOSLinker *linker,
X86MachineState *x86ms,
const char *oem_id, const char *oem_table_id)
{
int i;
bool x2apic_mode = false;
MachineClass *mc = MACHINE_GET_CLASS(x86ms);
X86MachineClass *x86mc = X86_MACHINE_GET_CLASS(x86ms);
const CPUArchIdList *apic_ids = mc->possible_cpu_arch_ids(MACHINE(x86ms));
AcpiTable table = { .sig = "APIC", .rev = 3, .oem_id = oem_id,
.oem_table_id = oem_table_id };
acpi_table_begin(&table, table_data);
/* Local APIC Address */
build_append_int_noprefix(table_data, APIC_DEFAULT_ADDRESS, 4);
build_append_int_noprefix(table_data, 1 /* PCAT_COMPAT */, 4); /* Flags */
for (i = 0; i < apic_ids->len; i++) {
pc_madt_cpu_entry(i, apic_ids, table_data, false);
if (apic_ids->cpus[i].arch_id > 254) {
x2apic_mode = true;
}
}
build_ioapic(table_data, ACPI_BUILD_IOAPIC_ID, IO_APIC_DEFAULT_ADDRESS, 0);
if (x86ms->ioapic2) {
build_ioapic(table_data, ACPI_BUILD_IOAPIC_ID + 1,
IO_APIC_SECONDARY_ADDRESS, IO_APIC_SECONDARY_IRQBASE);
}
if (x86mc->apic_xrupt_override) {
build_xrupt_override(table_data, 0, 2,
0 /* Flags: Conforms to the specifications of the bus */);
}
for (i = 1; i < 16; i++) {
if (!(x86ms->pci_irq_mask & (1 << i))) {
/* No need for a INT source override structure. */
continue;
}
build_xrupt_override(table_data, i, i,
0xd /* Flags: Active high, Level Triggered */);
}
if (x2apic_mode) {
/* Rev 4.0, 5.2.12.13 Local x2APIC NMI Structure*/
build_append_int_noprefix(table_data, 0xA, 1); /* Type */
build_append_int_noprefix(table_data, 12, 1); /* Length */
build_append_int_noprefix(table_data, 0, 2); /* Flags */
/* ACPI Processor UID */
build_append_int_noprefix(table_data, 0xFFFFFFFF /* all processors */,
4);
/* Local x2APIC LINT# */
build_append_int_noprefix(table_data, 1 /* ACPI_LINT1 */, 1);
build_append_int_noprefix(table_data, 0, 3); /* Reserved */
} else {
/* Rev 1.0b, 5.2.8.3.3 Local APIC NMI */
build_append_int_noprefix(table_data, 4, 1); /* Type */
build_append_int_noprefix(table_data, 6, 1); /* Length */
/* ACPI Processor ID */
build_append_int_noprefix(table_data, 0xFF /* all processors */, 1);
build_append_int_noprefix(table_data, 0, 2); /* Flags */
/* Local APIC INTI# */
build_append_int_noprefix(table_data, 1 /* ACPI_LINT1 */, 1);
}
acpi_table_end(linker, &table);
}