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