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