Indentation fix, cleanup.
[AROS.git] / arch / all-pc / acpica / source / tools / acpiexec / aehandlers.c
blob24474140f528969926c7b9911a20578c66e88299
1 /******************************************************************************
3 * Module Name: aehandlers - Various handlers for acpiexec
5 *****************************************************************************/
7 /*
8 * Copyright (C) 2000 - 2013, Intel Corp.
9 * All rights reserved.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
44 #include "aecommon.h"
46 #define _COMPONENT ACPI_TOOLS
47 ACPI_MODULE_NAME ("aehandlers")
49 /* Local prototypes */
51 static void
52 AeNotifyHandler1 (
53 ACPI_HANDLE Device,
54 UINT32 Value,
55 void *Context);
57 static void
58 AeNotifyHandler2 (
59 ACPI_HANDLE Device,
60 UINT32 Value,
61 void *Context);
63 static void
64 AeCommonNotifyHandler (
65 ACPI_HANDLE Device,
66 UINT32 Value,
67 UINT32 HandlerId);
69 static void
70 AeDeviceNotifyHandler (
71 ACPI_HANDLE Device,
72 UINT32 Value,
73 void *Context);
75 static ACPI_STATUS
76 AeExceptionHandler (
77 ACPI_STATUS AmlStatus,
78 ACPI_NAME Name,
79 UINT16 Opcode,
80 UINT32 AmlOffset,
81 void *Context);
83 static ACPI_STATUS
84 AeTableHandler (
85 UINT32 Event,
86 void *Table,
87 void *Context);
89 static ACPI_STATUS
90 AeRegionInit (
91 ACPI_HANDLE RegionHandle,
92 UINT32 Function,
93 void *HandlerContext,
94 void **RegionContext);
96 static void
97 AeAttachedDataHandler (
98 ACPI_HANDLE Object,
99 void *Data);
101 static void
102 AeAttachedDataHandler2 (
103 ACPI_HANDLE Object,
104 void *Data);
106 static UINT32
107 AeInterfaceHandler (
108 ACPI_STRING InterfaceName,
109 UINT32 Supported);
111 static ACPI_STATUS
112 AeInstallEcHandler (
113 ACPI_HANDLE ObjHandle,
114 UINT32 Level,
115 void *Context,
116 void **ReturnValue);
118 static ACPI_STATUS
119 AeInstallPciHandler (
120 ACPI_HANDLE ObjHandle,
121 UINT32 Level,
122 void *Context,
123 void **ReturnValue);
125 static ACPI_STATUS
126 AeInstallDeviceHandlers (
127 void);
129 #if (!ACPI_REDUCED_HARDWARE)
130 static UINT32
131 AeEventHandler (
132 void *Context);
134 static UINT32
135 AeSciHandler (
136 void *Context);
138 static char *TableEvents[] =
140 "LOAD",
141 "UNLOAD",
142 "UNKNOWN"
144 #endif /* !ACPI_REDUCED_HARDWARE */
147 static UINT32 SigintCount = 0;
148 static AE_DEBUG_REGIONS AeRegions;
149 BOOLEAN AcpiGbl_DisplayRegionAccess = FALSE;
152 * We will override some of the default region handlers, especially the
153 * SystemMemory handler, which must be implemented locally. Do not override
154 * the PCI_Config handler since we would like to exercise the default handler
155 * code. These handlers are installed "early" - before any _REG methods
156 * are executed - since they are special in the sense that the ACPI spec
157 * declares that they must "always be available". Cannot override the
158 * DataTable region handler either -- needed for test execution.
160 static ACPI_ADR_SPACE_TYPE DefaultSpaceIdList[] =
162 ACPI_ADR_SPACE_SYSTEM_MEMORY,
163 ACPI_ADR_SPACE_SYSTEM_IO
167 * We will install handlers for some of the various address space IDs.
168 * Test one user-defined address space (used by aslts).
170 #define ACPI_ADR_SPACE_USER_DEFINED1 0x80
171 #define ACPI_ADR_SPACE_USER_DEFINED2 0xE4
173 static ACPI_ADR_SPACE_TYPE SpaceIdList[] =
175 ACPI_ADR_SPACE_SMBUS,
176 ACPI_ADR_SPACE_CMOS,
177 ACPI_ADR_SPACE_PCI_BAR_TARGET,
178 ACPI_ADR_SPACE_IPMI,
179 ACPI_ADR_SPACE_GPIO,
180 ACPI_ADR_SPACE_GSBUS,
181 ACPI_ADR_SPACE_FIXED_HARDWARE,
182 ACPI_ADR_SPACE_USER_DEFINED1,
183 ACPI_ADR_SPACE_USER_DEFINED2
186 static ACPI_CONNECTION_INFO AeMyContext;
189 /******************************************************************************
191 * FUNCTION: AeCtrlCHandler
193 * PARAMETERS: Sig
195 * RETURN: none
197 * DESCRIPTION: Control-C handler. Abort running control method if any.
199 *****************************************************************************/
201 void ACPI_SYSTEM_XFACE
202 AeCtrlCHandler (
203 int Sig)
206 signal (SIGINT, SIG_IGN);
207 SigintCount++;
209 AcpiOsPrintf ("Caught a ctrl-c (#%u)\n\n", SigintCount);
211 if (AcpiGbl_MethodExecuting)
213 AcpiGbl_AbortMethod = TRUE;
214 signal (SIGINT, AeCtrlCHandler);
216 if (SigintCount < 10)
218 return;
222 (void) AcpiOsTerminate ();
223 exit (0);
227 /******************************************************************************
229 * FUNCTION: AeNotifyHandler(s)
231 * PARAMETERS: Standard notify handler parameters
233 * RETURN: Status
235 * DESCRIPTION: Notify handlers for AcpiExec utility. Used by the ASL
236 * test suite(s) to communicate errors and other information to
237 * this utility via the Notify() operator. Tests notify handling
238 * and multiple notify handler support.
240 *****************************************************************************/
242 static void
243 AeNotifyHandler1 (
244 ACPI_HANDLE Device,
245 UINT32 Value,
246 void *Context)
248 AeCommonNotifyHandler (Device, Value, 1);
251 static void
252 AeNotifyHandler2 (
253 ACPI_HANDLE Device,
254 UINT32 Value,
255 void *Context)
257 AeCommonNotifyHandler (Device, Value, 2);
260 static void
261 AeCommonNotifyHandler (
262 ACPI_HANDLE Device,
263 UINT32 Value,
264 UINT32 HandlerId)
266 char *Type;
269 Type = "Device";
270 if (Value <= ACPI_MAX_SYS_NOTIFY)
272 Type = "System";
275 switch (Value)
277 #if 0
278 case 0:
280 printf ("[AcpiExec] Method Error 0x%X: Results not equal\n", Value);
281 if (AcpiGbl_DebugFile)
283 AcpiOsPrintf ("[AcpiExec] Method Error: Results not equal\n");
285 break;
287 case 1:
289 printf ("[AcpiExec] Method Error: Incorrect numeric result\n");
290 if (AcpiGbl_DebugFile)
292 AcpiOsPrintf ("[AcpiExec] Method Error: Incorrect numeric result\n");
294 break;
296 case 2:
298 printf ("[AcpiExec] Method Error: An operand was overwritten\n");
299 if (AcpiGbl_DebugFile)
301 AcpiOsPrintf ("[AcpiExec] Method Error: An operand was overwritten\n");
303 break;
305 #endif
307 default:
309 printf ("[AcpiExec] Handler %u: Received a %s Notify on [%4.4s] %p Value 0x%2.2X (%s)\n",
310 HandlerId, Type, AcpiUtGetNodeName (Device), Device, Value,
311 AcpiUtGetNotifyName (Value));
312 if (AcpiGbl_DebugFile)
314 AcpiOsPrintf ("[AcpiExec] Handler %u: Received a %s notify, Value 0x%2.2X\n",
315 HandlerId, Type, Value);
318 (void) AcpiEvaluateObject (Device, "_NOT", NULL, NULL);
319 break;
324 /******************************************************************************
326 * FUNCTION: AeSystemNotifyHandler
328 * PARAMETERS: Standard notify handler parameters
330 * RETURN: Status
332 * DESCRIPTION: System notify handler for AcpiExec utility. Used by the ASL
333 * test suite(s) to communicate errors and other information to
334 * this utility via the Notify() operator.
336 *****************************************************************************/
338 static void
339 AeSystemNotifyHandler (
340 ACPI_HANDLE Device,
341 UINT32 Value,
342 void *Context)
345 printf ("[AcpiExec] Global: Received a System Notify on [%4.4s] %p Value 0x%2.2X (%s)\n",
346 AcpiUtGetNodeName (Device), Device, Value,
347 AcpiUtGetNotifyName (Value));
348 if (AcpiGbl_DebugFile)
350 AcpiOsPrintf ("[AcpiExec] Global: Received a System Notify, Value 0x%2.2X\n", Value);
353 (void) AcpiEvaluateObject (Device, "_NOT", NULL, NULL);
357 /******************************************************************************
359 * FUNCTION: AeDeviceNotifyHandler
361 * PARAMETERS: Standard notify handler parameters
363 * RETURN: Status
365 * DESCRIPTION: Device notify handler for AcpiExec utility. Used by the ASL
366 * test suite(s) to communicate errors and other information to
367 * this utility via the Notify() operator.
369 *****************************************************************************/
371 static void
372 AeDeviceNotifyHandler (
373 ACPI_HANDLE Device,
374 UINT32 Value,
375 void *Context)
378 printf ("[AcpiExec] Global: Received a Device Notify on [%4.4s] %p Value 0x%2.2X (%s)\n",
379 AcpiUtGetNodeName (Device), Device, Value,
380 AcpiUtGetNotifyName (Value));
381 if (AcpiGbl_DebugFile)
383 AcpiOsPrintf ("[AcpiExec] Global: Received a Device Notify, Value 0x%2.2X\n", Value);
386 (void) AcpiEvaluateObject (Device, "_NOT", NULL, NULL);
390 /******************************************************************************
392 * FUNCTION: AeExceptionHandler
394 * PARAMETERS: Standard exception handler parameters
396 * RETURN: Status
398 * DESCRIPTION: System exception handler for AcpiExec utility.
400 *****************************************************************************/
402 static ACPI_STATUS
403 AeExceptionHandler (
404 ACPI_STATUS AmlStatus,
405 ACPI_NAME Name,
406 UINT16 Opcode,
407 UINT32 AmlOffset,
408 void *Context)
410 ACPI_STATUS NewAmlStatus = AmlStatus;
411 ACPI_STATUS Status;
412 ACPI_BUFFER ReturnObj;
413 ACPI_OBJECT_LIST ArgList;
414 ACPI_OBJECT Arg[3];
415 const char *Exception;
418 Exception = AcpiFormatException (AmlStatus);
419 AcpiOsPrintf ("[AcpiExec] Exception %s during execution ", Exception);
420 if (Name)
422 AcpiOsPrintf ("of method [%4.4s]", (char *) &Name);
424 else
426 AcpiOsPrintf ("at module level (table load)");
428 AcpiOsPrintf (" Opcode [%s] @%X\n", AcpiPsGetOpcodeName (Opcode), AmlOffset);
431 * Invoke the _ERR method if present
433 * Setup parameter object
435 ArgList.Count = 3;
436 ArgList.Pointer = Arg;
438 Arg[0].Type = ACPI_TYPE_INTEGER;
439 Arg[0].Integer.Value = AmlStatus;
441 Arg[1].Type = ACPI_TYPE_STRING;
442 Arg[1].String.Pointer = ACPI_CAST_PTR (char, Exception);
443 Arg[1].String.Length = ACPI_STRLEN (Exception);
445 Arg[2].Type = ACPI_TYPE_INTEGER;
446 Arg[2].Integer.Value = AcpiOsGetThreadId();
448 /* Setup return buffer */
450 ReturnObj.Pointer = NULL;
451 ReturnObj.Length = ACPI_ALLOCATE_BUFFER;
453 Status = AcpiEvaluateObject (NULL, "\\_ERR", &ArgList, &ReturnObj);
454 if (ACPI_SUCCESS (Status))
456 if (ReturnObj.Pointer)
458 /* Override original status */
460 NewAmlStatus = (ACPI_STATUS)
461 ((ACPI_OBJECT *) ReturnObj.Pointer)->Integer.Value;
463 AcpiOsFree (ReturnObj.Pointer);
466 else if (Status != AE_NOT_FOUND)
468 AcpiOsPrintf ("[AcpiExec] Could not execute _ERR method, %s\n",
469 AcpiFormatException (Status));
472 /* Global override */
474 if (AcpiGbl_IgnoreErrors)
476 NewAmlStatus = AE_OK;
479 if (NewAmlStatus != AmlStatus)
481 AcpiOsPrintf ("[AcpiExec] Exception override, new status %s\n",
482 AcpiFormatException (NewAmlStatus));
485 return (NewAmlStatus);
489 /******************************************************************************
491 * FUNCTION: AeTableHandler
493 * PARAMETERS: Table handler
495 * RETURN: Status
497 * DESCRIPTION: System table handler for AcpiExec utility.
499 *****************************************************************************/
501 static ACPI_STATUS
502 AeTableHandler (
503 UINT32 Event,
504 void *Table,
505 void *Context)
507 #if (!ACPI_REDUCED_HARDWARE)
508 ACPI_STATUS Status;
509 #endif /* !ACPI_REDUCED_HARDWARE */
512 if (Event > ACPI_NUM_TABLE_EVENTS)
514 Event = ACPI_NUM_TABLE_EVENTS;
517 #if (!ACPI_REDUCED_HARDWARE)
518 /* Enable any GPEs associated with newly-loaded GPE methods */
520 Status = AcpiUpdateAllGpes ();
521 AE_CHECK_OK (AcpiUpdateAllGpes, Status);
523 printf ("[AcpiExec] Table Event %s, [%4.4s] %p\n",
524 TableEvents[Event], ((ACPI_TABLE_HEADER *) Table)->Signature, Table);
525 #endif /* !ACPI_REDUCED_HARDWARE */
527 return (AE_OK);
531 /******************************************************************************
533 * FUNCTION: AeGpeHandler
535 * DESCRIPTION: Common GPE handler for acpiexec
537 *****************************************************************************/
539 UINT32
540 AeGpeHandler (
541 ACPI_HANDLE GpeDevice,
542 UINT32 GpeNumber,
543 void *Context)
545 ACPI_NAMESPACE_NODE *DeviceNode = (ACPI_NAMESPACE_NODE *) GpeDevice;
548 AcpiOsPrintf ("[AcpiExec] GPE Handler received GPE%02X (GPE block %4.4s)\n",
549 GpeNumber, GpeDevice ? DeviceNode->Name.Ascii : "FADT");
551 return (ACPI_REENABLE_GPE);
555 /******************************************************************************
557 * FUNCTION: AeGlobalEventHandler
559 * DESCRIPTION: Global GPE/Fixed event handler
561 *****************************************************************************/
563 void
564 AeGlobalEventHandler (
565 UINT32 Type,
566 ACPI_HANDLE Device,
567 UINT32 EventNumber,
568 void *Context)
570 char *TypeName;
573 switch (Type)
575 case ACPI_EVENT_TYPE_GPE:
577 TypeName = "GPE";
578 break;
580 case ACPI_EVENT_TYPE_FIXED:
582 TypeName = "FixedEvent";
583 break;
585 default:
587 TypeName = "UNKNOWN";
588 break;
591 AcpiOsPrintf ("[AcpiExec] Global Event Handler received: Type %s Number %.2X Dev %p\n",
592 TypeName, EventNumber, Device);
596 /******************************************************************************
598 * FUNCTION: AeAttachedDataHandler
600 * DESCRIPTION: Handler for deletion of nodes with attached data (attached via
601 * AcpiAttachData)
603 *****************************************************************************/
605 static void
606 AeAttachedDataHandler (
607 ACPI_HANDLE Object,
608 void *Data)
610 ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Data);
613 AcpiOsPrintf ("Received an attached data deletion (1) on %4.4s\n",
614 Node->Name.Ascii);
618 /******************************************************************************
620 * FUNCTION: AeAttachedDataHandler2
622 * DESCRIPTION: Handler for deletion of nodes with attached data (attached via
623 * AcpiAttachData)
625 *****************************************************************************/
627 static void
628 AeAttachedDataHandler2 (
629 ACPI_HANDLE Object,
630 void *Data)
632 ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Data);
635 AcpiOsPrintf ("Received an attached data deletion (2) on %4.4s\n",
636 Node->Name.Ascii);
640 /******************************************************************************
642 * FUNCTION: AeInterfaceHandler
644 * DESCRIPTION: Handler for _OSI invocations
646 *****************************************************************************/
648 static UINT32
649 AeInterfaceHandler (
650 ACPI_STRING InterfaceName,
651 UINT32 Supported)
653 ACPI_FUNCTION_NAME (AeInterfaceHandler);
656 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
657 "Received _OSI (\"%s\"), is %ssupported\n",
658 InterfaceName, Supported == 0 ? "not " : ""));
660 return (Supported);
664 #if (!ACPI_REDUCED_HARDWARE)
665 /******************************************************************************
667 * FUNCTION: AeEventHandler, AeSciHandler
669 * DESCRIPTION: Handler for Fixed Events and SCIs
671 *****************************************************************************/
673 static UINT32
674 AeEventHandler (
675 void *Context)
677 return (0);
680 static UINT32
681 AeSciHandler (
682 void *Context)
685 AcpiOsPrintf ("[AcpiExec] Received an SCI at handler\n");
686 return (0);
689 #endif /* !ACPI_REDUCED_HARDWARE */
692 /******************************************************************************
694 * FUNCTION: AeRegionInit
696 * PARAMETERS: None
698 * RETURN: Status
700 * DESCRIPTION: Opregion init function.
702 *****************************************************************************/
704 static ACPI_STATUS
705 AeRegionInit (
706 ACPI_HANDLE RegionHandle,
707 UINT32 Function,
708 void *HandlerContext,
709 void **RegionContext)
712 if (Function == ACPI_REGION_DEACTIVATE)
714 *RegionContext = NULL;
716 else
718 *RegionContext = RegionHandle;
721 return (AE_OK);
725 /*******************************************************************************
727 * FUNCTION: AeInstallSciHandler
729 * PARAMETERS: None
731 * RETURN: Status
733 * DESCRIPTION: Install handler for SCIs. Exercise the code by doing an
734 * install/remove/install.
736 ******************************************************************************/
738 static ACPI_STATUS
739 AeInstallSciHandler (
740 void)
742 ACPI_STATUS Status;
745 Status = AcpiInstallSciHandler (AeSciHandler, &AeMyContext);
746 if (ACPI_FAILURE (Status))
748 ACPI_EXCEPTION ((AE_INFO, Status,
749 "Could not install an SCI handler (1)"));
752 Status = AcpiRemoveSciHandler (AeSciHandler);
753 if (ACPI_FAILURE (Status))
755 ACPI_EXCEPTION ((AE_INFO, Status,
756 "Could not remove an SCI handler"));
759 Status = AcpiInstallSciHandler (AeSciHandler, &AeMyContext);
760 if (ACPI_FAILURE (Status))
762 ACPI_EXCEPTION ((AE_INFO, Status,
763 "Could not install an SCI handler (2)"));
766 return (Status);
770 /*******************************************************************************
772 * FUNCTION: AeInstallDeviceHandlers, AeInstallEcHandler,
773 * AeInstallPciHandler
775 * PARAMETERS: ACPI_WALK_NAMESPACE callback
777 * RETURN: Status
779 * DESCRIPTION: Walk entire namespace, install a handler for every EC
780 * and PCI device found.
782 ******************************************************************************/
784 static ACPI_STATUS
785 AeInstallEcHandler (
786 ACPI_HANDLE ObjHandle,
787 UINT32 Level,
788 void *Context,
789 void **ReturnValue)
791 ACPI_STATUS Status;
794 /* Install the handler for this EC device */
796 Status = AcpiInstallAddressSpaceHandler (ObjHandle, ACPI_ADR_SPACE_EC,
797 AeRegionHandler, AeRegionInit, &AeMyContext);
798 if (ACPI_FAILURE (Status))
800 ACPI_EXCEPTION ((AE_INFO, Status,
801 "Could not install an OpRegion handler for EC device (%p)",
802 ObjHandle));
805 return (Status);
808 static ACPI_STATUS
809 AeInstallPciHandler (
810 ACPI_HANDLE ObjHandle,
811 UINT32 Level,
812 void *Context,
813 void **ReturnValue)
815 ACPI_STATUS Status;
818 /* Install memory and I/O handlers for the PCI device */
820 Status = AcpiInstallAddressSpaceHandler (ObjHandle, ACPI_ADR_SPACE_SYSTEM_IO,
821 AeRegionHandler, AeRegionInit, &AeMyContext);
822 if (ACPI_FAILURE (Status))
824 ACPI_EXCEPTION ((AE_INFO, Status,
825 "Could not install an OpRegion handler for PCI device (%p)",
826 ObjHandle));
829 Status = AcpiInstallAddressSpaceHandler (ObjHandle, ACPI_ADR_SPACE_SYSTEM_MEMORY,
830 AeRegionHandler, AeRegionInit, &AeMyContext);
831 if (ACPI_FAILURE (Status))
833 ACPI_EXCEPTION ((AE_INFO, Status,
834 "Could not install an OpRegion handler for PCI device (%p)",
835 ObjHandle));
838 return (AE_CTRL_TERMINATE);
841 static ACPI_STATUS
842 AeInstallDeviceHandlers (
843 void)
846 /* Find all Embedded Controller devices */
848 AcpiGetDevices ("PNP0C09", AeInstallEcHandler, NULL, NULL);
850 /* Install a PCI handler */
852 AcpiGetDevices ("PNP0A08", AeInstallPciHandler, NULL, NULL);
853 return (AE_OK);
857 /******************************************************************************
859 * FUNCTION: AeInstallLateHandlers
861 * PARAMETERS: None
863 * RETURN: Status
865 * DESCRIPTION: Install handlers for the AcpiExec utility.
867 *****************************************************************************/
869 ACPI_STATUS
870 AeInstallLateHandlers (
871 void)
873 ACPI_STATUS Status;
874 UINT32 i;
877 #if (!ACPI_REDUCED_HARDWARE)
878 if (!AcpiGbl_ReducedHardware)
880 /* Install a user SCI handler */
882 Status = AeInstallSciHandler ();
883 AE_CHECK_OK (AeInstallSciHandler, Status);
885 /* Install some fixed event handlers */
887 Status = AcpiInstallFixedEventHandler (ACPI_EVENT_GLOBAL, AeEventHandler, NULL);
888 AE_CHECK_OK (AcpiInstallFixedEventHandler, Status);
890 Status = AcpiInstallFixedEventHandler (ACPI_EVENT_RTC, AeEventHandler, NULL);
891 AE_CHECK_OK (AcpiInstallFixedEventHandler, Status);
893 #endif /* !ACPI_REDUCED_HARDWARE */
895 AeMyContext.Connection = NULL;
896 AeMyContext.AccessLength = 0xA5;
899 * We will install a handler for each EC device, directly under the EC
900 * device definition. This is unlike the other handlers which we install
901 * at the root node. Also install memory and I/O handlers at any PCI
902 * devices.
904 AeInstallDeviceHandlers ();
907 * Install handlers for some of the "device driver" address spaces
908 * such as SMBus, etc.
910 for (i = 0; i < ACPI_ARRAY_LENGTH (SpaceIdList); i++)
912 /* Install handler at the root object */
914 Status = AcpiInstallAddressSpaceHandler (ACPI_ROOT_OBJECT,
915 SpaceIdList[i], AeRegionHandler,
916 AeRegionInit, &AeMyContext);
917 if (ACPI_FAILURE (Status))
919 ACPI_EXCEPTION ((AE_INFO, Status,
920 "Could not install an OpRegion handler for %s space(%u)",
921 AcpiUtGetRegionName((UINT8) SpaceIdList[i]), SpaceIdList[i]));
922 return (Status);
926 return (AE_OK);
930 /******************************************************************************
932 * FUNCTION: AeInstallEarlyHandlers
934 * PARAMETERS: None
936 * RETURN: Status
938 * DESCRIPTION: Install handlers for the AcpiExec utility.
940 * Notes: Don't install handler for PCI_Config, we want to use the
941 * default handler to exercise that code.
943 *****************************************************************************/
945 ACPI_STATUS
946 AeInstallEarlyHandlers (
947 void)
949 ACPI_STATUS Status;
950 UINT32 i;
951 ACPI_HANDLE Handle;
954 ACPI_FUNCTION_ENTRY ();
957 Status = AcpiInstallInterfaceHandler (AeInterfaceHandler);
958 if (ACPI_FAILURE (Status))
960 printf ("Could not install interface handler, %s\n",
961 AcpiFormatException (Status));
964 Status = AcpiInstallTableHandler (AeTableHandler, NULL);
965 if (ACPI_FAILURE (Status))
967 printf ("Could not install table handler, %s\n",
968 AcpiFormatException (Status));
971 Status = AcpiInstallExceptionHandler (AeExceptionHandler);
972 if (ACPI_FAILURE (Status))
974 printf ("Could not install exception handler, %s\n",
975 AcpiFormatException (Status));
978 /* Install global notify handlers */
980 Status = AcpiInstallNotifyHandler (ACPI_ROOT_OBJECT, ACPI_SYSTEM_NOTIFY,
981 AeSystemNotifyHandler, NULL);
982 if (ACPI_FAILURE (Status))
984 printf ("Could not install a global system notify handler, %s\n",
985 AcpiFormatException (Status));
988 Status = AcpiInstallNotifyHandler (ACPI_ROOT_OBJECT, ACPI_DEVICE_NOTIFY,
989 AeDeviceNotifyHandler, NULL);
990 if (ACPI_FAILURE (Status))
992 printf ("Could not install a global notify handler, %s\n",
993 AcpiFormatException (Status));
996 Status = AcpiGetHandle (NULL, "\\_SB", &Handle);
997 if (ACPI_SUCCESS (Status))
999 Status = AcpiInstallNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY,
1000 AeNotifyHandler1, NULL);
1001 if (ACPI_FAILURE (Status))
1003 printf ("Could not install a notify handler, %s\n",
1004 AcpiFormatException (Status));
1007 Status = AcpiRemoveNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY,
1008 AeNotifyHandler1);
1009 if (ACPI_FAILURE (Status))
1011 printf ("Could not remove a notify handler, %s\n",
1012 AcpiFormatException (Status));
1015 Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
1016 AeNotifyHandler1, NULL);
1017 AE_CHECK_OK (AcpiInstallNotifyHandler, Status);
1019 Status = AcpiRemoveNotifyHandler (Handle, ACPI_ALL_NOTIFY,
1020 AeNotifyHandler1);
1021 AE_CHECK_OK (AcpiRemoveNotifyHandler, Status);
1023 #if 0
1024 Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
1025 AeNotifyHandler1, NULL);
1026 if (ACPI_FAILURE (Status))
1028 printf ("Could not install a notify handler, %s\n",
1029 AcpiFormatException (Status));
1031 #endif
1033 /* Install two handlers for _SB_ */
1035 Status = AcpiInstallNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY,
1036 AeNotifyHandler1, ACPI_CAST_PTR (void, 0x01234567));
1038 Status = AcpiInstallNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY,
1039 AeNotifyHandler2, ACPI_CAST_PTR (void, 0x89ABCDEF));
1041 /* Attempt duplicate handler installation, should fail */
1043 Status = AcpiInstallNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY,
1044 AeNotifyHandler1, ACPI_CAST_PTR (void, 0x77777777));
1046 Status = AcpiAttachData (Handle, AeAttachedDataHandler, Handle);
1047 AE_CHECK_OK (AcpiAttachData, Status);
1049 Status = AcpiDetachData (Handle, AeAttachedDataHandler);
1050 AE_CHECK_OK (AcpiDetachData, Status);
1052 /* Test attach data at the root object */
1054 Status = AcpiAttachData (ACPI_ROOT_OBJECT, AeAttachedDataHandler,
1055 AcpiGbl_RootNode);
1056 AE_CHECK_OK (AcpiAttachData, Status);
1058 Status = AcpiAttachData (ACPI_ROOT_OBJECT, AeAttachedDataHandler2,
1059 AcpiGbl_RootNode);
1060 AE_CHECK_OK (AcpiAttachData, Status);
1062 /* Test support for multiple attaches */
1064 Status = AcpiAttachData (Handle, AeAttachedDataHandler, Handle);
1065 AE_CHECK_OK (AcpiAttachData, Status);
1067 Status = AcpiAttachData (Handle, AeAttachedDataHandler2, Handle);
1068 AE_CHECK_OK (AcpiAttachData, Status);
1070 else
1072 printf ("No _SB_ found, %s\n", AcpiFormatException (Status));
1076 Status = AcpiGetHandle (NULL, "\\_TZ.TZ1", &Handle);
1077 if (ACPI_SUCCESS (Status))
1079 Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
1080 AeNotifyHandler1, ACPI_CAST_PTR (void, 0x01234567));
1082 Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
1083 AeNotifyHandler2, ACPI_CAST_PTR (void, 0x89ABCDEF));
1085 Status = AcpiRemoveNotifyHandler (Handle, ACPI_ALL_NOTIFY,
1086 AeNotifyHandler1);
1087 Status = AcpiRemoveNotifyHandler (Handle, ACPI_ALL_NOTIFY,
1088 AeNotifyHandler2);
1090 Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
1091 AeNotifyHandler2, ACPI_CAST_PTR (void, 0x89ABCDEF));
1093 Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
1094 AeNotifyHandler1, ACPI_CAST_PTR (void, 0x01234567));
1097 Status = AcpiGetHandle (NULL, "\\_PR.CPU0", &Handle);
1098 if (ACPI_SUCCESS (Status))
1100 Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
1101 AeNotifyHandler1, ACPI_CAST_PTR (void, 0x01234567));
1103 Status = AcpiInstallNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY,
1104 AeNotifyHandler2, ACPI_CAST_PTR (void, 0x89ABCDEF));
1108 * Install handlers that will override the default handlers for some of
1109 * the space IDs.
1111 for (i = 0; i < ACPI_ARRAY_LENGTH (DefaultSpaceIdList); i++)
1113 /* Install handler at the root object */
1115 Status = AcpiInstallAddressSpaceHandler (ACPI_ROOT_OBJECT,
1116 DefaultSpaceIdList[i], AeRegionHandler,
1117 AeRegionInit, &AeMyContext);
1118 if (ACPI_FAILURE (Status))
1120 ACPI_EXCEPTION ((AE_INFO, Status,
1121 "Could not install a default OpRegion handler for %s space(%u)",
1122 AcpiUtGetRegionName ((UINT8) DefaultSpaceIdList[i]),
1123 DefaultSpaceIdList[i]));
1124 return (Status);
1129 * Initialize the global Region Handler space
1130 * MCW 3/23/00
1132 AeRegions.NumberOfRegions = 0;
1133 AeRegions.RegionList = NULL;
1134 return (Status);
1138 /******************************************************************************
1140 * FUNCTION: AeRegionHandler
1142 * PARAMETERS: Standard region handler parameters
1144 * RETURN: Status
1146 * DESCRIPTION: Test handler - Handles some dummy regions via memory that can
1147 * be manipulated in Ring 3. Simulates actual reads and writes.
1149 *****************************************************************************/
1151 ACPI_STATUS
1152 AeRegionHandler (
1153 UINT32 Function,
1154 ACPI_PHYSICAL_ADDRESS Address,
1155 UINT32 BitWidth,
1156 UINT64 *Value,
1157 void *HandlerContext,
1158 void *RegionContext)
1161 ACPI_OPERAND_OBJECT *RegionObject = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, RegionContext);
1162 UINT8 *Buffer = ACPI_CAST_PTR (UINT8, Value);
1163 ACPI_PHYSICAL_ADDRESS BaseAddress;
1164 ACPI_SIZE Length;
1165 BOOLEAN BufferExists;
1166 AE_REGION *RegionElement;
1167 void *BufferValue;
1168 ACPI_STATUS Status;
1169 UINT32 ByteWidth;
1170 UINT32 i;
1171 UINT8 SpaceId;
1172 ACPI_CONNECTION_INFO *MyContext;
1173 UINT32 Value1;
1174 UINT32 Value2;
1175 ACPI_RESOURCE *Resource;
1178 ACPI_FUNCTION_NAME (AeRegionHandler);
1181 * If the object is not a region, simply return
1183 if (RegionObject->Region.Type != ACPI_TYPE_REGION)
1185 return (AE_OK);
1188 /* Check that we actually got back our context parameter */
1190 if (HandlerContext != &AeMyContext)
1192 printf ("Region handler received incorrect context %p, should be %p\n",
1193 HandlerContext, &AeMyContext);
1196 MyContext = ACPI_CAST_PTR (ACPI_CONNECTION_INFO, HandlerContext);
1199 * Find the region's address space and length before searching
1200 * the linked list.
1202 BaseAddress = RegionObject->Region.Address;
1203 Length = (ACPI_SIZE) RegionObject->Region.Length;
1204 SpaceId = RegionObject->Region.SpaceId;
1206 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, "Operation Region request on %s at 0x%X\n",
1207 AcpiUtGetRegionName (RegionObject->Region.SpaceId),
1208 (UINT32) Address));
1211 * Region support can be disabled with the -do option.
1212 * We use this to support dynamically loaded tables where we pass a valid
1213 * address to the AML.
1215 if (AcpiGbl_DbOpt_NoRegionSupport)
1217 BufferValue = ACPI_TO_POINTER (Address);
1218 ByteWidth = (BitWidth / 8);
1220 if (BitWidth % 8)
1222 ByteWidth += 1;
1224 goto DoFunction;
1227 switch (SpaceId)
1229 case ACPI_ADR_SPACE_SYSTEM_IO:
1231 * For I/O space, exercise the port validation
1232 * Note: ReadPort currently always returns all ones, length=BitLength
1234 switch (Function & ACPI_IO_MASK)
1236 case ACPI_READ:
1238 if (BitWidth == 64)
1240 /* Split the 64-bit request into two 32-bit requests */
1242 Status = AcpiHwReadPort (Address, &Value1, 32);
1243 AE_CHECK_OK (AcpiHwReadPort, Status);
1244 Status = AcpiHwReadPort (Address+4, &Value2, 32);
1245 AE_CHECK_OK (AcpiHwReadPort, Status);
1247 *Value = Value1 | ((UINT64) Value2 << 32);
1249 else
1251 Status = AcpiHwReadPort (Address, &Value1, BitWidth);
1252 AE_CHECK_OK (AcpiHwReadPort, Status);
1253 *Value = (UINT64) Value1;
1255 break;
1257 case ACPI_WRITE:
1259 if (BitWidth == 64)
1261 /* Split the 64-bit request into two 32-bit requests */
1263 Status = AcpiHwWritePort (Address, ACPI_LODWORD (*Value), 32);
1264 AE_CHECK_OK (AcpiHwWritePort, Status);
1265 Status = AcpiHwWritePort (Address+4, ACPI_HIDWORD (*Value), 32);
1266 AE_CHECK_OK (AcpiHwWritePort, Status);
1268 else
1270 Status = AcpiHwWritePort (Address, (UINT32) *Value, BitWidth);
1271 AE_CHECK_OK (AcpiHwWritePort, Status);
1273 break;
1275 default:
1277 Status = AE_BAD_PARAMETER;
1278 break;
1281 if (ACPI_FAILURE (Status))
1283 return (Status);
1286 /* Now go ahead and simulate the hardware */
1287 break;
1290 * SMBus and GenericSerialBus support the various bidirectional
1291 * protocols.
1293 case ACPI_ADR_SPACE_SMBUS:
1294 case ACPI_ADR_SPACE_GSBUS: /* ACPI 5.0 */
1296 Length = 0;
1298 switch (Function & ACPI_IO_MASK)
1300 case ACPI_READ:
1302 switch (Function >> 16)
1304 case AML_FIELD_ATTRIB_QUICK:
1305 case AML_FIELD_ATTRIB_SEND_RCV:
1306 case AML_FIELD_ATTRIB_BYTE:
1308 Length = 1;
1309 break;
1311 case AML_FIELD_ATTRIB_WORD:
1312 case AML_FIELD_ATTRIB_WORD_CALL:
1314 Length = 2;
1315 break;
1317 case AML_FIELD_ATTRIB_BLOCK:
1318 case AML_FIELD_ATTRIB_BLOCK_CALL:
1320 Length = 32;
1321 break;
1323 case AML_FIELD_ATTRIB_MULTIBYTE:
1324 case AML_FIELD_ATTRIB_RAW_BYTES:
1325 case AML_FIELD_ATTRIB_RAW_PROCESS:
1327 /* (-2) for status/length */
1328 Length = MyContext->AccessLength - 2;
1329 break;
1331 default:
1333 break;
1335 break;
1337 case ACPI_WRITE:
1339 switch (Function >> 16)
1341 case AML_FIELD_ATTRIB_QUICK:
1342 case AML_FIELD_ATTRIB_SEND_RCV:
1343 case AML_FIELD_ATTRIB_BYTE:
1344 case AML_FIELD_ATTRIB_WORD:
1345 case AML_FIELD_ATTRIB_BLOCK:
1347 Length = 0;
1348 break;
1350 case AML_FIELD_ATTRIB_WORD_CALL:
1351 Length = 2;
1352 break;
1354 case AML_FIELD_ATTRIB_BLOCK_CALL:
1355 Length = 32;
1356 break;
1358 case AML_FIELD_ATTRIB_MULTIBYTE:
1359 case AML_FIELD_ATTRIB_RAW_BYTES:
1360 case AML_FIELD_ATTRIB_RAW_PROCESS:
1362 /* (-2) for status/length */
1363 Length = MyContext->AccessLength - 2;
1364 break;
1366 default:
1368 break;
1370 break;
1372 default:
1374 break;
1377 if (AcpiGbl_DisplayRegionAccess)
1379 AcpiOsPrintf ("AcpiExec: %s "
1380 "%s: Attr %X Addr %.4X BaseAddr %.4X Len %.2X Width %X BufLen %X",
1381 AcpiUtGetRegionName (SpaceId),
1382 (Function & ACPI_IO_MASK) ? "Write" : "Read ",
1383 (UINT32) (Function >> 16),
1384 (UINT32) Address, (UINT32) BaseAddress,
1385 Length, BitWidth, Buffer[1]);
1387 /* GenericSerialBus has a Connection() parameter */
1389 if (SpaceId == ACPI_ADR_SPACE_GSBUS)
1391 Status = AcpiBufferToResource (MyContext->Connection,
1392 MyContext->Length, &Resource);
1394 AcpiOsPrintf (" [AccLen %.2X Conn %p]",
1395 MyContext->AccessLength, MyContext->Connection);
1397 AcpiOsPrintf ("\n");
1400 /* Setup the return buffer. Note: ASLTS depends on these fill values */
1402 for (i = 0; i < Length; i++)
1404 Buffer[i+2] = (UINT8) (0xA0 + i);
1407 Buffer[0] = 0x7A;
1408 Buffer[1] = (UINT8) Length;
1409 return (AE_OK);
1412 case ACPI_ADR_SPACE_IPMI: /* ACPI 4.0 */
1414 if (AcpiGbl_DisplayRegionAccess)
1416 AcpiOsPrintf ("AcpiExec: IPMI "
1417 "%s: Attr %X Addr %.4X BaseAddr %.4X Len %.2X Width %X BufLen %X\n",
1418 (Function & ACPI_IO_MASK) ? "Write" : "Read ",
1419 (UINT32) (Function >> 16), (UINT32) Address, (UINT32) BaseAddress,
1420 Length, BitWidth, Buffer[1]);
1424 * Regardless of a READ or WRITE, this handler is passed a 66-byte
1425 * buffer in which to return the IPMI status/length/data.
1427 * Return some example data to show use of the bidirectional buffer
1429 Buffer[0] = 0; /* Status byte */
1430 Buffer[1] = 64; /* Return buffer data length */
1431 Buffer[2] = 0; /* Completion code */
1432 Buffer[3] = 0; /* Reserved */
1435 * Fill the 66-byte buffer with the return data.
1436 * Note: ASLTS depends on these fill values.
1438 for (i = 4; i < 66; i++)
1440 Buffer[i] = (UINT8) (i);
1442 return (AE_OK);
1444 default:
1445 break;
1449 * Search through the linked list for this region's buffer
1451 BufferExists = FALSE;
1452 RegionElement = AeRegions.RegionList;
1454 if (AeRegions.NumberOfRegions)
1456 while (!BufferExists && RegionElement)
1458 if (RegionElement->Address == BaseAddress &&
1459 RegionElement->Length == Length &&
1460 RegionElement->SpaceId == SpaceId)
1462 BufferExists = TRUE;
1464 else
1466 RegionElement = RegionElement->NextRegion;
1472 * If the Region buffer does not exist, create it now
1474 if (!BufferExists)
1477 * Do the memory allocations first
1479 RegionElement = AcpiOsAllocate (sizeof (AE_REGION));
1480 if (!RegionElement)
1482 return (AE_NO_MEMORY);
1485 RegionElement->Buffer = AcpiOsAllocate (Length);
1486 if (!RegionElement->Buffer)
1488 AcpiOsFree (RegionElement);
1489 return (AE_NO_MEMORY);
1492 /* Initialize the region with the default fill value */
1494 ACPI_MEMSET (RegionElement->Buffer, AcpiGbl_RegionFillValue, Length);
1496 RegionElement->Address = BaseAddress;
1497 RegionElement->Length = Length;
1498 RegionElement->SpaceId = SpaceId;
1499 RegionElement->NextRegion = NULL;
1502 * Increment the number of regions and put this one
1503 * at the head of the list as it will probably get accessed
1504 * more often anyway.
1506 AeRegions.NumberOfRegions += 1;
1508 if (AeRegions.RegionList)
1510 RegionElement->NextRegion = AeRegions.RegionList;
1513 AeRegions.RegionList = RegionElement;
1517 * Calculate the size of the memory copy
1519 ByteWidth = (BitWidth / 8);
1521 if (BitWidth % 8)
1523 ByteWidth += 1;
1527 * The buffer exists and is pointed to by RegionElement.
1528 * We now need to verify the request is valid and perform the operation.
1530 * NOTE: RegionElement->Length is in bytes, therefore it we compare against
1531 * ByteWidth (see above)
1533 if (((UINT64) Address + ByteWidth) >
1534 ((UINT64)(RegionElement->Address) + RegionElement->Length))
1536 ACPI_WARNING ((AE_INFO,
1537 "Request on [%4.4s] is beyond region limit Req-0x%X+0x%X, Base=0x%X, Len-0x%X",
1538 (RegionObject->Region.Node)->Name.Ascii, (UINT32) Address,
1539 ByteWidth, (UINT32)(RegionElement->Address),
1540 RegionElement->Length));
1542 return (AE_AML_REGION_LIMIT);
1546 * Get BufferValue to point to the "address" in the buffer
1548 BufferValue = ((UINT8 *) RegionElement->Buffer +
1549 ((UINT64) Address - (UINT64) RegionElement->Address));
1551 DoFunction:
1553 * Perform a read or write to the buffer space
1555 switch (Function)
1557 case ACPI_READ:
1559 * Set the pointer Value to whatever is in the buffer
1561 ACPI_MEMCPY (Value, BufferValue, ByteWidth);
1562 break;
1564 case ACPI_WRITE:
1566 * Write the contents of Value to the buffer
1568 ACPI_MEMCPY (BufferValue, Value, ByteWidth);
1569 break;
1571 default:
1573 return (AE_BAD_PARAMETER);
1576 if (AcpiGbl_DisplayRegionAccess)
1578 switch (SpaceId)
1580 case ACPI_ADR_SPACE_SYSTEM_MEMORY:
1582 AcpiOsPrintf ("AcpiExec: SystemMemory "
1583 "%s: Val %.8X Addr %.4X Width %X [REGION: BaseAddr %.4X Len %.2X]\n",
1584 (Function & ACPI_IO_MASK) ? "Write" : "Read ",
1585 (UINT32) *Value, (UINT32) Address, BitWidth, (UINT32) BaseAddress, Length);
1586 break;
1588 case ACPI_ADR_SPACE_GPIO: /* ACPI 5.0 */
1590 /* This space is required to always be ByteAcc */
1592 Status = AcpiBufferToResource (MyContext->Connection,
1593 MyContext->Length, &Resource);
1595 AcpiOsPrintf ("AcpiExec: GeneralPurposeIo "
1596 "%s: Val %.8X Addr %.4X BaseAddr %.4X Len %.2X Width %X AccLen %.2X Conn %p\n",
1597 (Function & ACPI_IO_MASK) ? "Write" : "Read ", (UINT32) *Value,
1598 (UINT32) Address, (UINT32) BaseAddress, Length, BitWidth,
1599 MyContext->AccessLength, MyContext->Connection);
1600 break;
1602 default:
1604 break;
1608 return (AE_OK);