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