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