ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/src/trunk/usr.sbin/acpi/acpidb/acpidb.c
Revision: 6425
Committed: Sat Nov 30 22:34:04 2013 UTC (10 years, 5 months ago) by laffer1
Content type: text/plain
File size: 12255 byte(s)
Log Message:
reset props for svn keywords

File Contents

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

Properties

Name Value
cvs2svn:cvs-rev 1.2
svn:keywords MidnightBSD=%H