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