acpi.c revision 65286
1/*- 2 * Copyright (c) 1998 Doug Rabson 3 * Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org> 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 * $Id: acpi.c,v 1.4 2000/08/09 14:47:52 iwasaki Exp $ 28 * $FreeBSD: head/usr.sbin/acpi/acpidump/acpi.c 65286 2000-08-31 14:42:32Z iwasaki $ 29 */ 30 31#include <sys/param.h> 32#include <sys/stat.h> 33#include <sys/acpi.h> 34 35#include <assert.h> 36#include <err.h> 37#include <fcntl.h> 38#include <stdio.h> 39#include <unistd.h> 40 41#include "acpidump.h" 42 43static void 44acpi_print_string(char *s, size_t length) 45{ 46 int c; 47 48 /* Trim trailing spaces and NULLs */ 49 while (length > 0 && (s[length - 1] == ' ' || s[length - 1] == '\0')) 50 length--; 51 52 while (length--) { 53 c = *s++; 54 putchar(c); 55 } 56} 57 58static void 59acpi_handle_dsdt(struct ACPIsdt *dsdp) 60{ 61 u_int8_t *dp; 62 u_int8_t *end; 63 64 acpi_print_dsdt(dsdp); 65 dp = (u_int8_t *)dsdp->body; 66 end = (u_int8_t *)dsdp + dsdp->len; 67 asl_dump_objectlist(&dp, end, 0); 68 assert(dp == end); 69} 70 71static void 72acpi_handle_facp(struct FACPbody *facp) 73{ 74 struct ACPIsdt *dsdp; 75 76 acpi_print_facp(facp); 77 dsdp = (struct ACPIsdt *) acpi_map_sdt(facp->dsdt_ptr); 78 if (acpi_checksum(dsdp, dsdp->len)) 79 errx(1, "DSDT is corrupt\n"); 80 acpi_handle_dsdt(dsdp); 81 aml_dump(dsdp->body, dsdp->len - SIZEOF_SDT_HDR); 82} 83 84/* 85 * Public interfaces 86 */ 87 88void 89acpi_print_sdt(struct ACPIsdt *sdp) 90{ 91 92 acpi_print_string(sdp->signature, 4); 93 printf(": Lenth=%d, Revision=%d, Checksum=%d,\n", 94 sdp->len, sdp->rev, sdp->check); 95 printf("\tOEMID="); 96 acpi_print_string(sdp->oemid, 6); 97 printf(", OEM Table ID="); 98 acpi_print_string(sdp->oemtblid, 8); 99 printf(", OEM Revision=0x%x,\n", sdp->oemrev); 100 printf("\tCreator ID="); 101 acpi_print_string(sdp->creator, 4); 102 printf(", Creator Revision=0x%x\n", sdp->crerev); 103} 104 105void 106acpi_print_rsdt(struct ACPIsdt *rsdp) 107{ 108 int i, entries; 109 110 acpi_print_sdt(rsdp); 111 entries = (rsdp->len - SIZEOF_SDT_HDR) / sizeof(u_int32_t); 112 printf("\tEntries={ "); 113 for (i = 0; i < entries; i++) { 114 if (i > 0) 115 printf(", "); 116 printf("0x%08x", rsdp->body[i]); 117 } 118 printf(" }\n"); 119} 120 121void 122acpi_print_facp(struct FACPbody *facp) 123{ 124 char sep; 125 126 printf("\tDSDT=0x%x\n", facp->dsdt_ptr); 127 printf("\tINT_MODEL=%s\n", facp->int_model ? "APIC" : "PIC"); 128 printf("\tSCI_INT=%d\n", facp->sci_int); 129 printf("\tSMI_CMD=0x%x, ", facp->smi_cmd); 130 printf("ACPI_ENABLE=0x%x, ", facp->acpi_enable); 131 printf("ACPI_DISABLE=0x%x, ", facp->acpi_disable); 132 printf("S4BIOS_REQ=0x%x\n", facp->s4biosreq); 133 if (facp->pm1a_evt_blk) 134 printf("\tPM1a_EVT_BLK=0x%x-0x%x\n", 135 facp->pm1a_evt_blk, 136 facp->pm1a_evt_blk + facp->pm1_evt_len - 1); 137 if (facp->pm1b_evt_blk) 138 printf("\tPM1b_EVT_BLK=0x%x-0x%x\n", 139 facp->pm1b_evt_blk, 140 facp->pm1b_evt_blk + facp->pm1_evt_len - 1); 141 if (facp->pm1a_cnt_blk) 142 printf("\tPM1a_CNT_BLK=0x%x-0x%x\n", 143 facp->pm1a_cnt_blk, 144 facp->pm1a_cnt_blk + facp->pm1_cnt_len - 1); 145 if (facp->pm1b_cnt_blk) 146 printf("\tPM1b_CNT_BLK=0x%x-0x%x\n", 147 facp->pm1b_cnt_blk, 148 facp->pm1b_cnt_blk + facp->pm1_cnt_len - 1); 149 if (facp->pm2_cnt_blk) 150 printf("\tPM2_CNT_BLK=0x%x-0x%x\n", 151 facp->pm2_cnt_blk, 152 facp->pm2_cnt_blk + facp->pm2_cnt_len - 1); 153 if (facp->pm_tmr_blk) 154 printf("\tPM2_TMR_BLK=0x%x-0x%x\n", 155 facp->pm_tmr_blk, 156 facp->pm_tmr_blk + facp->pm_tmr_len - 1); 157 if (facp->gpe0_blk) 158 printf("\tPM2_GPE0_BLK=0x%x-0x%x\n", 159 facp->gpe0_blk, 160 facp->gpe0_blk + facp->gpe0_len - 1); 161 if (facp->gpe1_blk) 162 printf("\tPM2_GPE1_BLK=0x%x-0x%x, GPE1_BASE=%d\n", 163 facp->gpe1_blk, 164 facp->gpe1_blk + facp->gpe1_len - 1, 165 facp->gpe1_base); 166 printf("\tP_LVL2_LAT=%dms, P_LVL3_LAT=%dms\n", 167 facp->p_lvl2_lat, facp->p_lvl3_lat); 168 printf("\tFLUSH_SIZE=%d, FLUSH_STRIDE=%d\n", 169 facp->flush_size, facp->flush_stride); 170 printf("\tDUTY_OFFSET=%d, DUTY_WIDTH=%d\n", 171 facp->duty_off, facp->duty_width); 172 printf("\tDAY_ALRM=%d, MON_ALRM=%d, CENTURY=%d\n", 173 facp->day_alrm, facp->mon_alrm, facp->century); 174 printf("\tFlags="); 175 sep = '{'; 176 177#define PRINTFLAG(xx) do { \ 178 if (facp->flags & ACPI_FACP_FLAG_## xx) { \ 179 printf("%c%s", sep, #xx); sep = ','; \ 180 } \ 181} while (0) 182 183 PRINTFLAG(WBINVD); 184 PRINTFLAG(WBINVD_FLUSH); 185 PRINTFLAG(PROC_C1); 186 PRINTFLAG(P_LVL2_UP); 187 PRINTFLAG(PWR_BUTTON); 188 PRINTFLAG(SLP_BUTTON); 189 PRINTFLAG(FIX_RTC); 190 PRINTFLAG(RTC_S4); 191 PRINTFLAG(TMR_VAL_EXT); 192 PRINTFLAG(DCK_CAP); 193 194#undef PRINTFLAG 195 196 printf("}\n"); 197} 198 199void 200acpi_print_dsdt(struct ACPIsdt *dsdp) 201{ 202 203 acpi_print_sdt(dsdp); 204} 205 206int 207acpi_checksum(void *p, size_t length) 208{ 209 u_int8_t *bp; 210 u_int8_t sum; 211 212 bp = p; 213 sum = 0; 214 while (length--) 215 sum += *bp++; 216 217 return (sum); 218} 219 220struct ACPIsdt * 221acpi_map_sdt(vm_offset_t pa) 222{ 223 struct ACPIsdt *sp; 224 225 sp = acpi_map_physical(pa, sizeof(struct ACPIsdt)); 226 sp = acpi_map_physical(pa, sp->len); 227 return (sp); 228} 229 230void 231acpi_print_rsd_ptr(struct ACPIrsdp *rp) 232{ 233 234 printf("RSD PTR: Checksum=%d, OEMID=", rp->sum); 235 acpi_print_string(rp->oem, 6); 236 printf(", RsdtAddress=0x%08x\n", rp->addr); 237} 238 239void 240acpi_handle_rsdt(struct ACPIsdt *rsdp) 241{ 242 int i; 243 int entries; 244 struct ACPIsdt *sdp; 245 246 entries = (rsdp->len - SIZEOF_SDT_HDR) / sizeof(u_int32_t); 247 acpi_print_rsdt(rsdp); 248 for (i = 0; i < entries; i++) { 249 sdp = (struct ACPIsdt *) acpi_map_sdt(rsdp->body[i]); 250 if (acpi_checksum(sdp, sdp->len)) 251 errx(1, "RSDT entry %d is corrupt\n", i); 252 if (!memcmp(sdp->signature, "FACP", 4)) { 253 acpi_handle_facp((struct FACPbody *) sdp->body); 254 } else { 255 acpi_print_sdt(sdp); 256 } 257 } 258} 259