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