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