Bug Summary

File:src/usr.sbin/acpidump/acpidump.c
Warning:line 527, column 2
Value stored to 'dp' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name acpidump.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/usr.sbin/acpidump/obj -resource-dir /usr/local/lib/clang/13.0.0 -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.sbin/acpidump/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/usr.sbin/acpidump/acpidump.c
1/* $OpenBSD: acpidump.c,v 1.24 2021/07/12 15:09:20 beck Exp $ */
2/*
3 * Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 */
28
29#include <sys/types.h>
30#include <sys/mman.h>
31#include <sys/queue.h>
32#include <sys/stat.h>
33
34#include <assert.h>
35#include <err.h>
36#include <fcntl.h>
37#include <kvm.h>
38#include <stdio.h>
39#include <stdlib.h>
40#include <string.h>
41#include <unistd.h>
42#include <limits.h>
43#include <paths.h>
44
45
46#define vm_page_sizesysconf(28) sysconf(_SC_PAGESIZE28)
47#define PRINTFLAG(xx)do { if (facp->flags & ACPI_FACP_FLAG_xx) { fprintf(fhdr
, "%c%s", sep, "xx"); sep = ','; } } while (0)
\
48 do { \
49 if (facp->flags & ACPI_FACP_FLAG_## xx) { \
50 fprintf(fhdr, "%c%s", sep, #xx); sep = ','; \
51 } \
52 } while (0)
53
54
55typedef unsigned long vm_offset_t;
56
57struct ACPIrsdp {
58 u_char signature[8];
59 u_char sum;
60 u_char oem[6];
61 u_char rev;
62 u_int32_t addr;
63#define SIZEOF_RSDP_REV_020 20
64 u_int32_t len;
65 u_int64_t xaddr;
66 u_char xsum;
67 u_char xres[3];
68} __packed__attribute__((__packed__));
69
70struct ACPIsdt {
71 u_char signature[4];
72 u_int32_t len;
73 u_char rev;
74 u_char check;
75 u_char oemid[6];
76 u_char oemtblid[8];
77 u_int32_t oemrev;
78 u_char creator[4];
79 u_int32_t crerev;
80#define SIZEOF_SDT_HDR36 36 /* struct size except body */
81 u_int32_t body[1];/* This member should be casted */
82} __packed__attribute__((__packed__));
83
84struct ACPIgas {
85 u_int8_t address_space_id;
86#define ACPI_GAS_MEMORY0 0
87#define ACPI_GAS_IO1 1
88#define ACPI_GAS_PCI2 2
89#define ACPI_GAS_EMBEDDED3 3
90#define ACPI_GAS_SMBUS4 4
91#define ACPI_GAS_FIXED0x7f 0x7f
92 u_int8_t register_bit_width;
93 u_int8_t register_bit_offset;
94 u_int8_t res;
95 u_int64_t address;
96} __packed__attribute__((__packed__));
97
98struct FACPbody {
99 u_int32_t facs_ptr;
100 u_int32_t dsdt_ptr;
101 u_int8_t int_model;
102#define ACPI_FACP_INTMODEL_PIC0 0 /* Standard PC-AT PIC */
103#define ACPI_FACP_INTMODEL_APIC1 1 /* Multiple APIC */
104 u_char reserved1;
105 u_int16_t sci_int;
106 u_int32_t smi_cmd;
107 u_int8_t acpi_enable;
108 u_int8_t acpi_disable;
109 u_int8_t s4biosreq;
110 u_int8_t reserved2;
111 u_int32_t pm1a_evt_blk;
112 u_int32_t pm1b_evt_blk;
113 u_int32_t pm1a_cnt_blk;
114 u_int32_t pm1b_cnt_blk;
115 u_int32_t pm2_cnt_blk;
116 u_int32_t pm_tmr_blk;
117 u_int32_t gpe0_blk;
118 u_int32_t gpe1_blk;
119 u_int8_t pm1_evt_len;
120 u_int8_t pm1_cnt_len;
121 u_int8_t pm2_cnt_len;
122 u_int8_t pm_tmr_len;
123 u_int8_t gpe0_len;
124 u_int8_t gpe1_len;
125 u_int8_t gpe1_base;
126 u_int8_t reserved3;
127 u_int16_t p_lvl2_lat;
128 u_int16_t p_lvl3_lat;
129 u_int16_t flush_size;
130 u_int16_t flush_stride;
131 u_int8_t duty_off;
132 u_int8_t duty_width;
133 u_int8_t day_alrm;
134 u_int8_t mon_alrm;
135 u_int8_t century;
136 u_int16_t iapc_boot_arch;
137 u_char reserved4[1];
138 u_int32_t flags;
139#define ACPI_FACP_FLAG_WBINVD1 1 /* WBINVD is correctly supported */
140#define ACPI_FACP_FLAG_WBINVD_FLUSH2 2 /* WBINVD flushes caches */
141#define ACPI_FACP_FLAG_PROC_C14 4 /* C1 power state supported */
142#define ACPI_FACP_FLAG_P_LVL2_UP8 8 /* C2 power state works on SMP */
143#define ACPI_FACP_FLAG_PWR_BUTTON16 16 /* Power button uses control method */
144#define ACPI_FACP_FLAG_SLP_BUTTON32 32 /* Sleep button uses control method */
145#define ACPI_FACP_FLAG_FIX_RTC64 64 /* RTC wakeup not supported */
146#define ACPI_FACP_FLAG_RTC_S4128 128 /* RTC can wakeup from S4 state */
147#define ACPI_FACP_FLAG_TMR_VAL_EXT256 256 /* TMR_VAL is 32bit */
148#define ACPI_FACP_FLAG_DCK_CAP512 512 /* Can support docking */
149 struct ACPIgas reset_reg;
150 u_int8_t reset_value;
151 u_int8_t reserved5[3];
152 u_int64_t x_firmware_ctrl;
153 u_int64_t x_dsdt;
154 struct ACPIgas x_pm1a_evt_blk;
155 struct ACPIgas x_pm1b_evt_blk;
156 struct ACPIgas x_pm1a_cnt_blk;
157 struct ACPIgas x_pm1b_cnt_blk;
158 struct ACPIgas x_pm2_cnt_blk;
159 struct ACPIgas x_pm_tmr_blk;
160 struct ACPIgas x_gpe0_blk;
161 struct ACPIgas x_gpe1_blk;
162} __packed__attribute__((__packed__));
163
164struct acpi_user_mapping {
165 LIST_ENTRY(acpi_user_mapping)struct { struct acpi_user_mapping *le_next; struct acpi_user_mapping
**le_prev; }
link;
166 vm_offset_t pa;
167 caddr_t va;
168 size_t size;
169};
170
171LIST_HEAD(acpi_user_mapping_list, acpi_user_mapping)struct acpi_user_mapping_list { struct acpi_user_mapping *lh_first
; }
maplist;
172
173int acpi_mem_fd = -1;
174char *aml_dumpfile;
175int aml_dumpdir;
176FILE *fhdr;
177int quiet;
178
179int acpi_checksum(void *_p, size_t _length);
180struct acpi_user_mapping *acpi_user_find_mapping(vm_offset_t _pa, size_t _size);
181void *acpi_map_physical(vm_offset_t _pa, size_t _size);
182void acpi_user_init(void);
183struct ACPIrsdp *acpi_check_rsd_ptr(vm_offset_t _pa);
184struct ACPIrsdp *acpi_find_rsd_ptr(void);
185void acpi_print_string(char *_s, size_t _length);
186void acpi_print_rsd_ptr(struct ACPIrsdp *_rp);
187struct ACPIsdt *acpi_map_sdt(vm_offset_t _pa);
188void aml_dump(struct ACPIsdt *_hdr);
189void acpi_print_sdt(struct ACPIsdt *_sdp);
190void acpi_print_rsdt(struct ACPIsdt *_rsdp);
191void acpi_print_xsdt(struct ACPIsdt *_rsdp);
192void acpi_print_facp(struct FACPbody *_facp);
193void acpi_print_dsdt(struct ACPIsdt *_dsdp);
194void acpi_handle_dsdt(struct ACPIsdt *_dsdp);
195void acpi_handle_facp(struct FACPbody *_facp);
196void acpi_handle_rsdt(struct ACPIsdt *_rsdp);
197void acpi_handle_xsdt(struct ACPIsdt *_rsdp);
198void asl_dump_from_devmem(void);
199void usage(void);
200u_long efi_acpi_addr(void);
201
202
203struct ACPIsdt dsdt_header = {
204 "DSDT", 0, 1, 0, "OEMID", "OEMTBLID", 0x12345678, "CRTR", 0x12345678
205};
206
207int
208acpi_checksum(void *p, size_t length)
209{
210 u_int8_t *bp;
211 u_int8_t sum;
212
213 bp = p;
214 sum = 0;
215 while (length--)
216 sum += *bp++;
217
218 return (sum);
219}
220
221struct acpi_user_mapping *
222acpi_user_find_mapping(vm_offset_t pa, size_t size)
223{
224 struct acpi_user_mapping *map;
225 int page_mask = getpagesize() - 1;
226
227 /* First search for an existing mapping */
228 for (map = LIST_FIRST(&maplist)((&maplist)->lh_first); map; map = LIST_NEXT(map, link)((map)->link.le_next)) {
229 if (map->pa <= pa && map->size >= pa + size - map->pa)
230 return (map);
231 }
232
233 /* Then create a new one */
234#undef round_page
235#undef trunc_page
236#define round_page(x) (((x) + page_mask) & ~page_mask)
237#define trunc_page(x) ((x) & ~page_mask)
238 size = round_page(pa + size) - trunc_page(pa);
239 pa = trunc_page(pa);
240#undef round_page
241#undef trunc_page
242 map = malloc(sizeof(struct acpi_user_mapping));
243 if (!map)
244 errx(1, "out of memory");
245 map->pa = pa;
246 map->va = mmap(0, size, PROT_READ0x01, MAP_SHARED0x0001, acpi_mem_fd, pa);
247 map->size = size;
248 if (map->va == MAP_FAILED((void *)-1))
249 err(1, "can't map address");
250 LIST_INSERT_HEAD(&maplist, map, link)do { if (((map)->link.le_next = (&maplist)->lh_first
) != ((void *)0)) (&maplist)->lh_first->link.le_prev
= &(map)->link.le_next; (&maplist)->lh_first =
(map); (map)->link.le_prev = &(&maplist)->lh_first
; } while (0)
;
251
252 return (map);
253}
254
255void *
256acpi_map_physical(vm_offset_t pa, size_t size)
257{
258 struct acpi_user_mapping *map;
259
260 map = acpi_user_find_mapping(pa, size);
261 return (map->va + (pa - map->pa));
262}
263
264void
265acpi_user_init(void)
266{
267 if (acpi_mem_fd == -1) {
268 acpi_mem_fd = open("/dev/mem", O_RDONLY0x0000);
269 if (acpi_mem_fd == -1)
270 err(1, "opening /dev/mem");
271 LIST_INIT(&maplist)do { ((&maplist)->lh_first) = ((void *)0); } while (0);
272 }
273}
274
275struct ACPIrsdp *
276acpi_check_rsd_ptr(vm_offset_t pa)
277{
278 struct ACPIrsdp rp;
279
280 lseek(acpi_mem_fd, pa, SEEK_SET0);
281 read(acpi_mem_fd, &rp, SIZEOF_RSDP_REV_020);
282 if (memcmp(rp.signature, "RSD PTR ", 8) != 0)
283 return NULL((void *)0);
284
285 if (rp.rev >= 2) {
286 read(acpi_mem_fd, &(rp.len),
287 sizeof(struct ACPIrsdp) - SIZEOF_RSDP_REV_020);
288 if (acpi_checksum(&rp, sizeof(struct ACPIrsdp)) == 0)
289 return acpi_map_physical(pa, sizeof(struct ACPIrsdp));
290 }
291
292 if (acpi_checksum(&rp, SIZEOF_RSDP_REV_020) == 0)
293 return (acpi_map_physical(pa, SIZEOF_RSDP_REV_020));
294
295 return NULL((void *)0);
296}
297
298struct ACPIrsdp *
299acpi_find_rsd_ptr(void)
300{
301 struct ACPIrsdp *rp;
302 u_long addr;
303
304 if ((addr = efi_acpi_addr()) != 0) {
305 if ((rp = acpi_check_rsd_ptr(addr)))
306 return rp;
307 }
308
309#if defined(__amd64__1) || defined (__i386__)
310 for (addr = 0; addr < 1024 * 1024; addr += 16) {
311 if ((rp = acpi_check_rsd_ptr(addr)))
312 return rp;
313 }
314#endif
315
316 return NULL((void *)0);
317}
318
319void
320acpi_print_string(char *s, size_t length)
321{
322 int c;
323
324 /* Trim trailing spaces and NULLs */
325 while (length > 0 && (s[length - 1] == ' ' || s[length - 1] == '\0'))
326 length--;
327
328 while (length--) {
329 c = *s++;
330 fputc(c, fhdr);
331 }
332}
333
334void
335acpi_print_rsd_ptr(struct ACPIrsdp *rp)
336{
337 fprintf(fhdr, "\n");
338 fprintf(fhdr, "RSD PTR: Checksum=%d, OEMID=", rp->sum);
339 acpi_print_string(rp->oem, 6);
340 fprintf(fhdr, ", Revision=%d", rp->rev);
341 fprintf(fhdr, ", RsdtAddress=0x%08x\n", rp->addr);
342 if (rp->rev >= 2) {
343 fprintf(fhdr, "\tLength=%d", rp->len);
344 fprintf(fhdr, ", XsdtAddress=0x%016llx", rp->xaddr);
345 fprintf(fhdr, ", Extended Checksum=%d\n", rp->xsum);
346 }
347 fprintf(fhdr, "\n");
348}
349
350struct ACPIsdt *
351acpi_map_sdt(vm_offset_t pa)
352{
353 struct ACPIsdt *sp;
354
355 sp = acpi_map_physical(pa, sizeof(struct ACPIsdt));
356 sp = acpi_map_physical(pa, sp->len);
357 return (sp);
358}
359
360void
361aml_dump(struct ACPIsdt *hdr)
362{
363 static int hdr_index;
364 char name[PATH_MAX1024];
365 int fd;
366 mode_t mode;
367
368 snprintf(name, sizeof(name), "%s%c%c%c%c%c.%d",
369 aml_dumpfile, aml_dumpdir ? '/' : '.',
370 hdr->signature[0], hdr->signature[1],
371 hdr->signature[2], hdr->signature[3],
372 hdr_index++);
373
374 mode = (S_IRUSR0000400 | S_IWUSR0000200 | S_IRGRP0000040 | S_IROTH0000004);
375 fd = open(name, O_WRONLY0x0001 | O_CREAT0x0200 | O_TRUNC0x0400, mode);
376 if (fd == -1)
377 err(1, "aml_dump");
378
379 write(fd, hdr, SIZEOF_SDT_HDR36);
380 write(fd, hdr->body, hdr->len - SIZEOF_SDT_HDR36);
381 close(fd);
382}
383
384void
385acpi_print_sdt(struct ACPIsdt *sdp)
386{
387 fprintf(fhdr, "\n");
388 acpi_print_string(sdp->signature, 4);
389 fprintf(fhdr, ": Length=%d, Revision=%d, Checksum=%d,\n",
390 sdp->len, sdp->rev, sdp->check);
391 fprintf(fhdr, "\tOEMID=");
392 acpi_print_string(sdp->oemid, 6);
393 fprintf(fhdr, ", OEM Table ID=");
394 acpi_print_string(sdp->oemtblid, 8);
395 fprintf(fhdr, ", OEM Revision=0x%x,\n", sdp->oemrev);
396 fprintf(fhdr, "\tCreator ID=");
397 acpi_print_string(sdp->creator, 4);
398 fprintf(fhdr, ", Creator Revision=0x%x\n", sdp->crerev);
399 fprintf(fhdr, "\n");
400 if (!memcmp(sdp->signature, "DSDT", 4))
401 memcpy(&dsdt_header, sdp, sizeof(dsdt_header));
402}
403
404void
405acpi_print_rsdt(struct ACPIsdt *rsdp)
406{
407 int i, entries;
408
409 acpi_print_sdt(rsdp);
410 entries = (rsdp->len - SIZEOF_SDT_HDR36) / sizeof(u_int32_t);
411 fprintf(fhdr, "\n");
412 fprintf(fhdr, "\tEntries={ ");
413 for (i = 0; i < entries; i++) {
414 if (i > 0)
415 fprintf(fhdr, ", ");
416 fprintf(fhdr, "0x%08x", rsdp->body[i]);
417 }
418 fprintf(fhdr, " }\n");
419 fprintf(fhdr, "\n");
420}
421
422void
423acpi_print_xsdt(struct ACPIsdt *rsdp)
424{
425 int i, entries;
426 u_int64_t *body = (u_int64_t *) rsdp->body;
427
428 acpi_print_sdt(rsdp);
429 entries = (rsdp->len - SIZEOF_SDT_HDR36) / sizeof(u_int64_t);
430 fprintf(fhdr, "\n");
431 fprintf(fhdr, "\tEntries={ ");
432 for (i = 0; i < entries; i++) {
433 if (i > 0)
434 fprintf(fhdr, ", ");
435 fprintf(fhdr, "0x%016llx", body[i]);
436 }
437 fprintf(fhdr, " }\n");
438 fprintf(fhdr, "\n");
439}
440
441void
442acpi_print_facp(struct FACPbody *facp)
443{
444 char sep;
445
446 fprintf(fhdr, "\n");
447 fprintf(fhdr, "\tDSDT=0x%x\n", facp->dsdt_ptr);
448 fprintf(fhdr, "\tINT_MODEL=%s\n", facp->int_model ? "APIC" : "PIC");
449 fprintf(fhdr, "\tSCI_INT=%d\n", facp->sci_int);
450 fprintf(fhdr, "\tSMI_CMD=0x%x, ", facp->smi_cmd);
451 fprintf(fhdr, "ACPI_ENABLE=0x%x, ", facp->acpi_enable);
452 fprintf(fhdr, "ACPI_DISABLE=0x%x, ", facp->acpi_disable);
453 fprintf(fhdr, "S4BIOS_REQ=0x%x\n", facp->s4biosreq);
454 if (facp->pm1a_evt_blk)
455 fprintf(fhdr, "\tPM1a_EVT_BLK=0x%x-0x%x\n",
456 facp->pm1a_evt_blk,
457 facp->pm1a_evt_blk + facp->pm1_evt_len - 1);
458 if (facp->pm1b_evt_blk)
459 fprintf(fhdr, "\tPM1b_EVT_BLK=0x%x-0x%x\n",
460 facp->pm1b_evt_blk,
461 facp->pm1b_evt_blk + facp->pm1_evt_len - 1);
462 if (facp->pm1a_cnt_blk)
463 fprintf(fhdr, "\tPM1a_CNT_BLK=0x%x-0x%x\n",
464 facp->pm1a_cnt_blk,
465 facp->pm1a_cnt_blk + facp->pm1_cnt_len - 1);
466 if (facp->pm1b_cnt_blk)
467 fprintf(fhdr, "\tPM1b_CNT_BLK=0x%x-0x%x\n",
468 facp->pm1b_cnt_blk,
469 facp->pm1b_cnt_blk + facp->pm1_cnt_len - 1);
470 if (facp->pm2_cnt_blk)
471 fprintf(fhdr, "\tPM2_CNT_BLK=0x%x-0x%x\n",
472 facp->pm2_cnt_blk,
473 facp->pm2_cnt_blk + facp->pm2_cnt_len - 1);
474 if (facp->pm_tmr_blk)
475 fprintf(fhdr, "\tPM2_TMR_BLK=0x%x-0x%x\n",
476 facp->pm_tmr_blk,
477 facp->pm_tmr_blk + facp->pm_tmr_len - 1);
478 if (facp->gpe0_blk)
479 fprintf(fhdr, "\tPM2_GPE0_BLK=0x%x-0x%x\n",
480 facp->gpe0_blk,
481 facp->gpe0_blk + facp->gpe0_len - 1);
482 if (facp->gpe1_blk)
483 fprintf(fhdr, "\tPM2_GPE1_BLK=0x%x-0x%x, GPE1_BASE=%d\n",
484 facp->gpe1_blk,
485 facp->gpe1_blk + facp->gpe1_len - 1,
486 facp->gpe1_base);
487 fprintf(fhdr, "\tP_LVL2_LAT=%dms, P_LVL3_LAT=%dms\n",
488 facp->p_lvl2_lat, facp->p_lvl3_lat);
489 fprintf(fhdr, "\tFLUSH_SIZE=%d, FLUSH_STRIDE=%d\n",
490 facp->flush_size, facp->flush_stride);
491 fprintf(fhdr, "\tDUTY_OFFSET=%d, DUTY_WIDTH=%d\n",
492 facp->duty_off, facp->duty_width);
493 fprintf(fhdr, "\tDAY_ALRM=%d, MON_ALRM=%d, CENTURY=%d\n",
494 facp->day_alrm, facp->mon_alrm, facp->century);
495 fprintf(fhdr, "\tFlags=");
496 sep = '{';
497
498 PRINTFLAG(WBINVD)do { if (facp->flags & 1) { fprintf(fhdr, "%c%s", sep,
"WBINVD"); sep = ','; } } while (0)
;
499 PRINTFLAG(WBINVD_FLUSH)do { if (facp->flags & 2) { fprintf(fhdr, "%c%s", sep,
"WBINVD_FLUSH"); sep = ','; } } while (0)
;
500 PRINTFLAG(PROC_C1)do { if (facp->flags & 4) { fprintf(fhdr, "%c%s", sep,
"PROC_C1"); sep = ','; } } while (0)
;
501 PRINTFLAG(P_LVL2_UP)do { if (facp->flags & 8) { fprintf(fhdr, "%c%s", sep,
"P_LVL2_UP"); sep = ','; } } while (0)
;
502 PRINTFLAG(PWR_BUTTON)do { if (facp->flags & 16) { fprintf(fhdr, "%c%s", sep
, "PWR_BUTTON"); sep = ','; } } while (0)
;
503 PRINTFLAG(SLP_BUTTON)do { if (facp->flags & 32) { fprintf(fhdr, "%c%s", sep
, "SLP_BUTTON"); sep = ','; } } while (0)
;
504 PRINTFLAG(FIX_RTC)do { if (facp->flags & 64) { fprintf(fhdr, "%c%s", sep
, "FIX_RTC"); sep = ','; } } while (0)
;
505 PRINTFLAG(RTC_S4)do { if (facp->flags & 128) { fprintf(fhdr, "%c%s", sep
, "RTC_S4"); sep = ','; } } while (0)
;
506 PRINTFLAG(TMR_VAL_EXT)do { if (facp->flags & 256) { fprintf(fhdr, "%c%s", sep
, "TMR_VAL_EXT"); sep = ','; } } while (0)
;
507 PRINTFLAG(DCK_CAP)do { if (facp->flags & 512) { fprintf(fhdr, "%c%s", sep
, "DCK_CAP"); sep = ','; } } while (0)
;
508
509 fprintf(fhdr, "}\n");
510 fprintf(fhdr, "\n");
511}
512
513void
514acpi_print_dsdt(struct ACPIsdt *dsdp)
515{
516 acpi_print_sdt(dsdp);
517}
518
519void
520acpi_handle_dsdt(struct ACPIsdt *dsdp)
521{
522 u_int8_t *dp;
523 u_int8_t *end;
524
525 acpi_print_dsdt(dsdp);
526
527 dp = (u_int8_t *)dsdp->body;
Value stored to 'dp' is never read
528 end = (u_int8_t *)dsdp + dsdp->len;
529}
530
531void
532acpi_handle_facp(struct FACPbody *facp)
533{
534 struct ACPIsdt *dsdp;
535
536 acpi_print_facp(facp);
537 if (facp->dsdt_ptr == 0)
538 dsdp = (struct ACPIsdt *) acpi_map_sdt(facp->x_dsdt);
539 else
540 dsdp = (struct ACPIsdt *) acpi_map_sdt(facp->dsdt_ptr);
541 if (acpi_checksum(dsdp, dsdp->len))
542 errx(1, "DSDT is corrupt");
543 acpi_handle_dsdt(dsdp);
544 aml_dump(dsdp);
545}
546
547void
548acpi_handle_rsdt(struct ACPIsdt *rsdp)
549{
550 int i;
551 int entries;
552 struct ACPIsdt *sdp;
553
554 aml_dump(rsdp);
555 entries = (rsdp->len - SIZEOF_SDT_HDR36) / sizeof(u_int32_t);
556 acpi_print_rsdt(rsdp);
557 for (i = 0; i < entries; i++) {
558 sdp = (struct ACPIsdt *) acpi_map_sdt(rsdp->body[i]);
559 if (acpi_checksum(sdp, sdp->len))
560 errx(1, "RSDT entry %d is corrupt", i);
561 aml_dump(sdp);
562 if (!memcmp(sdp->signature, "FACP", 4)) {
563 acpi_handle_facp((struct FACPbody *) sdp->body);
564 } else {
565 acpi_print_sdt(sdp);
566 }
567 }
568}
569
570void
571acpi_handle_xsdt(struct ACPIsdt *rsdp)
572{
573 int i;
574 int entries;
575 struct ACPIsdt *sdp;
576 u_int64_t *body = (u_int64_t *) rsdp->body;
577
578 aml_dump(rsdp);
579 entries = (rsdp->len - SIZEOF_SDT_HDR36) / sizeof(u_int64_t);
580 acpi_print_xsdt(rsdp);
581 for (i = 0; i < entries; i++) {
582 sdp = (struct ACPIsdt *) acpi_map_sdt(body[i]);
583 if (acpi_checksum(sdp, sdp->len))
584 errx(1, "XSDT entry %d is corrupt", i);
585 aml_dump(sdp);
586 if (!memcmp(sdp->signature, "FACP", 4)) {
587 acpi_handle_facp((struct FACPbody *) sdp->body);
588 } else {
589 acpi_print_sdt(sdp);
590 }
591 }
592}
593
594void
595asl_dump_from_devmem(void)
596{
597 struct ACPIrsdp *rp;
598 struct ACPIsdt *rsdp;
599 char name[PATH_MAX1024];
600
601 snprintf(name, sizeof(name), "%s%cheaders", aml_dumpfile,
602 aml_dumpdir ? '/' : '.');
603
604 acpi_user_init();
605
606 /* Can only unveil if being dumped to a dir */
607 if (aml_dumpdir) {
608 if (unveil(aml_dumpfile, "wc") == -1)
609 err(1, "unveil %s", aml_dumpfile);
610 } else if (aml_dumpfile[0] == '/') { /* admittedly pretty shitty */
611 if (unveil("/", "wc") == -1)
612 err(1, "unveil /");
613 } else {
614 if (unveil(".", "wc") == -1)
615 err(1, "unveil .");
616 }
617
618 if (unveil(_PATH_MEM"/dev/mem", "r") == -1)
619 err(1, "unveil %s", _PATH_MEM"/dev/mem");
620 if (unveil(_PATH_KMEM"/dev/kmem", "r") == -1)
621 err(1, "unveil %s", _PATH_KMEM"/dev/kmem");
622 if (unveil(_PATH_KVMDB"/var/db/kvm_bsd.db", "r") == -1)
623 err(1, "unveil %s", _PATH_KVMDB"/var/db/kvm_bsd.db");
624 if (unveil(_PATH_KSYMS"/dev/ksyms", "r") == -1)
625 err(1, "unveil %s", _PATH_KSYMS"/dev/ksyms");
626 if (unveil(_PATH_UNIX"/bsd", "r") == -1)
627 err(1, "unveil %s", _PATH_UNIX"/bsd");
628 if (pledge("stdio rpath wpath cpath", NULL((void *)0)) == -1)
629 err(1, "pledge");
630
631 rp = acpi_find_rsd_ptr();
632 if (!rp) {
633 if (!quiet)
634 warnx("Can't find ACPI information");
635 exit(1);
636 }
637
638 fhdr = fopen(name, "w");
639 if (fhdr == NULL((void *)0))
640 err(1, "asl_dump_from_devmem");
641
642 acpi_print_rsd_ptr(rp);
643
644 if (rp->rev == 2 && rp->xaddr) {
645 rsdp = (struct ACPIsdt *) acpi_map_sdt(rp->xaddr);
646 if (memcmp(rsdp->signature, "XSDT", 4) ||
647 acpi_checksum(rsdp, rsdp->len))
648 errx(1, "XSDT is corrupted");
649
650 acpi_handle_xsdt(rsdp);
651 } else if (rp->addr) {
652 rsdp = (struct ACPIsdt *) acpi_map_sdt(rp->addr);
653 if (memcmp(rsdp->signature, "RSDT", 4) ||
654 acpi_checksum(rsdp, rsdp->len))
655 errx(1, "RSDT is corrupted");
656
657 acpi_handle_rsdt(rsdp);
658 } else
659 errx(1, "XSDT or RSDT not found");
660
661 fclose(fhdr);
662}
663
664void
665usage(void)
666{
667 extern char *__progname;
668
669 fprintf(stderr(&__sF[2]), "usage: %s -o prefix\n", __progname);
670 exit(1);
671}
672
673int
674main(int argc, char *argv[])
675{
676 struct stat st;
677 int c;
678
679 while ((c = getopt(argc, argv, "o:q")) != -1) {
680 switch (c) {
681 case 'o':
682 aml_dumpfile = optarg;
683 break;
684 case 'q':
685 quiet = 1;
686 break;
687 default:
688 usage();
689 break;
690 }
691 }
692
693 if (aml_dumpfile == NULL((void *)0))
694 usage();
695
696 if (stat(aml_dumpfile, &st) == 0 && S_ISDIR(st.st_mode)((st.st_mode & 0170000) == 0040000))
697 aml_dumpdir = 1;
698
699 asl_dump_from_devmem();
700
701 return (0);
702}
703
704#ifdef __aarch64__
705
706u_long
707efi_acpi_addr(void)
708{
709 kvm_t *kd;
710 struct nlist nl[2];
711 uint64_t table;
712
713 memset(&nl, 0, sizeof(nl));
714 kd = kvm_openfiles(NULL((void *)0), NULL((void *)0), NULL((void *)0), O_RDONLY0x0000, NULL((void *)0));
715 if (kd == NULL((void *)0))
716 goto on_error;
717 nl[0].n_name = "efi_acpi_table";
718 if (kvm_nlist(kd, nl) == -1)
719 goto on_error;
720 if (kvm_read(kd, nl[0].n_value, &table, sizeof(table)) == -1)
721 goto on_error;
722
723 kvm_close(kd);
724 return table;
725
726on_error:
727 if (kd != NULL((void *)0))
728 kvm_close(kd);
729 return (0);
730}
731
732#else
733
734#include <machine/biosvar.h>
735
736u_long
737efi_acpi_addr(void)
738{
739 kvm_t *kd;
740 struct nlist nl[2];
741 bios_efiinfo_t efiinfo;
742 u_long ptr;
743
744 memset(&nl, 0, sizeof(nl));
745 kd = kvm_openfiles(NULL((void *)0), NULL((void *)0), NULL((void *)0), O_RDONLY0x0000, NULL((void *)0));
746 if (kd == NULL((void *)0))
747 goto on_error;
748 nl[0].n_name = "_bios_efiinfo";
749 if (kvm_nlist(kd, nl) == -1)
750 goto on_error;
751 if (kvm_read(kd, nl[0].n_value, &ptr, sizeof(ptr)) == -1)
752 goto on_error;
753 if (kvm_read(kd, ptr, &efiinfo, sizeof(efiinfo)) == -1)
754 goto on_error;
755
756 kvm_close(kd);
757 return (efiinfo.config_acpi);
758
759on_error:
760 if (kd != NULL((void *)0))
761 kvm_close(kd);
762 return (0);
763}
764
765#endif