acpi.c revision 66490
18871Srgrimes/*-
21558Srgrimes * Copyright (c) 1998 Doug Rabson
31558Srgrimes * Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
41558Srgrimes * All rights reserved.
51558Srgrimes *
61558Srgrimes * Redistribution and use in source and binary forms, with or without
71558Srgrimes * modification, are permitted provided that the following conditions
81558Srgrimes * are met:
91558Srgrimes * 1. Redistributions of source code must retain the above copyright
101558Srgrimes *    notice, this list of conditions and the following disclaimer.
111558Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
121558Srgrimes *    notice, this list of conditions and the following disclaimer in the
131558Srgrimes *    documentation and/or other materials provided with the distribution.
141558Srgrimes *
151558Srgrimes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
161558Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
171558Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
181558Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
191558Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
201558Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
211558Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
221558Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
231558Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
241558Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
251558Srgrimes * SUCH DAMAGE.
261558Srgrimes *
271558Srgrimes *	$Id: acpi.c,v 1.4 2000/08/09 14:47:52 iwasaki Exp $
281558Srgrimes *	$FreeBSD: head/usr.sbin/acpi/acpidump/acpi.c 66490 2000-09-30 20:13:57Z msmith $
291558Srgrimes */
301558Srgrimes
311558Srgrimes#include <sys/param.h>
321558Srgrimes#include <sys/stat.h>
331558Srgrimes
341558Srgrimes#include <assert.h>
3541477Sjulian#include <err.h>
3623675Speter#include <fcntl.h>
3741477Sjulian#include <stdio.h>
3841477Sjulian#include <unistd.h>
3950476Speter
401558Srgrimes#include <dev/acpi/acpireg.h>
411558Srgrimes
421558Srgrimes#include "acpidump.h"
4362668Smckusick
4423675Speterstatic void
451558Srgrimesacpi_print_string(char *s, size_t length)
461558Srgrimes{
471558Srgrimes	int	c;
4823675Speter
4923675Speter	/* Trim trailing spaces and NULLs */
501558Srgrimes	while (length > 0 && (s[length - 1] == ' ' || s[length - 1] == '\0'))
5123675Speter		length--;
521558Srgrimes
531558Srgrimes	while (length--) {
5423675Speter		c = *s++;
5523675Speter		putchar(c);
5641474Sjulian	}
571558Srgrimes}
5823675Speter
597585Sbdestatic void
607585Sbdeacpi_handle_dsdt(struct ACPIsdt *dsdp)
611558Srgrimes{
621558Srgrimes	u_int8_t       *dp;
6341474Sjulian	u_int8_t       *end;
641558Srgrimes
6541474Sjulian	acpi_print_dsdt(dsdp);
6641474Sjulian	dp = (u_int8_t *)dsdp->body;
671558Srgrimes	end = (u_int8_t *)dsdp + dsdp->len;
681558Srgrimes	asl_dump_objectlist(&dp, end, 0);
691558Srgrimes	assert(dp == end);
701558Srgrimes}
711558Srgrimes
721558Srgrimesstatic void
731558Srgrimesacpi_handle_facp(struct FACPbody *facp)
741558Srgrimes{
751558Srgrimes	struct	ACPIsdt *dsdp;
761558Srgrimes
771558Srgrimes	acpi_print_facp(facp);
781558Srgrimes	dsdp = (struct ACPIsdt *) acpi_map_sdt(facp->dsdt_ptr);
791558Srgrimes	if (acpi_checksum(dsdp, dsdp->len))
801558Srgrimes		errx(1, "DSDT is corrupt\n");
8169800Stomsoft	acpi_handle_dsdt(dsdp);
8269800Stomsoft	aml_dump(dsdp->body, dsdp->len - SIZEOF_SDT_HDR);
8369800Stomsoft}
8469800Stomsoft
8569800Stomsoft/*
861558Srgrimes * Public interfaces
871558Srgrimes */
881558Srgrimes
8923675Spetervoid
901558Srgrimesacpi_print_sdt(struct ACPIsdt *sdp)
911558Srgrimes{
921558Srgrimes
9341474Sjulian	acpi_print_string(sdp->signature, 4);
9441474Sjulian	printf(": Lenth=%d, Revision=%d, Checksum=%d,\n",
9541474Sjulian	       sdp->len, sdp->rev, sdp->check);
9641474Sjulian	printf("\tOEMID=");
9741474Sjulian	acpi_print_string(sdp->oemid, 6);
9841474Sjulian	printf(", OEM Table ID=");
9941474Sjulian	acpi_print_string(sdp->oemtblid, 8);
10041474Sjulian	printf(", OEM Revision=0x%x,\n", sdp->oemrev);
10141474Sjulian	printf("\tCreator ID=");
10241474Sjulian	acpi_print_string(sdp->creator, 4);
10341474Sjulian	printf(", Creator Revision=0x%x\n", sdp->crerev);
10441474Sjulian}
10541474Sjulian
10641474Sjulianvoid
10741474Sjulianacpi_print_rsdt(struct ACPIsdt *rsdp)
10841474Sjulian{
10941474Sjulian	int	i, entries;
11041474Sjulian
11141474Sjulian	acpi_print_sdt(rsdp);
11241474Sjulian	entries = (rsdp->len - SIZEOF_SDT_HDR) / sizeof(u_int32_t);
11341474Sjulian	printf("\tEntries={ ");
11441474Sjulian	for (i = 0; i < entries; i++) {
11541474Sjulian		if (i > 0)
11641474Sjulian			printf(", ");
11741474Sjulian		printf("0x%08x", rsdp->body[i]);
11841474Sjulian	}
11941474Sjulian	printf(" }\n");
12041474Sjulian}
12141474Sjulian
12241474Sjulianvoid
12341474Sjulianacpi_print_facp(struct FACPbody *facp)
12441474Sjulian{
12541474Sjulian	char	sep;
12641474Sjulian
12741474Sjulian	printf("\tDSDT=0x%x\n", facp->dsdt_ptr);
12841474Sjulian	printf("\tINT_MODEL=%s\n", facp->int_model ? "APIC" : "PIC");
12941474Sjulian	printf("\tSCI_INT=%d\n", facp->sci_int);
13041474Sjulian	printf("\tSMI_CMD=0x%x, ", facp->smi_cmd);
13141474Sjulian	printf("ACPI_ENABLE=0x%x, ", facp->acpi_enable);
13241474Sjulian	printf("ACPI_DISABLE=0x%x, ", facp->acpi_disable);
13341474Sjulian	printf("S4BIOS_REQ=0x%x\n", facp->s4biosreq);
13441474Sjulian	if (facp->pm1a_evt_blk)
13541474Sjulian		printf("\tPM1a_EVT_BLK=0x%x-0x%x\n",
13641474Sjulian		       facp->pm1a_evt_blk,
13741474Sjulian		       facp->pm1a_evt_blk + facp->pm1_evt_len - 1);
13841474Sjulian	if (facp->pm1b_evt_blk)
13941474Sjulian		printf("\tPM1b_EVT_BLK=0x%x-0x%x\n",
1401558Srgrimes		       facp->pm1b_evt_blk,
14141474Sjulian		       facp->pm1b_evt_blk + facp->pm1_evt_len - 1);
1421558Srgrimes	if (facp->pm1a_cnt_blk)
1431558Srgrimes		printf("\tPM1a_CNT_BLK=0x%x-0x%x\n",
14441474Sjulian		       facp->pm1a_cnt_blk,
14541474Sjulian		       facp->pm1a_cnt_blk + facp->pm1_cnt_len - 1);
14641474Sjulian	if (facp->pm1b_cnt_blk)
14741474Sjulian		printf("\tPM1b_CNT_BLK=0x%x-0x%x\n",
14841474Sjulian		       facp->pm1b_cnt_blk,
14941474Sjulian		       facp->pm1b_cnt_blk + facp->pm1_cnt_len - 1);
15041474Sjulian	if (facp->pm2_cnt_blk)
15141474Sjulian		printf("\tPM2_CNT_BLK=0x%x-0x%x\n",
15241474Sjulian		       facp->pm2_cnt_blk,
15341474Sjulian		       facp->pm2_cnt_blk + facp->pm2_cnt_len - 1);
15441474Sjulian	if (facp->pm_tmr_blk)
15541474Sjulian		printf("\tPM2_TMR_BLK=0x%x-0x%x\n",
15641474Sjulian		       facp->pm_tmr_blk,
15741474Sjulian		       facp->pm_tmr_blk + facp->pm_tmr_len - 1);
15841474Sjulian	if (facp->gpe0_blk)
15941474Sjulian		printf("\tPM2_GPE0_BLK=0x%x-0x%x\n",
16041474Sjulian		       facp->gpe0_blk,
16141474Sjulian		       facp->gpe0_blk + facp->gpe0_len - 1);
16241474Sjulian	if (facp->gpe1_blk)
16341474Sjulian		printf("\tPM2_GPE1_BLK=0x%x-0x%x, GPE1_BASE=%d\n",
16441474Sjulian		       facp->gpe1_blk,
16541474Sjulian		       facp->gpe1_blk + facp->gpe1_len - 1,
16641474Sjulian		       facp->gpe1_base);
16741474Sjulian	printf("\tP_LVL2_LAT=%dms, P_LVL3_LAT=%dms\n",
16841474Sjulian	       facp->p_lvl2_lat, facp->p_lvl3_lat);
1691558Srgrimes	printf("\tFLUSH_SIZE=%d, FLUSH_STRIDE=%d\n",
1701558Srgrimes	       facp->flush_size, facp->flush_stride);
1711558Srgrimes	printf("\tDUTY_OFFSET=%d, DUTY_WIDTH=%d\n",
1721558Srgrimes	       facp->duty_off, facp->duty_width);
17323675Speter	printf("\tDAY_ALRM=%d, MON_ALRM=%d, CENTURY=%d\n",
1741558Srgrimes	       facp->day_alrm, facp->mon_alrm, facp->century);
1751558Srgrimes	printf("\tFlags=");
1761558Srgrimes	sep = '{';
1771558Srgrimes
1781558Srgrimes#define PRINTFLAG(xx) do {					\
1791558Srgrimes	if (facp->flags & ACPI_FACP_FLAG_## xx) {		\
1801558Srgrimes		printf("%c%s", sep, #xx); sep = ',';		\
1811558Srgrimes	}							\
1822603Sdg} while (0)
1831558Srgrimes
1841558Srgrimes	PRINTFLAG(WBINVD);
1851558Srgrimes	PRINTFLAG(WBINVD_FLUSH);
1861558Srgrimes	PRINTFLAG(PROC_C1);
18723675Speter	PRINTFLAG(P_LVL2_UP);
18823675Speter	PRINTFLAG(PWR_BUTTON);
18923675Speter	PRINTFLAG(SLP_BUTTON);
19023675Speter	PRINTFLAG(FIX_RTC);
1911558Srgrimes	PRINTFLAG(RTC_S4);
1921558Srgrimes	PRINTFLAG(TMR_VAL_EXT);
1931558Srgrimes	PRINTFLAG(DCK_CAP);
1941558Srgrimes
1951558Srgrimes#undef PRINTFLAG
1961558Srgrimes
1971558Srgrimes	printf("}\n");
1981558Srgrimes}
19941474Sjulian
2001558Srgrimesvoid
2011558Srgrimesacpi_print_dsdt(struct ACPIsdt *dsdp)
2021558Srgrimes{
2031558Srgrimes
20423999Speter	acpi_print_sdt(dsdp);
20523999Speter}
2061558Srgrimes
2071558Srgrimesint
2081558Srgrimesacpi_checksum(void *p, size_t length)
2091558Srgrimes{
2101558Srgrimes	u_int8_t	*bp;
2111558Srgrimes	u_int8_t	sum;
2121558Srgrimes
2131558Srgrimes	bp = p;
2141558Srgrimes	sum = 0;
2151558Srgrimes	while (length--)
21663003Smckusick		sum += *bp++;
21763003Smckusick
21863003Smckusick	return (sum);
21963003Smckusick}
22063003Smckusick
22163003Smckusickstruct ACPIsdt *
2221558Srgrimesacpi_map_sdt(vm_offset_t pa)
2231558Srgrimes{
2241558Srgrimes	struct	ACPIsdt *sp;
2251558Srgrimes
2261558Srgrimes	sp = acpi_map_physical(pa, sizeof(struct ACPIsdt));
2271558Srgrimes	sp = acpi_map_physical(pa, sp->len);
2281558Srgrimes	return (sp);
2291558Srgrimes}
2301558Srgrimes
2311558Srgrimesvoid
2321558Srgrimesacpi_print_rsd_ptr(struct ACPIrsdp *rp)
2331558Srgrimes{
2341558Srgrimes
2352603Sdg	printf("RSD PTR: Checksum=%d, OEMID=", rp->sum);
2361558Srgrimes	acpi_print_string(rp->oem, 6);
2371558Srgrimes	printf(", RsdtAddress=0x%08x\n", rp->addr);
2382603Sdg}
23923675Speter
2401558Srgrimesvoid
2411558Srgrimesacpi_handle_rsdt(struct ACPIsdt *rsdp)
24237236Sbde{
24341474Sjulian	int	i;
2441558Srgrimes	int	entries;
2451558Srgrimes	struct	ACPIsdt *sdp;
24623675Speter
2471558Srgrimes	entries = (rsdp->len - SIZEOF_SDT_HDR) / sizeof(u_int32_t);
2481558Srgrimes	acpi_print_rsdt(rsdp);
2491558Srgrimes	for (i = 0; i < entries; i++) {
2501558Srgrimes		sdp = (struct ACPIsdt *) acpi_map_sdt(rsdp->body[i]);
2511558Srgrimes		if (acpi_checksum(sdp, sdp->len))
2521558Srgrimes			errx(1, "RSDT entry %d is corrupt\n", i);
2531558Srgrimes		if (!memcmp(sdp->signature, "FACP", 4)) {
25441474Sjulian			acpi_handle_facp((struct FACPbody *) sdp->body);
25523675Speter		} else {
2561558Srgrimes			acpi_print_sdt(sdp);
2571558Srgrimes		}
2581558Srgrimes	}
2591558Srgrimes}
2601558Srgrimes