1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 * Copyright 2011 Joyent, Inc. All rights reserved. 26 * Copyright 2013 Nexenta Systems, Inc. All rights reserved. 27 */ 28 29 /* 30 * x86 ACPI CA Embedded Controller operation region handler 31 */ 32 33 #include <sys/file.h> 34 #include <sys/errno.h> 35 #include <sys/conf.h> 36 #include <sys/modctl.h> 37 #include <sys/open.h> 38 #include <sys/stat.h> 39 #include <sys/ddi.h> 40 #include <sys/sunddi.h> 41 #include <sys/note.h> 42 #include <sys/atomic.h> 43 44 #include <acpica/include/acpi.h> 45 #include <sys/acpica.h> 46 47 /* 48 * EC status bits 49 * Low to high 50 * Output buffer full? 51 * Input buffer full? 52 * <reserved> 53 * Data register is command byte? 54 * Burst mode enabled? 55 * SCI event? 56 * SMI event? 57 * <reserved> 58 */ 59 #define EC_OBF (0x01) 60 #define EC_IBF (0x02) 61 #define EC_DRC (0x08) 62 #define EC_BME (0x10) 63 #define EC_SCI (0x20) 64 #define EC_SMI (0x40) 65 66 /* 67 * EC commands 68 */ 69 #define EC_RD (0x80) 70 #define EC_WR (0x81) 71 #define EC_BE (0x82) 72 #define EC_BD (0x83) 73 #define EC_QR (0x84) 74 75 #define IO_PORT_DES (0x47) 76 77 /* 78 * EC softstate 79 */ 80 static struct ec_softstate { 81 uint8_t ec_ok; /* != 0 if we have ec_base, ec_sc */ 82 uint16_t ec_base; /* base of EC I/O port - data */ 83 uint16_t ec_sc; /* EC status/command */ 84 ACPI_HANDLE ec_dev_hdl; /* EC device handle */ 85 ACPI_HANDLE ec_gpe_hdl; /* GPE info */ 86 ACPI_INTEGER ec_gpe_bit; 87 kmutex_t ec_mutex; /* serialize access to EC */ 88 } ec; 89 90 /* I/O port range descriptor */ 91 typedef struct io_port_des { 92 uint8_t type; 93 uint8_t decode; 94 uint8_t min_base_lo; 95 uint8_t min_base_hi; 96 uint8_t max_base_lo; 97 uint8_t max_base_hi; 98 uint8_t align; 99 uint8_t len; 100 } io_port_des_t; 101 102 /* 103 * Patchable to ignore an ECDT, in case using that 104 * causes problems on someone's system. 105 */ 106 int ec_ignore_ecdt = 0; 107 108 /* 109 * Patchable timeout values for EC input-buffer-full-clear 110 * and output-buffer-full-set. These are in 10uS units and 111 * default to 1 second. 112 */ 113 int ibf_clear_timeout = 100000; 114 int obf_set_timeout = 100000; 115 116 /* 117 * ACPI CA EC address space handler support functions 118 */ 119 120 /* 121 * Busy-wait for IBF to clear 122 * return < 0 for time out, 0 for no error 123 */ 124 static int 125 ec_wait_ibf_clear(int sc_addr) 126 { 127 int cnt; 128 129 cnt = ibf_clear_timeout; 130 while (inb(sc_addr) & EC_IBF) { 131 if (cnt-- <= 0) 132 return (-1); 133 drv_usecwait(10); 134 } 135 return (0); 136 } 137 138 /* 139 * Busy-wait for OBF to set 140 * return < 0 for time out, 0 for no error 141 */ 142 static int 143 ec_wait_obf_set(int sc_addr) 144 { 145 int cnt; 146 147 cnt = obf_set_timeout; 148 while (!(inb(sc_addr) & EC_OBF)) { 149 if (cnt-- <= 0) 150 return (-1); 151 drv_usecwait(10); 152 } 153 return (0); 154 } 155 156 /* 157 * Only called from ec_handler(), which validates ec_ok 158 */ 159 static int 160 ec_rd(int addr) 161 { 162 int cnt, rv; 163 uint8_t sc; 164 165 mutex_enter(&ec.ec_mutex); 166 sc = inb(ec.ec_sc); 167 168 #ifdef DEBUG 169 if (sc & EC_IBF) { 170 cmn_err(CE_NOTE, "!ec_rd: IBF already set"); 171 } 172 173 if (sc & EC_OBF) { 174 cmn_err(CE_NOTE, "!ec_rd: OBF already set"); 175 } 176 #endif 177 178 outb(ec.ec_sc, EC_RD); /* output a read command */ 179 if (ec_wait_ibf_clear(ec.ec_sc) < 0) { 180 cmn_err(CE_NOTE, "!ec_rd:1: timed-out waiting " 181 "for IBF to clear"); 182 mutex_exit(&ec.ec_mutex); 183 return (-1); 184 } 185 186 outb(ec.ec_base, addr); /* output addr */ 187 if (ec_wait_ibf_clear(ec.ec_sc) < 0) { 188 cmn_err(CE_NOTE, "!ec_rd:2: timed-out waiting " 189 "for IBF to clear"); 190 mutex_exit(&ec.ec_mutex); 191 return (-1); 192 } 193 if (ec_wait_obf_set(ec.ec_sc) < 0) { 194 cmn_err(CE_NOTE, "!ec_rd:1: timed-out waiting " 195 "for OBF to set"); 196 mutex_exit(&ec.ec_mutex); 197 return (-1); 198 } 199 200 rv = inb(ec.ec_base); 201 mutex_exit(&ec.ec_mutex); 202 return (rv); 203 } 204 205 /* 206 * Only called from ec_handler(), which validates ec_ok 207 */ 208 static int 209 ec_wr(int addr, uint8_t val) 210 { 211 int cnt; 212 uint8_t sc; 213 214 mutex_enter(&ec.ec_mutex); 215 sc = inb(ec.ec_sc); 216 217 #ifdef DEBUG 218 if (sc & EC_IBF) { 219 cmn_err(CE_NOTE, "!ec_wr: IBF already set"); 220 } 221 222 if (sc & EC_OBF) { 223 cmn_err(CE_NOTE, "!ec_wr: OBF already set"); 224 } 225 #endif 226 227 outb(ec.ec_sc, EC_WR); /* output a write command */ 228 if (ec_wait_ibf_clear(ec.ec_sc) < 0) { 229 cmn_err(CE_NOTE, "!ec_wr:1: timed-out waiting " 230 "for IBF to clear"); 231 mutex_exit(&ec.ec_mutex); 232 return (-1); 233 } 234 235 outb(ec.ec_base, addr); /* output addr */ 236 if (ec_wait_ibf_clear(ec.ec_sc) < 0) { 237 cmn_err(CE_NOTE, "!ec_wr:2: timed-out waiting " 238 "for IBF to clear"); 239 mutex_exit(&ec.ec_mutex); 240 return (-1); 241 } 242 243 outb(ec.ec_base, val); /* write data */ 244 if (ec_wait_ibf_clear(ec.ec_sc) < 0) { 245 cmn_err(CE_NOTE, "!ec_wr:3: timed-out waiting " 246 "for IBF to clear"); 247 mutex_exit(&ec.ec_mutex); 248 return (-1); 249 } 250 251 mutex_exit(&ec.ec_mutex); 252 return (0); 253 } 254 255 /* 256 * Only called from ec_gpe_callback(), which validates ec_ok 257 */ 258 static int 259 ec_query(void) 260 { 261 int cnt, rv; 262 uint8_t sc; 263 264 mutex_enter(&ec.ec_mutex); 265 outb(ec.ec_sc, EC_QR); /* output a query command */ 266 if (ec_wait_ibf_clear(ec.ec_sc) < 0) { 267 cmn_err(CE_NOTE, "!ec_query:1: timed-out waiting " 268 "for IBF to clear"); 269 mutex_exit(&ec.ec_mutex); 270 return (-1); 271 } 272 273 if (ec_wait_obf_set(ec.ec_sc) < 0) { 274 cmn_err(CE_NOTE, "!ec_query:1: timed-out waiting " 275 "for OBF to set"); 276 mutex_exit(&ec.ec_mutex); 277 return (-1); 278 } 279 280 rv = inb(ec.ec_base); 281 mutex_exit(&ec.ec_mutex); 282 return (rv); 283 } 284 285 /* 286 * ACPI CA EC address space handler 287 * Requires: ec.ec_sc, ec.ec_base 288 */ 289 static ACPI_STATUS 290 ec_handler(UINT32 func, ACPI_PHYSICAL_ADDRESS addr, UINT32 width, 291 UINT64 *val, void *context, void *regcontext) 292 { 293 _NOTE(ARGUNUSED(context, regcontext)) 294 int i, tw, tmp; 295 296 /* Guard against unexpected invocation */ 297 if (ec.ec_ok == 0) 298 return (AE_ERROR); 299 300 /* 301 * Add safety checks for BIOSes not strictly compliant 302 * with ACPI spec 303 */ 304 if ((width % 8) != 0) { 305 cmn_err(CE_NOTE, "!ec_handler: invalid width %d", width); 306 return (AE_BAD_PARAMETER); 307 } 308 if (val == NULL) { 309 cmn_err(CE_NOTE, "!ec_handler: NULL value pointer"); 310 return (AE_BAD_PARAMETER); 311 } 312 313 while (width > 0) { 314 315 /* One UINT64 *val at a time. */ 316 tw = min(width, 64); 317 318 if (func == ACPI_READ) 319 *val = 0; 320 321 /* Do I/O of up to 64 bits */ 322 for (i = 0; i < tw; i += 8, addr++) { 323 switch (func) { 324 case ACPI_READ: 325 tmp = ec_rd(addr); 326 if (tmp < 0) 327 return (AE_ERROR); 328 *val |= ((UINT64)tmp) << i; 329 break; 330 case ACPI_WRITE: 331 tmp = ((*val) >> i) & 0xFF; 332 if (ec_wr(addr, (uint8_t)tmp) < 0) 333 return (AE_ERROR); 334 break; 335 default: 336 return (AE_ERROR); 337 } 338 } 339 val++; 340 width -= tw; 341 } 342 343 return (AE_OK); 344 } 345 346 /* 347 * Called via taskq entry enqueued by ec_gpe_handler, 348 * which validates ec_ok 349 */ 350 static void 351 ec_gpe_callback(void *ctx) 352 { 353 _NOTE(ARGUNUSED(ctx)) 354 char query_str[5]; 355 int query; 356 357 if (!(inb(ec.ec_sc) & EC_SCI)) 358 goto out; 359 360 query = ec_query(); 361 if (query < 0) 362 goto out; 363 364 (void) snprintf(query_str, 5, "_Q%02X", (uint8_t)query); 365 (void) AcpiEvaluateObject(ec.ec_dev_hdl, query_str, NULL, NULL); 366 367 out: 368 AcpiFinishGpe(ec.ec_gpe_hdl, ec.ec_gpe_bit); 369 } 370 371 static UINT32 372 ec_gpe_handler(ACPI_HANDLE GpeDevice, UINT32 GpeNumber, void *ctx) 373 { 374 _NOTE(ARGUNUSED(GpeDevice)) 375 _NOTE(ARGUNUSED(GpeNumber)) 376 _NOTE(ARGUNUSED(ctx)) 377 378 /* 379 * With ec_ok==0, we will not install a GPE handler, 380 * so this is just paranoia. But if this were to 381 * happen somehow, don't add the taskq entry, and 382 * tell the caller we're done with this GPE call. 383 */ 384 if (ec.ec_ok == 0) 385 return (ACPI_REENABLE_GPE); 386 387 AcpiOsExecute(OSL_GPE_HANDLER, ec_gpe_callback, NULL); 388 389 /* 390 * Returning zero tells the ACPI system that we will 391 * handle this event asynchronously. 392 */ 393 return (0); 394 } 395 396 /* 397 * Some systems describe the EC using an "ECDT" (table). 398 * If we find one use it (unless ec_ignore_ecdt is set). 399 * Modern systems don't provide an ECDT. 400 */ 401 static ACPI_STATUS 402 ec_probe_ecdt(void) 403 { 404 ACPI_TABLE_HEADER *th; 405 ACPI_TABLE_ECDT *ecdt; 406 ACPI_HANDLE dev_hdl; 407 ACPI_STATUS status; 408 409 status = AcpiGetTable(ACPI_SIG_ECDT, 1, &th); 410 #ifndef DEBUG 411 if (status == AE_NOT_FOUND) 412 return (status); 413 #endif 414 if (ACPI_FAILURE(status)) { 415 cmn_err(CE_NOTE, "!acpica: ECDT not found"); 416 return (status); 417 } 418 if (ec_ignore_ecdt) { 419 /* pretend it was not found */ 420 cmn_err(CE_NOTE, "!acpica: ECDT ignored"); 421 return (AE_NOT_FOUND); 422 } 423 424 ecdt = (ACPI_TABLE_ECDT *)th; 425 if (ecdt->Control.BitWidth != 8 || 426 ecdt->Data.BitWidth != 8) { 427 cmn_err(CE_NOTE, "!acpica: bad ECDT I/O width"); 428 return (AE_BAD_VALUE); 429 } 430 status = AcpiGetHandle(NULL, (char *)ecdt->Id, &dev_hdl); 431 if (ACPI_FAILURE(status)) { 432 cmn_err(CE_NOTE, "!acpica: no ECDT device handle"); 433 return (status); 434 } 435 436 /* 437 * Success. Save info for attach. 438 */ 439 ec.ec_base = ecdt->Data.Address; 440 ec.ec_sc = ecdt->Control.Address; 441 ec.ec_dev_hdl = dev_hdl; 442 ec.ec_gpe_hdl = NULL; 443 ec.ec_gpe_bit = ecdt->Gpe; 444 ec.ec_ok = 1; 445 446 #ifdef DEBUG 447 cmn_err(CE_NOTE, "!acpica:ec_probe_ecdt: success"); 448 #endif 449 return (0); 450 } 451 452 /* 453 * Called from AcpiWalkDevices() when an EC device is found 454 */ 455 static ACPI_STATUS 456 ec_find(ACPI_HANDLE obj, UINT32 nest, void *context, void **rv) 457 { 458 _NOTE(ARGUNUSED(nest, rv)) 459 460 *((ACPI_HANDLE *)context) = obj; 461 return (AE_OK); 462 } 463 464 /* 465 * Normal way to get the details about the EC, 466 * by searching the name space. 467 */ 468 static ACPI_STATUS 469 ec_probe_ns(void) 470 { 471 ACPI_HANDLE dev_hdl; 472 ACPI_BUFFER buf, crs; 473 ACPI_OBJECT *gpe_obj; 474 ACPI_HANDLE gpe_hdl; 475 ACPI_INTEGER gpe_bit; 476 ACPI_STATUS status; 477 int i, io_port_cnt; 478 uint16_t ec_sc, ec_base; 479 480 dev_hdl = NULL; 481 (void) AcpiGetDevices("PNP0C09", &ec_find, (void *)&dev_hdl, NULL); 482 if (dev_hdl == NULL) { 483 #ifdef DEBUG 484 /* Not an error, just no EC on this machine. */ 485 cmn_err(CE_WARN, "!acpica:ec_probe_ns: " 486 "PNP0C09 not found"); 487 #endif 488 return (AE_NOT_FOUND); 489 } 490 491 /* 492 * Find ec_base and ec_sc addresses 493 */ 494 crs.Length = ACPI_ALLOCATE_BUFFER; 495 status = AcpiEvaluateObjectTyped(dev_hdl, "_CRS", NULL, &crs, 496 ACPI_TYPE_BUFFER); 497 if (ACPI_FAILURE(status)) { 498 cmn_err(CE_WARN, "!acpica:ec_probe_ns: " 499 "_CRS object evaluate failed"); 500 return (status); 501 } 502 503 for (i = 0, io_port_cnt = 0; 504 i < ((ACPI_OBJECT *)crs.Pointer)->Buffer.Length; i++) { 505 io_port_des_t *io_port; 506 uint8_t *tmp; 507 508 tmp = ((ACPI_OBJECT *)crs.Pointer)->Buffer.Pointer + i; 509 if (*tmp != IO_PORT_DES) 510 continue; 511 io_port = (io_port_des_t *)tmp; 512 /* 513 * first port is ec_base and second is ec_sc 514 */ 515 if (io_port_cnt == 0) 516 ec_base = (io_port->min_base_hi << 8) | 517 io_port->min_base_lo; 518 if (io_port_cnt == 1) 519 ec_sc = (io_port->min_base_hi << 8) | 520 io_port->min_base_lo; 521 522 io_port_cnt++; 523 /* 524 * Increment ahead to next struct. 525 */ 526 i += 7; 527 } 528 AcpiOsFree(crs.Pointer); 529 if (io_port_cnt < 2) { 530 cmn_err(CE_WARN, "!acpica:ec_probe_ns: " 531 "_CRS parse failed"); 532 return (AE_BAD_VALUE); 533 } 534 535 /* 536 * Get the GPE info. 537 */ 538 buf.Length = ACPI_ALLOCATE_BUFFER; 539 status = AcpiEvaluateObject(dev_hdl, "_GPE", NULL, &buf); 540 if (ACPI_FAILURE(status)) { 541 cmn_err(CE_WARN, "!acpica:ec_probe_ns: " 542 "_GPE object evaluate"); 543 return (status); 544 } 545 gpe_obj = (ACPI_OBJECT *)buf.Pointer; 546 /* 547 * process the GPE description 548 */ 549 switch (gpe_obj->Type) { 550 case ACPI_TYPE_INTEGER: 551 gpe_hdl = NULL; 552 gpe_bit = gpe_obj->Integer.Value; 553 break; 554 case ACPI_TYPE_PACKAGE: 555 if (gpe_obj->Package.Count != 2) 556 goto bad_gpe; 557 gpe_obj = gpe_obj->Package.Elements; 558 if (gpe_obj[1].Type != ACPI_TYPE_INTEGER) 559 goto bad_gpe; 560 gpe_hdl = gpe_obj[0].Reference.Handle; 561 gpe_bit = gpe_obj[1].Integer.Value; 562 break; 563 bad_gpe: 564 default: 565 status = AE_BAD_VALUE; 566 break; 567 } 568 AcpiOsFree(buf.Pointer); 569 if (ACPI_FAILURE(status)) { 570 cmn_err(CE_WARN, "!acpica:ec_probe_ns: " 571 "_GPE parse failed"); 572 return (status); 573 } 574 575 /* 576 * Success. Save info for attach. 577 */ 578 ec.ec_base = ec_base; 579 ec.ec_sc = ec_sc; 580 ec.ec_dev_hdl = dev_hdl; 581 ec.ec_gpe_hdl = gpe_hdl; 582 ec.ec_gpe_bit = gpe_bit; 583 ec.ec_ok = 1; 584 585 #ifdef DEBUG 586 cmn_err(CE_NOTE, "!acpica:ec_probe_ns: success"); 587 #endif 588 return (0); 589 } 590 591 /* 592 * Setup the Embedded Controller (EC) address space handler. 593 * Entered only if one of the EC probe methods found an EC. 594 */ 595 static void 596 ec_init(void) 597 { 598 ACPI_STATUS rc; 599 int x; 600 601 /* paranoia */ 602 if (ec.ec_ok == 0) 603 return; 604 605 /* 606 * Drain the EC data register if something is left over from 607 * legacy mode 608 */ 609 if (inb(ec.ec_sc) & EC_OBF) { 610 x = inb(ec.ec_base); /* read and discard value */ 611 #ifdef DEBUG 612 cmn_err(CE_NOTE, "!EC had something: 0x%x", x); 613 #endif 614 } 615 616 /* 617 * Install an "EC address space" handler. 618 * 619 * This call does a name space walk under the passed 620 * object looking for child objects with an EC space 621 * region for which to install this handler. Using 622 * the ROOT object makes sure we find them all. 623 * 624 * XXX: Some systems return an error from this call 625 * after a partial success, i.e. where the NS walk 626 * installs on some nodes and fails on other nodes. 627 * In such cases, disabling the EC and GPE handlers 628 * makes things worse, so just report the error and 629 * leave the EC handler enabled. 630 * 631 * At one point, it seemed that doing this part of 632 * EC setup earlier may help, which is why this is 633 * now a separate function from ec_attach. Someone 634 * needs to figure our why some systems give us an 635 * error return from this call. (TODO) 636 */ 637 rc = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT, 638 ACPI_ADR_SPACE_EC, &ec_handler, NULL, NULL); 639 if (rc != AE_OK) { 640 cmn_err(CE_WARN, "!acpica:ec_init: " 641 "install AS handler, rc=0x%x", rc); 642 return; 643 } 644 #ifdef DEBUG 645 cmn_err(CE_NOTE, "!acpica:ec_init: success"); 646 #endif 647 } 648 649 /* 650 * Attach the EC General-Purpose Event (GPE) handler. 651 */ 652 static void 653 ec_attach(void) 654 { 655 ACPI_STATUS rc; 656 657 /* 658 * Guard against call without probe results. 659 */ 660 if (ec.ec_ok == 0) { 661 cmn_err(CE_WARN, "!acpica:ec_attach: " 662 "no EC device found"); 663 return; 664 } 665 666 /* 667 * Install the GPE handler and enable it. 668 */ 669 rc = AcpiInstallGpeHandler(ec.ec_gpe_hdl, ec.ec_gpe_bit, 670 ACPI_GPE_EDGE_TRIGGERED, ec_gpe_handler, NULL); 671 if (rc != AE_OK) { 672 cmn_err(CE_WARN, "!acpica:ec_attach: " 673 "install GPE handler, rc=0x%x", rc); 674 goto errout; 675 } 676 677 rc = AcpiEnableGpe(ec.ec_gpe_hdl, ec.ec_gpe_bit); 678 if (rc != AE_OK) { 679 cmn_err(CE_WARN, "!acpica:ec_attach: " 680 "enable GPE handler, rc=0x%x", rc); 681 goto errout; 682 } 683 684 #ifdef DEBUG 685 cmn_err(CE_NOTE, "!acpica:ec_attach: success"); 686 #endif 687 return; 688 689 errout: 690 AcpiRemoveGpeHandler(ec.ec_gpe_hdl, ec.ec_gpe_bit, 691 ec_gpe_handler); 692 } 693 694 /* 695 * System Management Bus Controller (SMBC) 696 * These also go through the EC. 697 * (not yet supported) 698 */ 699 static void 700 smbus_attach(void) 701 { 702 #ifdef DEBUG 703 ACPI_HANDLE obj; 704 705 obj = NULL; 706 (void) AcpiGetDevices("ACPI0001", &ec_find, (void *)&obj, NULL); 707 if (obj != NULL) { 708 cmn_err(CE_NOTE, "!acpica: found an SMBC Version 1.0"); 709 } 710 711 obj = NULL; 712 (void) AcpiGetDevices("ACPI0005", &ec_find, (void *)&obj, NULL); 713 if (obj != NULL) { 714 cmn_err(CE_NOTE, "!acpica: found an SMBC Version 2.0"); 715 } 716 #endif /* DEBUG */ 717 } 718 719 /* 720 * Initialize the EC, if present. 721 */ 722 void 723 acpica_ec_init(void) 724 { 725 ACPI_STATUS rc; 726 727 /* 728 * Initialize EC mutex here 729 */ 730 mutex_init(&ec.ec_mutex, NULL, MUTEX_DRIVER, NULL); 731 732 /* 733 * First search the ACPI tables for an ECDT, and 734 * if not found, search the name space for it. 735 */ 736 rc = ec_probe_ecdt(); 737 if (ACPI_FAILURE(rc)) 738 rc = ec_probe_ns(); 739 if (ACPI_SUCCESS(rc)) { 740 ec_init(); 741 ec_attach(); 742 } 743 smbus_attach(); 744 }