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 }