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