acpi.c revision 1.392
1/* $OpenBSD: acpi.c,v 1.392 2020/12/05 16:14:30 kettenis Exp $ */
2/*
3 * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
4 * Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <sys/param.h>
20#include <sys/systm.h>
21#include <sys/buf.h>
22#include <sys/device.h>
23#include <sys/malloc.h>
24#include <sys/fcntl.h>
25#include <sys/ioccom.h>
26#include <sys/event.h>
27#include <sys/signalvar.h>
28#include <sys/proc.h>
29#include <sys/kthread.h>
30#include <sys/sched.h>
31#include <sys/reboot.h>
32#include <sys/sysctl.h>
33#include <sys/mount.h>
34#include <sys/syscallargs.h>
35#include <sys/sensors.h>
36#include <sys/timetc.h>
37
38#ifdef HIBERNATE
39#include <sys/hibernate.h>
40#endif
41
42#include <machine/conf.h>
43#include <machine/cpufunc.h>
44#include <machine/bus.h>
45
46#include <dev/pci/pcivar.h>
47#include <dev/acpi/acpireg.h>
48#include <dev/acpi/acpivar.h>
49#include <dev/acpi/amltypes.h>
50#include <dev/acpi/acpidev.h>
51#include <dev/acpi/dsdt.h>
52#include <dev/wscons/wsdisplayvar.h>
53
54#include <dev/pci/pcidevs.h>
55#include <dev/pci/ppbreg.h>
56
57#include <dev/pci/pciidevar.h>
58
59#include <machine/apmvar.h>
60#define APMUNIT(dev)	(minor(dev)&0xf0)
61#define APMDEV(dev)	(minor(dev)&0x0f)
62#define APMDEV_NORMAL	0
63#define APMDEV_CTL	8
64
65#include "wd.h"
66#include "wsdisplay.h"
67#include "softraid.h"
68
69#ifdef ACPI_DEBUG
70int	acpi_debug = 16;
71#endif
72
73int	acpi_poll_enabled;
74int	acpi_hasprocfvs;
75int	acpi_haspci;
76
77#define ACPIEN_RETRIES 15
78
79struct aml_node *acpi_pci_match(struct device *, struct pci_attach_args *);
80pcireg_t acpi_pci_min_powerstate(pci_chipset_tag_t, pcitag_t);
81void	 acpi_pci_set_powerstate(pci_chipset_tag_t, pcitag_t, int, int);
82int	acpi_pci_notify(struct aml_node *, int, void *);
83
84int	acpi_submatch(struct device *, void *, void *);
85int	acpi_print(void *, const char *);
86
87void	acpi_map_pmregs(struct acpi_softc *);
88void	acpi_unmap_pmregs(struct acpi_softc *);
89
90int	acpi_loadtables(struct acpi_softc *, struct acpi_rsdp *);
91
92int	_acpi_matchhids(const char *, const char *[]);
93
94int	acpi_inidev(struct aml_node *, void *);
95int	acpi_foundprt(struct aml_node *, void *);
96
97int	acpi_enable(struct acpi_softc *);
98void	acpi_init_states(struct acpi_softc *);
99
100void 	acpi_gpe_task(void *, int);
101void	acpi_sbtn_task(void *, int);
102void	acpi_pbtn_task(void *, int);
103
104int	acpi_enabled;
105
106void	acpi_init_gpes(struct acpi_softc *);
107void	acpi_disable_allgpes(struct acpi_softc *);
108struct gpe_block *acpi_find_gpe(struct acpi_softc *, int);
109void	acpi_enable_onegpe(struct acpi_softc *, int);
110int	acpi_gpe(struct acpi_softc *, int, void *);
111
112void	acpi_enable_rungpes(struct acpi_softc *);
113void	acpi_enable_wakegpes(struct acpi_softc *, int);
114
115
116int	acpi_foundec(struct aml_node *, void *);
117int	acpi_foundsony(struct aml_node *node, void *arg);
118int	acpi_foundhid(struct aml_node *, void *);
119int	acpi_add_device(struct aml_node *node, void *arg);
120
121void	acpi_thread(void *);
122void	acpi_create_thread(void *);
123
124#ifndef SMALL_KERNEL
125
126void	acpi_indicator(struct acpi_softc *, int);
127
128void	acpi_init_pm(struct acpi_softc *);
129
130int	acpi_founddock(struct aml_node *, void *);
131int	acpi_foundpss(struct aml_node *, void *);
132int	acpi_foundtmp(struct aml_node *, void *);
133int	acpi_foundprw(struct aml_node *, void *);
134int	acpi_foundvideo(struct aml_node *, void *);
135int	acpi_foundsbs(struct aml_node *node, void *);
136
137int	acpi_foundide(struct aml_node *node, void *arg);
138int	acpiide_notify(struct aml_node *, int, void *);
139void	wdcattach(struct channel_softc *);
140int	wdcdetach(struct channel_softc *, int);
141int	is_ejectable_bay(struct aml_node *node);
142int	is_ata(struct aml_node *node);
143int	is_ejectable(struct aml_node *node);
144
145struct idechnl {
146	struct acpi_softc *sc;
147	int64_t		addr;
148	int64_t		chnl;
149	int64_t		sta;
150};
151
152/*
153 * This is a list of Synaptics devices with a 'top button area'
154 * based on the list in Linux supplied by Synaptics
155 * Synaptics clickpads with the following pnp ids will get a unique
156 * wscons mouse type that is used to define trackpad regions that will
157 * emulate mouse buttons
158 */
159static const char *sbtn_pnp[] = {
160	"LEN0017",
161	"LEN0018",
162	"LEN0019",
163	"LEN0023",
164	"LEN002A",
165	"LEN002B",
166	"LEN002C",
167	"LEN002D",
168	"LEN002E",
169	"LEN0033",
170	"LEN0034",
171	"LEN0035",
172	"LEN0036",
173	"LEN0037",
174	"LEN0038",
175	"LEN0039",
176	"LEN0041",
177	"LEN0042",
178	"LEN0045",
179	"LEN0047",
180	"LEN0049",
181	"LEN2000",
182	"LEN2001",
183	"LEN2002",
184	"LEN2003",
185	"LEN2004",
186	"LEN2005",
187	"LEN2006",
188	"LEN2007",
189	"LEN2008",
190	"LEN2009",
191	"LEN200A",
192	"LEN200B",
193};
194
195int	mouse_has_softbtn;
196#endif /* SMALL_KERNEL */
197
198struct acpi_softc *acpi_softc;
199
200/* XXX move this into dsdt softc at some point */
201extern struct aml_node aml_root;
202
203struct cfdriver acpi_cd = {
204	NULL, "acpi", DV_DULL
205};
206
207uint8_t
208acpi_pci_conf_read_1(pci_chipset_tag_t pc, pcitag_t tag, int reg)
209{
210	uint32_t val = pci_conf_read(pc, tag, reg & ~0x3);
211	return (val >> ((reg & 0x3) << 3));
212}
213
214uint16_t
215acpi_pci_conf_read_2(pci_chipset_tag_t pc, pcitag_t tag, int reg)
216{
217	uint32_t val = pci_conf_read(pc, tag, reg & ~0x2);
218	return (val >> ((reg & 0x2) << 3));
219}
220
221uint32_t
222acpi_pci_conf_read_4(pci_chipset_tag_t pc, pcitag_t tag, int reg)
223{
224	return pci_conf_read(pc, tag, reg);
225}
226
227void
228acpi_pci_conf_write_1(pci_chipset_tag_t pc, pcitag_t tag, int reg, uint8_t val)
229{
230	uint32_t tmp = pci_conf_read(pc, tag, reg & ~0x3);
231	tmp &= ~(0xff << ((reg & 0x3) << 3));
232	tmp |= (val << ((reg & 0x3) << 3));
233	pci_conf_write(pc, tag, reg & ~0x3, tmp);
234}
235
236void
237acpi_pci_conf_write_2(pci_chipset_tag_t pc, pcitag_t tag, int reg, uint16_t val)
238{
239	uint32_t tmp = pci_conf_read(pc, tag, reg & ~0x2);
240	tmp &= ~(0xffff << ((reg & 0x2) << 3));
241	tmp |= (val << ((reg & 0x2) << 3));
242	pci_conf_write(pc, tag, reg & ~0x2, tmp);
243}
244
245void
246acpi_pci_conf_write_4(pci_chipset_tag_t pc, pcitag_t tag, int reg, uint32_t val)
247{
248	pci_conf_write(pc, tag, reg, val);
249}
250
251int
252acpi_gasio(struct acpi_softc *sc, int iodir, int iospace, uint64_t address,
253    int access_size, int len, void *buffer)
254{
255	uint8_t *pb;
256	bus_space_tag_t iot;
257	bus_space_handle_t ioh;
258	pci_chipset_tag_t pc;
259	pcitag_t tag;
260	int reg, idx;
261
262	dnprintf(50, "gasio: %.2x 0x%.8llx %s\n",
263	    iospace, address, (iodir == ACPI_IOWRITE) ? "write" : "read");
264
265	KASSERT((len % access_size) == 0);
266
267	pb = (uint8_t *)buffer;
268	switch (iospace) {
269	case GAS_SYSTEM_MEMORY:
270	case GAS_SYSTEM_IOSPACE:
271		if (iospace == GAS_SYSTEM_MEMORY)
272			iot = sc->sc_memt;
273		else
274			iot = sc->sc_iot;
275
276		if (acpi_bus_space_map(iot, address, len, 0, &ioh) != 0) {
277			printf("%s: unable to map iospace\n", DEVNAME(sc));
278			return (-1);
279		}
280		for (reg = 0; reg < len; reg += access_size) {
281			if (iodir == ACPI_IOREAD) {
282				switch (access_size) {
283				case 1:
284					*(uint8_t *)(pb + reg) =
285					    bus_space_read_1(iot, ioh, reg);
286					dnprintf(80, "os_in8(%llx) = %x\n",
287					    reg+address, *(uint8_t *)(pb+reg));
288					break;
289				case 2:
290					*(uint16_t *)(pb + reg) =
291					    bus_space_read_2(iot, ioh, reg);
292					dnprintf(80, "os_in16(%llx) = %x\n",
293					    reg+address, *(uint16_t *)(pb+reg));
294					break;
295				case 4:
296					*(uint32_t *)(pb + reg) =
297					    bus_space_read_4(iot, ioh, reg);
298					break;
299				default:
300					printf("%s: rdio: invalid size %d\n",
301					    DEVNAME(sc), access_size);
302					return (-1);
303				}
304			} else {
305				switch (access_size) {
306				case 1:
307					bus_space_write_1(iot, ioh, reg,
308					    *(uint8_t *)(pb + reg));
309					dnprintf(80, "os_out8(%llx,%x)\n",
310					    reg+address, *(uint8_t *)(pb+reg));
311					break;
312				case 2:
313					bus_space_write_2(iot, ioh, reg,
314					    *(uint16_t *)(pb + reg));
315					dnprintf(80, "os_out16(%llx,%x)\n",
316					    reg+address, *(uint16_t *)(pb+reg));
317					break;
318				case 4:
319					bus_space_write_4(iot, ioh, reg,
320					    *(uint32_t *)(pb + reg));
321					break;
322				default:
323					printf("%s: wrio: invalid size %d\n",
324					    DEVNAME(sc), access_size);
325					return (-1);
326				}
327			}
328		}
329		acpi_bus_space_unmap(iot, ioh, len);
330		break;
331
332	case GAS_PCI_CFG_SPACE:
333		/*
334		 * The ACPI standard says that a function number of
335		 * FFFF can be used to refer to all functions on a
336		 * device.  This makes no sense though in the context
337		 * of accessing PCI config space.  Yet there is AML
338		 * out there that does this.  We simulate a read from
339		 * a nonexistent device here.  Writes will panic when
340		 * we try to construct the tag below.
341		 */
342		if (ACPI_PCI_FN(address) == 0xffff && iodir == ACPI_IOREAD) {
343			memset(buffer, 0xff, len);
344			return (0);
345		}
346
347		pc = pci_lookup_segment(ACPI_PCI_SEG(address));
348		tag = pci_make_tag(pc,
349		    ACPI_PCI_BUS(address), ACPI_PCI_DEV(address),
350		    ACPI_PCI_FN(address));
351
352		reg = ACPI_PCI_REG(address);
353		for (idx = 0; idx < len; idx += access_size) {
354			if (iodir == ACPI_IOREAD) {
355				switch (access_size) {
356				case 1:
357					*(uint8_t *)(pb + idx) =
358					    acpi_pci_conf_read_1(pc, tag, reg + idx);
359					break;
360				case 2:
361					*(uint16_t *)(pb + idx) =
362					    acpi_pci_conf_read_2(pc, tag, reg + idx);
363					break;
364				case 4:
365					*(uint32_t *)(pb + idx) =
366					    acpi_pci_conf_read_4(pc, tag, reg + idx);
367					break;
368				default:
369					printf("%s: rdcfg: invalid size %d\n",
370					    DEVNAME(sc), access_size);
371					return (-1);
372				}
373			} else {
374				switch (access_size) {
375				case 1:
376					acpi_pci_conf_write_1(pc, tag, reg + idx,
377					    *(uint8_t *)(pb + idx));
378					break;
379				case 2:
380					acpi_pci_conf_write_2(pc, tag, reg + idx,
381					    *(uint16_t *)(pb + idx));
382					break;
383				case 4:
384					acpi_pci_conf_write_4(pc, tag, reg + idx,
385					    *(uint32_t *)(pb + idx));
386					break;
387				default:
388					printf("%s: wrcfg: invalid size %d\n",
389					    DEVNAME(sc), access_size);
390					return (-1);
391				}
392			}
393		}
394		break;
395
396	case GAS_EMBEDDED:
397		if (sc->sc_ec == NULL) {
398			printf("%s: WARNING EC not initialized\n", DEVNAME(sc));
399			return (-1);
400		}
401		if (iodir == ACPI_IOREAD)
402			acpiec_read(sc->sc_ec, (uint8_t)address, len, buffer);
403		else
404			acpiec_write(sc->sc_ec, (uint8_t)address, len, buffer);
405		break;
406	}
407	return (0);
408}
409
410int
411acpi_inidev(struct aml_node *node, void *arg)
412{
413	struct acpi_softc	*sc = (struct acpi_softc *)arg;
414	int64_t sta;
415
416	/*
417	 * Per the ACPI spec 6.5.1, only run _INI when device is there or
418	 * when there is no _STA.  We terminate the tree walk (with return 1)
419	 * early if necessary.
420	 */
421
422	/* Evaluate _STA to decide _INI fate and walk fate */
423	sta = acpi_getsta(sc, node->parent);
424
425	/* Evaluate _INI if we are present */
426	if (sta & STA_PRESENT)
427		aml_evalnode(sc, node, 0, NULL, NULL);
428
429	/* If we are functioning, we walk/search our children */
430	if (sta & STA_DEV_OK)
431		return 0;
432
433	/* If we are not enabled, or not present, terminate search */
434	if (!(sta & (STA_PRESENT|STA_ENABLED)))
435		return 1;
436
437	/* Default just continue search */
438	return 0;
439}
440
441int
442acpi_foundprt(struct aml_node *node, void *arg)
443{
444	struct acpi_softc	*sc = (struct acpi_softc *)arg;
445	struct device		*self = (struct device *)arg;
446	struct acpi_attach_args	aaa;
447	int64_t sta;
448
449	dnprintf(10, "found prt entry: %s\n", node->parent->name);
450
451	/* Evaluate _STA to decide _PRT fate and walk fate */
452	sta = acpi_getsta(sc, node->parent);
453	if (sta & STA_PRESENT) {
454		memset(&aaa, 0, sizeof(aaa));
455		aaa.aaa_iot = sc->sc_iot;
456		aaa.aaa_memt = sc->sc_memt;
457		aaa.aaa_node = node;
458		aaa.aaa_name = "acpiprt";
459
460		config_found(self, &aaa, acpi_print);
461	}
462
463	/* If we are functioning, we walk/search our children */
464	if (sta & STA_DEV_OK)
465		return 0;
466
467	/* If we are not enabled, or not present, terminate search */
468	if (!(sta & (STA_PRESENT|STA_ENABLED)))
469		return 1;
470
471	/* Default just continue search */
472	return 0;
473}
474
475TAILQ_HEAD(, acpi_pci) acpi_pcidevs =
476    TAILQ_HEAD_INITIALIZER(acpi_pcidevs);
477TAILQ_HEAD(, acpi_pci) acpi_pcirootdevs =
478    TAILQ_HEAD_INITIALIZER(acpi_pcirootdevs);
479
480int acpi_getpci(struct aml_node *node, void *arg);
481int acpi_getminbus(int crsidx, union acpi_resource *crs, void *arg);
482
483int
484acpi_getminbus(int crsidx, union acpi_resource *crs, void *arg)
485{
486	int *bbn = arg;
487	int typ = AML_CRSTYPE(crs);
488
489	/* Check for embedded bus number */
490	if (typ == LR_WORD && crs->lr_word.type == 2) {
491		/* If _MIN > _MAX, the resource is considered to be invalid. */
492		if (crs->lr_word._min > crs->lr_word._max)
493			return -1;
494		*bbn = crs->lr_word._min;
495	}
496	return 0;
497}
498
499int
500acpi_matchcls(struct acpi_attach_args *aaa, int class, int subclass,
501    int interface)
502{
503	struct acpi_softc *sc = acpi_softc;
504	struct aml_value res;
505
506	if (aaa->aaa_dev == NULL || aaa->aaa_node == NULL)
507		return (0);
508
509	if (aml_evalname(sc, aaa->aaa_node, "_CLS", 0, NULL, &res))
510		return (0);
511
512	if (res.type != AML_OBJTYPE_PACKAGE || res.length != 3 ||
513	    res.v_package[0]->type != AML_OBJTYPE_INTEGER ||
514	    res.v_package[1]->type != AML_OBJTYPE_INTEGER ||
515	    res.v_package[2]->type != AML_OBJTYPE_INTEGER)
516		return (0);
517
518	if (res.v_package[0]->v_integer == class &&
519	    res.v_package[1]->v_integer == subclass &&
520	    res.v_package[2]->v_integer == interface)
521		return (1);
522
523	return (0);
524}
525
526int
527_acpi_matchhids(const char *hid, const char *hids[])
528{
529	int i;
530
531	for (i = 0; hids[i]; i++)
532		if (!strcmp(hid, hids[i]))
533			return (1);
534	return (0);
535}
536
537int
538acpi_matchhids(struct acpi_attach_args *aa, const char *hids[],
539    const char *driver)
540{
541	if (aa->aaa_dev == NULL || aa->aaa_node == NULL)
542		return (0);
543
544	if (_acpi_matchhids(aa->aaa_dev, hids)) {
545		dnprintf(5, "driver %s matches at least one hid\n", driver);
546		return (2);
547	}
548	if (aa->aaa_cdev && _acpi_matchhids(aa->aaa_cdev, hids)) {
549		dnprintf(5, "driver %s matches at least one cid\n", driver);
550		return (1);
551	}
552
553	return (0);
554}
555
556int64_t
557acpi_getsta(struct acpi_softc *sc, struct aml_node *node)
558{
559	int64_t sta;
560
561	if (aml_evalinteger(sc, node, "_STA", 0, NULL, &sta))
562		sta = STA_PRESENT | STA_ENABLED | STA_SHOW_UI |
563		    STA_DEV_OK | STA_BATTERY;
564
565	return sta;
566}
567
568/* Map ACPI device node to PCI */
569int
570acpi_getpci(struct aml_node *node, void *arg)
571{
572	const char *pcihid[] = { ACPI_DEV_PCIB, ACPI_DEV_PCIEB, "HWP0002", 0 };
573	struct acpi_pci *pci, *ppci;
574	struct aml_value res;
575	struct acpi_softc *sc = arg;
576	pci_chipset_tag_t pc;
577	pcitag_t tag;
578	uint64_t val;
579	int64_t sta;
580	uint32_t reg;
581
582	sta = acpi_getsta(sc, node);
583	if ((sta & STA_PRESENT) == 0)
584		return 0;
585
586	if (!node->value || node->value->type != AML_OBJTYPE_DEVICE)
587		return 0;
588	if (!aml_evalhid(node, &res)) {
589		/* Check if this is a PCI Root node */
590		if (_acpi_matchhids(res.v_string, pcihid)) {
591			aml_freevalue(&res);
592
593			pci = malloc(sizeof(*pci), M_DEVBUF, M_WAITOK|M_ZERO);
594
595			pci->bus = -1;
596			if (!aml_evalinteger(sc, node, "_SEG", 0, NULL, &val))
597				pci->seg = val;
598			if (!aml_evalname(sc, node, "_CRS", 0, NULL, &res)) {
599				aml_parse_resource(&res, acpi_getminbus,
600				    &pci->bus);
601				dnprintf(10, "%s post-crs: %d\n",
602				    aml_nodename(node), pci->bus);
603			}
604			if (!aml_evalinteger(sc, node, "_BBN", 0, NULL, &val)) {
605				dnprintf(10, "%s post-bbn: %d, %lld\n",
606				    aml_nodename(node), pci->bus, val);
607				if (pci->bus == -1)
608					pci->bus = val;
609			}
610			pci->sub = pci->bus;
611			node->pci = pci;
612			dnprintf(10, "found PCI root: %s %d\n",
613			    aml_nodename(node), pci->bus);
614			TAILQ_INSERT_TAIL(&acpi_pcirootdevs, pci, next);
615		}
616		aml_freevalue(&res);
617		return 0;
618	}
619
620	/* If parent is not PCI, or device does not have _ADR, return */
621	if (!node->parent || (ppci = node->parent->pci) == NULL)
622		return 0;
623	if (aml_evalinteger(sc, node, "_ADR", 0, NULL, &val))
624		return 0;
625
626	pci = malloc(sizeof(*pci), M_DEVBUF, M_WAITOK|M_ZERO);
627	pci->seg = ppci->seg;
628	pci->bus = ppci->sub;
629	pci->dev = ACPI_ADR_PCIDEV(val);
630	pci->fun = ACPI_ADR_PCIFUN(val);
631	pci->node = node;
632	pci->sub = -1;
633
634	dnprintf(10, "%.2x:%.2x.%x -> %s\n",
635		pci->bus, pci->dev, pci->fun,
636		aml_nodename(node));
637
638	/* Collect device power state information. */
639	if (aml_evalinteger(sc, node, "_S3D", 0, NULL, &val) == 0)
640		pci->_s3d = val;
641	else
642		pci->_s3d = -1;
643	if (aml_evalinteger(sc, node, "_S3W", 0, NULL, &val) == 0)
644		pci->_s3w = val;
645	else
646		pci->_s3w = -1;
647	if (aml_evalinteger(sc, node, "_S4D", 0, NULL, &val) == 0)
648		pci->_s4d = val;
649	else
650		pci->_s4d = -1;
651	if (aml_evalinteger(sc, node, "_S4W", 0, NULL, &val) == 0)
652		pci->_s4w = val;
653	else
654		pci->_s4w = -1;
655
656	/* Check if PCI device exists */
657	if (pci->dev > 0x1F || pci->fun > 7) {
658		free(pci, M_DEVBUF, sizeof(*pci));
659		return (1);
660	}
661	pc = pci_lookup_segment(pci->seg);
662	tag = pci_make_tag(pc, pci->bus, pci->dev, pci->fun);
663	reg = pci_conf_read(pc, tag, PCI_ID_REG);
664	if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID) {
665		free(pci, M_DEVBUF, sizeof(*pci));
666		return (1);
667	}
668	node->pci = pci;
669
670	TAILQ_INSERT_TAIL(&acpi_pcidevs, pci, next);
671
672	/* Check if this is a PCI bridge */
673	reg = pci_conf_read(pc, tag, PCI_CLASS_REG);
674	if (PCI_CLASS(reg) == PCI_CLASS_BRIDGE &&
675	    PCI_SUBCLASS(reg) == PCI_SUBCLASS_BRIDGE_PCI) {
676		reg = pci_conf_read(pc, tag, PPB_REG_BUSINFO);
677		pci->sub = PPB_BUSINFO_SECONDARY(reg);
678
679		dnprintf(10, "found PCI bridge: %s %d\n",
680		    aml_nodename(node), pci->sub);
681
682		/* Continue scanning */
683		return (0);
684	}
685
686	/* Device does not have children, stop scanning */
687	return (1);
688}
689
690struct aml_node *
691acpi_find_pci(pci_chipset_tag_t pc, pcitag_t tag)
692{
693	struct acpi_pci *pdev;
694	int bus, dev, fun;
695
696	pci_decompose_tag(pc, tag, &bus, &dev, &fun);
697	TAILQ_FOREACH(pdev, &acpi_pcidevs, next) {
698		if (pdev->bus == bus && pdev->dev == dev && pdev->fun == fun)
699			return pdev->node;
700	}
701
702	return NULL;
703}
704
705struct aml_node *
706acpi_pci_match(struct device *dev, struct pci_attach_args *pa)
707{
708	struct acpi_pci *pdev;
709	int state;
710
711	TAILQ_FOREACH(pdev, &acpi_pcidevs, next) {
712		if (pdev->bus != pa->pa_bus ||
713		    pdev->dev != pa->pa_device ||
714		    pdev->fun != pa->pa_function)
715			continue;
716
717		dnprintf(10,"%s at acpi0 %s\n", dev->dv_xname,
718		    aml_nodename(pdev->node));
719
720		pdev->device = dev;
721
722		/*
723		 * If some Power Resources are dependent on this device
724		 * initialize them.
725		 */
726		state = pci_get_powerstate(pa->pa_pc, pa->pa_tag);
727		acpi_pci_set_powerstate(pa->pa_pc, pa->pa_tag, state, 1);
728		acpi_pci_set_powerstate(pa->pa_pc, pa->pa_tag, state, 0);
729
730		aml_register_notify(pdev->node, NULL, acpi_pci_notify, pdev, 0);
731
732		return pdev->node;
733	}
734
735	return NULL;
736}
737
738pcireg_t
739acpi_pci_min_powerstate(pci_chipset_tag_t pc, pcitag_t tag)
740{
741	struct acpi_pci *pdev;
742	int bus, dev, fun;
743	int state = -1, defaultstate = pci_get_powerstate(pc, tag);
744
745	pci_decompose_tag(pc, tag, &bus, &dev, &fun);
746	TAILQ_FOREACH(pdev, &acpi_pcidevs, next) {
747		if (pdev->bus == bus && pdev->dev == dev && pdev->fun == fun) {
748			switch (acpi_softc->sc_state) {
749			case ACPI_STATE_S3:
750				defaultstate = PCI_PMCSR_STATE_D3;
751				state = MAX(pdev->_s3d, pdev->_s3w);
752				break;
753			case ACPI_STATE_S4:
754				state = MAX(pdev->_s4d, pdev->_s4w);
755				break;
756			case ACPI_STATE_S5:
757			default:
758				break;
759			}
760
761			if (state >= PCI_PMCSR_STATE_D0 &&
762			    state <= PCI_PMCSR_STATE_D3)
763				return state;
764		}
765	}
766
767	return defaultstate;
768}
769
770void
771acpi_pci_set_powerstate(pci_chipset_tag_t pc, pcitag_t tag, int state, int pre)
772{
773#if NACPIPWRRES > 0
774	struct acpi_softc *sc = acpi_softc;
775	struct acpi_pwrres *pr;
776	struct acpi_pci *pdev;
777	int bus, dev, fun;
778	char name[5];
779
780	pci_decompose_tag(pc, tag, &bus, &dev, &fun);
781	TAILQ_FOREACH(pdev, &acpi_pcidevs, next) {
782		if (pdev->bus == bus && pdev->dev == dev && pdev->fun == fun)
783			break;
784	}
785
786	/* XXX Add a check to discard nodes without Power Resources? */
787	if (pdev == NULL)
788		return;
789
790	SIMPLEQ_FOREACH(pr, &sc->sc_pwrresdevs, p_next) {
791		if (pr->p_node != pdev->node)
792			continue;
793
794		/*
795		 * If the firmware is already aware that the device
796		 * is in the given state, there's nothing to do.
797		 */
798		if (pr->p_state == state)
799			continue;
800
801		if (pre) {
802			/*
803			 * If a Resource is dependent on this device for
804			 * the given state, make sure it is turned "_ON".
805			 */
806			if (pr->p_res_state == state)
807				acpipwrres_ref_incr(pr->p_res_sc, pr->p_node);
808		} else {
809			/*
810			 * If a Resource was referenced for the state we
811			 * left, drop a reference and turn it "_OFF" if
812			 * it was the last one.
813			 */
814			if (pr->p_res_state == pr->p_state)
815				acpipwrres_ref_decr(pr->p_res_sc, pr->p_node);
816
817			if (pr->p_res_state == state) {
818				snprintf(name, sizeof(name), "_PS%d", state);
819				aml_evalname(sc, pr->p_node, name, 0,
820				    NULL, NULL);
821			}
822
823			pr->p_state = state;
824		}
825
826	}
827#endif /* NACPIPWRRES > 0 */
828}
829
830int
831acpi_pci_notify(struct aml_node *node, int ntype, void *arg)
832{
833	struct acpi_pci *pdev = arg;
834	pci_chipset_tag_t pc;
835	pcitag_t tag;
836	pcireg_t reg;
837	int offset;
838
839	/* We're only interested in Device Wake notifications. */
840	if (ntype != 2)
841		return (0);
842
843	pc = pci_lookup_segment(pdev->seg);
844	tag = pci_make_tag(pc, pdev->bus, pdev->dev, pdev->fun);
845	if (pci_get_capability(pc, tag, PCI_CAP_PWRMGMT, &offset, 0)) {
846		/* Clear the PME Status bit if it is set. */
847		reg = pci_conf_read(pc, tag, offset + PCI_PMCSR);
848		pci_conf_write(pc, tag, offset + PCI_PMCSR, reg);
849	}
850
851	return (0);
852}
853
854void
855acpi_pciroots_attach(struct device *dev, void *aux, cfprint_t pr)
856{
857	struct acpi_pci			*pdev;
858	struct pcibus_attach_args	*pba = aux;
859
860	KASSERT(pba->pba_busex != NULL);
861
862	TAILQ_FOREACH(pdev, &acpi_pcirootdevs, next) {
863		if (extent_alloc_region(pba->pba_busex, pdev->bus,
864		    1, EX_NOWAIT) != 0)
865			continue;
866		pba->pba_bus = pdev->bus;
867		config_found(dev, pba, pr);
868	}
869}
870
871/* GPIO support */
872
873struct acpi_gpio_event {
874	struct aml_node *node;
875	uint16_t pin;
876};
877
878void
879acpi_gpio_event_task(void *arg0, int arg1)
880{
881	struct aml_node *node = arg0;
882	struct aml_value evt;
883	uint16_t pin = arg1;
884	char name[5];
885
886	if (pin < 256) {
887		snprintf(name, sizeof(name), "_E%.2X", pin);
888		if (aml_evalname(acpi_softc, node, name, 0, NULL, NULL) == 0)
889			return;
890	}
891
892	memset(&evt, 0, sizeof(evt));
893	evt.v_integer = pin;
894	evt.type = AML_OBJTYPE_INTEGER;
895	aml_evalname(acpi_softc, node, "_EVT", 1, &evt, NULL);
896}
897
898int
899acpi_gpio_event(void *arg)
900{
901	struct acpi_gpio_event *ev = arg;
902
903	acpi_addtask(acpi_softc, acpi_gpio_event_task, ev->node, ev->pin);
904	acpi_wakeup(acpi_softc);
905	return 1;
906}
907
908int
909acpi_gpio_parse_events(int crsidx, union acpi_resource *crs, void *arg)
910{
911	struct aml_node *devnode = arg;
912	struct aml_node *node;
913	uint16_t pin;
914
915	switch (AML_CRSTYPE(crs)) {
916	case LR_GPIO:
917		node = aml_searchname(devnode,
918		    (char *)&crs->pad[crs->lr_gpio.res_off]);
919		pin = *(uint16_t *)&crs->pad[crs->lr_gpio.pin_off];
920		if (crs->lr_gpio.type == LR_GPIO_INT && pin < 256 &&
921		    node && node->gpio && node->gpio->intr_establish) {
922			struct acpi_gpio *gpio = node->gpio;
923			struct acpi_gpio_event *ev;
924
925			ev = malloc(sizeof(*ev), M_DEVBUF, M_WAITOK);
926			ev->node = devnode;
927			ev->pin = pin;
928			gpio->intr_establish(gpio->cookie, pin,
929			    crs->lr_gpio.tflags, acpi_gpio_event, ev);
930		}
931		break;
932	default:
933		printf("%s: unknown resource type %d\n", __func__,
934		    AML_CRSTYPE(crs));
935	}
936
937	return 0;
938}
939
940void
941acpi_register_gpio(struct acpi_softc *sc, struct aml_node *devnode)
942{
943	struct aml_value arg[2];
944	struct aml_node *node;
945	struct aml_value res;
946
947	/* Register GeneralPurposeIO address space. */
948	memset(&arg, 0, sizeof(arg));
949	arg[0].type = AML_OBJTYPE_INTEGER;
950	arg[0].v_integer = ACPI_OPREG_GPIO;
951	arg[1].type = AML_OBJTYPE_INTEGER;
952	arg[1].v_integer = 1;
953	node = aml_searchname(devnode, "_REG");
954	if (node && aml_evalnode(sc, node, 2, arg, NULL))
955		printf("%s: _REG failed\n", node->name);
956
957	/* Register GPIO signaled ACPI events. */
958	if (aml_evalname(sc, devnode, "_AEI", 0, NULL, &res))
959		return;
960	aml_parse_resource(&res, acpi_gpio_parse_events, devnode);
961}
962
963#ifndef SMALL_KERNEL
964
965void
966acpi_register_gsb(struct acpi_softc *sc, struct aml_node *devnode)
967{
968	struct aml_value arg[2];
969	struct aml_node *node;
970
971	/* Register GenericSerialBus address space. */
972	memset(&arg, 0, sizeof(arg));
973	arg[0].type = AML_OBJTYPE_INTEGER;
974	arg[0].v_integer = ACPI_OPREG_GSB;
975	arg[1].type = AML_OBJTYPE_INTEGER;
976	arg[1].v_integer = 1;
977	node = aml_searchname(devnode, "_REG");
978	if (node && aml_evalnode(sc, node, 2, arg, NULL))
979		printf("%s: _REG failed\n", node->name);
980}
981
982#endif
983
984void
985acpi_attach_common(struct acpi_softc *sc, paddr_t base)
986{
987	struct acpi_mem_map handle;
988	struct acpi_rsdp *rsdp;
989	struct acpi_q *entry;
990	struct acpi_dsdt *p_dsdt;
991#ifndef SMALL_KERNEL
992	int wakeup_dev_ct;
993	struct acpi_wakeq *wentry;
994	struct device *dev;
995#endif /* SMALL_KERNEL */
996	paddr_t facspa;
997	uint16_t pm1;
998	int s;
999
1000	rw_init(&sc->sc_lck, "acpilk");
1001
1002	acpi_softc = sc;
1003
1004	if (acpi_map(base, sizeof(struct acpi_rsdp), &handle)) {
1005		printf(": can't map memory\n");
1006		return;
1007	}
1008	rsdp = (struct acpi_rsdp *)handle.va;
1009
1010	SIMPLEQ_INIT(&sc->sc_tables);
1011	SIMPLEQ_INIT(&sc->sc_wakedevs);
1012#if NACPIPWRRES > 0
1013	SIMPLEQ_INIT(&sc->sc_pwrresdevs);
1014#endif /* NACPIPWRRES > 0 */
1015
1016
1017#ifndef SMALL_KERNEL
1018	sc->sc_note = malloc(sizeof(struct klist), M_DEVBUF, M_NOWAIT | M_ZERO);
1019	if (sc->sc_note == NULL) {
1020		printf(": can't allocate memory\n");
1021		acpi_unmap(&handle);
1022		return;
1023	}
1024#endif /* SMALL_KERNEL */
1025
1026	if (acpi_loadtables(sc, rsdp)) {
1027		printf(": can't load tables\n");
1028		acpi_unmap(&handle);
1029		return;
1030	}
1031
1032	acpi_unmap(&handle);
1033
1034	/*
1035	 * Find the FADT
1036	 */
1037	SIMPLEQ_FOREACH(entry, &sc->sc_tables, q_next) {
1038		if (memcmp(entry->q_table, FADT_SIG,
1039		    sizeof(FADT_SIG) - 1) == 0) {
1040			sc->sc_fadt = entry->q_table;
1041			break;
1042		}
1043	}
1044	if (sc->sc_fadt == NULL) {
1045		printf(": no FADT\n");
1046		return;
1047	}
1048
1049	sc->sc_major = sc->sc_fadt->hdr.revision;
1050	if (sc->sc_major > 4)
1051		sc->sc_minor = sc->sc_fadt->fadt_minor;
1052	printf(": ACPI %d.%d", sc->sc_major, sc->sc_minor);
1053
1054	/*
1055	 * A bunch of things need to be done differently for
1056	 * Hardware-reduced ACPI.
1057	 */
1058	if (sc->sc_fadt->hdr_revision >= 5 &&
1059	    sc->sc_fadt->flags & FADT_HW_REDUCED_ACPI)
1060		sc->sc_hw_reduced = 1;
1061
1062	/* Map Power Management registers */
1063	acpi_map_pmregs(sc);
1064
1065	/*
1066	 * Check if we can and need to enable ACPI control.
1067	 */
1068	pm1 = acpi_read_pmreg(sc, ACPIREG_PM1_CNT, 0);
1069	if ((pm1 & ACPI_PM1_SCI_EN) == 0 && sc->sc_fadt->smi_cmd &&
1070	    (!sc->sc_fadt->acpi_enable && !sc->sc_fadt->acpi_disable)) {
1071		printf(", ACPI control unavailable\n");
1072		acpi_unmap_pmregs(sc);
1073		return;
1074	}
1075
1076	/*
1077	 * Set up a pointer to the firmware control structure
1078	 */
1079	if (sc->sc_fadt->hdr_revision < 3 || sc->sc_fadt->x_firmware_ctl == 0)
1080		facspa = sc->sc_fadt->firmware_ctl;
1081	else
1082		facspa = sc->sc_fadt->x_firmware_ctl;
1083
1084	if (acpi_map(facspa, sizeof(struct acpi_facs), &handle))
1085		printf(" !FACS");
1086	else
1087		sc->sc_facs = (struct acpi_facs *)handle.va;
1088
1089	/* Create opcode hashtable */
1090	aml_hashopcodes();
1091
1092	/* Create Default AML objects */
1093	aml_create_defaultobjects();
1094
1095	/*
1096	 * Load the DSDT from the FADT pointer -- use the
1097	 * extended (64-bit) pointer if it exists
1098	 */
1099	if (sc->sc_fadt->hdr_revision < 3 || sc->sc_fadt->x_dsdt == 0)
1100		entry = acpi_maptable(sc, sc->sc_fadt->dsdt, NULL, NULL, NULL,
1101		    -1);
1102	else
1103		entry = acpi_maptable(sc, sc->sc_fadt->x_dsdt, NULL, NULL, NULL,
1104		    -1);
1105
1106	if (entry == NULL)
1107		printf(" !DSDT");
1108
1109	p_dsdt = entry->q_table;
1110	acpi_parse_aml(sc, p_dsdt->aml, p_dsdt->hdr_length -
1111	    sizeof(p_dsdt->hdr));
1112
1113	/* Load SSDT's */
1114	SIMPLEQ_FOREACH(entry, &sc->sc_tables, q_next) {
1115		if (memcmp(entry->q_table, SSDT_SIG,
1116		    sizeof(SSDT_SIG) - 1) == 0) {
1117			p_dsdt = entry->q_table;
1118			acpi_parse_aml(sc, p_dsdt->aml, p_dsdt->hdr_length -
1119			    sizeof(p_dsdt->hdr));
1120		}
1121	}
1122
1123	/* Perform post-parsing fixups */
1124	aml_postparse();
1125
1126
1127#ifndef SMALL_KERNEL
1128	/* Find available sleeping states */
1129	acpi_init_states(sc);
1130
1131	/* Find available sleep/resume related methods. */
1132	acpi_init_pm(sc);
1133#endif /* SMALL_KERNEL */
1134
1135	/* Initialize GPE handlers */
1136	s = splbio();
1137	acpi_init_gpes(sc);
1138	splx(s);
1139
1140	/* some devices require periodic polling */
1141	timeout_set(&sc->sc_dev_timeout, acpi_poll, sc);
1142
1143	acpi_enabled = 1;
1144
1145	/*
1146	 * Take over ACPI control.  Note that once we do this, we
1147	 * effectively tell the system that we have ownership of
1148	 * the ACPI hardware registers, and that SMI should leave
1149	 * them alone
1150	 *
1151	 * This may prevent thermal control on some systems where
1152	 * that actually does work
1153	 */
1154	if ((pm1 & ACPI_PM1_SCI_EN) == 0 && sc->sc_fadt->smi_cmd) {
1155		if (acpi_enable(sc)) {
1156			printf(", can't enable ACPI\n");
1157			return;
1158		}
1159	}
1160
1161	printf("\n%s: tables", DEVNAME(sc));
1162	SIMPLEQ_FOREACH(entry, &sc->sc_tables, q_next) {
1163		printf(" %.4s", (char *)entry->q_table);
1164	}
1165	printf("\n");
1166
1167#ifndef SMALL_KERNEL
1168	/* Display wakeup devices and lowest S-state */
1169	wakeup_dev_ct = 0;
1170	printf("%s: wakeup devices", DEVNAME(sc));
1171	SIMPLEQ_FOREACH(wentry, &sc->sc_wakedevs, q_next) {
1172		if (wakeup_dev_ct < 16)
1173			printf(" %.4s(S%d)", wentry->q_node->name,
1174			    wentry->q_state);
1175		else if (wakeup_dev_ct == 16)
1176			printf(" [...]");
1177		wakeup_dev_ct ++;
1178	}
1179	printf("\n");
1180
1181	/*
1182	 * ACPI is enabled now -- attach timer
1183	 */
1184	if (!sc->sc_hw_reduced &&
1185	    (sc->sc_fadt->pm_tmr_blk || sc->sc_fadt->x_pm_tmr_blk.address)) {
1186		struct acpi_attach_args aaa;
1187
1188		memset(&aaa, 0, sizeof(aaa));
1189		aaa.aaa_name = "acpitimer";
1190		aaa.aaa_iot = sc->sc_iot;
1191		aaa.aaa_memt = sc->sc_memt;
1192		config_found(&sc->sc_dev, &aaa, acpi_print);
1193	}
1194#endif /* SMALL_KERNEL */
1195
1196	/*
1197	 * Attach table-defined devices
1198	 */
1199	SIMPLEQ_FOREACH(entry, &sc->sc_tables, q_next) {
1200		struct acpi_attach_args aaa;
1201
1202		memset(&aaa, 0, sizeof(aaa));
1203		aaa.aaa_iot = sc->sc_iot;
1204		aaa.aaa_memt = sc->sc_memt;
1205		aaa.aaa_table = entry->q_table;
1206		config_found_sm(&sc->sc_dev, &aaa, acpi_print, acpi_submatch);
1207	}
1208
1209	/* initialize runtime environment */
1210	aml_find_node(&aml_root, "_INI", acpi_inidev, sc);
1211
1212	/* Get PCI mapping */
1213	aml_walknodes(&aml_root, AML_WALK_PRE, acpi_getpci, sc);
1214
1215#if defined (__amd64__) || defined(__i386__)
1216	/* attach pci interrupt routing tables */
1217	aml_find_node(&aml_root, "_PRT", acpi_foundprt, sc);
1218#endif
1219
1220	aml_find_node(&aml_root, "_HID", acpi_foundec, sc);
1221
1222	/* check if we're running on a sony */
1223	aml_find_node(&aml_root, "GBRT", acpi_foundsony, sc);
1224
1225#ifndef SMALL_KERNEL
1226	/* try to find smart battery first */
1227	aml_find_node(&aml_root, "_HID", acpi_foundsbs, sc);
1228#endif /* SMALL_KERNEL */
1229
1230	/* attach battery, power supply and button devices */
1231	aml_find_node(&aml_root, "_HID", acpi_foundhid, sc);
1232
1233	aml_walknodes(&aml_root, AML_WALK_PRE, acpi_add_device, sc);
1234
1235#ifndef SMALL_KERNEL
1236#if NWD > 0
1237	/* Attach IDE bay */
1238	aml_walknodes(&aml_root, AML_WALK_PRE, acpi_foundide, sc);
1239#endif
1240
1241	/* attach docks */
1242	aml_find_node(&aml_root, "_DCK", acpi_founddock, sc);
1243
1244	/* attach video */
1245	aml_find_node(&aml_root, "_DOS", acpi_foundvideo, sc);
1246
1247	/* create list of devices we want to query when APM comes in */
1248	SLIST_INIT(&sc->sc_ac);
1249	SLIST_INIT(&sc->sc_bat);
1250	TAILQ_FOREACH(dev, &alldevs, dv_list) {
1251		if (!strcmp(dev->dv_cfdata->cf_driver->cd_name, "acpiac")) {
1252			struct acpi_ac *ac;
1253
1254			ac = malloc(sizeof(*ac), M_DEVBUF, M_WAITOK | M_ZERO);
1255			ac->aac_softc = (struct acpiac_softc *)dev;
1256			SLIST_INSERT_HEAD(&sc->sc_ac, ac, aac_link);
1257		} else if (!strcmp(dev->dv_cfdata->cf_driver->cd_name, "acpibat")) {
1258			struct acpi_bat *bat;
1259
1260			bat = malloc(sizeof(*bat), M_DEVBUF, M_WAITOK | M_ZERO);
1261			bat->aba_softc = (struct acpibat_softc *)dev;
1262			SLIST_INSERT_HEAD(&sc->sc_bat, bat, aba_link);
1263		} else if (!strcmp(dev->dv_cfdata->cf_driver->cd_name, "acpisbs")) {
1264			struct acpi_sbs *sbs;
1265
1266			sbs = malloc(sizeof(*sbs), M_DEVBUF, M_WAITOK | M_ZERO);
1267			sbs->asbs_softc = (struct acpisbs_softc *)dev;
1268			SLIST_INSERT_HEAD(&sc->sc_sbs, sbs, asbs_link);
1269		}
1270	}
1271
1272#endif /* SMALL_KERNEL */
1273
1274	/* Setup threads */
1275	sc->sc_thread = malloc(sizeof(struct acpi_thread), M_DEVBUF, M_WAITOK);
1276	sc->sc_thread->sc = sc;
1277	sc->sc_thread->running = 1;
1278
1279	/* Enable PCI Power Management. */
1280	pci_dopm = 1;
1281
1282	acpi_attach_machdep(sc);
1283
1284	kthread_create_deferred(acpi_create_thread, sc);
1285}
1286
1287int
1288acpi_submatch(struct device *parent, void *match, void *aux)
1289{
1290	struct acpi_attach_args *aaa = (struct acpi_attach_args *)aux;
1291	struct cfdata *cf = match;
1292
1293	if (aaa->aaa_table == NULL)
1294		return (0);
1295	return ((*cf->cf_attach->ca_match)(parent, match, aux));
1296}
1297
1298int
1299acpi_print(void *aux, const char *pnp)
1300{
1301	struct acpi_attach_args *aa = aux;
1302
1303	if (pnp) {
1304		if (aa->aaa_name)
1305			printf("%s at %s", aa->aaa_name, pnp);
1306		else if (aa->aaa_dev)
1307			printf("\"%s\" at %s", aa->aaa_dev, pnp);
1308		else
1309			return (QUIET);
1310	}
1311
1312	return (UNCONF);
1313}
1314
1315struct acpi_q *
1316acpi_maptable(struct acpi_softc *sc, paddr_t addr, const char *sig,
1317    const char *oem, const char *tbl, int flag)
1318{
1319	static int tblid;
1320	struct acpi_mem_map handle;
1321	struct acpi_table_header *hdr;
1322	struct acpi_q *entry;
1323	size_t len;
1324
1325	/* Check if we can map address */
1326	if (addr == 0)
1327		return NULL;
1328	if (acpi_map(addr, sizeof(*hdr), &handle))
1329		return NULL;
1330	hdr = (struct acpi_table_header *)handle.va;
1331	len = hdr->length;
1332	acpi_unmap(&handle);
1333
1334	/* Validate length/checksum */
1335	if (acpi_map(addr, len, &handle))
1336		return NULL;
1337	hdr = (struct acpi_table_header *)handle.va;
1338	if (acpi_checksum(hdr, len))
1339		printf("\n%s: %.4s checksum error",
1340		    DEVNAME(sc), hdr->signature);
1341
1342	if ((sig && memcmp(sig, hdr->signature, 4)) ||
1343	    (oem && memcmp(oem, hdr->oemid, 6)) ||
1344	    (tbl && memcmp(tbl, hdr->oemtableid, 8))) {
1345		acpi_unmap(&handle);
1346		return NULL;
1347	}
1348
1349	/* Allocate copy */
1350	entry = malloc(sizeof(*entry) + len, M_DEVBUF, M_NOWAIT);
1351	if (entry != NULL) {
1352		memcpy(entry->q_data, handle.va, len);
1353		entry->q_table = entry->q_data;
1354		entry->q_id = ++tblid;
1355
1356		if (flag < 0)
1357			SIMPLEQ_INSERT_HEAD(&sc->sc_tables, entry,
1358			    q_next);
1359		else if (flag > 0)
1360			SIMPLEQ_INSERT_TAIL(&sc->sc_tables, entry,
1361			    q_next);
1362	}
1363	acpi_unmap(&handle);
1364	return entry;
1365}
1366
1367int
1368acpi_loadtables(struct acpi_softc *sc, struct acpi_rsdp *rsdp)
1369{
1370	struct acpi_q *sdt;
1371	int i, ntables;
1372	size_t len;
1373
1374	if (rsdp->rsdp_revision == 2 && rsdp->rsdp_xsdt) {
1375		struct acpi_xsdt *xsdt;
1376
1377		sdt = acpi_maptable(sc, rsdp->rsdp_xsdt, NULL, NULL, NULL, 0);
1378		if (sdt == NULL) {
1379			printf("couldn't map xsdt\n");
1380			return (ENOMEM);
1381		}
1382
1383		xsdt = (struct acpi_xsdt *)sdt->q_data;
1384		len  = xsdt->hdr.length;
1385		ntables = (len - sizeof(struct acpi_table_header)) /
1386		    sizeof(xsdt->table_offsets[0]);
1387
1388		for (i = 0; i < ntables; i++)
1389			acpi_maptable(sc, xsdt->table_offsets[i], NULL, NULL,
1390			    NULL, 1);
1391
1392		free(sdt, M_DEVBUF, sizeof(*sdt) + len);
1393	} else {
1394		struct acpi_rsdt *rsdt;
1395
1396		sdt = acpi_maptable(sc, rsdp->rsdp_rsdt, NULL, NULL, NULL, 0);
1397		if (sdt == NULL) {
1398			printf("couldn't map rsdt\n");
1399			return (ENOMEM);
1400		}
1401
1402		rsdt = (struct acpi_rsdt *)sdt->q_data;
1403		len  = rsdt->hdr.length;
1404		ntables = (len - sizeof(struct acpi_table_header)) /
1405		    sizeof(rsdt->table_offsets[0]);
1406
1407		for (i = 0; i < ntables; i++)
1408			acpi_maptable(sc, rsdt->table_offsets[i], NULL, NULL,
1409			    NULL, 1);
1410
1411		free(sdt, M_DEVBUF, sizeof(*sdt) + len);
1412	}
1413
1414	return (0);
1415}
1416
1417/* Read from power management register */
1418int
1419acpi_read_pmreg(struct acpi_softc *sc, int reg, int offset)
1420{
1421	bus_space_handle_t ioh;
1422	bus_size_t size;
1423	int regval;
1424
1425	/*
1426	 * For Hardware-reduced ACPI we emulate PM1B_CNT to reflect
1427	 * that the system is always in ACPI mode.
1428	 */
1429	if (sc->sc_hw_reduced && reg == ACPIREG_PM1B_CNT) {
1430		KASSERT(offset == 0);
1431		return ACPI_PM1_SCI_EN;
1432	}
1433
1434	/*
1435	 * For Hardware-reduced ACPI we also emulate PM1A_STS using
1436	 * SLEEP_STATUS_REG.
1437	 */
1438	if (sc->sc_hw_reduced && reg == ACPIREG_PM1A_STS) {
1439		uint8_t value;
1440
1441		KASSERT(offset == 0);
1442		acpi_gasio(sc, ACPI_IOREAD,
1443		    sc->sc_fadt->sleep_status_reg.address_space_id,
1444		    sc->sc_fadt->sleep_status_reg.address,
1445		    sc->sc_fadt->sleep_status_reg.register_bit_width / 8,
1446		    sc->sc_fadt->sleep_status_reg.access_size, &value);
1447		return ((int)value << 8);
1448	}
1449
1450	/* Special cases: 1A/1B blocks can be OR'ed together */
1451	switch (reg) {
1452	case ACPIREG_PM1_EN:
1453		return (acpi_read_pmreg(sc, ACPIREG_PM1A_EN, offset) |
1454		    acpi_read_pmreg(sc, ACPIREG_PM1B_EN, offset));
1455	case ACPIREG_PM1_STS:
1456		return (acpi_read_pmreg(sc, ACPIREG_PM1A_STS, offset) |
1457		    acpi_read_pmreg(sc, ACPIREG_PM1B_STS, offset));
1458	case ACPIREG_PM1_CNT:
1459		return (acpi_read_pmreg(sc, ACPIREG_PM1A_CNT, offset) |
1460		    acpi_read_pmreg(sc, ACPIREG_PM1B_CNT, offset));
1461	case ACPIREG_GPE_STS:
1462		dnprintf(50, "read GPE_STS  offset: %.2x %.2x %.2x\n", offset,
1463		    sc->sc_fadt->gpe0_blk_len>>1, sc->sc_fadt->gpe1_blk_len>>1);
1464		if (offset < (sc->sc_fadt->gpe0_blk_len >> 1)) {
1465			reg = ACPIREG_GPE0_STS;
1466		}
1467		break;
1468	case ACPIREG_GPE_EN:
1469		dnprintf(50, "read GPE_EN   offset: %.2x %.2x %.2x\n",
1470		    offset, sc->sc_fadt->gpe0_blk_len>>1,
1471		    sc->sc_fadt->gpe1_blk_len>>1);
1472		if (offset < (sc->sc_fadt->gpe0_blk_len >> 1)) {
1473			reg = ACPIREG_GPE0_EN;
1474		}
1475		break;
1476	}
1477
1478	if (reg >= ACPIREG_MAXREG || sc->sc_pmregs[reg].size == 0)
1479		return (0);
1480
1481	regval = 0;
1482	ioh = sc->sc_pmregs[reg].ioh;
1483	size = sc->sc_pmregs[reg].size;
1484	if (size > sc->sc_pmregs[reg].access)
1485		size = sc->sc_pmregs[reg].access;
1486
1487	switch (size) {
1488	case 1:
1489		regval = bus_space_read_1(sc->sc_iot, ioh, offset);
1490		break;
1491	case 2:
1492		regval = bus_space_read_2(sc->sc_iot, ioh, offset);
1493		break;
1494	case 4:
1495		regval = bus_space_read_4(sc->sc_iot, ioh, offset);
1496		break;
1497	}
1498
1499	dnprintf(30, "acpi_readpm: %s = %.4x:%.4x %x\n",
1500	    sc->sc_pmregs[reg].name,
1501	    sc->sc_pmregs[reg].addr, offset, regval);
1502	return (regval);
1503}
1504
1505/* Write to power management register */
1506void
1507acpi_write_pmreg(struct acpi_softc *sc, int reg, int offset, int regval)
1508{
1509	bus_space_handle_t ioh;
1510	bus_size_t size;
1511
1512	/*
1513	 * For Hardware-reduced ACPI we also emulate PM1A_STS using
1514	 * SLEEP_STATUS_REG.
1515	 */
1516	if (sc->sc_hw_reduced && reg == ACPIREG_PM1A_STS) {
1517		uint8_t value = (regval >> 8);
1518
1519		KASSERT(offset == 0);
1520		acpi_gasio(sc, ACPI_IOWRITE,
1521		    sc->sc_fadt->sleep_status_reg.address_space_id,
1522		    sc->sc_fadt->sleep_status_reg.address,
1523		    sc->sc_fadt->sleep_status_reg.register_bit_width / 8,
1524		    sc->sc_fadt->sleep_status_reg.access_size, &value);
1525		return;
1526	}
1527
1528	/*
1529	 * For Hardware-reduced ACPI we also emulate PM1A_CNT using
1530	 * SLEEP_CONTROL_REG.
1531	 */
1532	if (sc->sc_hw_reduced && reg == ACPIREG_PM1A_CNT) {
1533		uint8_t value = (regval >> 8);
1534
1535		KASSERT(offset == 0);
1536		acpi_gasio(sc, ACPI_IOWRITE,
1537		    sc->sc_fadt->sleep_control_reg.address_space_id,
1538		    sc->sc_fadt->sleep_control_reg.address,
1539		    sc->sc_fadt->sleep_control_reg.register_bit_width / 8,
1540		    sc->sc_fadt->sleep_control_reg.access_size, &value);
1541		return;
1542	}
1543
1544	/* Special cases: 1A/1B blocks can be written with same value */
1545	switch (reg) {
1546	case ACPIREG_PM1_EN:
1547		acpi_write_pmreg(sc, ACPIREG_PM1A_EN, offset, regval);
1548		acpi_write_pmreg(sc, ACPIREG_PM1B_EN, offset, regval);
1549		break;
1550	case ACPIREG_PM1_STS:
1551		acpi_write_pmreg(sc, ACPIREG_PM1A_STS, offset, regval);
1552		acpi_write_pmreg(sc, ACPIREG_PM1B_STS, offset, regval);
1553		break;
1554	case ACPIREG_PM1_CNT:
1555		acpi_write_pmreg(sc, ACPIREG_PM1A_CNT, offset, regval);
1556		acpi_write_pmreg(sc, ACPIREG_PM1B_CNT, offset, regval);
1557		break;
1558	case ACPIREG_GPE_STS:
1559		dnprintf(50, "write GPE_STS offset: %.2x %.2x %.2x %.2x\n",
1560		    offset, sc->sc_fadt->gpe0_blk_len>>1,
1561		    sc->sc_fadt->gpe1_blk_len>>1, regval);
1562		if (offset < (sc->sc_fadt->gpe0_blk_len >> 1)) {
1563			reg = ACPIREG_GPE0_STS;
1564		}
1565		break;
1566	case ACPIREG_GPE_EN:
1567		dnprintf(50, "write GPE_EN  offset: %.2x %.2x %.2x %.2x\n",
1568		    offset, sc->sc_fadt->gpe0_blk_len>>1,
1569		    sc->sc_fadt->gpe1_blk_len>>1, regval);
1570		if (offset < (sc->sc_fadt->gpe0_blk_len >> 1)) {
1571			reg = ACPIREG_GPE0_EN;
1572		}
1573		break;
1574	}
1575
1576	/* All special case return here */
1577	if (reg >= ACPIREG_MAXREG)
1578		return;
1579
1580	ioh = sc->sc_pmregs[reg].ioh;
1581	size = sc->sc_pmregs[reg].size;
1582	if (size > sc->sc_pmregs[reg].access)
1583		size = sc->sc_pmregs[reg].access;
1584
1585	switch (size) {
1586	case 1:
1587		bus_space_write_1(sc->sc_iot, ioh, offset, regval);
1588		break;
1589	case 2:
1590		bus_space_write_2(sc->sc_iot, ioh, offset, regval);
1591		break;
1592	case 4:
1593		bus_space_write_4(sc->sc_iot, ioh, offset, regval);
1594		break;
1595	}
1596
1597	dnprintf(30, "acpi_writepm: %s = %.4x:%.4x %x\n",
1598	    sc->sc_pmregs[reg].name, sc->sc_pmregs[reg].addr, offset, regval);
1599}
1600
1601/* Map Power Management registers */
1602void
1603acpi_map_pmregs(struct acpi_softc *sc)
1604{
1605	struct acpi_fadt *fadt = sc->sc_fadt;
1606	bus_addr_t addr;
1607	bus_size_t size, access;
1608	const char *name;
1609	int reg;
1610
1611	/* Registers don't exist on Hardware-reduced ACPI. */
1612	if (sc->sc_hw_reduced)
1613		return;
1614
1615	for (reg = 0; reg < ACPIREG_MAXREG; reg++) {
1616		size = 0;
1617		access = 0;
1618		switch (reg) {
1619		case ACPIREG_SMICMD:
1620			name = "smi";
1621			size = access = 1;
1622			addr = fadt->smi_cmd;
1623			break;
1624		case ACPIREG_PM1A_STS:
1625		case ACPIREG_PM1A_EN:
1626			name = "pm1a_sts";
1627			size = fadt->pm1_evt_len >> 1;
1628			if (fadt->pm1a_evt_blk) {
1629				addr = fadt->pm1a_evt_blk;
1630				access = 2;
1631			} else if (fadt->hdr_revision >= 3) {
1632				addr = fadt->x_pm1a_evt_blk.address;
1633				access = 1 << fadt->x_pm1a_evt_blk.access_size;
1634			}
1635			if (reg == ACPIREG_PM1A_EN && addr) {
1636				addr += size;
1637				name = "pm1a_en";
1638			}
1639			break;
1640		case ACPIREG_PM1A_CNT:
1641			name = "pm1a_cnt";
1642			size = fadt->pm1_cnt_len;
1643			if (fadt->pm1a_cnt_blk) {
1644				addr = fadt->pm1a_cnt_blk;
1645				access = 2;
1646			} else if (fadt->hdr_revision >= 3) {
1647				addr = fadt->x_pm1a_cnt_blk.address;
1648				access = 1 << fadt->x_pm1a_cnt_blk.access_size;
1649			}
1650			break;
1651		case ACPIREG_PM1B_STS:
1652		case ACPIREG_PM1B_EN:
1653			name = "pm1b_sts";
1654			size = fadt->pm1_evt_len >> 1;
1655			if (fadt->pm1b_evt_blk) {
1656				addr = fadt->pm1b_evt_blk;
1657				access = 2;
1658			} else if (fadt->hdr_revision >= 3) {
1659				addr = fadt->x_pm1b_evt_blk.address;
1660				access = 1 << fadt->x_pm1b_evt_blk.access_size;
1661			}
1662			if (reg == ACPIREG_PM1B_EN && addr) {
1663				addr += size;
1664				name = "pm1b_en";
1665			}
1666			break;
1667		case ACPIREG_PM1B_CNT:
1668			name = "pm1b_cnt";
1669			size = fadt->pm1_cnt_len;
1670			if (fadt->pm1b_cnt_blk) {
1671				addr = fadt->pm1b_cnt_blk;
1672				access = 2;
1673			} else if (fadt->hdr_revision >= 3) {
1674				addr = fadt->x_pm1b_cnt_blk.address;
1675				access = 1 << fadt->x_pm1b_cnt_blk.access_size;
1676			}
1677			break;
1678		case ACPIREG_PM2_CNT:
1679			name = "pm2_cnt";
1680			size = fadt->pm2_cnt_len;
1681			if (fadt->pm2_cnt_blk) {
1682				addr = fadt->pm2_cnt_blk;
1683				access = size;
1684			} else if (fadt->hdr_revision >= 3) {
1685				addr = fadt->x_pm2_cnt_blk.address;
1686				access = 1 << fadt->x_pm2_cnt_blk.access_size;
1687			}
1688			break;
1689#if 0
1690		case ACPIREG_PM_TMR:
1691			/* Allocated in acpitimer */
1692			name = "pm_tmr";
1693			size = fadt->pm_tmr_len;
1694			if (fadt->pm_tmr_blk) {
1695				addr = fadt->pm_tmr_blk;
1696				access = 4;
1697			} else if (fadt->hdr_revision >= 3) {
1698				addr = fadt->x_pm_tmr_blk.address;
1699				access = 1 << fadt->x_pm_tmr_blk.access_size;
1700			}
1701			break;
1702#endif
1703		case ACPIREG_GPE0_STS:
1704		case ACPIREG_GPE0_EN:
1705			name = "gpe0_sts";
1706			size = fadt->gpe0_blk_len >> 1;
1707			if (fadt->gpe0_blk) {
1708				addr = fadt->gpe0_blk;
1709				access = 1;
1710			} else if (fadt->hdr_revision >= 3) {
1711				addr = fadt->x_gpe0_blk.address;
1712				access = 1 << fadt->x_gpe0_blk.access_size;
1713			}
1714
1715			dnprintf(20, "gpe0 block len : %x\n",
1716			    fadt->gpe0_blk_len >> 1);
1717			dnprintf(20, "gpe0 block addr: %x\n",
1718			    fadt->gpe0_blk);
1719			if (reg == ACPIREG_GPE0_EN && addr) {
1720				addr += size;
1721				name = "gpe0_en";
1722			}
1723			break;
1724		case ACPIREG_GPE1_STS:
1725		case ACPIREG_GPE1_EN:
1726			name = "gpe1_sts";
1727			size = fadt->gpe1_blk_len >> 1;
1728			if (fadt->gpe1_blk) {
1729				addr = fadt->gpe1_blk;
1730				access = 1;
1731			} else if (fadt->hdr_revision >= 3) {
1732				addr = fadt->x_gpe1_blk.address;
1733				access = 1 << fadt->x_gpe1_blk.access_size;
1734			}
1735
1736			dnprintf(20, "gpe1 block len : %x\n",
1737			    fadt->gpe1_blk_len >> 1);
1738			dnprintf(20, "gpe1 block addr: %x\n",
1739			    fadt->gpe1_blk);
1740			if (reg == ACPIREG_GPE1_EN && addr) {
1741				addr += size;
1742				name = "gpe1_en";
1743			}
1744			break;
1745		}
1746		if (size && addr) {
1747			dnprintf(50, "mapping: %.4lx %.4lx %s\n",
1748			    addr, size, name);
1749
1750			/* Size and address exist; map register space */
1751			bus_space_map(sc->sc_iot, addr, size, 0,
1752			    &sc->sc_pmregs[reg].ioh);
1753
1754			sc->sc_pmregs[reg].name = name;
1755			sc->sc_pmregs[reg].size = size;
1756			sc->sc_pmregs[reg].addr = addr;
1757			sc->sc_pmregs[reg].access = min(access, 4);
1758		}
1759	}
1760}
1761
1762void
1763acpi_unmap_pmregs(struct acpi_softc *sc)
1764{
1765	int reg;
1766
1767	for (reg = 0; reg < ACPIREG_MAXREG; reg++) {
1768		if (sc->sc_pmregs[reg].size && sc->sc_pmregs[reg].addr)
1769			bus_space_unmap(sc->sc_iot, sc->sc_pmregs[reg].ioh,
1770			    sc->sc_pmregs[reg].size);
1771	}
1772}
1773
1774int
1775acpi_enable(struct acpi_softc *sc)
1776{
1777	int idx;
1778
1779	acpi_write_pmreg(sc, ACPIREG_SMICMD, 0, sc->sc_fadt->acpi_enable);
1780	idx = 0;
1781	do {
1782		if (idx++ > ACPIEN_RETRIES) {
1783			return ETIMEDOUT;
1784		}
1785	} while (!(acpi_read_pmreg(sc, ACPIREG_PM1_CNT, 0) & ACPI_PM1_SCI_EN));
1786
1787	return 0;
1788}
1789
1790/* ACPI Workqueue support */
1791SIMPLEQ_HEAD(,acpi_taskq) acpi_taskq =
1792    SIMPLEQ_HEAD_INITIALIZER(acpi_taskq);
1793
1794void
1795acpi_addtask(struct acpi_softc *sc, void (*handler)(void *, int),
1796    void *arg0, int arg1)
1797{
1798	struct acpi_taskq *wq;
1799	int s;
1800
1801	wq = malloc(sizeof(*wq), M_DEVBUF, M_ZERO | M_NOWAIT);
1802	if (wq == NULL)
1803		return;
1804	wq->handler = handler;
1805	wq->arg0 = arg0;
1806	wq->arg1 = arg1;
1807
1808	s = splbio();
1809	SIMPLEQ_INSERT_TAIL(&acpi_taskq, wq, next);
1810	splx(s);
1811}
1812
1813int
1814acpi_dotask(struct acpi_softc *sc)
1815{
1816	struct acpi_taskq *wq;
1817	int s;
1818
1819	s = splbio();
1820	if (SIMPLEQ_EMPTY(&acpi_taskq)) {
1821		splx(s);
1822
1823		/* we don't have anything to do */
1824		return (0);
1825	}
1826	wq = SIMPLEQ_FIRST(&acpi_taskq);
1827	SIMPLEQ_REMOVE_HEAD(&acpi_taskq, next);
1828	splx(s);
1829
1830	wq->handler(wq->arg0, wq->arg1);
1831
1832	free(wq, M_DEVBUF, sizeof(*wq));
1833
1834	/* We did something */
1835	return (1);
1836}
1837
1838#ifndef SMALL_KERNEL
1839
1840int
1841is_ata(struct aml_node *node)
1842{
1843	return (aml_searchname(node, "_GTM") != NULL ||
1844	    aml_searchname(node, "_GTF") != NULL ||
1845	    aml_searchname(node, "_STM") != NULL ||
1846	    aml_searchname(node, "_SDD") != NULL);
1847}
1848
1849int
1850is_ejectable(struct aml_node *node)
1851{
1852	return (aml_searchname(node, "_EJ0") != NULL);
1853}
1854
1855int
1856is_ejectable_bay(struct aml_node *node)
1857{
1858	return ((is_ata(node) || is_ata(node->parent)) && is_ejectable(node));
1859}
1860
1861#if NWD > 0
1862int
1863acpiide_notify(struct aml_node *node, int ntype, void *arg)
1864{
1865	struct idechnl 		*ide = arg;
1866	struct acpi_softc 	*sc = ide->sc;
1867	struct pciide_softc 	*wsc;
1868	struct device 		*dev;
1869	int 			b,d,f;
1870	int64_t 		sta;
1871
1872	if (aml_evalinteger(sc, node, "_STA", 0, NULL, &sta) != 0)
1873		return (0);
1874
1875	dnprintf(10, "IDE notify! %s %d status:%llx\n", aml_nodename(node),
1876	    ntype, sta);
1877
1878	/* Walk device list looking for IDE device match */
1879	TAILQ_FOREACH(dev, &alldevs, dv_list) {
1880		if (strcmp(dev->dv_cfdata->cf_driver->cd_name, "pciide"))
1881			continue;
1882
1883		wsc = (struct pciide_softc *)dev;
1884		pci_decompose_tag(NULL, wsc->sc_tag, &b, &d, &f);
1885		if (b != ACPI_PCI_BUS(ide->addr) ||
1886		    d != ACPI_PCI_DEV(ide->addr) ||
1887		    f != ACPI_PCI_FN(ide->addr))
1888			continue;
1889		dnprintf(10, "Found pciide: %s %x.%x.%x channel:%llx\n",
1890		    dev->dv_xname, b,d,f, ide->chnl);
1891
1892		if (sta == 0 && ide->sta)
1893			wdcdetach(
1894			    &wsc->pciide_channels[ide->chnl].wdc_channel, 0);
1895		else if (sta && !ide->sta)
1896			wdcattach(
1897			    &wsc->pciide_channels[ide->chnl].wdc_channel);
1898		ide->sta = sta;
1899	}
1900	return (0);
1901}
1902
1903int
1904acpi_foundide(struct aml_node *node, void *arg)
1905{
1906	struct acpi_softc 	*sc = arg;
1907	struct aml_node 	*pp;
1908	struct idechnl 		*ide;
1909	union amlpci_t 		pi;
1910	int 			lvl;
1911
1912	/* Check if this is an ejectable bay */
1913	if (!is_ejectable_bay(node))
1914		return (0);
1915
1916	ide = malloc(sizeof(struct idechnl), M_DEVBUF, M_NOWAIT | M_ZERO);
1917	ide->sc = sc;
1918
1919	/* GTM/GTF can be at 2/3 levels:  pciX.ideX.channelX[.driveX] */
1920	lvl = 0;
1921	for (pp=node->parent; pp; pp=pp->parent) {
1922		lvl++;
1923		if (aml_searchname(pp, "_HID"))
1924			break;
1925	}
1926
1927	/* Get PCI address and channel */
1928	if (lvl == 3) {
1929		aml_evalinteger(sc, node->parent, "_ADR", 0, NULL,
1930		    &ide->chnl);
1931		aml_rdpciaddr(node->parent->parent, &pi);
1932		ide->addr = pi.addr;
1933	} else if (lvl == 4) {
1934		aml_evalinteger(sc, node->parent->parent, "_ADR", 0, NULL,
1935		    &ide->chnl);
1936		aml_rdpciaddr(node->parent->parent->parent, &pi);
1937		ide->addr = pi.addr;
1938	}
1939	dnprintf(10, "%s %llx channel:%llx\n",
1940	    aml_nodename(node), ide->addr, ide->chnl);
1941
1942	aml_evalinteger(sc, node, "_STA", 0, NULL, &ide->sta);
1943	dnprintf(10, "Got Initial STA: %llx\n", ide->sta);
1944
1945	aml_register_notify(node, "acpiide", acpiide_notify, ide, 0);
1946	return (0);
1947}
1948#endif /* NWD > 0 */
1949
1950void
1951acpi_sleep_task(void *arg0, int sleepmode)
1952{
1953	struct acpi_softc *sc = arg0;
1954
1955	/* System goes to sleep here.. */
1956	acpi_sleep_state(sc, sleepmode);
1957	/* Tell userland to recheck A/C and battery status */
1958	acpi_record_event(sc, APM_POWER_CHANGE);
1959}
1960
1961#endif /* SMALL_KERNEL */
1962
1963void
1964acpi_reset(void)
1965{
1966	uint32_t		 reset_as, reset_len;
1967	uint32_t		 value;
1968	struct acpi_softc	*sc = acpi_softc;
1969	struct acpi_fadt	*fadt = sc->sc_fadt;
1970
1971	if (acpi_enabled == 0)
1972		return;
1973
1974	/*
1975	 * RESET_REG_SUP is not properly set in some implementations,
1976	 * but not testing against it breaks more machines than it fixes
1977	 */
1978	if (fadt->hdr_revision <= 1 ||
1979	    !(fadt->flags & FADT_RESET_REG_SUP) || fadt->reset_reg.address == 0)
1980		return;
1981
1982	value = fadt->reset_value;
1983
1984	reset_as = fadt->reset_reg.register_bit_width / 8;
1985	if (reset_as == 0)
1986		reset_as = 1;
1987
1988	reset_len = fadt->reset_reg.access_size;
1989	if (reset_len == 0)
1990		reset_len = reset_as;
1991
1992	acpi_gasio(sc, ACPI_IOWRITE,
1993	    fadt->reset_reg.address_space_id,
1994	    fadt->reset_reg.address, reset_as, reset_len, &value);
1995
1996	delay(100000);
1997}
1998
1999void
2000acpi_gpe_task(void *arg0, int gpe)
2001{
2002	struct acpi_softc *sc = acpi_softc;
2003	struct gpe_block *pgpe = &sc->gpe_table[gpe];
2004
2005	dnprintf(10, "handle gpe: %x\n", gpe);
2006	if (pgpe->handler && pgpe->active) {
2007		pgpe->active = 0;
2008		pgpe->handler(sc, gpe, pgpe->arg);
2009	}
2010}
2011
2012void
2013acpi_pbtn_task(void *arg0, int dummy)
2014{
2015	struct acpi_softc *sc = arg0;
2016	extern int pwr_action;
2017	uint16_t en;
2018	int s;
2019
2020	dnprintf(1,"power button pressed\n");
2021
2022	/* Reset the latch and re-enable the GPE */
2023	s = splbio();
2024	en = acpi_read_pmreg(sc, ACPIREG_PM1_EN, 0);
2025	acpi_write_pmreg(sc, ACPIREG_PM1_EN,  0,
2026	    en | ACPI_PM1_PWRBTN_EN);
2027	splx(s);
2028
2029	switch (pwr_action) {
2030	case 0:
2031		break;
2032	case 1:
2033		acpi_addtask(sc, acpi_powerdown_task, sc, 0);
2034		break;
2035#ifndef SMALL_KERNEL
2036	case 2:
2037		acpi_addtask(sc, acpi_sleep_task, sc, ACPI_SLEEP_SUSPEND);
2038		break;
2039#endif
2040	}
2041}
2042
2043void
2044acpi_sbtn_task(void *arg0, int dummy)
2045{
2046	struct acpi_softc *sc = arg0;
2047	uint16_t en;
2048	int s;
2049
2050	dnprintf(1,"sleep button pressed\n");
2051	aml_notify_dev(ACPI_DEV_SBD, 0x80);
2052
2053	/* Reset the latch and re-enable the GPE */
2054	s = splbio();
2055	en = acpi_read_pmreg(sc, ACPIREG_PM1_EN, 0);
2056	acpi_write_pmreg(sc, ACPIREG_PM1_EN,  0,
2057	    en | ACPI_PM1_SLPBTN_EN);
2058	splx(s);
2059}
2060
2061void
2062acpi_powerdown_task(void *arg0, int dummy)
2063{
2064	extern int allowpowerdown;
2065
2066	if (allowpowerdown == 1) {
2067		allowpowerdown = 0;
2068		prsignal(initprocess, SIGUSR2);
2069	}
2070}
2071
2072int
2073acpi_interrupt(void *arg)
2074{
2075	struct acpi_softc *sc = (struct acpi_softc *)arg;
2076	uint32_t processed = 0, idx, jdx;
2077	uint16_t sts, en;
2078	int gpe;
2079
2080	dnprintf(40, "ACPI Interrupt\n");
2081	for (idx = 0; idx < sc->sc_lastgpe; idx += 8) {
2082		sts = acpi_read_pmreg(sc, ACPIREG_GPE_STS, idx>>3);
2083		en  = acpi_read_pmreg(sc, ACPIREG_GPE_EN,  idx>>3);
2084		if (en & sts) {
2085			dnprintf(10, "GPE block: %.2x %.2x %.2x\n", idx, sts,
2086			    en);
2087			/* Mask the GPE until it is serviced */
2088			acpi_write_pmreg(sc, ACPIREG_GPE_EN, idx>>3, en & ~sts);
2089			for (jdx = 0; jdx < 8; jdx++) {
2090				if (!(en & sts & (1L << jdx)))
2091					continue;
2092
2093				/* Signal this GPE */
2094				gpe = idx + jdx;
2095				if (sc->gpe_table[gpe].flags & GPE_DIRECT) {
2096					dnprintf(10, "directly handle gpe: %x\n",
2097					    gpe);
2098					sc->gpe_table[gpe].handler(sc, gpe,
2099					    sc->gpe_table[gpe].arg);
2100					if (sc->gpe_table[gpe].flags &
2101					    GPE_LEVEL)
2102						acpi_gpe(sc, gpe,
2103						    sc->gpe_table[gpe].arg);
2104				} else {
2105					sc->gpe_table[gpe].active = 1;
2106					dnprintf(10, "queue gpe: %x\n", gpe);
2107					acpi_addtask(sc, acpi_gpe_task, NULL,
2108					    gpe);
2109				}
2110
2111				/*
2112				 * Edge interrupts need their STS bits cleared
2113				 * now.  Level interrupts will have their STS
2114				 * bits cleared just before they are
2115				 * re-enabled.
2116				 */
2117				if (sc->gpe_table[gpe].flags & GPE_EDGE)
2118					acpi_write_pmreg(sc,
2119					    ACPIREG_GPE_STS, idx>>3, 1L << jdx);
2120
2121				processed = 1;
2122			}
2123		}
2124	}
2125
2126	sts = acpi_read_pmreg(sc, ACPIREG_PM1_STS, 0);
2127	en  = acpi_read_pmreg(sc, ACPIREG_PM1_EN, 0);
2128	if (sts & en) {
2129		dnprintf(10,"GEN interrupt: %.4x\n", sts & en);
2130		sts &= en;
2131		if (sts & ACPI_PM1_PWRBTN_STS) {
2132			/* Mask and acknowledge */
2133			en &= ~ACPI_PM1_PWRBTN_EN;
2134			acpi_write_pmreg(sc, ACPIREG_PM1_EN, 0, en);
2135			acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0,
2136			    ACPI_PM1_PWRBTN_STS);
2137			sts &= ~ACPI_PM1_PWRBTN_STS;
2138
2139			acpi_addtask(sc, acpi_pbtn_task, sc, 0);
2140		}
2141		if (sts & ACPI_PM1_SLPBTN_STS) {
2142			/* Mask and acknowledge */
2143			en &= ~ACPI_PM1_SLPBTN_EN;
2144			acpi_write_pmreg(sc, ACPIREG_PM1_EN, 0, en);
2145			acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0,
2146			    ACPI_PM1_SLPBTN_STS);
2147			sts &= ~ACPI_PM1_SLPBTN_STS;
2148
2149			acpi_addtask(sc, acpi_sbtn_task, sc, 0);
2150		}
2151		if (sts) {
2152			printf("%s: PM1 stuck (en 0x%x st 0x%x), clearing\n",
2153			    sc->sc_dev.dv_xname, en, sts);
2154			acpi_write_pmreg(sc, ACPIREG_PM1_EN, 0, en & ~sts);
2155			acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0, sts);
2156		}
2157		processed = 1;
2158	}
2159
2160	if (processed) {
2161		acpi_wakeup(sc);
2162	}
2163
2164	return (processed);
2165}
2166
2167int
2168acpi_add_device(struct aml_node *node, void *arg)
2169{
2170	static int nacpicpus = 0;
2171	struct device *self = arg;
2172	struct acpi_softc *sc = arg;
2173	struct acpi_attach_args aaa;
2174	struct aml_value res;
2175	CPU_INFO_ITERATOR cii;
2176	struct cpu_info *ci;
2177	int proc_id = -1;
2178
2179	memset(&aaa, 0, sizeof(aaa));
2180	aaa.aaa_node = node;
2181	aaa.aaa_iot = sc->sc_iot;
2182	aaa.aaa_memt = sc->sc_memt;
2183	if (node == NULL || node->value == NULL)
2184		return 0;
2185
2186	switch (node->value->type) {
2187	case AML_OBJTYPE_PROCESSOR:
2188		if (sc->sc_skip_processor != 0)
2189			return 0;
2190		if (nacpicpus >= ncpus)
2191			return 0;
2192		if (aml_evalnode(sc, aaa.aaa_node, 0, NULL, &res) == 0) {
2193			if (res.type == AML_OBJTYPE_PROCESSOR)
2194				proc_id = res.v_processor.proc_id;
2195			aml_freevalue(&res);
2196		}
2197		CPU_INFO_FOREACH(cii, ci) {
2198			if (ci->ci_acpi_proc_id == proc_id)
2199				break;
2200		}
2201		if (ci == NULL)
2202			return 0;
2203		nacpicpus++;
2204
2205		aaa.aaa_name = "acpicpu";
2206		break;
2207	case AML_OBJTYPE_THERMZONE:
2208		aaa.aaa_name = "acpitz";
2209		break;
2210	case AML_OBJTYPE_POWERRSRC:
2211		aaa.aaa_name = "acpipwrres";
2212		break;
2213	default:
2214		return 0;
2215	}
2216	config_found(self, &aaa, acpi_print);
2217	return 0;
2218}
2219
2220void
2221acpi_enable_onegpe(struct acpi_softc *sc, int gpe)
2222{
2223	uint8_t mask, en;
2224
2225	/* Read enabled register */
2226	mask = (1L << (gpe & 7));
2227	en = acpi_read_pmreg(sc, ACPIREG_GPE_EN, gpe>>3);
2228	dnprintf(50, "enabling GPE %.2x (current: %sabled) %.2x\n",
2229	    gpe, (en & mask) ? "en" : "dis", en);
2230	acpi_write_pmreg(sc, ACPIREG_GPE_EN, gpe>>3, en | mask);
2231}
2232
2233/* Clear all GPEs */
2234void
2235acpi_disable_allgpes(struct acpi_softc *sc)
2236{
2237	int idx;
2238
2239	for (idx = 0; idx < sc->sc_lastgpe; idx += 8) {
2240		acpi_write_pmreg(sc, ACPIREG_GPE_EN, idx >> 3, 0);
2241		acpi_write_pmreg(sc, ACPIREG_GPE_STS, idx >> 3, -1);
2242	}
2243}
2244
2245/* Enable runtime GPEs */
2246void
2247acpi_enable_rungpes(struct acpi_softc *sc)
2248{
2249	int idx;
2250
2251	for (idx = 0; idx < sc->sc_lastgpe; idx++)
2252		if (sc->gpe_table[idx].handler)
2253			acpi_enable_onegpe(sc, idx);
2254}
2255
2256/* Enable wakeup GPEs */
2257void
2258acpi_enable_wakegpes(struct acpi_softc *sc, int state)
2259{
2260	struct acpi_wakeq *wentry;
2261
2262	SIMPLEQ_FOREACH(wentry, &sc->sc_wakedevs, q_next) {
2263		dnprintf(10, "%.4s(S%d) gpe %.2x\n", wentry->q_node->name,
2264		    wentry->q_state,
2265		    wentry->q_gpe);
2266		if (state <= wentry->q_state)
2267			acpi_enable_onegpe(sc, wentry->q_gpe);
2268	}
2269}
2270
2271int
2272acpi_set_gpehandler(struct acpi_softc *sc, int gpe, int (*handler)
2273    (struct acpi_softc *, int, void *), void *arg, int flags)
2274{
2275	struct gpe_block *ptbl;
2276
2277	ptbl = acpi_find_gpe(sc, gpe);
2278	if (ptbl == NULL || handler == NULL)
2279		return -EINVAL;
2280	if ((flags & GPE_LEVEL) && (flags & GPE_EDGE))
2281		return -EINVAL;
2282	if (!(flags & (GPE_LEVEL | GPE_EDGE)))
2283		return -EINVAL;
2284	if (ptbl->handler != NULL && !(flags & GPE_DIRECT))
2285		printf("%s: GPE 0x%.2x already enabled\n", DEVNAME(sc), gpe);
2286
2287	dnprintf(50, "Adding GPE handler 0x%.2x (%s)\n", gpe,
2288	    (flags & GPE_EDGE ? "edge" : "level"));
2289	ptbl->handler = handler;
2290	ptbl->arg = arg;
2291	ptbl->flags = flags;
2292
2293	return (0);
2294}
2295
2296int
2297acpi_gpe(struct acpi_softc *sc, int gpe, void *arg)
2298{
2299	struct aml_node *node = arg;
2300	uint8_t mask, en;
2301
2302	dnprintf(10, "handling GPE %.2x\n", gpe);
2303	aml_evalnode(sc, node, 0, NULL, NULL);
2304
2305	mask = (1L << (gpe & 7));
2306	if (sc->gpe_table[gpe].flags & GPE_LEVEL)
2307		acpi_write_pmreg(sc, ACPIREG_GPE_STS, gpe>>3, mask);
2308	en = acpi_read_pmreg(sc, ACPIREG_GPE_EN,  gpe>>3);
2309	acpi_write_pmreg(sc, ACPIREG_GPE_EN,  gpe>>3, en | mask);
2310	return (0);
2311}
2312
2313/* Discover Devices that can wakeup the system
2314 * _PRW returns a package
2315 *  pkg[0] = integer (FADT gpe bit) or package (gpe block,gpe bit)
2316 *  pkg[1] = lowest sleep state
2317 *  pkg[2+] = power resource devices (optional)
2318 *
2319 * To enable wakeup devices:
2320 *    Evaluate _ON method in each power resource device
2321 *    Evaluate _PSW method
2322 */
2323int
2324acpi_foundprw(struct aml_node *node, void *arg)
2325{
2326	struct acpi_softc *sc = arg;
2327	struct acpi_wakeq *wq;
2328	int64_t sta;
2329
2330	sta = acpi_getsta(sc, node->parent);
2331	if ((sta & STA_PRESENT) == 0)
2332		return 0;
2333
2334	wq = malloc(sizeof(struct acpi_wakeq), M_DEVBUF, M_NOWAIT | M_ZERO);
2335	if (wq == NULL)
2336		return 0;
2337
2338	wq->q_wakepkg = malloc(sizeof(struct aml_value), M_DEVBUF,
2339	    M_NOWAIT | M_ZERO);
2340	if (wq->q_wakepkg == NULL) {
2341		free(wq, M_DEVBUF, sizeof(*wq));
2342		return 0;
2343	}
2344	dnprintf(10, "Found _PRW (%s)\n", node->parent->name);
2345	aml_evalnode(sc, node, 0, NULL, wq->q_wakepkg);
2346	wq->q_node = node->parent;
2347	wq->q_gpe = -1;
2348
2349	/* Get GPE of wakeup device, and lowest sleep level */
2350	if (wq->q_wakepkg->type == AML_OBJTYPE_PACKAGE &&
2351	    wq->q_wakepkg->length >= 2) {
2352		if (wq->q_wakepkg->v_package[0]->type == AML_OBJTYPE_INTEGER)
2353			wq->q_gpe = wq->q_wakepkg->v_package[0]->v_integer;
2354		if (wq->q_wakepkg->v_package[1]->type == AML_OBJTYPE_INTEGER)
2355			wq->q_state = wq->q_wakepkg->v_package[1]->v_integer;
2356	}
2357	SIMPLEQ_INSERT_TAIL(&sc->sc_wakedevs, wq, q_next);
2358	return 0;
2359}
2360
2361struct gpe_block *
2362acpi_find_gpe(struct acpi_softc *sc, int gpe)
2363{
2364	if (gpe >= sc->sc_lastgpe)
2365		return NULL;
2366	return &sc->gpe_table[gpe];
2367}
2368
2369void
2370acpi_init_gpes(struct acpi_softc *sc)
2371{
2372	struct aml_node *gpe;
2373	char name[12];
2374	int  idx;
2375
2376	sc->sc_lastgpe = sc->sc_fadt->gpe0_blk_len << 2;
2377	dnprintf(50, "Last GPE: %.2x\n", sc->sc_lastgpe);
2378
2379	/* Allocate GPE table */
2380	sc->gpe_table = mallocarray(sc->sc_lastgpe, sizeof(struct gpe_block),
2381	    M_DEVBUF, M_WAITOK | M_ZERO);
2382
2383	/* Clear GPE status */
2384	acpi_disable_allgpes(sc);
2385	for (idx = 0; idx < sc->sc_lastgpe; idx++) {
2386		/* Search Level-sensitive GPES */
2387		snprintf(name, sizeof(name), "\\_GPE._L%.2X", idx);
2388		gpe = aml_searchname(&aml_root, name);
2389		if (gpe != NULL)
2390			acpi_set_gpehandler(sc, idx, acpi_gpe, gpe, GPE_LEVEL);
2391		if (gpe == NULL) {
2392			/* Search Edge-sensitive GPES */
2393			snprintf(name, sizeof(name), "\\_GPE._E%.2X", idx);
2394			gpe = aml_searchname(&aml_root, name);
2395			if (gpe != NULL)
2396				acpi_set_gpehandler(sc, idx, acpi_gpe, gpe,
2397				    GPE_EDGE);
2398		}
2399	}
2400	aml_find_node(&aml_root, "_PRW", acpi_foundprw, sc);
2401}
2402
2403void
2404acpi_init_pm(struct acpi_softc *sc)
2405{
2406	sc->sc_tts = aml_searchname(&aml_root, "_TTS");
2407	sc->sc_pts = aml_searchname(&aml_root, "_PTS");
2408	sc->sc_wak = aml_searchname(&aml_root, "_WAK");
2409	sc->sc_bfs = aml_searchname(&aml_root, "_BFS");
2410	sc->sc_gts = aml_searchname(&aml_root, "_GTS");
2411	sc->sc_sst = aml_searchname(&aml_root, "_SI_._SST");
2412}
2413
2414#ifndef SMALL_KERNEL
2415
2416void
2417acpi_init_states(struct acpi_softc *sc)
2418{
2419	struct aml_value res;
2420	char name[8];
2421	int i;
2422
2423	printf("\n%s: sleep states", DEVNAME(sc));
2424	for (i = ACPI_STATE_S0; i <= ACPI_STATE_S5; i++) {
2425		snprintf(name, sizeof(name), "_S%d_", i);
2426		sc->sc_sleeptype[i].slp_typa = -1;
2427		sc->sc_sleeptype[i].slp_typb = -1;
2428		if (aml_evalname(sc, &aml_root, name, 0, NULL, &res) == 0) {
2429			if (res.type == AML_OBJTYPE_PACKAGE) {
2430				sc->sc_sleeptype[i].slp_typa =
2431				    aml_val2int(res.v_package[0]);
2432				sc->sc_sleeptype[i].slp_typb =
2433				    aml_val2int(res.v_package[1]);
2434				printf(" S%d", i);
2435			}
2436			aml_freevalue(&res);
2437		}
2438	}
2439}
2440
2441void
2442acpi_sleep_pm(struct acpi_softc *sc, int state)
2443{
2444	uint16_t rega, regb, regra, regrb;
2445	int retry = 0;
2446
2447	intr_disable();
2448
2449	/* Clear WAK_STS bit */
2450	acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0, ACPI_PM1_WAK_STS);
2451
2452	/* Disable BM arbitration at deep sleep and beyond */
2453	if (state >= ACPI_STATE_S3 &&
2454	    sc->sc_fadt->pm2_cnt_blk && sc->sc_fadt->pm2_cnt_len)
2455		acpi_write_pmreg(sc, ACPIREG_PM2_CNT, 0, ACPI_PM2_ARB_DIS);
2456
2457	/* Write SLP_TYPx values */
2458	rega = acpi_read_pmreg(sc, ACPIREG_PM1A_CNT, 0);
2459	regb = acpi_read_pmreg(sc, ACPIREG_PM1B_CNT, 0);
2460	rega &= ~(ACPI_PM1_SLP_TYPX_MASK | ACPI_PM1_SLP_EN);
2461	regb &= ~(ACPI_PM1_SLP_TYPX_MASK | ACPI_PM1_SLP_EN);
2462	rega |= ACPI_PM1_SLP_TYPX(sc->sc_sleeptype[state].slp_typa);
2463	regb |= ACPI_PM1_SLP_TYPX(sc->sc_sleeptype[state].slp_typb);
2464	acpi_write_pmreg(sc, ACPIREG_PM1A_CNT, 0, rega);
2465	acpi_write_pmreg(sc, ACPIREG_PM1B_CNT, 0, regb);
2466
2467	/* Loop on WAK_STS, setting the SLP_EN bits once in a while */
2468	rega |= ACPI_PM1_SLP_EN;
2469	regb |= ACPI_PM1_SLP_EN;
2470	while (1) {
2471		if (retry == 0) {
2472			acpi_write_pmreg(sc, ACPIREG_PM1A_CNT, 0, rega);
2473			acpi_write_pmreg(sc, ACPIREG_PM1B_CNT, 0, regb);
2474		}
2475		retry = (retry + 1) % 100000;
2476
2477		regra = acpi_read_pmreg(sc, ACPIREG_PM1A_STS, 0);
2478		regrb = acpi_read_pmreg(sc, ACPIREG_PM1B_STS, 0);
2479		if ((regra & ACPI_PM1_WAK_STS) ||
2480		    (regrb & ACPI_PM1_WAK_STS))
2481			break;
2482	}
2483}
2484
2485uint32_t acpi_force_bm;
2486
2487void
2488acpi_resume_pm(struct acpi_softc *sc, int fromstate)
2489{
2490	uint16_t rega, regb, en;
2491
2492	/* Write SLP_TYPx values */
2493	rega = acpi_read_pmreg(sc, ACPIREG_PM1A_CNT, 0);
2494	regb = acpi_read_pmreg(sc, ACPIREG_PM1B_CNT, 0);
2495	rega &= ~(ACPI_PM1_SLP_TYPX_MASK | ACPI_PM1_SLP_EN);
2496	regb &= ~(ACPI_PM1_SLP_TYPX_MASK | ACPI_PM1_SLP_EN);
2497	rega |= ACPI_PM1_SLP_TYPX(sc->sc_sleeptype[ACPI_STATE_S0].slp_typa);
2498	regb |= ACPI_PM1_SLP_TYPX(sc->sc_sleeptype[ACPI_STATE_S0].slp_typb);
2499	acpi_write_pmreg(sc, ACPIREG_PM1A_CNT, 0, rega);
2500	acpi_write_pmreg(sc, ACPIREG_PM1B_CNT, 0, regb);
2501
2502	/* Force SCI_EN on resume to fix horribly broken machines */
2503	acpi_write_pmreg(sc, ACPIREG_PM1_CNT, 0,
2504	    ACPI_PM1_SCI_EN | acpi_force_bm);
2505
2506	/* Clear fixed event status */
2507	acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0, ACPI_PM1_ALL_STS);
2508
2509	/* acpica-reference.pdf page 148 says do not call _BFS */
2510	/* 1st resume AML step: _BFS(fromstate) */
2511	aml_node_setval(sc, sc->sc_bfs, fromstate);
2512
2513	/* Enable runtime GPEs */
2514	acpi_disable_allgpes(sc);
2515	acpi_enable_rungpes(sc);
2516
2517	acpi_indicator(sc, ACPI_SST_WAKING);
2518
2519	/* 2nd resume AML step: _WAK(fromstate) */
2520	aml_node_setval(sc, sc->sc_wak, fromstate);
2521
2522	/* Clear WAK_STS bit */
2523	acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0, ACPI_PM1_WAK_STS);
2524
2525	en = acpi_read_pmreg(sc, ACPIREG_PM1_EN, 0);
2526	if (!(sc->sc_fadt->flags & FADT_PWR_BUTTON))
2527		en |= ACPI_PM1_PWRBTN_EN;
2528	if (!(sc->sc_fadt->flags & FADT_SLP_BUTTON))
2529		en |= ACPI_PM1_SLPBTN_EN;
2530	acpi_write_pmreg(sc, ACPIREG_PM1_EN, 0, en);
2531
2532	/*
2533	 * If PM2 exists, re-enable BM arbitration (reportedly some
2534	 * BIOS forget to)
2535	 */
2536	if (sc->sc_fadt->pm2_cnt_blk && sc->sc_fadt->pm2_cnt_len) {
2537		rega = acpi_read_pmreg(sc, ACPIREG_PM2_CNT, 0);
2538		rega &= ~ACPI_PM2_ARB_DIS;
2539		acpi_write_pmreg(sc, ACPIREG_PM2_CNT, 0, rega);
2540	}
2541}
2542
2543/* Set the indicator light to some state */
2544void
2545acpi_indicator(struct acpi_softc *sc, int led_state)
2546{
2547	static int save_led_state = -1;
2548
2549	if (save_led_state != led_state) {
2550		aml_node_setval(sc, sc->sc_sst, led_state);
2551		save_led_state = led_state;
2552	}
2553}
2554
2555
2556int
2557acpi_sleep_state(struct acpi_softc *sc, int sleepmode)
2558{
2559	extern int perflevel;
2560	extern int lid_action;
2561	int error = ENXIO;
2562	size_t rndbuflen = 0;
2563	char *rndbuf = NULL;
2564	int state, s;
2565#if NSOFTRAID > 0
2566	extern void sr_quiesce(void);
2567#endif
2568
2569	switch (sleepmode) {
2570	case ACPI_SLEEP_SUSPEND:
2571		state = ACPI_STATE_S3;
2572		break;
2573	case ACPI_SLEEP_HIBERNATE:
2574		state = ACPI_STATE_S4;
2575		break;
2576	default:
2577		return (EOPNOTSUPP);
2578	}
2579
2580	if (sc->sc_sleeptype[state].slp_typa == -1 ||
2581	    sc->sc_sleeptype[state].slp_typb == -1) {
2582		printf("%s: state S%d unavailable\n",
2583		    sc->sc_dev.dv_xname, state);
2584		return (EOPNOTSUPP);
2585	}
2586
2587	/* 1st suspend AML step: _TTS(tostate) */
2588	if (aml_node_setval(sc, sc->sc_tts, state) != 0)
2589		goto fail_tts;
2590	acpi_indicator(sc, ACPI_SST_WAKING);	/* blink */
2591
2592#if NWSDISPLAY > 0
2593	/*
2594	 * Temporarily release the lock to prevent the X server from
2595	 * blocking on setting the display brightness.
2596	 */
2597	rw_exit_write(&sc->sc_lck);
2598	wsdisplay_suspend();
2599	rw_enter_write(&sc->sc_lck);
2600#endif /* NWSDISPLAY > 0 */
2601
2602	stop_periodic_resettodr();
2603
2604#ifdef HIBERNATE
2605	if (sleepmode == ACPI_SLEEP_HIBERNATE) {
2606		/*
2607		 * Discard useless memory to reduce fragmentation,
2608		 * and attempt to create a hibernate work area
2609		 */
2610		hibernate_suspend_bufcache();
2611		uvmpd_hibernate();
2612		if (hibernate_alloc()) {
2613			printf("%s: failed to allocate hibernate memory\n",
2614			    sc->sc_dev.dv_xname);
2615			goto fail_alloc;
2616		}
2617	}
2618#endif /* HIBERNATE */
2619
2620	sensor_quiesce();
2621	if (config_suspend_all(DVACT_QUIESCE))
2622		goto fail_quiesce;
2623
2624	vfs_stall(curproc, 1);
2625#if NSOFTRAID > 0
2626	sr_quiesce();
2627#endif
2628	bufq_quiesce();
2629
2630#ifdef MULTIPROCESSOR
2631	acpi_sleep_mp();
2632#endif
2633
2634#ifdef HIBERNATE
2635	if (sleepmode == ACPI_SLEEP_HIBERNATE) {
2636		/*
2637		 * We've just done various forms of syncing to disk
2638		 * churned lots of memory dirty.  We don't need to
2639		 * save that dirty memory to hibernate, so release it.
2640		 */
2641		hibernate_suspend_bufcache();
2642		uvmpd_hibernate();
2643	}
2644#endif /* HIBERNATE */
2645
2646	resettodr();
2647
2648	s = splhigh();
2649	intr_disable();	/* PSL_I for resume; PIC/APIC broken until repair */
2650	cold = 2;	/* Force other code to delay() instead of tsleep() */
2651
2652	if (config_suspend_all(DVACT_SUSPEND) != 0)
2653		goto fail_suspend;
2654	acpi_sleep_clocks(sc, state);
2655
2656	suspend_randomness();
2657
2658	/* 2nd suspend AML step: _PTS(tostate) */
2659	if (aml_node_setval(sc, sc->sc_pts, state) != 0)
2660		goto fail_pts;
2661
2662	acpibtn_enable_psw();	/* enable _LID for wakeup */
2663	acpi_indicator(sc, ACPI_SST_SLEEPING);
2664
2665	/* 3rd suspend AML step: _GTS(tostate) */
2666	aml_node_setval(sc, sc->sc_gts, state);
2667
2668	/* Clear fixed event status */
2669	acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0, ACPI_PM1_ALL_STS);
2670
2671	/* Enable wake GPEs */
2672	acpi_disable_allgpes(sc);
2673	acpi_enable_wakegpes(sc, state);
2674
2675	/* Sleep */
2676	sc->sc_state = state;
2677	error = acpi_sleep_cpu(sc, state);
2678	sc->sc_state = ACPI_STATE_S0;
2679	/* Resume */
2680
2681#ifdef HIBERNATE
2682	if (sleepmode == ACPI_SLEEP_HIBERNATE) {
2683		uvm_pmr_dirty_everything();
2684		hib_getentropy(&rndbuf, &rndbuflen);
2685	}
2686#endif /* HIBERNATE */
2687
2688	acpi_resume_cpu(sc, state);
2689
2690fail_pts:
2691	config_suspend_all(DVACT_RESUME);
2692
2693fail_suspend:
2694	cold = 0;
2695	intr_enable();
2696	splx(s);
2697
2698	acpibtn_disable_psw();		/* disable _LID for wakeup */
2699
2700	inittodr(gettime());
2701
2702	/* 3rd resume AML step: _TTS(runstate) */
2703	aml_node_setval(sc, sc->sc_tts, sc->sc_state);
2704
2705	/* force RNG upper level reseed */
2706	resume_randomness(rndbuf, rndbuflen);
2707
2708#ifdef MULTIPROCESSOR
2709	acpi_resume_mp();
2710#endif
2711
2712	vfs_stall(curproc, 0);
2713	bufq_restart();
2714
2715fail_quiesce:
2716	config_suspend_all(DVACT_WAKEUP);
2717	sensor_restart();
2718
2719#ifdef HIBERNATE
2720	if (sleepmode == ACPI_SLEEP_HIBERNATE) {
2721		hibernate_free();
2722fail_alloc:
2723		hibernate_resume_bufcache();
2724	}
2725#endif /* HIBERNATE */
2726
2727	start_periodic_resettodr();
2728
2729#if NWSDISPLAY > 0
2730	rw_exit_write(&sc->sc_lck);
2731	wsdisplay_resume();
2732	rw_enter_write(&sc->sc_lck);
2733#endif /* NWSDISPLAY > 0 */
2734
2735	sys_sync(curproc, NULL, NULL);
2736
2737	/* Restore hw.setperf */
2738	if (cpu_setperf != NULL)
2739		cpu_setperf(perflevel);
2740
2741	acpi_record_event(sc, APM_NORMAL_RESUME);
2742	acpi_indicator(sc, ACPI_SST_WORKING);
2743
2744	/* If we woke up but all the lids are closed, go back to sleep */
2745	if (acpibtn_numopenlids() == 0 && lid_action != 0)
2746		acpi_addtask(sc, acpi_sleep_task, sc, sleepmode);
2747
2748fail_tts:
2749	return (error);
2750}
2751
2752/* XXX
2753 * We are going to do AML execution but are not in the acpi thread.
2754 * We do not know if the acpi thread is sleeping on acpiec in some
2755 * intermediate context.  Wish us luck.
2756 */
2757void
2758acpi_powerdown(void)
2759{
2760	int state = ACPI_STATE_S5, s;
2761	struct acpi_softc *sc = acpi_softc;
2762
2763	if (acpi_enabled == 0)
2764		return;
2765
2766	s = splhigh();
2767	intr_disable();
2768	cold = 1;
2769
2770	/* 1st powerdown AML step: _PTS(tostate) */
2771	aml_node_setval(sc, sc->sc_pts, state);
2772
2773	acpi_disable_allgpes(sc);
2774	acpi_enable_wakegpes(sc, state);
2775
2776	/* 2nd powerdown AML step: _GTS(tostate) */
2777	aml_node_setval(sc, sc->sc_gts, state);
2778
2779	acpi_sleep_pm(sc, state);
2780	panic("acpi S5 transition did not happen");
2781	while (1)
2782		;
2783}
2784
2785int
2786acpi_map_address(struct acpi_softc *sc, struct acpi_gas *gas, bus_addr_t base,
2787    bus_size_t size, bus_space_handle_t *pioh, bus_space_tag_t *piot)
2788{
2789	int iospace = GAS_SYSTEM_IOSPACE;
2790
2791	/* No GAS structure, default to I/O space */
2792	if (gas != NULL) {
2793		base += gas->address;
2794		iospace = gas->address_space_id;
2795	}
2796	switch (iospace) {
2797	case GAS_SYSTEM_MEMORY:
2798		*piot = sc->sc_memt;
2799		break;
2800	case GAS_SYSTEM_IOSPACE:
2801		*piot = sc->sc_iot;
2802		break;
2803	default:
2804		return -1;
2805	}
2806	if (bus_space_map(*piot, base, size, 0, pioh))
2807		return -1;
2808
2809	return 0;
2810}
2811
2812#endif /* SMALL_KERNEL */
2813
2814void
2815acpi_wakeup(void *arg)
2816{
2817	struct acpi_softc  *sc = (struct acpi_softc *)arg;
2818
2819	sc->sc_threadwaiting = 0;
2820	wakeup(sc);
2821}
2822
2823
2824void
2825acpi_thread(void *arg)
2826{
2827	struct acpi_thread *thread = arg;
2828	struct acpi_softc  *sc = thread->sc;
2829	extern int aml_busy;
2830	int s;
2831
2832	/* AML/SMI cannot be trusted -- only run on the BSP */
2833	sched_peg_curproc(&cpu_info_primary);
2834
2835	rw_enter_write(&sc->sc_lck);
2836
2837	/*
2838	 * If we have an interrupt handler, we can get notification
2839	 * when certain status bits changes in the ACPI registers,
2840	 * so let us enable some events we can forward to userland
2841	 */
2842	if (sc->sc_interrupt) {
2843		int16_t en;
2844
2845		dnprintf(1,"slpbtn:%c  pwrbtn:%c\n",
2846		    sc->sc_fadt->flags & FADT_SLP_BUTTON ? 'n' : 'y',
2847		    sc->sc_fadt->flags & FADT_PWR_BUTTON ? 'n' : 'y');
2848		dnprintf(10, "Enabling acpi interrupts...\n");
2849		sc->sc_threadwaiting = 1;
2850
2851		/* Enable Sleep/Power buttons if they exist */
2852		s = splbio();
2853		en = acpi_read_pmreg(sc, ACPIREG_PM1_EN, 0);
2854		if (!(sc->sc_fadt->flags & FADT_PWR_BUTTON))
2855			en |= ACPI_PM1_PWRBTN_EN;
2856		if (!(sc->sc_fadt->flags & FADT_SLP_BUTTON))
2857			en |= ACPI_PM1_SLPBTN_EN;
2858		acpi_write_pmreg(sc, ACPIREG_PM1_EN, 0, en);
2859
2860		/* Enable handled GPEs here */
2861		acpi_enable_rungpes(sc);
2862		splx(s);
2863	}
2864
2865	while (thread->running) {
2866		s = splbio();
2867		while (sc->sc_threadwaiting) {
2868			dnprintf(10, "acpi thread going to sleep...\n");
2869			rw_exit_write(&sc->sc_lck);
2870			tsleep_nsec(sc, PWAIT, "acpi0", INFSLP);
2871			rw_enter_write(&sc->sc_lck);
2872		}
2873		sc->sc_threadwaiting = 1;
2874		splx(s);
2875		if (aml_busy) {
2876			panic("thread woke up to find aml was busy");
2877			continue;
2878		}
2879
2880		/* Run ACPI taskqueue */
2881		while(acpi_dotask(acpi_softc))
2882			;
2883	}
2884	free(thread, M_DEVBUF, sizeof(*thread));
2885
2886	kthread_exit(0);
2887}
2888
2889void
2890acpi_create_thread(void *arg)
2891{
2892	struct acpi_softc *sc = arg;
2893
2894	if (kthread_create(acpi_thread, sc->sc_thread, NULL, DEVNAME(sc))
2895	    != 0)
2896		printf("%s: unable to create isr thread, GPEs disabled\n",
2897		    DEVNAME(sc));
2898}
2899
2900int
2901acpi_foundec(struct aml_node *node, void *arg)
2902{
2903	struct acpi_softc	*sc = (struct acpi_softc *)arg;
2904	struct device		*self = (struct device *)arg;
2905	const char		*dev;
2906	struct aml_value	 res;
2907	struct acpi_attach_args	aaa;
2908
2909	if (aml_evalnode(sc, node, 0, NULL, &res) != 0)
2910		return 0;
2911
2912	switch (res.type) {
2913	case AML_OBJTYPE_STRING:
2914		dev = res.v_string;
2915		break;
2916	case AML_OBJTYPE_INTEGER:
2917		dev = aml_eisaid(aml_val2int(&res));
2918		break;
2919	default:
2920		dev = "unknown";
2921		break;
2922	}
2923
2924	if (strcmp(dev, ACPI_DEV_ECD))
2925		return 0;
2926
2927	/* Check if we're already attached */
2928	if (sc->sc_ec && sc->sc_ec->sc_devnode == node->parent)
2929		return 0;
2930
2931	memset(&aaa, 0, sizeof(aaa));
2932	aaa.aaa_iot = sc->sc_iot;
2933	aaa.aaa_memt = sc->sc_memt;
2934	aaa.aaa_node = node->parent;
2935	aaa.aaa_dev = dev;
2936	aaa.aaa_name = "acpiec";
2937	config_found(self, &aaa, acpi_print);
2938	aml_freevalue(&res);
2939
2940	return 0;
2941}
2942
2943int
2944acpi_foundsony(struct aml_node *node, void *arg)
2945{
2946	struct acpi_softc *sc = (struct acpi_softc *)arg;
2947	struct device *self = (struct device *)arg;
2948	struct acpi_attach_args aaa;
2949
2950	memset(&aaa, 0, sizeof(aaa));
2951	aaa.aaa_iot = sc->sc_iot;
2952	aaa.aaa_memt = sc->sc_memt;
2953	aaa.aaa_node = node->parent;
2954	aaa.aaa_name = "acpisony";
2955
2956	config_found(self, &aaa, acpi_print);
2957
2958	return 0;
2959}
2960
2961/* Support for _DSD Device Properties. */
2962
2963int
2964acpi_getprop(struct aml_node *node, const char *prop, void *buf, int buflen)
2965{
2966	struct aml_value dsd;
2967	int i;
2968
2969	/* daffd814-6eba-4d8c-8a91-bc9bbf4aa301 */
2970	static uint8_t prop_guid[] = {
2971		0x14, 0xd8, 0xff, 0xda, 0xba, 0x6e, 0x8c, 0x4d,
2972		0x8a, 0x91, 0xbc, 0x9b, 0xbf, 0x4a, 0xa3, 0x01,
2973	};
2974
2975	if (aml_evalname(acpi_softc, node, "_DSD", 0, NULL, &dsd))
2976		return -1;
2977
2978	if (dsd.type != AML_OBJTYPE_PACKAGE || dsd.length != 2 ||
2979	    dsd.v_package[0]->type != AML_OBJTYPE_BUFFER ||
2980	    dsd.v_package[1]->type != AML_OBJTYPE_PACKAGE)
2981		return -1;
2982
2983	/* Check UUID. */
2984	if (dsd.v_package[0]->length != sizeof(prop_guid) ||
2985	    memcmp(dsd.v_package[0]->v_buffer, prop_guid,
2986	    sizeof(prop_guid)) != 0)
2987		return -1;
2988
2989	/* Check properties. */
2990	for (i = 0; i < dsd.v_package[1]->length; i++) {
2991		struct aml_value *res = dsd.v_package[1]->v_package[i];
2992		int len;
2993
2994		if (res->type != AML_OBJTYPE_PACKAGE || res->length != 2 ||
2995		    res->v_package[0]->type != AML_OBJTYPE_STRING)
2996			continue;
2997
2998		len = res->v_package[1]->length;
2999		switch (res->v_package[1]->type) {
3000		case AML_OBJTYPE_BUFFER:
3001			memcpy(buf, res->v_package[1]->v_buffer,
3002			    min(len, buflen));
3003			return len;
3004		case AML_OBJTYPE_STRING:
3005			memcpy(buf, res->v_package[1]->v_string,
3006			    min(len, buflen));
3007			return len;
3008		}
3009	}
3010
3011	return -1;
3012}
3013
3014uint32_t
3015acpi_getpropint(struct aml_node *node, const char *prop, uint32_t defval)
3016{
3017	struct aml_value dsd;
3018	int i;
3019
3020	/* daffd814-6eba-4d8c-8a91-bc9bbf4aa301 */
3021	static uint8_t prop_guid[] = {
3022		0x14, 0xd8, 0xff, 0xda, 0xba, 0x6e, 0x8c, 0x4d,
3023		0x8a, 0x91, 0xbc, 0x9b, 0xbf, 0x4a, 0xa3, 0x01,
3024	};
3025
3026	if (aml_evalname(acpi_softc, node, "_DSD", 0, NULL, &dsd))
3027		return defval;
3028
3029	if (dsd.type != AML_OBJTYPE_PACKAGE || dsd.length != 2 ||
3030	    dsd.v_package[0]->type != AML_OBJTYPE_BUFFER ||
3031	    dsd.v_package[1]->type != AML_OBJTYPE_PACKAGE)
3032		return defval;
3033
3034	/* Check UUID. */
3035	if (dsd.v_package[0]->length != sizeof(prop_guid) ||
3036	    memcmp(dsd.v_package[0]->v_buffer, prop_guid,
3037	    sizeof(prop_guid)) != 0)
3038		return defval;
3039
3040	/* Check properties. */
3041	for (i = 0; i < dsd.v_package[1]->length; i++) {
3042		struct aml_value *res = dsd.v_package[1]->v_package[i];
3043
3044		if (res->type != AML_OBJTYPE_PACKAGE || res->length != 2 ||
3045		    res->v_package[0]->type != AML_OBJTYPE_STRING ||
3046		    res->v_package[1]->type != AML_OBJTYPE_INTEGER)
3047			continue;
3048
3049		if (strcmp(res->v_package[0]->v_string, prop) == 0)
3050			return res->v_package[1]->v_integer;
3051	}
3052
3053	return defval;
3054}
3055
3056int
3057acpi_parsehid(struct aml_node *node, void *arg, char *outcdev, char *outdev,
3058    size_t devlen)
3059{
3060	struct acpi_softc	*sc = (struct acpi_softc *)arg;
3061	struct aml_value	 res;
3062	const char		*dev;
3063
3064	/* NB aml_eisaid returns a static buffer, this must come first */
3065	if (aml_evalname(acpi_softc, node->parent, "_CID", 0, NULL, &res) == 0) {
3066		switch (res.type) {
3067		case AML_OBJTYPE_STRING:
3068			dev = res.v_string;
3069			break;
3070		case AML_OBJTYPE_INTEGER:
3071			dev = aml_eisaid(aml_val2int(&res));
3072			break;
3073		default:
3074			dev = "unknown";
3075			break;
3076		}
3077		strlcpy(outcdev, dev, devlen);
3078		aml_freevalue(&res);
3079
3080		dnprintf(10, "compatible with device: %s\n", outcdev);
3081	} else {
3082		outcdev[0] = '\0';
3083	}
3084
3085	dnprintf(10, "found hid device: %s ", node->parent->name);
3086	if (aml_evalnode(sc, node, 0, NULL, &res) != 0)
3087		return (1);
3088
3089	switch (res.type) {
3090	case AML_OBJTYPE_STRING:
3091		dev = res.v_string;
3092		break;
3093	case AML_OBJTYPE_INTEGER:
3094		dev = aml_eisaid(aml_val2int(&res));
3095		break;
3096	default:
3097		dev = "unknown";
3098		break;
3099	}
3100	dnprintf(10, "	device: %s\n", dev);
3101
3102	strlcpy(outdev, dev, devlen);
3103
3104	aml_freevalue(&res);
3105
3106	return (0);
3107}
3108
3109/* Devices for which we don't want to attach a driver */
3110const char *acpi_skip_hids[] = {
3111	"INT0800",	/* Intel 82802Firmware Hub Device */
3112	"PNP0000",	/* 8259-compatible Programmable Interrupt Controller */
3113	"PNP0001",	/* EISA Interrupt Controller */
3114	"PNP0100",	/* PC-class System Timer */
3115	"PNP0103",	/* HPET System Timer */
3116	"PNP0200",	/* PC-class DMA Controller */
3117	"PNP0201",	/* EISA DMA Controller */
3118	"PNP0800",	/* Microsoft Sound System Compatible Device */
3119	"PNP0C01",	/* System Board */
3120	"PNP0C02",	/* PNP Motherboard Resources */
3121	"PNP0C04",	/* x87-compatible Floating Point Processing Unit */
3122	"PNP0C09",	/* Embedded Controller Device */
3123	"PNP0C0F",	/* PCI Interrupt Link Device */
3124	NULL
3125};
3126
3127/* ISA devices for which we attach a driver later */
3128const char *acpi_isa_hids[] = {
3129	"PNP0303",	/* IBM Enhanced Keyboard (101/102-key, PS/2 Mouse) */
3130	"PNP0400",	/* Standard LPT Parallel Port */
3131	"PNP0401",	/* ECP Parallel Port */
3132	"PNP0501",	/* 16550A-compatible COM Serial Port */
3133	"PNP0700",	/* PC-class Floppy Disk Controller */
3134	"PNP0F03",	/* Microsoft PS/2-style Mouse */
3135	"PNP0F13",	/* PS/2 Mouse */
3136	NULL
3137};
3138
3139void
3140acpi_attach_deps(struct acpi_softc *sc, struct aml_node *node)
3141{
3142	struct aml_value res;
3143	struct aml_node *dep;
3144	int i;
3145
3146	if (aml_evalname(sc, node, "_DEP", 0, NULL, &res))
3147		return;
3148
3149	if (res.type != AML_OBJTYPE_PACKAGE)
3150		return;
3151
3152	for (i = 0; i < res.length; i++) {
3153		if (res.v_package[i]->type != AML_OBJTYPE_STRING)
3154			continue;
3155		dep = aml_searchrel(node, res.v_package[i]->v_string);
3156		if (dep == NULL || dep->attached)
3157			continue;
3158		dep = aml_searchname(dep, "_HID");
3159		if (dep)
3160			acpi_foundhid(dep, sc);
3161	}
3162
3163	aml_freevalue(&res);
3164}
3165
3166int
3167acpi_parse_resources(int crsidx, union acpi_resource *crs, void *arg)
3168{
3169	struct acpi_attach_args *aaa = arg;
3170	int type = AML_CRSTYPE(crs);
3171	uint8_t flags;
3172
3173	switch (type) {
3174	case SR_IOPORT:
3175	case SR_FIXEDPORT:
3176	case LR_MEM24:
3177	case LR_MEM32:
3178	case LR_MEM32FIXED:
3179	case LR_WORD:
3180	case LR_DWORD:
3181	case LR_QWORD:
3182		if (aaa->aaa_naddr >= nitems(aaa->aaa_addr))
3183			return 0;
3184		break;
3185	case SR_IRQ:
3186	case LR_EXTIRQ:
3187		if (aaa->aaa_nirq >= nitems(aaa->aaa_irq))
3188			return 0;
3189	}
3190
3191	switch (type) {
3192	case SR_IOPORT:
3193	case SR_FIXEDPORT:
3194		aaa->aaa_bst[aaa->aaa_naddr] = aaa->aaa_iot;
3195		break;
3196	case LR_MEM24:
3197	case LR_MEM32:
3198	case LR_MEM32FIXED:
3199		aaa->aaa_bst[aaa->aaa_naddr] = aaa->aaa_memt;
3200		break;
3201	case LR_WORD:
3202	case LR_DWORD:
3203	case LR_QWORD:
3204		switch (crs->lr_word.type) {
3205		case LR_TYPE_MEMORY:
3206			aaa->aaa_bst[aaa->aaa_naddr] = aaa->aaa_memt;
3207			break;
3208		case LR_TYPE_IO:
3209			aaa->aaa_bst[aaa->aaa_naddr] = aaa->aaa_iot;
3210			break;
3211		default:
3212			/* Bus number range or something else; skip. */
3213			return 0;
3214		}
3215	}
3216
3217	switch (type) {
3218	case SR_IOPORT:
3219		aaa->aaa_addr[aaa->aaa_naddr] = crs->sr_ioport._min;
3220		aaa->aaa_size[aaa->aaa_naddr] = crs->sr_ioport._len;
3221		aaa->aaa_naddr++;
3222		break;
3223	case SR_FIXEDPORT:
3224		aaa->aaa_addr[aaa->aaa_naddr] = crs->sr_fioport._bas;
3225		aaa->aaa_size[aaa->aaa_naddr] = crs->sr_fioport._len;
3226		aaa->aaa_naddr++;
3227		break;
3228	case LR_MEM24:
3229		aaa->aaa_addr[aaa->aaa_naddr] = crs->lr_m24._min;
3230		aaa->aaa_size[aaa->aaa_naddr] = crs->lr_m24._len;
3231		aaa->aaa_naddr++;
3232		break;
3233	case LR_MEM32:
3234		aaa->aaa_addr[aaa->aaa_naddr] = crs->lr_m32._min;
3235		aaa->aaa_size[aaa->aaa_naddr] = crs->lr_m32._len;
3236		aaa->aaa_naddr++;
3237		break;
3238	case LR_MEM32FIXED:
3239		aaa->aaa_addr[aaa->aaa_naddr] = crs->lr_m32fixed._bas;
3240		aaa->aaa_size[aaa->aaa_naddr] = crs->lr_m32fixed._len;
3241		aaa->aaa_naddr++;
3242		break;
3243	case LR_WORD:
3244		aaa->aaa_addr[aaa->aaa_naddr] = crs->lr_word._min;
3245		aaa->aaa_size[aaa->aaa_naddr] = crs->lr_word._len;
3246		aaa->aaa_naddr++;
3247		break;
3248	case LR_DWORD:
3249		aaa->aaa_addr[aaa->aaa_naddr] = crs->lr_dword._min;
3250		aaa->aaa_size[aaa->aaa_naddr] = crs->lr_dword._len;
3251		aaa->aaa_naddr++;
3252		break;
3253	case LR_QWORD:
3254		aaa->aaa_addr[aaa->aaa_naddr] = crs->lr_qword._min;
3255		aaa->aaa_size[aaa->aaa_naddr] = crs->lr_qword._len;
3256		aaa->aaa_naddr++;
3257		break;
3258	case SR_IRQ:
3259		aaa->aaa_irq[aaa->aaa_nirq] = ffs(crs->sr_irq.irq_mask) - 1;
3260		/* Default is exclusive, active-high, edge triggered. */
3261		if (AML_CRSLEN(crs) < 3)
3262			flags = SR_IRQ_MODE;
3263		else
3264			flags = crs->sr_irq.irq_flags;
3265		/* Map flags to those of the extended interrupt descriptor. */
3266		if (flags & SR_IRQ_SHR)
3267			aaa->aaa_irq_flags[aaa->aaa_nirq] |= LR_EXTIRQ_SHR;
3268		if (flags & SR_IRQ_POLARITY)
3269			aaa->aaa_irq_flags[aaa->aaa_nirq] |= LR_EXTIRQ_POLARITY;
3270		if (flags & SR_IRQ_MODE)
3271			aaa->aaa_irq_flags[aaa->aaa_nirq] |= LR_EXTIRQ_MODE;
3272		aaa->aaa_nirq++;
3273		break;
3274	case LR_EXTIRQ:
3275		aaa->aaa_irq[aaa->aaa_nirq] = crs->lr_extirq.irq[0];
3276		aaa->aaa_irq_flags[aaa->aaa_nirq] = crs->lr_extirq.flags;
3277		aaa->aaa_nirq++;
3278		break;
3279	}
3280
3281	return 0;
3282}
3283
3284void
3285acpi_parse_crs(struct acpi_softc *sc, struct acpi_attach_args *aaa)
3286{
3287	struct aml_value res;
3288
3289	if (aml_evalname(sc, aaa->aaa_node, "_CRS", 0, NULL, &res))
3290		return;
3291
3292	aml_parse_resource(&res, acpi_parse_resources, aaa);
3293}
3294
3295int
3296acpi_foundhid(struct aml_node *node, void *arg)
3297{
3298	struct acpi_softc	*sc = (struct acpi_softc *)arg;
3299	struct device		*self = (struct device *)arg;
3300	char		 	 cdev[32];
3301	char		 	 dev[32];
3302	struct acpi_attach_args	 aaa;
3303	int64_t			 sta;
3304	int64_t			 cca;
3305#ifndef SMALL_KERNEL
3306	int			 i;
3307#endif
3308
3309	if (acpi_parsehid(node, arg, cdev, dev, sizeof(dev)) != 0)
3310		return (0);
3311
3312	sta = acpi_getsta(sc, node->parent);
3313	if ((sta & STA_PRESENT) == 0)
3314		return (0);
3315
3316	if (aml_evalinteger(sc, node->parent, "_CCA", 0, NULL, &cca))
3317		cca = 1;
3318
3319	acpi_attach_deps(sc, node->parent);
3320
3321	memset(&aaa, 0, sizeof(aaa));
3322	aaa.aaa_iot = sc->sc_iot;
3323	aaa.aaa_memt = sc->sc_memt;
3324	aaa.aaa_dmat = cca ? sc->sc_cc_dmat : sc->sc_ci_dmat;
3325	aaa.aaa_node = node->parent;
3326	aaa.aaa_dev = dev;
3327	aaa.aaa_cdev = cdev;
3328	acpi_parse_crs(sc, &aaa);
3329
3330#ifndef SMALL_KERNEL
3331	if (!strcmp(cdev, ACPI_DEV_MOUSE)) {
3332		for (i = 0; i < nitems(sbtn_pnp); i++) {
3333			if (!strcmp(dev, sbtn_pnp[i])) {
3334				mouse_has_softbtn = 1;
3335				break;
3336			}
3337		}
3338	}
3339#endif
3340
3341	if (acpi_matchhids(&aaa, acpi_skip_hids, "none") ||
3342	    acpi_matchhids(&aaa, acpi_isa_hids, "none"))
3343		return (0);
3344
3345	if (!node->parent->attached) {
3346		node->parent->attached = 1;
3347		config_found(self, &aaa, acpi_print);
3348	}
3349
3350	return (0);
3351}
3352
3353#ifndef SMALL_KERNEL
3354int
3355acpi_founddock(struct aml_node *node, void *arg)
3356{
3357	struct acpi_softc	*sc = (struct acpi_softc *)arg;
3358	struct device		*self = (struct device *)arg;
3359	struct acpi_attach_args	aaa;
3360
3361	dnprintf(10, "found dock entry: %s\n", node->parent->name);
3362
3363	memset(&aaa, 0, sizeof(aaa));
3364	aaa.aaa_iot = sc->sc_iot;
3365	aaa.aaa_memt = sc->sc_memt;
3366	aaa.aaa_node = node->parent;
3367	aaa.aaa_name = "acpidock";
3368
3369	config_found(self, &aaa, acpi_print);
3370
3371	return 0;
3372}
3373
3374int
3375acpi_foundvideo(struct aml_node *node, void *arg)
3376{
3377	struct acpi_softc *sc = (struct acpi_softc *)arg;
3378	struct device *self = (struct device *)arg;
3379	struct acpi_attach_args	aaa;
3380
3381	memset(&aaa, 0, sizeof(aaa));
3382	aaa.aaa_iot = sc->sc_iot;
3383	aaa.aaa_memt = sc->sc_memt;
3384	aaa.aaa_node = node->parent;
3385	aaa.aaa_name = "acpivideo";
3386
3387	config_found(self, &aaa, acpi_print);
3388
3389	return (0);
3390}
3391
3392int
3393acpi_foundsbs(struct aml_node *node, void *arg)
3394{
3395	struct acpi_softc	*sc = (struct acpi_softc *)arg;
3396	struct device		*self = (struct device *)arg;
3397	char		 	 cdev[32], dev[32];
3398	struct acpi_attach_args	 aaa;
3399	int64_t			 sta;
3400
3401	if (acpi_parsehid(node, arg, cdev, dev, sizeof(dev)) != 0)
3402		return (0);
3403
3404	sta = acpi_getsta(sc, node->parent);
3405	if ((sta & STA_PRESENT) == 0)
3406		return (0);
3407
3408	acpi_attach_deps(sc, node->parent);
3409
3410	if (strcmp(dev, ACPI_DEV_SBS) != 0)
3411		return (0);
3412
3413	if (node->parent->attached)
3414		return (0);
3415
3416	memset(&aaa, 0, sizeof(aaa));
3417	aaa.aaa_iot = sc->sc_iot;
3418	aaa.aaa_memt = sc->sc_memt;
3419	aaa.aaa_node = node->parent;
3420	aaa.aaa_dev = dev;
3421	aaa.aaa_cdev = cdev;
3422
3423	config_found(self, &aaa, acpi_print);
3424	node->parent->attached = 1;
3425
3426	return (0);
3427}
3428
3429int
3430acpiopen(dev_t dev, int flag, int mode, struct proc *p)
3431{
3432	int error = 0;
3433	struct acpi_softc *sc;
3434	int s;
3435
3436	if (!acpi_cd.cd_ndevs || APMUNIT(dev) != 0 ||
3437	    !(sc = acpi_cd.cd_devs[APMUNIT(dev)]))
3438		return (ENXIO);
3439
3440	s = splbio();
3441	switch (APMDEV(dev)) {
3442	case APMDEV_CTL:
3443		if (!(flag & FWRITE)) {
3444			error = EINVAL;
3445			break;
3446		}
3447		if (sc->sc_flags & SCFLAG_OWRITE) {
3448			error = EBUSY;
3449			break;
3450		}
3451		sc->sc_flags |= SCFLAG_OWRITE;
3452		break;
3453	case APMDEV_NORMAL:
3454		if (!(flag & FREAD) || (flag & FWRITE)) {
3455			error = EINVAL;
3456			break;
3457		}
3458		sc->sc_flags |= SCFLAG_OREAD;
3459		break;
3460	default:
3461		error = ENXIO;
3462		break;
3463	}
3464	splx(s);
3465	return (error);
3466}
3467
3468int
3469acpiclose(dev_t dev, int flag, int mode, struct proc *p)
3470{
3471	int error = 0;
3472	struct acpi_softc *sc;
3473	int s;
3474
3475	if (!acpi_cd.cd_ndevs || APMUNIT(dev) != 0 ||
3476	    !(sc = acpi_cd.cd_devs[APMUNIT(dev)]))
3477		return (ENXIO);
3478
3479	s = splbio();
3480	switch (APMDEV(dev)) {
3481	case APMDEV_CTL:
3482		sc->sc_flags &= ~SCFLAG_OWRITE;
3483		break;
3484	case APMDEV_NORMAL:
3485		sc->sc_flags &= ~SCFLAG_OREAD;
3486		break;
3487	default:
3488		error = ENXIO;
3489		break;
3490	}
3491	splx(s);
3492	return (error);
3493}
3494
3495int
3496acpiioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
3497{
3498	int error = 0;
3499	struct acpi_softc *sc;
3500	struct acpi_ac *ac;
3501	struct acpi_bat *bat;
3502	struct acpi_sbs *sbs;
3503	struct apm_power_info *pi = (struct apm_power_info *)data;
3504	int bats;
3505	unsigned int capacity, remaining, minutes, rate;
3506	int s;
3507
3508	if (!acpi_cd.cd_ndevs || APMUNIT(dev) != 0 ||
3509	    !(sc = acpi_cd.cd_devs[APMUNIT(dev)]))
3510		return (ENXIO);
3511
3512	s = splbio();
3513	/* fake APM */
3514	switch (cmd) {
3515	case APM_IOC_SUSPEND:
3516	case APM_IOC_STANDBY:
3517		if ((flag & FWRITE) == 0) {
3518			error = EBADF;
3519			break;
3520		}
3521		acpi_addtask(sc, acpi_sleep_task, sc, ACPI_SLEEP_SUSPEND);
3522		acpi_wakeup(sc);
3523		break;
3524#ifdef HIBERNATE
3525	case APM_IOC_HIBERNATE:
3526		if ((error = suser(p)) != 0)
3527			break;
3528		if ((flag & FWRITE) == 0) {
3529			error = EBADF;
3530			break;
3531		}
3532		if (get_hibernate_io_function(swdevt[0].sw_dev) == NULL) {
3533			error = EOPNOTSUPP;
3534			break;
3535		}
3536		acpi_addtask(sc, acpi_sleep_task, sc, ACPI_SLEEP_HIBERNATE);
3537		acpi_wakeup(sc);
3538		break;
3539#endif
3540	case APM_IOC_GETPOWER:
3541		/* A/C */
3542		pi->ac_state = APM_AC_UNKNOWN;
3543		SLIST_FOREACH(ac, &sc->sc_ac, aac_link) {
3544			if (ac->aac_softc->sc_ac_stat == PSR_ONLINE)
3545				pi->ac_state = APM_AC_ON;
3546			else if (ac->aac_softc->sc_ac_stat == PSR_OFFLINE)
3547				if (pi->ac_state == APM_AC_UNKNOWN)
3548					pi->ac_state = APM_AC_OFF;
3549		}
3550
3551		/* battery */
3552		pi->battery_state = APM_BATT_UNKNOWN;
3553		pi->battery_life = 0;
3554		pi->minutes_left = 0;
3555		bats = 0;
3556		capacity = 0;
3557		remaining = 0;
3558		minutes = 0;
3559		rate = 0;
3560		SLIST_FOREACH(bat, &sc->sc_bat, aba_link) {
3561			if (bat->aba_softc->sc_bat_present == 0)
3562				continue;
3563
3564			if (bat->aba_softc->sc_bix.bix_last_capacity == 0)
3565				continue;
3566
3567			bats++;
3568			capacity += bat->aba_softc->sc_bix.bix_last_capacity;
3569			remaining += min(bat->aba_softc->sc_bst.bst_capacity,
3570			    bat->aba_softc->sc_bix.bix_last_capacity);
3571
3572			if (bat->aba_softc->sc_bst.bst_rate == BST_UNKNOWN)
3573				continue;
3574			else if (bat->aba_softc->sc_bst.bst_rate > 1)
3575				rate = bat->aba_softc->sc_bst.bst_rate;
3576
3577			minutes += bat->aba_softc->sc_bst.bst_capacity;
3578		}
3579
3580		SLIST_FOREACH(sbs, &sc->sc_sbs, asbs_link) {
3581			if (sbs->asbs_softc->sc_batteries_present == 0)
3582				continue;
3583
3584			if (sbs->asbs_softc->sc_battery.rel_charge == 0)
3585				continue;
3586
3587			bats++;
3588			capacity += 100;
3589			remaining += min(100,
3590			    sbs->asbs_softc->sc_battery.rel_charge);
3591
3592			if (sbs->asbs_softc->sc_battery.run_time ==
3593			    ACPISBS_VALUE_UNKNOWN)
3594				continue;
3595
3596			rate = 60; /* XXX */
3597			minutes += sbs->asbs_softc->sc_battery.run_time;
3598		}
3599
3600		if (bats == 0) {
3601			pi->battery_state = APM_BATTERY_ABSENT;
3602			pi->battery_life = 0;
3603			pi->minutes_left = (unsigned int)-1;
3604			break;
3605		}
3606
3607		if (pi->ac_state == APM_AC_ON || rate == 0)
3608			pi->minutes_left = (unsigned int)-1;
3609		else
3610			pi->minutes_left = 60 * minutes / rate;
3611
3612		/* running on battery */
3613		pi->battery_life = remaining * 100 / capacity;
3614		if (pi->battery_life > 50)
3615			pi->battery_state = APM_BATT_HIGH;
3616		else if (pi->battery_life > 25)
3617			pi->battery_state = APM_BATT_LOW;
3618		else
3619			pi->battery_state = APM_BATT_CRITICAL;
3620
3621		break;
3622
3623	default:
3624		error = ENOTTY;
3625	}
3626
3627	splx(s);
3628	return (error);
3629}
3630
3631void	acpi_filtdetach(struct knote *);
3632int	acpi_filtread(struct knote *, long);
3633
3634const struct filterops acpiread_filtops = {
3635	.f_flags	= FILTEROP_ISFD,
3636	.f_attach	= NULL,
3637	.f_detach	= acpi_filtdetach,
3638	.f_event	= acpi_filtread,
3639};
3640
3641int acpi_evindex;
3642
3643int
3644acpi_record_event(struct acpi_softc *sc, u_int type)
3645{
3646	if ((sc->sc_flags & SCFLAG_OPEN) == 0)
3647		return (1);
3648
3649	acpi_evindex++;
3650	KNOTE(sc->sc_note, APM_EVENT_COMPOSE(type, acpi_evindex));
3651	return (0);
3652}
3653
3654void
3655acpi_filtdetach(struct knote *kn)
3656{
3657	struct acpi_softc *sc = kn->kn_hook;
3658	int s;
3659
3660	s = splbio();
3661	klist_remove(sc->sc_note, kn);
3662	splx(s);
3663}
3664
3665int
3666acpi_filtread(struct knote *kn, long hint)
3667{
3668	/* XXX weird kqueue_scan() semantics */
3669	if (hint && !kn->kn_data)
3670		kn->kn_data = hint;
3671	return (1);
3672}
3673
3674int
3675acpikqfilter(dev_t dev, struct knote *kn)
3676{
3677	struct acpi_softc *sc;
3678	int s;
3679
3680	if (!acpi_cd.cd_ndevs || APMUNIT(dev) != 0 ||
3681	    !(sc = acpi_cd.cd_devs[APMUNIT(dev)]))
3682		return (ENXIO);
3683
3684	switch (kn->kn_filter) {
3685	case EVFILT_READ:
3686		kn->kn_fop = &acpiread_filtops;
3687		break;
3688	default:
3689		return (EINVAL);
3690	}
3691
3692	kn->kn_hook = sc;
3693
3694	s = splbio();
3695	klist_insert(sc->sc_note, kn);
3696	splx(s);
3697
3698	return (0);
3699}
3700
3701#else /* SMALL_KERNEL */
3702
3703int
3704acpiopen(dev_t dev, int flag, int mode, struct proc *p)
3705{
3706	return (ENXIO);
3707}
3708
3709int
3710acpiclose(dev_t dev, int flag, int mode, struct proc *p)
3711{
3712	return (ENXIO);
3713}
3714
3715int
3716acpiioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
3717{
3718	return (ENXIO);
3719}
3720
3721int
3722acpikqfilter(dev_t dev, struct knote *kn)
3723{
3724	return (EOPNOTSUPP);
3725}
3726
3727#endif /* SMALL_KERNEL */
3728