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