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