xref: /openbsd-src/sys/dev/acpi/acpi.c (revision 850e275390052b330d93020bf619a739a3c277ac)
1 /* $OpenBSD: acpi.c,v 1.125 2008/07/02 03:14:54 fgsch 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/fcntl.h>
24 #include <sys/ioccom.h>
25 #include <sys/event.h>
26 #include <sys/signalvar.h>
27 #include <sys/proc.h>
28 #include <sys/kthread.h>
29 
30 #include <machine/conf.h>
31 #include <machine/cpufunc.h>
32 #include <machine/bus.h>
33 
34 #include <dev/pci/pcivar.h>
35 #include <dev/acpi/acpireg.h>
36 #include <dev/acpi/acpivar.h>
37 #include <dev/acpi/amltypes.h>
38 #include <dev/acpi/acpidev.h>
39 #include <dev/acpi/dsdt.h>
40 
41 #include <machine/apmvar.h>
42 #define APMUNIT(dev)	(minor(dev)&0xf0)
43 #define APMDEV(dev)	(minor(dev)&0x0f)
44 #define APMDEV_NORMAL	0
45 #define APMDEV_CTL	8
46 
47 #ifdef ACPI_DEBUG
48 int acpi_debug = 16;
49 #endif
50 int acpi_enabled;
51 int acpi_poll_enabled;
52 int acpi_hasprocfvs;
53 
54 #define ACPIEN_RETRIES 15
55 
56 void	acpi_isr_thread(void *);
57 void	acpi_create_thread(void *);
58 
59 int	acpi_match(struct device *, void *, void *);
60 void	acpi_attach(struct device *, struct device *, void *);
61 int	acpi_submatch(struct device *, void *, void *);
62 int	acpi_print(void *, const char *);
63 
64 void	acpi_map_pmregs(struct acpi_softc *);
65 
66 int	acpi_founddock(struct aml_node *, void *);
67 int	acpi_foundpss(struct aml_node *, void *);
68 int	acpi_foundhid(struct aml_node *, void *);
69 int	acpi_foundec(struct aml_node *, void *);
70 int	acpi_foundtmp(struct aml_node *, void *);
71 int	acpi_foundprt(struct aml_node *, void *);
72 int	acpi_foundprw(struct aml_node *, void *);
73 int	acpi_foundvideo(struct aml_node *, void *);
74 int	acpi_inidev(struct aml_node *, void *);
75 
76 int	acpi_loadtables(struct acpi_softc *, struct acpi_rsdp *);
77 void	acpi_load_table(paddr_t, size_t, acpi_qhead_t *);
78 void	acpi_load_dsdt(paddr_t, struct acpi_q **);
79 
80 void	acpi_init_states(struct acpi_softc *);
81 void	acpi_init_gpes(struct acpi_softc *);
82 void	acpi_init_pm(struct acpi_softc *);
83 
84 #ifndef SMALL_KERNEL
85 int acpi_add_device(struct aml_node *node, void *arg);
86 #endif /* SMALL_KERNEL */
87 
88 void	acpi_enable_onegpe(struct acpi_softc *, int, int);
89 int	acpi_gpe_level(struct acpi_softc *, int, void *);
90 int	acpi_gpe_edge(struct acpi_softc *, int, void *);
91 
92 struct gpe_block *acpi_find_gpe(struct acpi_softc *, int);
93 
94 #define	ACPI_LOCK(sc)
95 #define	ACPI_UNLOCK(sc)
96 
97 /* XXX move this into dsdt softc at some point */
98 extern struct aml_node aml_root;
99 
100 /* XXX do we need this? */
101 void	acpi_filtdetach(struct knote *);
102 int	acpi_filtread(struct knote *, long);
103 
104 struct filterops acpiread_filtops = {
105 	1, NULL, acpi_filtdetach, acpi_filtread
106 };
107 
108 struct cfattach acpi_ca = {
109 	sizeof(struct acpi_softc), acpi_match, acpi_attach
110 };
111 
112 struct cfdriver acpi_cd = {
113 	NULL, "acpi", DV_DULL
114 };
115 
116 struct acpi_softc *acpi_softc;
117 int acpi_evindex;
118 
119 #define acpi_bus_space_map	_bus_space_map
120 #define acpi_bus_space_unmap	_bus_space_unmap
121 
122 #define pch(x) (((x)>=' ' && (x)<='z') ? (x) : ' ')
123 
124 #if 0
125 void
126 acpi_delay(struct acpi_softc *sc, int64_t uSecs)
127 {
128 	/* XXX this needs to become a tsleep later */
129 	delay(uSecs);
130 }
131 #endif
132 
133 int
134 acpi_gasio(struct acpi_softc *sc, int iodir, int iospace, uint64_t address,
135     int access_size, int len, void *buffer)
136 {
137 	u_int8_t *pb;
138 	bus_space_handle_t ioh;
139 	struct acpi_mem_map mh;
140 	pci_chipset_tag_t pc;
141 	pcitag_t tag;
142 	bus_addr_t ioaddr;
143 	int reg, idx, ival, sval;
144 
145 	dnprintf(50, "gasio: %.2x 0x%.8llx %s\n",
146 	    iospace, address, (iodir == ACPI_IOWRITE) ? "write" : "read");
147 
148 	pb = (u_int8_t *)buffer;
149 	switch (iospace) {
150 	case GAS_SYSTEM_MEMORY:
151 		/* copy to/from system memory */
152 		acpi_map(address, len, &mh);
153 		if (iodir == ACPI_IOREAD)
154 			memcpy(buffer, mh.va, len);
155 		else
156 			memcpy(mh.va, buffer, len);
157 		acpi_unmap(&mh);
158 		break;
159 
160 	case GAS_SYSTEM_IOSPACE:
161 		/* read/write from I/O registers */
162 		ioaddr = address;
163 		if (acpi_bus_space_map(sc->sc_iot, ioaddr, len, 0, &ioh) != 0) {
164 			printf("unable to map iospace\n");
165 			return (-1);
166 		}
167 		for (reg = 0; reg < len; reg += access_size) {
168 			if (iodir == ACPI_IOREAD) {
169 				switch (access_size) {
170 				case 1:
171 					*(uint8_t *)(pb+reg) = bus_space_read_1(
172 					    sc->sc_iot, ioh, reg);
173 					dnprintf(80, "os_in8(%llx) = %x\n",
174 					    reg+address, *(uint8_t *)(pb+reg));
175 					break;
176 				case 2:
177 					*(uint16_t *)(pb+reg) = bus_space_read_2(
178 					    sc->sc_iot, ioh, reg);
179 					dnprintf(80, "os_in16(%llx) = %x\n",
180 					    reg+address, *(uint16_t *)(pb+reg));
181 					break;
182 				case 4:
183 					*(uint32_t *)(pb+reg) = bus_space_read_4(
184 					    sc->sc_iot, ioh, reg);
185 					break;
186 				default:
187 					printf("rdio: invalid size %d\n", access_size);
188 					break;
189 				}
190 			} else {
191 				switch (access_size) {
192 				case 1:
193 					bus_space_write_1(sc->sc_iot, ioh, reg,
194 					    *(uint8_t *)(pb+reg));
195 					dnprintf(80, "os_out8(%llx,%x)\n",
196 					    reg+address, *(uint8_t *)(pb+reg));
197 					break;
198 				case 2:
199 					bus_space_write_2(sc->sc_iot, ioh, reg,
200 					    *(uint16_t *)(pb+reg));
201 					dnprintf(80, "os_out16(%llx,%x)\n",
202 					    reg+address, *(uint16_t *)(pb+reg));
203 					break;
204 				case 4:
205 					bus_space_write_4(sc->sc_iot, ioh, reg,
206 					    *(uint32_t *)(pb+reg));
207 					break;
208 				default:
209 					printf("wrio: invalid size %d\n", access_size);
210 					break;
211 				}
212 			}
213 
214 			/* During autoconf some devices are still gathering
215 			 * information.  Delay here to give them an opportunity
216 			 * to finish.  During runtime we simply need to ignore
217 			 * transient values.
218 			 */
219 			if (cold)
220 				delay(10000);
221 		}
222 		acpi_bus_space_unmap(sc->sc_iot, ioh, len, &ioaddr);
223 		break;
224 
225 	case GAS_PCI_CFG_SPACE:
226 		/* format of address:
227 		 *    bits 00..15 = register
228 		 *    bits 16..31 = function
229 		 *    bits 32..47 = device
230 		 *    bits 48..63 = bus
231 		 */
232 		pc = NULL;
233 		tag = pci_make_tag(pc,
234 		    ACPI_PCI_BUS(address), ACPI_PCI_DEV(address),
235 		    ACPI_PCI_FN(address));
236 
237 		/* XXX: This is ugly. read-modify-write does a byte at a time */
238 		reg = ACPI_PCI_REG(address);
239 		for (idx = reg; idx < reg+len; idx++) {
240 			ival = pci_conf_read(pc, tag, idx & ~0x3);
241 			if (iodir == ACPI_IOREAD) {
242 				*pb = ival >> (8 * (idx & 0x3));
243 			} else {
244 				sval = *pb;
245 				ival &= ~(0xFF << (8* (idx & 0x3)));
246 				ival |= sval << (8* (idx & 0x3));
247 				pci_conf_write(pc, tag, idx & ~0x3, ival);
248 			}
249 			pb++;
250 		}
251 		break;
252 	case GAS_EMBEDDED:
253 		if (sc->sc_ec == NULL)
254 			break;
255 #ifndef SMALL_KERNEL
256 		if (iodir == ACPI_IOREAD)
257 			acpiec_read(sc->sc_ec, (u_int8_t)address, len, buffer);
258 		else
259 			acpiec_write(sc->sc_ec, (u_int8_t)address, len, buffer);
260 #endif
261 		break;
262 	}
263 	return (0);
264 }
265 
266 int
267 acpi_inidev(struct aml_node *node, void *arg)
268 {
269 	struct acpi_softc	*sc = (struct acpi_softc *)arg;
270 	struct aml_value	res;
271 	int st = 0;
272 
273 	/* Default value */
274 	st = STA_PRESENT|STA_ENABLED;
275 	st |= STA_SHOW_UI|STA_DEV_OK;
276 	st |= STA_BATTERY;
277 
278 	/*
279 	 * Per the ACPI spec 6.5.1, only run _INI when device is there or
280 	 * when there is no _STA.  We terminate the tree walk (with return 1)
281 	 * early if necessary.
282 	 */
283 
284 	/* Evaluate _STA to decide _INI fate and walk fate */
285 	if (!aml_evalname(sc, node->parent, "_STA", 0, NULL, &res))
286 		st = (int)aml_val2int(&res);
287 	aml_freevalue(&res);
288 
289 	/* Evaluate _INI if we are present */
290 	if (st & STA_PRESENT)
291 		aml_evalnode(sc, node, 0, NULL, NULL);
292 
293 	/* If we are functioning, we walk/search our children */
294 	if(st & STA_DEV_OK)
295 		return 0;
296 
297 	/* If we are not enabled, or not present, terminate search */
298 	if (!(st & (STA_PRESENT|STA_ENABLED)))
299 		return 1;
300 
301 	/* Default just continue search */
302 	return 0;
303 }
304 
305 int
306 acpi_foundprt(struct aml_node *node, void *arg)
307 {
308 	struct acpi_softc	*sc = (struct acpi_softc *)arg;
309 	struct device		*self = (struct device *)arg;
310 	struct acpi_attach_args	aaa;
311 	struct aml_value	res;
312 	int st = 0;
313 
314 	dnprintf(10, "found prt entry: %s\n", node->parent->name);
315 
316 	/* Default value */
317 	st = STA_PRESENT|STA_ENABLED;
318 	st |= STA_SHOW_UI|STA_DEV_OK;
319 	st |= STA_BATTERY;
320 
321 	/* Evaluate _STA to decide _PRT fate and walk fate */
322 	if (!aml_evalname(sc, node->parent, "_STA", 0, NULL, &res))
323 		st = (int)aml_val2int(&res);
324 	aml_freevalue(&res);
325 
326 	if (st & STA_PRESENT) {
327 		memset(&aaa, 0, sizeof(aaa));
328 		aaa.aaa_iot = sc->sc_iot;
329 		aaa.aaa_memt = sc->sc_memt;
330 		aaa.aaa_node = node;
331 		aaa.aaa_name = "acpiprt";
332 
333 		config_found(self, &aaa, acpi_print);
334 	}
335 
336 	/* If we are functioning, we walk/search our children */
337 	if(st & STA_DEV_OK)
338 		return 0;
339 
340 	/* If we are not enabled, or not present, terminate search */
341 	if (!(st & (STA_PRESENT|STA_ENABLED)))
342 		return 1;
343 
344 	/* Default just continue search */
345 	return 0;
346 }
347 
348 int
349 acpi_match(struct device *parent, void *match, void *aux)
350 {
351 	struct bios_attach_args	*ba = aux;
352 	struct cfdata		*cf = match;
353 
354 	/* sanity */
355 	if (strcmp(ba->ba_name, cf->cf_driver->cd_name))
356 		return (0);
357 
358 	if (!acpi_probe(parent, cf, ba))
359 		return (0);
360 
361 	return (1);
362 }
363 
364 void
365 acpi_attach(struct device *parent, struct device *self, void *aux)
366 {
367 	struct bios_attach_args *ba = aux;
368 	struct acpi_softc *sc = (struct acpi_softc *)self;
369 	struct acpi_mem_map handle;
370 	struct acpi_rsdp *rsdp;
371 	struct acpi_q *entry;
372 	struct acpi_dsdt *p_dsdt;
373 	int idx;
374 #ifndef SMALL_KERNEL
375 	struct acpi_wakeq *wentry;
376 	struct device *dev;
377 	struct acpi_ac *ac;
378 	struct acpi_bat *bat;
379 #endif /* SMALL_KERNEL */
380 	paddr_t facspa;
381 
382 	sc->sc_iot = ba->ba_iot;
383 	sc->sc_memt = ba->ba_memt;
384 
385 	if (acpi_map(ba->ba_acpipbase, sizeof(struct acpi_rsdp), &handle)) {
386 		printf(": can't map memory\n");
387 		return;
388 	}
389 
390 	rsdp = (struct acpi_rsdp *)handle.va;
391 	sc->sc_revision = (int)rsdp->rsdp_revision;
392 	printf(": rev %d", sc->sc_revision);
393 
394 	SIMPLEQ_INIT(&sc->sc_tables);
395 	SIMPLEQ_INIT(&sc->sc_wakedevs);
396 
397 #ifndef SMALL_KERNEL
398 	sc->sc_note = malloc(sizeof(struct klist), M_DEVBUF, M_NOWAIT | M_ZERO);
399 	if (sc->sc_note == NULL) {
400 		printf(", can't allocate memory\n");
401 		acpi_unmap(&handle);
402 		return;
403 	}
404 #endif /* SMALL_KERNEL */
405 
406 	if (acpi_loadtables(sc, rsdp)) {
407 		printf(", can't load tables\n");
408 		acpi_unmap(&handle);
409 		return;
410 	}
411 
412 	acpi_unmap(&handle);
413 
414 	/*
415 	 * Find the FADT
416 	 */
417 	SIMPLEQ_FOREACH(entry, &sc->sc_tables, q_next) {
418 		if (memcmp(entry->q_table, FADT_SIG,
419 		    sizeof(FADT_SIG) - 1) == 0) {
420 			sc->sc_fadt = entry->q_table;
421 			break;
422 		}
423 	}
424 	if (sc->sc_fadt == NULL) {
425 		printf(", no FADT\n");
426 		return;
427 	}
428 
429 	/*
430 	 * Check if we are able to enable ACPI control
431 	 */
432 	if (!sc->sc_fadt->smi_cmd ||
433 	    (!sc->sc_fadt->acpi_enable && !sc->sc_fadt->acpi_disable)) {
434 		printf(", ACPI control unavailable\n");
435 		return;
436 	}
437 
438 	/*
439 	 * Set up a pointer to the firmware control structure
440 	 */
441 	if (sc->sc_fadt->hdr_revision < 3 || sc->sc_fadt->x_firmware_ctl == 0)
442 		facspa = sc->sc_fadt->firmware_ctl;
443 	else
444 		facspa = sc->sc_fadt->x_firmware_ctl;
445 
446 	if (acpi_map(facspa, sizeof(struct acpi_facs), &handle))
447 		printf(" !FACS");
448 	else
449 		sc->sc_facs = (struct acpi_facs *)handle.va;
450 
451 	acpi_enabled = 1;
452 
453 	/* Create opcode hashtable */
454 	aml_hashopcodes();
455 
456 	/* Create Default AML objects */
457 	aml_create_defaultobjects();
458 
459 	/*
460 	 * Load the DSDT from the FADT pointer -- use the
461 	 * extended (64-bit) pointer if it exists
462 	 */
463 	if (sc->sc_fadt->hdr_revision < 3 || sc->sc_fadt->x_dsdt == 0)
464 		acpi_load_dsdt(sc->sc_fadt->dsdt, &entry);
465 	else
466 		acpi_load_dsdt(sc->sc_fadt->x_dsdt, &entry);
467 
468 	if (entry == NULL)
469 		printf(" !DSDT");
470 	SIMPLEQ_INSERT_HEAD(&sc->sc_tables, entry, q_next);
471 
472 	p_dsdt = entry->q_table;
473 	acpi_parse_aml(sc, p_dsdt->aml, p_dsdt->hdr_length -
474 	    sizeof(p_dsdt->hdr));
475 
476 	/* Load SSDT's */
477 	SIMPLEQ_FOREACH(entry, &sc->sc_tables, q_next) {
478 		if (memcmp(entry->q_table, SSDT_SIG,
479 		    sizeof(SSDT_SIG) - 1) == 0) {
480 			p_dsdt = entry->q_table;
481 			acpi_parse_aml(sc, p_dsdt->aml, p_dsdt->hdr_length -
482 			    sizeof(p_dsdt->hdr));
483 		}
484 	}
485 
486 	/* Perform post-parsing fixups */
487 	aml_postparse();
488 
489 #ifndef SMALL_KERNEL
490 	/* Find available sleeping states */
491 	acpi_init_states(sc);
492 
493 	/* Find available sleep/resume related methods. */
494 	acpi_init_pm(sc);
495 #endif /* SMALL_KERNEL */
496 
497 	/* Map Power Management registers */
498 	acpi_map_pmregs(sc);
499 
500 #ifndef SMALL_KERNEL
501 	/* Initialize GPE handlers */
502 	acpi_init_gpes(sc);
503 
504 	/* some devices require periodic polling */
505 	timeout_set(&sc->sc_dev_timeout, acpi_poll, sc);
506 #endif /* SMALL_KERNEL */
507 
508 	/*
509 	 * Take over ACPI control.  Note that once we do this, we
510 	 * effectively tell the system that we have ownership of
511 	 * the ACPI hardware registers, and that SMI should leave
512 	 * them alone
513 	 *
514 	 * This may prevent thermal control on some systems where
515 	 * that actually does work
516 	 */
517 	acpi_write_pmreg(sc, ACPIREG_SMICMD, 0, sc->sc_fadt->acpi_enable);
518 	idx = 0;
519 	do {
520 		if (idx++ > ACPIEN_RETRIES) {
521 			printf(", can't enable ACPI\n");
522 			return;
523 		}
524 	} while (!(acpi_read_pmreg(sc, ACPIREG_PM1_CNT, 0) & ACPI_PM1_SCI_EN));
525 
526 	printf("\n%s: tables", DEVNAME(sc));
527 	SIMPLEQ_FOREACH(entry, &sc->sc_tables, q_next) {
528 		printf(" %.4s", entry->q_table);
529 	}
530 	printf("\n");
531 
532 #ifndef SMALL_KERNEL
533 	/* Display wakeup devices and lowest S-state */
534 	printf("%s: wakeup devices", DEVNAME(sc));
535 	SIMPLEQ_FOREACH(wentry, &sc->sc_wakedevs, q_next) {
536 		printf(" %.4s(S%d)", wentry->q_node->name,
537 		    wentry->q_state);
538 	}
539 	printf("\n");
540 
541 
542 	/*
543 	 * ACPI is enabled now -- attach timer
544 	 */
545 	{
546 		struct acpi_attach_args aaa;
547 
548 		memset(&aaa, 0, sizeof(aaa));
549 		aaa.aaa_name = "acpitimer";
550 		aaa.aaa_iot = sc->sc_iot;
551 		aaa.aaa_memt = sc->sc_memt;
552 #if 0
553 		aaa.aaa_pcit = sc->sc_pcit;
554 		aaa.aaa_smbust = sc->sc_smbust;
555 #endif
556 		config_found(self, &aaa, acpi_print);
557 	}
558 #endif /* SMALL_KERNEL */
559 
560 	/*
561 	 * Attach table-defined devices
562 	 */
563 	SIMPLEQ_FOREACH(entry, &sc->sc_tables, q_next) {
564 		struct acpi_attach_args aaa;
565 
566 		memset(&aaa, 0, sizeof(aaa));
567 		aaa.aaa_iot = sc->sc_iot;
568 		aaa.aaa_memt = sc->sc_memt;
569 	#if 0
570 		aaa.aaa_pcit = sc->sc_pcit;
571 		aaa.aaa_smbust = sc->sc_smbust;
572 	#endif
573 		aaa.aaa_table = entry->q_table;
574 		config_found_sm(self, &aaa, acpi_print, acpi_submatch);
575 	}
576 
577 	acpi_softc = sc;
578 
579 	/* initialize runtime environment */
580 	aml_find_node(&aml_root, "_INI", acpi_inidev, sc);
581 
582 	/* attach pci interrupt routing tables */
583 	aml_find_node(&aml_root, "_PRT", acpi_foundprt, sc);
584 
585 #ifndef SMALL_KERNEL
586 	 /* XXX EC needs to be attached first on some systems */
587 	aml_find_node(&aml_root, "_HID", acpi_foundec, sc);
588 
589 	aml_walknodes(&aml_root, AML_WALK_PRE, acpi_add_device, sc);
590 
591 	/* attach battery, power supply and button devices */
592 	aml_find_node(&aml_root, "_HID", acpi_foundhid, sc);
593 
594 	/* attach docks */
595 	aml_find_node(&aml_root, "_DCK", acpi_founddock, sc);
596 
597 	/* attach video */
598 	aml_find_node(&aml_root, "_DOS", acpi_foundvideo, sc);
599 
600 	/* create list of devices we want to query when APM come in */
601 	SLIST_INIT(&sc->sc_ac);
602 	SLIST_INIT(&sc->sc_bat);
603 	TAILQ_FOREACH(dev, &alldevs, dv_list) {
604 		if (!strncmp(dev->dv_xname, "acpiac", strlen("acpiac"))) {
605 			ac = malloc(sizeof(*ac), M_DEVBUF, M_WAITOK | M_ZERO);
606 			ac->aac_softc = (struct acpiac_softc *)dev;
607 			SLIST_INSERT_HEAD(&sc->sc_ac, ac, aac_link);
608 		}
609 		if (!strncmp(dev->dv_xname, "acpibat", strlen("acpibat"))) {
610 			bat = malloc(sizeof(*bat), M_DEVBUF, M_WAITOK | M_ZERO);
611 			bat->aba_softc = (struct acpibat_softc *)dev;
612 			SLIST_INSERT_HEAD(&sc->sc_bat, bat, aba_link);
613 		}
614 	}
615 
616 	/* Setup threads */
617 	sc->sc_thread = malloc(sizeof(struct acpi_thread), M_DEVBUF, M_WAITOK);
618 	sc->sc_thread->sc = sc;
619 	sc->sc_thread->running = 1;
620 
621 	acpi_attach_machdep(sc);
622 
623 	kthread_create_deferred(acpi_create_thread, sc);
624 #endif /* SMALL_KERNEL */
625 }
626 
627 int
628 acpi_submatch(struct device *parent, void *match, void *aux)
629 {
630 	struct acpi_attach_args *aaa = (struct acpi_attach_args *)aux;
631 	struct cfdata *cf = match;
632 
633 	if (aaa->aaa_table == NULL)
634 		return (0);
635 	return ((*cf->cf_attach->ca_match)(parent, match, aux));
636 }
637 
638 int
639 acpi_print(void *aux, const char *pnp)
640 {
641 	struct acpi_attach_args *aa = aux;
642 
643 	if (pnp) {
644 		if (aa->aaa_name)
645 			printf("%s at %s", aa->aaa_name, pnp);
646 		else
647 			return (QUIET);
648 	}
649 
650 	return (UNCONF);
651 }
652 
653 int
654 acpi_loadtables(struct acpi_softc *sc, struct acpi_rsdp *rsdp)
655 {
656 	struct acpi_mem_map hrsdt, handle;
657 	struct acpi_table_header *hdr;
658 	int i, ntables;
659 	size_t len;
660 
661 	if (rsdp->rsdp_revision == 2) {
662 		struct acpi_xsdt *xsdt;
663 
664 		if (acpi_map(rsdp->rsdp_xsdt, sizeof(*hdr), &handle)) {
665 			printf("couldn't map rsdt\n");
666 			return (ENOMEM);
667 		}
668 
669 		hdr = (struct acpi_table_header *)handle.va;
670 		len = hdr->length;
671 		acpi_unmap(&handle);
672 		hdr = NULL;
673 
674 		acpi_map(rsdp->rsdp_xsdt, len, &hrsdt);
675 		xsdt = (struct acpi_xsdt *)hrsdt.va;
676 
677 		ntables = (len - sizeof(struct acpi_table_header)) /
678 		    sizeof(xsdt->table_offsets[0]);
679 
680 		for (i = 0; i < ntables; i++) {
681 			acpi_map(xsdt->table_offsets[i], sizeof(*hdr), &handle);
682 			hdr = (struct acpi_table_header *)handle.va;
683 			acpi_load_table(xsdt->table_offsets[i], hdr->length,
684 			    &sc->sc_tables);
685 			acpi_unmap(&handle);
686 		}
687 		acpi_unmap(&hrsdt);
688 	} else {
689 		struct acpi_rsdt *rsdt;
690 
691 		if (acpi_map(rsdp->rsdp_rsdt, sizeof(*hdr), &handle)) {
692 			printf("couldn't map rsdt\n");
693 			return (ENOMEM);
694 		}
695 
696 		hdr = (struct acpi_table_header *)handle.va;
697 		len = hdr->length;
698 		acpi_unmap(&handle);
699 		hdr = NULL;
700 
701 		acpi_map(rsdp->rsdp_rsdt, len, &hrsdt);
702 		rsdt = (struct acpi_rsdt *)hrsdt.va;
703 
704 		ntables = (len - sizeof(struct acpi_table_header)) /
705 		    sizeof(rsdt->table_offsets[0]);
706 
707 		for (i = 0; i < ntables; i++) {
708 			acpi_map(rsdt->table_offsets[i], sizeof(*hdr), &handle);
709 			hdr = (struct acpi_table_header *)handle.va;
710 			acpi_load_table(rsdt->table_offsets[i], hdr->length,
711 			    &sc->sc_tables);
712 			acpi_unmap(&handle);
713 		}
714 		acpi_unmap(&hrsdt);
715 	}
716 
717 	return (0);
718 }
719 
720 void
721 acpi_load_table(paddr_t pa, size_t len, acpi_qhead_t *queue)
722 {
723 	struct acpi_mem_map handle;
724 	struct acpi_q *entry;
725 
726 	entry = malloc(len + sizeof(struct acpi_q), M_DEVBUF, M_NOWAIT);
727 
728 	if (entry != NULL) {
729 		if (acpi_map(pa, len, &handle)) {
730 			free(entry, M_DEVBUF);
731 			return;
732 		}
733 		memcpy(entry->q_data, handle.va, len);
734 		entry->q_table = entry->q_data;
735 		acpi_unmap(&handle);
736 		SIMPLEQ_INSERT_TAIL(queue, entry, q_next);
737 	}
738 }
739 
740 void
741 acpi_load_dsdt(paddr_t pa, struct acpi_q **dsdt)
742 {
743 	struct acpi_mem_map handle;
744 	struct acpi_table_header *hdr;
745 	size_t len;
746 
747 	if (acpi_map(pa, sizeof(*hdr), &handle))
748 		return;
749 	hdr = (struct acpi_table_header *)handle.va;
750 	len = hdr->length;
751 	acpi_unmap(&handle);
752 
753 	*dsdt = malloc(len + sizeof(struct acpi_q), M_DEVBUF, M_NOWAIT);
754 
755 	if (*dsdt != NULL) {
756 		if (acpi_map(pa, len, &handle)) {
757 			free(*dsdt, M_DEVBUF);
758 			*dsdt = NULL;
759 			return;
760 		}
761 		memcpy((*dsdt)->q_data, handle.va, len);
762 		(*dsdt)->q_table = (*dsdt)->q_data;
763 		acpi_unmap(&handle);
764 	}
765 }
766 
767 int
768 acpiopen(dev_t dev, int flag, int mode, struct proc *p)
769 {
770 	int error = 0;
771 #ifndef SMALL_KERNEL
772 	struct acpi_softc *sc;
773 
774 	if (!acpi_cd.cd_ndevs || APMUNIT(dev) != 0 ||
775 	    !(sc = acpi_cd.cd_devs[APMUNIT(dev)]))
776 		return (ENXIO);
777 
778 	switch (APMDEV(dev)) {
779 	case APMDEV_CTL:
780 		if (!(flag & FWRITE)) {
781 			error = EINVAL;
782 			break;
783 		}
784 		break;
785 	case APMDEV_NORMAL:
786 		if (!(flag & FREAD) || (flag & FWRITE)) {
787 			error = EINVAL;
788 			break;
789 		}
790 		break;
791 	default:
792 		error = ENXIO;
793 		break;
794 	}
795 #else
796 	error = ENXIO;
797 #endif
798 	return (error);
799 }
800 
801 int
802 acpiclose(dev_t dev, int flag, int mode, struct proc *p)
803 {
804 	int error = 0;
805 #ifndef SMALL_KERNEL
806 	struct acpi_softc *sc;
807 
808 	if (!acpi_cd.cd_ndevs || APMUNIT(dev) != 0 ||
809 	    !(sc = acpi_cd.cd_devs[APMUNIT(dev)]))
810 		return (ENXIO);
811 	switch (APMDEV(dev)) {
812 	case APMDEV_CTL:
813 	case APMDEV_NORMAL:
814 		break;
815 	default:
816 		error = ENXIO;
817 		break;
818 	}
819 #else
820 	error = ENXIO;
821 #endif
822 	return (error);
823 }
824 
825 int
826 acpiioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
827 {
828 	int error = 0;
829 #ifndef SMALL_KERNEL
830 	struct acpi_softc *sc;
831 	struct acpi_ac *ac;
832 	struct acpi_bat *bat;
833 	struct apm_power_info *pi = (struct apm_power_info *)data;
834 	int bats;
835 	unsigned int remaining, rem, minutes, rate;
836 
837 	if (!acpi_cd.cd_ndevs || APMUNIT(dev) != 0 ||
838 	    !(sc = acpi_cd.cd_devs[APMUNIT(dev)]))
839 		return (ENXIO);
840 
841 	ACPI_LOCK(sc);
842 	/* fake APM */
843 	switch (cmd) {
844 	case APM_IOC_GETPOWER:
845 		/* A/C */
846 		pi->ac_state = APM_AC_UNKNOWN;
847 		SLIST_FOREACH(ac, &sc->sc_ac, aac_link) {
848 			if (ac->aac_softc->sc_ac_stat == PSR_ONLINE)
849 				pi->ac_state = APM_AC_ON;
850 			else if (ac->aac_softc->sc_ac_stat == PSR_OFFLINE)
851 				if (pi->ac_state == APM_AC_UNKNOWN)
852 					pi->ac_state = APM_AC_OFF;
853 		}
854 
855 		/* battery */
856 		pi->battery_state = APM_BATT_UNKNOWN;
857 		pi->battery_life = 0;
858 		pi->minutes_left = 0;
859 		bats = 0;
860 		remaining = rem = 0;
861 		minutes = 0;
862 		rate = 0;
863 		SLIST_FOREACH(bat, &sc->sc_bat, aba_link) {
864 			if (bat->aba_softc->sc_bat_present == 0)
865 				continue;
866 
867 			if (bat->aba_softc->sc_bif.bif_last_capacity == 0)
868 				continue;
869 
870 			bats++;
871 			rem = (bat->aba_softc->sc_bst.bst_capacity * 100) /
872 			    bat->aba_softc->sc_bif.bif_last_capacity;
873 			if (rem > 100)
874 				rem = 100;
875 			remaining += rem;
876 
877 			if (bat->aba_softc->sc_bst.bst_rate == BST_UNKNOWN)
878 				continue;
879 			else if (bat->aba_softc->sc_bst.bst_rate > 1)
880 				rate = bat->aba_softc->sc_bst.bst_rate;
881 
882 			minutes += bat->aba_softc->sc_bst.bst_capacity;
883 		}
884 
885 		if (bats == 0) {
886 			pi->battery_state = APM_BATTERY_ABSENT;
887 			pi->battery_life = 0;
888 			pi->minutes_left = (unsigned int)-1;
889 			break;
890 		}
891 
892 		if (pi->ac_state == APM_AC_ON || rate == 0)
893 			pi->minutes_left = (unsigned int)-1;
894 		else
895 			pi->minutes_left = 100 * minutes / rate;
896 
897 		/* running on battery */
898 		pi->battery_life = remaining / bats;
899 		if (pi->battery_life > 50)
900 			pi->battery_state = APM_BATT_HIGH;
901 		else if (pi->battery_life > 25)
902 			pi->battery_state = APM_BATT_LOW;
903 		else
904 			pi->battery_state = APM_BATT_CRITICAL;
905 
906 		break;
907 
908 	default:
909 		error = ENOTTY;
910 	}
911 
912 	ACPI_UNLOCK(sc);
913 #else
914 	error = ENXIO;
915 #endif /* SMALL_KERNEL */
916 	return (error);
917 }
918 
919 void
920 acpi_filtdetach(struct knote *kn)
921 {
922 #ifndef SMALL_KERNEL
923 	struct acpi_softc *sc = kn->kn_hook;
924 
925 	ACPI_LOCK(sc);
926 	SLIST_REMOVE(sc->sc_note, kn, knote, kn_selnext);
927 	ACPI_UNLOCK(sc);
928 #endif
929 }
930 
931 int
932 acpi_filtread(struct knote *kn, long hint)
933 {
934 #ifndef SMALL_KERNEL
935 	/* XXX weird kqueue_scan() semantics */
936 	if (hint & !kn->kn_data)
937 		kn->kn_data = hint;
938 #endif
939 	return (1);
940 }
941 
942 int
943 acpikqfilter(dev_t dev, struct knote *kn)
944 {
945 #ifndef SMALL_KERNEL
946 	struct acpi_softc *sc;
947 
948 	if (!acpi_cd.cd_ndevs || APMUNIT(dev) != 0 ||
949 	    !(sc = acpi_cd.cd_devs[APMUNIT(dev)]))
950 		return (ENXIO);
951 
952 	switch (kn->kn_filter) {
953 	case EVFILT_READ:
954 		kn->kn_fop = &acpiread_filtops;
955 		break;
956 	default:
957 		return (1);
958 	}
959 
960 	kn->kn_hook = sc;
961 
962 	ACPI_LOCK(sc);
963 	SLIST_INSERT_HEAD(sc->sc_note, kn, kn_selnext);
964 	ACPI_UNLOCK(sc);
965 
966 	return (0);
967 #else
968 	return (1);
969 #endif
970 }
971 
972 /* Read from power management register */
973 int
974 acpi_read_pmreg(struct acpi_softc *sc, int reg, int offset)
975 {
976 	bus_space_handle_t ioh;
977 	bus_size_t size, __size;
978 	int regval;
979 
980 	__size = 0;
981 	/* Special cases: 1A/1B blocks can be OR'ed together */
982 	switch (reg) {
983 	case ACPIREG_PM1_EN:
984 		return (acpi_read_pmreg(sc, ACPIREG_PM1A_EN, offset) |
985 		    acpi_read_pmreg(sc, ACPIREG_PM1B_EN, offset));
986 	case ACPIREG_PM1_STS:
987 		return (acpi_read_pmreg(sc, ACPIREG_PM1A_STS, offset) |
988 		    acpi_read_pmreg(sc, ACPIREG_PM1B_STS, offset));
989 	case ACPIREG_PM1_CNT:
990 		return (acpi_read_pmreg(sc, ACPIREG_PM1A_CNT, offset) |
991 		    acpi_read_pmreg(sc, ACPIREG_PM1B_CNT, offset));
992 	case ACPIREG_GPE_STS:
993 		__size = 1;
994 		dnprintf(50, "read GPE_STS  offset: %.2x %.2x %.2x\n", offset,
995 		    sc->sc_fadt->gpe0_blk_len>>1, sc->sc_fadt->gpe1_blk_len>>1);
996 		if (offset < (sc->sc_fadt->gpe0_blk_len >> 1)) {
997 			reg = ACPIREG_GPE0_STS;
998 		}
999 		break;
1000 	case ACPIREG_GPE_EN:
1001 		__size = 1;
1002 		dnprintf(50, "read GPE_EN   offset: %.2x %.2x %.2x\n",
1003 		    offset, sc->sc_fadt->gpe0_blk_len>>1,
1004 		    sc->sc_fadt->gpe1_blk_len>>1);
1005 		if (offset < (sc->sc_fadt->gpe0_blk_len >> 1)) {
1006 			reg = ACPIREG_GPE0_EN;
1007 		}
1008 		break;
1009 	}
1010 
1011 	if (reg >= ACPIREG_MAXREG || sc->sc_pmregs[reg].size == 0)
1012 		return (0);
1013 
1014 	regval = 0;
1015 	ioh = sc->sc_pmregs[reg].ioh;
1016 	size = sc->sc_pmregs[reg].size;
1017 	if (__size)
1018 		size = __size;
1019 	if (size > 4)
1020 		size = 4;
1021 
1022 	switch (size) {
1023 	case 1:
1024 		regval = bus_space_read_1(sc->sc_iot, ioh, offset);
1025 		break;
1026 	case 2:
1027 		regval = bus_space_read_2(sc->sc_iot, ioh, offset);
1028 		break;
1029 	case 4:
1030 		regval = bus_space_read_4(sc->sc_iot, ioh, offset);
1031 		break;
1032 	}
1033 
1034 	dnprintf(30, "acpi_readpm: %s = %.4x:%.4x %x\n",
1035 	    sc->sc_pmregs[reg].name,
1036 	    sc->sc_pmregs[reg].addr, offset, regval);
1037 	return (regval);
1038 }
1039 
1040 /* Write to power management register */
1041 void
1042 acpi_write_pmreg(struct acpi_softc *sc, int reg, int offset, int regval)
1043 {
1044 	bus_space_handle_t ioh;
1045 	bus_size_t size, __size;
1046 
1047 	__size = 0;
1048 	/* Special cases: 1A/1B blocks can be written with same value */
1049 	switch (reg) {
1050 	case ACPIREG_PM1_EN:
1051 		acpi_write_pmreg(sc, ACPIREG_PM1A_EN, offset, regval);
1052 		acpi_write_pmreg(sc, ACPIREG_PM1B_EN, offset, regval);
1053 		break;
1054 	case ACPIREG_PM1_STS:
1055 		acpi_write_pmreg(sc, ACPIREG_PM1A_STS, offset, regval);
1056 		acpi_write_pmreg(sc, ACPIREG_PM1B_STS, offset, regval);
1057 		break;
1058 	case ACPIREG_PM1_CNT:
1059 		acpi_write_pmreg(sc, ACPIREG_PM1A_CNT, offset, regval);
1060 		acpi_write_pmreg(sc, ACPIREG_PM1B_CNT, offset, regval);
1061 		break;
1062 	case ACPIREG_GPE_STS:
1063 		__size = 1;
1064 		dnprintf(50, "write GPE_STS offset: %.2x %.2x %.2x %.2x\n",
1065 		    offset, sc->sc_fadt->gpe0_blk_len>>1,
1066 		    sc->sc_fadt->gpe1_blk_len>>1, regval);
1067 		if (offset < (sc->sc_fadt->gpe0_blk_len >> 1)) {
1068 			reg = ACPIREG_GPE0_STS;
1069 		}
1070 		break;
1071 	case ACPIREG_GPE_EN:
1072 		__size = 1;
1073 		dnprintf(50, "write GPE_EN  offset: %.2x %.2x %.2x %.2x\n",
1074 		    offset, sc->sc_fadt->gpe0_blk_len>>1,
1075 		    sc->sc_fadt->gpe1_blk_len>>1, regval);
1076 		if (offset < (sc->sc_fadt->gpe0_blk_len >> 1)) {
1077 			reg = ACPIREG_GPE0_EN;
1078 		}
1079 		break;
1080 	}
1081 
1082 	/* All special case return here */
1083 	if (reg >= ACPIREG_MAXREG)
1084 		return;
1085 
1086 	ioh = sc->sc_pmregs[reg].ioh;
1087 	size = sc->sc_pmregs[reg].size;
1088 	if (__size)
1089 		size = __size;
1090 	if (size > 4)
1091 		size = 4;
1092 	switch (size) {
1093 	case 1:
1094 		bus_space_write_1(sc->sc_iot, ioh, offset, regval);
1095 		break;
1096 	case 2:
1097 		bus_space_write_2(sc->sc_iot, ioh, offset, regval);
1098 		break;
1099 	case 4:
1100 		bus_space_write_4(sc->sc_iot, ioh, offset, regval);
1101 		break;
1102 	}
1103 
1104 	dnprintf(30, "acpi_writepm: %s = %.4x:%.4x %x\n",
1105 	    sc->sc_pmregs[reg].name, sc->sc_pmregs[reg].addr, offset, regval);
1106 }
1107 
1108 /* Map Power Management registers */
1109 void
1110 acpi_map_pmregs(struct acpi_softc *sc)
1111 {
1112 	bus_addr_t addr;
1113 	bus_size_t size;
1114 	const char *name;
1115 	int reg;
1116 
1117 	for (reg = 0; reg < ACPIREG_MAXREG; reg++) {
1118 		size = 0;
1119 		switch (reg) {
1120 		case ACPIREG_SMICMD:
1121 			name = "smi";
1122 			size = 1;
1123 			addr = sc->sc_fadt->smi_cmd;
1124 			break;
1125 		case ACPIREG_PM1A_STS:
1126 		case ACPIREG_PM1A_EN:
1127 			name = "pm1a_sts";
1128 			size = sc->sc_fadt->pm1_evt_len >> 1;
1129 			addr = sc->sc_fadt->pm1a_evt_blk;
1130 			if (reg == ACPIREG_PM1A_EN && addr) {
1131 				addr += size;
1132 				name = "pm1a_en";
1133 			}
1134 			break;
1135 		case ACPIREG_PM1A_CNT:
1136 			name = "pm1a_cnt";
1137 			size = sc->sc_fadt->pm1_cnt_len;
1138 			addr = sc->sc_fadt->pm1a_cnt_blk;
1139 			break;
1140 		case ACPIREG_PM1B_STS:
1141 		case ACPIREG_PM1B_EN:
1142 			name = "pm1b_sts";
1143 			size = sc->sc_fadt->pm1_evt_len >> 1;
1144 			addr = sc->sc_fadt->pm1b_evt_blk;
1145 			if (reg == ACPIREG_PM1B_EN && addr) {
1146 				addr += size;
1147 				name = "pm1b_en";
1148 			}
1149 			break;
1150 		case ACPIREG_PM1B_CNT:
1151 			name = "pm1b_cnt";
1152 			size = sc->sc_fadt->pm1_cnt_len;
1153 			addr = sc->sc_fadt->pm1b_cnt_blk;
1154 			break;
1155 		case ACPIREG_PM2_CNT:
1156 			name = "pm2_cnt";
1157 			size = sc->sc_fadt->pm2_cnt_len;
1158 			addr = sc->sc_fadt->pm2_cnt_blk;
1159 			break;
1160 #if 0
1161 		case ACPIREG_PM_TMR:
1162 			/* Allocated in acpitimer */
1163 			name = "pm_tmr";
1164 			size = sc->sc_fadt->pm_tmr_len;
1165 			addr = sc->sc_fadt->pm_tmr_blk;
1166 			break;
1167 #endif
1168 		case ACPIREG_GPE0_STS:
1169 		case ACPIREG_GPE0_EN:
1170 			name = "gpe0_sts";
1171 			size = sc->sc_fadt->gpe0_blk_len >> 1;
1172 			addr = sc->sc_fadt->gpe0_blk;
1173 
1174 			dnprintf(20, "gpe0 block len : %x\n",
1175 			    sc->sc_fadt->gpe0_blk_len >> 1);
1176 			dnprintf(20, "gpe0 block addr: %x\n",
1177 			    sc->sc_fadt->gpe0_blk);
1178 			if (reg == ACPIREG_GPE0_EN && addr) {
1179 				addr += size;
1180 				name = "gpe0_en";
1181 			}
1182 			break;
1183 		case ACPIREG_GPE1_STS:
1184 		case ACPIREG_GPE1_EN:
1185 			name = "gpe1_sts";
1186 			size = sc->sc_fadt->gpe1_blk_len >> 1;
1187 			addr = sc->sc_fadt->gpe1_blk;
1188 
1189 			dnprintf(20, "gpe1 block len : %x\n",
1190 			    sc->sc_fadt->gpe1_blk_len >> 1);
1191 			dnprintf(20, "gpe1 block addr: %x\n",
1192 			    sc->sc_fadt->gpe1_blk);
1193 			if (reg == ACPIREG_GPE1_EN && addr) {
1194 				addr += size;
1195 				name = "gpe1_en";
1196 			}
1197 			break;
1198 		}
1199 		if (size && addr) {
1200 			dnprintf(50, "mapping: %.4x %.4x %s\n",
1201 			    addr, size, name);
1202 
1203 			/* Size and address exist; map register space */
1204 			bus_space_map(sc->sc_iot, addr, size, 0,
1205 			    &sc->sc_pmregs[reg].ioh);
1206 
1207 			sc->sc_pmregs[reg].name = name;
1208 			sc->sc_pmregs[reg].size = size;
1209 			sc->sc_pmregs[reg].addr = addr;
1210 		}
1211 	}
1212 }
1213 
1214 /* move all stuff that doesn't go on the boot media in here */
1215 #ifndef SMALL_KERNEL
1216 void
1217 acpi_reset(void)
1218 {
1219 	struct acpi_fadt	*fadt;
1220 	u_int32_t		 reset_as, reset_len;
1221 	u_int32_t		 value;
1222 
1223 	fadt = acpi_softc->sc_fadt;
1224 
1225 	/*
1226 	 * RESET_REG_SUP is not properly set in some implementations,
1227 	 * but not testing against it breaks more machines than it fixes
1228 	 */
1229 	if (acpi_softc->sc_revision <= 1 ||
1230 	    !(fadt->flags & FADT_RESET_REG_SUP) || fadt->reset_reg.address == 0)
1231 		return;
1232 
1233 	value = fadt->reset_value;
1234 
1235 	reset_as = fadt->reset_reg.register_bit_width / 8;
1236 	if (reset_as == 0)
1237 		reset_as = 1;
1238 
1239 	reset_len = fadt->reset_reg.access_size;
1240 	if (reset_len == 0)
1241 		reset_len = reset_as;
1242 
1243 	acpi_gasio(acpi_softc, ACPI_IOWRITE,
1244 	    fadt->reset_reg.address_space_id,
1245 	    fadt->reset_reg.address, reset_as, reset_len, &value);
1246 
1247 	delay(100000);
1248 }
1249 
1250 int
1251 acpi_interrupt(void *arg)
1252 {
1253 	struct acpi_softc *sc = (struct acpi_softc *)arg;
1254 	u_int32_t processed, sts, en, idx, jdx;
1255 
1256 	processed = 0;
1257 
1258 #if 0
1259 	acpi_add_gpeblock(sc, sc->sc_fadt->gpe0_blk, sc->sc_fadt->gpe0_blk_len>>1, 0);
1260 	acpi_add_gpeblock(sc, sc->sc_fadt->gpe1_blk, sc->sc_fadt->gpe1_blk_len>>1,
1261 	    sc->sc_fadt->gpe1_base);
1262 #endif
1263 
1264 	dnprintf(40, "ACPI Interrupt\n");
1265 	for (idx = 0; idx < sc->sc_lastgpe; idx += 8) {
1266 		sts = acpi_read_pmreg(sc, ACPIREG_GPE_STS, idx>>3);
1267 		en  = acpi_read_pmreg(sc, ACPIREG_GPE_EN,  idx>>3);
1268 		if (en & sts) {
1269 			dnprintf(10, "GPE block: %.2x %.2x %.2x\n", idx, sts,
1270 			    en);
1271 			acpi_write_pmreg(sc, ACPIREG_GPE_EN, idx>>3, en & ~sts);
1272 			for (jdx = 0; jdx < 8; jdx++) {
1273 				if (en & sts & (1L << jdx)) {
1274 					/* Signal this GPE */
1275 					sc->gpe_table[idx+jdx].active = 1;
1276 					processed = 1;
1277 				}
1278 			}
1279 		}
1280 	}
1281 
1282 	sts = acpi_read_pmreg(sc, ACPIREG_PM1_STS, 0);
1283 	en  = acpi_read_pmreg(sc, ACPIREG_PM1_EN, 0);
1284 	if (sts & en) {
1285 		dnprintf(10,"GEN interrupt: %.4x\n", sts & en);
1286 		acpi_write_pmreg(sc, ACPIREG_PM1_EN, 0, en & ~sts);
1287 		acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0, en);
1288 		acpi_write_pmreg(sc, ACPIREG_PM1_EN, 0, en);
1289 		if (sts & ACPI_PM1_PWRBTN_STS)
1290 			sc->sc_powerbtn = 1;
1291 		if (sts & ACPI_PM1_SLPBTN_STS)
1292 			sc->sc_sleepbtn = 1;
1293 		processed = 1;
1294 	}
1295 
1296 	if (processed) {
1297 		sc->sc_wakeup = 0;
1298 		wakeup(sc);
1299 	}
1300 
1301 	return (processed);
1302 }
1303 
1304 int
1305 acpi_add_device(struct aml_node *node, void *arg)
1306 {
1307 	static int nacpicpus = 0;
1308 	struct device *self = arg;
1309 	struct acpi_softc *sc = arg;
1310 	struct acpi_attach_args aaa;
1311 #ifdef MULTIPROCESSOR
1312 	struct aml_value res;
1313 	int proc_id = -1;
1314 #endif
1315 
1316 	memset(&aaa, 0, sizeof(aaa));
1317 	aaa.aaa_node = node;
1318 	aaa.aaa_iot = sc->sc_iot;
1319 	aaa.aaa_memt = sc->sc_memt;
1320 	if (node == NULL || node->value == NULL)
1321 		return 0;
1322 
1323 	switch (node->value->type) {
1324 	case AML_OBJTYPE_PROCESSOR:
1325 		if (nacpicpus >= ncpus)
1326 			return 0;
1327 #ifdef MULTIPROCESSOR
1328 		if (aml_evalnode(sc, aaa.aaa_node, 0, NULL, &res) == 0) {
1329 			if (res.type == AML_OBJTYPE_PROCESSOR)
1330 				proc_id = res.v_processor.proc_id;
1331 			aml_freevalue(&res);
1332 		}
1333 		if (proc_id < -1 || proc_id >= LAPIC_MAP_SIZE ||
1334 		    (acpi_lapic_flags[proc_id] & ACPI_PROC_ENABLE) == 0)
1335 			return 0;
1336 #endif
1337 		nacpicpus++;
1338 
1339 		aaa.aaa_name = "acpicpu";
1340 		break;
1341 	case AML_OBJTYPE_THERMZONE:
1342 		aaa.aaa_name = "acpitz";
1343 		break;
1344 	default:
1345 		return 0;
1346 	}
1347 	config_found(self, &aaa, acpi_print);
1348 	return 0;
1349 }
1350 
1351 void
1352 acpi_enable_onegpe(struct acpi_softc *sc, int gpe, int enable)
1353 {
1354 	uint8_t mask = (1L << (gpe & 7));
1355 	uint8_t en;
1356 
1357 	/* Read enabled register */
1358 	en = acpi_read_pmreg(sc, ACPIREG_GPE_EN, gpe>>3);
1359 	dnprintf(50, "%sabling GPE %.2x (current: %sabled) %.2x\n",
1360 	    enable ? "en" : "dis", gpe, (en & mask) ? "en" : "dis", en);
1361 	if (enable)
1362 		en |= mask;
1363 	else
1364 		en &= ~mask;
1365 	acpi_write_pmreg(sc, ACPIREG_GPE_EN, gpe>>3, en);
1366 }
1367 
1368 int
1369 acpi_set_gpehandler(struct acpi_softc *sc, int gpe, int (*handler)
1370     (struct acpi_softc *, int, void *), void *arg, const char *label)
1371 {
1372 	struct gpe_block *ptbl;
1373 
1374 	ptbl = acpi_find_gpe(sc, gpe);
1375 	if (ptbl == NULL || handler == NULL)
1376 		return -EINVAL;
1377 	if (ptbl->handler != NULL) {
1378 		dnprintf(10, "error: GPE %.2x already enabled\n", gpe);
1379 		return -EBUSY;
1380 	}
1381 	dnprintf(50, "Adding GPE handler %.2x (%s)\n", gpe, label);
1382 	ptbl->handler = handler;
1383 	ptbl->arg = arg;
1384 
1385 	return (0);
1386 }
1387 
1388 int
1389 acpi_gpe_level(struct acpi_softc *sc, int gpe, void *arg)
1390 {
1391 	struct aml_node *node = arg;
1392 	uint8_t mask;
1393 
1394 	dnprintf(10, "handling Level-sensitive GPE %.2x\n", gpe);
1395 	mask = (1L << (gpe & 7));
1396 
1397 	aml_evalnode(sc, node, 0, NULL, NULL);
1398 	acpi_write_pmreg(sc, ACPIREG_GPE_STS, gpe>>3, mask);
1399 	acpi_write_pmreg(sc, ACPIREG_GPE_EN,  gpe>>3, mask);
1400 
1401 	return (0);
1402 }
1403 
1404 int
1405 acpi_gpe_edge(struct acpi_softc *sc, int gpe, void *arg)
1406 {
1407 
1408 	struct aml_node *node = arg;
1409 	uint8_t mask;
1410 
1411 	dnprintf(10, "handling Edge-sensitive GPE %.2x\n", gpe);
1412 	mask = (1L << (gpe & 7));
1413 
1414 	aml_evalnode(sc, node, 0, NULL, NULL);
1415 	acpi_write_pmreg(sc, ACPIREG_GPE_STS, gpe>>3, mask);
1416 	acpi_write_pmreg(sc, ACPIREG_GPE_EN,  gpe>>3, mask);
1417 
1418 	return (0);
1419 }
1420 
1421 /* Discover Devices that can wakeup the system
1422  * _PRW returns a package
1423  *  pkg[0] = integer (FADT gpe bit) or package (gpe block,gpe bit)
1424  *  pkg[1] = lowest sleep state
1425  *  pkg[2+] = power resource devices (optional)
1426  *
1427  * To enable wakeup devices:
1428  *    Evaluate _ON method in each power resource device
1429  *    Evaluate _PSW method
1430  */
1431 int
1432 acpi_foundprw(struct aml_node *node, void *arg)
1433 {
1434 	struct acpi_softc *sc = arg;
1435 	struct acpi_wakeq *wq;
1436 
1437 	wq = (struct acpi_wakeq *)malloc(sizeof(struct acpi_wakeq), M_DEVBUF, M_NOWAIT);
1438 	if (wq == NULL) {
1439 		return 0;
1440 	}
1441 	memset(wq, 0, sizeof(struct acpi_wakeq));
1442 
1443 	wq->q_wakepkg = (struct aml_value *)malloc(sizeof(struct aml_value),
1444 	    M_DEVBUF, M_NOWAIT);
1445 	if (wq->q_wakepkg == NULL) {
1446 		free(wq, M_DEVBUF);
1447 		return 0;
1448 	}
1449 	memset(wq->q_wakepkg, 0, sizeof(struct aml_value));
1450 	dnprintf(10, "Found _PRW (%s)\n", node->parent->name);
1451 	aml_evalnode(sc, node, 0, NULL, wq->q_wakepkg);
1452 	wq->q_node = node->parent;
1453 	wq->q_gpe = -1;
1454 
1455 	/* Get GPE of wakeup device, and lowest sleep level */
1456 	if (wq->q_wakepkg->type == AML_OBJTYPE_PACKAGE && wq->q_wakepkg->length >= 2) {
1457 	  if (wq->q_wakepkg->v_package[0]->type == AML_OBJTYPE_INTEGER) {
1458 	    wq->q_gpe = wq->q_wakepkg->v_package[0]->v_integer;
1459 	  }
1460 	  if (wq->q_wakepkg->v_package[1]->type == AML_OBJTYPE_INTEGER) {
1461 	    wq->q_state = wq->q_wakepkg->v_package[1]->v_integer;
1462 	  }
1463 	}
1464 	SIMPLEQ_INSERT_TAIL(&sc->sc_wakedevs, wq, q_next);
1465 	return 0;
1466 }
1467 
1468 struct gpe_block *
1469 acpi_find_gpe(struct acpi_softc *sc, int gpe)
1470 {
1471 #if 1
1472 	if (gpe >= sc->sc_lastgpe)
1473 		return NULL;
1474 	return &sc->gpe_table[gpe];
1475 #else
1476 	SIMPLEQ_FOREACH(pgpe, &sc->sc_gpes, gpe_link) {
1477 		if (gpe >= pgpe->start && gpe <= (pgpe->start+7))
1478 			return &pgpe->table[gpe & 7];
1479 	}
1480 	return NULL;
1481 #endif
1482 }
1483 
1484 #if 0
1485 /* New GPE handling code: Create GPE block */
1486 void
1487 acpi_init_gpeblock(struct acpi_softc *sc, int reg, int len, int base)
1488 {
1489 	int i, j;
1490 
1491 	if (!reg || !len)
1492 		return;
1493 	for (i=0; i<len; i++) {
1494 		pgpe = acpi_os_malloc(sizeof(gpeblock));
1495 		if (pgpe == NULL)
1496 			return;
1497 
1498 		/* Allocate GPE Handler Block */
1499 		pgpe->start = base + i;
1500 		acpi_bus_space_map(sc->sc_iot, reg+i,     1, 0, &pgpe->sts_ioh);
1501 		acpi_bus_space_map(sc->sc_iot, reg+i+len, 1, 0, &pgpe->en_ioh);
1502 		SIMPLEQ_INSERT_TAIL(&sc->sc_gpes, gpe, gpe_link);
1503 
1504 		/* Clear pending GPEs */
1505 		bus_space_write_1(sc->sc_iot, pgpe->sts_ioh, 0, 0xFF);
1506 		bus_space_write_1(sc->sc_iot, pgpe->en_ioh,  0, 0x00);
1507 	}
1508 
1509 	/* Search for GPE handlers */
1510 	for (i=0; i<len*8; i++) {
1511 		char gpestr[32];
1512 		struct aml_node *h;
1513 
1514 		snprintf(gpestr, sizeof(gpestr), "\\_GPE._L%.2X", base+i);
1515 		h = aml_searchnode(&aml_root, gpestr);
1516 		if (acpi_set_gpehandler(sc, base+i, acpi_gpe_level, h, "level") != 0) {
1517 			snprintf(gpestr, sizeof(gpestr), "\\_GPE._E%.2X", base+i);
1518 			h = aml_searchnode(&aml_root, gpestr);
1519 			acpi_set_gpehandler(sc, base+i, acpi_gpe_edge, h, "edge");
1520 		}
1521 	}
1522 }
1523 
1524 /* Process GPE interrupts */
1525 int
1526 acpi_handle_gpes(struct acpi_softc *sc)
1527 {
1528 	uint8_t en, sts;
1529 	int processed, i;
1530 
1531 	processed=0;
1532 	SIMPLEQ_FOREACH(pgpe, &sc->sc_gpes, gpe_link) {
1533 		sts = bus_space_read_1(sc->sc_iot, pgpe->sts_ioh, 0);
1534 		en = bus_space_read_1(sc->sc_iot, pgpe->en_ioh, 0);
1535 		for (i=0; i<8; i++) {
1536 			if (en & sts & (1L << i)) {
1537 				pgpe->table[i].active = 1;
1538 				processed=1;
1539 			}
1540 		}
1541 	}
1542 	return processed;
1543 }
1544 #endif
1545 
1546 #if 0
1547 void
1548 acpi_add_gpeblock(struct acpi_softc *sc, int reg, int len, int gpe)
1549 {
1550 	int idx, jdx;
1551 	u_int8_t en, sts;
1552 
1553 	if (!reg || !len)
1554 		return;
1555 	for (idx=0; idx<len; idx++) {
1556 		sts = inb(reg + idx);
1557 		en  = inb(reg + len + idx);
1558 		printf("-- gpe %.2x-%.2x : en:%.2x sts:%.2x  %.2x\n",
1559 		    gpe+idx*8, gpe+idx*8+7, en, sts, en&sts);
1560 		for (jdx=0; jdx<8; jdx++) {
1561 			char gpestr[32];
1562 			struct aml_node *l, *e;
1563 
1564 			if (en & sts & (1L << jdx)) {
1565 				snprintf(gpestr,sizeof(gpestr), "\\_GPE._L%.2X", gpe+idx*8+jdx);
1566 				l = aml_searchname(&aml_root, gpestr);
1567 				snprintf(gpestr,sizeof(gpestr), "\\_GPE._E%.2X", gpe+idx*8+jdx);
1568 				e = aml_searchname(&aml_root, gpestr);
1569 				printf("  GPE %.2x active L%x E%x\n", gpe+idx*8+jdx, l, e);
1570 			}
1571 		}
1572 	}
1573 }
1574 #endif
1575 
1576 void
1577 acpi_init_gpes(struct acpi_softc *sc)
1578 {
1579 	struct aml_node *gpe;
1580 	char name[12];
1581 	int  idx, ngpe;
1582 
1583 #if 0
1584 	acpi_add_gpeblock(sc, sc->sc_fadt->gpe0_blk, sc->sc_fadt->gpe0_blk_len>>1, 0);
1585 	acpi_add_gpeblock(sc, sc->sc_fadt->gpe1_blk, sc->sc_fadt->gpe1_blk_len>>1,
1586 	    sc->sc_fadt->gpe1_base);
1587 #endif
1588 
1589 	sc->sc_lastgpe = sc->sc_fadt->gpe0_blk_len << 2;
1590 	if (sc->sc_fadt->gpe1_blk_len) {
1591 	}
1592 	dnprintf(50, "Last GPE: %.2x\n", sc->sc_lastgpe);
1593 
1594 	/* Allocate GPE table */
1595 	sc->gpe_table = malloc(sc->sc_lastgpe * sizeof(struct gpe_block),
1596 	    M_DEVBUF, M_WAITOK | M_ZERO);
1597 
1598 	ngpe = 0;
1599 
1600 	/* Clear GPE status */
1601 	for (idx = 0; idx < sc->sc_lastgpe; idx += 8) {
1602 		acpi_write_pmreg(sc, ACPIREG_GPE_EN,  idx>>3, 0);
1603 		acpi_write_pmreg(sc, ACPIREG_GPE_STS, idx>>3, -1);
1604 	}
1605 	for (idx = 0; idx < sc->sc_lastgpe; idx++) {
1606 		/* Search Level-sensitive GPES */
1607 		snprintf(name, sizeof(name), "\\_GPE._L%.2X", idx);
1608 		gpe = aml_searchname(&aml_root, name);
1609 		if (gpe != NULL)
1610 			acpi_set_gpehandler(sc, idx, acpi_gpe_level, gpe,
1611 			    "level");
1612 		if (gpe == NULL) {
1613 			/* Search Edge-sensitive GPES */
1614 			snprintf(name, sizeof(name), "\\_GPE._E%.2X", idx);
1615 			gpe = aml_searchname(&aml_root, name);
1616 			if (gpe != NULL)
1617 				acpi_set_gpehandler(sc, idx, acpi_gpe_edge, gpe,
1618 				    "edge");
1619 		}
1620 	}
1621 	aml_find_node(&aml_root, "_PRW", acpi_foundprw, sc);
1622 	sc->sc_maxgpe = ngpe;
1623 }
1624 
1625 void
1626 acpi_init_states(struct acpi_softc *sc)
1627 {
1628 	struct aml_value res;
1629 	char name[8];
1630 	int i;
1631 
1632 	for (i = ACPI_STATE_S0; i <= ACPI_STATE_S5; i++) {
1633 		snprintf(name, sizeof(name), "_S%d_", i);
1634 		sc->sc_sleeptype[i].slp_typa = -1;
1635 		sc->sc_sleeptype[i].slp_typb = -1;
1636 		if (aml_evalname(sc, &aml_root, name, 0, NULL, &res) == 0) {
1637 			if (res.type == AML_OBJTYPE_PACKAGE) {
1638 				sc->sc_sleeptype[i].slp_typa = aml_val2int(res.v_package[0]);
1639 				sc->sc_sleeptype[i].slp_typb = aml_val2int(res.v_package[1]);
1640 			}
1641 			aml_freevalue(&res);
1642 		}
1643 	}
1644 }
1645 
1646 void
1647 acpi_init_pm(struct acpi_softc *sc)
1648 {
1649 	sc->sc_tts = aml_searchname(&aml_root, "_TTS");
1650 	sc->sc_pts = aml_searchname(&aml_root, "_PTS");
1651 	sc->sc_wak = aml_searchname(&aml_root, "_WAK");
1652 	sc->sc_bfs = aml_searchname(&aml_root, "_BFS");
1653 	sc->sc_gts = aml_searchname(&aml_root, "_GTS");
1654 }
1655 
1656 void
1657 acpi_enter_sleep_state(struct acpi_softc *sc, int state)
1658 {
1659 	struct aml_value env;
1660 	u_int16_t rega, regb;
1661 	int retries;
1662 
1663 	if (state == ACPI_STATE_S0)
1664 		return;
1665 	if (sc->sc_sleeptype[state].slp_typa == -1 ||
1666 	    sc->sc_sleeptype[state].slp_typb == -1) {
1667 		printf("%s: state S%d unavailable\n",
1668 		    sc->sc_dev.dv_xname, state);
1669 		return;
1670 	}
1671 
1672 	memset(&env, 0, sizeof(env));
1673 	env.type = AML_OBJTYPE_INTEGER;
1674 	env.v_integer = state;
1675 	/* _TTS(state) */
1676 	if (sc->sc_tts) {
1677 		if (aml_evalnode(sc, sc->sc_tts, 1, &env, NULL) != 0) {
1678 			dnprintf(10, "%s evaluating method _TTS failed.\n",
1679 			    DEVNAME(sc));
1680 			return;
1681 		}
1682 	}
1683 	switch (state) {
1684 	case ACPI_STATE_S1:
1685 	case ACPI_STATE_S2:
1686 		resettodr();
1687 		dopowerhooks(PWR_SUSPEND);
1688 		break;
1689 	case ACPI_STATE_S3:
1690 		resettodr();
1691 		dopowerhooks(PWR_STANDBY);
1692 		break;
1693 	}
1694 	/* _PTS(state) */
1695 	if (sc->sc_pts) {
1696 		if (aml_evalnode(sc, sc->sc_pts, 1, &env, NULL) != 0) {
1697 			dnprintf(10, "%s evaluating method _PTS failed.\n",
1698 			    DEVNAME(sc));
1699 			return;
1700 		}
1701 	}
1702 	sc->sc_state = state;
1703 	/* _GTS(state) */
1704 	if (sc->sc_gts) {
1705 		if (aml_evalnode(sc, sc->sc_gts, 1, &env, NULL) != 0) {
1706 			dnprintf(10, "%s evaluating method _GTS failed.\n",
1707 			    DEVNAME(sc));
1708 			return;
1709 		}
1710 	}
1711 	disable_intr();
1712 
1713 	/* Clear WAK_STS bit */
1714 	acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0, ACPI_PM1_WAK_STS);
1715 
1716 	/* Write SLP_TYPx values */
1717 	rega = acpi_read_pmreg(sc, ACPIREG_PM1A_CNT, 0);
1718 	regb = acpi_read_pmreg(sc, ACPIREG_PM1B_CNT, 0);
1719 	rega &= ~(ACPI_PM1_SLP_TYPX_MASK | ACPI_PM1_SLP_EN);
1720 	regb &= ~(ACPI_PM1_SLP_TYPX_MASK | ACPI_PM1_SLP_EN);
1721 	rega |= ACPI_PM1_SLP_TYPX(sc->sc_sleeptype[state].slp_typa);
1722 	regb |= ACPI_PM1_SLP_TYPX(sc->sc_sleeptype[state].slp_typb);
1723 	acpi_write_pmreg(sc, ACPIREG_PM1A_CNT, 0, rega);
1724 	acpi_write_pmreg(sc, ACPIREG_PM1B_CNT, 0, regb);
1725 
1726 	/* Set SLP_EN bit */
1727 	rega |= ACPI_PM1_SLP_EN;
1728 	regb |= ACPI_PM1_SLP_EN;
1729 	acpi_write_pmreg(sc, ACPIREG_PM1A_CNT, 0, rega);
1730 	acpi_write_pmreg(sc, ACPIREG_PM1B_CNT, 0, regb);
1731 
1732 	/* Loop on WAK_STS */
1733 	for (retries = 1000; retries > 0; retries--) {
1734 		rega = acpi_read_pmreg(sc, ACPIREG_PM1A_STS, 0);
1735 		regb = acpi_read_pmreg(sc, ACPIREG_PM1B_STS, 0);
1736 		if (rega & ACPI_PM1_WAK_STS ||
1737 		    regb & ACPI_PM1_WAK_STS)
1738 			break;
1739 		DELAY(10);
1740 	}
1741 
1742 	enable_intr();
1743 }
1744 
1745 #if 0
1746 void
1747 acpi_resume(struct acpi_softc *sc)
1748 {
1749 	struct aml_value env;
1750 
1751 	memset(&env, 0, sizeof(env));
1752 	env.type = AML_OBJTYPE_INTEGER;
1753 	env.v_integer = sc->sc_state;
1754 
1755 	if (sc->sc_bfs) {
1756 		if (aml_evalnode(sc, sc->sc_pts, 1, &env, NULL) != 0) {
1757 			dnprintf(10, "%s evaluating method _BFS failed.\n",
1758 			    DEVNAME(sc));
1759 		}
1760 	}
1761 	dopowerhooks(PWR_RESUME);
1762 	inittodr(0);
1763 	if (sc->sc_wak) {
1764 		if (aml_evalnode(sc, sc->sc_wak, 1, &env, NULL) != 0) {
1765 			dnprintf(10, "%s evaluating method _WAK failed.\n",
1766 			    DEVNAME(sc));
1767 		}
1768 	}
1769 	sc->sc_state = ACPI_STATE_S0;
1770 	if (sc->sc_tts) {
1771 		env.v_integer = sc->sc_state;
1772 		if (aml_evalnode(sc, sc->sc_wak, 1, &env, NULL) != 0) {
1773 			dnprintf(10, "%s evaluating method _TTS failed.\n",
1774 			    DEVNAME(sc));
1775 		}
1776 	}
1777 }
1778 #endif
1779 
1780 void
1781 acpi_powerdown(void)
1782 {
1783 	acpi_enter_sleep_state(acpi_softc, ACPI_STATE_S5);
1784 }
1785 
1786 extern int aml_busy;
1787 
1788 void
1789 acpi_isr_thread(void *arg)
1790 {
1791 	struct acpi_thread *thread = arg;
1792 	struct acpi_softc  *sc = thread->sc;
1793 	u_int32_t gpe;
1794 
1795 	/*
1796 	 * If we have an interrupt handler, we can get notification
1797 	 * when certain status bits changes in the ACPI registers,
1798 	 * so let us enable some events we can forward to userland
1799 	 */
1800 	if (sc->sc_interrupt) {
1801 		int16_t flag;
1802 
1803 		dnprintf(1,"slpbtn:%c  pwrbtn:%c\n",
1804 		    sc->sc_fadt->flags & FADT_SLP_BUTTON ? 'n' : 'y',
1805 		    sc->sc_fadt->flags & FADT_PWR_BUTTON ? 'n' : 'y');
1806 		dnprintf(10, "Enabling acpi interrupts...\n");
1807 		sc->sc_wakeup = 1;
1808 
1809 		/* Enable Sleep/Power buttons if they exist */
1810 		flag = acpi_read_pmreg(sc, ACPIREG_PM1_EN, 0);
1811 		if (!(sc->sc_fadt->flags & FADT_PWR_BUTTON)) {
1812 			flag |= ACPI_PM1_PWRBTN_EN;
1813 		}
1814 		if (!(sc->sc_fadt->flags & FADT_SLP_BUTTON)) {
1815 			flag |= ACPI_PM1_SLPBTN_EN;
1816 		}
1817 		acpi_write_pmreg(sc, ACPIREG_PM1_EN, 0, flag);
1818 
1819 		/* Enable handled GPEs here */
1820 		for (gpe = 0; gpe < sc->sc_lastgpe; gpe++) {
1821 			if (sc->gpe_table[gpe].handler)
1822 				acpi_enable_onegpe(sc, gpe, 1);
1823 		}
1824 	}
1825 
1826 	while (thread->running) {
1827 		dnprintf(10, "sleep... %d\n", sc->sc_wakeup);
1828 		while (sc->sc_wakeup)
1829 			tsleep(sc, PWAIT, "acpi_idle", 0);
1830 		sc->sc_wakeup = 1;
1831 		dnprintf(10, "wakeup..\n");
1832 		if (aml_busy)
1833 			continue;
1834 
1835 		for (gpe = 0; gpe < sc->sc_lastgpe; gpe++) {
1836 			struct gpe_block *pgpe = &sc->gpe_table[gpe];
1837 
1838 			if (pgpe->active) {
1839 				pgpe->active = 0;
1840 				dnprintf(50, "softgpe: %.2x\n", gpe);
1841 				if (pgpe->handler)
1842 					pgpe->handler(sc, gpe, pgpe->arg);
1843 			}
1844 		}
1845 		if (sc->sc_powerbtn) {
1846 			sc->sc_powerbtn = 0;
1847 
1848 			aml_notify_dev(ACPI_DEV_PBD, 0x80);
1849 
1850 			acpi_evindex++;
1851 			dnprintf(1,"power button pressed\n");
1852 			KNOTE(sc->sc_note, ACPI_EVENT_COMPOSE(ACPI_EV_PWRBTN,
1853 			    acpi_evindex));
1854 		}
1855 		if (sc->sc_sleepbtn) {
1856 			sc->sc_sleepbtn = 0;
1857 
1858 			aml_notify_dev(ACPI_DEV_SBD, 0x80);
1859 
1860 			acpi_evindex++;
1861 			dnprintf(1,"sleep button pressed\n");
1862 			KNOTE(sc->sc_note, ACPI_EVENT_COMPOSE(ACPI_EV_SLPBTN,
1863 			    acpi_evindex));
1864 		}
1865 
1866 		/* handle polling here to keep code non-concurrent*/
1867 		if (sc->sc_poll) {
1868 			sc->sc_poll = 0;
1869 			acpi_poll_notify();
1870 		}
1871 	}
1872 	free(thread, M_DEVBUF);
1873 
1874 	kthread_exit(0);
1875 }
1876 
1877 void
1878 acpi_create_thread(void *arg)
1879 {
1880 	struct acpi_softc *sc = arg;
1881 
1882 	if (kthread_create(acpi_isr_thread, sc->sc_thread, NULL, DEVNAME(sc))
1883 	    != 0) {
1884 		printf("%s: unable to create isr thread, GPEs disabled\n",
1885 		    DEVNAME(sc));
1886 		return;
1887 	}
1888 }
1889 
1890 int
1891 acpi_map_address(struct acpi_softc *sc, struct acpi_gas *gas, bus_addr_t base,
1892     bus_size_t size, bus_space_handle_t *pioh, bus_space_tag_t *piot)
1893 {
1894 	int iospace = GAS_SYSTEM_IOSPACE;
1895 
1896 	/* No GAS structure, default to I/O space */
1897 	if (gas != NULL) {
1898 		base += gas->address;
1899 		iospace = gas->address_space_id;
1900 	}
1901 	switch (iospace) {
1902 	case GAS_SYSTEM_MEMORY:
1903 		*piot = sc->sc_memt;
1904 		break;
1905 	case GAS_SYSTEM_IOSPACE:
1906 		*piot = sc->sc_iot;
1907 		break;
1908 	default:
1909 		return -1;
1910 	}
1911 	if (bus_space_map(*piot, base, size, 0, pioh))
1912 		return -1;
1913 
1914 	return 0;
1915 }
1916 
1917 int
1918 acpi_foundec(struct aml_node *node, void *arg)
1919 {
1920 	struct acpi_softc	*sc = (struct acpi_softc *)arg;
1921 	struct device		*self = (struct device *)arg;
1922 	const char		*dev;
1923 	struct aml_value	 res;
1924 	struct acpi_attach_args	aaa;
1925 
1926 	if (aml_evalnode(sc, node, 0, NULL, &res) != 0)
1927 		return 0;
1928 
1929 	switch (res.type) {
1930 	case AML_OBJTYPE_STRING:
1931 		dev = res.v_string;
1932 		break;
1933 	case AML_OBJTYPE_INTEGER:
1934 		dev = aml_eisaid(aml_val2int(&res));
1935 		break;
1936 	default:
1937 		dev = "unknown";
1938 		break;
1939 	}
1940 
1941 	if (strcmp(dev, ACPI_DEV_ECD))
1942 		return 0;
1943 
1944 	memset(&aaa, 0, sizeof(aaa));
1945 	aaa.aaa_iot = sc->sc_iot;
1946 	aaa.aaa_memt = sc->sc_memt;
1947 	aaa.aaa_node = node->parent;
1948 	aaa.aaa_dev = dev;
1949 	aaa.aaa_name = "acpiec";
1950 	config_found(self, &aaa, acpi_print);
1951 	aml_freevalue(&res);
1952 
1953 	return 0;
1954 }
1955 
1956 int
1957 acpi_foundhid(struct aml_node *node, void *arg)
1958 {
1959 	struct acpi_softc	*sc = (struct acpi_softc *)arg;
1960 	struct device		*self = (struct device *)arg;
1961 	const char		*dev;
1962 	struct aml_value	 res;
1963 	struct acpi_attach_args	aaa;
1964 
1965 	dnprintf(10, "found hid device: %s ", node->parent->name);
1966 	if (aml_evalnode(sc, node, 0, NULL, &res) != 0)
1967 		return 0;
1968 
1969 	switch (res.type) {
1970 	case AML_OBJTYPE_STRING:
1971 		dev = res.v_string;
1972 		break;
1973 	case AML_OBJTYPE_INTEGER:
1974 		dev = aml_eisaid(aml_val2int(&res));
1975 		break;
1976 	default:
1977 		dev = "unknown";
1978 		break;
1979 	}
1980 	dnprintf(10, "	device: %s\n", dev);
1981 
1982 	memset(&aaa, 0, sizeof(aaa));
1983 	aaa.aaa_iot = sc->sc_iot;
1984 	aaa.aaa_memt = sc->sc_memt;
1985 	aaa.aaa_node = node->parent;
1986 	aaa.aaa_dev = dev;
1987 
1988 	if (!strcmp(dev, ACPI_DEV_AC))
1989 		aaa.aaa_name = "acpiac";
1990 	else if (!strcmp(dev, ACPI_DEV_CMB))
1991 		aaa.aaa_name = "acpibat";
1992 	else if (!strcmp(dev, ACPI_DEV_LD) ||
1993 	    !strcmp(dev, ACPI_DEV_PBD) ||
1994 	    !strcmp(dev, ACPI_DEV_SBD))
1995 		aaa.aaa_name = "acpibtn";
1996 	else if (!strcmp(dev, ACPI_DEV_ASUS))
1997 		aaa.aaa_name = "acpiasus";
1998 	else if (!strcmp(dev, ACPI_DEV_THINKPAD))
1999 		aaa.aaa_name = "acpithinkpad";
2000 
2001 	if (aaa.aaa_name)
2002 		config_found(self, &aaa, acpi_print);
2003 
2004 	aml_freevalue(&res);
2005 
2006 	return 0;
2007 }
2008 
2009 int
2010 acpi_founddock(struct aml_node *node, void *arg)
2011 {
2012 	struct acpi_softc	*sc = (struct acpi_softc *)arg;
2013 	struct device		*self = (struct device *)arg;
2014 	struct acpi_attach_args	aaa;
2015 
2016 	dnprintf(10, "found dock entry: %s\n", node->parent->name);
2017 
2018 	memset(&aaa, 0, sizeof(aaa));
2019 	aaa.aaa_iot = sc->sc_iot;
2020 	aaa.aaa_memt = sc->sc_memt;
2021 	aaa.aaa_node = node->parent;
2022 	aaa.aaa_name = "acpidock";
2023 
2024 	config_found(self, &aaa, acpi_print);
2025 
2026 	return 0;
2027 }
2028 
2029 int
2030 acpi_foundvideo(struct aml_node *node, void *arg)
2031 {
2032 	struct acpi_softc *sc = (struct acpi_softc *)arg;
2033 	struct device *self = (struct device *)arg;
2034 	struct acpi_attach_args	aaa;
2035 
2036 	memset(&aaa, 0, sizeof(aaa));
2037 	aaa.aaa_iot = sc->sc_iot;
2038 	aaa.aaa_memt = sc->sc_memt;
2039 	aaa.aaa_node = node->parent;
2040 	aaa.aaa_name = "acpivideo";
2041 
2042 	config_found(self, &aaa, acpi_print);
2043 
2044 	return (0);
2045 }
2046 #endif /* SMALL_KERNEL */
2047