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