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