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