acpi.c revision 65285
1279377Simp/*- 2279377Simp * Copyright (c) 1998 Doug Rabson 3279377Simp * Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org> 4279377Simp * All rights reserved. 5279377Simp * 6279377Simp * Redistribution and use in source and binary forms, with or without 7279377Simp * modification, are permitted provided that the following conditions 8279377Simp * are met: 9279377Simp * 1. Redistributions of source code must retain the above copyright 10279377Simp * notice, this list of conditions and the following disclaimer. 11279377Simp * 2. Redistributions in binary form must reproduce the above copyright 12279377Simp * notice, this list of conditions and the following disclaimer in the 13279377Simp * documentation and/or other materials provided with the distribution. 14279377Simp * 15279377Simp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16279377Simp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17279377Simp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18279377Simp * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19279377Simp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20279377Simp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21279377Simp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22279377Simp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23279377Simp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24279377Simp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25279377Simp * SUCH DAMAGE. 26279377Simp * 27279377Simp * $Id: acpi.c,v 1.4 2000/08/09 14:47:52 iwasaki Exp $ 28279377Simp * $FreeBSD: cvs2svn/branches/ACPI4FREEBSD/usr.sbin/acpi/acpidump/acpi.c 65285 2000-08-31 14:42:32Z iwasaki $ 29279377Simp */ 30279377Simp 31279377Simp#include <sys/param.h> 32279377Simp#include <sys/stat.h> 33279377Simp#include <sys/acpi.h> 34279377Simp 35279377Simp#include <assert.h> 36279377Simp#include <err.h> 37279377Simp#include <fcntl.h> 38279377Simp#include <stdio.h> 39279377Simp#include <unistd.h> 40279377Simp 41279377Simp#include "acpidump.h" 42279377Simp 43279377Simpstatic void 44279377Simpacpi_print_string(char *s, size_t length) 45279377Simp{ 46279377Simp int c; 47279377Simp 48279377Simp /* Trim trailing spaces and NULLs */ 49279377Simp while (length > 0 && (s[length - 1] == ' ' || s[length - 1] == '\0')) 50279377Simp length--; 51279377Simp 52279377Simp while (length--) { 53279377Simp c = *s++; 54279377Simp putchar(c); 55279377Simp } 56279377Simp} 57279377Simp 58279377Simpstatic void 59279377Simpacpi_handle_dsdt(struct ACPIsdt *dsdp) 60279377Simp{ 61279377Simp u_int8_t *dp; 62279377Simp u_int8_t *end; 63295436Sandrew 64295436Sandrew acpi_print_dsdt(dsdp); 65295436Sandrew dp = (u_int8_t *)dsdp->body; 66279377Simp end = (u_int8_t *)dsdp + dsdp->len; 67295436Sandrew asl_dump_objectlist(&dp, end, 0); 68295436Sandrew assert(dp == end); 69295436Sandrew} 70295436Sandrew 71279377Simpstatic void 72295436Sandrewacpi_handle_facp(struct FACPbody *facp) 73295436Sandrew{ 74295436Sandrew struct ACPIsdt *dsdp; 75295436Sandrew 76279377Simp acpi_print_facp(facp); 77295436Sandrew dsdp = (struct ACPIsdt *) acpi_map_sdt(facp->dsdt_ptr); 78295436Sandrew if (acpi_checksum(dsdp, dsdp->len)) 79279377Simp errx(1, "DSDT is corrupt\n"); 80295436Sandrew acpi_handle_dsdt(dsdp); 81295436Sandrew aml_dump(dsdp->body, dsdp->len - SIZEOF_SDT_HDR); 82295436Sandrew} 83279377Simp 84295436Sandrew/* 85295436Sandrew * Public interfaces 86295436Sandrew */ 87295436Sandrew 88295436Sandrewvoid 89295436Sandrewacpi_print_sdt(struct ACPIsdt *sdp) 90279377Simp{ 91295436Sandrew 92295436Sandrew acpi_print_string(sdp->signature, 4); 93295436Sandrew printf(": Lenth=%d, Revision=%d, Checksum=%d,\n", 94279377Simp sdp->len, sdp->rev, sdp->check); 95295436Sandrew printf("\tOEMID="); 96295436Sandrew acpi_print_string(sdp->oemid, 6); 97295436Sandrew printf(", OEM Table ID="); 98295436Sandrew acpi_print_string(sdp->oemtblid, 8); 99279377Simp printf(", OEM Revision=0x%x,\n", sdp->oemrev); 100295436Sandrew printf("\tCreator ID="); 101295436Sandrew acpi_print_string(sdp->creator, 4); 102295436Sandrew printf(", Creator Revision=0x%x\n", sdp->crerev); 103295436Sandrew} 104295436Sandrew 105279377Simpvoid 106295436Sandrewacpi_print_rsdt(struct ACPIsdt *rsdp) 107279377Simp{ 108295436Sandrew int i, entries; 109295436Sandrew 110295436Sandrew acpi_print_sdt(rsdp); 111295436Sandrew entries = (rsdp->len - SIZEOF_SDT_HDR) / sizeof(u_int32_t); 112279377Simp printf("\tEntries={ "); 113295436Sandrew for (i = 0; i < entries; i++) { 114295436Sandrew if (i > 0) 115295436Sandrew printf(", "); 116295436Sandrew printf("0x%08x", rsdp->body[i]); 117295436Sandrew } 118295436Sandrew printf(" }\n"); 119295436Sandrew} 120279377Simp 121295436Sandrewvoid 122295436Sandrewacpi_print_facp(struct FACPbody *facp) 123295436Sandrew{ 124295436Sandrew char sep; 125295436Sandrew 126279377Simp printf("\tDSDT=0x%x\n", facp->dsdt_ptr); 127295436Sandrew printf("\tINT_MODEL=%s\n", facp->int_model ? "APIC" : "PIC"); 128295436Sandrew printf("\tSCI_INT=%d\n", facp->sci_int); 129295436Sandrew printf("\tSMI_CMD=0x%x, ", facp->smi_cmd); 130279377Simp printf("ACPI_ENABLE=0x%x, ", facp->acpi_enable); 131295436Sandrew printf("ACPI_DISABLE=0x%x, ", facp->acpi_disable); 132295436Sandrew printf("S4BIOS_REQ=0x%x\n", facp->s4biosreq); 133295436Sandrew if (facp->pm1a_evt_blk) 134295436Sandrew printf("\tPM1a_EVT_BLK=0x%x-0x%x\n", 135295436Sandrew facp->pm1a_evt_blk, 136295436Sandrew facp->pm1a_evt_blk + facp->pm1_evt_len - 1); 137279377Simp if (facp->pm1b_evt_blk) 138295436Sandrew printf("\tPM1b_EVT_BLK=0x%x-0x%x\n", 139295436Sandrew facp->pm1b_evt_blk, 140295436Sandrew facp->pm1b_evt_blk + facp->pm1_evt_len - 1); 141295436Sandrew if (facp->pm1a_cnt_blk) 142295436Sandrew printf("\tPM1a_CNT_BLK=0x%x-0x%x\n", 143295436Sandrew facp->pm1a_cnt_blk, 144279377Simp facp->pm1a_cnt_blk + facp->pm1_cnt_len - 1); 145295436Sandrew if (facp->pm1b_cnt_blk) 146295436Sandrew printf("\tPM1b_CNT_BLK=0x%x-0x%x\n", 147295436Sandrew facp->pm1b_cnt_blk, 148295436Sandrew facp->pm1b_cnt_blk + facp->pm1_cnt_len - 1); 149295436Sandrew if (facp->pm2_cnt_blk) 150295436Sandrew printf("\tPM2_CNT_BLK=0x%x-0x%x\n", 151279377Simp facp->pm2_cnt_blk, 152295436Sandrew facp->pm2_cnt_blk + facp->pm2_cnt_len - 1); 153295436Sandrew if (facp->pm_tmr_blk) 154295436Sandrew printf("\tPM2_TMR_BLK=0x%x-0x%x\n", 155295436Sandrew facp->pm_tmr_blk, 156295436Sandrew facp->pm_tmr_blk + facp->pm_tmr_len - 1); 157295436Sandrew if (facp->gpe0_blk) 158279377Simp printf("\tPM2_GPE0_BLK=0x%x-0x%x\n", 159295436Sandrew facp->gpe0_blk, 160295436Sandrew facp->gpe0_blk + facp->gpe0_len - 1); 161295436Sandrew if (facp->gpe1_blk) 162295436Sandrew printf("\tPM2_GPE1_BLK=0x%x-0x%x, GPE1_BASE=%d\n", 163295436Sandrew facp->gpe1_blk, 164295436Sandrew facp->gpe1_blk + facp->gpe1_len - 1, 165295436Sandrew facp->gpe1_base); 166279377Simp printf("\tP_LVL2_LAT=%dms, P_LVL3_LAT=%dms\n", 167295436Sandrew facp->p_lvl2_lat, facp->p_lvl3_lat); 168295436Sandrew printf("\tFLUSH_SIZE=%d, FLUSH_STRIDE=%d\n", 169279377Simp facp->flush_size, facp->flush_stride); 170295436Sandrew printf("\tDUTY_OFFSET=%d, DUTY_WIDTH=%d\n", 171295436Sandrew facp->duty_off, facp->duty_width); 172295436Sandrew printf("\tDAY_ALRM=%d, MON_ALRM=%d, CENTURY=%d\n", 173295436Sandrew facp->day_alrm, facp->mon_alrm, facp->century); 174279377Simp printf("\tFlags="); 175295436Sandrew sep = '{'; 176295436Sandrew 177295436Sandrew#define PRINTFLAG(xx) do { \ 178295436Sandrew if (facp->flags & ACPI_FACP_FLAG_## xx) { \ 179295436Sandrew printf("%c%s", sep, #xx); sep = ','; \ 180295436Sandrew } \ 181295436Sandrew} while (0) 182295436Sandrew 183295436Sandrew PRINTFLAG(WBINVD); 184279377Simp PRINTFLAG(WBINVD_FLUSH); 185295436Sandrew PRINTFLAG(PROC_C1); 186295436Sandrew PRINTFLAG(P_LVL2_UP); 187295436Sandrew PRINTFLAG(PWR_BUTTON); 188295436Sandrew PRINTFLAG(SLP_BUTTON); 189295436Sandrew PRINTFLAG(FIX_RTC); 190295436Sandrew PRINTFLAG(RTC_S4); 191295436Sandrew PRINTFLAG(TMR_VAL_EXT); 192295436Sandrew PRINTFLAG(DCK_CAP); 193295436Sandrew 194279377Simp#undef PRINTFLAG 195295436Sandrew 196295436Sandrew printf("}\n"); 197295436Sandrew} 198279377Simp 199295436Sandrewvoid 200295436Sandrewacpi_print_dsdt(struct ACPIsdt *dsdp) 201295436Sandrew{ 202279377Simp 203295436Sandrew acpi_print_sdt(dsdp); 204295436Sandrew} 205295436Sandrew 206295436Sandrewint 207295436Sandrewacpi_checksum(void *p, size_t length) 208295436Sandrew{ 209279377Simp u_int8_t *bp; 210279377Simp u_int8_t sum; 211295436Sandrew 212295436Sandrew bp = p; 213295436Sandrew sum = 0; 214295436Sandrew while (length--) 215295436Sandrew sum += *bp++; 216295436Sandrew 217279377Simp return (sum); 218295436Sandrew} 219295436Sandrew 220295436Sandrewstruct ACPIsdt * 221295436Sandrewacpi_map_sdt(vm_offset_t pa) 222295436Sandrew{ 223279377Simp struct ACPIsdt *sp; 224279377Simp 225295436Sandrew sp = acpi_map_physical(pa, sizeof(struct ACPIsdt)); 226295436Sandrew sp = acpi_map_physical(pa, sp->len); 227295436Sandrew return (sp); 228295436Sandrew} 229295436Sandrew 230279377Simpvoid 231295436Sandrewacpi_print_rsd_ptr(struct ACPIrsdp *rp) 232295436Sandrew{ 233295436Sandrew 234295436Sandrew printf("RSD PTR: Checksum=%d, OEMID=", rp->sum); 235295436Sandrew acpi_print_string(rp->oem, 6); 236295436Sandrew printf(", RsdtAddress=0x%08x\n", rp->addr); 237295436Sandrew} 238279377Simp 239295436Sandrewvoid 240295436Sandrewacpi_handle_rsdt(struct ACPIsdt *rsdp) 241295436Sandrew{ 242295436Sandrew int i; 243295436Sandrew int entries; 244295436Sandrew struct ACPIsdt *sdp; 245295436Sandrew 246295436Sandrew entries = (rsdp->len - SIZEOF_SDT_HDR) / sizeof(u_int32_t); 247295436Sandrew acpi_print_rsdt(rsdp); 248295436Sandrew for (i = 0; i < entries; i++) { 249295436Sandrew sdp = (struct ACPIsdt *) acpi_map_sdt(rsdp->body[i]); 250295436Sandrew if (acpi_checksum(sdp, sdp->len)) 251295436Sandrew errx(1, "RSDT entry %d is corrupt\n", i); 252295436Sandrew if (!memcmp(sdp->signature, "FACP", 4)) { 253295436Sandrew acpi_handle_facp((struct FACPbody *) sdp->body); 254295436Sandrew } else { 255295436Sandrew acpi_print_sdt(sdp); 256295436Sandrew } 257295436Sandrew } 258295436Sandrew} 259295436Sandrew