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