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