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