From 8e6a8737d788ab956c1871d03958ba9b065d1fe5 Mon Sep 17 00:00:00 2001 From: Nate Lawson Date: Tue, 9 Sep 2003 08:31:58 +0000 Subject: [PATCH] Rename FACP to FADT throughout. Update FADT for new fields including pm_profile, pstate_cnt, and cst_cnt. Add acpi_print_gas() for printing various address formats. Print FACS contents. Remove unused code. --- usr.sbin/acpi/acpidump/acpi.c | 233 +++++++++++++++++++++--------- usr.sbin/acpi/acpidump/acpidump.8 | 2 +- usr.sbin/acpi/acpidump/acpidump.c | 2 +- usr.sbin/acpi/acpidump/acpidump.h | 80 +++++----- 4 files changed, 206 insertions(+), 111 deletions(-) diff --git a/usr.sbin/acpi/acpidump/acpi.c b/usr.sbin/acpi/acpidump/acpi.c index ee07f6422789..8e7ec2a3048b 100644 --- a/usr.sbin/acpi/acpidump/acpi.c +++ b/usr.sbin/acpi/acpidump/acpi.c @@ -44,7 +44,8 @@ #define END_COMMENT " */\n" static void acpi_print_string(char *s, size_t length); -static void acpi_handle_facp(struct FACPbody *facp); +static void acpi_print_gas(struct ACPIgas *gas); +static void acpi_handle_fadt(struct FADTbody *fadt); static void acpi_print_cpu(u_char cpu_id); static void acpi_print_local_apic(u_char cpu_id, u_char apic_id, u_int32_t flags); @@ -56,7 +57,8 @@ static void acpi_print_apic(struct MADT_APIC *mp); static void acpi_handle_apic(struct ACPIsdt *sdp); static void acpi_handle_hpet(struct ACPIsdt *sdp); static void acpi_print_sdt(struct ACPIsdt *sdp, int endcomment); -static void acpi_print_facp(struct FACPbody *facp); +static void acpi_print_fadt(struct FADTbody *fadt); +static void acpi_print_facs(struct FACSbody *facs); static void acpi_print_dsdt(struct ACPIsdt *dsdp); static struct ACPIsdt * acpi_map_sdt(vm_offset_t pa); @@ -79,12 +81,52 @@ acpi_print_string(char *s, size_t length) } static void -acpi_handle_facp(struct FACPbody *facp) +acpi_print_gas(struct ACPIgas *gas) { - struct ACPIsdt *dsdp; + switch(gas->address_space_id) { + case ACPI_GAS_MEMORY: + printf("0x%08lx:%u[%u] (Memory)\n", (u_long)gas->address, + gas->bit_offset, gas->bit_width); + break; + case ACPI_GAS_IO: + printf("0x%08lx:%u[%u] (IO)\n", (u_long)gas->address, + gas->bit_offset, gas->bit_width); + break; + case ACPI_GAS_PCI: + printf("%x:%x+%#x (PCI)\n", (uint16_t)(gas->address >> 32), + (uint16_t)((gas->address >> 16) & 0xffff), + (uint16_t)gas->address); + break; + /* XXX How to handle these below? */ + case ACPI_GAS_EMBEDDED: + printf("0x%#x:%u[%u] (EC)\n", (uint16_t)gas->address, + gas->bit_offset, gas->bit_width); + break; + case ACPI_GAS_SMBUS: + printf("0x%#x:%u[%u] (SMBus)\n", (uint16_t)gas->address, + gas->bit_offset, gas->bit_width); + break; + case ACPI_GAS_FIXED: + default: + printf("0x%08lx (?)\n", (u_long)gas->address); + break; + } +} - acpi_print_facp(facp); - dsdp = (struct ACPIsdt *)acpi_map_sdt(facp->dsdt_ptr); +static void +acpi_handle_fadt(struct FADTbody *fadt) +{ + struct ACPIsdt *dsdp; + struct FACSbody *facs; + + acpi_print_fadt(fadt); + + facs = (struct FACSbody *)acpi_map_sdt(fadt->facs_ptr); + if (memcmp(facs->signature, "FACS", 4) != 0 || facs->len < 64) + errx(1, "FACS is corrupt"); + acpi_print_facs(facs); + + dsdp = (struct ACPIsdt *)acpi_map_sdt(fadt->dsdt_ptr); if (acpi_checksum(dsdp, dsdp->len)) errx(1, "DSDT is corrupt"); acpi_print_dsdt(dsdp); @@ -312,83 +354,144 @@ acpi_print_rsdt(struct ACPIsdt *rsdp) printf(END_COMMENT); } +static const char *acpi_pm_profiles[] = { + "Unspecified", "Desktop", "Mobile", "Workstation", + "Enterprise Server", "SOHO Server", "Appliance PC" +}; + static void -acpi_print_facp(struct FACPbody *facp) +acpi_print_fadt(struct FADTbody *fadt) { - char sep; + const char *pm; + char sep; printf(BEGIN_COMMENT); - printf(" FACP:\tDSDT=0x%x\n", facp->dsdt_ptr); - printf("\tINT_MODEL=%s\n", facp->int_model ? "APIC" : "PIC"); - printf("\tSCI_INT=%d\n", facp->sci_int); - printf("\tSMI_CMD=0x%x, ", facp->smi_cmd); - printf("ACPI_ENABLE=0x%x, ", facp->acpi_enable); - printf("ACPI_DISABLE=0x%x, ", facp->acpi_disable); - printf("S4BIOS_REQ=0x%x\n", facp->s4biosreq); - if (facp->pm1a_evt_blk) + printf(" FADT:\tFACS=0x%x, DSDT=0x%x\n", fadt->facs_ptr, + fadt->dsdt_ptr); + printf("\tINT_MODEL=%s\n", fadt->int_model ? "APIC" : "PIC"); + if (fadt->pm_profile >= sizeof(acpi_pm_profiles) / sizeof(char *)) + pm = "Reserved"; + else + pm = acpi_pm_profiles[fadt->pm_profile]; + printf("\tPreferred_PM_Profile=%s (%d)\n", pm, fadt->pm_profile); + printf("\tSCI_INT=%d\n", fadt->sci_int); + printf("\tSMI_CMD=0x%x, ", fadt->smi_cmd); + printf("ACPI_ENABLE=0x%x, ", fadt->acpi_enable); + printf("ACPI_DISABLE=0x%x, ", fadt->acpi_disable); + printf("S4BIOS_REQ=0x%x\n", fadt->s4biosreq); + printf("\tPSTATE_CNT=0x%x\n", fadt->pstate_cnt); + if (fadt->pm1a_evt_blk != 0) printf("\tPM1a_EVT_BLK=0x%x-0x%x\n", - facp->pm1a_evt_blk, - facp->pm1a_evt_blk + facp->pm1_evt_len - 1); - if (facp->pm1b_evt_blk) + fadt->pm1a_evt_blk, + fadt->pm1a_evt_blk + fadt->pm1_evt_len - 1); + if (fadt->pm1b_evt_blk != 0) printf("\tPM1b_EVT_BLK=0x%x-0x%x\n", - facp->pm1b_evt_blk, - facp->pm1b_evt_blk + facp->pm1_evt_len - 1); - if (facp->pm1a_cnt_blk) + fadt->pm1b_evt_blk, + fadt->pm1b_evt_blk + fadt->pm1_evt_len - 1); + if (fadt->pm1a_cnt_blk != 0) printf("\tPM1a_CNT_BLK=0x%x-0x%x\n", - facp->pm1a_cnt_blk, - facp->pm1a_cnt_blk + facp->pm1_cnt_len - 1); - if (facp->pm1b_cnt_blk) + fadt->pm1a_cnt_blk, + fadt->pm1a_cnt_blk + fadt->pm1_cnt_len - 1); + if (fadt->pm1b_cnt_blk != 0) printf("\tPM1b_CNT_BLK=0x%x-0x%x\n", - facp->pm1b_cnt_blk, - facp->pm1b_cnt_blk + facp->pm1_cnt_len - 1); - if (facp->pm2_cnt_blk) + fadt->pm1b_cnt_blk, + fadt->pm1b_cnt_blk + fadt->pm1_cnt_len - 1); + if (fadt->pm2_cnt_blk != 0) printf("\tPM2_CNT_BLK=0x%x-0x%x\n", - facp->pm2_cnt_blk, - facp->pm2_cnt_blk + facp->pm2_cnt_len - 1); - if (facp->pm_tmr_blk) + fadt->pm2_cnt_blk, + fadt->pm2_cnt_blk + fadt->pm2_cnt_len - 1); + if (fadt->pm_tmr_blk != 0) printf("\tPM2_TMR_BLK=0x%x-0x%x\n", - facp->pm_tmr_blk, - facp->pm_tmr_blk + facp->pm_tmr_len - 1); - if (facp->gpe0_blk) - printf("\tPM2_GPE0_BLK=0x%x-0x%x\n", - facp->gpe0_blk, - facp->gpe0_blk + facp->gpe0_len - 1); - if (facp->gpe1_blk) - printf("\tPM2_GPE1_BLK=0x%x-0x%x, GPE1_BASE=%d\n", - facp->gpe1_blk, - facp->gpe1_blk + facp->gpe1_len - 1, - facp->gpe1_base); + fadt->pm_tmr_blk, + fadt->pm_tmr_blk + fadt->pm_tmr_len - 1); + if (fadt->gpe0_blk != 0) + printf("\tGPE0_BLK=0x%x-0x%x\n", + fadt->gpe0_blk, + fadt->gpe0_blk + fadt->gpe0_len - 1); + if (fadt->gpe1_blk != 0) + printf("\tGPE1_BLK=0x%x-0x%x, GPE1_BASE=%d\n", + fadt->gpe1_blk, + fadt->gpe1_blk + fadt->gpe1_len - 1, + fadt->gpe1_base); + if (fadt->cst_cnt != 0) + printf("\tCST_CNT=0x%x\n", fadt->cst_cnt); printf("\tP_LVL2_LAT=%dms, P_LVL3_LAT=%dms\n", - facp->p_lvl2_lat, facp->p_lvl3_lat); + fadt->p_lvl2_lat, fadt->p_lvl3_lat); printf("\tFLUSH_SIZE=%d, FLUSH_STRIDE=%d\n", - facp->flush_size, facp->flush_stride); + fadt->flush_size, fadt->flush_stride); printf("\tDUTY_OFFSET=%d, DUTY_WIDTH=%d\n", - facp->duty_off, facp->duty_width); + fadt->duty_off, fadt->duty_width); printf("\tDAY_ALRM=%d, MON_ALRM=%d, CENTURY=%d\n", - facp->day_alrm, facp->mon_alrm, facp->century); - printf("\tFlags="); - sep = '{'; + fadt->day_alrm, fadt->mon_alrm, fadt->century); -#define PRINTFLAG(xx) do { \ - if (facp->flags & ACPI_FACP_FLAG_## xx) { \ - printf("%c%s", sep, #xx); sep = ','; \ - } \ +#define PRINTFLAG(var, flag) do { \ + if ((var) & FADT_FLAG_## flag) { \ + printf("%c%s", sep, #flag); sep = ','; \ + } \ } while (0) - PRINTFLAG(WBINVD); - PRINTFLAG(WBINVD_FLUSH); - PRINTFLAG(PROC_C1); - PRINTFLAG(P_LVL2_UP); - PRINTFLAG(PWR_BUTTON); - PRINTFLAG(SLP_BUTTON); - PRINTFLAG(FIX_RTC); - PRINTFLAG(RTC_S4); - PRINTFLAG(TMR_VAL_EXT); - PRINTFLAG(DCK_CAP); + printf("\tIAPC_BOOT_ARCH="); + sep = '{'; + PRINTFLAG(fadt->iapc_boot_arch, LEGACY_DEV); + PRINTFLAG(fadt->iapc_boot_arch, 8042); + printf("}\n"); + + printf("\tFlags="); + sep = '{'; + PRINTFLAG(fadt->flags, WBINVD); + PRINTFLAG(fadt->flags, WBINVD_FLUSH); + PRINTFLAG(fadt->flags, PROC_C1); + PRINTFLAG(fadt->flags, P_LVL2_UP); + PRINTFLAG(fadt->flags, PWR_BUTTON); + PRINTFLAG(fadt->flags, SLP_BUTTON); + PRINTFLAG(fadt->flags, FIX_RTC); + PRINTFLAG(fadt->flags, RTC_S4); + PRINTFLAG(fadt->flags, TMR_VAL_EXT); + PRINTFLAG(fadt->flags, DCK_CAP); + PRINTFLAG(fadt->flags, RESET_REG); + PRINTFLAG(fadt->flags, SEALED_CASE); + PRINTFLAG(fadt->flags, HEADLESS); + PRINTFLAG(fadt->flags, CPU_SW_SLP); + printf("}\n"); #undef PRINTFLAG + if (fadt->flags & FADT_FLAG_RESET_REG) { + printf("\tRESET_REG="); + acpi_print_gas(&fadt->reset_reg); + printf(", RESET_VALUE=%#x\n", fadt->reset_value); + } + + printf(END_COMMENT); +} + +static void +acpi_print_facs(struct FACSbody *facs) +{ + printf(BEGIN_COMMENT); + printf(" FACS:\tLength=%u, ", facs->len); + printf("HwSig=0x%08x, ", facs->hw_sig); + printf("Firm_Wake_Vec=0x%08x\n", facs->firm_wake_vec); + + printf("\tGlobal_Lock={"); + if (facs->global_lock != 0) { + if (facs->global_lock & FACS_FLAG_LOCK_PENDING) + printf("PENDING,"); + if (facs->global_lock & FACS_FLAG_LOCK_OWNED) + printf("OWNED"); + } printf("}\n"); + + printf("\tFlags={"); + if (facs->flags & FACS_FLAG_S4BIOS_F) + printf("S4BIOS"); + printf("}\n"); + + if (facs->x_firm_wake_vec != 0) { + printf("\tX_Firm_Wake_Vec=%08lx\n", + (u_long)facs->x_firm_wake_vec); + } + printf(END_COMMENT); } @@ -447,7 +550,7 @@ acpi_handle_rsdt(struct ACPIsdt *rsdp) if (acpi_checksum(sdp, sdp->len)) errx(1, "RSDT entry %d is corrupt", i); if (!memcmp(sdp->signature, "FACP", 4)) - acpi_handle_facp((struct FACPbody *) sdp->body); + acpi_handle_fadt((struct FADTbody *) sdp->body); else if (!memcmp(sdp->signature, "APIC", 4)) acpi_handle_apic(sdp); else if (!memcmp(sdp->signature, "HPET", 4)) @@ -565,11 +668,11 @@ sdt_from_rsdt(struct ACPIsdt *rsdt, const char *sig) } struct ACPIsdt * -dsdt_from_facp(struct FACPbody *facp) +dsdt_from_fadt(struct FADTbody *fadt) { struct ACPIsdt *sdt; - sdt = (struct ACPIsdt *)acpi_map_sdt(facp->dsdt_ptr); + sdt = (struct ACPIsdt *)acpi_map_sdt(fadt->dsdt_ptr); if (acpi_checksum(sdt, sdt->len)) errx(1, "DSDT is corrupt\n"); return (sdt); diff --git a/usr.sbin/acpi/acpidump/acpidump.8 b/usr.sbin/acpi/acpidump/acpidump.8 index c2b7f5a79b18..06b366e52425 100644 --- a/usr.sbin/acpi/acpidump/acpidump.8 +++ b/usr.sbin/acpi/acpidump/acpidump.8 @@ -151,7 +151,7 @@ Verbose messages are enabled. .Sh BUGS In the current implementation, .Nm -doesn't dump the Firmware ACPI Control Structure (FACS), +doesn't dump the Secondary System Descriptor Table (SSDT), Embedded Controller Descriptor Table (ECDT), or BOOT structures. diff --git a/usr.sbin/acpi/acpidump/acpidump.c b/usr.sbin/acpi/acpidump/acpidump.c index 8e27a4ea7713..269a595cbd43 100644 --- a/usr.sbin/acpi/acpidump/acpidump.c +++ b/usr.sbin/acpi/acpidump/acpidump.c @@ -116,7 +116,7 @@ main(int argc, char *argv[]) /* Translate RSDT to DSDT pointer */ if (dsdt_input_file == NULL) { sdt = sdt_from_rsdt(sdt, "FACP"); - sdt = dsdt_from_facp((struct FACPbody *)sdt->body); + sdt = dsdt_from_fadt((struct FADTbody *)sdt->body); } /* Dump the DSDT to a file */ diff --git a/usr.sbin/acpi/acpidump/acpidump.h b/usr.sbin/acpi/acpidump/acpidump.h index 31aeb282ea75..09ebfcec0d01 100644 --- a/usr.sbin/acpi/acpidump/acpidump.h +++ b/usr.sbin/acpi/acpidump/acpidump.h @@ -39,9 +39,9 @@ struct ACPIgas { #define ACPI_GAS_EMBEDDED 3 #define ACPI_GAS_SMBUS 4 #define ACPI_GAS_FIXED 0x7f - u_int8_t register_bit_width; - u_int8_t register_bit_offset; - u_int8_t res; + u_int8_t bit_width; + u_int8_t bit_offset; + u_int8_t _reserved; u_int64_t address; } __packed; @@ -74,19 +74,19 @@ struct ACPIsdt { } __packed; /* Fixed ACPI Description Table (body) */ -struct FACPbody { +struct FADTbody { u_int32_t facs_ptr; u_int32_t dsdt_ptr; u_int8_t int_model; -#define ACPI_FACP_INTMODEL_PIC 0 /* Standard PC-AT PIC */ -#define ACPI_FACP_INTMODEL_APIC 1 /* Multiple APIC */ - u_char reserved1; +#define ACPI_FADT_INTMODEL_PIC 0 /* Standard PC-AT PIC */ +#define ACPI_FADT_INTMODEL_APIC 1 /* Multiple APIC */ + u_int8_t pm_profile; u_int16_t sci_int; u_int32_t smi_cmd; u_int8_t acpi_enable; u_int8_t acpi_disable; u_int8_t s4biosreq; - u_int8_t reserved2; + u_int8_t pstate_cnt; u_int32_t pm1a_evt_blk; u_int32_t pm1b_evt_blk; u_int32_t pm1a_cnt_blk; @@ -102,7 +102,7 @@ struct FACPbody { u_int8_t gpe0_len; u_int8_t gpe1_len; u_int8_t gpe1_base; - u_int8_t reserved3; + u_int8_t cst_cnt; u_int16_t p_lvl2_lat; u_int16_t p_lvl3_lat; u_int16_t flush_size; @@ -113,18 +113,24 @@ struct FACPbody { u_int8_t mon_alrm; u_int8_t century; u_int16_t iapc_boot_arch; +#define FADT_FLAG_LEGACY_DEV 1 /* System has legacy devices */ +#define FADT_FLAG_8042 2 /* 8042 keyboard controller */ u_char reserved4[1]; u_int32_t flags; -#define ACPI_FACP_FLAG_WBINVD 1 /* WBINVD is correctly supported */ -#define ACPI_FACP_FLAG_WBINVD_FLUSH 2 /* WBINVD flushes caches */ -#define ACPI_FACP_FLAG_PROC_C1 4 /* C1 power state supported */ -#define ACPI_FACP_FLAG_P_LVL2_UP 8 /* C2 power state works on SMP */ -#define ACPI_FACP_FLAG_PWR_BUTTON 16 /* Power button uses control method */ -#define ACPI_FACP_FLAG_SLP_BUTTON 32 /* Sleep button uses control method */ -#define ACPI_FACP_FLAG_FIX_RTC 64 /* RTC wakeup not supported */ -#define ACPI_FACP_FLAG_RTC_S4 128 /* RTC can wakeup from S4 state */ -#define ACPI_FACP_FLAG_TMR_VAL_EXT 256 /* TMR_VAL is 32bit */ -#define ACPI_FACP_FLAG_DCK_CAP 512 /* Can support docking */ +#define FADT_FLAG_WBINVD 1 /* WBINVD is correctly supported */ +#define FADT_FLAG_WBINVD_FLUSH 2 /* WBINVD flushes caches */ +#define FADT_FLAG_PROC_C1 4 /* C1 power state supported */ +#define FADT_FLAG_P_LVL2_UP 8 /* C2 power state works on SMP */ +#define FADT_FLAG_PWR_BUTTON 16 /* Power button uses control method */ +#define FADT_FLAG_SLP_BUTTON 32 /* Sleep button uses control method */ +#define FADT_FLAG_FIX_RTC 64 /* RTC wakeup not supported */ +#define FADT_FLAG_RTC_S4 128 /* RTC can wakeup from S4 state */ +#define FADT_FLAG_TMR_VAL_EXT 256 /* TMR_VAL is 32bit */ +#define FADT_FLAG_DCK_CAP 512 /* Can support docking */ +#define FADT_FLAG_RESET_REG 1024 /* Supports RESET_REG */ +#define FADT_FLAG_SEALED_CASE 2048 /* Case cannot be opened */ +#define FADT_FLAG_HEADLESS 4096 /* No monitor */ +#define FADT_FLAG_CPU_SW_SLP 8192 /* Supports CPU software sleep */ struct ACPIgas reset_reg; u_int8_t reset_value; u_int8_t reserved5[3]; @@ -141,22 +147,23 @@ struct FACPbody { } __packed; /* Firmware ACPI Control Structure */ -struct FACS { +struct FACSbody { u_char signature[4]; u_int32_t len; - u_char hard_sig[4]; + u_int32_t hw_sig; /* * NOTE This should be filled with physical address below 1MB!! * sigh.... */ u_int32_t firm_wake_vec; - u_int32_t g_lock; /* bit field */ - /* 5.2.6.1 Global Lock */ -#define ACPI_GLOBAL_LOCK_PENDING 1 -#define ACPI_GLOBAL_LOCK_OWNED 2 - u_int32_t flags; /* bit field */ -#define ACPI_FACS_FLAG_S4BIOS_F 1 /* Supports S4BIOS_SEQ */ - char reserved[40]; + u_int32_t global_lock; +#define FACS_FLAG_LOCK_PENDING 1 /* 5.2.6.1 Global Lock */ +#define FACS_FLAG_LOCK_OWNED 2 + u_int32_t flags; +#define FACS_FLAG_S4BIOS_F 1 /* Supports S4BIOS_SEQ */ + u_int64_t x_firm_wake_vec; + u_int8_t version; + char reserved[31]; } __packed; struct MADT_local_apic { @@ -277,21 +284,6 @@ struct HPETbody { u_int16_t clock_tick __packed; } __packed; -#if 0 -void *acpi_map_physical(vm_offset_t, size_t); -struct ACPIrsdp *acpi_find_rsd_ptr(void); -int acpi_checksum(void *, size_t); -struct ACPIsdt *acpi_map_sdt(vm_offset_t); -void acpi_print_rsd_ptr(struct ACPIrsdp *); -void acpi_print_sdt(struct ACPIsdt *); -void acpi_print_rsdt(struct ACPIsdt *); -void acpi_print_facp(struct FACPbody *); -void acpi_print_dsdt(struct ACPIsdt *); -void acpi_handle_rsdt(struct ACPIsdt *); -void acpi_load_dsdt(char *, u_int8_t **, u_int8_t **); -void acpi_dump_dsdt(u_int8_t *, u_int8_t *); -#endif - /* Find and map the RSD PTR structure and return it for parsing */ struct ACPIsdt *sdt_load_devmem(void); @@ -314,7 +306,7 @@ void aml_disassemble(struct ACPIsdt *); struct ACPIrsdp *acpi_find_rsd_ptr(void); void * acpi_map_physical(vm_offset_t, size_t); struct ACPIsdt *sdt_from_rsdt(struct ACPIsdt *, const char *); -struct ACPIsdt *dsdt_from_facp(struct FACPbody *); +struct ACPIsdt *dsdt_from_fadt(struct FADTbody *); int acpi_checksum(void *, size_t); /* Command line flags */