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