int __init find_unisys_acpi_oem_table(unsigned long *oem_addr) { struct acpi_table_rsdp *rsdp = NULL; unsigned long rsdp_phys = 0; struct acpi_table_header *header = NULL; int i; struct acpi_table_sdt sdt; rsdp_phys = acpi_find_rsdp(); rsdp = __va(rsdp_phys); if (rsdp->rsdt_address) { struct acpi_table_rsdt *mapped_rsdt = NULL; sdt.pa = rsdp->rsdt_address; header = (struct acpi_table_header *) __acpi_map_table(sdt.pa, sizeof(struct acpi_table_header)); if (!header) return -ENODEV; sdt.count = (header->length - sizeof(struct acpi_table_header)) >> 3; mapped_rsdt = (struct acpi_table_rsdt *) __acpi_map_table(sdt.pa, header->length); if (!mapped_rsdt) return -ENODEV; header = &mapped_rsdt->header; for (i = 0; i < sdt.count; i++) sdt.entry[i].pa = (unsigned long) mapped_rsdt->entry[i]; }; for (i = 0; i < sdt.count; i++) { header = (struct acpi_table_header *) __acpi_map_table(sdt.entry[i].pa, sizeof(struct acpi_table_header)); if (!header) continue; if (!strncmp((char *) &header->signature, "OEM1", 4)) { if (!strncmp((char *) &header->oem_id, "UNISYS", 6)) { void *addr; struct oem_table *t; acpi_table_print(header, sdt.entry[i].pa); t = (struct oem_table *) __acpi_map_table(sdt.entry[i].pa, header->length); addr = (void *) __acpi_map_table(t->OEMTableAddr, t->OEMTableSize); *oem_addr = (unsigned long) addr; return 0; } } } return -1; }
/* * acpi_get_table_header_early() * for acpi_blacklisted(), acpi_table_get_sdt() */ int __init acpi_get_table_header_early ( enum acpi_table_id id, struct acpi_table_header **header) { unsigned int i; enum acpi_table_id temp_id; /* DSDT is different from the rest */ if (id == ACPI_DSDT) temp_id = ACPI_FADT; else temp_id = id; /* Locate the table. */ for (i = 0; i < sdt_count; i++) { if (sdt_entry[i].id != temp_id) continue; *header = (void *) __acpi_map_table(sdt_entry[i].pa, sdt_entry[i].size); if (!*header) { printk(KERN_WARNING PREFIX "Unable to map %s\n", acpi_table_signatures[temp_id]); return -ENODEV; } break; } if (!*header) { printk(KERN_WARNING PREFIX "%s not present\n", acpi_table_signatures[id]); return -ENODEV; } /* Map the DSDT header via the pointer in the FADT */ if (id == ACPI_DSDT) { struct acpi_table_fadt *fadt = (struct acpi_table_fadt *) *header; *header = (void *) __acpi_map_table(fadt->dsdt_addr, sizeof(struct acpi_table_header)); if (!*header) { printk(KERN_WARNING PREFIX "Unable to map DSDT\n"); return -ENODEV; } } return 0; }
static int __init acpi_parse_madt ( unsigned long phys_addr, unsigned long size) { struct acpi_table_madt *madt = NULL; if (!phys_addr || !size) return -EINVAL; madt = (struct acpi_table_madt *) __acpi_map_table(phys_addr, size); if (!madt) { printk(KERN_WARNING PREFIX "Unable to map MADT\n"); return -ENODEV; } if (madt->lapic_address) acpi_lapic_addr = (u64) madt->lapic_address; printk(KERN_INFO PREFIX "Local APIC address 0x%08x\n", madt->lapic_address); detect_clustered_apic(madt->header.oem_id, madt->header.oem_table_id); return 0; }
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; }
/* Get pm1x_cnt and pm1x_evt information for ACPI sleep */ static void __init acpi_fadt_parse_sleep_info(struct acpi_table_fadt *fadt) { struct acpi_table_facs *facs = NULL; uint64_t facs_pa; acpi_fadt_copy_address(pm1a_cnt, pm1a_control, pm1_control); acpi_fadt_copy_address(pm1b_cnt, pm1b_control, pm1_control); acpi_fadt_copy_address(pm1a_evt, pm1a_event, pm1_event); acpi_fadt_copy_address(pm1b_evt, pm1b_event, pm1_event); printk(KERN_INFO PREFIX "ACPI SLEEP INFO: pm1x_cnt[%"PRIx64",%"PRIx64"], " "pm1x_evt[%"PRIx64",%"PRIx64"]\n", acpi_sinfo.pm1a_cnt_blk.address, acpi_sinfo.pm1b_cnt_blk.address, acpi_sinfo.pm1a_evt_blk.address, acpi_sinfo.pm1b_evt_blk.address); /* Now FACS... */ if (fadt->header.revision >= FADT2_REVISION_ID) facs_pa = fadt->Xfacs; else facs_pa = (uint64_t)fadt->facs; facs = (struct acpi_table_facs *) __acpi_map_table(facs_pa, sizeof(struct acpi_table_facs)); if (!facs) goto bad; if (strncmp(facs->signature, "FACS", 4)) { printk(KERN_ERR PREFIX "Invalid FACS signature %.4s\n", facs->signature); goto bad; } if (facs->length < 24) { printk(KERN_ERR PREFIX "Invalid FACS table length: 0x%x", facs->length); goto bad; } if (facs->length < 64) printk(KERN_WARNING PREFIX "FACS is shorter than ACPI spec allow: 0x%x", facs->length); acpi_sinfo.wakeup_vector = facs_pa + offsetof(struct acpi_table_facs, firmware_waking_vector); acpi_sinfo.vector_width = 32; printk(KERN_INFO PREFIX " wakeup_vec[%"PRIx64"], vec_size[%x]\n", acpi_sinfo.wakeup_vector, acpi_sinfo.vector_width); return; bad: memset(&acpi_sinfo, 0, sizeof(acpi_sinfo)); }
int __init acpi_table_parse_madt_family ( enum acpi_table_id id, unsigned long madt_size, int entry_id, acpi_madt_entry_handler handler) { void *madt = NULL; acpi_table_entry_header *entry = NULL; unsigned long count = 0; unsigned long madt_end = 0; unsigned int i = 0; if (!handler) return -EINVAL; /* Locate the MADT (if exists). There should only be one. */ for (i = 0; i < sdt_count; i++) { if (sdt_entry[i].id != id) continue; madt = (void *) __acpi_map_table(sdt_entry[i].pa, sdt_entry[i].size); if (!madt) { printk(KERN_WARNING PREFIX "Unable to map %s\n", acpi_table_signatures[id]); return -ENODEV; } break; } if (!madt) { printk(KERN_WARNING PREFIX "%s not present\n", acpi_table_signatures[id]); return -ENODEV; } madt_end = (unsigned long) madt + sdt_entry[i].size; /* Parse all entries looking for a match. */ entry = (acpi_table_entry_header *) ((unsigned long) madt + madt_size); while (((unsigned long) entry) < madt_end) { if (entry->type == entry_id) { count++; handler(entry); } entry = (acpi_table_entry_header *) ((unsigned long) entry + entry->length); } return count; }
void __iomem *__init_refok acpi_os_map_memory(acpi_physical_address phys, acpi_size size) { struct acpi_ioremap *map; void __iomem *virt; acpi_physical_address pg_off; acpi_size pg_sz; if (phys > ULONG_MAX) { printk(KERN_ERR PREFIX "Cannot map memory that high\n"); return NULL; } if (!acpi_gbl_permanent_mmap) return __acpi_map_table((unsigned long)phys, size); mutex_lock(&acpi_ioremap_lock); /* Check if there's a suitable mapping already. */ map = acpi_map_lookup(phys, size); if (map) { map->refcount++; goto out; } map = kzalloc(sizeof(*map), GFP_KERNEL); if (!map) { mutex_unlock(&acpi_ioremap_lock); return NULL; } pg_off = round_down(phys, PAGE_SIZE); pg_sz = round_up(phys + size, PAGE_SIZE) - pg_off; virt = acpi_map(pg_off, pg_sz); if (!virt) { mutex_unlock(&acpi_ioremap_lock); kfree(map); return NULL; } INIT_LIST_HEAD(&map->list); map->virt = virt; map->phys = pg_off; map->size = pg_sz; map->refcount = 1; list_add_tail_rcu(&map->list, &acpi_ioremaps); out: mutex_unlock(&acpi_ioremap_lock); return map->virt + (phys - map->phys); }
void __iomem *acpi_os_map_memory(acpi_physical_address phys, acpi_size size) { if (phys > ULONG_MAX) { printk(KERN_ERR PREFIX "Cannot map memory that high\n"); return NULL; } if (acpi_gbl_permanent_mmap) /* * ioremap checks to ensure this is in reserved space */ return ioremap((unsigned long)phys, size); else return __acpi_map_table((unsigned long)phys, size); }
int __init find_unisys_acpi_oem_table(unsigned long *oem_addr) { struct acpi_table_header *header = NULL; int i = 0; while (ACPI_SUCCESS(acpi_get_table("OEM1", i++, &header))) { if (!memcmp((char *) &header->oem_id, "UNISYS", 6)) { struct oem_table *t = (struct oem_table *)header; *oem_addr = (unsigned long)__acpi_map_table(t->OEMTableAddr, t->OEMTableSize); return 0; } } return -1; }
static int __init acpi_parse_fadt(unsigned long phys, unsigned long size) { struct fadt_descriptor_rev2 *fadt =0; fadt = (struct fadt_descriptor_rev2*) __acpi_map_table(phys,size); if (!fadt) { printk(KERN_WARNING PREFIX "Unable to map FADT\n"); return 0; } #ifdef CONFIG_ACPI_INTERPRETER /* initialize sci_int early for INT_SRC_OVR MADT parsing */ acpi_fadt.sci_int = fadt->sci_int; #endif return 0; }
static void acpi_sleep_prepare(u32 state) { void *wakeup_vector_va; if ( state != ACPI_STATE_S3 ) return; wakeup_vector_va = __acpi_map_table( acpi_sinfo.wakeup_vector, sizeof(uint64_t)); /* TBoot will set resume vector itself (when it is safe to do so). */ if ( tboot_in_measured_env() ) return; if ( acpi_sinfo.vector_width == 32 ) *(uint32_t *)wakeup_vector_va = bootsym_phys(wakeup_start); else *(uint64_t *)wakeup_vector_va = bootsym_phys(wakeup_start); }
static int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) { struct acpi_table_mcfg *mcfg = NULL; if (!phys_addr || !size) return -EINVAL; mcfg = (struct acpi_table_mcfg *) __acpi_map_table(phys_addr, size); if (!mcfg) { printk(KERN_WARNING PREFIX "Unable to map MCFG\n"); return -ENODEV; } if (mcfg->base_reserved) { printk(KERN_ERR PREFIX "MMCONFIG not in low 4GB of memory\n"); return -ENODEV; } pci_mmcfg_base_addr = mcfg->base_address; return 0; }
/* Get pm1x_cnt and pm1x_evt information for ACPI sleep */ static void __init acpi_fadt_parse_sleep_info(struct acpi_table_fadt *fadt) { struct acpi_table_facs *facs = NULL; uint64_t facs_pa; if (fadt->header.revision >= 5 && fadt->header.length >= ACPI_FADT_V5_SIZE) { acpi_sinfo.sleep_control = fadt->sleep_control; acpi_sinfo.sleep_status = fadt->sleep_status; printk(KERN_INFO PREFIX "v5 SLEEP INFO: control[%d:%"PRIx64"]," " status[%d:%"PRIx64"]\n", acpi_sinfo.sleep_control.space_id, acpi_sinfo.sleep_control.address, acpi_sinfo.sleep_status.space_id, acpi_sinfo.sleep_status.address); if ((fadt->sleep_control.address && (fadt->sleep_control.bit_offset || fadt->sleep_control.bit_width != fadt->sleep_control.access_width * 8)) || (fadt->sleep_status.address && (fadt->sleep_status.bit_offset || fadt->sleep_status.bit_width != fadt->sleep_status.access_width * 8))) { printk(KERN_WARNING PREFIX "Invalid sleep control/status register data:" " %#x:%#x:%#x %#x:%#x:%#x\n", fadt->sleep_control.bit_offset, fadt->sleep_control.bit_width, fadt->sleep_control.access_width, fadt->sleep_status.bit_offset, fadt->sleep_status.bit_width, fadt->sleep_status.access_width); fadt->sleep_control.address = 0; fadt->sleep_status.address = 0; } } if (fadt->flags & ACPI_FADT_HW_REDUCED) goto bad; acpi_fadt_copy_address(pm1a_cnt, pm1a_control, pm1_control); acpi_fadt_copy_address(pm1b_cnt, pm1b_control, pm1_control); acpi_fadt_copy_address(pm1a_evt, pm1a_event, pm1_event); acpi_fadt_copy_address(pm1b_evt, pm1b_event, pm1_event); printk(KERN_INFO PREFIX "SLEEP INFO: pm1x_cnt[%"PRIx64",%"PRIx64"], " "pm1x_evt[%"PRIx64",%"PRIx64"]\n", acpi_sinfo.pm1a_cnt_blk.address, acpi_sinfo.pm1b_cnt_blk.address, acpi_sinfo.pm1a_evt_blk.address, acpi_sinfo.pm1b_evt_blk.address); /* Now FACS... */ facs_pa = ((fadt->header.revision >= FADT2_REVISION_ID) ? fadt->Xfacs : (uint64_t)fadt->facs); if (fadt->facs && ((uint64_t)fadt->facs != facs_pa)) { printk(KERN_WARNING PREFIX "32/64X FACS address mismatch in FADT - " "%08x/%016"PRIx64", using 32\n", fadt->facs, facs_pa); facs_pa = (uint64_t)fadt->facs; } if (!facs_pa) goto bad; facs = (struct acpi_table_facs *) __acpi_map_table(facs_pa, sizeof(struct acpi_table_facs)); if (!facs) goto bad; if (strncmp(facs->signature, "FACS", 4)) { printk(KERN_ERR PREFIX "Invalid FACS signature %.4s\n", facs->signature); goto bad; } if (facs->length < 24) { printk(KERN_ERR PREFIX "Invalid FACS table length: %#x", facs->length); goto bad; } if (facs->length < 64) printk(KERN_WARNING PREFIX "FACS is shorter than ACPI spec allow: %#x", facs->length); acpi_sinfo.wakeup_vector = facs_pa + offsetof(struct acpi_table_facs, firmware_waking_vector); acpi_sinfo.vector_width = 32; printk(KERN_INFO PREFIX " wakeup_vec[%"PRIx64"], vec_size[%x]\n", acpi_sinfo.wakeup_vector, acpi_sinfo.vector_width); return; bad: memset(&acpi_sinfo, 0, offsetof(struct acpi_sleep_info, sleep_control)); memset(&acpi_sinfo.sleep_status + 1, 0, (long)(&acpi_sinfo + 1) - (long)(&acpi_sinfo.sleep_status + 1)); }
static int __init acpi_table_get_sdt ( struct acpi_table_rsdp *rsdp) { struct acpi_table_header *header = NULL; unsigned int i, id = 0; if (!rsdp) return -EINVAL; /* First check XSDT (but only on ACPI 2.0-compatible systems) */ if ((rsdp->revision >= 2) && (((struct acpi20_table_rsdp*)rsdp)->xsdt_address)) { struct acpi_table_xsdt *mapped_xsdt = NULL; sdt_pa = ((struct acpi20_table_rsdp*)rsdp)->xsdt_address; /* map in just the header */ header = (struct acpi_table_header *) __acpi_map_table(sdt_pa, sizeof(struct acpi_table_header)); if (!header) { printk(KERN_WARNING PREFIX "Unable to map XSDT header\n"); return -ENODEV; } /* remap in the entire table before processing */ mapped_xsdt = (struct acpi_table_xsdt *) __acpi_map_table(sdt_pa, header->length); if (!mapped_xsdt) { printk(KERN_WARNING PREFIX "Unable to map XSDT\n"); return -ENODEV; } header = &mapped_xsdt->header; if (strncmp(header->signature, "XSDT", 4)) { printk(KERN_WARNING PREFIX "XSDT signature incorrect\n"); return -ENODEV; } if (acpi_table_compute_checksum(header, header->length)) { printk(KERN_WARNING PREFIX "Invalid XSDT checksum\n"); return -ENODEV; } sdt_count = (header->length - sizeof(struct acpi_table_header)) >> 3; if (sdt_count > ACPI_MAX_TABLES) { printk(KERN_WARNING PREFIX "Truncated %lu XSDT entries\n", (sdt_count - ACPI_MAX_TABLES)); sdt_count = ACPI_MAX_TABLES; } for (i = 0; i < sdt_count; i++) sdt_entry[i].pa = (unsigned long) mapped_xsdt->entry[i]; } /* Then check RSDT */ else if (rsdp->rsdt_address) {
for (i = 0; i < sdt_count; i++) sdt_entry[i].pa = (unsigned long) mapped_xsdt->entry[i]; } /* Then check RSDT */ else if (rsdp->rsdt_address) { struct acpi_table_rsdt *mapped_rsdt = NULL; sdt_pa = rsdp->rsdt_address; /* map in just the header */ header = (struct acpi_table_header *) __acpi_map_table(sdt_pa, sizeof(struct acpi_table_header)); if (!header) { printk(KERN_WARNING PREFIX "Unable to map RSDT header\n"); return -ENODEV; } /* remap in the entire table before processing */ mapped_rsdt = (struct acpi_table_rsdt *) __acpi_map_table(sdt_pa, header->length); if (!mapped_rsdt) { printk(KERN_WARNING PREFIX "Unable to map RSDT\n"); return -ENODEV; } header = &mapped_rsdt->header; if (strncmp(header->signature, "RSDT", 4)) {
void __iomem * acpi_os_map_memory(acpi_physical_address phys, acpi_size size) { return __acpi_map_table((unsigned long)phys, size); }