1a42b7543SNate Lawson /*- 2a42b7543SNate Lawson * Copyright (c) 2000-2002 Mitsuru IWASAKI <iwasaki@FreeBSD.org> 3a42b7543SNate Lawson * All rights reserved. 4a42b7543SNate Lawson * 5a42b7543SNate Lawson * Redistribution and use in source and binary forms, with or without 6a42b7543SNate Lawson * modification, are permitted provided that the following conditions 7a42b7543SNate Lawson * are met: 8a42b7543SNate Lawson * 1. Redistributions of source code must retain the above copyright 9a42b7543SNate Lawson * notice, this list of conditions and the following disclaimer. 10a42b7543SNate Lawson * 2. Redistributions in binary form must reproduce the above copyright 11a42b7543SNate Lawson * notice, this list of conditions and the following disclaimer in the 12a42b7543SNate Lawson * documentation and/or other materials provided with the distribution. 13a42b7543SNate Lawson * 14a42b7543SNate Lawson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15a42b7543SNate Lawson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16a42b7543SNate Lawson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17a42b7543SNate Lawson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18a42b7543SNate Lawson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19a42b7543SNate Lawson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20a42b7543SNate Lawson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21a42b7543SNate Lawson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22a42b7543SNate Lawson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23a42b7543SNate Lawson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24a42b7543SNate Lawson * SUCH DAMAGE. 25a42b7543SNate Lawson * 26a42b7543SNate Lawson * $FreeBSD$ 27a42b7543SNate Lawson */ 28a42b7543SNate Lawson 29a42b7543SNate Lawson #include <sys/param.h> 30a42b7543SNate Lawson #include <sys/queue.h> 31a42b7543SNate Lawson #include <sys/mman.h> 32a42b7543SNate Lawson #include <sys/stat.h> 332be4e471SJung-uk Kim #include <sys/stdint.h> 34a42b7543SNate Lawson #include <sys/types.h> 35a42b7543SNate Lawson 36a42b7543SNate Lawson #include <assert.h> 37a42b7543SNate Lawson #include <ctype.h> 38a42b7543SNate Lawson #include <err.h> 39a42b7543SNate Lawson #include <fcntl.h> 40a42b7543SNate Lawson #include <limits.h> 41a42b7543SNate Lawson #include <stdio.h> 42a42b7543SNate Lawson #include <stdlib.h> 43a42b7543SNate Lawson #include <unistd.h> 44a42b7543SNate Lawson 4599065116SJung-uk Kim #include <contrib/dev/acpica/include/acpi.h> 463f0275a0SJung-uk Kim #include <contrib/dev/acpica/include/accommon.h> 47f8146b88SJung-uk Kim #include <contrib/dev/acpica/include/acapps.h> 483f0275a0SJung-uk Kim #include <contrib/dev/acpica/include/acdebug.h> 49313a0c13SJung-uk Kim #include <contrib/dev/acpica/include/amlresrc.h> 50a42b7543SNate Lawson 51a42b7543SNate Lawson /* 52a42b7543SNate Lawson * Dummy DSDT Table Header 53a42b7543SNate Lawson */ 54a42b7543SNate Lawson 55d5af120cSJung-uk Kim static ACPI_TABLE_HEADER dummy_dsdt_table = { 56a42b7543SNate Lawson "DSDT", 123, 1, 123, "OEMID", "OEMTBLID", 1, "CRID", 1 57a42b7543SNate Lawson }; 58a42b7543SNate Lawson 59a42b7543SNate Lawson /* 60a42b7543SNate Lawson * Region space I/O routines on virtual machine 61a42b7543SNate Lawson */ 62a42b7543SNate Lawson 63d5af120cSJung-uk Kim static int aml_debug_prompt = 1; 64a42b7543SNate Lawson 65a42b7543SNate Lawson struct ACPIRegionContent { 66a42b7543SNate Lawson TAILQ_ENTRY(ACPIRegionContent) links; 67a42b7543SNate Lawson int regtype; 68a42b7543SNate Lawson ACPI_PHYSICAL_ADDRESS addr; 69a42b7543SNate Lawson UINT8 value; 70a42b7543SNate Lawson }; 71a42b7543SNate Lawson 72a42b7543SNate Lawson TAILQ_HEAD(ACPIRegionContentList, ACPIRegionContent); 73d5af120cSJung-uk Kim static struct ACPIRegionContentList RegionContentList; 74a42b7543SNate Lawson 75a42b7543SNate Lawson static int aml_simulation_initialized = 0; 76a42b7543SNate Lawson 77d5af120cSJung-uk Kim ACPI_PHYSICAL_ADDRESS AeLocalGetRootPointer(void); 781c0e1b6dSJung-uk Kim void AeDoObjectOverrides(void); 79d5af120cSJung-uk Kim void AeTableOverride(ACPI_TABLE_HEADER *, ACPI_TABLE_HEADER **); 80d5af120cSJung-uk Kim 81a42b7543SNate Lawson static void aml_simulation_init(void); 82a42b7543SNate Lawson static int aml_simulate_regcontent_add(int regtype, 83a42b7543SNate Lawson ACPI_PHYSICAL_ADDRESS addr, 84a42b7543SNate Lawson UINT8 value); 85a42b7543SNate Lawson static int aml_simulate_regcontent_read(int regtype, 86a42b7543SNate Lawson ACPI_PHYSICAL_ADDRESS addr, 87a42b7543SNate Lawson UINT8 *valuep); 88a42b7543SNate Lawson static int aml_simulate_regcontent_write(int regtype, 89a42b7543SNate Lawson ACPI_PHYSICAL_ADDRESS addr, 90a42b7543SNate Lawson UINT8 *valuep); 919a179dd8SJung-uk Kim static UINT64 aml_simulate_prompt(char *msg, UINT64 def_val); 92a42b7543SNate Lawson static void aml_simulation_regload(const char *dumpfile); 93a42b7543SNate Lawson static void aml_simulation_regdump(const char *dumpfile); 94a42b7543SNate Lawson 952be4e471SJung-uk Kim /* Stubs to simplify linkage to the ACPICA core subsystem. */ 96d5af120cSJung-uk Kim ACPI_PHYSICAL_ADDRESS 97313a0c13SJung-uk Kim AcpiOsGetRootPointer(void) 982be4e471SJung-uk Kim { 9999065116SJung-uk Kim 100d5af120cSJung-uk Kim return (0); 10199065116SJung-uk Kim } 10299065116SJung-uk Kim 10399065116SJung-uk Kim void 1041c0e1b6dSJung-uk Kim AeDoObjectOverrides(void) 1051c0e1b6dSJung-uk Kim { 1061c0e1b6dSJung-uk Kim } 1071c0e1b6dSJung-uk Kim 1081c0e1b6dSJung-uk Kim void 10999065116SJung-uk Kim AeTableOverride(ACPI_TABLE_HEADER *ExistingTable, ACPI_TABLE_HEADER **NewTable) 11099065116SJung-uk Kim { 1112be4e471SJung-uk Kim } 1122be4e471SJung-uk Kim 113313a0c13SJung-uk Kim void 114313a0c13SJung-uk Kim MpSaveGpioInfo(ACPI_PARSE_OBJECT *Op, AML_RESOURCE *Resource, 115313a0c13SJung-uk Kim UINT32 PinCount, UINT16 *PinList, char *DeviceName) 116313a0c13SJung-uk Kim { 117313a0c13SJung-uk Kim } 118313a0c13SJung-uk Kim 119313a0c13SJung-uk Kim void 120313a0c13SJung-uk Kim MpSaveSerialInfo(ACPI_PARSE_OBJECT *Op, AML_RESOURCE *Resource, 121313a0c13SJung-uk Kim char *DeviceName) 122313a0c13SJung-uk Kim { 123313a0c13SJung-uk Kim } 124313a0c13SJung-uk Kim 125a42b7543SNate Lawson static void 126a42b7543SNate Lawson aml_simulation_init(void) 127a42b7543SNate Lawson { 128a42b7543SNate Lawson 129a42b7543SNate Lawson aml_simulation_initialized = 1; 130a42b7543SNate Lawson TAILQ_INIT(&RegionContentList); 131a42b7543SNate Lawson aml_simulation_regload("region.ini"); 132a42b7543SNate Lawson } 133a42b7543SNate Lawson 134a42b7543SNate Lawson static int 135a42b7543SNate Lawson aml_simulate_regcontent_add(int regtype, ACPI_PHYSICAL_ADDRESS addr, UINT8 value) 136a42b7543SNate Lawson { 137a42b7543SNate Lawson struct ACPIRegionContent *rc; 138a42b7543SNate Lawson 139a42b7543SNate Lawson rc = malloc(sizeof(struct ACPIRegionContent)); 140a42b7543SNate Lawson if (rc == NULL) { 141a42b7543SNate Lawson return (-1); /* malloc fail */ 142a42b7543SNate Lawson } 143a42b7543SNate Lawson rc->regtype = regtype; 144a42b7543SNate Lawson rc->addr = addr; 145a42b7543SNate Lawson rc->value = value; 146a42b7543SNate Lawson 147a42b7543SNate Lawson TAILQ_INSERT_TAIL(&RegionContentList, rc, links); 148a42b7543SNate Lawson return (0); 149a42b7543SNate Lawson } 150a42b7543SNate Lawson 151a42b7543SNate Lawson static int 152a42b7543SNate Lawson aml_simulate_regcontent_read(int regtype, ACPI_PHYSICAL_ADDRESS addr, UINT8 *valuep) 153a42b7543SNate Lawson { 154a42b7543SNate Lawson struct ACPIRegionContent *rc; 155a42b7543SNate Lawson 156a42b7543SNate Lawson if (!aml_simulation_initialized) { 157a42b7543SNate Lawson aml_simulation_init(); 158a42b7543SNate Lawson } 159a42b7543SNate Lawson TAILQ_FOREACH(rc, &RegionContentList, links) { 160a42b7543SNate Lawson if (rc->regtype == regtype && rc->addr == addr) { 161a42b7543SNate Lawson *valuep = rc->value; 162a42b7543SNate Lawson return (1); /* found */ 163a42b7543SNate Lawson } 164a42b7543SNate Lawson } 165a42b7543SNate Lawson 166a42b7543SNate Lawson *valuep = 0; 167a42b7543SNate Lawson return (aml_simulate_regcontent_add(regtype, addr, *valuep)); 168a42b7543SNate Lawson } 169a42b7543SNate Lawson 170a42b7543SNate Lawson static int 171a42b7543SNate Lawson aml_simulate_regcontent_write(int regtype, ACPI_PHYSICAL_ADDRESS addr, UINT8 *valuep) 172a42b7543SNate Lawson { 173a42b7543SNate Lawson struct ACPIRegionContent *rc; 174a42b7543SNate Lawson 175a42b7543SNate Lawson if (!aml_simulation_initialized) { 176a42b7543SNate Lawson aml_simulation_init(); 177a42b7543SNate Lawson } 178a42b7543SNate Lawson TAILQ_FOREACH(rc, &RegionContentList, links) { 179a42b7543SNate Lawson if (rc->regtype == regtype && rc->addr == addr) { 180a42b7543SNate Lawson rc->value = *valuep; 181a42b7543SNate Lawson return (1); /* exists */ 182a42b7543SNate Lawson } 183a42b7543SNate Lawson } 184a42b7543SNate Lawson 185a42b7543SNate Lawson return (aml_simulate_regcontent_add(regtype, addr, *valuep)); 186a42b7543SNate Lawson } 187a42b7543SNate Lawson 1889a179dd8SJung-uk Kim static UINT64 1899a179dd8SJung-uk Kim aml_simulate_prompt(char *msg, UINT64 def_val) 190a42b7543SNate Lawson { 191a42b7543SNate Lawson char buf[16], *ep; 1929a179dd8SJung-uk Kim UINT64 val; 193a42b7543SNate Lawson 194a42b7543SNate Lawson val = def_val; 195a42b7543SNate Lawson printf("DEBUG"); 196a42b7543SNate Lawson if (msg != NULL) { 197a42b7543SNate Lawson printf("%s", msg); 198a42b7543SNate Lawson } 1990c10b85aSJung-uk Kim printf("(default: 0x%jx ", (uintmax_t)val); 2000c10b85aSJung-uk Kim printf(" / %ju) >>", (uintmax_t)val); 201a42b7543SNate Lawson fflush(stdout); 202a42b7543SNate Lawson 203a42b7543SNate Lawson bzero(buf, sizeof buf); 204a42b7543SNate Lawson while (1) { 205a42b7543SNate Lawson if (read(0, buf, sizeof buf) == 0) { 206a42b7543SNate Lawson continue; 207a42b7543SNate Lawson } 208a42b7543SNate Lawson if (buf[0] == '\n') { 209a42b7543SNate Lawson break; /* use default value */ 210a42b7543SNate Lawson } 211a42b7543SNate Lawson if (buf[0] == '0' && buf[1] == 'x') { 212a42b7543SNate Lawson val = strtoq(buf, &ep, 16); 213a42b7543SNate Lawson } else { 214a42b7543SNate Lawson val = strtoq(buf, &ep, 10); 215a42b7543SNate Lawson } 216a42b7543SNate Lawson break; 217a42b7543SNate Lawson } 218a42b7543SNate Lawson return (val); 219a42b7543SNate Lawson } 220a42b7543SNate Lawson 221a42b7543SNate Lawson static void 222a42b7543SNate Lawson aml_simulation_regload(const char *dumpfile) 223a42b7543SNate Lawson { 224a42b7543SNate Lawson char buf[256], *np, *ep; 225a42b7543SNate Lawson struct ACPIRegionContent rc; 226a42b7543SNate Lawson FILE *fp; 227a42b7543SNate Lawson 228a42b7543SNate Lawson if (!aml_simulation_initialized) { 229a42b7543SNate Lawson return; 230a42b7543SNate Lawson } 231a42b7543SNate Lawson 232a42b7543SNate Lawson if ((fp = fopen(dumpfile, "r")) == NULL) { 233a42b7543SNate Lawson return; 234a42b7543SNate Lawson } 235a42b7543SNate Lawson 236a42b7543SNate Lawson while (fgets(buf, sizeof buf, fp) != NULL) { 237a42b7543SNate Lawson np = buf; 238a42b7543SNate Lawson /* reading region type */ 239a42b7543SNate Lawson rc.regtype = strtoq(np, &ep, 10); 240a42b7543SNate Lawson if (np == ep) { 241a42b7543SNate Lawson continue; 242a42b7543SNate Lawson } 243a42b7543SNate Lawson np = ep; 244a42b7543SNate Lawson 245a42b7543SNate Lawson /* reading address */ 246a42b7543SNate Lawson rc.addr = strtoq(np, &ep, 16); 247a42b7543SNate Lawson if (np == ep) { 248a42b7543SNate Lawson continue; 249a42b7543SNate Lawson } 250a42b7543SNate Lawson np = ep; 251a42b7543SNate Lawson 252a42b7543SNate Lawson /* reading value */ 253a42b7543SNate Lawson rc.value = strtoq(np, &ep, 16); 254a42b7543SNate Lawson if (np == ep) { 255a42b7543SNate Lawson continue; 256a42b7543SNate Lawson } 257a42b7543SNate Lawson aml_simulate_regcontent_write(rc.regtype, rc.addr, &rc.value); 258a42b7543SNate Lawson } 259a42b7543SNate Lawson 260a42b7543SNate Lawson fclose(fp); 261a42b7543SNate Lawson } 262a42b7543SNate Lawson 263a42b7543SNate Lawson static void 264a42b7543SNate Lawson aml_simulation_regdump(const char *dumpfile) 265a42b7543SNate Lawson { 266a42b7543SNate Lawson struct ACPIRegionContent *rc; 267a42b7543SNate Lawson FILE *fp; 268a42b7543SNate Lawson 269a42b7543SNate Lawson if (!aml_simulation_initialized) { 270a42b7543SNate Lawson return; 271a42b7543SNate Lawson } 272a42b7543SNate Lawson if ((fp = fopen(dumpfile, "w")) == NULL) { 273a42b7543SNate Lawson warn("%s", dumpfile); 274a42b7543SNate Lawson return; 275a42b7543SNate Lawson } 276a42b7543SNate Lawson while (!TAILQ_EMPTY(&RegionContentList)) { 277a42b7543SNate Lawson rc = TAILQ_FIRST(&RegionContentList); 278e18d08c9SPhilip Paeps fprintf(fp, "%d 0x%jx 0x%x\n", 2792be4e471SJung-uk Kim rc->regtype, (uintmax_t)rc->addr, rc->value); 280a42b7543SNate Lawson TAILQ_REMOVE(&RegionContentList, rc, links); 281a42b7543SNate Lawson free(rc); 282a42b7543SNate Lawson } 283a42b7543SNate Lawson 284a42b7543SNate Lawson fclose(fp); 285a42b7543SNate Lawson TAILQ_INIT(&RegionContentList); 286a42b7543SNate Lawson } 287a42b7543SNate Lawson 288a42b7543SNate Lawson /* 289a42b7543SNate Lawson * Space handlers on virtual machine 290a42b7543SNate Lawson */ 291a42b7543SNate Lawson 292a42b7543SNate Lawson static ACPI_STATUS 293a42b7543SNate Lawson aml_vm_space_handler( 294a42b7543SNate Lawson UINT32 SpaceID, 295a42b7543SNate Lawson UINT32 Function, 296a42b7543SNate Lawson ACPI_PHYSICAL_ADDRESS Address, 297a42b7543SNate Lawson UINT32 BitWidth, 2989a179dd8SJung-uk Kim UINT64 *Value, 299a42b7543SNate Lawson int Prompt) 300a42b7543SNate Lawson { 301a42b7543SNate Lawson int state; 302a42b7543SNate Lawson UINT8 val; 3039a179dd8SJung-uk Kim UINT64 value, i; 304a42b7543SNate Lawson char msg[256]; 305e18d08c9SPhilip Paeps static const char *space_names[] = { 306a42b7543SNate Lawson "SYSTEM_MEMORY", "SYSTEM_IO", "PCI_CONFIG", 307a42b7543SNate Lawson "EC", "SMBUS", "CMOS", "PCI_BAR_TARGET"}; 308a42b7543SNate Lawson 309a42b7543SNate Lawson switch (Function) { 310a42b7543SNate Lawson case ACPI_READ: 311a42b7543SNate Lawson value = 0; 312a42b7543SNate Lawson for (i = 0; (i * 8) < BitWidth; i++) { 313a42b7543SNate Lawson state = aml_simulate_regcontent_read(SpaceID, 314a42b7543SNate Lawson Address + i, &val); 315a42b7543SNate Lawson if (state == -1) { 316a42b7543SNate Lawson return (AE_NO_MEMORY); 317a42b7543SNate Lawson } 318a42b7543SNate Lawson value |= val << (i * 8); 319a42b7543SNate Lawson } 320a42b7543SNate Lawson *Value = value; 321a42b7543SNate Lawson if (Prompt) { 322e18d08c9SPhilip Paeps sprintf(msg, "[read (%s, %2d, 0x%jx)]", 3232be4e471SJung-uk Kim space_names[SpaceID], BitWidth, 3242be4e471SJung-uk Kim (uintmax_t)Address); 325a42b7543SNate Lawson *Value = aml_simulate_prompt(msg, value); 326a42b7543SNate Lawson if (*Value != value) { 327a42b7543SNate Lawson return(aml_vm_space_handler(SpaceID, 328a42b7543SNate Lawson ACPI_WRITE, 329a42b7543SNate Lawson Address, BitWidth, Value, 0)); 330a42b7543SNate Lawson } 331a42b7543SNate Lawson } 332a42b7543SNate Lawson break; 333a42b7543SNate Lawson 334a42b7543SNate Lawson case ACPI_WRITE: 335a42b7543SNate Lawson value = *Value; 336a42b7543SNate Lawson if (Prompt) { 337e18d08c9SPhilip Paeps sprintf(msg, "[write(%s, %2d, 0x%jx)]", 3382be4e471SJung-uk Kim space_names[SpaceID], BitWidth, 3392be4e471SJung-uk Kim (uintmax_t)Address); 340a42b7543SNate Lawson value = aml_simulate_prompt(msg, *Value); 341a42b7543SNate Lawson } 342a42b7543SNate Lawson *Value = value; 343a42b7543SNate Lawson for (i = 0; (i * 8) < BitWidth; i++) { 344a42b7543SNate Lawson val = value & 0xff; 345a42b7543SNate Lawson state = aml_simulate_regcontent_write(SpaceID, 346a42b7543SNate Lawson Address + i, &val); 347a42b7543SNate Lawson if (state == -1) { 348a42b7543SNate Lawson return (AE_NO_MEMORY); 349a42b7543SNate Lawson } 350a42b7543SNate Lawson value = value >> 8; 351a42b7543SNate Lawson } 352a42b7543SNate Lawson } 353a42b7543SNate Lawson 354a42b7543SNate Lawson return (AE_OK); 355a42b7543SNate Lawson } 356a42b7543SNate Lawson 357a42b7543SNate Lawson #define DECLARE_VM_SPACE_HANDLER(name, id); \ 358a42b7543SNate Lawson static ACPI_STATUS \ 359a42b7543SNate Lawson aml_vm_space_handler_##name ( \ 360a42b7543SNate Lawson UINT32 Function, \ 361a42b7543SNate Lawson ACPI_PHYSICAL_ADDRESS Address, \ 362a42b7543SNate Lawson UINT32 BitWidth, \ 3639a179dd8SJung-uk Kim UINT64 *Value) \ 364a42b7543SNate Lawson { \ 365a42b7543SNate Lawson return (aml_vm_space_handler(id, Function, Address, \ 366a42b7543SNate Lawson BitWidth, Value, aml_debug_prompt)); \ 367a42b7543SNate Lawson } 368a42b7543SNate Lawson 369a42b7543SNate Lawson DECLARE_VM_SPACE_HANDLER(system_memory, ACPI_ADR_SPACE_SYSTEM_MEMORY); 370a42b7543SNate Lawson DECLARE_VM_SPACE_HANDLER(system_io, ACPI_ADR_SPACE_SYSTEM_IO); 371a42b7543SNate Lawson DECLARE_VM_SPACE_HANDLER(pci_config, ACPI_ADR_SPACE_PCI_CONFIG); 372a42b7543SNate Lawson DECLARE_VM_SPACE_HANDLER(ec, ACPI_ADR_SPACE_EC); 373a42b7543SNate Lawson DECLARE_VM_SPACE_HANDLER(smbus, ACPI_ADR_SPACE_SMBUS); 374a42b7543SNate Lawson DECLARE_VM_SPACE_HANDLER(cmos, ACPI_ADR_SPACE_CMOS); 375a42b7543SNate Lawson DECLARE_VM_SPACE_HANDLER(pci_bar_target,ACPI_ADR_SPACE_PCI_BAR_TARGET); 376a42b7543SNate Lawson 377a42b7543SNate Lawson /* 378a42b7543SNate Lawson * Load DSDT data file and invoke debugger 379a42b7543SNate Lawson */ 380a42b7543SNate Lawson 381a42b7543SNate Lawson static int 382a42b7543SNate Lawson load_dsdt(const char *dsdtfile) 383a42b7543SNate Lawson { 384a42b7543SNate Lawson char filetmp[PATH_MAX]; 385f8146b88SJung-uk Kim ACPI_NEW_TABLE_DESC *list; 386e18d08c9SPhilip Paeps u_int8_t *code; 387a42b7543SNate Lawson struct stat sb; 388*668bf37aSDon Lewis int dounlink, error, fd; 389a42b7543SNate Lawson 390a42b7543SNate Lawson fd = open(dsdtfile, O_RDONLY, 0); 391a42b7543SNate Lawson if (fd == -1) { 392a42b7543SNate Lawson perror("open"); 393a42b7543SNate Lawson return (-1); 394a42b7543SNate Lawson } 395a42b7543SNate Lawson if (fstat(fd, &sb) == -1) { 396a42b7543SNate Lawson perror("fstat"); 397de028133SKevin Lo close(fd); 398a42b7543SNate Lawson return (-1); 399a42b7543SNate Lawson } 400a42b7543SNate Lawson code = mmap(NULL, (size_t)sb.st_size, PROT_READ, MAP_PRIVATE, fd, (off_t)0); 401*668bf37aSDon Lewis close(fd); 402a42b7543SNate Lawson if (code == NULL) { 403a42b7543SNate Lawson perror("mmap"); 404a42b7543SNate Lawson return (-1); 405a42b7543SNate Lawson } 406a42b7543SNate Lawson if ((error = AcpiInitializeSubsystem()) != AE_OK) { 407*668bf37aSDon Lewis munmap(code, (size_t)sb.st_size); 408a42b7543SNate Lawson return (-1); 409a42b7543SNate Lawson } 410a42b7543SNate Lawson 411a42b7543SNate Lawson /* 412a42b7543SNate Lawson * make sure DSDT data contains table header or not. 413a42b7543SNate Lawson */ 414a42b7543SNate Lawson if (strncmp((char *)code, "DSDT", 4) == 0) { 415*668bf37aSDon Lewis dounlink = 0; 416*668bf37aSDon Lewis strlcpy(filetmp, dsdtfile, sizeof(filetmp)); 417a42b7543SNate Lawson } else { 418*668bf37aSDon Lewis dounlink = 1; 419a42b7543SNate Lawson mode_t mode = (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 420a42b7543SNate Lawson dummy_dsdt_table.Length = sizeof(ACPI_TABLE_HEADER) + sb.st_size; 421*668bf37aSDon Lewis if ((size_t)snprintf(filetmp, sizeof(filetmp), "%s.tmp", 422*668bf37aSDon Lewis dsdtfile) > sizeof(filetmp) - 1) { 423*668bf37aSDon Lewis fprintf(stderr, "file name too long\n"); 424*668bf37aSDon Lewis munmap(code, (size_t)sb.st_size); 425a42b7543SNate Lawson return (-1); 426a42b7543SNate Lawson } 427*668bf37aSDon Lewis fd = open(filetmp, O_WRONLY | O_CREAT | O_TRUNC, mode); 428*668bf37aSDon Lewis if (fd == -1) { 429*668bf37aSDon Lewis perror("open"); 430*668bf37aSDon Lewis munmap(code, (size_t)sb.st_size); 431*668bf37aSDon Lewis return (-1); 432a42b7543SNate Lawson } 433*668bf37aSDon Lewis write(fd, &dummy_dsdt_table, sizeof(ACPI_TABLE_HEADER)); 434*668bf37aSDon Lewis 435*668bf37aSDon Lewis write(fd, code, sb.st_size); 436*668bf37aSDon Lewis close(fd); 437*668bf37aSDon Lewis } 438*668bf37aSDon Lewis munmap(code, (size_t)sb.st_size); 439a42b7543SNate Lawson 440a42b7543SNate Lawson /* 441a42b7543SNate Lawson * Install the virtual machine version of address space handlers. 442a42b7543SNate Lawson */ 443a42b7543SNate Lawson if ((error = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT, 444a42b7543SNate Lawson ACPI_ADR_SPACE_SYSTEM_MEMORY, 445e18d08c9SPhilip Paeps (ACPI_ADR_SPACE_HANDLER)aml_vm_space_handler_system_memory, 446a42b7543SNate Lawson NULL, NULL)) != AE_OK) { 447a42b7543SNate Lawson fprintf(stderr, "could not initialise SystemMemory handler: %d\n", error); 448a42b7543SNate Lawson return (-1); 449a42b7543SNate Lawson } 450a42b7543SNate Lawson if ((error = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT, 451a42b7543SNate Lawson ACPI_ADR_SPACE_SYSTEM_IO, 452e18d08c9SPhilip Paeps (ACPI_ADR_SPACE_HANDLER)aml_vm_space_handler_system_io, 453a42b7543SNate Lawson NULL, NULL)) != AE_OK) { 454a42b7543SNate Lawson fprintf(stderr, "could not initialise SystemIO handler: %d\n", error); 455a42b7543SNate Lawson return (-1); 456a42b7543SNate Lawson } 457a42b7543SNate Lawson if ((error = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT, 458a42b7543SNate Lawson ACPI_ADR_SPACE_PCI_CONFIG, 459e18d08c9SPhilip Paeps (ACPI_ADR_SPACE_HANDLER)aml_vm_space_handler_pci_config, 460a42b7543SNate Lawson NULL, NULL)) != AE_OK) { 461a42b7543SNate Lawson fprintf(stderr, "could not initialise PciConfig handler: %d\n", error); 462a42b7543SNate Lawson return (-1); 463a42b7543SNate Lawson } 464a42b7543SNate Lawson if ((error = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT, 465a42b7543SNate Lawson ACPI_ADR_SPACE_EC, 466e18d08c9SPhilip Paeps (ACPI_ADR_SPACE_HANDLER)aml_vm_space_handler_ec, 467a42b7543SNate Lawson NULL, NULL)) != AE_OK) { 468a42b7543SNate Lawson fprintf(stderr, "could not initialise EC handler: %d\n", error); 469a42b7543SNate Lawson return (-1); 470a42b7543SNate Lawson } 471a42b7543SNate Lawson if ((error = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT, 472a42b7543SNate Lawson ACPI_ADR_SPACE_SMBUS, 473e18d08c9SPhilip Paeps (ACPI_ADR_SPACE_HANDLER)aml_vm_space_handler_smbus, 474a42b7543SNate Lawson NULL, NULL)) != AE_OK) { 475a42b7543SNate Lawson fprintf(stderr, "could not initialise SMBUS handler: %d\n", error); 476a42b7543SNate Lawson return (-1); 477a42b7543SNate Lawson } 478a42b7543SNate Lawson if ((error = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT, 479a42b7543SNate Lawson ACPI_ADR_SPACE_CMOS, 480e18d08c9SPhilip Paeps (ACPI_ADR_SPACE_HANDLER)aml_vm_space_handler_cmos, 481a42b7543SNate Lawson NULL, NULL)) != AE_OK) { 482a42b7543SNate Lawson fprintf(stderr, "could not initialise CMOS handler: %d\n", error); 483a42b7543SNate Lawson return (-1); 484a42b7543SNate Lawson } 485a42b7543SNate Lawson if ((error = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT, 486a42b7543SNate Lawson ACPI_ADR_SPACE_PCI_BAR_TARGET, 487e18d08c9SPhilip Paeps (ACPI_ADR_SPACE_HANDLER)aml_vm_space_handler_pci_bar_target, 488a42b7543SNate Lawson NULL, NULL)) != AE_OK) { 489a42b7543SNate Lawson fprintf(stderr, "could not initialise PCI BAR TARGET handler: %d\n", error); 490a42b7543SNate Lawson return (-1); 491a42b7543SNate Lawson } 492a42b7543SNate Lawson 493f8146b88SJung-uk Kim list = NULL; 494f8146b88SJung-uk Kim AcGetAllTablesFromFile(filetmp, TRUE, &list); 495a42b7543SNate Lawson 49670e6ab8fSJung-uk Kim AcpiInitializeDebugger(); 497a42b7543SNate Lawson AcpiGbl_DebuggerConfiguration = 0; 498a42b7543SNate Lawson AcpiDbUserCommands(':', NULL); 499a42b7543SNate Lawson 500*668bf37aSDon Lewis if (dounlink) { 501a42b7543SNate Lawson unlink(filetmp); 502a42b7543SNate Lawson } 503a42b7543SNate Lawson 504a42b7543SNate Lawson return (0); 505a42b7543SNate Lawson } 506a42b7543SNate Lawson 507a42b7543SNate Lawson static void 508a42b7543SNate Lawson usage(const char *progname) 509a42b7543SNate Lawson { 510a42b7543SNate Lawson 511a42b7543SNate Lawson printf("usage: %s dsdt_file\n", progname); 512a42b7543SNate Lawson exit(1); 513a42b7543SNate Lawson } 514a42b7543SNate Lawson 515a42b7543SNate Lawson int 516a42b7543SNate Lawson main(int argc, char *argv[]) 517a42b7543SNate Lawson { 518a42b7543SNate Lawson char *progname; 519a42b7543SNate Lawson 520a42b7543SNate Lawson progname = argv[0]; 521a42b7543SNate Lawson 522a42b7543SNate Lawson if (argc == 1) { 523a42b7543SNate Lawson usage(progname); 524a42b7543SNate Lawson } 525a42b7543SNate Lawson 526a42b7543SNate Lawson AcpiDbgLevel = ACPI_DEBUG_DEFAULT; 527a42b7543SNate Lawson 528a41e7b6aSNate Lawson /* 529a41e7b6aSNate Lawson * Match kernel options for the interpreter. Global variable names 530a41e7b6aSNate Lawson * can be found in acglobal.h. 531a41e7b6aSNate Lawson */ 532a41e7b6aSNate Lawson AcpiGbl_EnableInterpreterSlack = TRUE; 533a41e7b6aSNate Lawson 534a42b7543SNate Lawson aml_simulation_regload("region.ini"); 535a42b7543SNate Lawson if (load_dsdt(argv[1]) == 0) { 536a42b7543SNate Lawson aml_simulation_regdump("region.dmp"); 537a42b7543SNate Lawson } 538a42b7543SNate Lawson 539a42b7543SNate Lawson return (0); 540a42b7543SNate Lawson } 541