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