0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #define pr_fmt(fmt) "ACPI: " fmt
0011
0012 #include <linux/init.h>
0013 #include <linux/kernel.h>
0014 #include <linux/smp.h>
0015 #include <linux/string.h>
0016 #include <linux/types.h>
0017 #include <linux/irq.h>
0018 #include <linux/errno.h>
0019 #include <linux/acpi.h>
0020 #include <linux/memblock.h>
0021 #include <linux/earlycpio.h>
0022 #include <linux/initrd.h>
0023 #include <linux/security.h>
0024 #include <linux/kmemleak.h>
0025 #include "internal.h"
0026
0027 #ifdef CONFIG_ACPI_CUSTOM_DSDT
0028 #include CONFIG_ACPI_CUSTOM_DSDT_FILE
0029 #endif
0030
0031 #define ACPI_MAX_TABLES 128
0032
0033 static char *mps_inti_flags_polarity[] = { "dfl", "high", "res", "low" };
0034 static char *mps_inti_flags_trigger[] = { "dfl", "edge", "res", "level" };
0035
0036 static struct acpi_table_desc initial_tables[ACPI_MAX_TABLES] __initdata;
0037
0038 static int acpi_apic_instance __initdata_or_acpilib;
0039
0040 enum acpi_subtable_type {
0041 ACPI_SUBTABLE_COMMON,
0042 ACPI_SUBTABLE_HMAT,
0043 ACPI_SUBTABLE_PRMT,
0044 ACPI_SUBTABLE_CEDT,
0045 };
0046
0047 struct acpi_subtable_entry {
0048 union acpi_subtable_headers *hdr;
0049 enum acpi_subtable_type type;
0050 };
0051
0052
0053
0054
0055
0056 static bool acpi_verify_table_checksum __initdata_or_acpilib = false;
0057
0058 void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
0059 {
0060 if (!header)
0061 return;
0062
0063 switch (header->type) {
0064
0065 case ACPI_MADT_TYPE_LOCAL_APIC:
0066 {
0067 struct acpi_madt_local_apic *p =
0068 (struct acpi_madt_local_apic *)header;
0069 pr_debug("LAPIC (acpi_id[0x%02x] lapic_id[0x%02x] %s)\n",
0070 p->processor_id, p->id,
0071 (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled");
0072 }
0073 break;
0074
0075 case ACPI_MADT_TYPE_LOCAL_X2APIC:
0076 {
0077 struct acpi_madt_local_x2apic *p =
0078 (struct acpi_madt_local_x2apic *)header;
0079 pr_debug("X2APIC (apic_id[0x%02x] uid[0x%02x] %s)\n",
0080 p->local_apic_id, p->uid,
0081 (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled");
0082 }
0083 break;
0084
0085 case ACPI_MADT_TYPE_IO_APIC:
0086 {
0087 struct acpi_madt_io_apic *p =
0088 (struct acpi_madt_io_apic *)header;
0089 pr_debug("IOAPIC (id[0x%02x] address[0x%08x] gsi_base[%d])\n",
0090 p->id, p->address, p->global_irq_base);
0091 }
0092 break;
0093
0094 case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
0095 {
0096 struct acpi_madt_interrupt_override *p =
0097 (struct acpi_madt_interrupt_override *)header;
0098 pr_info("INT_SRC_OVR (bus %d bus_irq %d global_irq %d %s %s)\n",
0099 p->bus, p->source_irq, p->global_irq,
0100 mps_inti_flags_polarity[p->inti_flags & ACPI_MADT_POLARITY_MASK],
0101 mps_inti_flags_trigger[(p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2]);
0102 if (p->inti_flags &
0103 ~(ACPI_MADT_POLARITY_MASK | ACPI_MADT_TRIGGER_MASK))
0104 pr_info("INT_SRC_OVR unexpected reserved flags: 0x%x\n",
0105 p->inti_flags &
0106 ~(ACPI_MADT_POLARITY_MASK | ACPI_MADT_TRIGGER_MASK));
0107 }
0108 break;
0109
0110 case ACPI_MADT_TYPE_NMI_SOURCE:
0111 {
0112 struct acpi_madt_nmi_source *p =
0113 (struct acpi_madt_nmi_source *)header;
0114 pr_info("NMI_SRC (%s %s global_irq %d)\n",
0115 mps_inti_flags_polarity[p->inti_flags & ACPI_MADT_POLARITY_MASK],
0116 mps_inti_flags_trigger[(p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2],
0117 p->global_irq);
0118 }
0119 break;
0120
0121 case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
0122 {
0123 struct acpi_madt_local_apic_nmi *p =
0124 (struct acpi_madt_local_apic_nmi *)header;
0125 pr_info("LAPIC_NMI (acpi_id[0x%02x] %s %s lint[0x%x])\n",
0126 p->processor_id,
0127 mps_inti_flags_polarity[p->inti_flags & ACPI_MADT_POLARITY_MASK ],
0128 mps_inti_flags_trigger[(p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2],
0129 p->lint);
0130 }
0131 break;
0132
0133 case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
0134 {
0135 u16 polarity, trigger;
0136 struct acpi_madt_local_x2apic_nmi *p =
0137 (struct acpi_madt_local_x2apic_nmi *)header;
0138
0139 polarity = p->inti_flags & ACPI_MADT_POLARITY_MASK;
0140 trigger = (p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2;
0141
0142 pr_info("X2APIC_NMI (uid[0x%02x] %s %s lint[0x%x])\n",
0143 p->uid,
0144 mps_inti_flags_polarity[polarity],
0145 mps_inti_flags_trigger[trigger],
0146 p->lint);
0147 }
0148 break;
0149
0150 case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
0151 {
0152 struct acpi_madt_local_apic_override *p =
0153 (struct acpi_madt_local_apic_override *)header;
0154 pr_info("LAPIC_ADDR_OVR (address[0x%llx])\n",
0155 p->address);
0156 }
0157 break;
0158
0159 case ACPI_MADT_TYPE_IO_SAPIC:
0160 {
0161 struct acpi_madt_io_sapic *p =
0162 (struct acpi_madt_io_sapic *)header;
0163 pr_debug("IOSAPIC (id[0x%x] address[%p] gsi_base[%d])\n",
0164 p->id, (void *)(unsigned long)p->address,
0165 p->global_irq_base);
0166 }
0167 break;
0168
0169 case ACPI_MADT_TYPE_LOCAL_SAPIC:
0170 {
0171 struct acpi_madt_local_sapic *p =
0172 (struct acpi_madt_local_sapic *)header;
0173 pr_debug("LSAPIC (acpi_id[0x%02x] lsapic_id[0x%02x] lsapic_eid[0x%02x] %s)\n",
0174 p->processor_id, p->id, p->eid,
0175 (p->lapic_flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled");
0176 }
0177 break;
0178
0179 case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
0180 {
0181 struct acpi_madt_interrupt_source *p =
0182 (struct acpi_madt_interrupt_source *)header;
0183 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",
0184 mps_inti_flags_polarity[p->inti_flags & ACPI_MADT_POLARITY_MASK],
0185 mps_inti_flags_trigger[(p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2],
0186 p->type, p->id, p->eid, p->io_sapic_vector,
0187 p->global_irq);
0188 }
0189 break;
0190
0191 case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
0192 {
0193 struct acpi_madt_generic_interrupt *p =
0194 (struct acpi_madt_generic_interrupt *)header;
0195 pr_debug("GICC (acpi_id[0x%04x] address[%llx] MPIDR[0x%llx] %s)\n",
0196 p->uid, p->base_address,
0197 p->arm_mpidr,
0198 (p->flags & ACPI_MADT_ENABLED) ? "enabled" : "disabled");
0199
0200 }
0201 break;
0202
0203 case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
0204 {
0205 struct acpi_madt_generic_distributor *p =
0206 (struct acpi_madt_generic_distributor *)header;
0207 pr_debug("GIC Distributor (gic_id[0x%04x] address[%llx] gsi_base[%d])\n",
0208 p->gic_id, p->base_address,
0209 p->global_irq_base);
0210 }
0211 break;
0212
0213 default:
0214 pr_warn("Found unsupported MADT entry (type = 0x%x)\n",
0215 header->type);
0216 break;
0217 }
0218 }
0219
0220 static unsigned long __init_or_acpilib
0221 acpi_get_entry_type(struct acpi_subtable_entry *entry)
0222 {
0223 switch (entry->type) {
0224 case ACPI_SUBTABLE_COMMON:
0225 return entry->hdr->common.type;
0226 case ACPI_SUBTABLE_HMAT:
0227 return entry->hdr->hmat.type;
0228 case ACPI_SUBTABLE_PRMT:
0229 return 0;
0230 case ACPI_SUBTABLE_CEDT:
0231 return entry->hdr->cedt.type;
0232 }
0233 return 0;
0234 }
0235
0236 static unsigned long __init_or_acpilib
0237 acpi_get_entry_length(struct acpi_subtable_entry *entry)
0238 {
0239 switch (entry->type) {
0240 case ACPI_SUBTABLE_COMMON:
0241 return entry->hdr->common.length;
0242 case ACPI_SUBTABLE_HMAT:
0243 return entry->hdr->hmat.length;
0244 case ACPI_SUBTABLE_PRMT:
0245 return entry->hdr->prmt.length;
0246 case ACPI_SUBTABLE_CEDT:
0247 return entry->hdr->cedt.length;
0248 }
0249 return 0;
0250 }
0251
0252 static unsigned long __init_or_acpilib
0253 acpi_get_subtable_header_length(struct acpi_subtable_entry *entry)
0254 {
0255 switch (entry->type) {
0256 case ACPI_SUBTABLE_COMMON:
0257 return sizeof(entry->hdr->common);
0258 case ACPI_SUBTABLE_HMAT:
0259 return sizeof(entry->hdr->hmat);
0260 case ACPI_SUBTABLE_PRMT:
0261 return sizeof(entry->hdr->prmt);
0262 case ACPI_SUBTABLE_CEDT:
0263 return sizeof(entry->hdr->cedt);
0264 }
0265 return 0;
0266 }
0267
0268 static enum acpi_subtable_type __init_or_acpilib
0269 acpi_get_subtable_type(char *id)
0270 {
0271 if (strncmp(id, ACPI_SIG_HMAT, 4) == 0)
0272 return ACPI_SUBTABLE_HMAT;
0273 if (strncmp(id, ACPI_SIG_PRMT, 4) == 0)
0274 return ACPI_SUBTABLE_PRMT;
0275 if (strncmp(id, ACPI_SIG_CEDT, 4) == 0)
0276 return ACPI_SUBTABLE_CEDT;
0277 return ACPI_SUBTABLE_COMMON;
0278 }
0279
0280 static __init_or_acpilib bool has_handler(struct acpi_subtable_proc *proc)
0281 {
0282 return proc->handler || proc->handler_arg;
0283 }
0284
0285 static __init_or_acpilib int call_handler(struct acpi_subtable_proc *proc,
0286 union acpi_subtable_headers *hdr,
0287 unsigned long end)
0288 {
0289 if (proc->handler)
0290 return proc->handler(hdr, end);
0291 if (proc->handler_arg)
0292 return proc->handler_arg(hdr, proc->arg, end);
0293 return -EINVAL;
0294 }
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319 static int __init_or_acpilib acpi_parse_entries_array(
0320 char *id, unsigned long table_size,
0321 struct acpi_table_header *table_header, struct acpi_subtable_proc *proc,
0322 int proc_num, unsigned int max_entries)
0323 {
0324 struct acpi_subtable_entry entry;
0325 unsigned long table_end, subtable_len, entry_len;
0326 int count = 0;
0327 int errs = 0;
0328 int i;
0329
0330 table_end = (unsigned long)table_header + table_header->length;
0331
0332
0333
0334 entry.type = acpi_get_subtable_type(id);
0335 entry.hdr = (union acpi_subtable_headers *)
0336 ((unsigned long)table_header + table_size);
0337 subtable_len = acpi_get_subtable_header_length(&entry);
0338
0339 while (((unsigned long)entry.hdr) + subtable_len < table_end) {
0340 if (max_entries && count >= max_entries)
0341 break;
0342
0343 for (i = 0; i < proc_num; i++) {
0344 if (acpi_get_entry_type(&entry) != proc[i].id)
0345 continue;
0346 if (!has_handler(&proc[i]) ||
0347 (!errs &&
0348 call_handler(&proc[i], entry.hdr, table_end))) {
0349 errs++;
0350 continue;
0351 }
0352
0353 proc[i].count++;
0354 break;
0355 }
0356 if (i != proc_num)
0357 count++;
0358
0359
0360
0361
0362
0363 entry_len = acpi_get_entry_length(&entry);
0364 if (entry_len == 0) {
0365 pr_err("[%4.4s:0x%02x] Invalid zero length\n", id, proc->id);
0366 return -EINVAL;
0367 }
0368
0369 entry.hdr = (union acpi_subtable_headers *)
0370 ((unsigned long)entry.hdr + entry_len);
0371 }
0372
0373 if (max_entries && count > max_entries) {
0374 pr_warn("[%4.4s:0x%02x] found the maximum %i entries\n",
0375 id, proc->id, count);
0376 }
0377
0378 return errs ? -EINVAL : count;
0379 }
0380
0381 int __init_or_acpilib acpi_table_parse_entries_array(
0382 char *id, unsigned long table_size, struct acpi_subtable_proc *proc,
0383 int proc_num, unsigned int max_entries)
0384 {
0385 struct acpi_table_header *table_header = NULL;
0386 int count;
0387 u32 instance = 0;
0388
0389 if (acpi_disabled)
0390 return -ENODEV;
0391
0392 if (!id)
0393 return -EINVAL;
0394
0395 if (!table_size)
0396 return -EINVAL;
0397
0398 if (!strncmp(id, ACPI_SIG_MADT, 4))
0399 instance = acpi_apic_instance;
0400
0401 acpi_get_table(id, instance, &table_header);
0402 if (!table_header) {
0403 pr_debug("%4.4s not present\n", id);
0404 return -ENODEV;
0405 }
0406
0407 count = acpi_parse_entries_array(id, table_size, table_header,
0408 proc, proc_num, max_entries);
0409
0410 acpi_put_table(table_header);
0411 return count;
0412 }
0413
0414 static int __init_or_acpilib __acpi_table_parse_entries(
0415 char *id, unsigned long table_size, int entry_id,
0416 acpi_tbl_entry_handler handler, acpi_tbl_entry_handler_arg handler_arg,
0417 void *arg, unsigned int max_entries)
0418 {
0419 struct acpi_subtable_proc proc = {
0420 .id = entry_id,
0421 .handler = handler,
0422 .handler_arg = handler_arg,
0423 .arg = arg,
0424 };
0425
0426 return acpi_table_parse_entries_array(id, table_size, &proc, 1,
0427 max_entries);
0428 }
0429
0430 int __init_or_acpilib
0431 acpi_table_parse_cedt(enum acpi_cedt_type id,
0432 acpi_tbl_entry_handler_arg handler_arg, void *arg)
0433 {
0434 return __acpi_table_parse_entries(ACPI_SIG_CEDT,
0435 sizeof(struct acpi_table_cedt), id,
0436 NULL, handler_arg, arg, 0);
0437 }
0438 EXPORT_SYMBOL_ACPI_LIB(acpi_table_parse_cedt);
0439
0440 int __init acpi_table_parse_entries(char *id, unsigned long table_size,
0441 int entry_id,
0442 acpi_tbl_entry_handler handler,
0443 unsigned int max_entries)
0444 {
0445 return __acpi_table_parse_entries(id, table_size, entry_id, handler,
0446 NULL, NULL, max_entries);
0447 }
0448
0449 int __init acpi_table_parse_madt(enum acpi_madt_type id,
0450 acpi_tbl_entry_handler handler, unsigned int max_entries)
0451 {
0452 return acpi_table_parse_entries(ACPI_SIG_MADT,
0453 sizeof(struct acpi_table_madt), id,
0454 handler, max_entries);
0455 }
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467 int __init acpi_table_parse(char *id, acpi_tbl_table_handler handler)
0468 {
0469 struct acpi_table_header *table = NULL;
0470
0471 if (acpi_disabled)
0472 return -ENODEV;
0473
0474 if (!id || !handler)
0475 return -EINVAL;
0476
0477 if (strncmp(id, ACPI_SIG_MADT, 4) == 0)
0478 acpi_get_table(id, acpi_apic_instance, &table);
0479 else
0480 acpi_get_table(id, 0, &table);
0481
0482 if (table) {
0483 handler(table);
0484 acpi_put_table(table);
0485 return 0;
0486 } else
0487 return -ENODEV;
0488 }
0489
0490
0491
0492
0493
0494
0495 static void __init check_multiple_madt(void)
0496 {
0497 struct acpi_table_header *table = NULL;
0498
0499 acpi_get_table(ACPI_SIG_MADT, 2, &table);
0500 if (table) {
0501 pr_warn("BIOS bug: multiple APIC/MADT found, using %d\n",
0502 acpi_apic_instance);
0503 pr_warn("If \"acpi_apic_instance=%d\" works better, "
0504 "notify linux-acpi@vger.kernel.org\n",
0505 acpi_apic_instance ? 0 : 2);
0506 acpi_put_table(table);
0507
0508 } else
0509 acpi_apic_instance = 0;
0510
0511 return;
0512 }
0513
0514 static void acpi_table_taint(struct acpi_table_header *table)
0515 {
0516 pr_warn("Override [%4.4s-%8.8s], this is unsafe: tainting kernel\n",
0517 table->signature, table->oem_table_id);
0518 add_taint(TAINT_OVERRIDDEN_ACPI_TABLE, LOCKDEP_NOW_UNRELIABLE);
0519 }
0520
0521 #ifdef CONFIG_ACPI_TABLE_UPGRADE
0522 static u64 acpi_tables_addr;
0523 static int all_tables_size;
0524
0525
0526 static u8 __init acpi_table_checksum(u8 *buffer, u32 length)
0527 {
0528 u8 sum = 0;
0529 u8 *end = buffer + length;
0530
0531 while (buffer < end)
0532 sum = (u8) (sum + *(buffer++));
0533 return sum;
0534 }
0535
0536
0537 static const char table_sigs[][ACPI_NAMESEG_SIZE] __initconst = {
0538 ACPI_SIG_BERT, ACPI_SIG_BGRT, ACPI_SIG_CPEP, ACPI_SIG_ECDT,
0539 ACPI_SIG_EINJ, ACPI_SIG_ERST, ACPI_SIG_HEST, ACPI_SIG_MADT,
0540 ACPI_SIG_MSCT, ACPI_SIG_SBST, ACPI_SIG_SLIT, ACPI_SIG_SRAT,
0541 ACPI_SIG_ASF, ACPI_SIG_BOOT, ACPI_SIG_DBGP, ACPI_SIG_DMAR,
0542 ACPI_SIG_HPET, ACPI_SIG_IBFT, ACPI_SIG_IVRS, ACPI_SIG_MCFG,
0543 ACPI_SIG_MCHI, ACPI_SIG_SLIC, ACPI_SIG_SPCR, ACPI_SIG_SPMI,
0544 ACPI_SIG_TCPA, ACPI_SIG_UEFI, ACPI_SIG_WAET, ACPI_SIG_WDAT,
0545 ACPI_SIG_WDDT, ACPI_SIG_WDRT, ACPI_SIG_DSDT, ACPI_SIG_FADT,
0546 ACPI_SIG_PSDT, ACPI_SIG_RSDT, ACPI_SIG_XSDT, ACPI_SIG_SSDT,
0547 ACPI_SIG_IORT, ACPI_SIG_NFIT, ACPI_SIG_HMAT, ACPI_SIG_PPTT,
0548 ACPI_SIG_NHLT, ACPI_SIG_AEST, ACPI_SIG_CEDT, ACPI_SIG_AGDI };
0549
0550 #define ACPI_HEADER_SIZE sizeof(struct acpi_table_header)
0551
0552 #define NR_ACPI_INITRD_TABLES 64
0553 static struct cpio_data __initdata acpi_initrd_files[NR_ACPI_INITRD_TABLES];
0554 static DECLARE_BITMAP(acpi_initrd_installed, NR_ACPI_INITRD_TABLES);
0555
0556 #define MAP_CHUNK_SIZE (NR_FIX_BTMAPS << PAGE_SHIFT)
0557
0558 void __init acpi_table_upgrade(void)
0559 {
0560 void *data;
0561 size_t size;
0562 int sig, no, table_nr = 0, total_offset = 0;
0563 long offset = 0;
0564 struct acpi_table_header *table;
0565 char cpio_path[32] = "kernel/firmware/acpi/";
0566 struct cpio_data file;
0567
0568 if (IS_ENABLED(CONFIG_ACPI_TABLE_OVERRIDE_VIA_BUILTIN_INITRD)) {
0569 data = __initramfs_start;
0570 size = __initramfs_size;
0571 } else {
0572 data = (void *)initrd_start;
0573 size = initrd_end - initrd_start;
0574 }
0575
0576 if (data == NULL || size == 0)
0577 return;
0578
0579 for (no = 0; no < NR_ACPI_INITRD_TABLES; no++) {
0580 file = find_cpio_data(cpio_path, data, size, &offset);
0581 if (!file.data)
0582 break;
0583
0584 data += offset;
0585 size -= offset;
0586
0587 if (file.size < sizeof(struct acpi_table_header)) {
0588 pr_err("ACPI OVERRIDE: Table smaller than ACPI header [%s%s]\n",
0589 cpio_path, file.name);
0590 continue;
0591 }
0592
0593 table = file.data;
0594
0595 for (sig = 0; sig < ARRAY_SIZE(table_sigs); sig++)
0596 if (!memcmp(table->signature, table_sigs[sig], 4))
0597 break;
0598
0599 if (sig >= ARRAY_SIZE(table_sigs)) {
0600 pr_err("ACPI OVERRIDE: Unknown signature [%s%s]\n",
0601 cpio_path, file.name);
0602 continue;
0603 }
0604 if (file.size != table->length) {
0605 pr_err("ACPI OVERRIDE: File length does not match table length [%s%s]\n",
0606 cpio_path, file.name);
0607 continue;
0608 }
0609 if (acpi_table_checksum(file.data, table->length)) {
0610 pr_err("ACPI OVERRIDE: Bad table checksum [%s%s]\n",
0611 cpio_path, file.name);
0612 continue;
0613 }
0614
0615 pr_info("%4.4s ACPI table found in initrd [%s%s][0x%x]\n",
0616 table->signature, cpio_path, file.name, table->length);
0617
0618 all_tables_size += table->length;
0619 acpi_initrd_files[table_nr].data = file.data;
0620 acpi_initrd_files[table_nr].size = file.size;
0621 table_nr++;
0622 }
0623 if (table_nr == 0)
0624 return;
0625
0626 if (security_locked_down(LOCKDOWN_ACPI_TABLES)) {
0627 pr_notice("kernel is locked down, ignoring table override\n");
0628 return;
0629 }
0630
0631 acpi_tables_addr =
0632 memblock_phys_alloc_range(all_tables_size, PAGE_SIZE,
0633 0, ACPI_TABLE_UPGRADE_MAX_PHYS);
0634 if (!acpi_tables_addr) {
0635 WARN_ON(1);
0636 return;
0637 }
0638
0639
0640
0641
0642
0643
0644
0645
0646
0647
0648 arch_reserve_mem_area(acpi_tables_addr, all_tables_size);
0649
0650 kmemleak_ignore_phys(acpi_tables_addr);
0651
0652
0653
0654
0655
0656
0657 for (no = 0; no < table_nr; no++) {
0658 unsigned char *src_p = acpi_initrd_files[no].data;
0659 phys_addr_t size = acpi_initrd_files[no].size;
0660 phys_addr_t dest_addr = acpi_tables_addr + total_offset;
0661 phys_addr_t slop, clen;
0662 char *dest_p;
0663
0664 total_offset += size;
0665
0666 while (size) {
0667 slop = dest_addr & ~PAGE_MASK;
0668 clen = size;
0669 if (clen > MAP_CHUNK_SIZE - slop)
0670 clen = MAP_CHUNK_SIZE - slop;
0671 dest_p = early_memremap(dest_addr & PAGE_MASK,
0672 clen + slop);
0673 memcpy(dest_p + slop, src_p, clen);
0674 early_memunmap(dest_p, clen + slop);
0675 src_p += clen;
0676 dest_addr += clen;
0677 size -= clen;
0678 }
0679 }
0680 }
0681
0682 static acpi_status
0683 acpi_table_initrd_override(struct acpi_table_header *existing_table,
0684 acpi_physical_address *address, u32 *length)
0685 {
0686 int table_offset = 0;
0687 int table_index = 0;
0688 struct acpi_table_header *table;
0689 u32 table_length;
0690
0691 *length = 0;
0692 *address = 0;
0693 if (!acpi_tables_addr)
0694 return AE_OK;
0695
0696 while (table_offset + ACPI_HEADER_SIZE <= all_tables_size) {
0697 table = acpi_os_map_memory(acpi_tables_addr + table_offset,
0698 ACPI_HEADER_SIZE);
0699 if (table_offset + table->length > all_tables_size) {
0700 acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
0701 WARN_ON(1);
0702 return AE_OK;
0703 }
0704
0705 table_length = table->length;
0706
0707
0708 if (memcmp(existing_table->signature, table->signature, 4) ||
0709 memcmp(table->oem_id, existing_table->oem_id,
0710 ACPI_OEM_ID_SIZE) ||
0711 memcmp(table->oem_table_id, existing_table->oem_table_id,
0712 ACPI_OEM_TABLE_ID_SIZE)) {
0713 acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
0714 goto next_table;
0715 }
0716
0717
0718
0719
0720 if (test_and_set_bit(table_index, acpi_initrd_installed) ||
0721 existing_table->oem_revision >= table->oem_revision) {
0722 acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
0723 goto next_table;
0724 }
0725
0726 *length = table_length;
0727 *address = acpi_tables_addr + table_offset;
0728 pr_info("Table Upgrade: override [%4.4s-%6.6s-%8.8s]\n",
0729 table->signature, table->oem_id,
0730 table->oem_table_id);
0731 acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
0732 break;
0733
0734 next_table:
0735 table_offset += table_length;
0736 table_index++;
0737 }
0738 return AE_OK;
0739 }
0740
0741 static void __init acpi_table_initrd_scan(void)
0742 {
0743 int table_offset = 0;
0744 int table_index = 0;
0745 u32 table_length;
0746 struct acpi_table_header *table;
0747
0748 if (!acpi_tables_addr)
0749 return;
0750
0751 while (table_offset + ACPI_HEADER_SIZE <= all_tables_size) {
0752 table = acpi_os_map_memory(acpi_tables_addr + table_offset,
0753 ACPI_HEADER_SIZE);
0754 if (table_offset + table->length > all_tables_size) {
0755 acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
0756 WARN_ON(1);
0757 return;
0758 }
0759
0760 table_length = table->length;
0761
0762
0763 if (ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_RSDT) ||
0764 ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_XSDT)) {
0765 acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
0766 goto next_table;
0767 }
0768
0769
0770
0771
0772
0773 if (test_and_set_bit(table_index, acpi_initrd_installed)) {
0774 acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
0775 goto next_table;
0776 }
0777
0778 pr_info("Table Upgrade: install [%4.4s-%6.6s-%8.8s]\n",
0779 table->signature, table->oem_id,
0780 table->oem_table_id);
0781 acpi_os_unmap_memory(table, ACPI_HEADER_SIZE);
0782 acpi_install_physical_table(acpi_tables_addr + table_offset);
0783 next_table:
0784 table_offset += table_length;
0785 table_index++;
0786 }
0787 }
0788 #else
0789 static acpi_status
0790 acpi_table_initrd_override(struct acpi_table_header *existing_table,
0791 acpi_physical_address *address,
0792 u32 *table_length)
0793 {
0794 *table_length = 0;
0795 *address = 0;
0796 return AE_OK;
0797 }
0798
0799 static void __init acpi_table_initrd_scan(void)
0800 {
0801 }
0802 #endif
0803
0804 acpi_status
0805 acpi_os_physical_table_override(struct acpi_table_header *existing_table,
0806 acpi_physical_address *address,
0807 u32 *table_length)
0808 {
0809 return acpi_table_initrd_override(existing_table, address,
0810 table_length);
0811 }
0812
0813 #ifdef CONFIG_ACPI_CUSTOM_DSDT
0814 static void *amlcode __attribute__ ((weakref("AmlCode")));
0815 static void *dsdt_amlcode __attribute__ ((weakref("dsdt_aml_code")));
0816 #endif
0817
0818 acpi_status acpi_os_table_override(struct acpi_table_header *existing_table,
0819 struct acpi_table_header **new_table)
0820 {
0821 if (!existing_table || !new_table)
0822 return AE_BAD_PARAMETER;
0823
0824 *new_table = NULL;
0825
0826 #ifdef CONFIG_ACPI_CUSTOM_DSDT
0827 if (!strncmp(existing_table->signature, "DSDT", 4)) {
0828 *new_table = (struct acpi_table_header *)&amlcode;
0829 if (!(*new_table))
0830 *new_table = (struct acpi_table_header *)&dsdt_amlcode;
0831 }
0832 #endif
0833 if (*new_table != NULL)
0834 acpi_table_taint(existing_table);
0835 return AE_OK;
0836 }
0837
0838
0839
0840
0841
0842
0843
0844
0845
0846
0847 int __init acpi_locate_initial_tables(void)
0848 {
0849 acpi_status status;
0850
0851 if (acpi_verify_table_checksum) {
0852 pr_info("Early table checksum verification enabled\n");
0853 acpi_gbl_enable_table_validation = TRUE;
0854 } else {
0855 pr_info("Early table checksum verification disabled\n");
0856 acpi_gbl_enable_table_validation = FALSE;
0857 }
0858
0859 status = acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0);
0860 if (ACPI_FAILURE(status))
0861 return -EINVAL;
0862
0863 return 0;
0864 }
0865
0866 void __init acpi_reserve_initial_tables(void)
0867 {
0868 int i;
0869
0870 for (i = 0; i < ACPI_MAX_TABLES; i++) {
0871 struct acpi_table_desc *table_desc = &initial_tables[i];
0872 u64 start = table_desc->address;
0873 u64 size = table_desc->length;
0874
0875 if (!start || !size)
0876 break;
0877
0878 pr_info("Reserving %4s table memory at [mem 0x%llx-0x%llx]\n",
0879 table_desc->signature.ascii, start, start + size - 1);
0880
0881 memblock_reserve(start, size);
0882 }
0883 }
0884
0885 void __init acpi_table_init_complete(void)
0886 {
0887 acpi_table_initrd_scan();
0888 check_multiple_madt();
0889 }
0890
0891 int __init acpi_table_init(void)
0892 {
0893 int ret;
0894
0895 ret = acpi_locate_initial_tables();
0896 if (ret)
0897 return ret;
0898
0899 acpi_table_init_complete();
0900
0901 return 0;
0902 }
0903
0904 static int __init acpi_parse_apic_instance(char *str)
0905 {
0906 if (!str)
0907 return -EINVAL;
0908
0909 if (kstrtoint(str, 0, &acpi_apic_instance))
0910 return -EINVAL;
0911
0912 pr_notice("Shall use APIC/MADT table %d\n", acpi_apic_instance);
0913
0914 return 0;
0915 }
0916 early_param("acpi_apic_instance", acpi_parse_apic_instance);
0917
0918 static int __init acpi_force_table_verification_setup(char *s)
0919 {
0920 acpi_verify_table_checksum = true;
0921
0922 return 0;
0923 }
0924 early_param("acpi_force_table_verification", acpi_force_table_verification_setup);
0925
0926 static int __init acpi_force_32bit_fadt_addr(char *s)
0927 {
0928 pr_info("Forcing 32 Bit FADT addresses\n");
0929 acpi_gbl_use32_bit_fadt_addresses = TRUE;
0930
0931 return 0;
0932 }
0933 early_param("acpi_force_32bit_fadt_addr", acpi_force_32bit_fadt_addr);