/* 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)); }
/* 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)); }