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.
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.
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]
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.
28 * Solaris x86 ACPI CA Embedded Controller operation region handler
32 #include <sys/errno.h>
34 #include <sys/modctl.h>
38 #include <sys/sunddi.h>
40 #include <sys/atomic.h>
42 #include <sys/acpi/acpi.h>
43 #include <sys/acpica.h>
51 * Data register is command byte?
73 #define IO_PORT_DES (0x47)
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 */
88 /* I/O port range descriptor */
89 typedef struct io_port_des
{
101 * Patchable to ignore an ECDT, in case using that
102 * causes problems on someone's system.
104 int ec_ignore_ecdt
= 0;
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.
111 int ibf_clear_timeout
= 100000;
112 int obf_set_timeout
= 100000;
115 * ACPI CA EC address space handler support functions
119 * Busy-wait for IBF to clear
120 * return < 0 for time out, 0 for no error
123 ec_wait_ibf_clear(int sc_addr
)
127 cnt
= ibf_clear_timeout
;
128 while (inb(sc_addr
) & EC_IBF
) {
137 * Busy-wait for OBF to set
138 * return < 0 for time out, 0 for no error
141 ec_wait_obf_set(int sc_addr
)
145 cnt
= obf_set_timeout
;
146 while (!(inb(sc_addr
) & EC_OBF
)) {
155 * Only called from ec_handler(), which validates ec_ok
163 mutex_enter(&ec
.ec_mutex
);
168 cmn_err(CE_NOTE
, "!ec_rd: IBF already set");
172 cmn_err(CE_NOTE
, "!ec_rd: OBF already set");
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 "
180 mutex_exit(&ec
.ec_mutex
);
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 "
188 mutex_exit(&ec
.ec_mutex
);
191 if (ec_wait_obf_set(ec
.ec_sc
) < 0) {
192 cmn_err(CE_NOTE
, "!ec_rd:1: timed-out waiting "
194 mutex_exit(&ec
.ec_mutex
);
198 rv
= inb(ec
.ec_base
);
199 mutex_exit(&ec
.ec_mutex
);
204 * Only called from ec_handler(), which validates ec_ok
207 ec_wr(int addr
, uint8_t val
)
212 mutex_enter(&ec
.ec_mutex
);
217 cmn_err(CE_NOTE
, "!ec_wr: IBF already set");
221 cmn_err(CE_NOTE
, "!ec_wr: OBF already set");
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 "
229 mutex_exit(&ec
.ec_mutex
);
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 "
237 mutex_exit(&ec
.ec_mutex
);
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 "
245 mutex_exit(&ec
.ec_mutex
);
249 mutex_exit(&ec
.ec_mutex
);
254 * Only called from ec_gpe_callback(), which validates ec_ok
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 "
267 mutex_exit(&ec
.ec_mutex
);
271 if (ec_wait_obf_set(ec
.ec_sc
) < 0) {
272 cmn_err(CE_NOTE
, "!ec_query:1: timed-out waiting "
274 mutex_exit(&ec
.ec_mutex
);
278 rv
= inb(ec
.ec_base
);
279 mutex_exit(&ec
.ec_mutex
);
284 * ACPI CA EC address space handler
285 * Requires: ec.ec_sc, ec.ec_base
288 ec_handler(UINT32 func
, ACPI_PHYSICAL_ADDRESS addr
, UINT32 width
,
289 UINT64
*val
, void *context
, void *regcontext
)
291 _NOTE(ARGUNUSED(context
, regcontext
))
294 /* Guard against unexpected invocation */
299 * Add safety checks for BIOSes not strictly compliant
302 if ((width
% 8) != 0) {
303 cmn_err(CE_NOTE
, "!ec_handler: invalid width %d", width
);
304 return (AE_BAD_PARAMETER
);
307 cmn_err(CE_NOTE
, "!ec_handler: NULL value pointer");
308 return (AE_BAD_PARAMETER
);
313 /* One UINT64 *val at a time. */
316 if (func
== ACPI_READ
)
319 /* Do I/O of up to 64 bits */
320 for (i
= 0; i
< tw
; i
+= 8, addr
++) {
326 *val
|= ((UINT64
)tmp
) << i
;
329 tmp
= ((*val
) >> i
) & 0xFF;
330 if (ec_wr(addr
, (uint8_t)tmp
) < 0)
345 * Called via taskq entry enqueued by ec_gpe_handler,
346 * which validates ec_ok
349 ec_gpe_callback(void *ctx
)
351 _NOTE(ARGUNUSED(ctx
))
355 if (!(inb(ec
.ec_sc
) & EC_SCI
))
362 (void) snprintf(query_str
, 5, "_Q%02X", (uint8_t)query
);
363 (void) AcpiEvaluateObject(ec
.ec_dev_hdl
, query_str
, NULL
, NULL
);
366 AcpiFinishGpe(ec
.ec_gpe_hdl
, ec
.ec_gpe_bit
);
370 ec_gpe_handler(ACPI_HANDLE GpeDevice
, UINT32 GpeNumber
, void *ctx
)
372 _NOTE(ARGUNUSED(GpeDevice
))
373 _NOTE(ARGUNUSED(GpeNumber
))
374 _NOTE(ARGUNUSED(ctx
))
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.
383 return (ACPI_REENABLE_GPE
);
385 AcpiOsExecute(OSL_GPE_HANDLER
, ec_gpe_callback
, NULL
);
388 * Returning zero tells the ACPI system that we will
389 * handle this event asynchronously.
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.
402 ACPI_TABLE_HEADER
*th
;
403 ACPI_TABLE_ECDT
*ecdt
;
407 status
= AcpiGetTable(ACPI_SIG_ECDT
, 1, &th
);
409 if (status
== AE_NOT_FOUND
)
412 if (ACPI_FAILURE(status
)) {
413 cmn_err(CE_NOTE
, "!acpica: ECDT not found");
416 if (ec_ignore_ecdt
) {
417 /* pretend it was not found */
418 cmn_err(CE_NOTE
, "!acpica: ECDT ignored");
419 return (AE_NOT_FOUND
);
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
);
428 status
= AcpiGetHandle(NULL
, (char *)ecdt
->Id
, &dev_hdl
);
429 if (ACPI_FAILURE(status
)) {
430 cmn_err(CE_NOTE
, "!acpica: no ECDT device handle");
435 * Success. Save info for attach.
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
;
445 cmn_err(CE_NOTE
, "!acpica:ec_probe_ecdt: success");
451 * Called from AcpiWalkDevices() when an EC device is found
454 ec_find(ACPI_HANDLE obj
, UINT32 nest
, void *context
, void **rv
)
456 _NOTE(ARGUNUSED(nest
, rv
))
458 *((ACPI_HANDLE
*)context
) = obj
;
463 * Normal way to get the details about the EC,
464 * by searching the name space.
470 ACPI_BUFFER buf
, crs
;
471 ACPI_OBJECT
*gpe_obj
;
473 ACPI_INTEGER gpe_bit
;
476 uint16_t ec_sc
, ec_base
;
479 (void) AcpiGetDevices("PNP0C09", &ec_find
, (void *)&dev_hdl
, NULL
);
480 if (dev_hdl
== NULL
) {
482 /* Not an error, just no EC on this machine. */
483 cmn_err(CE_WARN
, "!acpica:ec_probe_ns: "
484 "PNP0C09 not found");
486 return (AE_NOT_FOUND
);
490 * Find ec_base and ec_sc addresses
492 crs
.Length
= ACPI_ALLOCATE_BUFFER
;
493 status
= AcpiEvaluateObjectTyped(dev_hdl
, "_CRS", NULL
, &crs
,
495 if (ACPI_FAILURE(status
)) {
496 cmn_err(CE_WARN
, "!acpica:ec_probe_ns: "
497 "_CRS object evaluate failed");
501 for (i
= 0, io_port_cnt
= 0;
502 i
< ((ACPI_OBJECT
*)crs
.Pointer
)->Buffer
.Length
; i
++) {
503 io_port_des_t
*io_port
;
506 tmp
= ((ACPI_OBJECT
*)crs
.Pointer
)->Buffer
.Pointer
+ i
;
507 if (*tmp
!= IO_PORT_DES
)
509 io_port
= (io_port_des_t
*)tmp
;
511 * first port is ec_base and second is ec_sc
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
;
522 * Increment ahead to next struct.
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
);
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");
543 gpe_obj
= (ACPI_OBJECT
*)buf
.Pointer
;
545 * process the GPE description
547 switch (gpe_obj
->Type
) {
548 case ACPI_TYPE_INTEGER
:
550 gpe_bit
= gpe_obj
->Integer
.Value
;
552 case ACPI_TYPE_PACKAGE
:
553 if (gpe_obj
->Package
.Count
!= 2)
555 gpe_obj
= gpe_obj
->Package
.Elements
;
556 if (gpe_obj
[1].Type
!= ACPI_TYPE_INTEGER
)
558 gpe_hdl
= gpe_obj
[0].Reference
.Handle
;
559 gpe_bit
= gpe_obj
[1].Integer
.Value
;
563 status
= AE_BAD_VALUE
;
566 AcpiOsFree(buf
.Pointer
);
567 if (ACPI_FAILURE(status
)) {
568 cmn_err(CE_WARN
, "!acpica:ec_probe_ns: "
569 "_GPE parse failed");
574 * Success. Save info for attach.
576 ec
.ec_base
= ec_base
;
578 ec
.ec_dev_hdl
= dev_hdl
;
579 ec
.ec_gpe_hdl
= gpe_hdl
;
580 ec
.ec_gpe_bit
= gpe_bit
;
584 cmn_err(CE_NOTE
, "!acpica:ec_probe_ns: success");
590 * Setup the Embedded Controller (EC) address space handler.
591 * Entered only if one of the EC probe methods found an EC.
604 * Drain the EC data register if something is left over from
607 if (inb(ec
.ec_sc
) & EC_OBF
) {
608 x
= inb(ec
.ec_base
); /* read and discard value */
610 cmn_err(CE_NOTE
, "!EC had something: 0x%x", x
);
615 * Install an "EC address space" handler.
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.
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.
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)
635 rc
= AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT
,
636 ACPI_ADR_SPACE_EC
, &ec_handler
, NULL
, NULL
);
638 cmn_err(CE_WARN
, "!acpica:ec_init: "
639 "install AS handler, rc=0x%x", rc
);
643 cmn_err(CE_NOTE
, "!acpica:ec_init: success");
648 * Attach the EC General-Purpose Event (GPE) handler.
656 * Guard against call without probe results.
659 cmn_err(CE_WARN
, "!acpica:ec_attach: "
660 "no EC device found");
665 * Install the GPE handler and enable it.
667 rc
= AcpiInstallGpeHandler(ec
.ec_gpe_hdl
, ec
.ec_gpe_bit
,
668 ACPI_GPE_EDGE_TRIGGERED
, ec_gpe_handler
, NULL
);
670 cmn_err(CE_WARN
, "!acpica:ec_attach: "
671 "install GPE handler, rc=0x%x", rc
);
675 rc
= AcpiEnableGpe(ec
.ec_gpe_hdl
, ec
.ec_gpe_bit
);
677 cmn_err(CE_WARN
, "!acpica:ec_attach: "
678 "enable GPE handler, rc=0x%x", rc
);
683 cmn_err(CE_NOTE
, "!acpica:ec_attach: success");
688 AcpiRemoveGpeHandler(ec
.ec_gpe_hdl
, ec
.ec_gpe_bit
,
693 * System Management Bus Controller (SMBC)
694 * These also go through the EC.
695 * (not yet supported)
704 (void) AcpiGetDevices("ACPI0001", &ec_find
, (void *)&obj
, NULL
);
706 cmn_err(CE_NOTE
, "!acpica: found an SMBC Version 1.0");
710 (void) AcpiGetDevices("ACPI0005", &ec_find
, (void *)&obj
, NULL
);
712 cmn_err(CE_NOTE
, "!acpica: found an SMBC Version 2.0");
718 * Initialize the EC, if present.
726 * Initialize EC mutex here
728 mutex_init(&ec
.ec_mutex
, NULL
, MUTEX_DRIVER
, NULL
);
731 * First search the ACPI tables for an ECDT, and
732 * if not found, search the name space for it.
734 rc
= ec_probe_ecdt();
735 if (ACPI_FAILURE(rc
))
737 if (ACPI_SUCCESS(rc
)) {