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