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