acpi.c revision 66490
18871Srgrimes/*- 21558Srgrimes * Copyright (c) 1998 Doug Rabson 31558Srgrimes * Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org> 41558Srgrimes * All rights reserved. 51558Srgrimes * 61558Srgrimes * Redistribution and use in source and binary forms, with or without 71558Srgrimes * modification, are permitted provided that the following conditions 81558Srgrimes * are met: 91558Srgrimes * 1. Redistributions of source code must retain the above copyright 101558Srgrimes * notice, this list of conditions and the following disclaimer. 111558Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 121558Srgrimes * notice, this list of conditions and the following disclaimer in the 131558Srgrimes * documentation and/or other materials provided with the distribution. 141558Srgrimes * 151558Srgrimes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 161558Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 171558Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 181558Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 191558Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 201558Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 211558Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 221558Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 231558Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 241558Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 251558Srgrimes * SUCH DAMAGE. 261558Srgrimes * 271558Srgrimes * $Id: acpi.c,v 1.4 2000/08/09 14:47:52 iwasaki Exp $ 281558Srgrimes * $FreeBSD: head/usr.sbin/acpi/acpidump/acpi.c 66490 2000-09-30 20:13:57Z msmith $ 291558Srgrimes */ 301558Srgrimes 311558Srgrimes#include <sys/param.h> 321558Srgrimes#include <sys/stat.h> 331558Srgrimes 341558Srgrimes#include <assert.h> 3541477Sjulian#include <err.h> 3623675Speter#include <fcntl.h> 3741477Sjulian#include <stdio.h> 3841477Sjulian#include <unistd.h> 3950476Speter 401558Srgrimes#include <dev/acpi/acpireg.h> 411558Srgrimes 421558Srgrimes#include "acpidump.h" 4362668Smckusick 4423675Speterstatic void 451558Srgrimesacpi_print_string(char *s, size_t length) 461558Srgrimes{ 471558Srgrimes int c; 4823675Speter 4923675Speter /* Trim trailing spaces and NULLs */ 501558Srgrimes while (length > 0 && (s[length - 1] == ' ' || s[length - 1] == '\0')) 5123675Speter length--; 521558Srgrimes 531558Srgrimes while (length--) { 5423675Speter c = *s++; 5523675Speter putchar(c); 5641474Sjulian } 571558Srgrimes} 5823675Speter 597585Sbdestatic void 607585Sbdeacpi_handle_dsdt(struct ACPIsdt *dsdp) 611558Srgrimes{ 621558Srgrimes u_int8_t *dp; 6341474Sjulian u_int8_t *end; 641558Srgrimes 6541474Sjulian acpi_print_dsdt(dsdp); 6641474Sjulian dp = (u_int8_t *)dsdp->body; 671558Srgrimes end = (u_int8_t *)dsdp + dsdp->len; 681558Srgrimes asl_dump_objectlist(&dp, end, 0); 691558Srgrimes assert(dp == end); 701558Srgrimes} 711558Srgrimes 721558Srgrimesstatic void 731558Srgrimesacpi_handle_facp(struct FACPbody *facp) 741558Srgrimes{ 751558Srgrimes struct ACPIsdt *dsdp; 761558Srgrimes 771558Srgrimes acpi_print_facp(facp); 781558Srgrimes dsdp = (struct ACPIsdt *) acpi_map_sdt(facp->dsdt_ptr); 791558Srgrimes if (acpi_checksum(dsdp, dsdp->len)) 801558Srgrimes errx(1, "DSDT is corrupt\n"); 8169800Stomsoft acpi_handle_dsdt(dsdp); 8269800Stomsoft aml_dump(dsdp->body, dsdp->len - SIZEOF_SDT_HDR); 8369800Stomsoft} 8469800Stomsoft 8569800Stomsoft/* 861558Srgrimes * Public interfaces 871558Srgrimes */ 881558Srgrimes 8923675Spetervoid 901558Srgrimesacpi_print_sdt(struct ACPIsdt *sdp) 911558Srgrimes{ 921558Srgrimes 9341474Sjulian acpi_print_string(sdp->signature, 4); 9441474Sjulian printf(": Lenth=%d, Revision=%d, Checksum=%d,\n", 9541474Sjulian sdp->len, sdp->rev, sdp->check); 9641474Sjulian printf("\tOEMID="); 9741474Sjulian acpi_print_string(sdp->oemid, 6); 9841474Sjulian printf(", OEM Table ID="); 9941474Sjulian acpi_print_string(sdp->oemtblid, 8); 10041474Sjulian printf(", OEM Revision=0x%x,\n", sdp->oemrev); 10141474Sjulian printf("\tCreator ID="); 10241474Sjulian acpi_print_string(sdp->creator, 4); 10341474Sjulian printf(", Creator Revision=0x%x\n", sdp->crerev); 10441474Sjulian} 10541474Sjulian 10641474Sjulianvoid 10741474Sjulianacpi_print_rsdt(struct ACPIsdt *rsdp) 10841474Sjulian{ 10941474Sjulian int i, entries; 11041474Sjulian 11141474Sjulian acpi_print_sdt(rsdp); 11241474Sjulian entries = (rsdp->len - SIZEOF_SDT_HDR) / sizeof(u_int32_t); 11341474Sjulian printf("\tEntries={ "); 11441474Sjulian for (i = 0; i < entries; i++) { 11541474Sjulian if (i > 0) 11641474Sjulian printf(", "); 11741474Sjulian printf("0x%08x", rsdp->body[i]); 11841474Sjulian } 11941474Sjulian printf(" }\n"); 12041474Sjulian} 12141474Sjulian 12241474Sjulianvoid 12341474Sjulianacpi_print_facp(struct FACPbody *facp) 12441474Sjulian{ 12541474Sjulian char sep; 12641474Sjulian 12741474Sjulian printf("\tDSDT=0x%x\n", facp->dsdt_ptr); 12841474Sjulian printf("\tINT_MODEL=%s\n", facp->int_model ? "APIC" : "PIC"); 12941474Sjulian printf("\tSCI_INT=%d\n", facp->sci_int); 13041474Sjulian printf("\tSMI_CMD=0x%x, ", facp->smi_cmd); 13141474Sjulian printf("ACPI_ENABLE=0x%x, ", facp->acpi_enable); 13241474Sjulian printf("ACPI_DISABLE=0x%x, ", facp->acpi_disable); 13341474Sjulian printf("S4BIOS_REQ=0x%x\n", facp->s4biosreq); 13441474Sjulian if (facp->pm1a_evt_blk) 13541474Sjulian printf("\tPM1a_EVT_BLK=0x%x-0x%x\n", 13641474Sjulian facp->pm1a_evt_blk, 13741474Sjulian facp->pm1a_evt_blk + facp->pm1_evt_len - 1); 13841474Sjulian if (facp->pm1b_evt_blk) 13941474Sjulian printf("\tPM1b_EVT_BLK=0x%x-0x%x\n", 1401558Srgrimes facp->pm1b_evt_blk, 14141474Sjulian facp->pm1b_evt_blk + facp->pm1_evt_len - 1); 1421558Srgrimes if (facp->pm1a_cnt_blk) 1431558Srgrimes printf("\tPM1a_CNT_BLK=0x%x-0x%x\n", 14441474Sjulian facp->pm1a_cnt_blk, 14541474Sjulian facp->pm1a_cnt_blk + facp->pm1_cnt_len - 1); 14641474Sjulian if (facp->pm1b_cnt_blk) 14741474Sjulian printf("\tPM1b_CNT_BLK=0x%x-0x%x\n", 14841474Sjulian facp->pm1b_cnt_blk, 14941474Sjulian facp->pm1b_cnt_blk + facp->pm1_cnt_len - 1); 15041474Sjulian if (facp->pm2_cnt_blk) 15141474Sjulian printf("\tPM2_CNT_BLK=0x%x-0x%x\n", 15241474Sjulian facp->pm2_cnt_blk, 15341474Sjulian facp->pm2_cnt_blk + facp->pm2_cnt_len - 1); 15441474Sjulian if (facp->pm_tmr_blk) 15541474Sjulian printf("\tPM2_TMR_BLK=0x%x-0x%x\n", 15641474Sjulian facp->pm_tmr_blk, 15741474Sjulian facp->pm_tmr_blk + facp->pm_tmr_len - 1); 15841474Sjulian if (facp->gpe0_blk) 15941474Sjulian printf("\tPM2_GPE0_BLK=0x%x-0x%x\n", 16041474Sjulian facp->gpe0_blk, 16141474Sjulian facp->gpe0_blk + facp->gpe0_len - 1); 16241474Sjulian if (facp->gpe1_blk) 16341474Sjulian printf("\tPM2_GPE1_BLK=0x%x-0x%x, GPE1_BASE=%d\n", 16441474Sjulian facp->gpe1_blk, 16541474Sjulian facp->gpe1_blk + facp->gpe1_len - 1, 16641474Sjulian facp->gpe1_base); 16741474Sjulian printf("\tP_LVL2_LAT=%dms, P_LVL3_LAT=%dms\n", 16841474Sjulian facp->p_lvl2_lat, facp->p_lvl3_lat); 1691558Srgrimes printf("\tFLUSH_SIZE=%d, FLUSH_STRIDE=%d\n", 1701558Srgrimes facp->flush_size, facp->flush_stride); 1711558Srgrimes printf("\tDUTY_OFFSET=%d, DUTY_WIDTH=%d\n", 1721558Srgrimes facp->duty_off, facp->duty_width); 17323675Speter printf("\tDAY_ALRM=%d, MON_ALRM=%d, CENTURY=%d\n", 1741558Srgrimes facp->day_alrm, facp->mon_alrm, facp->century); 1751558Srgrimes printf("\tFlags="); 1761558Srgrimes sep = '{'; 1771558Srgrimes 1781558Srgrimes#define PRINTFLAG(xx) do { \ 1791558Srgrimes if (facp->flags & ACPI_FACP_FLAG_## xx) { \ 1801558Srgrimes printf("%c%s", sep, #xx); sep = ','; \ 1811558Srgrimes } \ 1822603Sdg} while (0) 1831558Srgrimes 1841558Srgrimes PRINTFLAG(WBINVD); 1851558Srgrimes PRINTFLAG(WBINVD_FLUSH); 1861558Srgrimes PRINTFLAG(PROC_C1); 18723675Speter PRINTFLAG(P_LVL2_UP); 18823675Speter PRINTFLAG(PWR_BUTTON); 18923675Speter PRINTFLAG(SLP_BUTTON); 19023675Speter PRINTFLAG(FIX_RTC); 1911558Srgrimes PRINTFLAG(RTC_S4); 1921558Srgrimes PRINTFLAG(TMR_VAL_EXT); 1931558Srgrimes PRINTFLAG(DCK_CAP); 1941558Srgrimes 1951558Srgrimes#undef PRINTFLAG 1961558Srgrimes 1971558Srgrimes printf("}\n"); 1981558Srgrimes} 19941474Sjulian 2001558Srgrimesvoid 2011558Srgrimesacpi_print_dsdt(struct ACPIsdt *dsdp) 2021558Srgrimes{ 2031558Srgrimes 20423999Speter acpi_print_sdt(dsdp); 20523999Speter} 2061558Srgrimes 2071558Srgrimesint 2081558Srgrimesacpi_checksum(void *p, size_t length) 2091558Srgrimes{ 2101558Srgrimes u_int8_t *bp; 2111558Srgrimes u_int8_t sum; 2121558Srgrimes 2131558Srgrimes bp = p; 2141558Srgrimes sum = 0; 2151558Srgrimes while (length--) 21663003Smckusick sum += *bp++; 21763003Smckusick 21863003Smckusick return (sum); 21963003Smckusick} 22063003Smckusick 22163003Smckusickstruct ACPIsdt * 2221558Srgrimesacpi_map_sdt(vm_offset_t pa) 2231558Srgrimes{ 2241558Srgrimes struct ACPIsdt *sp; 2251558Srgrimes 2261558Srgrimes sp = acpi_map_physical(pa, sizeof(struct ACPIsdt)); 2271558Srgrimes sp = acpi_map_physical(pa, sp->len); 2281558Srgrimes return (sp); 2291558Srgrimes} 2301558Srgrimes 2311558Srgrimesvoid 2321558Srgrimesacpi_print_rsd_ptr(struct ACPIrsdp *rp) 2331558Srgrimes{ 2341558Srgrimes 2352603Sdg printf("RSD PTR: Checksum=%d, OEMID=", rp->sum); 2361558Srgrimes acpi_print_string(rp->oem, 6); 2371558Srgrimes printf(", RsdtAddress=0x%08x\n", rp->addr); 2382603Sdg} 23923675Speter 2401558Srgrimesvoid 2411558Srgrimesacpi_handle_rsdt(struct ACPIsdt *rsdp) 24237236Sbde{ 24341474Sjulian int i; 2441558Srgrimes int entries; 2451558Srgrimes struct ACPIsdt *sdp; 24623675Speter 2471558Srgrimes entries = (rsdp->len - SIZEOF_SDT_HDR) / sizeof(u_int32_t); 2481558Srgrimes acpi_print_rsdt(rsdp); 2491558Srgrimes for (i = 0; i < entries; i++) { 2501558Srgrimes sdp = (struct ACPIsdt *) acpi_map_sdt(rsdp->body[i]); 2511558Srgrimes if (acpi_checksum(sdp, sdp->len)) 2521558Srgrimes errx(1, "RSDT entry %d is corrupt\n", i); 2531558Srgrimes if (!memcmp(sdp->signature, "FACP", 4)) { 25441474Sjulian acpi_handle_facp((struct FACPbody *) sdp->body); 25523675Speter } else { 2561558Srgrimes acpi_print_sdt(sdp); 2571558Srgrimes } 2581558Srgrimes } 2591558Srgrimes} 2601558Srgrimes