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