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