static int __init find_unisys_acpi_oem_table(unsigned long *oem_addr) { struct acpi_table_header *header = NULL; struct es7000_oem_table *table; acpi_size tbl_size; acpi_status ret; int i = 0; for (;;) { ret = acpi_get_table_with_size("OEM1", i++, &header, &tbl_size); if (!ACPI_SUCCESS(ret)) return -1; if (!memcmp((char *) &header->oem_id, "UNISYS", 6)) break; early_acpi_os_unmap_memory(header, tbl_size); } table = (void *)header; oem_addrX = table->OEMTableAddr; oem_size = table->OEMTableSize; early_acpi_os_unmap_memory(header, tbl_size); *oem_addr = (unsigned long)__acpi_map_table(oem_addrX, oem_size); return 0; }
int __init acpi_table_parse_entries(char *id, unsigned long table_size, int entry_id, acpi_table_entry_handler handler, unsigned int max_entries) { struct acpi_table_header *table_header = NULL; struct acpi_subtable_header *entry; unsigned int count = 0; unsigned long table_end; acpi_size tbl_size; if (acpi_disabled && !acpi_ht) return -ENODEV; if (!handler) return -EINVAL; if (strncmp(id, ACPI_SIG_MADT, 4) == 0) acpi_get_table_with_size(id, acpi_apic_instance, &table_header, &tbl_size); else acpi_get_table_with_size(id, 0, &table_header, &tbl_size); if (!table_header) { printk(KERN_WARNING PREFIX "%4.4s not present\n", id); return -ENODEV; } table_end = (unsigned long)table_header + table_header->length; /* Parse all entries looking for a match. */ entry = (struct acpi_subtable_header *) ((unsigned long)table_header + table_size); while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) < table_end) { if (entry->type == entry_id && (!max_entries || count++ < max_entries)) if (handler(entry, table_end)) { early_acpi_os_unmap_memory((char *)table_header, tbl_size); return -EINVAL; } entry = (struct acpi_subtable_header *) ((unsigned long)entry + entry->length); } if (max_entries && count > max_entries) { printk(KERN_WARNING PREFIX "[%4.4s:0x%02x] ignored %i entries of " "%i found\n", id, entry_id, count - max_entries, count); } early_acpi_os_unmap_memory((char *)table_header, tbl_size); return count; }
int __init acpi_table_parse_entries(char *id, unsigned long table_size, int entry_id, acpi_tbl_entry_handler handler, unsigned int max_entries) { struct acpi_table_header *table_header = NULL; acpi_size tbl_size; int count; u32 instance = 0; if (acpi_disabled) return -ENODEV; if (!id || !handler) return -EINVAL; if (!strncmp(id, ACPI_SIG_MADT, 4)) instance = acpi_apic_instance; acpi_get_table_with_size(id, instance, &table_header, &tbl_size); if (!table_header) { pr_warn("%4.4s not present\n", id); return -ENODEV; } count = acpi_parse_entries(id, table_size, handler, table_header, entry_id, max_entries); early_acpi_os_unmap_memory((char *)table_header, tbl_size); return count; }
/* * acpi_fadt_sanity_check() - Check FADT presence and carry out sanity * checks on it * * Return 0 on success, <0 on failure */ static int __init acpi_fadt_sanity_check(void) { struct acpi_table_header *table; struct acpi_table_fadt *fadt; acpi_status status; acpi_size tbl_size; int ret = 0; /* * FADT is required on arm64; retrieve it to check its presence * and carry out revision and ACPI HW reduced compliancy tests */ status = acpi_get_table_with_size(ACPI_SIG_FADT, 0, &table, &tbl_size); if (ACPI_FAILURE(status)) { const char *msg = acpi_format_exception(status); pr_err("Failed to get FADT table, %s\n", msg); return -ENODEV; } fadt = (struct acpi_table_fadt *)table; /* * Revision in table header is the FADT Major revision, and there * is a minor revision of FADT which was introduced by ACPI 5.1, * we only deal with ACPI 5.1 or newer revision to get GIC and SMP * boot protocol configuration data. */ if (table->revision < 5 || (table->revision == 5 && fadt->minor_revision < 1)) { pr_err("Unsupported FADT revision %d.%d, should be 5.1+\n", table->revision, fadt->minor_revision); ret = -EINVAL; goto out; } if (!(fadt->flags & ACPI_FADT_HW_REDUCED)) { pr_err("FADT not ACPI hardware reduced compliant\n"); ret = -EINVAL; } out: /* * acpi_get_table_with_size() creates FADT table mapping that * should be released after parsing and before resuming boot */ early_acpi_os_unmap_memory(table, tbl_size); return ret; }
/* * The BIOS is supposed to supply a single APIC/MADT, * but some report two. Provide a knob to use either. * (don't you wish instance 0 and 1 were not the same?) */ static void __init check_multiple_madt(void) { struct acpi_table_header *table = NULL; acpi_size tbl_size; acpi_get_table_with_size(ACPI_SIG_MADT, 2, &table, &tbl_size); if (table) { pr_warn("BIOS bug: multiple APIC/MADT found, using %d\n", acpi_apic_instance); pr_warn("If \"acpi_apic_instance=%d\" works better, " "notify [email protected]\n", acpi_apic_instance ? 0 : 2); early_acpi_os_unmap_memory(table, tbl_size); } else acpi_apic_instance = 0; return; }
/** * acpi_table_parse - find table with @id, run @handler on it * * @id: table id to find * @handler: handler to run * * Scan the ACPI System Descriptor Table (STD) for a table matching @id, * run @handler on it. Return 0 if table found, return on if not. */ int __init acpi_table_parse(char *id, acpi_table_handler handler) { struct acpi_table_header *table = NULL; acpi_size tbl_size; if (!handler) return -EINVAL; if (strncmp(id, ACPI_SIG_MADT, 4) == 0) acpi_get_table_with_size(id, acpi_apic_instance, &table, &tbl_size); else acpi_get_table_with_size(id, 0, &table, &tbl_size); if (table) { handler(table); early_acpi_os_unmap_memory(table, tbl_size); return 0; } else return 1; }
void __init acpi_gic_init(void) { struct acpi_table_header *table; acpi_status status; acpi_size tbl_size; int err; if (acpi_disabled) return; status = acpi_get_table_with_size(ACPI_SIG_MADT, 0, &table, &tbl_size); if (ACPI_FAILURE(status)) { const char *msg = acpi_format_exception(status); pr_err("Failed to get MADT table, %s\n", msg); return; } err = gic_v2_acpi_init(table); if (err) pr_err("Failed to initialize GIC IRQ controller"); early_acpi_os_unmap_memory((char *)table, tbl_size); }
/** * parse_spcr() - parse ACPI SPCR table and add preferred console * * @earlycon: set up earlycon for the console specified by the table * * For the architectures with support for ACPI, CONFIG_ACPI_SPCR_TABLE may be * defined to parse ACPI SPCR table. As a result of the parsing preferred * console is registered and if @earlycon is true, earlycon is set up. * * When CONFIG_ACPI_SPCR_TABLE is defined, this function should should be called * from arch inintialization code as soon as the DT/ACPI decision is made. * */ int __init parse_spcr(bool earlycon) { static char opts[64]; struct acpi_table_spcr *table; acpi_size table_size; acpi_status status; char *uart; char *iotype; int baud_rate; int err; if (acpi_disabled) return -ENODEV; status = acpi_get_table_with_size(ACPI_SIG_SPCR, 0, (struct acpi_table_header **)&table, &table_size); if (ACPI_FAILURE(status)) return -ENOENT; if (table->header.revision < 2) { err = -ENOENT; pr_err("wrong table version\n"); goto done; } iotype = table->serial_port.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY ? "mmio" : "io"; switch (table->interface_type) { case ACPI_DBG2_ARM_SBSA_32BIT: iotype = "mmio32"; /* fall through */ case ACPI_DBG2_ARM_PL011: case ACPI_DBG2_ARM_SBSA_GENERIC: case ACPI_DBG2_BCM2835: uart = "pl011"; break; case ACPI_DBG2_16550_COMPATIBLE: case ACPI_DBG2_16550_SUBSET: if (table->serial_port.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY && table->serial_port.bit_width == 32) iotype = "mmio32"; uart = "uart"; break; default: err = -ENOENT; goto done; } switch (table->baud_rate) { case 3: baud_rate = 9600; break; case 4: baud_rate = 19200; break; case 6: baud_rate = 57600; break; case 7: baud_rate = 115200; break; default: err = -ENOENT; goto done; } snprintf(opts, sizeof(opts), "%s,%s,0x%llx", uart, iotype, table->serial_port.address); pr_info("console: %s", opts); if (earlycon) setup_earlycon(opts); err = add_preferred_console(uart, 0, opts + strlen(uart) + 1); done: early_acpi_os_unmap_memory((void __iomem *)table, table_size); return err; }