Home | History | Annotate | Line # | Download | only in acpidump
acpi.c revision 1.3
      1 /*	$NetBSD: acpi.c,v 1.3 2008/02/13 11:47:36 joerg Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 1998 Doug Rabson
      5  * Copyright (c) 2000 Mitsuru IWASAKI <iwasaki (at) FreeBSD.org>
      6  * Copyright (c) 2008 Joerg Sonnenberger <joerg (at) NetBSD.org>
      7  * All rights reserved.
      8  *
      9  * Redistribution and use in source and binary forms, with or without
     10  * modification, are permitted provided that the following conditions
     11  * are met:
     12  * 1. Redistributions of source code must retain the above copyright
     13  *    notice, this list of conditions and the following disclaimer.
     14  * 2. Redistributions in binary form must reproduce the above copyright
     15  *    notice, this list of conditions and the following disclaimer in the
     16  *    documentation and/or other materials provided with the distribution.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     28  * SUCH DAMAGE.
     29  *
     30  *	Id: acpi.c,v 1.4 2000/08/09 14:47:52 iwasaki Exp
     31  *	$FreeBSD: src/usr.sbin/acpi/acpidump/acpi.c,v 1.4 2001/10/22 17:25:25 iwasaki Exp $
     32  */
     33 #include <sys/cdefs.h>
     34 __RCSID("$NetBSD: acpi.c,v 1.3 2008/02/13 11:47:36 joerg Exp $");
     35 
     36 #include <sys/param.h>
     37 #include <sys/stat.h>
     38 
     39 #include <assert.h>
     40 #include <err.h>
     41 #include <fcntl.h>
     42 #include <stdio.h>
     43 #include <unistd.h>
     44 #include <string.h>
     45 
     46 #include <acpi_common.h>
     47 #include "acpidump.h"
     48 
     49 #include "aml/aml_env.h"
     50 #include "aml/aml_common.h"
     51 #include "aml/aml_parse.h"
     52 #include "aml/aml_region.h"
     53 
     54 #define BEGIN_COMMENT	"/*\n"
     55 #define END_COMMENT	" */\n"
     56 
     57 struct ACPIsdt	dsdt_header = {
     58 	.signature = "DSDT",
     59 	.rev = 1,
     60 	.oemid = "OEMID",
     61 	.oemtblid = "OEMTBLID",
     62 	.oemrev = 0x12345678,
     63 	.creator = "CRTR",
     64 	.crerev = 0x12345678,
     65 };
     66 
     67 static void
     68 acpi_trim_string(char *s, size_t length)
     69 {
     70 
     71 	/* Trim trailing spaces and NULLs */
     72 	while (length > 0 && (s[length - 1] == ' ' || s[length - 1] == '\0'))
     73 		s[length-- - 1] = '\0';
     74 }
     75 
     76 static void
     77 acpi_print_dsdt_definition(void)
     78 {
     79 	char	oemid[6 + 1];
     80 	char	oemtblid[8 + 1];
     81 
     82 	acpi_trim_string((char *)dsdt_header.oemid, sizeof(oemid) - 1);
     83 	acpi_trim_string((char *)dsdt_header.oemtblid, sizeof(oemtblid) - 1);
     84 	(void)strlcpy(oemid, (const char *)dsdt_header.oemid, sizeof(oemid));
     85 	(void)strlcpy(oemtblid, (const char *)dsdt_header.oemtblid,
     86 	    sizeof(oemtblid));
     87 
     88 	printf("DefinitionBlock (\"%s\", \"%s\", 0x%x, \"%s\", \"%s\", 0x%x)",
     89 	    "acpi_dst.aml", "DSDT", dsdt_header.rev, oemid, oemtblid,
     90 	    dsdt_header.oemrev);
     91 }
     92 
     93 static void
     94 acpi_print_string(const char *s, size_t length)
     95 {
     96 	int	c;
     97 
     98 	/* Trim trailing spaces and NULLs */
     99 	while (length > 0 && (s[length - 1] == ' ' || s[length - 1] == '\0'))
    100 		length--;
    101 
    102 	while (length--) {
    103 		c = *s++;
    104 		putchar(c);
    105 	}
    106 }
    107 
    108 static void
    109 acpi_handle_dsdt(struct ACPIsdt *dsdp)
    110 {
    111 	u_int8_t       *dp;
    112 	u_int8_t       *end;
    113 
    114 	acpi_print_dsdt(dsdp);
    115 	dp = (u_int8_t *)dsdp->body;
    116 	end = (u_int8_t *)dsdp + dsdp->len;
    117 
    118 	acpi_dump_dsdt(dp, end);
    119 }
    120 
    121 static void
    122 acpi_handle_facp(struct FACPbody *facp)
    123 {
    124 	struct	ACPIsdt *dsdp;
    125 
    126 	acpi_print_facp(facp);
    127 	dsdp = (struct ACPIsdt *) acpi_map_sdt(facp->dsdt_ptr);
    128 	if (acpi_checksum(dsdp, dsdp->len))
    129 		errx(1, "DSDT is corrupt\n");
    130 	acpi_handle_dsdt(dsdp);
    131 	aml_dump(dsdp);
    132 }
    133 
    134 static void
    135 init_namespace(void)
    136 {
    137 	struct	aml_environ env;
    138 	struct	aml_name *newname;
    139 
    140 	aml_new_name_group((void *)AML_NAME_GROUP_OS_DEFINED);
    141 	env.curname = aml_get_rootname();
    142 	newname = aml_create_name(&env, (const unsigned char *)"\\_OS_");
    143 	newname->property = aml_alloc_object(aml_t_string, NULL);
    144 	newname->property->str.needfree = 0;
    145 	newname->property->str.string = __UNCONST("Microsoft Windows NT");
    146 
    147 	newname = aml_create_name(&env, (const unsigned char *)"\\_OSI");
    148 	newname->property = aml_alloc_object(aml_t_method, NULL);
    149 	newname->property->meth.argnum = 1;
    150 }
    151 
    152 /*
    153  * Public interfaces
    154  */
    155 
    156 void
    157 acpi_dump_dsdt(u_int8_t *dp, u_int8_t *end)
    158 {
    159 	extern struct aml_environ	asl_env;
    160 
    161 	acpi_print_dsdt_definition();
    162 
    163 	/* 1st stage: parse only w/o printing */
    164 	init_namespace();
    165 	aml_new_name_group(dp);
    166 	bzero(&asl_env, sizeof(asl_env));
    167 
    168 	asl_env.dp = dp;
    169 	asl_env.end = end;
    170 	asl_env.curname = aml_get_rootname();
    171 
    172 	aml_local_stack_push(aml_local_stack_create());
    173 	aml_parse_objectlist(&asl_env, 0);
    174 	aml_local_stack_delete(aml_local_stack_pop());
    175 
    176 	assert(asl_env.dp == asl_env.end);
    177 	asl_env.dp = dp;
    178 
    179 	/* 2nd stage: dump whole object list */
    180 	printf("\n{\n");
    181 	asl_dump_objectlist(&dp, end, 0);
    182 	printf("\n}\n");
    183 	assert(dp == end);
    184 }
    185 void
    186 acpi_print_sdt(struct ACPIsdt *sdp)
    187 {
    188 
    189 	printf(BEGIN_COMMENT);
    190 	acpi_print_string((const char *)sdp->signature, 4);
    191 	printf(": Length=%d, Revision=%d, Checksum=%d,\n",
    192 	       sdp->len, sdp->rev, sdp->check);
    193 	printf("\tOEMID=");
    194 	acpi_print_string((const char *)sdp->oemid, 6);
    195 	printf(", OEM Table ID=");
    196 	acpi_print_string((const char *)sdp->oemtblid, 8);
    197 	printf(", OEM Revision=0x%x,\n", sdp->oemrev);
    198 	printf("\tCreator ID=");
    199 	acpi_print_string((const char *)sdp->creator, 4);
    200 	printf(", Creator Revision=0x%x\n", sdp->crerev);
    201 	printf(END_COMMENT);
    202 	if (!memcmp(sdp->signature, "DSDT", 4)) {
    203 		memcpy(&dsdt_header, sdp, sizeof(dsdt_header));
    204 	}
    205 }
    206 
    207 void
    208 acpi_print_rsdt(struct ACPIsdt *rsdp)
    209 {
    210 	int	i, entries;
    211 
    212 	acpi_print_sdt(rsdp);
    213 	entries = (rsdp->len - SIZEOF_SDT_HDR) / sizeof(u_int32_t);
    214 	printf(BEGIN_COMMENT);
    215 	printf("\tEntries={ ");
    216 	for (i = 0; i < entries; i++) {
    217 		if (i > 0)
    218 			printf(", ");
    219 		printf("0x%08x", rsdp->body[i]);
    220 	}
    221 	printf(" }\n");
    222 	printf(END_COMMENT);
    223 }
    224 
    225 void
    226 acpi_print_facp(struct FACPbody *facp)
    227 {
    228 	char	sep;
    229 
    230 	printf(BEGIN_COMMENT);
    231 	printf("\tDSDT=0x%x\n", facp->dsdt_ptr);
    232 	printf("\tINT_MODEL=%s\n", facp->int_model ? "APIC" : "PIC");
    233 	printf("\tSCI_INT=%d\n", facp->sci_int);
    234 	printf("\tSMI_CMD=0x%x, ", facp->smi_cmd);
    235 	printf("ACPI_ENABLE=0x%x, ", facp->acpi_enable);
    236 	printf("ACPI_DISABLE=0x%x, ", facp->acpi_disable);
    237 	printf("S4BIOS_REQ=0x%x\n", facp->s4biosreq);
    238 	if (facp->pm1a_evt_blk)
    239 		printf("\tPM1a_EVT_BLK=0x%x-0x%x\n",
    240 		       facp->pm1a_evt_blk,
    241 		       facp->pm1a_evt_blk + facp->pm1_evt_len - 1);
    242 	if (facp->pm1b_evt_blk)
    243 		printf("\tPM1b_EVT_BLK=0x%x-0x%x\n",
    244 		       facp->pm1b_evt_blk,
    245 		       facp->pm1b_evt_blk + facp->pm1_evt_len - 1);
    246 	if (facp->pm1a_cnt_blk)
    247 		printf("\tPM1a_CNT_BLK=0x%x-0x%x\n",
    248 		       facp->pm1a_cnt_blk,
    249 		       facp->pm1a_cnt_blk + facp->pm1_cnt_len - 1);
    250 	if (facp->pm1b_cnt_blk)
    251 		printf("\tPM1b_CNT_BLK=0x%x-0x%x\n",
    252 		       facp->pm1b_cnt_blk,
    253 		       facp->pm1b_cnt_blk + facp->pm1_cnt_len - 1);
    254 	if (facp->pm2_cnt_blk)
    255 		printf("\tPM2_CNT_BLK=0x%x-0x%x\n",
    256 		       facp->pm2_cnt_blk,
    257 		       facp->pm2_cnt_blk + facp->pm2_cnt_len - 1);
    258 	if (facp->pm_tmr_blk)
    259 		printf("\tPM2_TMR_BLK=0x%x-0x%x\n",
    260 		       facp->pm_tmr_blk,
    261 		       facp->pm_tmr_blk + facp->pm_tmr_len - 1);
    262 	if (facp->gpe0_blk)
    263 		printf("\tPM2_GPE0_BLK=0x%x-0x%x\n",
    264 		       facp->gpe0_blk,
    265 		       facp->gpe0_blk + facp->gpe0_len - 1);
    266 	if (facp->gpe1_blk)
    267 		printf("\tPM2_GPE1_BLK=0x%x-0x%x, GPE1_BASE=%d\n",
    268 		       facp->gpe1_blk,
    269 		       facp->gpe1_blk + facp->gpe1_len - 1,
    270 		       facp->gpe1_base);
    271 	printf("\tP_LVL2_LAT=%dms, P_LVL3_LAT=%dms\n",
    272 	       facp->p_lvl2_lat, facp->p_lvl3_lat);
    273 	printf("\tFLUSH_SIZE=%d, FLUSH_STRIDE=%d\n",
    274 	       facp->flush_size, facp->flush_stride);
    275 	printf("\tDUTY_OFFSET=%d, DUTY_WIDTH=%d\n",
    276 	       facp->duty_off, facp->duty_width);
    277 	printf("\tDAY_ALRM=%d, MON_ALRM=%d, CENTURY=%d\n",
    278 	       facp->day_alrm, facp->mon_alrm, facp->century);
    279 	printf("\tFlags=");
    280 	sep = '{';
    281 
    282 #define PRINTFLAG(xx) do {					\
    283 	if (facp->flags & ACPI_FACP_FLAG_## xx) {		\
    284 		printf("%c%s", sep, #xx); sep = ',';		\
    285 	}							\
    286 } while (0)
    287 
    288 	PRINTFLAG(WBINVD);
    289 	PRINTFLAG(WBINVD_FLUSH);
    290 	PRINTFLAG(PROC_C1);
    291 	PRINTFLAG(P_LVL2_UP);
    292 	PRINTFLAG(PWR_BUTTON);
    293 	PRINTFLAG(SLP_BUTTON);
    294 	PRINTFLAG(FIX_RTC);
    295 	PRINTFLAG(RTC_S4);
    296 	PRINTFLAG(TMR_VAL_EXT);
    297 	PRINTFLAG(DCK_CAP);
    298 
    299 #undef PRINTFLAG
    300 
    301 	printf("}\n");
    302 	printf(END_COMMENT);
    303 }
    304 
    305 void
    306 acpi_print_dsdt(struct ACPIsdt *dsdp)
    307 {
    308 
    309 	acpi_print_sdt(dsdp);
    310 }
    311 
    312 int
    313 acpi_checksum(void *p, size_t length)
    314 {
    315 	u_int8_t	*bp;
    316 	u_int8_t	sum;
    317 
    318 	bp = p;
    319 	sum = 0;
    320 	while (length--)
    321 		sum += *bp++;
    322 
    323 	return (sum);
    324 }
    325 
    326 struct ACPIsdt *
    327 acpi_map_sdt(vm_offset_t pa)
    328 {
    329 	struct	ACPIsdt *sp;
    330 
    331 	sp = acpi_map_physical(pa, sizeof(struct ACPIsdt));
    332 	sp = acpi_map_physical(pa, sp->len);
    333 	return (sp);
    334 }
    335 
    336 void
    337 acpi_print_rsd_ptr(struct ACPIrsdp *rp)
    338 {
    339 
    340 	printf(BEGIN_COMMENT);
    341 	printf("RSD PTR: Checksum=%d, OEMID=", rp->sum);
    342 	acpi_print_string((const char *)rp->oem, 6);
    343 	printf(", RsdtAddress=0x%08x\n", rp->addr);
    344 	printf(END_COMMENT);
    345 }
    346 
    347 void
    348 acpi_handle_rsdt(struct ACPIsdt *rsdp)
    349 {
    350 	int	i;
    351 	int	entries;
    352 	struct	ACPIsdt *sdp;
    353 
    354 	entries = (rsdp->len - SIZEOF_SDT_HDR) / sizeof(u_int32_t);
    355 	acpi_print_rsdt(rsdp);
    356 	for (i = 0; i < entries; i++) {
    357 		sdp = (struct ACPIsdt *) acpi_map_sdt(rsdp->body[i]);
    358 		if (acpi_checksum(sdp, sdp->len))
    359 			errx(1, "RSDT entry %d is corrupt\n", i);
    360 		if (!memcmp(sdp->signature, "FACP", 4)) {
    361 			acpi_handle_facp((struct FACPbody *) sdp->body);
    362 		} else {
    363 			acpi_print_sdt(sdp);
    364 		}
    365 	}
    366 }
    367 
    368 /*
    369  *	Dummy functions
    370  */
    371 
    372 void
    373 aml_dbgr(struct aml_environ *env1, struct aml_environ *env2)
    374 {
    375 	/* do nothing */
    376 }
    377 
    378 int
    379 aml_region_read_simple(struct aml_region_handle *h, vm_offset_t offset,
    380     u_int32_t *valuep)
    381 {
    382 	return (0);
    383 }
    384 
    385 int
    386 aml_region_write_simple(struct aml_region_handle *h, vm_offset_t offset,
    387     u_int32_t value)
    388 {
    389 	return (0);
    390 }
    391 
    392 u_int32_t
    393 aml_region_prompt_read(struct aml_region_handle *h, u_int32_t value)
    394 {
    395 	return (0);
    396 }
    397 
    398 u_int32_t
    399 aml_region_prompt_write(struct aml_region_handle *h, u_int32_t value)
    400 {
    401 	return (0);
    402 }
    403 
    404 int
    405 aml_region_prompt_update_value(u_int32_t orgval, u_int32_t value,
    406     struct aml_region_handle *h)
    407 {
    408 	return (0);
    409 }
    410 
    411 u_int32_t
    412 aml_region_read(struct aml_environ *env, int regtype, u_int32_t flags,
    413     u_int32_t addr, u_int32_t bitoffset, u_int32_t bitlen)
    414 {
    415 	return (0);
    416 }
    417 
    418 int
    419 aml_region_write(struct aml_environ *env, int regtype, u_int32_t flags,
    420     u_int32_t value, u_int32_t addr, u_int32_t bitoffset, u_int32_t bitlen)
    421 {
    422 	return (0);
    423 }
    424 
    425 int
    426 aml_region_write_from_buffer(struct aml_environ *env, int regtype,
    427     u_int32_t flags, u_int8_t *buffer, u_int32_t addr, u_int32_t bitoffset,
    428     u_int32_t bitlen)
    429 {
    430 	return (0);
    431 }
    432 
    433 int
    434 aml_region_bcopy(struct aml_environ *env, int regtype, u_int32_t flags,
    435     u_int32_t addr, u_int32_t bitoffset, u_int32_t bitlen,
    436     u_int32_t dflags, u_int32_t daddr,
    437     u_int32_t dbitoffset, u_int32_t dbitlen)
    438 {
    439 	return (0);
    440 }
    441 
    442 int
    443 aml_region_read_into_buffer(struct aml_environ *env, int regtype,
    444     u_int32_t flags, u_int32_t addr, u_int32_t bitoffset,
    445     u_int32_t bitlen, u_int8_t *buffer)
    446 {
    447 	return (0);
    448 }
    449