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