1 /******************************************************************************
2 *
3 * Module Name: aehandlers - Various handlers for acpiexec
4 *
5 *****************************************************************************/
6
7 /******************************************************************************
8 *
9 * 1. Copyright Notice
10 *
11 * Some or all of this work - Copyright (c) 1999 - 2014, Intel Corp.
12 * All rights reserved.
13 *
14 * 2. License
15 *
16 * 2.1. This is your license from Intel Corp. under its intellectual property
17 * rights. You may have additional license terms from the party that provided
18 * you this software, covering your right to use that party's intellectual
19 * property rights.
20 *
21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22 * copy of the source code appearing in this file ("Covered Code") an
23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24 * base code distributed originally by Intel ("Original Intel Code") to copy,
25 * make derivatives, distribute, use and display any portion of the Covered
26 * Code in any form, with the right to sublicense such rights; and
27 *
28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29 * license (with the right to sublicense), under only those claims of Intel
30 * patents that are infringed by the Original Intel Code, to make, use, sell,
31 * offer to sell, and import the Covered Code and derivative works thereof
32 * solely to the minimum extent necessary to exercise the above copyright
33 * license, and in no event shall the patent license extend to any additions
34 * to or modifications of the Original Intel Code. No other license or right
35 * is granted directly or by implication, estoppel or otherwise;
36 *
37 * The above copyright and patent license is granted only if the following
38 * conditions are met:
39 *
40 * 3. Conditions
41 *
42 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43 * Redistribution of source code of any substantial portion of the Covered
44 * Code or modification with rights to further distribute source must include
45 * the above Copyright Notice, the above License, this list of Conditions,
46 * and the following Disclaimer and Export Compliance provision. In addition,
47 * Licensee must cause all Covered Code to which Licensee contributes to
48 * contain a file documenting the changes Licensee made to create that Covered
49 * Code and the date of any change. Licensee must include in that file the
50 * documentation of any changes made by any predecessor Licensee. Licensee
51 * must include a prominent statement that the modification is derived,
52 * directly or indirectly, from Original Intel Code.
53 *
54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55 * Redistribution of source code of any substantial portion of the Covered
56 * Code or modification without rights to further distribute source must
57 * include the following Disclaimer and Export Compliance provision in the
58 * documentation and/or other materials provided with distribution. In
59 * addition, Licensee may not authorize further sublicense of source of any
60 * portion of the Covered Code, and must include terms to the effect that the
61 * license from Licensee to its licensee is limited to the intellectual
62 * property embodied in the software Licensee provides to its licensee, and
63 * not to intellectual property embodied in modifications its licensee may
64 * make.
65 *
66 * 3.3. Redistribution of Executable. Redistribution in executable form of any
67 * substantial portion of the Covered Code or modification must reproduce the
68 * above Copyright Notice, and the following Disclaimer and Export Compliance
69 * provision in the documentation and/or other materials provided with the
70 * distribution.
71 *
72 * 3.4. Intel retains all right, title, and interest in and to the Original
73 * Intel Code.
74 *
75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76 * Intel shall be used in advertising or otherwise to promote the sale, use or
77 * other dealings in products derived from or relating to the Covered Code
78 * without prior written authorization from Intel.
79 *
80 * 4. Disclaimer and Export Compliance
81 *
82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88 * PARTICULAR PURPOSE.
89 *
90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97 * LIMITED REMEDY.
98 *
99 * 4.3. Licensee shall not export, either directly or indirectly, any of this
100 * software or system incorporating such software without first obtaining any
101 * required license or other approval from the U. S. Department of Commerce or
102 * any other agency or department of the United States Government. In the
103 * event Licensee exports any such software from the United States or
104 * re-exports any such software from a foreign destination, Licensee shall
105 * ensure that the distribution and export/re-export of the software is in
106 * compliance with all laws, regulations, orders, or other restrictions of the
107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108 * any of its subsidiaries will export/re-export any technical data, process,
109 * software, or service, directly or indirectly, to any country for which the
110 * United States government or any agency thereof requires an export license,
111 * other governmental approval, or letter of assurance, without first obtaining
112 * such license, approval or letter.
113 *
114 *****************************************************************************/
115
116 #include "aecommon.h"
117
118 #define _COMPONENT ACPI_TOOLS
119 ACPI_MODULE_NAME ("aehandlers")
120
121 /* Local prototypes */
122
123 static void
124 AeNotifyHandler1 (
125 ACPI_HANDLE Device,
126 UINT32 Value,
127 void *Context);
128
129 static void
130 AeNotifyHandler2 (
131 ACPI_HANDLE Device,
132 UINT32 Value,
133 void *Context);
134
135 static void
136 AeCommonNotifyHandler (
137 ACPI_HANDLE Device,
138 UINT32 Value,
139 UINT32 HandlerId);
140
141 static void
142 AeDeviceNotifyHandler (
143 ACPI_HANDLE Device,
144 UINT32 Value,
145 void *Context);
146
147 static ACPI_STATUS
148 AeExceptionHandler (
149 ACPI_STATUS AmlStatus,
150 ACPI_NAME Name,
151 UINT16 Opcode,
152 UINT32 AmlOffset,
153 void *Context);
154
155 static ACPI_STATUS
156 AeTableHandler (
157 UINT32 Event,
158 void *Table,
159 void *Context);
160
161 static ACPI_STATUS
162 AeRegionInit (
163 ACPI_HANDLE RegionHandle,
164 UINT32 Function,
165 void *HandlerContext,
166 void **RegionContext);
167
168 static void
169 AeAttachedDataHandler (
170 ACPI_HANDLE Object,
171 void *Data);
172
173 static void
174 AeAttachedDataHandler2 (
175 ACPI_HANDLE Object,
176 void *Data);
177
178 static UINT32
179 AeInterfaceHandler (
180 ACPI_STRING InterfaceName,
181 UINT32 Supported);
182
183 static ACPI_STATUS
184 AeInstallEcHandler (
185 ACPI_HANDLE ObjHandle,
186 UINT32 Level,
187 void *Context,
188 void **ReturnValue);
189
190 static ACPI_STATUS
191 AeInstallPciHandler (
192 ACPI_HANDLE ObjHandle,
193 UINT32 Level,
194 void *Context,
195 void **ReturnValue);
196
197 static ACPI_STATUS
198 AeInstallDeviceHandlers (
199 void);
200
201 #if (!ACPI_REDUCED_HARDWARE)
202 static UINT32
203 AeEventHandler (
204 void *Context);
205
206 static UINT32
207 AeSciHandler (
208 void *Context);
209
210 static char *TableEvents[] =
211 {
212 "LOAD",
213 "UNLOAD",
214 "UNKNOWN"
215 };
216 #endif /* !ACPI_REDUCED_HARDWARE */
217
218
219 static UINT32 SigintCount = 0;
220 static AE_DEBUG_REGIONS AeRegions;
221 BOOLEAN AcpiGbl_DisplayRegionAccess = FALSE;
222
223 /*
224 * We will override some of the default region handlers, especially
225 * the SystemMemory handler, which must be implemented locally.
226 * These handlers are installed "early" - before any _REG methods
227 * are executed - since they are special in the sense that the ACPI spec
228 * declares that they must "always be available". Cannot override the
229 * DataTable region handler either -- needed for test execution.
230 *
231 * NOTE: The local region handler will simulate access to these address
232 * spaces by creating a memory buffer behind each operation region.
233 */
234 static ACPI_ADR_SPACE_TYPE DefaultSpaceIdList[] =
235 {
236 ACPI_ADR_SPACE_SYSTEM_MEMORY,
237 ACPI_ADR_SPACE_SYSTEM_IO,
238 ACPI_ADR_SPACE_PCI_CONFIG,
239 ACPI_ADR_SPACE_EC
240 };
241
242 /*
243 * We will install handlers for some of the various address space IDs.
244 * Test one user-defined address space (used by aslts).
245 */
246 #define ACPI_ADR_SPACE_USER_DEFINED1 0x80
247 #define ACPI_ADR_SPACE_USER_DEFINED2 0xE4
248
249 static ACPI_ADR_SPACE_TYPE SpaceIdList[] =
250 {
251 ACPI_ADR_SPACE_SMBUS,
252 ACPI_ADR_SPACE_CMOS,
253 ACPI_ADR_SPACE_PCI_BAR_TARGET,
254 ACPI_ADR_SPACE_IPMI,
255 ACPI_ADR_SPACE_GPIO,
256 ACPI_ADR_SPACE_GSBUS,
257 ACPI_ADR_SPACE_FIXED_HARDWARE,
258 ACPI_ADR_SPACE_USER_DEFINED1,
259 ACPI_ADR_SPACE_USER_DEFINED2
260 };
261
262 static ACPI_CONNECTION_INFO AeMyContext;
263
264
265 /******************************************************************************
266 *
267 * FUNCTION: AeCtrlCHandler
268 *
269 * PARAMETERS: Sig
270 *
271 * RETURN: none
272 *
273 * DESCRIPTION: Control-C handler. Abort running control method if any.
274 *
275 *****************************************************************************/
276
277 void ACPI_SYSTEM_XFACE
278 AeCtrlCHandler (
279 int Sig)
280 {
281
282 signal (SIGINT, SIG_IGN);
283 SigintCount++;
284
285 AcpiOsPrintf ("Caught a ctrl-c (#%u)\n\n", SigintCount);
286
287 if (AcpiGbl_MethodExecuting)
288 {
289 AcpiGbl_AbortMethod = TRUE;
290 signal (SIGINT, AeCtrlCHandler);
291
292 if (SigintCount < 10)
293 {
294 return;
295 }
296 }
297
298 (void) AcpiOsTerminate ();
299 exit (0);
300 }
301
302
303 /******************************************************************************
304 *
305 * FUNCTION: AeNotifyHandler(s)
306 *
307 * PARAMETERS: Standard notify handler parameters
308 *
309 * RETURN: Status
310 *
311 * DESCRIPTION: Notify handlers for AcpiExec utility. Used by the ASL
312 * test suite(s) to communicate errors and other information to
313 * this utility via the Notify() operator. Tests notify handling
314 * and multiple notify handler support.
315 *
316 *****************************************************************************/
317
318 static void
319 AeNotifyHandler1 (
320 ACPI_HANDLE Device,
321 UINT32 Value,
322 void *Context)
323 {
324 AeCommonNotifyHandler (Device, Value, 1);
325 }
326
327 static void
328 AeNotifyHandler2 (
329 ACPI_HANDLE Device,
330 UINT32 Value,
331 void *Context)
332 {
333 AeCommonNotifyHandler (Device, Value, 2);
334 }
335
336 static void
337 AeCommonNotifyHandler (
338 ACPI_HANDLE Device,
339 UINT32 Value,
340 UINT32 HandlerId)
341 {
342 char *Type;
343
344
345 Type = "Device";
346 if (Value <= ACPI_MAX_SYS_NOTIFY)
347 {
348 Type = "System";
349 }
350
351 switch (Value)
352 {
353 #if 0
354 case 0:
355
356 printf ("[AcpiExec] Method Error 0x%X: Results not equal\n", Value);
357 if (AcpiGbl_DebugFile)
358 {
359 AcpiOsPrintf ("[AcpiExec] Method Error: Results not equal\n");
360 }
361 break;
362
363 case 1:
364
365 printf ("[AcpiExec] Method Error: Incorrect numeric result\n");
366 if (AcpiGbl_DebugFile)
367 {
368 AcpiOsPrintf ("[AcpiExec] Method Error: Incorrect numeric result\n");
369 }
370 break;
371
372 case 2:
373
374 printf ("[AcpiExec] Method Error: An operand was overwritten\n");
375 if (AcpiGbl_DebugFile)
376 {
377 AcpiOsPrintf ("[AcpiExec] Method Error: An operand was overwritten\n");
378 }
379 break;
380
381 #endif
382
383 default:
384
385 printf ("[AcpiExec] Handler %u: Received a %s Notify on [%4.4s] %p Value 0x%2.2X (%s)\n",
386 HandlerId, Type, AcpiUtGetNodeName (Device), Device, Value,
387 AcpiUtGetNotifyName (Value));
388 if (AcpiGbl_DebugFile)
389 {
390 AcpiOsPrintf ("[AcpiExec] Handler %u: Received a %s notify, Value 0x%2.2X\n",
391 HandlerId, Type, Value);
392 }
393
394 (void) AcpiEvaluateObject (Device, "_NOT", NULL, NULL);
395 break;
396 }
397 }
398
399
400 /******************************************************************************
401 *
402 * FUNCTION: AeSystemNotifyHandler
403 *
404 * PARAMETERS: Standard notify handler parameters
405 *
406 * RETURN: Status
407 *
408 * DESCRIPTION: System notify handler for AcpiExec utility. Used by the ASL
409 * test suite(s) to communicate errors and other information to
410 * this utility via the Notify() operator.
411 *
412 *****************************************************************************/
413
414 static void
415 AeSystemNotifyHandler (
416 ACPI_HANDLE Device,
417 UINT32 Value,
418 void *Context)
419 {
420
421 printf ("[AcpiExec] Global: Received a System Notify on [%4.4s] %p Value 0x%2.2X (%s)\n",
422 AcpiUtGetNodeName (Device), Device, Value,
423 AcpiUtGetNotifyName (Value));
424 if (AcpiGbl_DebugFile)
425 {
426 AcpiOsPrintf ("[AcpiExec] Global: Received a System Notify, Value 0x%2.2X\n", Value);
427 }
428
429 (void) AcpiEvaluateObject (Device, "_NOT", NULL, NULL);
430 }
431
432
433 /******************************************************************************
434 *
435 * FUNCTION: AeDeviceNotifyHandler
436 *
437 * PARAMETERS: Standard notify handler parameters
438 *
439 * RETURN: Status
440 *
441 * DESCRIPTION: Device notify handler for AcpiExec utility. Used by the ASL
442 * test suite(s) to communicate errors and other information to
443 * this utility via the Notify() operator.
444 *
445 *****************************************************************************/
446
447 static void
448 AeDeviceNotifyHandler (
449 ACPI_HANDLE Device,
450 UINT32 Value,
451 void *Context)
452 {
453
454 printf ("[AcpiExec] Global: Received a Device Notify on [%4.4s] %p Value 0x%2.2X (%s)\n",
455 AcpiUtGetNodeName (Device), Device, Value,
456 AcpiUtGetNotifyName (Value));
457 if (AcpiGbl_DebugFile)
458 {
459 AcpiOsPrintf ("[AcpiExec] Global: Received a Device Notify, Value 0x%2.2X\n", Value);
460 }
461
462 (void) AcpiEvaluateObject (Device, "_NOT", NULL, NULL);
463 }
464
465
466 /******************************************************************************
467 *
468 * FUNCTION: AeExceptionHandler
469 *
470 * PARAMETERS: Standard exception handler parameters
471 *
472 * RETURN: Status
473 *
474 * DESCRIPTION: System exception handler for AcpiExec utility.
475 *
476 *****************************************************************************/
477
478 static ACPI_STATUS
479 AeExceptionHandler (
480 ACPI_STATUS AmlStatus,
481 ACPI_NAME Name,
482 UINT16 Opcode,
483 UINT32 AmlOffset,
484 void *Context)
485 {
486 ACPI_STATUS NewAmlStatus = AmlStatus;
487 ACPI_STATUS Status;
488 ACPI_BUFFER ReturnObj;
489 ACPI_OBJECT_LIST ArgList;
490 ACPI_OBJECT Arg[3];
491 const char *Exception;
492
493
494 Exception = AcpiFormatException (AmlStatus);
495 AcpiOsPrintf ("[AcpiExec] Exception %s during execution ", Exception);
496 if (Name)
497 {
498 AcpiOsPrintf ("of method [%4.4s]", (char *) &Name);
499 }
500 else
501 {
502 AcpiOsPrintf ("at module level (table load)");
503 }
504 AcpiOsPrintf (" Opcode [%s] @%X\n", AcpiPsGetOpcodeName (Opcode), AmlOffset);
505
506 /*
507 * Invoke the _ERR method if present
508 *
509 * Setup parameter object
510 */
511 ArgList.Count = 3;
512 ArgList.Pointer = Arg;
513
514 Arg[0].Type = ACPI_TYPE_INTEGER;
515 Arg[0].Integer.Value = AmlStatus;
516
517 Arg[1].Type = ACPI_TYPE_STRING;
518 Arg[1].String.Pointer = ACPI_CAST_PTR (char, Exception);
519 Arg[1].String.Length = ACPI_STRLEN (Exception);
520
521 Arg[2].Type = ACPI_TYPE_INTEGER;
522 Arg[2].Integer.Value = AcpiOsGetThreadId();
523
524 /* Setup return buffer */
525
526 ReturnObj.Pointer = NULL;
527 ReturnObj.Length = ACPI_ALLOCATE_BUFFER;
528
529 Status = AcpiEvaluateObject (NULL, "\\_ERR", &ArgList, &ReturnObj);
530 if (ACPI_SUCCESS (Status))
531 {
532 if (ReturnObj.Pointer)
533 {
534 /* Override original status */
535
536 NewAmlStatus = (ACPI_STATUS)
537 ((ACPI_OBJECT *) ReturnObj.Pointer)->Integer.Value;
538
539 /* Free a buffer created via ACPI_ALLOCATE_BUFFER */
540
541 AcpiOsFree (ReturnObj.Pointer);
542 }
543 }
544 else if (Status != AE_NOT_FOUND)
545 {
546 AcpiOsPrintf ("[AcpiExec] Could not execute _ERR method, %s\n",
547 AcpiFormatException (Status));
548 }
549
550 /* Global override */
551
552 if (AcpiGbl_IgnoreErrors)
553 {
554 NewAmlStatus = AE_OK;
555 }
556
557 if (NewAmlStatus != AmlStatus)
558 {
559 AcpiOsPrintf ("[AcpiExec] Exception override, new status %s\n",
560 AcpiFormatException (NewAmlStatus));
561 }
562
563 return (NewAmlStatus);
564 }
565
566
567 /******************************************************************************
568 *
569 * FUNCTION: AeTableHandler
570 *
571 * PARAMETERS: Table handler
572 *
573 * RETURN: Status
574 *
575 * DESCRIPTION: System table handler for AcpiExec utility.
576 *
577 *****************************************************************************/
578
579 static ACPI_STATUS
580 AeTableHandler (
581 UINT32 Event,
582 void *Table,
583 void *Context)
584 {
585 #if (!ACPI_REDUCED_HARDWARE)
586 ACPI_STATUS Status;
587 #endif /* !ACPI_REDUCED_HARDWARE */
588
589
590 if (Event > ACPI_NUM_TABLE_EVENTS)
591 {
592 Event = ACPI_NUM_TABLE_EVENTS;
593 }
594
595 #if (!ACPI_REDUCED_HARDWARE)
596 /* Enable any GPEs associated with newly-loaded GPE methods */
597
598 Status = AcpiUpdateAllGpes ();
599 AE_CHECK_OK (AcpiUpdateAllGpes, Status);
600
601 printf ("[AcpiExec] Table Event %s, [%4.4s] %p\n",
602 TableEvents[Event], ((ACPI_TABLE_HEADER *) Table)->Signature, Table);
603 #endif /* !ACPI_REDUCED_HARDWARE */
604
605 return (AE_OK);
606 }
607
608
609 /******************************************************************************
610 *
611 * FUNCTION: AeGpeHandler
612 *
613 * DESCRIPTION: Common GPE handler for acpiexec
614 *
615 *****************************************************************************/
616
617 UINT32
618 AeGpeHandler (
619 ACPI_HANDLE GpeDevice,
620 UINT32 GpeNumber,
621 void *Context)
622 {
623 ACPI_NAMESPACE_NODE *DeviceNode = (ACPI_NAMESPACE_NODE *) GpeDevice;
624
625
626 AcpiOsPrintf ("[AcpiExec] GPE Handler received GPE%02X (GPE block %4.4s)\n",
627 GpeNumber, GpeDevice ? DeviceNode->Name.Ascii : "FADT");
628
629 return (ACPI_REENABLE_GPE);
630 }
631
632
633 /******************************************************************************
634 *
635 * FUNCTION: AeGlobalEventHandler
636 *
637 * DESCRIPTION: Global GPE/Fixed event handler
638 *
639 *****************************************************************************/
640
641 void
642 AeGlobalEventHandler (
643 UINT32 Type,
644 ACPI_HANDLE Device,
645 UINT32 EventNumber,
646 void *Context)
647 {
648 char *TypeName;
649
650
651 switch (Type)
652 {
653 case ACPI_EVENT_TYPE_GPE:
654
655 TypeName = "GPE";
656 break;
657
658 case ACPI_EVENT_TYPE_FIXED:
659
660 TypeName = "FixedEvent";
661 break;
662
663 default:
664
665 TypeName = "UNKNOWN";
666 break;
667 }
668
669 AcpiOsPrintf ("[AcpiExec] Global Event Handler received: Type %s Number %.2X Dev %p\n",
670 TypeName, EventNumber, Device);
671 }
672
673
674 /******************************************************************************
675 *
676 * FUNCTION: AeAttachedDataHandler
677 *
678 * DESCRIPTION: Handler for deletion of nodes with attached data (attached via
679 * AcpiAttachData)
680 *
681 *****************************************************************************/
682
683 static void
684 AeAttachedDataHandler (
685 ACPI_HANDLE Object,
686 void *Data)
687 {
688 ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Data);
689
690
691 AcpiOsPrintf ("Received an attached data deletion (1) on %4.4s\n",
692 Node->Name.Ascii);
693 }
694
695
696 /******************************************************************************
697 *
698 * FUNCTION: AeAttachedDataHandler2
699 *
700 * DESCRIPTION: Handler for deletion of nodes with attached data (attached via
701 * AcpiAttachData)
702 *
703 *****************************************************************************/
704
705 static void
706 AeAttachedDataHandler2 (
707 ACPI_HANDLE Object,
708 void *Data)
709 {
710 ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Data);
711
712
713 AcpiOsPrintf ("Received an attached data deletion (2) on %4.4s\n",
714 Node->Name.Ascii);
715 }
716
717
718 /******************************************************************************
719 *
720 * FUNCTION: AeInterfaceHandler
721 *
722 * DESCRIPTION: Handler for _OSI invocations
723 *
724 *****************************************************************************/
725
726 static UINT32
727 AeInterfaceHandler (
728 ACPI_STRING InterfaceName,
729 UINT32 Supported)
730 {
731 ACPI_FUNCTION_NAME (AeInterfaceHandler);
732
733
734 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
735 "Received _OSI (\"%s\"), is %ssupported\n",
736 InterfaceName, Supported == 0 ? "not " : ""));
737
738 return (Supported);
739 }
740
741
742 #if (!ACPI_REDUCED_HARDWARE)
743 /******************************************************************************
744 *
745 * FUNCTION: AeEventHandler, AeSciHandler
746 *
747 * DESCRIPTION: Handler for Fixed Events and SCIs
748 *
749 *****************************************************************************/
750
751 static UINT32
752 AeEventHandler (
753 void *Context)
754 {
755 return (0);
756 }
757
758 static UINT32
759 AeSciHandler (
760 void *Context)
761 {
762
763 AcpiOsPrintf ("[AcpiExec] Received an SCI at handler\n");
764 return (0);
765 }
766
767 #endif /* !ACPI_REDUCED_HARDWARE */
768
769
770 /******************************************************************************
771 *
772 * FUNCTION: AeRegionInit
773 *
774 * PARAMETERS: None
775 *
776 * RETURN: Status
777 *
778 * DESCRIPTION: Opregion init function.
779 *
780 *****************************************************************************/
781
782 static ACPI_STATUS
783 AeRegionInit (
784 ACPI_HANDLE RegionHandle,
785 UINT32 Function,
786 void *HandlerContext,
787 void **RegionContext)
788 {
789
790 if (Function == ACPI_REGION_DEACTIVATE)
791 {
792 *RegionContext = NULL;
793 }
794 else
795 {
796 *RegionContext = RegionHandle;
797 }
798
799 return (AE_OK);
800 }
801
802
803 /*******************************************************************************
804 *
805 * FUNCTION: AeInstallSciHandler
806 *
807 * PARAMETERS: None
808 *
809 * RETURN: Status
810 *
811 * DESCRIPTION: Install handler for SCIs. Exercise the code by doing an
812 * install/remove/install.
813 *
814 ******************************************************************************/
815
816 static ACPI_STATUS
817 AeInstallSciHandler (
818 void)
819 {
820 ACPI_STATUS Status;
821
822
823 Status = AcpiInstallSciHandler (AeSciHandler, &AeMyContext);
824 if (ACPI_FAILURE (Status))
825 {
826 ACPI_EXCEPTION ((AE_INFO, Status,
827 "Could not install an SCI handler (1)"));
828 }
829
830 Status = AcpiRemoveSciHandler (AeSciHandler);
831 if (ACPI_FAILURE (Status))
832 {
833 ACPI_EXCEPTION ((AE_INFO, Status,
834 "Could not remove an SCI handler"));
835 }
836
837 Status = AcpiInstallSciHandler (AeSciHandler, &AeMyContext);
838 if (ACPI_FAILURE (Status))
839 {
840 ACPI_EXCEPTION ((AE_INFO, Status,
841 "Could not install an SCI handler (2)"));
842 }
843
844 return (Status);
845 }
846
847
848 /*******************************************************************************
849 *
850 * FUNCTION: AeInstallDeviceHandlers, AeInstallEcHandler,
851 * AeInstallPciHandler
852 *
853 * PARAMETERS: ACPI_WALK_NAMESPACE callback
854 *
855 * RETURN: Status
856 *
857 * DESCRIPTION: Walk entire namespace, install a handler for every EC
858 * and PCI device found.
859 *
860 ******************************************************************************/
861
862 static ACPI_STATUS
863 AeInstallEcHandler (
864 ACPI_HANDLE ObjHandle,
865 UINT32 Level,
866 void *Context,
867 void **ReturnValue)
868 {
869 ACPI_STATUS Status;
870
871
872 /* Install the handler for this EC device */
873
874 Status = AcpiInstallAddressSpaceHandler (ObjHandle, ACPI_ADR_SPACE_EC,
875 AeRegionHandler, AeRegionInit, &AeMyContext);
876 if (ACPI_FAILURE (Status))
877 {
878 ACPI_EXCEPTION ((AE_INFO, Status,
879 "Could not install an OpRegion handler for EC device (%p)",
880 ObjHandle));
881 }
882
883 return (Status);
884 }
885
886 static ACPI_STATUS
887 AeInstallPciHandler (
888 ACPI_HANDLE ObjHandle,
889 UINT32 Level,
890 void *Context,
891 void **ReturnValue)
892 {
893 ACPI_STATUS Status;
894
895
896 /* Install memory and I/O handlers for the PCI device */
897
898 Status = AcpiInstallAddressSpaceHandler (ObjHandle, ACPI_ADR_SPACE_SYSTEM_IO,
899 AeRegionHandler, AeRegionInit, &AeMyContext);
900 if (ACPI_FAILURE (Status))
901 {
902 ACPI_EXCEPTION ((AE_INFO, Status,
903 "Could not install an OpRegion handler for PCI device (%p)",
904 ObjHandle));
905 }
906
907 Status = AcpiInstallAddressSpaceHandler (ObjHandle, ACPI_ADR_SPACE_SYSTEM_MEMORY,
908 AeRegionHandler, AeRegionInit, &AeMyContext);
909 if (ACPI_FAILURE (Status))
910 {
911 ACPI_EXCEPTION ((AE_INFO, Status,
912 "Could not install an OpRegion handler for PCI device (%p)",
913 ObjHandle));
914 }
915
916 return (AE_CTRL_TERMINATE);
917 }
918
919 static ACPI_STATUS
920 AeInstallDeviceHandlers (
921 void)
922 {
923
924 /* Find all Embedded Controller devices */
925
926 AcpiGetDevices ("PNP0C09", AeInstallEcHandler, NULL, NULL);
927
928 /* Install a PCI handler */
929
930 AcpiGetDevices ("PNP0A08", AeInstallPciHandler, NULL, NULL);
931 return (AE_OK);
932 }
933
934
935 /******************************************************************************
936 *
937 * FUNCTION: AeInstallLateHandlers
938 *
939 * PARAMETERS: None
940 *
941 * RETURN: Status
942 *
943 * DESCRIPTION: Install handlers for the AcpiExec utility.
944 *
945 *****************************************************************************/
946
947 ACPI_STATUS
948 AeInstallLateHandlers (
949 void)
950 {
951 ACPI_STATUS Status;
952 UINT32 i;
953
954
955 #if (!ACPI_REDUCED_HARDWARE)
956 if (!AcpiGbl_ReducedHardware)
957 {
958 /* Install a user SCI handler */
959
960 Status = AeInstallSciHandler ();
961 AE_CHECK_OK (AeInstallSciHandler, Status);
962
963 /* Install some fixed event handlers */
964
965 Status = AcpiInstallFixedEventHandler (ACPI_EVENT_GLOBAL, AeEventHandler, NULL);
966 AE_CHECK_OK (AcpiInstallFixedEventHandler, Status);
967
968 Status = AcpiInstallFixedEventHandler (ACPI_EVENT_RTC, AeEventHandler, NULL);
969 AE_CHECK_OK (AcpiInstallFixedEventHandler, Status);
970 }
971 #endif /* !ACPI_REDUCED_HARDWARE */
972
973 AeMyContext.Connection = NULL;
974 AeMyContext.AccessLength = 0xA5;
975
976 /*
977 * We will install a handler for each EC device, directly under the EC
978 * device definition. This is unlike the other handlers which we install
979 * at the root node. Also install memory and I/O handlers at any PCI
980 * devices.
981 */
982 AeInstallDeviceHandlers ();
983
984 /*
985 * Install handlers for some of the "device driver" address spaces
986 * such as SMBus, etc.
987 */
988 for (i = 0; i < ACPI_ARRAY_LENGTH (SpaceIdList); i++)
989 {
990 /* Install handler at the root object */
991
992 Status = AcpiInstallAddressSpaceHandler (ACPI_ROOT_OBJECT,
993 SpaceIdList[i], AeRegionHandler,
994 AeRegionInit, &AeMyContext);
995 if (ACPI_FAILURE (Status))
996 {
997 ACPI_EXCEPTION ((AE_INFO, Status,
998 "Could not install an OpRegion handler for %s space(%u)",
999 AcpiUtGetRegionName((UINT8) SpaceIdList[i]), SpaceIdList[i]));
1000 return (Status);
1001 }
1002 }
1003
1004 return (AE_OK);
1005 }
1006
1007
1008 /******************************************************************************
1009 *
1010 * FUNCTION: AeInstallEarlyHandlers
1011 *
1012 * PARAMETERS: None
1013 *
1014 * RETURN: Status
1015 *
1016 * DESCRIPTION: Install handlers for the AcpiExec utility.
1017 *
1018 * Notes: Don't install handler for PCI_Config, we want to use the
1019 * default handler to exercise that code.
1020 *
1021 *****************************************************************************/
1022
1023 ACPI_STATUS
1024 AeInstallEarlyHandlers (
1025 void)
1026 {
1027 ACPI_STATUS Status;
1028 UINT32 i;
1029 ACPI_HANDLE Handle;
1030
1031
1032 ACPI_FUNCTION_ENTRY ();
1033
1034
1035 Status = AcpiInstallInterfaceHandler (AeInterfaceHandler);
1036 if (ACPI_FAILURE (Status))
1037 {
1038 printf ("Could not install interface handler, %s\n",
1039 AcpiFormatException (Status));
1040 }
1041
1042 Status = AcpiInstallTableHandler (AeTableHandler, NULL);
1043 if (ACPI_FAILURE (Status))
1044 {
1045 printf ("Could not install table handler, %s\n",
1046 AcpiFormatException (Status));
1047 }
1048
1049 Status = AcpiInstallExceptionHandler (AeExceptionHandler);
1050 if (ACPI_FAILURE (Status))
1051 {
1052 printf ("Could not install exception handler, %s\n",
1053 AcpiFormatException (Status));
1054 }
1055
1056 /* Install global notify handlers */
1057
1058 Status = AcpiInstallNotifyHandler (ACPI_ROOT_OBJECT, ACPI_SYSTEM_NOTIFY,
1059 AeSystemNotifyHandler, NULL);
1060 if (ACPI_FAILURE (Status))
1061 {
1062 printf ("Could not install a global system notify handler, %s\n",
1063 AcpiFormatException (Status));
1064 }
1065
1066 Status = AcpiInstallNotifyHandler (ACPI_ROOT_OBJECT, ACPI_DEVICE_NOTIFY,
1067 AeDeviceNotifyHandler, NULL);
1068 if (ACPI_FAILURE (Status))
1069 {
1070 printf ("Could not install a global notify handler, %s\n",
1071 AcpiFormatException (Status));
1072 }
1073
1074 Status = AcpiGetHandle (NULL, "\\_SB", &Handle);
1075 if (ACPI_SUCCESS (Status))
1076 {
1077 Status = AcpiInstallNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY,
1078 AeNotifyHandler1, NULL);
1079 if (ACPI_FAILURE (Status))
1080 {
1081 printf ("Could not install a notify handler, %s\n",
1082 AcpiFormatException (Status));
1083 }
1084
1085 Status = AcpiRemoveNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY,
1086 AeNotifyHandler1);
1087 if (ACPI_FAILURE (Status))
1088 {
1089 printf ("Could not remove a notify handler, %s\n",
1090 AcpiFormatException (Status));
1091 }
1092
1093 Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
1094 AeNotifyHandler1, NULL);
1095 AE_CHECK_OK (AcpiInstallNotifyHandler, Status);
1096
1097 Status = AcpiRemoveNotifyHandler (Handle, ACPI_ALL_NOTIFY,
1098 AeNotifyHandler1);
1099 AE_CHECK_OK (AcpiRemoveNotifyHandler, Status);
1100
1101 #if 0
1102 Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
1103 AeNotifyHandler1, NULL);
1104 if (ACPI_FAILURE (Status))
1105 {
1106 printf ("Could not install a notify handler, %s\n",
1107 AcpiFormatException (Status));
1108 }
1109 #endif
1110
1111 /* Install two handlers for _SB_ */
1112
1113 Status = AcpiInstallNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY,
1114 AeNotifyHandler1, ACPI_CAST_PTR (void, 0x01234567));
1115
1116 Status = AcpiInstallNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY,
1117 AeNotifyHandler2, ACPI_CAST_PTR (void, 0x89ABCDEF));
1118
1119 /* Attempt duplicate handler installation, should fail */
1120
1121 Status = AcpiInstallNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY,
1122 AeNotifyHandler1, ACPI_CAST_PTR (void, 0x77777777));
1123
1124 Status = AcpiAttachData (Handle, AeAttachedDataHandler, Handle);
1125 AE_CHECK_OK (AcpiAttachData, Status);
1126
1127 Status = AcpiDetachData (Handle, AeAttachedDataHandler);
1128 AE_CHECK_OK (AcpiDetachData, Status);
1129
1130 Status = AcpiAttachData (Handle, AeAttachedDataHandler, Handle);
1131 AE_CHECK_OK (AcpiAttachData, Status);
1132
1133 /* Test support for multiple attaches */
1134
1135 Status = AcpiAttachData (Handle, AeAttachedDataHandler2, Handle);
1136 AE_CHECK_OK (AcpiAttachData, Status);
1137 }
1138 else
1139 {
1140 printf ("No _SB_ found, %s\n", AcpiFormatException (Status));
1141 }
1142
1143
1144 Status = AcpiGetHandle (NULL, "\\_TZ.TZ1", &Handle);
1145 if (ACPI_SUCCESS (Status))
1146 {
1147 Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
1148 AeNotifyHandler1, ACPI_CAST_PTR (void, 0x01234567));
1149
1150 Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
1151 AeNotifyHandler2, ACPI_CAST_PTR (void, 0x89ABCDEF));
1152
1153 Status = AcpiRemoveNotifyHandler (Handle, ACPI_ALL_NOTIFY,
1154 AeNotifyHandler1);
1155 Status = AcpiRemoveNotifyHandler (Handle, ACPI_ALL_NOTIFY,
1156 AeNotifyHandler2);
1157
1158 Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
1159 AeNotifyHandler2, ACPI_CAST_PTR (void, 0x89ABCDEF));
1160
1161 Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
1162 AeNotifyHandler1, ACPI_CAST_PTR (void, 0x01234567));
1163 }
1164
1165 Status = AcpiGetHandle (NULL, "\\_PR.CPU0", &Handle);
1166 if (ACPI_SUCCESS (Status))
1167 {
1168 Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
1169 AeNotifyHandler1, ACPI_CAST_PTR (void, 0x01234567));
1170
1171 Status = AcpiInstallNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY,
1172 AeNotifyHandler2, ACPI_CAST_PTR (void, 0x89ABCDEF));
1173 }
1174
1175 /*
1176 * Install handlers that will override the default handlers for some of
1177 * the space IDs.
1178 */
1179 for (i = 0; i < ACPI_ARRAY_LENGTH (DefaultSpaceIdList); i++)
1180 {
1181 /* Install handler at the root object */
1182
1183 Status = AcpiInstallAddressSpaceHandler (ACPI_ROOT_OBJECT,
1184 DefaultSpaceIdList[i], AeRegionHandler,
1185 AeRegionInit, &AeMyContext);
1186 if (ACPI_FAILURE (Status))
1187 {
1188 ACPI_EXCEPTION ((AE_INFO, Status,
1189 "Could not install a default OpRegion handler for %s space(%u)",
1190 AcpiUtGetRegionName ((UINT8) DefaultSpaceIdList[i]),
1191 DefaultSpaceIdList[i]));
1192 return (Status);
1193 }
1194 }
1195
1196 /*
1197 * Initialize the global Region Handler space
1198 * MCW 3/23/00
1199 */
1200 AeRegions.NumberOfRegions = 0;
1201 AeRegions.RegionList = NULL;
1202 return (Status);
1203 }
1204
1205
1206 /******************************************************************************
1207 *
1208 * FUNCTION: AeRegionHandler
1209 *
1210 * PARAMETERS: Standard region handler parameters
1211 *
1212 * RETURN: Status
1213 *
1214 * DESCRIPTION: Test handler - Handles some dummy regions via memory that can
1215 * be manipulated in Ring 3. Simulates actual reads and writes.
1216 *
1217 *****************************************************************************/
1218
1219 ACPI_STATUS
1220 AeRegionHandler (
1221 UINT32 Function,
1222 ACPI_PHYSICAL_ADDRESS Address,
1223 UINT32 BitWidth,
1224 UINT64 *Value,
1225 void *HandlerContext,
1226 void *RegionContext)
1227 {
1228
1229 ACPI_OPERAND_OBJECT *RegionObject = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, RegionContext);
1230 UINT8 *Buffer = ACPI_CAST_PTR (UINT8, Value);
1231 UINT8 *OldBuffer;
1232 UINT8 *NewBuffer;
1233 ACPI_PHYSICAL_ADDRESS BaseAddress;
1234 ACPI_PHYSICAL_ADDRESS BaseAddressEnd;
1235 ACPI_PHYSICAL_ADDRESS RegionAddress;
1236 ACPI_PHYSICAL_ADDRESS RegionAddressEnd;
1237 ACPI_SIZE Length;
1238 BOOLEAN BufferExists;
1239 BOOLEAN BufferResize;
1240 AE_REGION *RegionElement;
1241 void *BufferValue;
1242 ACPI_STATUS Status;
1243 UINT32 ByteWidth;
1244 UINT32 RegionLength;
1245 UINT32 i;
1246 UINT8 SpaceId;
1247 ACPI_CONNECTION_INFO *MyContext;
1248 UINT32 Value1;
1249 UINT32 Value2;
1250 ACPI_RESOURCE *Resource;
1251
1252
1253 ACPI_FUNCTION_NAME (AeRegionHandler);
1254
1255 /*
1256 * If the object is not a region, simply return
1257 */
1258 if (RegionObject->Region.Type != ACPI_TYPE_REGION)
1259 {
1260 return (AE_OK);
1261 }
1262
1263 /* Check that we actually got back our context parameter */
1264
1265 if (HandlerContext != &AeMyContext)
1266 {
1267 printf ("Region handler received incorrect context %p, should be %p\n",
1268 HandlerContext, &AeMyContext);
1269 }
1270
1271 MyContext = ACPI_CAST_PTR (ACPI_CONNECTION_INFO, HandlerContext);
1272
1273 /*
1274 * Find the region's address space and length before searching
1275 * the linked list.
1276 */
1277 BaseAddress = RegionObject->Region.Address;
1278 Length = (ACPI_SIZE) RegionObject->Region.Length;
1279 SpaceId = RegionObject->Region.SpaceId;
1280
1281 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, "Operation Region request on %s at 0x%X\n",
1282 AcpiUtGetRegionName (RegionObject->Region.SpaceId),
1283 (UINT32) Address));
1284
1285 /*
1286 * Region support can be disabled with the -do option.
1287 * We use this to support dynamically loaded tables where we pass a valid
1288 * address to the AML.
1289 */
1290 if (AcpiGbl_DbOpt_NoRegionSupport)
1291 {
1292 BufferValue = ACPI_TO_POINTER (Address);
1293 ByteWidth = (BitWidth / 8);
1294
1295 if (BitWidth % 8)
1296 {
1297 ByteWidth += 1;
1298 }
1299 goto DoFunction;
1300 }
1301
1302 switch (SpaceId)
1303 {
1304 case ACPI_ADR_SPACE_SYSTEM_IO:
1305 /*
1306 * For I/O space, exercise the port validation
1307 * Note: ReadPort currently always returns all ones, length=BitLength
1308 */
1309 switch (Function & ACPI_IO_MASK)
1310 {
1311 case ACPI_READ:
1312
1313 if (BitWidth == 64)
1314 {
1315 /* Split the 64-bit request into two 32-bit requests */
1316
1317 Status = AcpiHwReadPort (Address, &Value1, 32);
1318 AE_CHECK_OK (AcpiHwReadPort, Status);
1319 Status = AcpiHwReadPort (Address+4, &Value2, 32);
1320 AE_CHECK_OK (AcpiHwReadPort, Status);
1321
1322 *Value = Value1 | ((UINT64) Value2 << 32);
1323 }
1324 else
1325 {
1326 Status = AcpiHwReadPort (Address, &Value1, BitWidth);
1327 AE_CHECK_OK (AcpiHwReadPort, Status);
1328 *Value = (UINT64) Value1;
1329 }
1330 break;
1331
1332 case ACPI_WRITE:
1333
1334 if (BitWidth == 64)
1335 {
1336 /* Split the 64-bit request into two 32-bit requests */
1337
1338 Status = AcpiHwWritePort (Address, ACPI_LODWORD (*Value), 32);
1339 AE_CHECK_OK (AcpiHwWritePort, Status);
1340 Status = AcpiHwWritePort (Address+4, ACPI_HIDWORD (*Value), 32);
1341 AE_CHECK_OK (AcpiHwWritePort, Status);
1342 }
1343 else
1344 {
1345 Status = AcpiHwWritePort (Address, (UINT32) *Value, BitWidth);
1346 AE_CHECK_OK (AcpiHwWritePort, Status);
1347 }
1348 break;
1349
1350 default:
1351
1352 Status = AE_BAD_PARAMETER;
1353 break;
1354 }
1355
1356 if (ACPI_FAILURE (Status))
1357 {
1358 return (Status);
1359 }
1360
1361 /* Now go ahead and simulate the hardware */
1362 break;
1363
1364 /*
1365 * SMBus and GenericSerialBus support the various bidirectional
1366 * protocols.
1367 */
1368 case ACPI_ADR_SPACE_SMBUS:
1369 case ACPI_ADR_SPACE_GSBUS: /* ACPI 5.0 */
1370
1371 Length = 0;
1372
1373 switch (Function & ACPI_IO_MASK)
1374 {
1375 case ACPI_READ:
1376
1377 switch (Function >> 16)
1378 {
1379 case AML_FIELD_ATTRIB_QUICK:
1380 case AML_FIELD_ATTRIB_SEND_RCV:
1381 case AML_FIELD_ATTRIB_BYTE:
1382
1383 Length = 1;
1384 break;
1385
1386 case AML_FIELD_ATTRIB_WORD:
1387 case AML_FIELD_ATTRIB_WORD_CALL:
1388
1389 Length = 2;
1390 break;
1391
1392 case AML_FIELD_ATTRIB_BLOCK:
1393 case AML_FIELD_ATTRIB_BLOCK_CALL:
1394
1395 Length = 32;
1396 break;
1397
1398 case AML_FIELD_ATTRIB_MULTIBYTE:
1399 case AML_FIELD_ATTRIB_RAW_BYTES:
1400 case AML_FIELD_ATTRIB_RAW_PROCESS:
1401
1402 /* (-2) for status/length */
1403 Length = MyContext->AccessLength - 2;
1404 break;
1405
1406 default:
1407
1408 break;
1409 }
1410 break;
1411
1412 case ACPI_WRITE:
1413
1414 switch (Function >> 16)
1415 {
1416 case AML_FIELD_ATTRIB_QUICK:
1417 case AML_FIELD_ATTRIB_SEND_RCV:
1418 case AML_FIELD_ATTRIB_BYTE:
1419 case AML_FIELD_ATTRIB_WORD:
1420 case AML_FIELD_ATTRIB_BLOCK:
1421
1422 Length = 0;
1423 break;
1424
1425 case AML_FIELD_ATTRIB_WORD_CALL:
1426 Length = 2;
1427 break;
1428
1429 case AML_FIELD_ATTRIB_BLOCK_CALL:
1430 Length = 32;
1431 break;
1432
1433 case AML_FIELD_ATTRIB_MULTIBYTE:
1434 case AML_FIELD_ATTRIB_RAW_BYTES:
1435 case AML_FIELD_ATTRIB_RAW_PROCESS:
1436
1437 /* (-2) for status/length */
1438 Length = MyContext->AccessLength - 2;
1439 break;
1440
1441 default:
1442
1443 break;
1444 }
1445 break;
1446
1447 default:
1448
1449 break;
1450 }
1451
1452 if (AcpiGbl_DisplayRegionAccess)
1453 {
1454 AcpiOsPrintf ("AcpiExec: %s "
1455 "%s: Attr %X Addr %.4X BaseAddr %.4X Len %.2X Width %X BufLen %X",
1456 AcpiUtGetRegionName (SpaceId),
1457 (Function & ACPI_IO_MASK) ? "Write" : "Read ",
1458 (UINT32) (Function >> 16),
1459 (UINT32) Address, (UINT32) BaseAddress,
1460 Length, BitWidth, Buffer[1]);
1461
1462 /* GenericSerialBus has a Connection() parameter */
1463
1464 if (SpaceId == ACPI_ADR_SPACE_GSBUS)
1465 {
1466 Status = AcpiBufferToResource (MyContext->Connection,
1467 MyContext->Length, &Resource);
1468
1469 AcpiOsPrintf (" [AccLen %.2X Conn %p]",
1470 MyContext->AccessLength, MyContext->Connection);
1471 }
1472 AcpiOsPrintf ("\n");
1473 }
1474
1475 /* Setup the return buffer. Note: ASLTS depends on these fill values */
1476
1477 for (i = 0; i < Length; i++)
1478 {
1479 Buffer[i+2] = (UINT8) (0xA0 + i);
1480 }
1481
1482 Buffer[0] = 0x7A;
1483 Buffer[1] = (UINT8) Length;
1484 return (AE_OK);
1485
1486
1487 case ACPI_ADR_SPACE_IPMI: /* ACPI 4.0 */
1488
1489 if (AcpiGbl_DisplayRegionAccess)
1490 {
1491 AcpiOsPrintf ("AcpiExec: IPMI "
1492 "%s: Attr %X Addr %.4X BaseAddr %.4X Len %.2X Width %X BufLen %X\n",
1493 (Function & ACPI_IO_MASK) ? "Write" : "Read ",
1494 (UINT32) (Function >> 16), (UINT32) Address, (UINT32) BaseAddress,
1495 Length, BitWidth, Buffer[1]);
1496 }
1497
1498 /*
1499 * Regardless of a READ or WRITE, this handler is passed a 66-byte
1500 * buffer in which to return the IPMI status/length/data.
1501 *
1502 * Return some example data to show use of the bidirectional buffer
1503 */
1504 Buffer[0] = 0; /* Status byte */
1505 Buffer[1] = 64; /* Return buffer data length */
1506 Buffer[2] = 0; /* Completion code */
1507 Buffer[3] = 0; /* Reserved */
1508
1509 /*
1510 * Fill the 66-byte buffer with the return data.
1511 * Note: ASLTS depends on these fill values.
1512 */
1513 for (i = 4; i < 66; i++)
1514 {
1515 Buffer[i] = (UINT8) (i);
1516 }
1517 return (AE_OK);
1518
1519 default:
1520 break;
1521 }
1522
1523 /*
1524 * Search through the linked list for this region's buffer
1525 */
1526 BufferExists = FALSE;
1527 BufferResize = FALSE;
1528 RegionElement = AeRegions.RegionList;
1529
1530 if (AeRegions.NumberOfRegions)
1531 {
1532 BaseAddressEnd = BaseAddress + Length - 1;
1533 while (!BufferExists && RegionElement)
1534 {
1535 RegionAddress = RegionElement->Address;
1536 RegionAddressEnd = RegionElement->Address + RegionElement->Length - 1;
1537 RegionLength = RegionElement->Length;
1538
1539 /*
1540 * Overlapping Region Support
1541 *
1542 * While searching through the region buffer list, determine if an
1543 * overlap exists between the requested buffer space and the current
1544 * RegionElement space. If there is an overlap then replace the old
1545 * buffer with a new buffer of increased size before continuing to
1546 * do the read or write
1547 */
1548 if (RegionElement->SpaceId != SpaceId ||
1549 BaseAddressEnd < RegionAddress ||
1550 BaseAddress > RegionAddressEnd)
1551 {
1552 /*
1553 * Requested buffer is outside of the current RegionElement
1554 * bounds
1555 */
1556 RegionElement = RegionElement->NextRegion;
1557 }
1558 else
1559 {
1560 /*
1561 * Some amount of buffer space sharing exists. There are 4 cases
1562 * to consider:
1563 *
1564 * 1. Right overlap
1565 * 2. Left overlap
1566 * 3. Left and right overlap
1567 * 4. Fully contained - no resizing required
1568 */
1569 BufferExists = TRUE;
1570
1571 if ((BaseAddress >= RegionAddress) &&
1572 (BaseAddress <= RegionAddressEnd) &&
1573 (BaseAddressEnd > RegionAddressEnd))
1574 {
1575 /* Right overlap */
1576
1577 RegionElement->Length = BaseAddress -
1578 RegionAddress + Length;
1579 BufferResize = TRUE;
1580 }
1581
1582 else if ((BaseAddressEnd >= RegionAddress) &&
1583 (BaseAddressEnd <= RegionAddressEnd) &&
1584 (BaseAddress < RegionAddress))
1585 {
1586 /* Left overlap */
1587
1588 RegionElement->Address = BaseAddress;
1589 RegionElement->Length = RegionAddress -
1590 BaseAddress + RegionElement->Length;
1591 BufferResize = TRUE;
1592 }
1593
1594 else if ((BaseAddress < RegionAddress) &&
1595 (BaseAddressEnd > RegionAddressEnd))
1596 {
1597 /* Left and right overlap */
1598
1599 RegionElement->Address = BaseAddress;
1600 RegionElement->Length = Length;
1601 BufferResize = TRUE;
1602 }
1603
1604 /*
1605 * only remaining case is fully contained for which we don't
1606 * need to do anything
1607 */
1608 if (BufferResize)
1609 {
1610 NewBuffer = AcpiOsAllocate (RegionElement->Length);
1611 if (!NewBuffer)
1612 {
1613 return (AE_NO_MEMORY);
1614 }
1615
1616 OldBuffer = RegionElement->Buffer;
1617 RegionElement->Buffer = NewBuffer;
1618 NewBuffer = NULL;
1619
1620 /* Initialize the region with the default fill value */
1621
1622 ACPI_MEMSET (RegionElement->Buffer,
1623 AcpiGbl_RegionFillValue, RegionElement->Length);
1624
1625 /*
1626 * Get BufferValue to point (within the new buffer) to the
1627 * base address of the old buffer
1628 */
1629 BufferValue = (UINT8 *) RegionElement->Buffer +
1630 (UINT64) RegionAddress -
1631 (UINT64) RegionElement->Address;
1632
1633 /*
1634 * Copy the old buffer to its same location within the new
1635 * buffer
1636 */
1637 ACPI_MEMCPY (BufferValue, OldBuffer, RegionLength);
1638 AcpiOsFree (OldBuffer);
1639 }
1640 }
1641 }
1642 }
1643
1644 /*
1645 * If the Region buffer does not exist, create it now
1646 */
1647 if (!BufferExists)
1648 {
1649 /* Do the memory allocations first */
1650
1651 RegionElement = AcpiOsAllocate (sizeof (AE_REGION));
1652 if (!RegionElement)
1653 {
1654 return (AE_NO_MEMORY);
1655 }
1656
1657 RegionElement->Buffer = AcpiOsAllocate (Length);
1658 if (!RegionElement->Buffer)
1659 {
1660 AcpiOsFree (RegionElement);
1661 return (AE_NO_MEMORY);
1662 }
1663
1664 /* Initialize the region with the default fill value */
1665
1666 ACPI_MEMSET (RegionElement->Buffer, AcpiGbl_RegionFillValue, Length);
1667
1668 RegionElement->Address = BaseAddress;
1669 RegionElement->Length = Length;
1670 RegionElement->SpaceId = SpaceId;
1671 RegionElement->NextRegion = NULL;
1672
1673 /*
1674 * Increment the number of regions and put this one
1675 * at the head of the list as it will probably get accessed
1676 * more often anyway.
1677 */
1678 AeRegions.NumberOfRegions += 1;
1679
1680 if (AeRegions.RegionList)
1681 {
1682 RegionElement->NextRegion = AeRegions.RegionList;
1683 }
1684
1685 AeRegions.RegionList = RegionElement;
1686 }
1687
1688 /* Calculate the size of the memory copy */
1689
1690 ByteWidth = (BitWidth / 8);
1691
1692 if (BitWidth % 8)
1693 {
1694 ByteWidth += 1;
1695 }
1696
1697 /*
1698 * The buffer exists and is pointed to by RegionElement.
1699 * We now need to verify the request is valid and perform the operation.
1700 *
1701 * NOTE: RegionElement->Length is in bytes, therefore it we compare against
1702 * ByteWidth (see above)
1703 */
1704 if (((UINT64) Address + ByteWidth) >
1705 ((UINT64)(RegionElement->Address) + RegionElement->Length))
1706 {
1707 ACPI_WARNING ((AE_INFO,
1708 "Request on [%4.4s] is beyond region limit Req-0x%X+0x%X, Base=0x%X, Len-0x%X",
1709 (RegionObject->Region.Node)->Name.Ascii, (UINT32) Address,
1710 ByteWidth, (UINT32)(RegionElement->Address),
1711 RegionElement->Length));
1712
1713 return (AE_AML_REGION_LIMIT);
1714 }
1715
1716 /*
1717 * Get BufferValue to point to the "address" in the buffer
1718 */
1719 BufferValue = ((UINT8 *) RegionElement->Buffer +
1720 ((UINT64) Address - (UINT64) RegionElement->Address));
1721
1722 DoFunction:
1723 /*
1724 * Perform a read or write to the buffer space
1725 */
1726 switch (Function)
1727 {
1728 case ACPI_READ:
1729 /*
1730 * Set the pointer Value to whatever is in the buffer
1731 */
1732 ACPI_MEMCPY (Value, BufferValue, ByteWidth);
1733 break;
1734
1735 case ACPI_WRITE:
1736 /*
1737 * Write the contents of Value to the buffer
1738 */
1739 ACPI_MEMCPY (BufferValue, Value, ByteWidth);
1740 break;
1741
1742 default:
1743
1744 return (AE_BAD_PARAMETER);
1745 }
1746
1747 if (AcpiGbl_DisplayRegionAccess)
1748 {
1749 switch (SpaceId)
1750 {
1751 case ACPI_ADR_SPACE_SYSTEM_MEMORY:
1752
1753 AcpiOsPrintf ("AcpiExec: SystemMemory "
1754 "%s: Val %.8X Addr %.4X Width %X [REGION: BaseAddr %.4X Len %.2X]\n",
1755 (Function & ACPI_IO_MASK) ? "Write" : "Read ",
1756 (UINT32) *Value, (UINT32) Address, BitWidth, (UINT32) BaseAddress, Length);
1757 break;
1758
1759 case ACPI_ADR_SPACE_GPIO: /* ACPI 5.0 */
1760
1761 /* This space is required to always be ByteAcc */
1762
1763 Status = AcpiBufferToResource (MyContext->Connection,
1764 MyContext->Length, &Resource);
1765
1766 AcpiOsPrintf ("AcpiExec: GeneralPurposeIo "
1767 "%s: Val %.8X Addr %.4X BaseAddr %.4X Len %.2X Width %X AccLen %.2X Conn %p\n",
1768 (Function & ACPI_IO_MASK) ? "Write" : "Read ", (UINT32) *Value,
1769 (UINT32) Address, (UINT32) BaseAddress, Length, BitWidth,
1770 MyContext->AccessLength, MyContext->Connection);
1771 break;
1772
1773 default:
1774
1775 break;
1776 }
1777 }
1778
1779 return (AE_OK);
1780 }