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