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