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