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$ 29 */ 30 31 #include <sys/param.h> 32 #include <sys/stat.h> 33 34 #include <assert.h> 35 #include <err.h> 36 #include <fcntl.h> 37 #include <stdio.h> 38 #include <unistd.h> 39 40 #include "acpidump.h" 41 42 static void 43 acpi_print_string(char *s, size_t length) 44 { 45 int c; 46 47 /* Trim trailing spaces and NULLs */ 48 while (length > 0 && (s[length - 1] == ' ' || s[length - 1] == '\0')) 49 length--; 50 51 while (length--) { 52 c = *s++; 53 putchar(c); 54 } 55 } 56 57 static void 58 acpi_handle_dsdt(struct ACPIsdt *dsdp) 59 { 60 u_int8_t *dp; 61 u_int8_t *end; 62 63 acpi_print_dsdt(dsdp); 64 dp = (u_int8_t *)dsdp->body; 65 end = (u_int8_t *)dsdp + dsdp->len; 66 asl_dump_objectlist(&dp, end, 0); 67 assert(dp == end); 68 } 69 70 static void 71 acpi_handle_facp(struct FACPbody *facp) 72 { 73 struct ACPIsdt *dsdp; 74 75 acpi_print_facp(facp); 76 dsdp = (struct ACPIsdt *) acpi_map_sdt(facp->dsdt_ptr); 77 if (acpi_checksum(dsdp, dsdp->len)) 78 errx(1, "DSDT is corrupt\n"); 79 acpi_handle_dsdt(dsdp); 80 aml_dump(dsdp->body, dsdp->len - SIZEOF_SDT_HDR); 81 } 82 83 /* 84 * Public interfaces 85 */ 86 87 void 88 acpi_print_sdt(struct ACPIsdt *sdp) 89 { 90 91 acpi_print_string(sdp->signature, 4); 92 printf(": Lenth=%d, Revision=%d, Checksum=%d,\n", 93 sdp->len, sdp->rev, sdp->check); 94 printf("\tOEMID="); 95 acpi_print_string(sdp->oemid, 6); 96 printf(", OEM Table ID="); 97 acpi_print_string(sdp->oemtblid, 8); 98 printf(", OEM Revision=0x%x,\n", sdp->oemrev); 99 printf("\tCreator ID="); 100 acpi_print_string(sdp->creator, 4); 101 printf(", Creator Revision=0x%x\n", sdp->crerev); 102 } 103 104 void 105 acpi_print_rsdt(struct ACPIsdt *rsdp) 106 { 107 int i, entries; 108 109 acpi_print_sdt(rsdp); 110 entries = (rsdp->len - SIZEOF_SDT_HDR) / sizeof(u_int32_t); 111 printf("\tEntries={ "); 112 for (i = 0; i < entries; i++) { 113 if (i > 0) 114 printf(", "); 115 printf("0x%08x", rsdp->body[i]); 116 } 117 printf(" }\n"); 118 } 119 120 void 121 acpi_print_facp(struct FACPbody *facp) 122 { 123 char sep; 124 125 printf("\tDSDT=0x%x\n", facp->dsdt_ptr); 126 printf("\tINT_MODEL=%s\n", facp->int_model ? "APIC" : "PIC"); 127 printf("\tSCI_INT=%d\n", facp->sci_int); 128 printf("\tSMI_CMD=0x%x, ", facp->smi_cmd); 129 printf("ACPI_ENABLE=0x%x, ", facp->acpi_enable); 130 printf("ACPI_DISABLE=0x%x, ", facp->acpi_disable); 131 printf("S4BIOS_REQ=0x%x\n", facp->s4biosreq); 132 if (facp->pm1a_evt_blk) 133 printf("\tPM1a_EVT_BLK=0x%x-0x%x\n", 134 facp->pm1a_evt_blk, 135 facp->pm1a_evt_blk + facp->pm1_evt_len - 1); 136 if (facp->pm1b_evt_blk) 137 printf("\tPM1b_EVT_BLK=0x%x-0x%x\n", 138 facp->pm1b_evt_blk, 139 facp->pm1b_evt_blk + facp->pm1_evt_len - 1); 140 if (facp->pm1a_cnt_blk) 141 printf("\tPM1a_CNT_BLK=0x%x-0x%x\n", 142 facp->pm1a_cnt_blk, 143 facp->pm1a_cnt_blk + facp->pm1_cnt_len - 1); 144 if (facp->pm1b_cnt_blk) 145 printf("\tPM1b_CNT_BLK=0x%x-0x%x\n", 146 facp->pm1b_cnt_blk, 147 facp->pm1b_cnt_blk + facp->pm1_cnt_len - 1); 148 if (facp->pm2_cnt_blk) 149 printf("\tPM2_CNT_BLK=0x%x-0x%x\n", 150 facp->pm2_cnt_blk, 151 facp->pm2_cnt_blk + facp->pm2_cnt_len - 1); 152 if (facp->pm_tmr_blk) 153 printf("\tPM2_TMR_BLK=0x%x-0x%x\n", 154 facp->pm_tmr_blk, 155 facp->pm_tmr_blk + facp->pm_tmr_len - 1); 156 if (facp->gpe0_blk) 157 printf("\tPM2_GPE0_BLK=0x%x-0x%x\n", 158 facp->gpe0_blk, 159 facp->gpe0_blk + facp->gpe0_len - 1); 160 if (facp->gpe1_blk) 161 printf("\tPM2_GPE1_BLK=0x%x-0x%x, GPE1_BASE=%d\n", 162 facp->gpe1_blk, 163 facp->gpe1_blk + facp->gpe1_len - 1, 164 facp->gpe1_base); 165 printf("\tP_LVL2_LAT=%dms, P_LVL3_LAT=%dms\n", 166 facp->p_lvl2_lat, facp->p_lvl3_lat); 167 printf("\tFLUSH_SIZE=%d, FLUSH_STRIDE=%d\n", 168 facp->flush_size, facp->flush_stride); 169 printf("\tDUTY_OFFSET=%d, DUTY_WIDTH=%d\n", 170 facp->duty_off, facp->duty_width); 171 printf("\tDAY_ALRM=%d, MON_ALRM=%d, CENTURY=%d\n", 172 facp->day_alrm, facp->mon_alrm, facp->century); 173 printf("\tFlags="); 174 sep = '{'; 175 176 #define PRINTFLAG(xx) do { \ 177 if (facp->flags & ACPI_FACP_FLAG_## xx) { \ 178 printf("%c%s", sep, #xx); sep = ','; \ 179 } \ 180 } while (0) 181 182 PRINTFLAG(WBINVD); 183 PRINTFLAG(WBINVD_FLUSH); 184 PRINTFLAG(PROC_C1); 185 PRINTFLAG(P_LVL2_UP); 186 PRINTFLAG(PWR_BUTTON); 187 PRINTFLAG(SLP_BUTTON); 188 PRINTFLAG(FIX_RTC); 189 PRINTFLAG(RTC_S4); 190 PRINTFLAG(TMR_VAL_EXT); 191 PRINTFLAG(DCK_CAP); 192 193 #undef PRINTFLAG 194 195 printf("}\n"); 196 } 197 198 void 199 acpi_print_dsdt(struct ACPIsdt *dsdp) 200 { 201 202 acpi_print_sdt(dsdp); 203 } 204 205 int 206 acpi_checksum(void *p, size_t length) 207 { 208 u_int8_t *bp; 209 u_int8_t sum; 210 211 bp = p; 212 sum = 0; 213 while (length--) 214 sum += *bp++; 215 216 return (sum); 217 } 218 219 struct ACPIsdt * 220 acpi_map_sdt(vm_offset_t pa) 221 { 222 struct ACPIsdt *sp; 223 224 sp = acpi_map_physical(pa, sizeof(struct ACPIsdt)); 225 sp = acpi_map_physical(pa, sp->len); 226 return (sp); 227 } 228 229 void 230 acpi_print_rsd_ptr(struct ACPIrsdp *rp) 231 { 232 233 printf("RSD PTR: Checksum=%d, OEMID=", rp->sum); 234 acpi_print_string(rp->oem, 6); 235 printf(", RsdtAddress=0x%08x\n", rp->addr); 236 } 237 238 void 239 acpi_handle_rsdt(struct ACPIsdt *rsdp) 240 { 241 int i; 242 int entries; 243 struct ACPIsdt *sdp; 244 245 entries = (rsdp->len - SIZEOF_SDT_HDR) / sizeof(u_int32_t); 246 acpi_print_rsdt(rsdp); 247 for (i = 0; i < entries; i++) { 248 sdp = (struct ACPIsdt *) acpi_map_sdt(rsdp->body[i]); 249 if (acpi_checksum(sdp, sdp->len)) 250 errx(1, "RSDT entry %d is corrupt\n", i); 251 if (!memcmp(sdp->signature, "FACP", 4)) { 252 acpi_handle_facp((struct FACPbody *) sdp->body); 253 } else { 254 acpi_print_sdt(sdp); 255 } 256 } 257 } 258