acpi.c revision 1.167 1 /* $NetBSD: acpi.c,v 1.167 2010/04/12 18:59:08 jruoho Exp $ */
2
3 /*-
4 * Copyright (c) 2003, 2007 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Charles M. Hannum of By Noon Software, Inc.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 /*
33 * Copyright 2001, 2003 Wasabi Systems, Inc.
34 * All rights reserved.
35 *
36 * Written by Jason R. Thorpe for Wasabi Systems, Inc.
37 *
38 * Redistribution and use in source and binary forms, with or without
39 * modification, are permitted provided that the following conditions
40 * are met:
41 * 1. Redistributions of source code must retain the above copyright
42 * notice, this list of conditions and the following disclaimer.
43 * 2. Redistributions in binary form must reproduce the above copyright
44 * notice, this list of conditions and the following disclaimer in the
45 * documentation and/or other materials provided with the distribution.
46 * 3. All advertising materials mentioning features or use of this software
47 * must display the following acknowledgement:
48 * This product includes software developed for the NetBSD Project by
49 * Wasabi Systems, Inc.
50 * 4. The name of Wasabi Systems, Inc. may not be used to endorse
51 * or promote products derived from this software without specific prior
52 * written permission.
53 *
54 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
55 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
56 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
57 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
58 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
59 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
60 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
61 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
62 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
63 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
64 * POSSIBILITY OF SUCH DAMAGE.
65 */
66
67 /*
68 * Autoconfiguration support for the Intel ACPI Component Architecture
69 * ACPI reference implementation.
70 */
71
72 #include <sys/cdefs.h>
73 __KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.167 2010/04/12 18:59:08 jruoho Exp $");
74
75 #include "opt_acpi.h"
76 #include "opt_pcifixup.h"
77
78 #include <sys/param.h>
79 #include <sys/device.h>
80 #include <sys/kernel.h>
81 #include <sys/malloc.h>
82 #include <sys/mutex.h>
83 #include <sys/sysctl.h>
84 #include <sys/systm.h>
85
86 #include <dev/acpi/acpireg.h>
87 #include <dev/acpi/acpivar.h>
88 #include <dev/acpi/acpi_osd.h>
89 #include <dev/acpi/acpi_pci.h>
90 #include <dev/acpi/acpi_timer.h>
91 #include <dev/acpi/acpi_wakedev.h>
92
93 #ifdef ACPIVERBOSE
94 #include <dev/acpi/acpidevs_data.h>
95 #endif
96
97 #define _COMPONENT ACPI_BUS_COMPONENT
98 ACPI_MODULE_NAME ("acpi")
99
100 #if defined(ACPI_PCI_FIXUP)
101 #error The option ACPI_PCI_FIXUP has been obsoleted by PCI_INTR_FIXUP_DISABLED. Please adjust your kernel configuration file.
102 #endif
103
104 #ifdef PCI_INTR_FIXUP_DISABLED
105 #include <dev/pci/pcidevs.h>
106 #endif
107
108 MALLOC_DECLARE(M_ACPI);
109
110 #include <machine/acpi_machdep.h>
111
112 #ifdef ACPI_DEBUGGER
113 #define ACPI_DBGR_INIT 0x01
114 #define ACPI_DBGR_TABLES 0x02
115 #define ACPI_DBGR_ENABLE 0x04
116 #define ACPI_DBGR_PROBE 0x08
117 #define ACPI_DBGR_RUNNING 0x10
118
119 static int acpi_dbgr = 0x00;
120 #endif
121
122 static ACPI_TABLE_DESC acpi_initial_tables[128];
123
124 static int acpi_match(device_t, cfdata_t, void *);
125 static void acpi_attach(device_t, device_t, void *);
126 static void acpi_childdet(device_t, device_t);
127 static int acpi_detach(device_t, int);
128
129 static int acpi_rescan(device_t, const char *, const int *);
130 static void acpi_rescan1(struct acpi_softc *, const char *, const int *);
131 static void acpi_rescan_nodes(struct acpi_softc *);
132 static void acpi_rescan_capabilities(struct acpi_softc *);
133
134 static int acpi_print(void *aux, const char *);
135
136 static int sysctl_hw_acpi_fixedstats(SYSCTLFN_ARGS);
137 static int sysctl_hw_acpi_sleepstate(SYSCTLFN_ARGS);
138 static int sysctl_hw_acpi_sleepstates(SYSCTLFN_ARGS);
139
140 extern struct cfdriver acpi_cd;
141
142 CFATTACH_DECL2_NEW(acpi, sizeof(struct acpi_softc),
143 acpi_match, acpi_attach, acpi_detach, NULL, acpi_rescan, acpi_childdet);
144
145 /*
146 * This is a flag we set when the ACPI subsystem is active. Machine
147 * dependent code may wish to skip other steps (such as attaching
148 * subsystems that ACPI supercedes) when ACPI is active.
149 */
150 int acpi_active;
151 int acpi_force_load;
152 int acpi_suspended = 0;
153
154 struct acpi_softc *acpi_softc;
155 static uint64_t acpi_root_pointer;
156 extern kmutex_t acpi_interrupt_list_mtx;
157
158 /*
159 * Ignored HIDs.
160 */
161 static const char * const acpi_ignored_ids[] = {
162 #if defined(i386) || defined(x86_64)
163 "PNP0000", /* AT interrupt controller is handled internally */
164 "PNP0200", /* AT DMA controller is handled internally */
165 "PNP0A??", /* PCI Busses are handled internally */
166 "PNP0B00", /* AT RTC is handled internally */
167 "PNP0C01", /* No "System Board" driver */
168 "PNP0C02", /* No "PnP motherboard register resources" driver */
169 "PNP0C0B", /* No need for "ACPI fan" driver */
170 "PNP0C0F", /* ACPI PCI link devices are handled internally */
171 "IFX0102", /* No driver for Infineon TPM */
172 "INT0800", /* No driver for Intel Firmware Hub device */
173 #endif
174 #if defined(x86_64)
175 "PNP0C04", /* FPU is handled internally */
176 #endif
177 NULL
178 };
179
180 /*
181 * Prototypes.
182 */
183 static void acpi_build_tree(struct acpi_softc *);
184 static ACPI_STATUS acpi_make_devnode(ACPI_HANDLE, uint32_t,
185 void *, void **);
186
187 static void acpi_enable_fixed_events(struct acpi_softc *);
188 static void acpi_sleep_init(struct acpi_softc *);
189
190 static ACPI_TABLE_HEADER *acpi_map_rsdt(void);
191 static void acpi_unmap_rsdt(ACPI_TABLE_HEADER *);
192
193 static bool acpi_suspend(device_t, const pmf_qual_t *);
194 static bool acpi_resume(device_t, const pmf_qual_t *);
195
196 #ifdef ACPI_ACTIVATE_DEV
197 static void acpi_activate_device(ACPI_HANDLE, ACPI_DEVICE_INFO **);
198 static ACPI_STATUS acpi_allocate_resources(ACPI_HANDLE);
199 #endif
200
201 /*
202 * acpi_probe:
203 *
204 * Probe for ACPI support. This is called by the
205 * machine-dependent ACPI front-end. All of the
206 * actual work is done by ACPICA.
207 *
208 * NOTE: This is not an autoconfiguration interface function.
209 */
210 int
211 acpi_probe(void)
212 {
213 static int beenhere;
214 ACPI_TABLE_HEADER *rsdt;
215 ACPI_STATUS rv;
216
217 if (beenhere != 0)
218 panic("acpi_probe: ACPI has already been probed");
219 beenhere = 1;
220
221 mutex_init(&acpi_interrupt_list_mtx, MUTEX_DEFAULT, IPL_NONE);
222
223 /*
224 * Start up ACPICA.
225 */
226 #ifdef ACPI_DEBUGGER
227 if (acpi_dbgr & ACPI_DBGR_INIT)
228 acpi_osd_debugger();
229 #endif
230
231 AcpiGbl_AllMethodsSerialized = FALSE;
232 AcpiGbl_EnableInterpreterSlack = TRUE;
233
234 rv = AcpiInitializeSubsystem();
235 if (ACPI_FAILURE(rv)) {
236 printf("ACPI: unable to initialize ACPICA: %s\n",
237 AcpiFormatException(rv));
238 return 0;
239 }
240
241 rv = AcpiInitializeTables(acpi_initial_tables, 128, 0);
242 if (ACPI_FAILURE(rv)) {
243 #ifdef ACPI_DEBUG
244 printf("ACPI: unable to initialize ACPI tables: %s\n",
245 AcpiFormatException(rv));
246 #endif
247 AcpiTerminate();
248 return 0;
249 }
250
251 rv = AcpiReallocateRootTable();
252 if (ACPI_FAILURE(rv)) {
253 printf("ACPI: unable to reallocate root table: %s\n",
254 AcpiFormatException(rv));
255 AcpiTerminate();
256 return 0;
257 }
258
259 #ifdef ACPI_DEBUGGER
260 if (acpi_dbgr & ACPI_DBGR_TABLES)
261 acpi_osd_debugger();
262 #endif
263
264 rv = AcpiLoadTables();
265 if (ACPI_FAILURE(rv)) {
266 printf("ACPI: unable to load tables: %s\n",
267 AcpiFormatException(rv));
268 AcpiTerminate();
269 return 0;
270 }
271
272 rsdt = acpi_map_rsdt();
273 if (rsdt == NULL) {
274 printf("ACPI: unable to map RSDT\n");
275 AcpiTerminate();
276 return 0;
277 }
278
279 if (!acpi_force_load && (acpi_find_quirks() & ACPI_QUIRK_BROKEN)) {
280 printf("ACPI: BIOS implementation in listed as broken:\n");
281 printf("ACPI: X/RSDT: OemId <%6.6s,%8.8s,%08x>, "
282 "AslId <%4.4s,%08x>\n",
283 rsdt->OemId, rsdt->OemTableId,
284 rsdt->OemRevision,
285 rsdt->AslCompilerId,
286 rsdt->AslCompilerRevision);
287 printf("ACPI: not used. set acpi_force_load to use anyway.\n");
288 acpi_unmap_rsdt(rsdt);
289 AcpiTerminate();
290 return 0;
291 }
292
293 acpi_unmap_rsdt(rsdt);
294
295 #if notyet
296 /* Install the default address space handlers. */
297 rv = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT,
298 ACPI_ADR_SPACE_SYSTEM_MEMORY, ACPI_DEFAULT_HANDLER, NULL, NULL);
299 if (ACPI_FAILURE(rv)) {
300 printf("ACPI: unable to initialize SystemMemory handler: %s\n",
301 AcpiFormatException(rv));
302 AcpiTerminate();
303 return 0;
304 }
305 rv = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT,
306 ACPI_ADR_SPACE_SYSTEM_IO, ACPI_DEFAULT_HANDLER, NULL, NULL);
307 if (ACPI_FAILURE(rv)) {
308 printf("ACPI: unable to initialize SystemIO handler: %s\n",
309 AcpiFormatException(rv));
310 AcpiTerminate();
311 return 0;
312 }
313 rv = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT,
314 ACPI_ADR_SPACE_PCI_CONFIG, ACPI_DEFAULT_HANDLER, NULL, NULL);
315 if (ACPI_FAILURE(rv)) {
316 printf("ACPI: unable to initialize PciConfig handler: %s\n",
317 AcpiFormatException(rv));
318 AcpiTerminate();
319 return 0;
320 }
321 #endif
322
323 rv = AcpiEnableSubsystem(~(ACPI_NO_HARDWARE_INIT|ACPI_NO_ACPI_ENABLE));
324 if (ACPI_FAILURE(rv)) {
325 printf("ACPI: unable to enable: %s\n", AcpiFormatException(rv));
326 AcpiTerminate();
327 return 0;
328 }
329
330 /*
331 * Looks like we have ACPI!
332 */
333
334 return 1;
335 }
336
337 static int
338 acpi_submatch(device_t parent, cfdata_t cf, const int *locs, void *aux)
339 {
340 struct cfattach *ca;
341
342 ca = config_cfattach_lookup(cf->cf_name, cf->cf_atname);
343 return (ca == &acpi_ca);
344 }
345
346 int
347 acpi_check(device_t parent, const char *ifattr)
348 {
349 return (config_search_ia(acpi_submatch, parent, ifattr, NULL) != NULL);
350 }
351
352 ACPI_PHYSICAL_ADDRESS
353 acpi_OsGetRootPointer(void)
354 {
355 ACPI_PHYSICAL_ADDRESS PhysicalAddress;
356
357 /*
358 * IA-32: Use AcpiFindRootPointer() to locate the RSDP.
359 *
360 * IA-64: Use the EFI.
361 *
362 * We let MD code handle this since there are multiple
363 * ways to do it.
364 */
365
366 PhysicalAddress = acpi_md_OsGetRootPointer();
367
368 if (acpi_root_pointer == 0)
369 acpi_root_pointer = PhysicalAddress;
370
371 return PhysicalAddress;
372 }
373
374 /*
375 * acpi_match:
376 *
377 * Autoconfiguration `match' routine.
378 */
379 static int
380 acpi_match(device_t parent, cfdata_t match, void *aux)
381 {
382 /*
383 * XXX Check other locators? Hard to know -- machine
384 * dependent code has already checked for the presence
385 * of ACPI by calling acpi_probe(), so I suppose we
386 * don't really have to do anything else.
387 */
388 return 1;
389 }
390
391 /* Remove references to child devices.
392 *
393 * XXX Need to reclaim any resources?
394 */
395 static void
396 acpi_childdet(device_t self, device_t child)
397 {
398 struct acpi_softc *sc = device_private(self);
399 struct acpi_devnode *ad;
400
401 if (sc->sc_apmbus == child)
402 sc->sc_apmbus = NULL;
403
404 SIMPLEQ_FOREACH(ad, &sc->sc_devnodes, ad_list) {
405
406 if (ad->ad_device == child)
407 ad->ad_device = NULL;
408 }
409 }
410
411 /*
412 * acpi_attach:
413 *
414 * Autoconfiguration `attach' routine. Finish initializing
415 * ACPICA (some initialization was done in acpi_probe(),
416 * which was required to check for the presence of ACPI),
417 * and enable the ACPI subsystem.
418 */
419 static void
420 acpi_attach(device_t parent, device_t self, void *aux)
421 {
422 struct acpi_softc *sc = device_private(self);
423 struct acpibus_attach_args *aa = aux;
424 ACPI_TABLE_HEADER *rsdt;
425 ACPI_STATUS rv;
426
427 aprint_naive("\n");
428 aprint_normal(": Intel ACPICA %08x\n", ACPI_CA_VERSION);
429
430 if (acpi_softc != NULL)
431 panic("acpi_attach: ACPI has already been attached");
432
433 sysmon_power_settype("acpi");
434
435 rsdt = acpi_map_rsdt();
436 if (rsdt) {
437 aprint_verbose_dev(
438 self,
439 "X/RSDT: OemId <%6.6s,%8.8s,%08x>, AslId <%4.4s,%08x>\n",
440 rsdt->OemId, rsdt->OemTableId,
441 rsdt->OemRevision,
442 rsdt->AslCompilerId, rsdt->AslCompilerRevision);
443 } else
444 aprint_error_dev(self, "X/RSDT: Not found\n");
445
446 acpi_unmap_rsdt(rsdt);
447
448 sc->sc_dev = self;
449 sc->sc_quirks = acpi_find_quirks();
450 sc->sc_sleepstate = ACPI_STATE_S0;
451
452 sc->sc_iot = aa->aa_iot;
453 sc->sc_memt = aa->aa_memt;
454 sc->sc_pc = aa->aa_pc;
455 sc->sc_pciflags = aa->aa_pciflags;
456 sc->sc_ic = aa->aa_ic;
457
458 SIMPLEQ_INIT(&sc->sc_devnodes);
459
460 acpi_softc = sc;
461
462 /*
463 * Register null power management handler.
464 */
465 if (!pmf_device_register(self, acpi_suspend, acpi_resume))
466 aprint_error_dev(self, "couldn't establish power handler\n");
467
468 /*
469 * Bring ACPI on-line.
470 */
471 #ifdef ACPI_DEBUGGER
472 if (acpi_dbgr & ACPI_DBGR_ENABLE)
473 acpi_osd_debugger();
474 #endif
475
476 #define ACPI_ENABLE_PHASE1 \
477 (ACPI_NO_HANDLER_INIT | ACPI_NO_EVENT_INIT)
478 #define ACPI_ENABLE_PHASE2 \
479 (ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE | \
480 ACPI_NO_ADDRESS_SPACE_INIT)
481
482 rv = AcpiEnableSubsystem(ACPI_ENABLE_PHASE1);
483 if (ACPI_FAILURE(rv)) {
484 aprint_error_dev(self, "unable to enable ACPI: %s\n",
485 AcpiFormatException(rv));
486 return;
487 }
488
489 acpi_md_callback();
490
491 rv = AcpiEnableSubsystem(ACPI_ENABLE_PHASE2);
492 if (ACPI_FAILURE(rv)) {
493 aprint_error_dev(self, "unable to enable ACPI: %s\n",
494 AcpiFormatException(rv));
495 return;
496 }
497
498 /* Early EC handler initialization if ECDT table is available. */
499 config_found_ia(self, "acpiecdtbus", aa, NULL);
500
501 rv = AcpiInitializeObjects(ACPI_FULL_INITIALIZATION);
502 if (ACPI_FAILURE(rv)) {
503 aprint_error_dev(self,
504 "unable to initialize ACPI objects: %s\n",
505 AcpiFormatException(rv));
506 return;
507 }
508 acpi_active = 1;
509
510 /* Our current state is "awake". */
511 sc->sc_sleepstate = ACPI_STATE_S0;
512
513 /* Show SCI interrupt. */
514 aprint_verbose_dev(self, "SCI interrupting at int %u\n",
515 AcpiGbl_FADT.SciInterrupt);
516
517 /*
518 * Check for fixed-hardware features.
519 */
520 acpi_enable_fixed_events(sc);
521 acpitimer_init();
522
523 /*
524 * Scan the namespace and build our device tree.
525 */
526 #ifdef ACPI_DEBUGGER
527 if (acpi_dbgr & ACPI_DBGR_PROBE)
528 acpi_osd_debugger();
529 #endif
530
531 acpi_build_tree(sc);
532 acpi_sleep_init(sc);
533
534 #ifdef ACPI_DEBUGGER
535 if (acpi_dbgr & ACPI_DBGR_RUNNING)
536 acpi_osd_debugger();
537 #endif
538
539 #ifdef ACPI_DEBUG
540 acpi_debug_init();
541 #endif
542 }
543
544 static int
545 acpi_detach(device_t self, int flags)
546 {
547 int rc;
548
549 #ifdef ACPI_DEBUGGER
550 if (acpi_dbgr & ACPI_DBGR_RUNNING)
551 acpi_osd_debugger();
552 #endif
553
554 if ((rc = config_detach_children(self, flags)) != 0)
555 return rc;
556
557 #ifdef ACPI_DEBUGGER
558 if (acpi_dbgr & ACPI_DBGR_PROBE)
559 acpi_osd_debugger();
560 #endif
561
562 if ((rc = acpitimer_detach()) != 0)
563 return rc;
564
565 #if 0
566 /*
567 * Bring ACPI on-line.
568 */
569 #ifdef ACPI_DEBUGGER
570 if (acpi_dbgr & ACPI_DBGR_ENABLE)
571 acpi_osd_debugger();
572 #endif
573
574 #define ACPI_ENABLE_PHASE1 \
575 (ACPI_NO_HANDLER_INIT | ACPI_NO_EVENT_INIT)
576 #define ACPI_ENABLE_PHASE2 \
577 (ACPI_NO_HARDWARE_INIT | ACPI_NO_ACPI_ENABLE | \
578 ACPI_NO_ADDRESS_SPACE_INIT)
579
580 rv = AcpiEnableSubsystem(ACPI_ENABLE_PHASE1);
581 if (ACPI_FAILURE(rv)) {
582 aprint_error_dev(self, "unable to enable ACPI: %s\n",
583 AcpiFormatException(rv));
584 return;
585 }
586
587 rv = AcpiEnableSubsystem(ACPI_ENABLE_PHASE2);
588 if (ACPI_FAILURE(rv)) {
589 aprint_error_dev(self, "unable to enable ACPI: %s\n",
590 AcpiFormatException(rv));
591 return;
592 }
593
594 /* Early EC handler initialization if ECDT table is available. */
595 config_found_ia(self, "acpiecdtbus", aa, NULL);
596
597 rv = AcpiInitializeObjects(ACPI_FULL_INITIALIZATION);
598 if (ACPI_FAILURE(rv)) {
599 aprint_error_dev(self,
600 "unable to initialize ACPI objects: %s\n",
601 AcpiFormatException(rv));
602 return;
603 }
604 acpi_active = 1;
605
606 acpi_enable_fixed_events(sc);
607 #endif
608
609 pmf_device_deregister(self);
610
611 #if 0
612 sysmon_power_settype("acpi");
613 #endif
614 acpi_softc = NULL;
615
616 return 0;
617 }
618
619 static bool
620 acpi_suspend(device_t dv, const pmf_qual_t *qual)
621 {
622 acpi_suspended = 1;
623 return true;
624 }
625
626 static bool
627 acpi_resume(device_t dv, const pmf_qual_t *qual)
628 {
629 acpi_suspended = 0;
630 return true;
631 }
632
633 #if 0
634 /*
635 * acpi_disable:
636 *
637 * Disable ACPI.
638 */
639 static ACPI_STATUS
640 acpi_disable(struct acpi_softc *sc)
641 {
642 ACPI_STATUS rv = AE_OK;
643
644 if (acpi_active) {
645 rv = AcpiDisable();
646 if (ACPI_SUCCESS(rv))
647 acpi_active = 0;
648 }
649 return rv;
650 }
651 #endif
652
653 /*
654 * acpi_build_tree:
655 *
656 * Scan the ACPI namespace and attach child devices.
657 */
658 static void
659 acpi_build_tree(struct acpi_softc *sc)
660 {
661
662 (void)AcpiWalkNamespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
663 UINT32_MAX, acpi_make_devnode, NULL, sc, NULL);
664
665 acpi_rescan1(sc, NULL, NULL);
666 acpi_rescan_capabilities(sc);
667
668 acpi_pcidev_scan(sc);
669 }
670
671 static int
672 acpi_rescan(device_t self, const char *ifattr, const int *locators)
673 {
674 struct acpi_softc *sc = device_private(self);
675
676 acpi_rescan1(sc, ifattr, locators);
677 return 0;
678 }
679
680 static void
681 acpi_rescan1(struct acpi_softc *sc, const char *ifattr, const int *locators)
682 {
683 if (ifattr_match(ifattr, "acpinodebus"))
684 acpi_rescan_nodes(sc);
685
686 if (ifattr_match(ifattr, "acpiapmbus") && sc->sc_apmbus == NULL) {
687 sc->sc_apmbus = config_found_ia(sc->sc_dev, "acpiapmbus", NULL,
688 NULL);
689 }
690 }
691
692 static void
693 acpi_rescan_nodes(struct acpi_softc *sc)
694 {
695 struct acpi_attach_args aa;
696 struct acpi_devnode *ad;
697
698 SIMPLEQ_FOREACH(ad, &sc->sc_devnodes, ad_list) {
699
700 if (ad->ad_device != NULL)
701 continue;
702
703 aa.aa_node = ad;
704 aa.aa_iot = sc->sc_iot;
705 aa.aa_memt = sc->sc_memt;
706 aa.aa_pc = sc->sc_pc;
707 aa.aa_pciflags = sc->sc_pciflags;
708 aa.aa_ic = sc->sc_ic;
709
710 if (ad->ad_devinfo->Type == ACPI_TYPE_DEVICE) {
711 /*
712 * XXX We only attach devices which are:
713 *
714 * - present
715 * - enabled
716 * - functioning properly
717 *
718 * However, if enabled, it's decoding resources,
719 * so we should claim them, if possible.
720 * Requires changes to bus_space(9).
721 */
722 if ((ad->ad_devinfo->Valid & ACPI_VALID_STA) ==
723 ACPI_VALID_STA &&
724 (ad->ad_devinfo->CurrentStatus &
725 (ACPI_STA_DEV_PRESENT|ACPI_STA_DEV_ENABLED|
726 ACPI_STA_DEV_OK)) !=
727 (ACPI_STA_DEV_PRESENT|ACPI_STA_DEV_ENABLED|
728 ACPI_STA_DEV_OK))
729 continue;
730 }
731
732 /*
733 * XXX Same problem as above...
734 *
735 * Do this check only for devices, as e.g.
736 * a Thermal Zone doesn't have a HID.
737 */
738 if (ad->ad_devinfo->Type == ACPI_TYPE_DEVICE &&
739 (ad->ad_devinfo->Valid & ACPI_VALID_HID) == 0)
740 continue;
741
742 /*
743 * Handled internally.
744 */
745 if (ad->ad_devinfo->Type == ACPI_TYPE_PROCESSOR ||
746 ad->ad_devinfo->Type == ACPI_TYPE_POWER)
747 continue;
748
749 /*
750 * Skip ignored HIDs.
751 */
752 if (acpi_match_hid(ad->ad_devinfo, acpi_ignored_ids))
753 continue;
754
755 ad->ad_device = config_found_ia(sc->sc_dev,
756 "acpinodebus", &aa, acpi_print);
757 }
758 }
759
760 #define ACPI_STA_DEV_VALID \
761 (ACPI_STA_DEV_PRESENT | ACPI_STA_DEV_ENABLED | ACPI_STA_DEV_OK)
762
763 /*
764 * acpi_rescan_capabilities:
765 *
766 * Scan device capabilities.
767 */
768 static void
769 acpi_rescan_capabilities(struct acpi_softc *sc)
770 {
771 struct acpi_devnode *ad;
772 ACPI_DEVICE_INFO *di;
773 ACPI_HANDLE tmp;
774 ACPI_STATUS rv;
775
776 SIMPLEQ_FOREACH(ad, &sc->sc_devnodes, ad_list) {
777
778 di = ad->ad_devinfo;
779
780 if (di->Type != ACPI_TYPE_DEVICE)
781 continue;
782
783 if ((di->Valid & ACPI_VALID_STA) != 0 &&
784 (di->CurrentStatus & ACPI_STA_DEV_VALID) !=
785 ACPI_STA_DEV_VALID)
786 continue;
787
788 /*
789 * Scan power resource capabilities.
790 */
791 rv = AcpiGetHandle(ad->ad_handle, "_PR0", &tmp);
792
793 if (ACPI_FAILURE(rv))
794 rv = AcpiGetHandle(ad->ad_handle, "_PSC", &tmp);
795
796 if (ACPI_SUCCESS(rv))
797 ad->ad_flags |= ACPI_DEVICE_POWER;
798
799 /*
800 * Scan wake-up capabilities.
801 */
802 rv = AcpiGetHandle(ad->ad_handle, "_PRW", &tmp);
803
804 if (ACPI_SUCCESS(rv)) {
805 ad->ad_flags |= ACPI_DEVICE_WAKEUP;
806 acpi_wakedev_add(ad);
807 }
808
809 if (ad->ad_flags != 0) {
810 aprint_debug_dev(sc->sc_dev, "%-5s ", ad->ad_name);
811
812 if ((ad->ad_flags & ACPI_DEVICE_POWER) != 0)
813 aprint_debug("power ");
814
815 if ((ad->ad_flags & ACPI_DEVICE_WAKEUP) != 0)
816 aprint_debug("wake-up ");
817
818 aprint_debug("\n");
819 }
820 }
821 }
822
823 #undef ACPI_STA_DEV_VALID
824
825 /*
826 * acpi_make_devnode:
827 *
828 * Make an ACPI devnode.
829 */
830 static ACPI_STATUS
831 acpi_make_devnode(ACPI_HANDLE handle, uint32_t level,
832 void *context, void **status)
833 {
834 struct acpi_softc *sc = context;
835 struct acpi_devnode *ad;
836 ACPI_DEVICE_INFO *devinfo;
837 ACPI_OBJECT_TYPE type;
838 ACPI_NAME_UNION *anu;
839 ACPI_STATUS rv;
840 int clear, i;
841
842 rv = AcpiGetObjectInfo(handle, &devinfo);
843
844 if (ACPI_FAILURE(rv))
845 return AE_OK; /* Do not terminate the walk. */
846
847 type = devinfo->Type;
848
849 switch (type) {
850
851 case ACPI_TYPE_DEVICE:
852
853 #ifdef ACPI_ACTIVATE_DEV
854 acpi_activate_device(handle, &devinfo);
855 #endif
856
857 case ACPI_TYPE_PROCESSOR:
858 case ACPI_TYPE_THERMAL:
859 case ACPI_TYPE_POWER:
860
861 ad = malloc(sizeof(*ad), M_ACPI, M_NOWAIT | M_ZERO);
862
863 if (ad == NULL)
864 return AE_NO_MEMORY;
865
866 ad->ad_parent = sc->sc_dev;
867 ad->ad_devinfo = devinfo;
868 ad->ad_handle = handle;
869 ad->ad_type = type;
870
871 anu = (ACPI_NAME_UNION *)&devinfo->Name;
872 ad->ad_name[4] = '\0';
873
874 for (i = 3, clear = 0; i >= 0; i--) {
875
876 if (clear == 0 && anu->Ascii[i] == '_')
877 ad->ad_name[i] = '\0';
878 else {
879 ad->ad_name[i] = anu->Ascii[i];
880 clear = 1;
881 }
882 }
883
884 if (ad->ad_name[0] == '\0')
885 ad->ad_name[0] = '_';
886
887 SIMPLEQ_INSERT_TAIL(&sc->sc_devnodes, ad, ad_list);
888
889 #ifdef ACPIVERBOSE
890
891 if (type != ACPI_TYPE_DEVICE)
892 return AE_OK;
893
894 aprint_normal_dev(sc->sc_dev, "%-5s ", ad->ad_name);
895
896 aprint_normal("HID %-10s ",
897 ((devinfo->Valid & ACPI_VALID_HID) != 0) ?
898 devinfo->HardwareId.String: "-");
899
900 aprint_normal("UID %-4s ",
901 ((devinfo->Valid & ACPI_VALID_UID) != 0) ?
902 devinfo->UniqueId.String : "-");
903
904 if ((devinfo->Valid & ACPI_VALID_STA) != 0)
905 aprint_normal("STA 0x%08X ", devinfo->CurrentStatus);
906 else
907 aprint_normal("STA %10s ", "-");
908
909 if ((devinfo->Valid & ACPI_VALID_ADR) != 0)
910 aprint_normal("ADR 0x%016" PRIX64"",
911 devinfo->Address);
912
913 aprint_normal("\n");
914 #endif
915 }
916
917 return AE_OK;
918 }
919
920 /*
921 * acpi_print:
922 *
923 * Autoconfiguration print routine for ACPI node bus.
924 */
925 static int
926 acpi_print(void *aux, const char *pnp)
927 {
928 struct acpi_attach_args *aa = aux;
929 ACPI_STATUS rv;
930
931 if (pnp) {
932 if (aa->aa_node->ad_devinfo->Valid & ACPI_VALID_HID) {
933 char *pnpstr =
934 aa->aa_node->ad_devinfo->HardwareId.String;
935 ACPI_BUFFER buf;
936
937 aprint_normal("%s (%s) ", aa->aa_node->ad_name,
938 pnpstr);
939
940 rv = acpi_eval_struct(aa->aa_node->ad_handle,
941 "_STR", &buf);
942 if (ACPI_SUCCESS(rv)) {
943 ACPI_OBJECT *obj = buf.Pointer;
944 switch (obj->Type) {
945 case ACPI_TYPE_STRING:
946 aprint_normal("[%s] ", obj->String.Pointer);
947 break;
948 case ACPI_TYPE_BUFFER:
949 aprint_normal("buffer %p ", obj->Buffer.Pointer);
950 break;
951 default:
952 aprint_normal("type %u ",obj->Type);
953 break;
954 }
955 ACPI_FREE(buf.Pointer);
956 }
957 #ifdef ACPIVERBOSE
958 else {
959 int i;
960
961 for (i = 0; i < __arraycount(acpi_knowndevs);
962 i++) {
963 if (strcmp(acpi_knowndevs[i].pnp,
964 pnpstr) == 0) {
965 aprint_normal("[%s] ",
966 acpi_knowndevs[i].str);
967 }
968 }
969 }
970
971 #endif
972 aprint_normal("at %s", pnp);
973 } else if (aa->aa_node->ad_devinfo->Type != ACPI_TYPE_DEVICE) {
974 aprint_normal("%s (ACPI Object Type '%s' "
975 "[0x%02x]) ", aa->aa_node->ad_name,
976 AcpiUtGetTypeName(aa->aa_node->ad_devinfo->Type),
977 aa->aa_node->ad_devinfo->Type);
978 aprint_normal("at %s", pnp);
979 } else
980 return 0;
981 } else {
982 aprint_normal(" (%s", aa->aa_node->ad_name);
983 if (aa->aa_node->ad_devinfo->Valid & ACPI_VALID_HID) {
984 aprint_normal(", %s", aa->aa_node->ad_devinfo->HardwareId.String);
985 if (aa->aa_node->ad_devinfo->Valid & ACPI_VALID_UID) {
986 const char *uid;
987
988 uid = aa->aa_node->ad_devinfo->UniqueId.String;
989 if (uid[0] == '\0')
990 uid = "<null>";
991 aprint_normal("-%s", uid);
992 }
993 }
994 aprint_normal(")");
995 }
996
997 return UNCONF;
998 }
999
1000 /*****************************************************************************
1001 * ACPI fixed-hardware feature handlers
1002 *****************************************************************************/
1003
1004 static UINT32 acpi_fixed_button_handler(void *);
1005 static void acpi_fixed_button_pressed(void *);
1006
1007 /*
1008 * acpi_enable_fixed_events:
1009 *
1010 * Enable any fixed-hardware feature handlers.
1011 */
1012 static void
1013 acpi_enable_fixed_events(struct acpi_softc *sc)
1014 {
1015 static int beenhere;
1016 ACPI_STATUS rv;
1017
1018 KASSERT(beenhere == 0);
1019 beenhere = 1;
1020
1021 /*
1022 * Check for fixed-hardware buttons.
1023 */
1024 if ((AcpiGbl_FADT.Flags & ACPI_FADT_POWER_BUTTON) == 0) {
1025 aprint_verbose_dev(sc->sc_dev,
1026 "fixed-feature power button present\n");
1027 sc->sc_smpsw_power.smpsw_name = device_xname(sc->sc_dev);
1028 sc->sc_smpsw_power.smpsw_type = PSWITCH_TYPE_POWER;
1029 if (sysmon_pswitch_register(&sc->sc_smpsw_power) != 0) {
1030 aprint_error_dev(sc->sc_dev,
1031 "unable to register fixed power "
1032 "button with sysmon\n");
1033 } else {
1034 rv = AcpiInstallFixedEventHandler(
1035 ACPI_EVENT_POWER_BUTTON,
1036 acpi_fixed_button_handler, &sc->sc_smpsw_power);
1037 if (ACPI_FAILURE(rv)) {
1038 aprint_error_dev(sc->sc_dev,
1039 "unable to install handler "
1040 "for fixed power button: %s\n",
1041 AcpiFormatException(rv));
1042 }
1043 }
1044 }
1045
1046 if ((AcpiGbl_FADT.Flags & ACPI_FADT_SLEEP_BUTTON) == 0) {
1047 aprint_verbose_dev(sc->sc_dev,
1048 "fixed-feature sleep button present\n");
1049 sc->sc_smpsw_sleep.smpsw_name = device_xname(sc->sc_dev);
1050 sc->sc_smpsw_sleep.smpsw_type = PSWITCH_TYPE_SLEEP;
1051 if (sysmon_pswitch_register(&sc->sc_smpsw_power) != 0) {
1052 aprint_error_dev(sc->sc_dev,
1053 "unable to register fixed sleep "
1054 "button with sysmon\n");
1055 } else {
1056 rv = AcpiInstallFixedEventHandler(
1057 ACPI_EVENT_SLEEP_BUTTON,
1058 acpi_fixed_button_handler, &sc->sc_smpsw_sleep);
1059 if (ACPI_FAILURE(rv)) {
1060 aprint_error_dev(sc->sc_dev,
1061 "unable to install handler "
1062 "for fixed sleep button: %s\n",
1063 AcpiFormatException(rv));
1064 }
1065 }
1066 }
1067 }
1068
1069 /*
1070 * acpi_fixed_button_handler:
1071 *
1072 * Event handler for the fixed buttons.
1073 */
1074 static UINT32
1075 acpi_fixed_button_handler(void *context)
1076 {
1077 static const int handler = OSL_NOTIFY_HANDLER;
1078 struct sysmon_pswitch *smpsw = context;
1079
1080 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s\n", __func__));
1081
1082 (void)AcpiOsExecute(handler, acpi_fixed_button_pressed, smpsw);
1083
1084 return ACPI_INTERRUPT_HANDLED;
1085 }
1086
1087 /*
1088 * acpi_fixed_button_pressed:
1089 *
1090 * Deal with a fixed button being pressed.
1091 */
1092 static void
1093 acpi_fixed_button_pressed(void *context)
1094 {
1095 struct sysmon_pswitch *smpsw = context;
1096
1097 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: %s fixed button pressed\n",
1098 __func__, smpsw->smpsw_name));
1099
1100 sysmon_pswitch_event(smpsw, PSWITCH_EVENT_PRESSED);
1101 }
1102
1103 /*****************************************************************************
1104 * ACPI utility routines.
1105 *****************************************************************************/
1106
1107 /*
1108 * acpi_eval_integer:
1109 *
1110 * Evaluate an integer object.
1111 */
1112 ACPI_STATUS
1113 acpi_eval_integer(ACPI_HANDLE handle, const char *path, ACPI_INTEGER *valp)
1114 {
1115 ACPI_STATUS rv;
1116 ACPI_BUFFER buf;
1117 ACPI_OBJECT param;
1118
1119 if (handle == NULL)
1120 handle = ACPI_ROOT_OBJECT;
1121
1122 buf.Pointer = ¶m;
1123 buf.Length = sizeof(param);
1124
1125 rv = AcpiEvaluateObjectTyped(handle, path, NULL, &buf,
1126 ACPI_TYPE_INTEGER);
1127 if (ACPI_SUCCESS(rv))
1128 *valp = param.Integer.Value;
1129
1130 return rv;
1131 }
1132
1133 /*
1134 * acpi_eval_set_integer:
1135 *
1136 * Evaluate an integer object with a single integer input parameter.
1137 */
1138 ACPI_STATUS
1139 acpi_eval_set_integer(ACPI_HANDLE handle, const char *path, ACPI_INTEGER arg)
1140 {
1141 ACPI_OBJECT param_arg;
1142 ACPI_OBJECT_LIST param_args;
1143
1144 if (handle == NULL)
1145 handle = ACPI_ROOT_OBJECT;
1146
1147 param_arg.Type = ACPI_TYPE_INTEGER;
1148 param_arg.Integer.Value = arg;
1149
1150 param_args.Count = 1;
1151 param_args.Pointer = ¶m_arg;
1152
1153 return AcpiEvaluateObject(handle, path, ¶m_args, NULL);
1154 }
1155
1156 /*
1157 * acpi_eval_string:
1158 *
1159 * Evaluate a (Unicode) string object.
1160 */
1161 ACPI_STATUS
1162 acpi_eval_string(ACPI_HANDLE handle, const char *path, char **stringp)
1163 {
1164 ACPI_OBJECT *obj;
1165 ACPI_BUFFER buf;
1166 ACPI_STATUS rv;
1167
1168 rv = acpi_eval_struct(handle, path, &buf);
1169
1170 if (ACPI_FAILURE(rv))
1171 return rv;
1172
1173 obj = buf.Pointer;
1174
1175 if (obj->Type != ACPI_TYPE_STRING) {
1176 rv = AE_TYPE;
1177 goto out;
1178 }
1179
1180 if (obj->String.Length == 0) {
1181 rv = AE_BAD_DATA;
1182 goto out;
1183 }
1184
1185 *stringp = ACPI_ALLOCATE(obj->String.Length + 1);
1186
1187 if (*stringp == NULL) {
1188 rv = AE_NO_MEMORY;
1189 goto out;
1190 }
1191
1192 (void)memcpy(*stringp, obj->String.Pointer, obj->String.Length);
1193
1194 (*stringp)[obj->String.Length] = '\0';
1195
1196 out:
1197 ACPI_FREE(buf.Pointer);
1198
1199 return rv;
1200 }
1201
1202 /*
1203 * acpi_eval_struct:
1204 *
1205 * Evaluate a more complex structure.
1206 * Caller must free buf.Pointer by ACPI_FREE().
1207 */
1208 ACPI_STATUS
1209 acpi_eval_struct(ACPI_HANDLE handle, const char *path, ACPI_BUFFER *bufp)
1210 {
1211 ACPI_STATUS rv;
1212
1213 if (handle == NULL)
1214 handle = ACPI_ROOT_OBJECT;
1215
1216 bufp->Pointer = NULL;
1217 bufp->Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1218
1219 rv = AcpiEvaluateObject(handle, path, NULL, bufp);
1220
1221 return rv;
1222 }
1223
1224 /*
1225 * acpi_eval_reference_handle:
1226 *
1227 * Evaluate a reference handle from an element in a package.
1228 */
1229 ACPI_STATUS
1230 acpi_eval_reference_handle(ACPI_OBJECT *elm, ACPI_HANDLE *handle)
1231 {
1232
1233 if (elm == NULL || handle == NULL)
1234 return AE_BAD_PARAMETER;
1235
1236 switch (elm->Type) {
1237
1238 case ACPI_TYPE_ANY:
1239 case ACPI_TYPE_LOCAL_REFERENCE:
1240
1241 if (elm->Reference.Handle == NULL)
1242 return AE_NULL_ENTRY;
1243
1244 *handle = elm->Reference.Handle;
1245
1246 return AE_OK;
1247
1248 case ACPI_TYPE_STRING:
1249 return AcpiGetHandle(NULL, elm->String.Pointer, handle);
1250
1251 default:
1252 return AE_TYPE;
1253 }
1254 }
1255
1256 /*
1257 * acpi_foreach_package_object:
1258 *
1259 * Iterate over all objects in a package, and pass them all
1260 * to a function. If the called function returns non AE_OK, the
1261 * iteration is stopped and that value is returned.
1262 */
1263 ACPI_STATUS
1264 acpi_foreach_package_object(ACPI_OBJECT *pkg,
1265 ACPI_STATUS (*func)(ACPI_OBJECT *, void *),
1266 void *arg)
1267 {
1268 ACPI_STATUS rv = AE_OK;
1269 int i;
1270
1271 if (pkg == NULL || pkg->Type != ACPI_TYPE_PACKAGE)
1272 return AE_BAD_PARAMETER;
1273
1274 for (i = 0; i < pkg->Package.Count; i++) {
1275 rv = (*func)(&pkg->Package.Elements[i], arg);
1276 if (ACPI_FAILURE(rv))
1277 break;
1278 }
1279
1280 return rv;
1281 }
1282
1283 /*
1284 * acpi_name:
1285 *
1286 * Return a complete pathname from a handle.
1287 *
1288 * Note that the function uses static data storage;
1289 * if the data is needed for future use, it should be
1290 * copied before any subsequent calls overwrite it.
1291 */
1292 const char *
1293 acpi_name(ACPI_HANDLE handle)
1294 {
1295 static char buffer[80];
1296 ACPI_BUFFER buf;
1297 ACPI_STATUS rv;
1298
1299 buf.Length = sizeof(buffer);
1300 buf.Pointer = buffer;
1301
1302 rv = AcpiGetName(handle, ACPI_FULL_PATHNAME, &buf);
1303 if (ACPI_FAILURE(rv))
1304 return "(unknown acpi path)";
1305 return buffer;
1306 }
1307
1308 /*
1309 * acpi_get:
1310 *
1311 * Fetch data info the specified (empty) ACPI buffer.
1312 * Caller must free buf.Pointer by ACPI_FREE().
1313 */
1314 ACPI_STATUS
1315 acpi_get(ACPI_HANDLE handle, ACPI_BUFFER *buf,
1316 ACPI_STATUS (*getit)(ACPI_HANDLE, ACPI_BUFFER *))
1317 {
1318 buf->Pointer = NULL;
1319 buf->Length = ACPI_ALLOCATE_LOCAL_BUFFER;
1320
1321 return (*getit)(handle, buf);
1322 }
1323
1324
1325 /*
1326 * acpi_match_hid
1327 *
1328 * Match given ids against _HID and _CIDs.
1329 */
1330 int
1331 acpi_match_hid(ACPI_DEVICE_INFO *ad, const char * const *ids)
1332 {
1333 int i;
1334
1335 while (*ids) {
1336 if (ad->Valid & ACPI_VALID_HID) {
1337 if (pmatch(ad->HardwareId.String, *ids, NULL) == 2)
1338 return 1;
1339 }
1340
1341 if (ad->Valid & ACPI_VALID_CID) {
1342 for (i = 0; i < ad->CompatibleIdList.Count; i++) {
1343 if (pmatch(ad->CompatibleIdList.Ids[i].String, *ids, NULL) == 2)
1344 return 1;
1345 }
1346 }
1347 ids++;
1348 }
1349
1350 return 0;
1351 }
1352
1353 /*
1354 * acpi_wake_gpe_helper
1355 *
1356 * Set/unset GPE as both Runtime and Wake.
1357 */
1358 static void
1359 acpi_wake_gpe_helper(ACPI_HANDLE handle, bool enable)
1360 {
1361 ACPI_OBJECT *elm, *obj;
1362 ACPI_INTEGER val;
1363 ACPI_BUFFER buf;
1364 ACPI_STATUS rv;
1365
1366 rv = acpi_eval_struct(handle, METHOD_NAME__PRW, &buf);
1367
1368 if (ACPI_FAILURE(rv))
1369 return;
1370
1371 obj = buf.Pointer;
1372
1373 if (obj->Type != ACPI_TYPE_PACKAGE || obj->Package.Count < 2)
1374 goto out;
1375
1376 /*
1377 * As noted in ACPI 3.0 (section 7.2.10), the _PRW object is
1378 * a package in which the first element is either an integer
1379 * or again a package. In the latter case the package inside
1380 * the package element has two elements, a reference handle
1381 * and the GPE number.
1382 */
1383 elm = &obj->Package.Elements[0];
1384
1385 switch (elm->Type) {
1386
1387 case ACPI_TYPE_INTEGER:
1388 val = elm->Integer.Value;
1389 break;
1390
1391 case ACPI_TYPE_PACKAGE:
1392
1393 if (elm->Package.Count < 2)
1394 goto out;
1395
1396 if (elm->Package.Elements[0].Type != ACPI_TYPE_LOCAL_REFERENCE)
1397 goto out;
1398
1399 if (elm->Package.Elements[1].Type != ACPI_TYPE_INTEGER)
1400 goto out;
1401
1402 val = elm->Package.Elements[1].Integer.Value;
1403 break;
1404
1405 default:
1406 goto out;
1407 }
1408
1409 if (enable) {
1410 (void)AcpiSetGpeType(NULL, val, ACPI_GPE_TYPE_WAKE_RUN);
1411 (void)AcpiEnableGpe(NULL, val, ACPI_NOT_ISR);
1412 } else
1413 (void)AcpiDisableGpe(NULL, val, ACPI_NOT_ISR);
1414
1415 out:
1416 ACPI_FREE(buf.Pointer);
1417 }
1418
1419 /*
1420 * acpi_clear_wake_gpe
1421 *
1422 * Clear GPE as both Runtime and Wake.
1423 */
1424 void
1425 acpi_clear_wake_gpe(ACPI_HANDLE handle)
1426 {
1427 acpi_wake_gpe_helper(handle, false);
1428 }
1429
1430 /*
1431 * acpi_set_wake_gpe
1432 *
1433 * Set GPE as both Runtime and Wake.
1434 */
1435 void
1436 acpi_set_wake_gpe(ACPI_HANDLE handle)
1437 {
1438 acpi_wake_gpe_helper(handle, true);
1439 }
1440
1441
1442 /*****************************************************************************
1443 * ACPI sleep support.
1444 *****************************************************************************/
1445
1446 /*
1447 * acpi_sleep_init:
1448 *
1449 * Evaluate supported sleep states.
1450 */
1451 static void
1452 acpi_sleep_init(struct acpi_softc *sc)
1453 {
1454 uint8_t a, b, i;
1455 ACPI_STATUS rv;
1456
1457 CTASSERT(ACPI_STATE_S0 == 0 && ACPI_STATE_S1 == 1);
1458 CTASSERT(ACPI_STATE_S2 == 2 && ACPI_STATE_S3 == 3);
1459 CTASSERT(ACPI_STATE_S4 == 4 && ACPI_STATE_S5 == 5);
1460
1461 for (i = ACPI_STATE_S0; i <= ACPI_STATE_S5; i++) {
1462
1463 rv = AcpiGetSleepTypeData(i, &a, &b);
1464
1465 if (ACPI_SUCCESS(rv))
1466 sc->sc_sleepstates |= __BIT(i);
1467 }
1468 }
1469
1470 /*
1471 * acpi_enter_sleep_state:
1472 *
1473 * Enter to the specified sleep state.
1474 */
1475 ACPI_STATUS
1476 acpi_enter_sleep_state(struct acpi_softc *sc, int state)
1477 {
1478 ACPI_STATUS rv = AE_OK;
1479 int err;
1480
1481 if (state == sc->sc_sleepstate)
1482 return AE_OK;
1483
1484 aprint_normal_dev(sc->sc_dev, "entering state S%d\n", state);
1485
1486 switch (state) {
1487
1488 case ACPI_STATE_S0:
1489 break;
1490
1491 case ACPI_STATE_S1:
1492 case ACPI_STATE_S2:
1493 case ACPI_STATE_S3:
1494 case ACPI_STATE_S4:
1495
1496 if ((sc->sc_sleepstates & __BIT(state)) == 0) {
1497 aprint_error_dev(sc->sc_dev, "sleep state "
1498 "S%d is not available\n", state);
1499 break;
1500 }
1501
1502 acpi_wakedev_commit(sc, state);
1503
1504 if (state != ACPI_STATE_S1 &&
1505 pmf_system_suspend(PMF_Q_NONE) != true) {
1506 aprint_error_dev(sc->sc_dev, "aborting suspend\n");
1507 break;
1508 }
1509
1510 rv = AcpiEnterSleepStatePrep(state);
1511
1512 if (ACPI_FAILURE(rv)) {
1513 aprint_error_dev(sc->sc_dev, "failed to prepare "
1514 "S%d: %s\n", state, AcpiFormatException(rv));
1515 break;
1516 }
1517
1518 sc->sc_sleepstate = state;
1519
1520 if (state == ACPI_STATE_S1) {
1521
1522 /* Just enter the state. */
1523 acpi_md_OsDisableInterrupt();
1524 rv = AcpiEnterSleepState(state);
1525
1526 if (ACPI_FAILURE(rv))
1527 aprint_error_dev(sc->sc_dev, "failed to "
1528 "enter S1: %s\n", AcpiFormatException(rv));
1529
1530 (void)AcpiLeaveSleepState(state);
1531
1532 } else {
1533
1534 err = acpi_md_sleep(state);
1535
1536 if (state == ACPI_STATE_S4)
1537 AcpiEnable();
1538
1539 pmf_system_bus_resume(PMF_Q_NONE);
1540 (void)AcpiLeaveSleepState(state);
1541 pmf_system_resume(PMF_Q_NONE);
1542 }
1543
1544 break;
1545 case ACPI_STATE_S5:
1546
1547 rv = AcpiEnterSleepStatePrep(ACPI_STATE_S5);
1548
1549 if (ACPI_FAILURE(rv)) {
1550 aprint_error_dev(sc->sc_dev, "failed to prepare "
1551 "S%d: %s\n", state, AcpiFormatException(rv));
1552 break;
1553 }
1554
1555 DELAY(1000000);
1556
1557 sc->sc_sleepstate = state;
1558 acpi_md_OsDisableInterrupt();
1559
1560 (void)AcpiEnterSleepState(ACPI_STATE_S5);
1561
1562 aprint_error_dev(sc->sc_dev, "WARNING: powerdown failed!\n");
1563 break;
1564 }
1565
1566 sc->sc_sleepstate = ACPI_STATE_S0;
1567
1568 return rv;
1569 }
1570
1571 #ifdef ACPI_ACTIVATE_DEV
1572
1573 #define ACPI_DEV_VALID (ACPI_VALID_STA | ACPI_VALID_HID)
1574 #define ACPI_DEV_STATUS (ACPI_STA_DEV_PRESENT | ACPI_STA_DEV_ENABLED)
1575
1576 static void
1577 acpi_activate_device(ACPI_HANDLE handle, ACPI_DEVICE_INFO **di)
1578 {
1579 ACPI_DEVICE_INFO *newdi;
1580 ACPI_STATUS rv;
1581 uint32_t old;
1582
1583 /*
1584 * If the device is valid and present,
1585 * but not enabled, try to activate it.
1586 */
1587 if (((*di)->Valid & ACPI_DEV_VALID) != ACPI_DEV_VALID)
1588 return;
1589
1590 old = (*di)->CurrentStatus;
1591
1592 if ((old & ACPI_DEV_STATUS) != ACPI_STA_DEV_PRESENT)
1593 return;
1594
1595 rv = acpi_allocate_resources(handle);
1596
1597 if (ACPI_FAILURE(rv))
1598 goto fail;
1599
1600 rv = AcpiGetObjectInfo(handle, &newdi);
1601
1602 if (ACPI_FAILURE(rv))
1603 goto fail;
1604
1605 ACPI_FREE(*di);
1606 *di = newdi;
1607
1608 aprint_verbose_dev(acpi_softc->sc_dev,
1609 "%s activated, STA 0x%08X -> STA 0x%08X\n",
1610 (*di)->HardwareId.String, old, (*di)->CurrentStatus);
1611
1612 return;
1613
1614 fail:
1615 aprint_error_dev(acpi_softc->sc_dev, "failed to "
1616 "activate %s\n", (*di)->HardwareId.String);
1617 }
1618
1619 /*
1620 * XXX: This very incomplete.
1621 */
1622 ACPI_STATUS
1623 acpi_allocate_resources(ACPI_HANDLE handle)
1624 {
1625 ACPI_BUFFER bufp, bufc, bufn;
1626 ACPI_RESOURCE *resp, *resc, *resn;
1627 ACPI_RESOURCE_IRQ *irq;
1628 ACPI_RESOURCE_EXTENDED_IRQ *xirq;
1629 ACPI_STATUS rv;
1630 uint delta;
1631
1632 rv = acpi_get(handle, &bufp, AcpiGetPossibleResources);
1633 if (ACPI_FAILURE(rv))
1634 goto out;
1635 rv = acpi_get(handle, &bufc, AcpiGetCurrentResources);
1636 if (ACPI_FAILURE(rv)) {
1637 goto out1;
1638 }
1639
1640 bufn.Length = 1000;
1641 bufn.Pointer = resn = malloc(bufn.Length, M_ACPI, M_WAITOK);
1642 resp = bufp.Pointer;
1643 resc = bufc.Pointer;
1644 while (resc->Type != ACPI_RESOURCE_TYPE_END_TAG &&
1645 resp->Type != ACPI_RESOURCE_TYPE_END_TAG) {
1646 while (resc->Type != resp->Type && resp->Type != ACPI_RESOURCE_TYPE_END_TAG)
1647 resp = ACPI_NEXT_RESOURCE(resp);
1648 if (resp->Type == ACPI_RESOURCE_TYPE_END_TAG)
1649 break;
1650 /* Found identical Id */
1651 resn->Type = resc->Type;
1652 switch (resc->Type) {
1653 case ACPI_RESOURCE_TYPE_IRQ:
1654 memcpy(&resn->Data, &resp->Data,
1655 sizeof(ACPI_RESOURCE_IRQ));
1656 irq = (ACPI_RESOURCE_IRQ *)&resn->Data;
1657 irq->Interrupts[0] =
1658 ((ACPI_RESOURCE_IRQ *)&resp->Data)->
1659 Interrupts[irq->InterruptCount-1];
1660 irq->InterruptCount = 1;
1661 resn->Length = ACPI_RS_SIZE(ACPI_RESOURCE_IRQ);
1662 break;
1663 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
1664 memcpy(&resn->Data, &resp->Data,
1665 sizeof(ACPI_RESOURCE_EXTENDED_IRQ));
1666 xirq = (ACPI_RESOURCE_EXTENDED_IRQ *)&resn->Data;
1667 #if 0
1668 /*
1669 * XXX not duplicating the interrupt logic above
1670 * because its not clear what it accomplishes.
1671 */
1672 xirq->Interrupts[0] =
1673 ((ACPI_RESOURCE_EXT_IRQ *)&resp->Data)->
1674 Interrupts[irq->NumberOfInterrupts-1];
1675 xirq->NumberOfInterrupts = 1;
1676 #endif
1677 resn->Length = ACPI_RS_SIZE(ACPI_RESOURCE_EXTENDED_IRQ);
1678 break;
1679 case ACPI_RESOURCE_TYPE_IO:
1680 memcpy(&resn->Data, &resp->Data,
1681 sizeof(ACPI_RESOURCE_IO));
1682 resn->Length = resp->Length;
1683 break;
1684 default:
1685 aprint_error_dev(acpi_softc->sc_dev,
1686 "%s: invalid type %u\n", __func__, resc->Type);
1687 rv = AE_BAD_DATA;
1688 goto out2;
1689 }
1690 resc = ACPI_NEXT_RESOURCE(resc);
1691 resn = ACPI_NEXT_RESOURCE(resn);
1692 resp = ACPI_NEXT_RESOURCE(resp);
1693 delta = (UINT8 *)resn - (UINT8 *)bufn.Pointer;
1694 if (delta >=
1695 bufn.Length-ACPI_RS_SIZE(ACPI_RESOURCE_DATA)) {
1696 bufn.Length *= 2;
1697 bufn.Pointer = realloc(bufn.Pointer, bufn.Length,
1698 M_ACPI, M_WAITOK);
1699 resn = (ACPI_RESOURCE *)((UINT8 *)bufn.Pointer + delta);
1700 }
1701 }
1702
1703 if (resc->Type != ACPI_RESOURCE_TYPE_END_TAG) {
1704 aprint_error_dev(acpi_softc->sc_dev,
1705 "%s: resc not exhausted\n", __func__);
1706 rv = AE_BAD_DATA;
1707 goto out3;
1708 }
1709
1710 resn->Type = ACPI_RESOURCE_TYPE_END_TAG;
1711 rv = AcpiSetCurrentResources(handle, &bufn);
1712
1713 if (ACPI_FAILURE(rv))
1714 aprint_error_dev(acpi_softc->sc_dev, "%s: failed to set "
1715 "resources: %s\n", __func__, AcpiFormatException(rv));
1716
1717 out3:
1718 free(bufn.Pointer, M_ACPI);
1719 out2:
1720 ACPI_FREE(bufc.Pointer);
1721 out1:
1722 ACPI_FREE(bufp.Pointer);
1723 out:
1724 return rv;
1725 }
1726
1727 #undef ACPI_DEV_VALID
1728 #undef ACPI_DEV_STATUS
1729
1730 #endif /* ACPI_ACTIVATE_DEV */
1731
1732 SYSCTL_SETUP(sysctl_acpi_setup, "sysctl hw.acpi subtree setup")
1733 {
1734 const struct sysctlnode *mnode, *rnode;
1735 int err;
1736
1737 err = sysctl_createv(clog, 0, NULL, &rnode,
1738 CTLFLAG_PERMANENT, CTLTYPE_NODE, "hw",
1739 NULL, NULL, 0, NULL, 0,
1740 CTL_HW, CTL_EOL);
1741
1742 if (err != 0)
1743 return;
1744
1745 err = sysctl_createv(clog, 0, &rnode, &rnode,
1746 CTLFLAG_PERMANENT, CTLTYPE_NODE,
1747 "acpi", SYSCTL_DESCR("ACPI subsystem parameters"),
1748 NULL, 0, NULL, 0,
1749 CTL_CREATE, CTL_EOL);
1750
1751 if (err != 0)
1752 return;
1753
1754 (void)sysctl_createv(NULL, 0, &rnode, NULL,
1755 CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_QUAD,
1756 "root", SYSCTL_DESCR("ACPI root pointer"),
1757 NULL, 0, &acpi_root_pointer, sizeof(acpi_root_pointer),
1758 CTL_CREATE, CTL_EOL);
1759
1760 (void)sysctl_createv(NULL, 0, &rnode, NULL,
1761 CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_STRING,
1762 "supported_states", SYSCTL_DESCR("Supported system states"),
1763 sysctl_hw_acpi_sleepstates, 0, NULL, 0,
1764 CTL_CREATE, CTL_EOL);
1765
1766 err = sysctl_createv(NULL, 0, NULL, &mnode,
1767 CTLFLAG_PERMANENT, CTLTYPE_NODE, "machdep",
1768 NULL, NULL, 0, NULL, 0,
1769 CTL_MACHDEP, CTL_EOL);
1770
1771 if (err == 0) {
1772
1773 (void)sysctl_createv(NULL, 0, &mnode, NULL,
1774 CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT,
1775 "sleep_state", SYSCTL_DESCR("System sleep state"),
1776 sysctl_hw_acpi_sleepstate, 0, NULL, 0,
1777 CTL_CREATE, CTL_EOL);
1778 }
1779
1780 err = sysctl_createv(clog, 0, &rnode, &rnode,
1781 CTLFLAG_PERMANENT, CTLTYPE_NODE,
1782 "stat", SYSCTL_DESCR("ACPI statistics"),
1783 NULL, 0, NULL, 0,
1784 CTL_CREATE, CTL_EOL);
1785
1786 if (err != 0)
1787 return;
1788
1789 (void)sysctl_createv(clog, 0, &rnode, NULL,
1790 CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_QUAD,
1791 "gpe", SYSCTL_DESCR("Number of dispatched GPEs"),
1792 NULL, 0, &AcpiGpeCount, sizeof(AcpiGpeCount),
1793 CTL_CREATE, CTL_EOL);
1794
1795 (void)sysctl_createv(clog, 0, &rnode, NULL,
1796 CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_QUAD,
1797 "sci", SYSCTL_DESCR("Number of SCI interrupts"),
1798 NULL, 0, &AcpiSciCount, sizeof(AcpiSciCount),
1799 CTL_CREATE, CTL_EOL);
1800
1801 (void)sysctl_createv(clog, 0, &rnode, NULL,
1802 CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_QUAD,
1803 "fixed", SYSCTL_DESCR("Number of fixed events"),
1804 sysctl_hw_acpi_fixedstats, 0, NULL, 0,
1805 CTL_CREATE, CTL_EOL);
1806
1807 (void)sysctl_createv(clog, 0, &rnode, NULL,
1808 CTLFLAG_PERMANENT | CTLFLAG_READONLY, CTLTYPE_QUAD,
1809 "method", SYSCTL_DESCR("Number of methods executed"),
1810 NULL, 0, &AcpiMethodCount, sizeof(AcpiMethodCount),
1811 CTL_CREATE, CTL_EOL);
1812
1813 CTASSERT(sizeof(AcpiGpeCount) == sizeof(uint64_t));
1814 CTASSERT(sizeof(AcpiSciCount) == sizeof(uint64_t));
1815 }
1816
1817 static int
1818 sysctl_hw_acpi_fixedstats(SYSCTLFN_ARGS)
1819 {
1820 struct sysctlnode node;
1821 uint64_t t;
1822 int err, i;
1823
1824 for (i = t = 0; i < __arraycount(AcpiFixedEventCount); i++)
1825 t += AcpiFixedEventCount[i];
1826
1827 node = *rnode;
1828 node.sysctl_data = &t;
1829
1830 err = sysctl_lookup(SYSCTLFN_CALL(&node));
1831
1832 if (err || newp == NULL)
1833 return err;
1834
1835 return 0;
1836 }
1837
1838 static int
1839 sysctl_hw_acpi_sleepstate(SYSCTLFN_ARGS)
1840 {
1841 struct acpi_softc *sc = acpi_softc;
1842 struct sysctlnode node;
1843 int err, t;
1844
1845 if (acpi_softc == NULL)
1846 return ENOSYS;
1847
1848 node = *rnode;
1849 t = sc->sc_sleepstate;
1850 node.sysctl_data = &t;
1851
1852 err = sysctl_lookup(SYSCTLFN_CALL(&node));
1853
1854 if (err || newp == NULL)
1855 return err;
1856
1857 if (t < ACPI_STATE_S0 || t > ACPI_STATE_S5)
1858 return EINVAL;
1859
1860 acpi_enter_sleep_state(sc, t);
1861
1862 return 0;
1863 }
1864
1865 static int
1866 sysctl_hw_acpi_sleepstates(SYSCTLFN_ARGS)
1867 {
1868 struct acpi_softc *sc = acpi_softc;
1869 struct sysctlnode node;
1870 char t[3 * 6 + 1];
1871 int err;
1872
1873 if (acpi_softc == NULL)
1874 return ENOSYS;
1875
1876 (void)memset(t, '\0', sizeof(t));
1877
1878 (void)snprintf(t, sizeof(t), "%s%s%s%s%s%s",
1879 ((sc->sc_sleepstates & __BIT(0)) != 0) ? "S0 " : "",
1880 ((sc->sc_sleepstates & __BIT(1)) != 0) ? "S1 " : "",
1881 ((sc->sc_sleepstates & __BIT(2)) != 0) ? "S2 " : "",
1882 ((sc->sc_sleepstates & __BIT(3)) != 0) ? "S3 " : "",
1883 ((sc->sc_sleepstates & __BIT(4)) != 0) ? "S4 " : "",
1884 ((sc->sc_sleepstates & __BIT(5)) != 0) ? "S5 " : "");
1885
1886 node = *rnode;
1887 node.sysctl_data = &t;
1888
1889 err = sysctl_lookup(SYSCTLFN_CALL(&node));
1890
1891 if (err || newp == NULL)
1892 return err;
1893
1894 return 0;
1895 }
1896
1897 static ACPI_TABLE_HEADER *
1898 acpi_map_rsdt(void)
1899 {
1900 ACPI_PHYSICAL_ADDRESS paddr;
1901 ACPI_TABLE_RSDP *rsdp;
1902
1903 paddr = AcpiOsGetRootPointer();
1904 if (paddr == 0) {
1905 printf("ACPI: couldn't get root pointer\n");
1906 return NULL;
1907 }
1908 rsdp = AcpiOsMapMemory(paddr, sizeof(ACPI_TABLE_RSDP));
1909 if (rsdp == NULL) {
1910 printf("ACPI: couldn't map RSDP\n");
1911 return NULL;
1912 }
1913 if (rsdp->Revision > 1 && rsdp->XsdtPhysicalAddress)
1914 paddr = (ACPI_PHYSICAL_ADDRESS)rsdp->XsdtPhysicalAddress;
1915 else
1916 paddr = (ACPI_PHYSICAL_ADDRESS)rsdp->RsdtPhysicalAddress;
1917 AcpiOsUnmapMemory(rsdp, sizeof(ACPI_TABLE_RSDP));
1918
1919 return AcpiOsMapMemory(paddr, sizeof(ACPI_TABLE_HEADER));
1920 }
1921
1922 static void
1923 acpi_unmap_rsdt(ACPI_TABLE_HEADER *rsdt)
1924 {
1925 if (rsdt == NULL)
1926 return;
1927
1928 AcpiOsUnmapMemory(rsdt, sizeof(ACPI_TABLE_HEADER));
1929 }
1930