brintos

brintos / linux-shallow public Read only

0
0
Text · 21.1 KiB · 9e1b01c Raw
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