#include <sys/cdefs.h>
__RCSID("$NetBSD: amldb.c,v 1.5 2020/08/20 15:54:12 riastradh Exp $");
#include <sys/param.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <acpi_common.h>
#include <aml/aml_amlmem.h>
#include <aml/aml_common.h>
#include <aml/aml_env.h>
#include <aml/aml_parse.h>
#include <aml/aml_region.h>
#include <assert.h>
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include "debug.h"
int regdump_enabled = 0;
int memstat_enabled = 0;
int showtree_enabled = 0;
static void aml_init_namespace(void);
void
aml_init_namespace(void)
{
struct aml_environ env;
struct aml_name *newname;
aml_new_name_group((void *)AML_NAME_GROUP_OS_DEFINED);
env.curname = aml_get_rootname();
newname = aml_create_name(&env, (const u_int8_t *)"\\_OS_");
newname->property = aml_alloc_object(aml_t_string, NULL);
newname->property->str.needfree = 0;
newname->property->str.string = __UNCONST("Microsoft Windows NT");
}
static int
load_dsdt(const char *dsdtfile)
{
struct aml_environ env;
u_int8_t *code;
struct stat sb;
int fd;
printf("Loading %s...", dsdtfile);
fd = open(dsdtfile, O_RDONLY, 0);
if (fd == -1) {
perror("open");
exit(-1);
}
if (fstat(fd, &sb) == -1) {
perror("fstat");
exit(-1);
}
if ((code = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) ==
MAP_FAILED) {
perror("mmap");
exit(-1);
}
aml_init_namespace();
aml_new_name_group(code);
bzero(&env, sizeof(env));
#define SIZEOF_SDT_HDR 36
if (strncmp((const char *)code, "DSDT", 4) == 0) {
env.dp = code + SIZEOF_SDT_HDR;
} else {
env.dp = code;
}
env.end = code + sb.st_size;
env.curname = aml_get_rootname();
aml_local_stack_push(aml_local_stack_create());
aml_parse_objectlist(&env, 0);
aml_local_stack_delete(aml_local_stack_pop());
assert(env.dp == env.end);
env.dp = code;
env.end = code + sb.st_size;
printf("done\n");
aml_debug = 1;
if (showtree_enabled == 1) {
aml_showtree(env.curname, 0);
}
do {
aml_dbgr(&env, &env);
} while (env.stat != aml_stat_panic);
aml_debug = 0;
if (regdump_enabled == 1) {
aml_simulation_regdump("region.dmp");
}
while (name_group_list->id != AML_NAME_GROUP_ROOT) {
aml_delete_name_group(name_group_list);
}
if (memstat_enabled == 1) {
memman_statistics(aml_memman);
}
memman_freeall(aml_memman);
return (0);
}
__dead static void
usage(const char *progname)
{
printf("usage: %s [-d] [-s] [-t] [-h] dsdt_files...\n", progname);
exit(1);
}
int
main(int argc, char *argv[])
{
char *progname;
int c, i;
progname = argv[0];
while ((c = getopt(argc, argv, "dsth")) != -1) {
switch (c) {
case 'd':
regdump_enabled = 1;
break;
case 's':
memstat_enabled = 1;
break;
case 't':
showtree_enabled = 1;
break;
case 'h':
default:
usage(progname);
}
}
argc -= optind;
argv += optind;
if (argc == 0) {
usage(progname);
}
for (i = 0; i < argc; i++) {
load_dsdt(argv[i]);
}
return (0);
}