acpi.c revision 1.187
1/* $OpenBSD: acpi.c,v 1.187 2010/07/22 14:19:47 deraadt 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/workq.h> 31#include <sys/sched.h> 32 33#include <machine/conf.h> 34#include <machine/cpufunc.h> 35#include <machine/bus.h> 36 37#include <dev/pci/pcivar.h> 38#include <dev/acpi/acpireg.h> 39#include <dev/acpi/acpivar.h> 40#include <dev/acpi/amltypes.h> 41#include <dev/acpi/acpidev.h> 42#include <dev/acpi/dsdt.h> 43#include <dev/wscons/wsdisplayvar.h> 44 45#include <dev/pci/pcivar.h> 46#include <dev/pci/pcidevs.h> 47#include <dev/pci/ppbreg.h> 48 49#include <dev/pci/pciidereg.h> 50#include <dev/pci/pciidevar.h> 51 52#include <machine/apmvar.h> 53#define APMUNIT(dev) (minor(dev)&0xf0) 54#define APMDEV(dev) (minor(dev)&0x0f) 55#define APMDEV_NORMAL 0 56#define APMDEV_CTL 8 57 58#include "wsdisplay.h" 59 60#ifdef ACPI_DEBUG 61int acpi_debug = 16; 62#endif 63 64int acpi_poll_enabled; 65int acpi_hasprocfvs; 66 67#define ACPIEN_RETRIES 15 68 69void acpi_pci_match(struct device *, struct pci_attach_args *); 70int acpi_match(struct device *, void *, void *); 71void acpi_attach(struct device *, struct device *, void *); 72int acpi_submatch(struct device *, void *, void *); 73int acpi_print(void *, const char *); 74 75void acpi_map_pmregs(struct acpi_softc *); 76 77int acpi_loadtables(struct acpi_softc *, struct acpi_rsdp *); 78 79int _acpi_matchhids(const char *, const char *[]); 80 81int acpi_inidev(struct aml_node *, void *); 82int acpi_foundprt(struct aml_node *, void *); 83 84struct acpi_q *acpi_maptable(struct acpi_softc *, paddr_t, const char *, 85 const char *, const char *, int); 86 87#ifndef SMALL_KERNEL 88 89int acpi_thinkpad_enabled; 90int acpi_saved_spl; 91int acpi_enabled; 92 93int acpi_matchhids(struct acpi_attach_args *aa, const char *hids[], 94 const char *driver); 95 96void acpi_thread(void *); 97void acpi_create_thread(void *); 98void acpi_init_pm(struct acpi_softc *); 99void acpi_init_states(struct acpi_softc *); 100 101void acpi_handle_suspend_failure(struct acpi_softc *); 102void acpi_init_gpes(struct acpi_softc *); 103 104int acpi_founddock(struct aml_node *, void *); 105int acpi_foundpss(struct aml_node *, void *); 106int acpi_foundhid(struct aml_node *, void *); 107int acpi_foundec(struct aml_node *, void *); 108int acpi_foundtmp(struct aml_node *, void *); 109int acpi_foundprw(struct aml_node *, void *); 110int acpi_foundvideo(struct aml_node *, void *); 111 112int acpi_foundide(struct aml_node *node, void *arg); 113int acpiide_notify(struct aml_node *, int, void *); 114void wdcattach(struct channel_softc *); 115int wdcdetach(struct channel_softc *, int); 116int is_ejectable_bay(struct aml_node *node); 117int is_ata(struct aml_node *node); 118int is_ejectable(struct aml_node *node); 119 120struct idechnl { 121 struct acpi_softc *sc; 122 int64_t addr; 123 int64_t chnl; 124 int64_t sta; 125}; 126 127void acpi_resume(struct acpi_softc *, int); 128void acpi_susp_resume_gpewalk(struct acpi_softc *, int, int); 129int acpi_add_device(struct aml_node *node, void *arg); 130 131struct gpe_block *acpi_find_gpe(struct acpi_softc *, int); 132void acpi_enable_onegpe(struct acpi_softc *, int, int); 133int acpi_gpe(struct acpi_softc *, int, void *); 134 135#endif /* SMALL_KERNEL */ 136 137/* XXX move this into dsdt softc at some point */ 138extern struct aml_node aml_root; 139 140struct cfattach acpi_ca = { 141 sizeof(struct acpi_softc), acpi_match, acpi_attach, NULL, 142 config_activate_children 143}; 144 145struct cfdriver acpi_cd = { 146 NULL, "acpi", DV_DULL 147}; 148 149struct acpi_softc *acpi_softc; 150 151#define acpi_bus_space_map _bus_space_map 152#define acpi_bus_space_unmap _bus_space_unmap 153 154int 155acpi_gasio(struct acpi_softc *sc, int iodir, int iospace, uint64_t address, 156 int access_size, int len, void *buffer) 157{ 158 u_int8_t *pb; 159 bus_space_handle_t ioh; 160 struct acpi_mem_map mh; 161 pci_chipset_tag_t pc; 162 pcitag_t tag; 163 bus_addr_t ioaddr; 164 int reg, idx, ival, sval; 165 166 dnprintf(50, "gasio: %.2x 0x%.8llx %s\n", 167 iospace, address, (iodir == ACPI_IOWRITE) ? "write" : "read"); 168 169 pb = (u_int8_t *)buffer; 170 switch (iospace) { 171 case GAS_SYSTEM_MEMORY: 172 /* copy to/from system memory */ 173 acpi_map(address, len, &mh); 174 if (iodir == ACPI_IOREAD) 175 memcpy(buffer, mh.va, len); 176 else 177 memcpy(mh.va, buffer, len); 178 acpi_unmap(&mh); 179 break; 180 181 case GAS_SYSTEM_IOSPACE: 182 /* read/write from I/O registers */ 183 ioaddr = address; 184 if (acpi_bus_space_map(sc->sc_iot, ioaddr, len, 0, &ioh) != 0) { 185 printf("unable to map iospace\n"); 186 return (-1); 187 } 188 for (reg = 0; reg < len; reg += access_size) { 189 if (iodir == ACPI_IOREAD) { 190 switch (access_size) { 191 case 1: 192 *(uint8_t *)(pb+reg) = bus_space_read_1( 193 sc->sc_iot, ioh, reg); 194 dnprintf(80, "os_in8(%llx) = %x\n", 195 reg+address, *(uint8_t *)(pb+reg)); 196 break; 197 case 2: 198 *(uint16_t *)(pb+reg) = bus_space_read_2( 199 sc->sc_iot, ioh, reg); 200 dnprintf(80, "os_in16(%llx) = %x\n", 201 reg+address, *(uint16_t *)(pb+reg)); 202 break; 203 case 4: 204 *(uint32_t *)(pb+reg) = bus_space_read_4( 205 sc->sc_iot, ioh, reg); 206 break; 207 default: 208 printf("rdio: invalid size %d\n", access_size); 209 break; 210 } 211 } else { 212 switch (access_size) { 213 case 1: 214 bus_space_write_1(sc->sc_iot, ioh, reg, 215 *(uint8_t *)(pb+reg)); 216 dnprintf(80, "os_out8(%llx,%x)\n", 217 reg+address, *(uint8_t *)(pb+reg)); 218 break; 219 case 2: 220 bus_space_write_2(sc->sc_iot, ioh, reg, 221 *(uint16_t *)(pb+reg)); 222 dnprintf(80, "os_out16(%llx,%x)\n", 223 reg+address, *(uint16_t *)(pb+reg)); 224 break; 225 case 4: 226 bus_space_write_4(sc->sc_iot, ioh, reg, 227 *(uint32_t *)(pb+reg)); 228 break; 229 default: 230 printf("wrio: invalid size %d\n", access_size); 231 break; 232 } 233 } 234 235 /* During autoconf some devices are still gathering 236 * information. Delay here to give them an opportunity 237 * to finish. During runtime we simply need to ignore 238 * transient values. 239 */ 240 if (cold) 241 delay(10000); 242 } 243 acpi_bus_space_unmap(sc->sc_iot, ioh, len, &ioaddr); 244 break; 245 246 case GAS_PCI_CFG_SPACE: 247 /* format of address: 248 * bits 00..15 = register 249 * bits 16..31 = function 250 * bits 32..47 = device 251 * bits 48..63 = bus 252 */ 253 pc = NULL; 254 tag = pci_make_tag(pc, 255 ACPI_PCI_BUS(address), ACPI_PCI_DEV(address), 256 ACPI_PCI_FN(address)); 257 258 /* XXX: This is ugly. read-modify-write does a byte at a time */ 259 reg = ACPI_PCI_REG(address); 260 for (idx = reg; idx < reg+len; idx++) { 261 ival = pci_conf_read(pc, tag, idx & ~0x3); 262 if (iodir == ACPI_IOREAD) { 263 *pb = ival >> (8 * (idx & 0x3)); 264 } else { 265 sval = *pb; 266 ival &= ~(0xFF << (8* (idx & 0x3))); 267 ival |= sval << (8* (idx & 0x3)); 268 pci_conf_write(pc, tag, idx & ~0x3, ival); 269 } 270 pb++; 271 } 272 break; 273 case GAS_EMBEDDED: 274 if (sc->sc_ec == NULL) 275 break; 276#ifndef SMALL_KERNEL 277 if (iodir == ACPI_IOREAD) 278 acpiec_read(sc->sc_ec, (u_int8_t)address, len, buffer); 279 else 280 acpiec_write(sc->sc_ec, (u_int8_t)address, len, buffer); 281#endif 282 break; 283 } 284 return (0); 285} 286 287int 288acpi_inidev(struct aml_node *node, void *arg) 289{ 290 struct acpi_softc *sc = (struct acpi_softc *)arg; 291 int64_t st; 292 293 /* 294 * Per the ACPI spec 6.5.1, only run _INI when device is there or 295 * when there is no _STA. We terminate the tree walk (with return 1) 296 * early if necessary. 297 */ 298 299 /* Evaluate _STA to decide _INI fate and walk fate */ 300 if (aml_evalinteger(sc, node->parent, "_STA", 0, NULL, &st)) 301 st = STA_PRESENT | STA_ENABLED | STA_DEV_OK | 0x1000; 302 303 /* Evaluate _INI if we are present */ 304 if (st & STA_PRESENT) 305 aml_evalnode(sc, node, 0, NULL, NULL); 306 307 /* If we are functioning, we walk/search our children */ 308 if (st & STA_DEV_OK) 309 return 0; 310 311 /* If we are not enabled, or not present, terminate search */ 312 if (!(st & (STA_PRESENT|STA_ENABLED))) 313 return 1; 314 315 /* Default just continue search */ 316 return 0; 317} 318 319int 320acpi_foundprt(struct aml_node *node, void *arg) 321{ 322 struct acpi_softc *sc = (struct acpi_softc *)arg; 323 struct device *self = (struct device *)arg; 324 struct acpi_attach_args aaa; 325 int64_t st = 0; 326 327 dnprintf(10, "found prt entry: %s\n", node->parent->name); 328 329 /* Evaluate _STA to decide _PRT fate and walk fate */ 330 if (aml_evalinteger(sc, node->parent, "_STA", 0, NULL, &st)) 331 st = STA_PRESENT | STA_ENABLED | STA_DEV_OK | 0x1000; 332 333 if (st & STA_PRESENT) { 334 memset(&aaa, 0, sizeof(aaa)); 335 aaa.aaa_iot = sc->sc_iot; 336 aaa.aaa_memt = sc->sc_memt; 337 aaa.aaa_node = node; 338 aaa.aaa_name = "acpiprt"; 339 340 config_found(self, &aaa, acpi_print); 341 } 342 343 /* If we are functioning, we walk/search our children */ 344 if (st & STA_DEV_OK) 345 return 0; 346 347 /* If we are not enabled, or not present, terminate search */ 348 if (!(st & (STA_PRESENT|STA_ENABLED))) 349 return 1; 350 351 /* Default just continue search */ 352 return 0; 353} 354 355int 356acpi_match(struct device *parent, void *match, void *aux) 357{ 358 struct bios_attach_args *ba = aux; 359 struct cfdata *cf = match; 360 361 /* sanity */ 362 if (strcmp(ba->ba_name, cf->cf_driver->cd_name)) 363 return (0); 364 365 if (!acpi_probe(parent, cf, ba)) 366 return (0); 367 368 return (1); 369} 370 371TAILQ_HEAD(, acpi_pci) acpi_pcidevs = 372 TAILQ_HEAD_INITIALIZER(acpi_pcidevs); 373 374int acpi_getpci(struct aml_node *node, void *arg); 375int acpi_getminbus(union acpi_resource *crs, void *arg); 376 377int 378acpi_getminbus(union acpi_resource *crs, void *arg) 379{ 380 int *bbn = arg; 381 int typ = AML_CRSTYPE(crs); 382 383 /* Check for embedded bus number */ 384 if (typ == LR_WORD && crs->lr_word.type == 2) 385 *bbn = crs->lr_word._min; 386 return 0; 387} 388 389int 390_acpi_matchhids(const char *hid, const char *hids[]) 391{ 392 int i; 393 394 for (i = 0; hids[i]; i++) 395 if (!strcmp(hid, hids[i])) 396 return (1); 397 return (0); 398} 399 400#ifndef SMALL_KERNEL 401int 402acpi_matchhids(struct acpi_attach_args *aa, const char *hids[], 403 const char *driver) 404{ 405 406 if (aa->aaa_dev == NULL || aa->aaa_node == NULL) 407 return (0); 408 if (_acpi_matchhids(aa->aaa_dev, hids)) { 409 dnprintf(5, "driver %s matches %s\n", driver, hids); 410 return (1); 411 } 412 return (0); 413} 414#endif /* SMALL_KERNEL */ 415 416/* Map ACPI device node to PCI */ 417int 418acpi_getpci(struct aml_node *node, void *arg) 419{ 420 const char *pcihid[] = { ACPI_DEV_PCIB, ACPI_DEV_PCIEB, "HWP0002", 0 }; 421 struct acpi_pci *pci, *ppci; 422 struct aml_value res; 423 struct acpi_softc *sc = arg; 424 pci_chipset_tag_t pc = NULL; 425 pcitag_t tag; 426 uint64_t val; 427 uint32_t reg; 428 429 if (!node->value || node->value->type != AML_OBJTYPE_DEVICE) 430 return 0; 431 if (!aml_evalhid(node, &res)) { 432 /* Check if this is a PCI Root node */ 433 if (_acpi_matchhids(res.v_string, pcihid)) { 434 aml_freevalue(&res); 435 436 pci = malloc(sizeof(*pci), M_DEVBUF, M_WAITOK|M_ZERO); 437 438 pci->bus = -1; 439 if (!aml_evalinteger(sc, node, "_SEG", 0, NULL, &val)) 440 pci->seg = val; 441 if (!aml_evalname(sc, node, "_CRS", 0, NULL, &res)) { 442 aml_parse_resource(&res, acpi_getminbus, 443 &pci->bus); 444 dnprintf(10, "%s post-crs: %d\n", aml_nodename(node), 445 pci->bus); 446 } 447 if (!aml_evalinteger(sc, node, "_BBN", 0, NULL, &val)) { 448 dnprintf(10, "%s post-bbn: %d, %lld\n", aml_nodename(node), 449 pci->bus, val); 450 if (pci->bus == -1) 451 pci->bus = val; 452 } 453 pci->sub = pci->bus; 454 node->pci = pci; 455 dnprintf(10, "found PCI root: %s %d\n", 456 aml_nodename(node), pci->bus); 457 } 458 aml_freevalue(&res); 459 return 0; 460 } 461 462 /* If parent is not PCI, or device does not have _ADR, return */ 463 if (!node->parent || (ppci = node->parent->pci) == NULL) 464 return 0; 465 if (aml_evalinteger(sc, node, "_ADR", 0, NULL, &val)) 466 return 0; 467 468 pci = malloc(sizeof(*pci), M_DEVBUF, M_WAITOK|M_ZERO); 469 pci->bus = ppci->sub; 470 pci->dev = ACPI_ADR_PCIDEV(val); 471 pci->fun = ACPI_ADR_PCIFUN(val); 472 pci->node = node; 473 pci->sub = -1; 474 475 dnprintf(10, "%.2x:%.2x.%x -> %s\n", 476 pci->bus, pci->dev, pci->fun, 477 aml_nodename(node)); 478 479 /* Check if PCI device exists */ 480 if (pci->dev > 0x1F || pci->fun > 7) { 481 free(pci, M_DEVBUF); 482 return (1); 483 } 484 tag = pci_make_tag(pc, pci->bus, pci->dev, pci->fun); 485 reg = pci_conf_read(pc, tag, PCI_ID_REG); 486 if (PCI_VENDOR(reg) == PCI_VENDOR_INVALID) { 487 free(pci, M_DEVBUF); 488 return (1); 489 } 490 node->pci = pci; 491 492 TAILQ_INSERT_TAIL(&acpi_pcidevs, pci, next); 493 494 /* Check if this is a PCI bridge */ 495 reg = pci_conf_read(pc, tag, PCI_CLASS_REG); 496 if (PCI_CLASS(reg) == PCI_CLASS_BRIDGE && 497 PCI_SUBCLASS(reg) == PCI_SUBCLASS_BRIDGE_PCI) { 498 reg = pci_conf_read(pc, tag, PPB_REG_BUSINFO); 499 pci->sub = PPB_BUSINFO_SECONDARY(reg); 500 501 dnprintf(10, "found PCI bridge: %s %d\n", 502 aml_nodename(node), pci->sub); 503 504 /* Continue scanning */ 505 return (0); 506 } 507 508 /* Device does not have children, stop scanning */ 509 return (1); 510} 511 512void 513acpi_pci_match(struct device *dev, struct pci_attach_args *pa) 514{ 515 struct acpi_pci *pdev; 516 517 TAILQ_FOREACH(pdev, &acpi_pcidevs, next) { 518 if (pdev->bus == pa->pa_bus && 519 pdev->dev == pa->pa_device && 520 pdev->fun == pa->pa_function) { 521 dnprintf(10,"%s at acpi0 %s\n", 522 dev->dv_xname, aml_nodename(pdev->node)); 523 pdev->device = dev; 524 } 525 } 526} 527 528void 529acpi_attach(struct device *parent, struct device *self, void *aux) 530{ 531 struct bios_attach_args *ba = aux; 532 struct acpi_softc *sc = (struct acpi_softc *)self; 533 struct acpi_mem_map handle; 534 struct acpi_rsdp *rsdp; 535 struct acpi_q *entry; 536 struct acpi_dsdt *p_dsdt; 537 int idx; 538#ifndef SMALL_KERNEL 539 struct acpi_wakeq *wentry; 540 struct device *dev; 541 struct acpi_ac *ac; 542 struct acpi_bat *bat; 543#endif /* SMALL_KERNEL */ 544 paddr_t facspa; 545 546 sc->sc_iot = ba->ba_iot; 547 sc->sc_memt = ba->ba_memt; 548 549 acpi_softc = sc; 550 551 if (acpi_map(ba->ba_acpipbase, sizeof(struct acpi_rsdp), &handle)) { 552 printf(": can't map memory\n"); 553 return; 554 } 555 556 rsdp = (struct acpi_rsdp *)handle.va; 557 sc->sc_revision = (int)rsdp->rsdp_revision; 558 printf(": rev %d", sc->sc_revision); 559 560 SIMPLEQ_INIT(&sc->sc_tables); 561 SIMPLEQ_INIT(&sc->sc_wakedevs); 562 563#ifndef SMALL_KERNEL 564 sc->sc_note = malloc(sizeof(struct klist), M_DEVBUF, M_NOWAIT | M_ZERO); 565 if (sc->sc_note == NULL) { 566 printf(", can't allocate memory\n"); 567 acpi_unmap(&handle); 568 return; 569 } 570#endif /* SMALL_KERNEL */ 571 572 if (acpi_loadtables(sc, rsdp)) { 573 printf(", can't load tables\n"); 574 acpi_unmap(&handle); 575 return; 576 } 577 578 acpi_unmap(&handle); 579 580 /* 581 * Find the FADT 582 */ 583 SIMPLEQ_FOREACH(entry, &sc->sc_tables, q_next) { 584 if (memcmp(entry->q_table, FADT_SIG, 585 sizeof(FADT_SIG) - 1) == 0) { 586 sc->sc_fadt = entry->q_table; 587 break; 588 } 589 } 590 if (sc->sc_fadt == NULL) { 591 printf(", no FADT\n"); 592 return; 593 } 594 595 /* 596 * Check if we are able to enable ACPI control 597 */ 598 if (!sc->sc_fadt->smi_cmd || 599 (!sc->sc_fadt->acpi_enable && !sc->sc_fadt->acpi_disable)) { 600 printf(", ACPI control unavailable\n"); 601 return; 602 } 603 604 /* 605 * Set up a pointer to the firmware control structure 606 */ 607 if (sc->sc_fadt->hdr_revision < 3 || sc->sc_fadt->x_firmware_ctl == 0) 608 facspa = sc->sc_fadt->firmware_ctl; 609 else 610 facspa = sc->sc_fadt->x_firmware_ctl; 611 612 if (acpi_map(facspa, sizeof(struct acpi_facs), &handle)) 613 printf(" !FACS"); 614 else 615 sc->sc_facs = (struct acpi_facs *)handle.va; 616 617 /* Create opcode hashtable */ 618 aml_hashopcodes(); 619 620 /* Create Default AML objects */ 621 aml_create_defaultobjects(); 622 623 /* 624 * Load the DSDT from the FADT pointer -- use the 625 * extended (64-bit) pointer if it exists 626 */ 627 if (sc->sc_fadt->hdr_revision < 3 || sc->sc_fadt->x_dsdt == 0) 628 entry = acpi_maptable(sc, sc->sc_fadt->dsdt, NULL, NULL, NULL, -1); 629 else 630 entry = acpi_maptable(sc, sc->sc_fadt->x_dsdt, NULL, NULL, NULL, -1); 631 632 if (entry == NULL) 633 printf(" !DSDT"); 634 635 p_dsdt = entry->q_table; 636 acpi_parse_aml(sc, p_dsdt->aml, p_dsdt->hdr_length - 637 sizeof(p_dsdt->hdr)); 638 639 /* Load SSDT's */ 640 SIMPLEQ_FOREACH(entry, &sc->sc_tables, q_next) { 641 if (memcmp(entry->q_table, SSDT_SIG, 642 sizeof(SSDT_SIG) - 1) == 0) { 643 p_dsdt = entry->q_table; 644 acpi_parse_aml(sc, p_dsdt->aml, p_dsdt->hdr_length - 645 sizeof(p_dsdt->hdr)); 646 } 647 } 648 649 /* Perform post-parsing fixups */ 650 aml_postparse(); 651 652#ifndef SMALL_KERNEL 653 /* Find available sleeping states */ 654 acpi_init_states(sc); 655 656 /* Find available sleep/resume related methods. */ 657 acpi_init_pm(sc); 658#endif /* SMALL_KERNEL */ 659 660 /* Map Power Management registers */ 661 acpi_map_pmregs(sc); 662 663#ifndef SMALL_KERNEL 664 /* Initialize GPE handlers */ 665 acpi_init_gpes(sc); 666 667 /* some devices require periodic polling */ 668 timeout_set(&sc->sc_dev_timeout, acpi_poll, sc); 669 670 acpi_enabled = 1; 671#endif /* SMALL_KERNEL */ 672 673 /* 674 * Take over ACPI control. Note that once we do this, we 675 * effectively tell the system that we have ownership of 676 * the ACPI hardware registers, and that SMI should leave 677 * them alone 678 * 679 * This may prevent thermal control on some systems where 680 * that actually does work 681 */ 682 acpi_write_pmreg(sc, ACPIREG_SMICMD, 0, sc->sc_fadt->acpi_enable); 683 idx = 0; 684 do { 685 if (idx++ > ACPIEN_RETRIES) { 686 printf(", can't enable ACPI\n"); 687 return; 688 } 689 } while (!(acpi_read_pmreg(sc, ACPIREG_PM1_CNT, 0) & ACPI_PM1_SCI_EN)); 690 691 printf("\n%s: tables", DEVNAME(sc)); 692 SIMPLEQ_FOREACH(entry, &sc->sc_tables, q_next) { 693 printf(" %.4s", entry->q_table); 694 } 695 printf("\n"); 696 697#ifndef SMALL_KERNEL 698 /* Display wakeup devices and lowest S-state */ 699 printf("%s: wakeup devices", DEVNAME(sc)); 700 SIMPLEQ_FOREACH(wentry, &sc->sc_wakedevs, q_next) { 701 printf(" %.4s(S%d)", wentry->q_node->name, 702 wentry->q_state); 703 } 704 printf("\n"); 705 706 /* 707 * ACPI is enabled now -- attach timer 708 */ 709 { 710 struct acpi_attach_args aaa; 711 712 memset(&aaa, 0, sizeof(aaa)); 713 aaa.aaa_name = "acpitimer"; 714 aaa.aaa_iot = sc->sc_iot; 715 aaa.aaa_memt = sc->sc_memt; 716#if 0 717 aaa.aaa_pcit = sc->sc_pcit; 718 aaa.aaa_smbust = sc->sc_smbust; 719#endif 720 config_found(self, &aaa, acpi_print); 721 } 722#endif /* SMALL_KERNEL */ 723 724 /* 725 * Attach table-defined devices 726 */ 727 SIMPLEQ_FOREACH(entry, &sc->sc_tables, q_next) { 728 struct acpi_attach_args aaa; 729 730 memset(&aaa, 0, sizeof(aaa)); 731 aaa.aaa_iot = sc->sc_iot; 732 aaa.aaa_memt = sc->sc_memt; 733 #if 0 734 aaa.aaa_pcit = sc->sc_pcit; 735 aaa.aaa_smbust = sc->sc_smbust; 736 #endif 737 aaa.aaa_table = entry->q_table; 738 config_found_sm(self, &aaa, acpi_print, acpi_submatch); 739 } 740 741 /* initialize runtime environment */ 742 aml_find_node(&aml_root, "_INI", acpi_inidev, sc); 743 744 /* Get PCI mapping */ 745 aml_walknodes(&aml_root, AML_WALK_PRE, acpi_getpci, sc); 746 747 /* attach pci interrupt routing tables */ 748 aml_find_node(&aml_root, "_PRT", acpi_foundprt, sc); 749 750#ifndef SMALL_KERNEL 751 /* XXX EC needs to be attached first on some systems */ 752 aml_find_node(&aml_root, "_HID", acpi_foundec, sc); 753 754 aml_walknodes(&aml_root, AML_WALK_PRE, acpi_add_device, sc); 755 756 /* attach battery, power supply and button devices */ 757 aml_find_node(&aml_root, "_HID", acpi_foundhid, sc); 758 759 /* Attach IDE bay */ 760 aml_walknodes(&aml_root, AML_WALK_PRE, acpi_foundide, sc); 761 762 /* attach docks */ 763 aml_find_node(&aml_root, "_DCK", acpi_founddock, sc); 764 765 /* attach video only if this is not a stinkpad */ 766 if (!acpi_thinkpad_enabled) 767 aml_find_node(&aml_root, "_DOS", acpi_foundvideo, sc); 768 769 /* create list of devices we want to query when APM come in */ 770 SLIST_INIT(&sc->sc_ac); 771 SLIST_INIT(&sc->sc_bat); 772 TAILQ_FOREACH(dev, &alldevs, dv_list) { 773 if (!strcmp(dev->dv_cfdata->cf_driver->cd_name, "acpiac")) { 774 ac = malloc(sizeof(*ac), M_DEVBUF, M_WAITOK | M_ZERO); 775 ac->aac_softc = (struct acpiac_softc *)dev; 776 SLIST_INSERT_HEAD(&sc->sc_ac, ac, aac_link); 777 } else if (!strcmp(dev->dv_cfdata->cf_driver->cd_name, "acpibat")) { 778 bat = malloc(sizeof(*bat), M_DEVBUF, M_WAITOK | M_ZERO); 779 bat->aba_softc = (struct acpibat_softc *)dev; 780 SLIST_INSERT_HEAD(&sc->sc_bat, bat, aba_link); 781 } 782 } 783 784 /* Setup threads */ 785 sc->sc_thread = malloc(sizeof(struct acpi_thread), M_DEVBUF, M_WAITOK); 786 sc->sc_thread->sc = sc; 787 sc->sc_thread->running = 1; 788 789 acpi_attach_machdep(sc); 790 791 kthread_create_deferred(acpi_create_thread, sc); 792#endif /* SMALL_KERNEL */ 793} 794 795int 796acpi_submatch(struct device *parent, void *match, void *aux) 797{ 798 struct acpi_attach_args *aaa = (struct acpi_attach_args *)aux; 799 struct cfdata *cf = match; 800 801 if (aaa->aaa_table == NULL) 802 return (0); 803 return ((*cf->cf_attach->ca_match)(parent, match, aux)); 804} 805 806int 807acpi_print(void *aux, const char *pnp) 808{ 809 struct acpi_attach_args *aa = aux; 810 811 if (pnp) { 812 if (aa->aaa_name) 813 printf("%s at %s", aa->aaa_name, pnp); 814 else 815 return (QUIET); 816 } 817 818 return (UNCONF); 819} 820 821struct acpi_q * 822acpi_maptable(struct acpi_softc *sc, paddr_t addr, const char *sig, 823 const char *oem, const char *tbl, int flag) 824{ 825 static int tblid; 826 struct acpi_mem_map handle; 827 struct acpi_table_header *hdr; 828 struct acpi_q *entry; 829 size_t len; 830 831 /* Check if we can map address */ 832 if (addr == 0) 833 return NULL; 834 if (acpi_map(addr, sizeof(*hdr), &handle)) 835 return NULL; 836 hdr = (struct acpi_table_header *)handle.va; 837 len = hdr->length; 838 acpi_unmap(&handle); 839 840 /* Validate length/checksum */ 841 if (acpi_map(addr, len, &handle)) 842 return NULL; 843 hdr = (struct acpi_table_header *)handle.va; 844 if (acpi_checksum(hdr, len)) { 845 acpi_unmap(&handle); 846 return NULL; 847 } 848 if ((sig && memcmp(sig, hdr->signature, 4)) || 849 (oem && memcmp(oem, hdr->oemid, 6)) || 850 (tbl && memcmp(tbl, hdr->oemtableid, 8))) { 851 acpi_unmap(&handle); 852 return NULL; 853 } 854 855 /* Allocate copy */ 856 entry = malloc(len + sizeof(*entry), M_DEVBUF, M_NOWAIT); 857 if (entry != NULL) { 858 memcpy(entry->q_data, handle.va, len); 859 entry->q_table = entry->q_data; 860 entry->q_id = ++tblid; 861 862 if (flag < 0) 863 SIMPLEQ_INSERT_HEAD(&sc->sc_tables, entry, 864 q_next); 865 else if (flag > 0) 866 SIMPLEQ_INSERT_TAIL(&sc->sc_tables, entry, 867 q_next); 868 } 869 acpi_unmap(&handle); 870 return entry; 871} 872 873int 874acpi_loadtables(struct acpi_softc *sc, struct acpi_rsdp *rsdp) 875{ 876 struct acpi_q *sdt; 877 int i, ntables; 878 size_t len; 879 880 if (rsdp->rsdp_revision == 2 && rsdp->rsdp_xsdt) { 881 struct acpi_xsdt *xsdt; 882 883 sdt = acpi_maptable(sc, rsdp->rsdp_xsdt, NULL, NULL, NULL, 0); 884 if (sdt == NULL) { 885 printf("couldn't map rsdt\n"); 886 return (ENOMEM); 887 } 888 889 xsdt = (struct acpi_xsdt *)sdt->q_data; 890 len = xsdt->hdr.length; 891 ntables = (len - sizeof(struct acpi_table_header)) / 892 sizeof(xsdt->table_offsets[0]); 893 894 for (i = 0; i < ntables; i++) 895 acpi_maptable(sc, xsdt->table_offsets[i], NULL, NULL, 896 NULL, 1); 897 898 free(sdt, M_DEVBUF); 899 } else { 900 struct acpi_rsdt *rsdt; 901 902 sdt = acpi_maptable(sc, rsdp->rsdp_rsdt, NULL, NULL, NULL, 0); 903 if (sdt == NULL) { 904 printf("couldn't map rsdt\n"); 905 return (ENOMEM); 906 } 907 908 rsdt = (struct acpi_rsdt *)sdt->q_data; 909 len = rsdt->hdr.length; 910 ntables = (len - sizeof(struct acpi_table_header)) / 911 sizeof(rsdt->table_offsets[0]); 912 913 for (i = 0; i < ntables; i++) 914 acpi_maptable(sc, rsdt->table_offsets[i], NULL, NULL, 915 NULL, 1); 916 917 free(sdt, M_DEVBUF); 918 } 919 920 return (0); 921} 922 923/* Read from power management register */ 924int 925acpi_read_pmreg(struct acpi_softc *sc, int reg, int offset) 926{ 927 bus_space_handle_t ioh; 928 bus_size_t size, __size; 929 int regval; 930 931 __size = 0; 932 /* Special cases: 1A/1B blocks can be OR'ed together */ 933 switch (reg) { 934 case ACPIREG_PM1_EN: 935 return (acpi_read_pmreg(sc, ACPIREG_PM1A_EN, offset) | 936 acpi_read_pmreg(sc, ACPIREG_PM1B_EN, offset)); 937 case ACPIREG_PM1_STS: 938 return (acpi_read_pmreg(sc, ACPIREG_PM1A_STS, offset) | 939 acpi_read_pmreg(sc, ACPIREG_PM1B_STS, offset)); 940 case ACPIREG_PM1_CNT: 941 return (acpi_read_pmreg(sc, ACPIREG_PM1A_CNT, offset) | 942 acpi_read_pmreg(sc, ACPIREG_PM1B_CNT, offset)); 943 case ACPIREG_GPE_STS: 944 __size = 1; 945 dnprintf(50, "read GPE_STS offset: %.2x %.2x %.2x\n", offset, 946 sc->sc_fadt->gpe0_blk_len>>1, sc->sc_fadt->gpe1_blk_len>>1); 947 if (offset < (sc->sc_fadt->gpe0_blk_len >> 1)) { 948 reg = ACPIREG_GPE0_STS; 949 } 950 break; 951 case ACPIREG_GPE_EN: 952 __size = 1; 953 dnprintf(50, "read GPE_EN offset: %.2x %.2x %.2x\n", 954 offset, sc->sc_fadt->gpe0_blk_len>>1, 955 sc->sc_fadt->gpe1_blk_len>>1); 956 if (offset < (sc->sc_fadt->gpe0_blk_len >> 1)) { 957 reg = ACPIREG_GPE0_EN; 958 } 959 break; 960 } 961 962 if (reg >= ACPIREG_MAXREG || sc->sc_pmregs[reg].size == 0) 963 return (0); 964 965 regval = 0; 966 ioh = sc->sc_pmregs[reg].ioh; 967 size = sc->sc_pmregs[reg].size; 968 if (__size) 969 size = __size; 970 if (size > 4) 971 size = 4; 972 973 switch (size) { 974 case 1: 975 regval = bus_space_read_1(sc->sc_iot, ioh, offset); 976 break; 977 case 2: 978 regval = bus_space_read_2(sc->sc_iot, ioh, offset); 979 break; 980 case 4: 981 regval = bus_space_read_4(sc->sc_iot, ioh, offset); 982 break; 983 } 984 985 dnprintf(30, "acpi_readpm: %s = %.4x:%.4x %x\n", 986 sc->sc_pmregs[reg].name, 987 sc->sc_pmregs[reg].addr, offset, regval); 988 return (regval); 989} 990 991/* Write to power management register */ 992void 993acpi_write_pmreg(struct acpi_softc *sc, int reg, int offset, int regval) 994{ 995 bus_space_handle_t ioh; 996 bus_size_t size, __size; 997 998 __size = 0; 999 /* Special cases: 1A/1B blocks can be written with same value */ 1000 switch (reg) { 1001 case ACPIREG_PM1_EN: 1002 acpi_write_pmreg(sc, ACPIREG_PM1A_EN, offset, regval); 1003 acpi_write_pmreg(sc, ACPIREG_PM1B_EN, offset, regval); 1004 break; 1005 case ACPIREG_PM1_STS: 1006 acpi_write_pmreg(sc, ACPIREG_PM1A_STS, offset, regval); 1007 acpi_write_pmreg(sc, ACPIREG_PM1B_STS, offset, regval); 1008 break; 1009 case ACPIREG_PM1_CNT: 1010 acpi_write_pmreg(sc, ACPIREG_PM1A_CNT, offset, regval); 1011 acpi_write_pmreg(sc, ACPIREG_PM1B_CNT, offset, regval); 1012 break; 1013 case ACPIREG_GPE_STS: 1014 __size = 1; 1015 dnprintf(50, "write GPE_STS offset: %.2x %.2x %.2x %.2x\n", 1016 offset, sc->sc_fadt->gpe0_blk_len>>1, 1017 sc->sc_fadt->gpe1_blk_len>>1, regval); 1018 if (offset < (sc->sc_fadt->gpe0_blk_len >> 1)) { 1019 reg = ACPIREG_GPE0_STS; 1020 } 1021 break; 1022 case ACPIREG_GPE_EN: 1023 __size = 1; 1024 dnprintf(50, "write GPE_EN offset: %.2x %.2x %.2x %.2x\n", 1025 offset, sc->sc_fadt->gpe0_blk_len>>1, 1026 sc->sc_fadt->gpe1_blk_len>>1, regval); 1027 if (offset < (sc->sc_fadt->gpe0_blk_len >> 1)) { 1028 reg = ACPIREG_GPE0_EN; 1029 } 1030 break; 1031 } 1032 1033 /* All special case return here */ 1034 if (reg >= ACPIREG_MAXREG) 1035 return; 1036 1037 ioh = sc->sc_pmregs[reg].ioh; 1038 size = sc->sc_pmregs[reg].size; 1039 if (__size) 1040 size = __size; 1041 if (size > 4) 1042 size = 4; 1043 switch (size) { 1044 case 1: 1045 bus_space_write_1(sc->sc_iot, ioh, offset, regval); 1046 break; 1047 case 2: 1048 bus_space_write_2(sc->sc_iot, ioh, offset, regval); 1049 break; 1050 case 4: 1051 bus_space_write_4(sc->sc_iot, ioh, offset, regval); 1052 break; 1053 } 1054 1055 dnprintf(30, "acpi_writepm: %s = %.4x:%.4x %x\n", 1056 sc->sc_pmregs[reg].name, sc->sc_pmregs[reg].addr, offset, regval); 1057} 1058 1059/* Map Power Management registers */ 1060void 1061acpi_map_pmregs(struct acpi_softc *sc) 1062{ 1063 bus_addr_t addr; 1064 bus_size_t size; 1065 const char *name; 1066 int reg; 1067 1068 for (reg = 0; reg < ACPIREG_MAXREG; reg++) { 1069 size = 0; 1070 switch (reg) { 1071 case ACPIREG_SMICMD: 1072 name = "smi"; 1073 size = 1; 1074 addr = sc->sc_fadt->smi_cmd; 1075 break; 1076 case ACPIREG_PM1A_STS: 1077 case ACPIREG_PM1A_EN: 1078 name = "pm1a_sts"; 1079 size = sc->sc_fadt->pm1_evt_len >> 1; 1080 addr = sc->sc_fadt->pm1a_evt_blk; 1081 if (reg == ACPIREG_PM1A_EN && addr) { 1082 addr += size; 1083 name = "pm1a_en"; 1084 } 1085 break; 1086 case ACPIREG_PM1A_CNT: 1087 name = "pm1a_cnt"; 1088 size = sc->sc_fadt->pm1_cnt_len; 1089 addr = sc->sc_fadt->pm1a_cnt_blk; 1090 break; 1091 case ACPIREG_PM1B_STS: 1092 case ACPIREG_PM1B_EN: 1093 name = "pm1b_sts"; 1094 size = sc->sc_fadt->pm1_evt_len >> 1; 1095 addr = sc->sc_fadt->pm1b_evt_blk; 1096 if (reg == ACPIREG_PM1B_EN && addr) { 1097 addr += size; 1098 name = "pm1b_en"; 1099 } 1100 break; 1101 case ACPIREG_PM1B_CNT: 1102 name = "pm1b_cnt"; 1103 size = sc->sc_fadt->pm1_cnt_len; 1104 addr = sc->sc_fadt->pm1b_cnt_blk; 1105 break; 1106 case ACPIREG_PM2_CNT: 1107 name = "pm2_cnt"; 1108 size = sc->sc_fadt->pm2_cnt_len; 1109 addr = sc->sc_fadt->pm2_cnt_blk; 1110 break; 1111#if 0 1112 case ACPIREG_PM_TMR: 1113 /* Allocated in acpitimer */ 1114 name = "pm_tmr"; 1115 size = sc->sc_fadt->pm_tmr_len; 1116 addr = sc->sc_fadt->pm_tmr_blk; 1117 break; 1118#endif 1119 case ACPIREG_GPE0_STS: 1120 case ACPIREG_GPE0_EN: 1121 name = "gpe0_sts"; 1122 size = sc->sc_fadt->gpe0_blk_len >> 1; 1123 addr = sc->sc_fadt->gpe0_blk; 1124 1125 dnprintf(20, "gpe0 block len : %x\n", 1126 sc->sc_fadt->gpe0_blk_len >> 1); 1127 dnprintf(20, "gpe0 block addr: %x\n", 1128 sc->sc_fadt->gpe0_blk); 1129 if (reg == ACPIREG_GPE0_EN && addr) { 1130 addr += size; 1131 name = "gpe0_en"; 1132 } 1133 break; 1134 case ACPIREG_GPE1_STS: 1135 case ACPIREG_GPE1_EN: 1136 name = "gpe1_sts"; 1137 size = sc->sc_fadt->gpe1_blk_len >> 1; 1138 addr = sc->sc_fadt->gpe1_blk; 1139 1140 dnprintf(20, "gpe1 block len : %x\n", 1141 sc->sc_fadt->gpe1_blk_len >> 1); 1142 dnprintf(20, "gpe1 block addr: %x\n", 1143 sc->sc_fadt->gpe1_blk); 1144 if (reg == ACPIREG_GPE1_EN && addr) { 1145 addr += size; 1146 name = "gpe1_en"; 1147 } 1148 break; 1149 } 1150 if (size && addr) { 1151 dnprintf(50, "mapping: %.4x %.4x %s\n", 1152 addr, size, name); 1153 1154 /* Size and address exist; map register space */ 1155 bus_space_map(sc->sc_iot, addr, size, 0, 1156 &sc->sc_pmregs[reg].ioh); 1157 1158 sc->sc_pmregs[reg].name = name; 1159 sc->sc_pmregs[reg].size = size; 1160 sc->sc_pmregs[reg].addr = addr; 1161 } 1162 } 1163} 1164 1165#ifndef SMALL_KERNEL 1166int 1167is_ata(struct aml_node *node) 1168{ 1169 return (aml_searchname(node, "_GTM") != NULL || 1170 aml_searchname(node, "_GTF") != NULL || 1171 aml_searchname(node, "_STM") != NULL || 1172 aml_searchname(node, "_SDD") != NULL); 1173} 1174 1175int 1176is_ejectable(struct aml_node *node) 1177{ 1178 return (aml_searchname(node, "_EJ0") != NULL); 1179} 1180 1181int 1182is_ejectable_bay(struct aml_node *node) 1183{ 1184 return ((is_ata(node) || is_ata(node->parent)) && is_ejectable(node)); 1185} 1186 1187int 1188acpiide_notify(struct aml_node *node, int ntype, void *arg) 1189{ 1190 struct idechnl *ide = arg; 1191 struct acpi_softc *sc = ide->sc; 1192 struct pciide_softc *wsc; 1193 struct device *dev; 1194 int b,d,f; 1195 int64_t sta; 1196 1197 if (aml_evalinteger(sc, node, "_STA", 0, NULL, &sta) != 0) 1198 return (0); 1199 1200 dnprintf(10, "IDE notify! %s %d status:%llx\n", aml_nodename(node), 1201 ntype, sta); 1202 1203 /* Walk device list looking for IDE device match */ 1204 TAILQ_FOREACH(dev, &alldevs, dv_list) { 1205 if (strcmp(dev->dv_cfdata->cf_driver->cd_name, "pciide")) 1206 continue; 1207 1208 wsc = (struct pciide_softc *)dev; 1209 pci_decompose_tag(NULL, wsc->sc_tag, &b, &d, &f); 1210 if (b != ACPI_PCI_BUS(ide->addr) || 1211 d != ACPI_PCI_DEV(ide->addr) || 1212 f != ACPI_PCI_FN(ide->addr)) 1213 continue; 1214 dnprintf(10, "Found pciide: %s %x.%x.%x channel:%llx\n", 1215 dev->dv_xname, b,d,f, ide->chnl); 1216 1217 if (sta == 0 && ide->sta) 1218 wdcdetach( 1219 &wsc->pciide_channels[ide->chnl].wdc_channel, 0); 1220 else if (sta && !ide->sta) 1221 wdcattach( 1222 &wsc->pciide_channels[ide->chnl].wdc_channel); 1223 ide->sta = sta; 1224 } 1225 return (0); 1226} 1227 1228int 1229acpi_foundide(struct aml_node *node, void *arg) 1230{ 1231 struct acpi_softc *sc = arg; 1232 struct aml_node *pp; 1233 struct idechnl *ide; 1234 union amlpci_t pi; 1235 int lvl; 1236 1237 /* Check if this is an ejectable bay */ 1238 if (!is_ejectable_bay(node)) 1239 return (0); 1240 1241 ide = malloc(sizeof(struct idechnl), M_DEVBUF, M_NOWAIT | M_ZERO); 1242 ide->sc = sc; 1243 1244 /* GTM/GTF can be at 2/3 levels: pciX.ideX.channelX[.driveX] */ 1245 lvl = 0; 1246 for (pp=node->parent; pp; pp=pp->parent) { 1247 lvl++; 1248 if (aml_searchname(pp, "_HID")) 1249 break; 1250 } 1251 1252 /* Get PCI address and channel */ 1253 if (lvl == 3) { 1254 aml_evalinteger(sc, node->parent, "_ADR", 0, NULL, 1255 &ide->chnl); 1256 aml_rdpciaddr(node->parent->parent, &pi); 1257 ide->addr = pi.addr; 1258 } else if (lvl == 4) { 1259 aml_evalinteger(sc, node->parent->parent, "_ADR", 0, NULL, 1260 &ide->chnl); 1261 aml_rdpciaddr(node->parent->parent->parent, &pi); 1262 ide->addr = pi.addr; 1263 } 1264 dnprintf(10, "%s %llx channel:%llx\n", 1265 aml_nodename(node), ide->addr, ide->chnl); 1266 1267 aml_evalinteger(sc, node, "_STA", 0, NULL, &ide->sta); 1268 dnprintf(10, "Got Initial STA: %llx\n", ide->sta); 1269 1270 aml_register_notify(node, "acpiide", acpiide_notify, ide, 0); 1271 return (0); 1272} 1273 1274void 1275acpi_reset(void) 1276{ 1277 struct acpi_fadt *fadt; 1278 u_int32_t reset_as, reset_len; 1279 u_int32_t value; 1280 1281 fadt = acpi_softc->sc_fadt; 1282 1283 /* 1284 * RESET_REG_SUP is not properly set in some implementations, 1285 * but not testing against it breaks more machines than it fixes 1286 */ 1287 if (acpi_softc->sc_revision <= 1 || 1288 !(fadt->flags & FADT_RESET_REG_SUP) || fadt->reset_reg.address == 0) 1289 return; 1290 1291 value = fadt->reset_value; 1292 1293 reset_as = fadt->reset_reg.register_bit_width / 8; 1294 if (reset_as == 0) 1295 reset_as = 1; 1296 1297 reset_len = fadt->reset_reg.access_size; 1298 if (reset_len == 0) 1299 reset_len = reset_as; 1300 1301 acpi_gasio(acpi_softc, ACPI_IOWRITE, 1302 fadt->reset_reg.address_space_id, 1303 fadt->reset_reg.address, reset_as, reset_len, &value); 1304 1305 delay(100000); 1306} 1307 1308int 1309acpi_interrupt(void *arg) 1310{ 1311 struct acpi_softc *sc = (struct acpi_softc *)arg; 1312 u_int32_t processed = 0, idx, jdx; 1313 u_int8_t sts, en; 1314 1315 dnprintf(40, "ACPI Interrupt\n"); 1316 for (idx = 0; idx < sc->sc_lastgpe; idx += 8) { 1317 sts = acpi_read_pmreg(sc, ACPIREG_GPE_STS, idx>>3); 1318 en = acpi_read_pmreg(sc, ACPIREG_GPE_EN, idx>>3); 1319 if (en & sts) { 1320 dnprintf(10, "GPE block: %.2x %.2x %.2x\n", idx, sts, 1321 en); 1322 /* Mask the GPE until it is serviced */ 1323 acpi_write_pmreg(sc, ACPIREG_GPE_EN, idx>>3, en & ~sts); 1324 for (jdx = 0; jdx < 8; jdx++) { 1325 if (en & sts & (1L << jdx)) { 1326 /* Signal this GPE */ 1327 sc->gpe_table[idx+jdx].active = 1; 1328 1329 /* 1330 * Edge interrupts need their STS bits 1331 * cleared now. Level interrupts will 1332 * have their STS bits cleared just 1333 * before they are re-enabled. 1334 */ 1335 if (sc->gpe_table[idx+jdx].edge) 1336 acpi_write_pmreg(sc, 1337 ACPIREG_GPE_STS, idx>>3, 1338 1L << jdx); 1339 processed = 1; 1340 } 1341 } 1342 } 1343 } 1344 1345 sts = acpi_read_pmreg(sc, ACPIREG_PM1_STS, 0); 1346 en = acpi_read_pmreg(sc, ACPIREG_PM1_EN, 0); 1347 if (sts & en) { 1348 dnprintf(10,"GEN interrupt: %.4x\n", sts & en); 1349 acpi_write_pmreg(sc, ACPIREG_PM1_EN, 0, en & ~sts); 1350 if (sts & ACPI_PM1_PWRBTN_STS) { 1351 acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0, 1352 ACPI_PM1_PWRBTN_STS); 1353 sc->sc_powerbtn = 1; 1354 } 1355 if (sts & ACPI_PM1_SLPBTN_STS) { 1356 acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0, 1357 ACPI_PM1_SLPBTN_STS); 1358 sc->sc_sleepbtn = 1; 1359 } 1360 processed = 1; 1361 } 1362 1363 if (processed) { 1364 acpi_wakeup(sc); 1365 } 1366 1367 return (processed); 1368} 1369 1370int 1371acpi_add_device(struct aml_node *node, void *arg) 1372{ 1373 static int nacpicpus = 0; 1374 struct device *self = arg; 1375 struct acpi_softc *sc = arg; 1376 struct acpi_attach_args aaa; 1377#ifdef MULTIPROCESSOR 1378 struct aml_value res; 1379 int proc_id = -1; 1380#endif 1381 1382 memset(&aaa, 0, sizeof(aaa)); 1383 aaa.aaa_node = node; 1384 aaa.aaa_iot = sc->sc_iot; 1385 aaa.aaa_memt = sc->sc_memt; 1386 if (node == NULL || node->value == NULL) 1387 return 0; 1388 1389 switch (node->value->type) { 1390 case AML_OBJTYPE_PROCESSOR: 1391 if (nacpicpus >= ncpus) 1392 return 0; 1393#ifdef MULTIPROCESSOR 1394 if (aml_evalnode(sc, aaa.aaa_node, 0, NULL, &res) == 0) { 1395 if (res.type == AML_OBJTYPE_PROCESSOR) 1396 proc_id = res.v_processor.proc_id; 1397 aml_freevalue(&res); 1398 } 1399 if (proc_id < -1 || proc_id >= LAPIC_MAP_SIZE || 1400 (acpi_lapic_flags[proc_id] & ACPI_PROC_ENABLE) == 0) 1401 return 0; 1402#endif 1403 nacpicpus++; 1404 1405 aaa.aaa_name = "acpicpu"; 1406 break; 1407 case AML_OBJTYPE_THERMZONE: 1408 aaa.aaa_name = "acpitz"; 1409 break; 1410 case AML_OBJTYPE_POWERRSRC: 1411 aaa.aaa_name = "acpipwrres"; 1412 break; 1413 default: 1414 return 0; 1415 } 1416 config_found(self, &aaa, acpi_print); 1417 return 0; 1418} 1419 1420void 1421acpi_enable_onegpe(struct acpi_softc *sc, int gpe, int enable) 1422{ 1423 uint8_t mask, en; 1424 int s; 1425 1426 /* Read enabled register */ 1427 s = spltty(); 1428 mask = (1L << (gpe & 7)); 1429 en = acpi_read_pmreg(sc, ACPIREG_GPE_EN, gpe>>3); 1430 dnprintf(50, "%sabling GPE %.2x (current: %sabled) %.2x\n", 1431 enable ? "en" : "dis", gpe, (en & mask) ? "en" : "dis", en); 1432 if (enable) 1433 en |= mask; 1434 else 1435 en &= ~mask; 1436 acpi_write_pmreg(sc, ACPIREG_GPE_EN, gpe>>3, en); 1437 splx(s); 1438} 1439 1440int 1441acpi_set_gpehandler(struct acpi_softc *sc, int gpe, int (*handler) 1442 (struct acpi_softc *, int, void *), void *arg, int edge) 1443{ 1444 struct gpe_block *ptbl; 1445 1446 ptbl = acpi_find_gpe(sc, gpe); 1447 if (ptbl == NULL || handler == NULL) 1448 return -EINVAL; 1449 if (ptbl->handler != NULL) { 1450 dnprintf(10, "error: GPE %.2x already enabled\n", gpe); 1451 return -EBUSY; 1452 } 1453 dnprintf(50, "Adding GPE handler %.2x (%s)\n", gpe, edge ? "edge" : "level"); 1454 ptbl->handler = handler; 1455 ptbl->arg = arg; 1456 ptbl->edge = edge; 1457 1458 return (0); 1459} 1460 1461int 1462acpi_gpe(struct acpi_softc *sc, int gpe, void *arg) 1463{ 1464 struct aml_node *node = arg; 1465 uint8_t mask, en; 1466 int s; 1467 1468 dnprintf(10, "handling GPE %.2x\n", gpe); 1469 aml_evalnode(sc, node, 0, NULL, NULL); 1470 1471 s = spltty(); 1472 mask = (1L << (gpe & 7)); 1473 if (!sc->gpe_table[gpe].edge) 1474 acpi_write_pmreg(sc, ACPIREG_GPE_STS, gpe>>3, mask); 1475 en = acpi_read_pmreg(sc, ACPIREG_GPE_EN, gpe>>3); 1476 acpi_write_pmreg(sc, ACPIREG_GPE_EN, gpe>>3, en | mask); 1477 splx(s); 1478 1479 return (0); 1480} 1481 1482/* Discover Devices that can wakeup the system 1483 * _PRW returns a package 1484 * pkg[0] = integer (FADT gpe bit) or package (gpe block,gpe bit) 1485 * pkg[1] = lowest sleep state 1486 * pkg[2+] = power resource devices (optional) 1487 * 1488 * To enable wakeup devices: 1489 * Evaluate _ON method in each power resource device 1490 * Evaluate _PSW method 1491 */ 1492int 1493acpi_foundprw(struct aml_node *node, void *arg) 1494{ 1495 struct acpi_softc *sc = arg; 1496 struct acpi_wakeq *wq; 1497 1498 wq = malloc(sizeof(struct acpi_wakeq), M_DEVBUF, M_NOWAIT | M_ZERO); 1499 if (wq == NULL) { 1500 return 0; 1501 } 1502 1503 wq->q_wakepkg = malloc(sizeof(struct aml_value), M_DEVBUF, 1504 M_NOWAIT | M_ZERO); 1505 if (wq->q_wakepkg == NULL) { 1506 free(wq, M_DEVBUF); 1507 return 0; 1508 } 1509 dnprintf(10, "Found _PRW (%s)\n", node->parent->name); 1510 aml_evalnode(sc, node, 0, NULL, wq->q_wakepkg); 1511 wq->q_node = node->parent; 1512 wq->q_gpe = -1; 1513 1514 /* Get GPE of wakeup device, and lowest sleep level */ 1515 if (wq->q_wakepkg->type == AML_OBJTYPE_PACKAGE && wq->q_wakepkg->length >= 2) { 1516 if (wq->q_wakepkg->v_package[0]->type == AML_OBJTYPE_INTEGER) { 1517 wq->q_gpe = wq->q_wakepkg->v_package[0]->v_integer; 1518 } 1519 if (wq->q_wakepkg->v_package[1]->type == AML_OBJTYPE_INTEGER) { 1520 wq->q_state = wq->q_wakepkg->v_package[1]->v_integer; 1521 } 1522 } 1523 SIMPLEQ_INSERT_TAIL(&sc->sc_wakedevs, wq, q_next); 1524 return 0; 1525} 1526 1527struct gpe_block * 1528acpi_find_gpe(struct acpi_softc *sc, int gpe) 1529{ 1530#if 1 1531 if (gpe >= sc->sc_lastgpe) 1532 return NULL; 1533 return &sc->gpe_table[gpe]; 1534#else 1535 SIMPLEQ_FOREACH(pgpe, &sc->sc_gpes, gpe_link) { 1536 if (gpe >= pgpe->start && gpe <= (pgpe->start+7)) 1537 return &pgpe->table[gpe & 7]; 1538 } 1539 return NULL; 1540#endif 1541} 1542 1543void 1544acpi_init_gpes(struct acpi_softc *sc) 1545{ 1546 struct aml_node *gpe; 1547 char name[12]; 1548 int idx, ngpe; 1549 1550 sc->sc_lastgpe = sc->sc_fadt->gpe0_blk_len << 2; 1551 if (sc->sc_fadt->gpe1_blk_len) { 1552 } 1553 dnprintf(50, "Last GPE: %.2x\n", sc->sc_lastgpe); 1554 1555 /* Allocate GPE table */ 1556 sc->gpe_table = malloc(sc->sc_lastgpe * sizeof(struct gpe_block), 1557 M_DEVBUF, M_WAITOK | M_ZERO); 1558 1559 ngpe = 0; 1560 1561 /* Clear GPE status */ 1562 for (idx = 0; idx < sc->sc_lastgpe; idx += 8) { 1563 acpi_write_pmreg(sc, ACPIREG_GPE_EN, idx>>3, 0); 1564 acpi_write_pmreg(sc, ACPIREG_GPE_STS, idx>>3, -1); 1565 } 1566 for (idx = 0; idx < sc->sc_lastgpe; idx++) { 1567 /* Search Level-sensitive GPES */ 1568 snprintf(name, sizeof(name), "\\_GPE._L%.2X", idx); 1569 gpe = aml_searchname(&aml_root, name); 1570 if (gpe != NULL) 1571 acpi_set_gpehandler(sc, idx, acpi_gpe, gpe, 0); 1572 if (gpe == NULL) { 1573 /* Search Edge-sensitive GPES */ 1574 snprintf(name, sizeof(name), "\\_GPE._E%.2X", idx); 1575 gpe = aml_searchname(&aml_root, name); 1576 if (gpe != NULL) 1577 acpi_set_gpehandler(sc, idx, acpi_gpe, gpe, 1); 1578 } 1579 } 1580 aml_find_node(&aml_root, "_PRW", acpi_foundprw, sc); 1581 sc->sc_maxgpe = ngpe; 1582} 1583 1584void 1585acpi_init_states(struct acpi_softc *sc) 1586{ 1587 struct aml_value res; 1588 char name[8]; 1589 int i; 1590 1591 for (i = ACPI_STATE_S0; i <= ACPI_STATE_S5; i++) { 1592 snprintf(name, sizeof(name), "_S%d_", i); 1593 sc->sc_sleeptype[i].slp_typa = -1; 1594 sc->sc_sleeptype[i].slp_typb = -1; 1595 if (aml_evalname(sc, &aml_root, name, 0, NULL, &res) == 0) { 1596 if (res.type == AML_OBJTYPE_PACKAGE) { 1597 sc->sc_sleeptype[i].slp_typa = aml_val2int(res.v_package[0]); 1598 sc->sc_sleeptype[i].slp_typb = aml_val2int(res.v_package[1]); 1599 } 1600 aml_freevalue(&res); 1601 } 1602 } 1603} 1604 1605void 1606acpi_init_pm(struct acpi_softc *sc) 1607{ 1608 sc->sc_tts = aml_searchname(&aml_root, "_TTS"); 1609 sc->sc_pts = aml_searchname(&aml_root, "_PTS"); 1610 sc->sc_wak = aml_searchname(&aml_root, "_WAK"); 1611 sc->sc_bfs = aml_searchname(&aml_root, "_BFS"); 1612 sc->sc_gts = aml_searchname(&aml_root, "_GTS"); 1613 sc->sc_sst = aml_searchname(&aml_root, "_SI_._SST"); 1614} 1615 1616void 1617acpi_susp_resume_gpewalk(struct acpi_softc *sc, int state, 1618 int wake_gpe_state) 1619{ 1620 struct acpi_wakeq *wentry; 1621 int idx; 1622 u_int32_t gpe; 1623 1624 /* Clear GPE status */ 1625 for (idx = 0; idx < sc->sc_lastgpe; idx += 8) { 1626 acpi_write_pmreg(sc, ACPIREG_GPE_EN, idx>>3, 0); 1627 acpi_write_pmreg(sc, ACPIREG_GPE_STS, idx>>3, -1); 1628 } 1629 1630 SIMPLEQ_FOREACH(wentry, &sc->sc_wakedevs, q_next) { 1631 dnprintf(10, "%.4s(S%d) gpe %.2x\n", wentry->q_node->name, 1632 wentry->q_state, 1633 wentry->q_gpe); 1634 1635 if (state <= wentry->q_state) 1636 acpi_enable_onegpe(sc, wentry->q_gpe, 1637 wake_gpe_state); 1638 } 1639 1640 /* If we are resuming (disabling wake GPEs), enable other GPEs */ 1641 1642 if (wake_gpe_state == 0) { 1643 for (gpe = 0; gpe < sc->sc_lastgpe; gpe++) { 1644 if (sc->gpe_table[gpe].handler) 1645 acpi_enable_onegpe(sc, gpe, 1); 1646 } 1647 } 1648} 1649 1650int 1651acpi_sleep_state(struct acpi_softc *sc, int state) 1652{ 1653 int ret; 1654 1655 switch (state) { 1656 case ACPI_STATE_S0: 1657 return (0); 1658 case ACPI_STATE_S4: 1659 return (EOPNOTSUPP); 1660 case ACPI_STATE_S5: 1661 break; 1662 case ACPI_STATE_S1: 1663 case ACPI_STATE_S2: 1664 case ACPI_STATE_S3: 1665 if (sc->sc_sleeptype[state].slp_typa == -1 || 1666 sc->sc_sleeptype[state].slp_typb == -1) 1667 return (EOPNOTSUPP); 1668 } 1669 1670 if ((ret = acpi_prepare_sleep_state(sc, state)) != 0) 1671 return (ret); 1672 1673 if (state != ACPI_STATE_S1) 1674 ret = acpi_sleep_machdep(sc, state); 1675 else 1676 ret = acpi_enter_sleep_state(sc, state); 1677 1678#ifndef SMALL_KERNEL 1679 if (state == ACPI_STATE_S3) 1680 acpi_resume(sc, state); 1681#endif /* !SMALL_KERNEL */ 1682 return (ret); 1683} 1684 1685int 1686acpi_enter_sleep_state(struct acpi_softc *sc, int state) 1687{ 1688 uint16_t rega, regb; 1689 int retries; 1690 1691 /* Clear WAK_STS bit */ 1692 acpi_write_pmreg(sc, ACPIREG_PM1_STS, 1, ACPI_PM1_WAK_STS); 1693 1694 /* Disable BM arbitration */ 1695 acpi_write_pmreg(sc, ACPIREG_PM2_CNT, 1, ACPI_PM2_ARB_DIS); 1696 1697 /* Write SLP_TYPx values */ 1698 rega = acpi_read_pmreg(sc, ACPIREG_PM1A_CNT, 0); 1699 regb = acpi_read_pmreg(sc, ACPIREG_PM1B_CNT, 0); 1700 rega &= ~(ACPI_PM1_SLP_TYPX_MASK | ACPI_PM1_SLP_EN); 1701 regb &= ~(ACPI_PM1_SLP_TYPX_MASK | ACPI_PM1_SLP_EN); 1702 rega |= ACPI_PM1_SLP_TYPX(sc->sc_sleeptype[state].slp_typa); 1703 regb |= ACPI_PM1_SLP_TYPX(sc->sc_sleeptype[state].slp_typb); 1704 acpi_write_pmreg(sc, ACPIREG_PM1A_CNT, 0, rega); 1705 acpi_write_pmreg(sc, ACPIREG_PM1B_CNT, 0, regb); 1706 1707 /* Set SLP_EN bit */ 1708 rega |= ACPI_PM1_SLP_EN; 1709 regb |= ACPI_PM1_SLP_EN; 1710 1711 /* 1712 * Let the machdep code flush caches and do any other necessary 1713 * tasks before going away. 1714 */ 1715 acpi_cpu_flush(sc, state); 1716 1717 acpi_write_pmreg(sc, ACPIREG_PM1A_CNT, 0, rega); 1718 acpi_write_pmreg(sc, ACPIREG_PM1B_CNT, 0, regb); 1719 1720 /* Loop on WAK_STS */ 1721 for (retries = 1000; retries > 0; retries--) { 1722 rega = acpi_read_pmreg(sc, ACPIREG_PM1A_STS, 0); 1723 regb = acpi_read_pmreg(sc, ACPIREG_PM1B_STS, 0); 1724 if (rega & ACPI_PM1_WAK_STS || 1725 regb & ACPI_PM1_WAK_STS) 1726 break; 1727 DELAY(10); 1728 } 1729 1730 return (-1); 1731} 1732 1733void 1734acpi_resume(struct acpi_softc *sc, int state) 1735{ 1736 struct aml_value env; 1737 1738 memset(&env, 0, sizeof(env)); 1739 env.type = AML_OBJTYPE_INTEGER; 1740 env.v_integer = sc->sc_state; 1741 1742 /* Force SCI_EN on resume to fix horribly broken machines */ 1743 acpi_write_pmreg(sc, ACPIREG_PM1_CNT, 0, ACPI_PM1_SCI_EN); 1744 1745 /* Clear fixed event status */ 1746 acpi_write_pmreg(sc, ACPIREG_PM1_STS, 1, 1747 ACPI_PM1_ALL_STS); 1748 1749 if (sc->sc_bfs) 1750 if (aml_evalnode(sc, sc->sc_bfs, 1, &env, NULL) != 0) { 1751 dnprintf(10, "%s evaluating method _BFS failed.\n", 1752 DEVNAME(sc)); 1753 } 1754 1755 if (sc->sc_wak) 1756 if (aml_evalnode(sc, sc->sc_wak, 1, &env, NULL) != 0) { 1757 dnprintf(10, "%s evaluating method _WAK failed.\n", 1758 DEVNAME(sc)); 1759 } 1760 1761 /* Reset the indicator lights to "waking" */ 1762 if (sc->sc_sst) { 1763 env.v_integer = ACPI_SST_WAKING; 1764 aml_evalnode(sc, sc->sc_sst, 1, &env, NULL); 1765 } 1766 1767 /* Disable wake GPEs */ 1768 acpi_susp_resume_gpewalk(sc, state, 0); 1769 1770 config_suspend(TAILQ_FIRST(&alldevs), DVACT_RESUME); 1771 1772 cold = 0; 1773 enable_intr(); 1774 splx(acpi_saved_spl); 1775 1776 acpi_resume_machdep(); 1777 1778 sc->sc_state = ACPI_STATE_S0; 1779 if (sc->sc_tts) { 1780 env.v_integer = sc->sc_state; 1781 if (aml_evalnode(sc, sc->sc_tts, 1, &env, NULL) != 0) { 1782 dnprintf(10, "%s evaluating method _TTS failed.\n", 1783 DEVNAME(sc)); 1784 } 1785 } 1786 1787 /* Reset the indicator lights to "working" */ 1788 if (sc->sc_sst) { 1789 env.v_integer = ACPI_SST_WORKING; 1790 aml_evalnode(sc, sc->sc_sst, 1, &env, NULL); 1791 } 1792 1793#ifdef MULTIPROCESSOR 1794 sched_start_secondary_cpus(); 1795#endif 1796 1797 acpi_record_event(sc, APM_NORMAL_RESUME); 1798 1799 bufq_restart(); 1800 1801#if NWSDISPLAY > 0 1802 wsdisplay_resume(); 1803#endif /* NWSDISPLAY > 0 */ 1804} 1805 1806void 1807acpi_handle_suspend_failure(struct acpi_softc *sc) 1808{ 1809 struct aml_value env; 1810 1811 /* Undo a partial suspend. Devices will have already been resumed */ 1812 cold = 0; 1813 enable_intr(); 1814 splx(acpi_saved_spl); 1815 1816 /* Tell ACPI to go back to S0 */ 1817 memset(&env, 0, sizeof(env)); 1818 env.type = AML_OBJTYPE_INTEGER; 1819 sc->sc_state = ACPI_STATE_S0; 1820 if (sc->sc_tts) { 1821 env.v_integer = sc->sc_state; 1822 if (aml_evalnode(sc, sc->sc_tts, 1, &env, NULL) != 0) { 1823 dnprintf(10, "%s evaluating method _TTS failed.\n", 1824 DEVNAME(sc)); 1825 } 1826 } 1827 1828 /* Reset the indicator lights to "working" */ 1829 if (sc->sc_sst) { 1830 env.v_integer = ACPI_SST_WORKING; 1831 aml_evalnode(sc, sc->sc_sst, 1, &env, NULL); 1832 } 1833 1834#ifdef MULTIPROCESSOR 1835 sched_start_secondary_cpus(); 1836#endif 1837} 1838 1839int 1840acpi_prepare_sleep_state(struct acpi_softc *sc, int state) 1841{ 1842 struct aml_value env; 1843 int error = 0; 1844 1845 if (sc == NULL || state == ACPI_STATE_S0) 1846 return(0); 1847 1848 if (sc->sc_sleeptype[state].slp_typa == -1 || 1849 sc->sc_sleeptype[state].slp_typb == -1) { 1850 printf("%s: state S%d unavailable\n", 1851 sc->sc_dev.dv_xname, state); 1852 return (ENXIO); 1853 } 1854 1855#ifdef MULTIPROCESSOR 1856 sched_stop_secondary_cpus(); 1857 KASSERT(CPU_IS_PRIMARY(curcpu())); 1858#endif 1859 1860 memset(&env, 0, sizeof(env)); 1861 env.type = AML_OBJTYPE_INTEGER; 1862 env.v_integer = state; 1863 /* _TTS(state) */ 1864 if (sc->sc_tts) 1865 if (aml_evalnode(sc, sc->sc_tts, 1, &env, NULL) != 0) { 1866 dnprintf(10, "%s evaluating method _TTS failed.\n", 1867 DEVNAME(sc)); 1868 return (ENXIO); 1869 } 1870 1871#if NWSDISPLAY > 0 1872 if (state == ACPI_STATE_S3) 1873 wsdisplay_suspend(); 1874#endif /* NWSDISPLAY > 0 */ 1875 1876 bufq_quiesce(); 1877 1878 acpi_saved_spl = splhigh(); 1879 disable_intr(); 1880 cold = 1; 1881 if (state == ACPI_STATE_S3) 1882 if (config_suspend(TAILQ_FIRST(&alldevs), DVACT_SUSPEND) != 0) { 1883 acpi_handle_suspend_failure(sc); 1884 error = ENXIO; 1885 goto fail; 1886 } 1887 1888 /* _PTS(state) */ 1889 if (sc->sc_pts) 1890 if (aml_evalnode(sc, sc->sc_pts, 1, &env, NULL) != 0) { 1891 dnprintf(10, "%s evaluating method _PTS failed.\n", 1892 DEVNAME(sc)); 1893 error = ENXIO; 1894 goto fail; 1895 } 1896 1897 sc->sc_state = state; 1898 /* _GTS(state) */ 1899 if (sc->sc_gts) 1900 if (aml_evalnode(sc, sc->sc_gts, 1, &env, NULL) != 0) { 1901 dnprintf(10, "%s evaluating method _GTS failed.\n", 1902 DEVNAME(sc)); 1903 error = ENXIO; 1904 goto fail; 1905 } 1906 1907 /* Clear fixed event status */ 1908 acpi_write_pmreg(sc, ACPIREG_PM1_STS, 1, 1909 ACPI_PM1_ALL_STS); 1910 1911 /* Enable wake GPEs */ 1912 acpi_susp_resume_gpewalk(sc, state, 1); 1913 1914fail: 1915 if (error) { 1916 bufq_restart(); 1917 1918#if NWSDISPLAY > 0 1919 wsdisplay_resume(); 1920#endif /* NWSDISPLAY > 0 */ 1921 } 1922 1923 return (error); 1924} 1925 1926void 1927acpi_wakeup(void *arg) 1928{ 1929 struct acpi_softc *sc = (struct acpi_softc *)arg; 1930 1931 sc->sc_threadwaiting = 0; 1932 wakeup(sc); 1933} 1934 1935void 1936acpi_powerdown(void) 1937{ 1938 /* 1939 * In case acpi_prepare_sleep fails, we shouldn't try to enter 1940 * the sleep state. It might cost us the battery. 1941 */ 1942 acpi_susp_resume_gpewalk(acpi_softc, ACPI_STATE_S5, 1); 1943 if (acpi_prepare_sleep_state(acpi_softc, ACPI_STATE_S5) == 0) 1944 acpi_enter_sleep_state(acpi_softc, ACPI_STATE_S5); 1945} 1946 1947void 1948acpi_thread(void *arg) 1949{ 1950 struct acpi_thread *thread = arg; 1951 struct acpi_softc *sc = thread->sc; 1952 extern int aml_busy; 1953 u_int32_t gpe; 1954 int s; 1955 1956 /* 1957 * If we have an interrupt handler, we can get notification 1958 * when certain status bits changes in the ACPI registers, 1959 * so let us enable some events we can forward to userland 1960 */ 1961 if (sc->sc_interrupt) { 1962 int16_t flag; 1963 1964 dnprintf(1,"slpbtn:%c pwrbtn:%c\n", 1965 sc->sc_fadt->flags & FADT_SLP_BUTTON ? 'n' : 'y', 1966 sc->sc_fadt->flags & FADT_PWR_BUTTON ? 'n' : 'y'); 1967 dnprintf(10, "Enabling acpi interrupts...\n"); 1968 sc->sc_threadwaiting = 1; 1969 1970 /* Enable Sleep/Power buttons if they exist */ 1971 s = spltty(); 1972 flag = acpi_read_pmreg(sc, ACPIREG_PM1_EN, 0); 1973 if (!(sc->sc_fadt->flags & FADT_PWR_BUTTON)) { 1974 flag |= ACPI_PM1_PWRBTN_EN; 1975 } 1976 if (!(sc->sc_fadt->flags & FADT_SLP_BUTTON)) { 1977 flag |= ACPI_PM1_SLPBTN_EN; 1978 } 1979 acpi_write_pmreg(sc, ACPIREG_PM1_EN, 0, flag); 1980 splx(s); 1981 1982 /* Enable handled GPEs here */ 1983 for (gpe = 0; gpe < sc->sc_lastgpe; gpe++) { 1984 if (sc->gpe_table[gpe].handler) 1985 acpi_enable_onegpe(sc, gpe, 1); 1986 } 1987 } 1988 1989 while (thread->running) { 1990 s = spltty(); 1991 while (sc->sc_threadwaiting) { 1992 dnprintf(10, "acpi going to sleep...\n"); 1993 tsleep(sc, PWAIT, "acpi0", 0); 1994 } 1995 sc->sc_threadwaiting = 1; 1996 splx(s); 1997 if (aml_busy) { 1998 panic("thread woke up to find aml was busy"); 1999 continue; 2000 } 2001 2002 for (gpe = 0; gpe < sc->sc_lastgpe; gpe++) { 2003 struct gpe_block *pgpe = &sc->gpe_table[gpe]; 2004 2005 if (pgpe->active) { 2006 pgpe->active = 0; 2007 dnprintf(50, "softgpe: %.2x\n", gpe); 2008 if (pgpe->handler) 2009 pgpe->handler(sc, gpe, pgpe->arg); 2010 } 2011 } 2012 if (sc->sc_powerbtn) { 2013 uint8_t en; 2014 2015 sc->sc_powerbtn = 0; 2016 dnprintf(1,"power button pressed\n"); 2017 aml_notify_dev(ACPI_DEV_PBD, 0x80); 2018 2019 /* Reset the latch and re-enable the GPE */ 2020 s = spltty(); 2021 en = acpi_read_pmreg(sc, ACPIREG_PM1_EN, 0); 2022 acpi_write_pmreg(sc, ACPIREG_PM1_EN, 0, 2023 en | ACPI_PM1_PWRBTN_STS); 2024 splx(s); 2025 2026 } 2027 if (sc->sc_sleepbtn) { 2028 uint8_t en; 2029 2030 sc->sc_sleepbtn = 0; 2031 dnprintf(1,"sleep button pressed\n"); 2032 aml_notify_dev(ACPI_DEV_SBD, 0x80); 2033 2034 /* Reset the latch and re-enable the GPE */ 2035 s = spltty(); 2036 en = acpi_read_pmreg(sc, ACPIREG_PM1_EN, 0); 2037 acpi_write_pmreg(sc, ACPIREG_PM1_EN, 0, 2038 en | ACPI_PM1_SLPBTN_STS); 2039 splx(s); 2040 } 2041 2042 /* handle polling here to keep code non-concurrent*/ 2043 if (sc->sc_poll) { 2044 sc->sc_poll = 0; 2045 acpi_poll_notify(); 2046 } 2047 2048 if (sc->sc_sleepmode) { 2049 int sleepmode = sc->sc_sleepmode; 2050 2051 sc->sc_sleepmode = 0; 2052 acpi_sleep_state(sc, sleepmode); 2053 continue; 2054 } 2055 } 2056 free(thread, M_DEVBUF); 2057 2058 kthread_exit(0); 2059} 2060 2061void 2062acpi_create_thread(void *arg) 2063{ 2064 struct acpi_softc *sc = arg; 2065 2066 if (kthread_create(acpi_thread, sc->sc_thread, NULL, DEVNAME(sc)) 2067 != 0) 2068 printf("%s: unable to create isr thread, GPEs disabled\n", 2069 DEVNAME(sc)); 2070} 2071 2072int 2073acpi_map_address(struct acpi_softc *sc, struct acpi_gas *gas, bus_addr_t base, 2074 bus_size_t size, bus_space_handle_t *pioh, bus_space_tag_t *piot) 2075{ 2076 int iospace = GAS_SYSTEM_IOSPACE; 2077 2078 /* No GAS structure, default to I/O space */ 2079 if (gas != NULL) { 2080 base += gas->address; 2081 iospace = gas->address_space_id; 2082 } 2083 switch (iospace) { 2084 case GAS_SYSTEM_MEMORY: 2085 *piot = sc->sc_memt; 2086 break; 2087 case GAS_SYSTEM_IOSPACE: 2088 *piot = sc->sc_iot; 2089 break; 2090 default: 2091 return -1; 2092 } 2093 if (bus_space_map(*piot, base, size, 0, pioh)) 2094 return -1; 2095 2096 return 0; 2097} 2098 2099int 2100acpi_foundec(struct aml_node *node, void *arg) 2101{ 2102 struct acpi_softc *sc = (struct acpi_softc *)arg; 2103 struct device *self = (struct device *)arg; 2104 const char *dev; 2105 struct aml_value res; 2106 struct acpi_attach_args aaa; 2107 2108 if (aml_evalnode(sc, node, 0, NULL, &res) != 0) 2109 return 0; 2110 2111 switch (res.type) { 2112 case AML_OBJTYPE_STRING: 2113 dev = res.v_string; 2114 break; 2115 case AML_OBJTYPE_INTEGER: 2116 dev = aml_eisaid(aml_val2int(&res)); 2117 break; 2118 default: 2119 dev = "unknown"; 2120 break; 2121 } 2122 2123 if (strcmp(dev, ACPI_DEV_ECD)) 2124 return 0; 2125 2126 memset(&aaa, 0, sizeof(aaa)); 2127 aaa.aaa_iot = sc->sc_iot; 2128 aaa.aaa_memt = sc->sc_memt; 2129 aaa.aaa_node = node->parent; 2130 aaa.aaa_dev = dev; 2131 aaa.aaa_name = "acpiec"; 2132 config_found(self, &aaa, acpi_print); 2133 aml_freevalue(&res); 2134 2135 return 0; 2136} 2137 2138int 2139acpi_foundhid(struct aml_node *node, void *arg) 2140{ 2141 struct acpi_softc *sc = (struct acpi_softc *)arg; 2142 struct device *self = (struct device *)arg; 2143 const char *dev; 2144 struct aml_value res; 2145 struct acpi_attach_args aaa; 2146 2147 dnprintf(10, "found hid device: %s ", node->parent->name); 2148 if (aml_evalnode(sc, node, 0, NULL, &res) != 0) 2149 return 0; 2150 2151 switch (res.type) { 2152 case AML_OBJTYPE_STRING: 2153 dev = res.v_string; 2154 break; 2155 case AML_OBJTYPE_INTEGER: 2156 dev = aml_eisaid(aml_val2int(&res)); 2157 break; 2158 default: 2159 dev = "unknown"; 2160 break; 2161 } 2162 dnprintf(10, " device: %s\n", dev); 2163 2164 memset(&aaa, 0, sizeof(aaa)); 2165 aaa.aaa_iot = sc->sc_iot; 2166 aaa.aaa_memt = sc->sc_memt; 2167 aaa.aaa_node = node->parent; 2168 aaa.aaa_dev = dev; 2169 2170 if (!strcmp(dev, ACPI_DEV_AC)) 2171 aaa.aaa_name = "acpiac"; 2172 else if (!strcmp(dev, ACPI_DEV_CMB)) 2173 aaa.aaa_name = "acpibat"; 2174 else if (!strcmp(dev, ACPI_DEV_LD) || 2175 !strcmp(dev, ACPI_DEV_PBD) || 2176 !strcmp(dev, ACPI_DEV_SBD)) 2177 aaa.aaa_name = "acpibtn"; 2178 else if (!strcmp(dev, ACPI_DEV_ASUS)) 2179 aaa.aaa_name = "acpiasus"; 2180 else if (!strcmp(dev, ACPI_DEV_THINKPAD)) { 2181 aaa.aaa_name = "acpithinkpad"; 2182 acpi_thinkpad_enabled = 1; 2183 } else if (!strcmp(dev, ACPI_DEV_ASUSAIBOOSTER)) 2184 aaa.aaa_name = "aibs"; 2185 2186 if (aaa.aaa_name) 2187 config_found(self, &aaa, acpi_print); 2188 2189 aml_freevalue(&res); 2190 2191 return 0; 2192} 2193 2194int 2195acpi_founddock(struct aml_node *node, void *arg) 2196{ 2197 struct acpi_softc *sc = (struct acpi_softc *)arg; 2198 struct device *self = (struct device *)arg; 2199 struct acpi_attach_args aaa; 2200 2201 dnprintf(10, "found dock entry: %s\n", node->parent->name); 2202 2203 memset(&aaa, 0, sizeof(aaa)); 2204 aaa.aaa_iot = sc->sc_iot; 2205 aaa.aaa_memt = sc->sc_memt; 2206 aaa.aaa_node = node->parent; 2207 aaa.aaa_name = "acpidock"; 2208 2209 config_found(self, &aaa, acpi_print); 2210 2211 return 0; 2212} 2213 2214int 2215acpi_foundvideo(struct aml_node *node, void *arg) 2216{ 2217 struct acpi_softc *sc = (struct acpi_softc *)arg; 2218 struct device *self = (struct device *)arg; 2219 struct acpi_attach_args aaa; 2220 2221 memset(&aaa, 0, sizeof(aaa)); 2222 aaa.aaa_iot = sc->sc_iot; 2223 aaa.aaa_memt = sc->sc_memt; 2224 aaa.aaa_node = node->parent; 2225 aaa.aaa_name = "acpivideo"; 2226 2227 config_found(self, &aaa, acpi_print); 2228 2229 return (0); 2230} 2231 2232int 2233acpiopen(dev_t dev, int flag, int mode, struct proc *p) 2234{ 2235 int error = 0; 2236 struct acpi_softc *sc; 2237 int s; 2238 2239 if (!acpi_cd.cd_ndevs || APMUNIT(dev) != 0 || 2240 !(sc = acpi_cd.cd_devs[APMUNIT(dev)])) 2241 return (ENXIO); 2242 2243 s = spltty(); 2244 switch (APMDEV(dev)) { 2245 case APMDEV_CTL: 2246 if (!(flag & FWRITE)) { 2247 error = EINVAL; 2248 break; 2249 } 2250 if (sc->sc_flags & SCFLAG_OWRITE) { 2251 error = EBUSY; 2252 break; 2253 } 2254 sc->sc_flags |= SCFLAG_OWRITE; 2255 break; 2256 case APMDEV_NORMAL: 2257 if (!(flag & FREAD) || (flag & FWRITE)) { 2258 error = EINVAL; 2259 break; 2260 } 2261 sc->sc_flags |= SCFLAG_OREAD; 2262 break; 2263 default: 2264 error = ENXIO; 2265 break; 2266 } 2267 splx(s); 2268 return (error); 2269} 2270 2271int 2272acpiclose(dev_t dev, int flag, int mode, struct proc *p) 2273{ 2274 int error = 0; 2275 struct acpi_softc *sc; 2276 int s; 2277 2278 if (!acpi_cd.cd_ndevs || APMUNIT(dev) != 0 || 2279 !(sc = acpi_cd.cd_devs[APMUNIT(dev)])) 2280 return (ENXIO); 2281 2282 s = spltty(); 2283 switch (APMDEV(dev)) { 2284 case APMDEV_CTL: 2285 sc->sc_flags &= ~SCFLAG_OWRITE; 2286 break; 2287 case APMDEV_NORMAL: 2288 sc->sc_flags &= ~SCFLAG_OREAD; 2289 break; 2290 default: 2291 error = ENXIO; 2292 break; 2293 } 2294 splx(s); 2295 return (error); 2296} 2297 2298int 2299acpiioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) 2300{ 2301 int error = 0; 2302 struct acpi_softc *sc; 2303 struct acpi_ac *ac; 2304 struct acpi_bat *bat; 2305 struct apm_power_info *pi = (struct apm_power_info *)data; 2306 int bats; 2307 unsigned int remaining, rem, minutes, rate; 2308 int s; 2309 2310 if (!acpi_cd.cd_ndevs || APMUNIT(dev) != 0 || 2311 !(sc = acpi_cd.cd_devs[APMUNIT(dev)])) 2312 return (ENXIO); 2313 2314 s = spltty(); 2315 /* fake APM */ 2316 switch (cmd) { 2317 case APM_IOC_SUSPEND: 2318 case APM_IOC_STANDBY: 2319 sc->sc_sleepmode = ACPI_STATE_S3; 2320 acpi_wakeup(sc); 2321 break; 2322 case APM_IOC_GETPOWER: 2323 /* A/C */ 2324 pi->ac_state = APM_AC_UNKNOWN; 2325 SLIST_FOREACH(ac, &sc->sc_ac, aac_link) { 2326 if (ac->aac_softc->sc_ac_stat == PSR_ONLINE) 2327 pi->ac_state = APM_AC_ON; 2328 else if (ac->aac_softc->sc_ac_stat == PSR_OFFLINE) 2329 if (pi->ac_state == APM_AC_UNKNOWN) 2330 pi->ac_state = APM_AC_OFF; 2331 } 2332 2333 /* battery */ 2334 pi->battery_state = APM_BATT_UNKNOWN; 2335 pi->battery_life = 0; 2336 pi->minutes_left = 0; 2337 bats = 0; 2338 remaining = rem = 0; 2339 minutes = 0; 2340 rate = 0; 2341 SLIST_FOREACH(bat, &sc->sc_bat, aba_link) { 2342 if (bat->aba_softc->sc_bat_present == 0) 2343 continue; 2344 2345 if (bat->aba_softc->sc_bif.bif_last_capacity == 0) 2346 continue; 2347 2348 bats++; 2349 rem = (bat->aba_softc->sc_bst.bst_capacity * 100) / 2350 bat->aba_softc->sc_bif.bif_last_capacity; 2351 if (rem > 100) 2352 rem = 100; 2353 remaining += rem; 2354 2355 if (bat->aba_softc->sc_bst.bst_rate == BST_UNKNOWN) 2356 continue; 2357 else if (bat->aba_softc->sc_bst.bst_rate > 1) 2358 rate = bat->aba_softc->sc_bst.bst_rate; 2359 2360 minutes += bat->aba_softc->sc_bst.bst_capacity; 2361 } 2362 2363 if (bats == 0) { 2364 pi->battery_state = APM_BATTERY_ABSENT; 2365 pi->battery_life = 0; 2366 pi->minutes_left = (unsigned int)-1; 2367 break; 2368 } 2369 2370 if (pi->ac_state == APM_AC_ON || rate == 0) 2371 pi->minutes_left = (unsigned int)-1; 2372 else 2373 pi->minutes_left = 60 * minutes / rate; 2374 2375 /* running on battery */ 2376 pi->battery_life = remaining / bats; 2377 if (pi->battery_life > 50) 2378 pi->battery_state = APM_BATT_HIGH; 2379 else if (pi->battery_life > 25) 2380 pi->battery_state = APM_BATT_LOW; 2381 else 2382 pi->battery_state = APM_BATT_CRITICAL; 2383 2384 break; 2385 2386 default: 2387 error = ENOTTY; 2388 } 2389 2390 splx(s); 2391 return (error); 2392} 2393 2394void acpi_filtdetach(struct knote *); 2395int acpi_filtread(struct knote *, long); 2396 2397struct filterops acpiread_filtops = { 2398 1, NULL, acpi_filtdetach, acpi_filtread 2399}; 2400 2401int acpi_evindex; 2402 2403int 2404acpi_record_event(struct acpi_softc *sc, u_int type) 2405{ 2406 if ((sc->sc_flags & SCFLAG_OPEN) == 0) 2407 return (1); 2408 2409 acpi_evindex++; 2410 KNOTE(sc->sc_note, APM_EVENT_COMPOSE(type, acpi_evindex)); 2411 return (0); 2412} 2413 2414void 2415acpi_filtdetach(struct knote *kn) 2416{ 2417 struct acpi_softc *sc = kn->kn_hook; 2418 int s; 2419 2420 s = spltty(); 2421 SLIST_REMOVE(sc->sc_note, kn, knote, kn_selnext); 2422 splx(s); 2423} 2424 2425int 2426acpi_filtread(struct knote *kn, long hint) 2427{ 2428 /* XXX weird kqueue_scan() semantics */ 2429 if (hint && !kn->kn_data) 2430 kn->kn_data = hint; 2431 return (1); 2432} 2433 2434int 2435acpikqfilter(dev_t dev, struct knote *kn) 2436{ 2437 struct acpi_softc *sc; 2438 int s; 2439 2440 if (!acpi_cd.cd_ndevs || APMUNIT(dev) != 0 || 2441 !(sc = acpi_cd.cd_devs[APMUNIT(dev)])) 2442 return (ENXIO); 2443 2444 switch (kn->kn_filter) { 2445 case EVFILT_READ: 2446 kn->kn_fop = &acpiread_filtops; 2447 break; 2448 default: 2449 return (1); 2450 } 2451 2452 kn->kn_hook = sc; 2453 2454 s = spltty(); 2455 SLIST_INSERT_HEAD(sc->sc_note, kn, kn_selnext); 2456 splx(s); 2457 2458 return (0); 2459} 2460 2461#else /* SMALL_KERNEL */ 2462 2463int 2464acpiopen(dev_t dev, int flag, int mode, struct proc *p) 2465{ 2466 return (ENXIO); 2467} 2468 2469int 2470acpiclose(dev_t dev, int flag, int mode, struct proc *p) 2471{ 2472 return (ENXIO); 2473} 2474 2475int 2476acpiioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) 2477{ 2478 return (ENXIO); 2479} 2480 2481int 2482acpikqfilter(dev_t dev, struct knote *kn) 2483{ 2484 return (1); 2485} 2486 2487#endif /* SMALL_KERNEL */ 2488