^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * acpi_tables.c - ACPI Boot-Time Table Parsing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2001 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) /* Uncomment next line to get verbose printout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) /* #define DEBUG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #define pr_fmt(fmt) "ACPI: " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/smp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/memblock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/earlycpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/initrd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/security.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #ifdef CONFIG_ACPI_CUSTOM_DSDT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include CONFIG_ACPI_CUSTOM_DSDT_FILE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define ACPI_MAX_TABLES 128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static char *mps_inti_flags_polarity[] = { "dfl", "high", "res", "low" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) static char *mps_inti_flags_trigger[] = { "dfl", "edge", "res", "level" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static struct acpi_table_desc initial_tables[ACPI_MAX_TABLES] __initdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) static int acpi_apic_instance __initdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) enum acpi_subtable_type {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) ACPI_SUBTABLE_COMMON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) ACPI_SUBTABLE_HMAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct acpi_subtable_entry {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) union acpi_subtable_headers *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) enum acpi_subtable_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * Disable table checksum verification for the early stage due to the size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * limitation of the current x86 early mapping implementation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) static bool acpi_verify_table_checksum __initdata = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) if (!header)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) switch (header->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) case ACPI_MADT_TYPE_LOCAL_APIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct acpi_madt_local_apic *p =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) (struct acpi_madt_local_apic *)header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) pr_debug("LAPIC (acpi_id[0x%02x] lapic_id[0x%02x] %s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) p->processor_id, p->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) case ACPI_MADT_TYPE_LOCAL_X2APIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) struct acpi_madt_local_x2apic *p =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) (struct acpi_madt_local_x2apic *)header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) pr_debug("X2APIC (apic_id[0x%02x] uid[0x%02x] %s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) p->local_apic_id, p->uid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) case ACPI_MADT_TYPE_IO_APIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) struct acpi_madt_io_apic *p =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) (struct acpi_madt_io_apic *)header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) pr_debug("IOAPIC (id[0x%02x] address[0x%08x] gsi_base[%d])\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) p->id, p->address, p->global_irq_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) struct acpi_madt_interrupt_override *p =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) (struct acpi_madt_interrupt_override *)header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) pr_info("INT_SRC_OVR (bus %d bus_irq %d global_irq %d %s %s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) p->bus, p->source_irq, p->global_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) mps_inti_flags_polarity[p->inti_flags & ACPI_MADT_POLARITY_MASK],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) mps_inti_flags_trigger[(p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) if (p->inti_flags &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) ~(ACPI_MADT_POLARITY_MASK | ACPI_MADT_TRIGGER_MASK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) pr_info("INT_SRC_OVR unexpected reserved flags: 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) p->inti_flags &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) ~(ACPI_MADT_POLARITY_MASK | ACPI_MADT_TRIGGER_MASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) case ACPI_MADT_TYPE_NMI_SOURCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct acpi_madt_nmi_source *p =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) (struct acpi_madt_nmi_source *)header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) pr_info("NMI_SRC (%s %s global_irq %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) mps_inti_flags_polarity[p->inti_flags & ACPI_MADT_POLARITY_MASK],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) mps_inti_flags_trigger[(p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) p->global_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) struct acpi_madt_local_apic_nmi *p =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) (struct acpi_madt_local_apic_nmi *)header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) pr_info("LAPIC_NMI (acpi_id[0x%02x] %s %s lint[0x%x])\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) p->processor_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) mps_inti_flags_polarity[p->inti_flags & ACPI_MADT_POLARITY_MASK ],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) mps_inti_flags_trigger[(p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) p->lint);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) u16 polarity, trigger;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) struct acpi_madt_local_x2apic_nmi *p =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) (struct acpi_madt_local_x2apic_nmi *)header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) polarity = p->inti_flags & ACPI_MADT_POLARITY_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) trigger = (p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) pr_info("X2APIC_NMI (uid[0x%02x] %s %s lint[0x%x])\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) p->uid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) mps_inti_flags_polarity[polarity],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) mps_inti_flags_trigger[trigger],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) p->lint);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) struct acpi_madt_local_apic_override *p =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) (struct acpi_madt_local_apic_override *)header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) pr_info("LAPIC_ADDR_OVR (address[%p])\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) (void *)(unsigned long)p->address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) case ACPI_MADT_TYPE_IO_SAPIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct acpi_madt_io_sapic *p =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) (struct acpi_madt_io_sapic *)header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) pr_debug("IOSAPIC (id[0x%x] address[%p] gsi_base[%d])\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) p->id, (void *)(unsigned long)p->address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) p->global_irq_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) case ACPI_MADT_TYPE_LOCAL_SAPIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) struct acpi_madt_local_sapic *p =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) (struct acpi_madt_local_sapic *)header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) pr_debug("LSAPIC (acpi_id[0x%02x] lsapic_id[0x%02x] lsapic_eid[0x%02x] %s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) p->processor_id, p->id, p->eid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) struct acpi_madt_interrupt_source *p =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) (struct acpi_madt_interrupt_source *)header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) pr_info("PLAT_INT_SRC (%s %s type[0x%x] id[0x%04x] eid[0x%x] iosapic_vector[0x%x] global_irq[0x%x]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) mps_inti_flags_polarity[p->inti_flags & ACPI_MADT_POLARITY_MASK],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) mps_inti_flags_trigger[(p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) p->type, p->id, p->eid, p->io_sapic_vector,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) p->global_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) struct acpi_madt_generic_interrupt *p =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) (struct acpi_madt_generic_interrupt *)header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) pr_debug("GICC (acpi_id[0x%04x] address[%llx] MPIDR[0x%llx] %s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) p->uid, p->base_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) p->arm_mpidr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) (p->flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) struct acpi_madt_generic_distributor *p =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) (struct acpi_madt_generic_distributor *)header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) pr_debug("GIC Distributor (gic_id[0x%04x] address[%llx] gsi_base[%d])\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) p->gic_id, p->base_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) p->global_irq_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) pr_warn("Found unsupported MADT entry (type = 0x%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) header->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) static unsigned long __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) acpi_get_entry_type(struct acpi_subtable_entry *entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) switch (entry->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) case ACPI_SUBTABLE_COMMON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return entry->hdr->common.type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) case ACPI_SUBTABLE_HMAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) return entry->hdr->hmat.type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) static unsigned long __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) acpi_get_entry_length(struct acpi_subtable_entry *entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) switch (entry->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) case ACPI_SUBTABLE_COMMON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) return entry->hdr->common.length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) case ACPI_SUBTABLE_HMAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) return entry->hdr->hmat.length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) static unsigned long __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) acpi_get_subtable_header_length(struct acpi_subtable_entry *entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) switch (entry->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) case ACPI_SUBTABLE_COMMON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) return sizeof(entry->hdr->common);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) case ACPI_SUBTABLE_HMAT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) return sizeof(entry->hdr->hmat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) static enum acpi_subtable_type __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) acpi_get_subtable_type(char *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (strncmp(id, ACPI_SIG_HMAT, 4) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) return ACPI_SUBTABLE_HMAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) return ACPI_SUBTABLE_COMMON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) * acpi_parse_entries_array - for each proc_num find a suitable subtable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) * @id: table id (for debugging purposes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) * @table_size: size of the root table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) * @table_header: where does the table start?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) * @proc: array of acpi_subtable_proc struct containing entry id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) * and associated handler with it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) * @proc_num: how big proc is?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) * @max_entries: how many entries can we process?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) * For each proc_num find a subtable with proc->id and run proc->handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) * on it. Assumption is that there's only single handler for particular
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) * entry id.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) * The table_size is not the size of the complete ACPI table (the length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * field in the header struct), but only the size of the root table; i.e.,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * the offset from the very first byte of the complete ACPI table, to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) * first byte of the very first subtable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) * On success returns sum of all matching entries for all proc handlers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) * Otherwise, -ENODEV or -EINVAL is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) static int __init acpi_parse_entries_array(char *id, unsigned long table_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) struct acpi_table_header *table_header,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) struct acpi_subtable_proc *proc, int proc_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) unsigned int max_entries)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) struct acpi_subtable_entry entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) unsigned long table_end, subtable_len, entry_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) int count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) int errs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) table_end = (unsigned long)table_header + table_header->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) /* Parse all entries looking for a match. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) entry.type = acpi_get_subtable_type(id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) entry.hdr = (union acpi_subtable_headers *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) ((unsigned long)table_header + table_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) subtable_len = acpi_get_subtable_header_length(&entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) while (((unsigned long)entry.hdr) + subtable_len < table_end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (max_entries && count >= max_entries)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) for (i = 0; i < proc_num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) if (acpi_get_entry_type(&entry) != proc[i].id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (!proc[i].handler ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) (!errs && proc[i].handler(entry.hdr, table_end))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) errs++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) proc[i].count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (i != proc_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) * If entry->length is 0, break from this loop to avoid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) * infinite loop.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) entry_len = acpi_get_entry_length(&entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) if (entry_len == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) pr_err("[%4.4s:0x%02x] Invalid zero length\n", id, proc->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) entry.hdr = (union acpi_subtable_headers *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) ((unsigned long)entry.hdr + entry_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if (max_entries && count > max_entries) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) pr_warn("[%4.4s:0x%02x] found the maximum %i entries\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) id, proc->id, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) return errs ? -EINVAL : count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) int __init acpi_table_parse_entries_array(char *id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) unsigned long table_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) struct acpi_subtable_proc *proc, int proc_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) unsigned int max_entries)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) struct acpi_table_header *table_header = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) u32 instance = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) if (acpi_disabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (!id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if (!table_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) if (!strncmp(id, ACPI_SIG_MADT, 4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) instance = acpi_apic_instance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) acpi_get_table(id, instance, &table_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) if (!table_header) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) pr_warn("%4.4s not present\n", id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) count = acpi_parse_entries_array(id, table_size, table_header,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) proc, proc_num, max_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) acpi_put_table(table_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) int __init acpi_table_parse_entries(char *id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) unsigned long table_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) int entry_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) acpi_tbl_entry_handler handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) unsigned int max_entries)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) struct acpi_subtable_proc proc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) .id = entry_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) .handler = handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) return acpi_table_parse_entries_array(id, table_size, &proc, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) max_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) int __init acpi_table_parse_madt(enum acpi_madt_type id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) acpi_tbl_entry_handler handler, unsigned int max_entries)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) return acpi_table_parse_entries(ACPI_SIG_MADT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) sizeof(struct acpi_table_madt), id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) handler, max_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) * acpi_table_parse - find table with @id, run @handler on it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) * @id: table id to find
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) * @handler: handler to run
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) * Scan the ACPI System Descriptor Table (STD) for a table matching @id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) * run @handler on it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) * Return 0 if table found, -errno if not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) int __init acpi_table_parse(char *id, acpi_tbl_table_handler handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) struct acpi_table_header *table = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) if (acpi_disabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (!id || !handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) if (strncmp(id, ACPI_SIG_MADT, 4) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) acpi_get_table(id, acpi_apic_instance, &table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) acpi_get_table(id, 0, &table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) if (table) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) handler(table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) acpi_put_table(table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) * The BIOS is supposed to supply a single APIC/MADT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) * but some report two. Provide a knob to use either.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) * (don't you wish instance 0 and 1 were not the same?)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) static void __init check_multiple_madt(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) struct acpi_table_header *table = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) acpi_get_table(ACPI_SIG_MADT, 2, &table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) if (table) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) pr_warn("BIOS bug: multiple APIC/MADT found, using %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) acpi_apic_instance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) pr_warn("If \"acpi_apic_instance=%d\" works better, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) "notify linux-acpi@vger.kernel.org\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) acpi_apic_instance ? 0 : 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) acpi_put_table(table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) acpi_apic_instance = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) static void acpi_table_taint(struct acpi_table_header *table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) pr_warn("Override [%4.4s-%8.8s], this is unsafe: tainting kernel\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) table->signature, table->oem_table_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) add_taint(TAINT_OVERRIDDEN_ACPI_TABLE, LOCKDEP_NOW_UNRELIABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) #ifdef CONFIG_ACPI_TABLE_UPGRADE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) static u64 acpi_tables_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) static int all_tables_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) /* Copied from acpica/tbutils.c:acpi_tb_checksum() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) static u8 __init acpi_table_checksum(u8 *buffer, u32 length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) u8 sum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) u8 *end = buffer + length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) while (buffer < end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) sum = (u8) (sum + *(buffer++));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) return sum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) /* All but ACPI_SIG_RSDP and ACPI_SIG_FACS: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) static const char table_sigs[][ACPI_NAMESEG_SIZE] __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) ACPI_SIG_BERT, ACPI_SIG_BGRT, ACPI_SIG_CPEP, ACPI_SIG_ECDT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) ACPI_SIG_EINJ, ACPI_SIG_ERST, ACPI_SIG_HEST, ACPI_SIG_MADT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) ACPI_SIG_MSCT, ACPI_SIG_SBST, ACPI_SIG_SLIT, ACPI_SIG_SRAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) ACPI_SIG_ASF, ACPI_SIG_BOOT, ACPI_SIG_DBGP, ACPI_SIG_DMAR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) ACPI_SIG_HPET, ACPI_SIG_IBFT, ACPI_SIG_IVRS, ACPI_SIG_MCFG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) ACPI_SIG_MCHI, ACPI_SIG_SLIC, ACPI_SIG_SPCR, ACPI_SIG_SPMI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) ACPI_SIG_TCPA, ACPI_SIG_UEFI, ACPI_SIG_WAET, ACPI_SIG_WDAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) ACPI_SIG_WDDT, ACPI_SIG_WDRT, ACPI_SIG_DSDT, ACPI_SIG_FADT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) ACPI_SIG_PSDT, ACPI_SIG_RSDT, ACPI_SIG_XSDT, ACPI_SIG_SSDT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) ACPI_SIG_IORT, ACPI_SIG_NFIT, ACPI_SIG_HMAT, ACPI_SIG_PPTT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) ACPI_SIG_NHLT };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) #define ACPI_HEADER_SIZE sizeof(struct acpi_table_header)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) #define NR_ACPI_INITRD_TABLES 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) static struct cpio_data __initdata acpi_initrd_files[NR_ACPI_INITRD_TABLES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) static DECLARE_BITMAP(acpi_initrd_installed, NR_ACPI_INITRD_TABLES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) #define MAP_CHUNK_SIZE (NR_FIX_BTMAPS << PAGE_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) void __init acpi_table_upgrade(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) void *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) size_t size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) int sig, no, table_nr = 0, total_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) long offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) struct acpi_table_header *table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) char cpio_path[32] = "kernel/firmware/acpi/";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) struct cpio_data file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (IS_ENABLED(CONFIG_ACPI_TABLE_OVERRIDE_VIA_BUILTIN_INITRD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) data = __initramfs_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) size = __initramfs_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) data = (void *)initrd_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) size = initrd_end - initrd_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) if (data == NULL || size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) for (no = 0; no < NR_ACPI_INITRD_TABLES; no++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) file = find_cpio_data(cpio_path, data, size, &offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) if (!file.data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) data += offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) size -= offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) if (file.size < sizeof(struct acpi_table_header)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) pr_err("ACPI OVERRIDE: Table smaller than ACPI header [%s%s]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) cpio_path, file.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) table = file.data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) for (sig = 0; sig < ARRAY_SIZE(table_sigs); sig++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) if (!memcmp(table->signature, table_sigs[sig], 4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (sig >= ARRAY_SIZE(table_sigs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) pr_err("ACPI OVERRIDE: Unknown signature [%s%s]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) cpio_path, file.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) if (file.size != table->length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) pr_err("ACPI OVERRIDE: File length does not match table length [%s%s]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) cpio_path, file.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) if (acpi_table_checksum(file.data, table->length)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) pr_err("ACPI OVERRIDE: Bad table checksum [%s%s]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) cpio_path, file.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) pr_info("%4.4s ACPI table found in initrd [%s%s][0x%x]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) table->signature, cpio_path, file.name, table->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) all_tables_size += table->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) acpi_initrd_files[table_nr].data = file.data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) acpi_initrd_files[table_nr].size = file.size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) table_nr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (table_nr == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) if (security_locked_down(LOCKDOWN_ACPI_TABLES)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) pr_notice("kernel is locked down, ignoring table override\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) acpi_tables_addr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) memblock_find_in_range(0, ACPI_TABLE_UPGRADE_MAX_PHYS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) all_tables_size, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) if (!acpi_tables_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) * Only calling e820_add_reserve does not work and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) * tables are invalid (memory got used) later.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) * memblock_reserve works as expected and the tables won't get modified.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) * But it's not enough on X86 because ioremap will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) * complain later (used by acpi_os_map_memory) that the pages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) * that should get mapped are not marked "reserved".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) * Both memblock_reserve and e820__range_add (via arch_reserve_mem_area)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) * works fine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) memblock_reserve(acpi_tables_addr, all_tables_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) arch_reserve_mem_area(acpi_tables_addr, all_tables_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) * early_ioremap only can remap 256k one time. If we map all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) * tables one time, we will hit the limit. Need to map chunks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) * one by one during copying the same as that in relocate_initrd().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) for (no = 0; no < table_nr; no++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) unsigned char *src_p = acpi_initrd_files[no].data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) phys_addr_t size = acpi_initrd_files[no].size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) phys_addr_t dest_addr = acpi_tables_addr + total_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) phys_addr_t slop, clen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) char *dest_p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) total_offset += size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) while (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) slop = dest_addr & ~PAGE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) clen = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) if (clen > MAP_CHUNK_SIZE - slop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) clen = MAP_CHUNK_SIZE - slop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) dest_p = early_memremap(dest_addr & PAGE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) clen + slop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) memcpy(dest_p + slop, src_p, clen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) early_memunmap(dest_p, clen + slop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) src_p += clen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) dest_addr += clen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) size -= clen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) static acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) acpi_table_initrd_override(struct acpi_table_header *existing_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) acpi_physical_address *address, u32 *length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) int table_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) int table_index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) struct acpi_table_header *table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) u32 table_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) *length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) *address = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) if (!acpi_tables_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) return AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) while (table_offset + ACPI_HEADER_SIZE <= all_tables_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) table = acpi_os_map_memory(acpi_tables_addr + table_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) ACPI_HEADER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) if (table_offset + table->length > all_tables_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) return AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) table_length = table->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) /* Only override tables matched */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) if (memcmp(existing_table->signature, table->signature, 4) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) memcmp(table->oem_id, existing_table->oem_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) ACPI_OEM_ID_SIZE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) memcmp(table->oem_table_id, existing_table->oem_table_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) ACPI_OEM_TABLE_ID_SIZE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) goto next_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) * Mark the table to avoid being used in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) * acpi_table_initrd_scan() and check the revision.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) if (test_and_set_bit(table_index, acpi_initrd_installed) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) existing_table->oem_revision >= table->oem_revision) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) goto next_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) *length = table_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) *address = acpi_tables_addr + table_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) pr_info("Table Upgrade: override [%4.4s-%6.6s-%8.8s]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) table->signature, table->oem_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) table->oem_table_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) next_table:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) table_offset += table_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) table_index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) return AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) static void __init acpi_table_initrd_scan(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) int table_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) int table_index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) u32 table_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) struct acpi_table_header *table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) if (!acpi_tables_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) while (table_offset + ACPI_HEADER_SIZE <= all_tables_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) table = acpi_os_map_memory(acpi_tables_addr + table_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) ACPI_HEADER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) if (table_offset + table->length > all_tables_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) table_length = table->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) /* Skip RSDT/XSDT which should only be used for override */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) if (ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_RSDT) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_XSDT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) goto next_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) * Mark the table to avoid being used in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) * acpi_table_initrd_override(). Though this is not possible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) * because override is disabled in acpi_install_table().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) if (test_and_set_bit(table_index, acpi_initrd_installed)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) goto next_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) pr_info("Table Upgrade: install [%4.4s-%6.6s-%8.8s]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) table->signature, table->oem_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) table->oem_table_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) acpi_install_table(acpi_tables_addr + table_offset, TRUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) next_table:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) table_offset += table_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) table_index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) static acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) acpi_table_initrd_override(struct acpi_table_header *existing_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) acpi_physical_address *address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) u32 *table_length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) *table_length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) *address = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) return AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) static void __init acpi_table_initrd_scan(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) #endif /* CONFIG_ACPI_TABLE_UPGRADE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) acpi_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) acpi_os_physical_table_override(struct acpi_table_header *existing_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) acpi_physical_address *address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) u32 *table_length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) return acpi_table_initrd_override(existing_table, address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) table_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) #ifdef CONFIG_ACPI_CUSTOM_DSDT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) static void *amlcode __attribute__ ((weakref("AmlCode")));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) static void *dsdt_amlcode __attribute__ ((weakref("dsdt_aml_code")));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) acpi_status acpi_os_table_override(struct acpi_table_header *existing_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) struct acpi_table_header **new_table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) if (!existing_table || !new_table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) return AE_BAD_PARAMETER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) *new_table = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) #ifdef CONFIG_ACPI_CUSTOM_DSDT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) if (!strncmp(existing_table->signature, "DSDT", 4)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) *new_table = (struct acpi_table_header *)&amlcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) if (!(*new_table))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) *new_table = (struct acpi_table_header *)&dsdt_amlcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) if (*new_table != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) acpi_table_taint(existing_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) return AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) * acpi_locate_initial_tables()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) * find RSDP, find and checksum SDT/XSDT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) * checksum all tables, print SDT/XSDT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) * result: sdt_entry[] is initialized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) int __init acpi_locate_initial_tables(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) if (acpi_verify_table_checksum) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) pr_info("Early table checksum verification enabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) acpi_gbl_enable_table_validation = TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) pr_info("Early table checksum verification disabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) acpi_gbl_enable_table_validation = FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) status = acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) if (ACPI_FAILURE(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) void __init acpi_reserve_initial_tables(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) for (i = 0; i < ACPI_MAX_TABLES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) struct acpi_table_desc *table_desc = &initial_tables[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) u64 start = table_desc->address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) u64 size = table_desc->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) if (!start || !size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) pr_info("Reserving %4s table memory at [mem 0x%llx-0x%llx]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) table_desc->signature.ascii, start, start + size - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) memblock_reserve(start, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) void __init acpi_table_init_complete(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) acpi_table_initrd_scan();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) check_multiple_madt();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) int __init acpi_table_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) ret = acpi_locate_initial_tables();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) acpi_table_init_complete();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) static int __init acpi_parse_apic_instance(char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) if (!str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) if (kstrtoint(str, 0, &acpi_apic_instance))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) pr_notice("Shall use APIC/MADT table %d\n", acpi_apic_instance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) early_param("acpi_apic_instance", acpi_parse_apic_instance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) static int __init acpi_force_table_verification_setup(char *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) acpi_verify_table_checksum = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) early_param("acpi_force_table_verification", acpi_force_table_verification_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) static int __init acpi_force_32bit_fadt_addr(char *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) pr_info("Forcing 32 Bit FADT addresses\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) acpi_gbl_use32_bit_fadt_addresses = TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) early_param("acpi_force_32bit_fadt_addr", acpi_force_32bit_fadt_addr);