1 /******************************************************************************
3 * Module Name: aehandlers - Various handlers for acpiexec
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2014, Intel Corp.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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.
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.
46 #define _COMPONENT ACPI_TOOLS
47 ACPI_MODULE_NAME ("aehandlers")
49 /* Local prototypes */
64 AeCommonNotifyHandler (
70 AeDeviceNotifyHandler (
77 ACPI_STATUS AmlStatus,
91 ACPI_HANDLE RegionHandle,
94 void **RegionContext);
97 AeAttachedDataHandler (
102 AeAttachedDataHandler2 (
108 ACPI_STRING InterfaceName,
113 ACPI_HANDLE ObjHandle,
119 AeInstallPciHandler (
120 ACPI_HANDLE ObjHandle,
126 AeInstallDeviceHandlers (
129 #if (!ACPI_REDUCED_HARDWARE)
138 static char *TableEvents[] =
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
153 * the SystemMemory handler, which must be implemented locally.
154 * These handlers are installed "early" - before any _REG methods
155 * are executed - since they are special in the sense that the ACPI spec
156 * declares that they must "always be available". Cannot override the
157 * DataTable region handler either -- needed for test execution.
159 * NOTE: The local region handler will simulate access to these address
160 * spaces by creating a memory buffer behind each operation region.
162 static ACPI_ADR_SPACE_TYPE DefaultSpaceIdList[] =
164 ACPI_ADR_SPACE_SYSTEM_MEMORY,
165 ACPI_ADR_SPACE_SYSTEM_IO,
166 ACPI_ADR_SPACE_PCI_CONFIG,
171 * We will install handlers for some of the various address space IDs.
172 * Test one user-defined address space (used by aslts).
174 #define ACPI_ADR_SPACE_USER_DEFINED1 0x80
175 #define ACPI_ADR_SPACE_USER_DEFINED2 0xE4
177 static ACPI_ADR_SPACE_TYPE SpaceIdList[] =
179 ACPI_ADR_SPACE_SMBUS,
181 ACPI_ADR_SPACE_PCI_BAR_TARGET,
184 ACPI_ADR_SPACE_GSBUS,
185 ACPI_ADR_SPACE_FIXED_HARDWARE,
186 ACPI_ADR_SPACE_USER_DEFINED1,
187 ACPI_ADR_SPACE_USER_DEFINED2
190 static ACPI_CONNECTION_INFO AeMyContext;
193 /******************************************************************************
195 * FUNCTION: AeCtrlCHandler
201 * DESCRIPTION: Control-C handler. Abort running control method if any.
203 *****************************************************************************/
205 void ACPI_SYSTEM_XFACE
210 signal (SIGINT, SIG_IGN);
213 AcpiOsPrintf ("Caught a ctrl-c (#%u)\n\n", SigintCount);
215 if (AcpiGbl_MethodExecuting)
217 AcpiGbl_AbortMethod = TRUE;
218 signal (SIGINT, AeCtrlCHandler);
220 if (SigintCount < 10)
226 (void) AcpiOsTerminate ();
231 /******************************************************************************
233 * FUNCTION: AeNotifyHandler(s)
235 * PARAMETERS: Standard notify handler parameters
239 * DESCRIPTION: Notify handlers for AcpiExec utility. Used by the ASL
240 * test suite(s) to communicate errors and other information to
241 * this utility via the Notify() operator. Tests notify handling
242 * and multiple notify handler support.
244 *****************************************************************************/
252 AeCommonNotifyHandler (Device, Value, 1);
261 AeCommonNotifyHandler (Device, Value, 2);
265 AeCommonNotifyHandler (
274 if (Value <= ACPI_MAX_SYS_NOTIFY)
284 printf ("[AcpiExec] Method Error 0x%X: Results not equal\n", Value);
285 if (AcpiGbl_DebugFile)
287 AcpiOsPrintf ("[AcpiExec] Method Error: Results not equal\n");
293 printf ("[AcpiExec] Method Error: Incorrect numeric result\n");
294 if (AcpiGbl_DebugFile)
296 AcpiOsPrintf ("[AcpiExec] Method Error: Incorrect numeric result\n");
302 printf ("[AcpiExec] Method Error: An operand was overwritten\n");
303 if (AcpiGbl_DebugFile)
305 AcpiOsPrintf ("[AcpiExec] Method Error: An operand was overwritten\n");
313 printf ("[AcpiExec] Handler %u: Received a %s Notify on [%4.4s] %p Value 0x%2.2X (%s)\n",
314 HandlerId, Type, AcpiUtGetNodeName (Device), Device, Value,
315 AcpiUtGetNotifyName (Value, ACPI_TYPE_ANY));
316 if (AcpiGbl_DebugFile)
318 AcpiOsPrintf ("[AcpiExec] Handler %u: Received a %s notify, Value 0x%2.2X\n",
319 HandlerId, Type, Value);
322 (void) AcpiEvaluateObject (Device, "_NOT", NULL, NULL);
328 /******************************************************************************
330 * FUNCTION: AeSystemNotifyHandler
332 * PARAMETERS: Standard notify handler parameters
336 * DESCRIPTION: System notify handler for AcpiExec utility. Used by the ASL
337 * test suite(s) to communicate errors and other information to
338 * this utility via the Notify() operator.
340 *****************************************************************************/
343 AeSystemNotifyHandler (
349 printf ("[AcpiExec] Global: Received a System Notify on [%4.4s] %p Value 0x%2.2X (%s)\n",
350 AcpiUtGetNodeName (Device), Device, Value,
351 AcpiUtGetNotifyName (Value, ACPI_TYPE_ANY));
352 if (AcpiGbl_DebugFile)
354 AcpiOsPrintf ("[AcpiExec] Global: Received a System Notify, Value 0x%2.2X\n", Value);
357 (void) AcpiEvaluateObject (Device, "_NOT", NULL, NULL);
361 /******************************************************************************
363 * FUNCTION: AeDeviceNotifyHandler
365 * PARAMETERS: Standard notify handler parameters
369 * DESCRIPTION: Device notify handler for AcpiExec utility. Used by the ASL
370 * test suite(s) to communicate errors and other information to
371 * this utility via the Notify() operator.
373 *****************************************************************************/
376 AeDeviceNotifyHandler (
382 printf ("[AcpiExec] Global: Received a Device Notify on [%4.4s] %p Value 0x%2.2X (%s)\n",
383 AcpiUtGetNodeName (Device), Device, Value,
384 AcpiUtGetNotifyName (Value, ACPI_TYPE_ANY));
385 if (AcpiGbl_DebugFile)
387 AcpiOsPrintf ("[AcpiExec] Global: Received a Device Notify, Value 0x%2.2X\n", Value);
390 (void) AcpiEvaluateObject (Device, "_NOT", NULL, NULL);
394 /******************************************************************************
396 * FUNCTION: AeExceptionHandler
398 * PARAMETERS: Standard exception handler parameters
402 * DESCRIPTION: System exception handler for AcpiExec utility.
404 *****************************************************************************/
408 ACPI_STATUS AmlStatus,
414 ACPI_STATUS NewAmlStatus = AmlStatus;
416 ACPI_BUFFER ReturnObj;
417 ACPI_OBJECT_LIST ArgList;
419 const char *Exception;
422 Exception = AcpiFormatException (AmlStatus);
423 AcpiOsPrintf ("[AcpiExec] Exception %s during execution ", Exception);
426 AcpiOsPrintf ("of method [%4.4s]", (char *) &Name);
430 AcpiOsPrintf ("at module level (table load)");
432 AcpiOsPrintf (" Opcode [%s] @%X\n", AcpiPsGetOpcodeName (Opcode), AmlOffset);
435 * Invoke the _ERR method if present
437 * Setup parameter object
440 ArgList.Pointer = Arg;
442 Arg[0].Type = ACPI_TYPE_INTEGER;
443 Arg[0].Integer.Value = AmlStatus;
445 Arg[1].Type = ACPI_TYPE_STRING;
446 Arg[1].String.Pointer = ACPI_CAST_PTR (char, Exception);
447 Arg[1].String.Length = ACPI_STRLEN (Exception);
449 Arg[2].Type = ACPI_TYPE_INTEGER;
450 Arg[2].Integer.Value = AcpiOsGetThreadId();
452 /* Setup return buffer */
454 ReturnObj.Pointer = NULL;
455 ReturnObj.Length = ACPI_ALLOCATE_BUFFER;
457 Status = AcpiEvaluateObject (NULL, "\\_ERR", &ArgList, &ReturnObj);
458 if (ACPI_SUCCESS (Status))
460 if (ReturnObj.Pointer)
462 /* Override original status */
464 NewAmlStatus = (ACPI_STATUS)
465 ((ACPI_OBJECT *) ReturnObj.Pointer)->Integer.Value;
467 /* Free a buffer created via ACPI_ALLOCATE_BUFFER */
469 AcpiOsFree (ReturnObj.Pointer);
472 else if (Status != AE_NOT_FOUND)
474 AcpiOsPrintf ("[AcpiExec] Could not execute _ERR method, %s\n",
475 AcpiFormatException (Status));
478 /* Global override */
480 if (AcpiGbl_IgnoreErrors)
482 NewAmlStatus = AE_OK;
485 if (NewAmlStatus != AmlStatus)
487 AcpiOsPrintf ("[AcpiExec] Exception override, new status %s\n",
488 AcpiFormatException (NewAmlStatus));
491 return (NewAmlStatus);
495 /******************************************************************************
497 * FUNCTION: AeTableHandler
499 * PARAMETERS: Table handler
503 * DESCRIPTION: System table handler for AcpiExec utility.
505 *****************************************************************************/
513 #if (!ACPI_REDUCED_HARDWARE)
515 #endif /* !ACPI_REDUCED_HARDWARE */
518 if (Event > ACPI_NUM_TABLE_EVENTS)
520 Event = ACPI_NUM_TABLE_EVENTS;
523 #if (!ACPI_REDUCED_HARDWARE)
524 /* Enable any GPEs associated with newly-loaded GPE methods */
526 Status = AcpiUpdateAllGpes ();
527 AE_CHECK_OK (AcpiUpdateAllGpes, Status);
529 printf ("[AcpiExec] Table Event %s, [%4.4s] %p\n",
530 TableEvents[Event], ((ACPI_TABLE_HEADER *) Table)->Signature, Table);
531 #endif /* !ACPI_REDUCED_HARDWARE */
537 /******************************************************************************
539 * FUNCTION: AeGpeHandler
541 * DESCRIPTION: Common GPE handler for acpiexec
543 *****************************************************************************/
547 ACPI_HANDLE GpeDevice,
551 ACPI_NAMESPACE_NODE *DeviceNode = (ACPI_NAMESPACE_NODE *) GpeDevice;
554 AcpiOsPrintf ("[AcpiExec] GPE Handler received GPE %02X (GPE block %4.4s)\n",
555 GpeNumber, GpeDevice ? DeviceNode->Name.Ascii : "FADT");
557 return (ACPI_REENABLE_GPE);
561 /******************************************************************************
563 * FUNCTION: AeGlobalEventHandler
565 * DESCRIPTION: Global GPE/Fixed event handler
567 *****************************************************************************/
570 AeGlobalEventHandler (
581 case ACPI_EVENT_TYPE_GPE:
586 case ACPI_EVENT_TYPE_FIXED:
588 TypeName = "FixedEvent";
593 TypeName = "UNKNOWN";
597 AcpiOsPrintf ("[AcpiExec] Global Event Handler received: Type %s Number %.2X Dev %p\n",
598 TypeName, EventNumber, Device);
602 /******************************************************************************
604 * FUNCTION: AeAttachedDataHandler
606 * DESCRIPTION: Handler for deletion of nodes with attached data (attached via
609 *****************************************************************************/
612 AeAttachedDataHandler (
616 ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Data);
619 AcpiOsPrintf ("Received an attached data deletion (1) on %4.4s\n",
624 /******************************************************************************
626 * FUNCTION: AeAttachedDataHandler2
628 * DESCRIPTION: Handler for deletion of nodes with attached data (attached via
631 *****************************************************************************/
634 AeAttachedDataHandler2 (
638 ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Data);
641 AcpiOsPrintf ("Received an attached data deletion (2) on %4.4s\n",
646 /******************************************************************************
648 * FUNCTION: AeInterfaceHandler
650 * DESCRIPTION: Handler for _OSI invocations
652 *****************************************************************************/
656 ACPI_STRING InterfaceName,
659 ACPI_FUNCTION_NAME (AeInterfaceHandler);
662 ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
663 "Received _OSI (\"%s\"), is %ssupported\n",
664 InterfaceName, Supported == 0 ? "not " : ""));
670 #if (!ACPI_REDUCED_HARDWARE)
671 /******************************************************************************
673 * FUNCTION: AeEventHandler, AeSciHandler
675 * DESCRIPTION: Handler for Fixed Events and SCIs
677 *****************************************************************************/
691 AcpiOsPrintf ("[AcpiExec] Received an SCI at handler\n");
695 #endif /* !ACPI_REDUCED_HARDWARE */
698 /******************************************************************************
700 * FUNCTION: AeRegionInit
706 * DESCRIPTION: Opregion init function.
708 *****************************************************************************/
712 ACPI_HANDLE RegionHandle,
714 void *HandlerContext,
715 void **RegionContext)
718 if (Function == ACPI_REGION_DEACTIVATE)
720 *RegionContext = NULL;
724 *RegionContext = RegionHandle;
731 /*******************************************************************************
733 * FUNCTION: AeInstallSciHandler
739 * DESCRIPTION: Install handler for SCIs. Exercise the code by doing an
740 * install/remove/install.
742 ******************************************************************************/
745 AeInstallSciHandler (
751 Status = AcpiInstallSciHandler (AeSciHandler, &AeMyContext);
752 if (ACPI_FAILURE (Status))
754 ACPI_EXCEPTION ((AE_INFO, Status,
755 "Could not install an SCI handler (1)"));
758 Status = AcpiRemoveSciHandler (AeSciHandler);
759 if (ACPI_FAILURE (Status))
761 ACPI_EXCEPTION ((AE_INFO, Status,
762 "Could not remove an SCI handler"));
765 Status = AcpiInstallSciHandler (AeSciHandler, &AeMyContext);
766 if (ACPI_FAILURE (Status))
768 ACPI_EXCEPTION ((AE_INFO, Status,
769 "Could not install an SCI handler (2)"));
776 /*******************************************************************************
778 * FUNCTION: AeInstallDeviceHandlers, AeInstallEcHandler,
779 * AeInstallPciHandler
781 * PARAMETERS: ACPI_WALK_NAMESPACE callback
785 * DESCRIPTION: Walk entire namespace, install a handler for every EC
786 * and PCI device found.
788 ******************************************************************************/
792 ACPI_HANDLE ObjHandle,
800 /* Install the handler for this EC device */
802 Status = AcpiInstallAddressSpaceHandler (ObjHandle, ACPI_ADR_SPACE_EC,
803 AeRegionHandler, AeRegionInit, &AeMyContext);
804 if (ACPI_FAILURE (Status))
806 ACPI_EXCEPTION ((AE_INFO, Status,
807 "Could not install an OpRegion handler for EC device (%p)",
815 AeInstallPciHandler (
816 ACPI_HANDLE ObjHandle,
824 /* Install memory and I/O handlers for the PCI device */
826 Status = AcpiInstallAddressSpaceHandler (ObjHandle, ACPI_ADR_SPACE_SYSTEM_IO,
827 AeRegionHandler, AeRegionInit, &AeMyContext);
828 if (ACPI_FAILURE (Status))
830 ACPI_EXCEPTION ((AE_INFO, Status,
831 "Could not install an OpRegion handler for PCI device (%p)",
835 Status = AcpiInstallAddressSpaceHandler (ObjHandle, ACPI_ADR_SPACE_SYSTEM_MEMORY,
836 AeRegionHandler, AeRegionInit, &AeMyContext);
837 if (ACPI_FAILURE (Status))
839 ACPI_EXCEPTION ((AE_INFO, Status,
840 "Could not install an OpRegion handler for PCI device (%p)",
844 return (AE_CTRL_TERMINATE);
848 AeInstallDeviceHandlers (
852 /* Find all Embedded Controller devices */
854 AcpiGetDevices ("PNP0C09", AeInstallEcHandler, NULL, NULL);
856 /* Install a PCI handler */
858 AcpiGetDevices ("PNP0A08", AeInstallPciHandler, NULL, NULL);
863 /******************************************************************************
865 * FUNCTION: AeInstallLateHandlers
871 * DESCRIPTION: Install handlers for the AcpiExec utility.
873 *****************************************************************************/
876 AeInstallLateHandlers (
883 #if (!ACPI_REDUCED_HARDWARE)
884 if (!AcpiGbl_ReducedHardware)
886 /* Install a user SCI handler */
888 Status = AeInstallSciHandler ();
889 AE_CHECK_OK (AeInstallSciHandler, Status);
891 /* Install some fixed event handlers */
893 Status = AcpiInstallFixedEventHandler (ACPI_EVENT_GLOBAL, AeEventHandler, NULL);
894 AE_CHECK_OK (AcpiInstallFixedEventHandler, Status);
896 Status = AcpiInstallFixedEventHandler (ACPI_EVENT_RTC, AeEventHandler, NULL);
897 AE_CHECK_OK (AcpiInstallFixedEventHandler, Status);
899 #endif /* !ACPI_REDUCED_HARDWARE */
901 AeMyContext.Connection = NULL;
902 AeMyContext.AccessLength = 0xA5;
905 * We will install a handler for each EC device, directly under the EC
906 * device definition. This is unlike the other handlers which we install
907 * at the root node. Also install memory and I/O handlers at any PCI
910 AeInstallDeviceHandlers ();
913 * Install handlers for some of the "device driver" address spaces
914 * such as SMBus, etc.
916 for (i = 0; i < ACPI_ARRAY_LENGTH (SpaceIdList); i++)
918 /* Install handler at the root object */
920 Status = AcpiInstallAddressSpaceHandler (ACPI_ROOT_OBJECT,
921 SpaceIdList[i], AeRegionHandler,
922 AeRegionInit, &AeMyContext);
923 if (ACPI_FAILURE (Status))
925 ACPI_EXCEPTION ((AE_INFO, Status,
926 "Could not install an OpRegion handler for %s space(%u)",
927 AcpiUtGetRegionName((UINT8) SpaceIdList[i]), SpaceIdList[i]));
936 /******************************************************************************
938 * FUNCTION: AeInstallEarlyHandlers
944 * DESCRIPTION: Install handlers for the AcpiExec utility.
946 * Notes: Don't install handler for PCI_Config, we want to use the
947 * default handler to exercise that code.
949 *****************************************************************************/
952 AeInstallEarlyHandlers (
960 ACPI_FUNCTION_ENTRY ();
963 Status = AcpiInstallInterfaceHandler (AeInterfaceHandler);
964 if (ACPI_FAILURE (Status))
966 printf ("Could not install interface handler, %s\n",
967 AcpiFormatException (Status));
970 Status = AcpiInstallTableHandler (AeTableHandler, NULL);
971 if (ACPI_FAILURE (Status))
973 printf ("Could not install table handler, %s\n",
974 AcpiFormatException (Status));
977 Status = AcpiInstallExceptionHandler (AeExceptionHandler);
978 if (ACPI_FAILURE (Status))
980 printf ("Could not install exception handler, %s\n",
981 AcpiFormatException (Status));
984 /* Install global notify handlers */
986 Status = AcpiInstallNotifyHandler (ACPI_ROOT_OBJECT, ACPI_SYSTEM_NOTIFY,
987 AeSystemNotifyHandler, NULL);
988 if (ACPI_FAILURE (Status))
990 printf ("Could not install a global system notify handler, %s\n",
991 AcpiFormatException (Status));
994 Status = AcpiInstallNotifyHandler (ACPI_ROOT_OBJECT, ACPI_DEVICE_NOTIFY,
995 AeDeviceNotifyHandler, NULL);
996 if (ACPI_FAILURE (Status))
998 printf ("Could not install a global notify handler, %s\n",
999 AcpiFormatException (Status));
1002 Status = AcpiGetHandle (NULL, "\\_SB", &Handle);
1003 if (ACPI_SUCCESS (Status))
1005 Status = AcpiInstallNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY,
1006 AeNotifyHandler1, NULL);
1007 if (ACPI_FAILURE (Status))
1009 printf ("Could not install a notify handler, %s\n",
1010 AcpiFormatException (Status));
1013 Status = AcpiRemoveNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY,
1015 if (ACPI_FAILURE (Status))
1017 printf ("Could not remove a notify handler, %s\n",
1018 AcpiFormatException (Status));
1021 Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
1022 AeNotifyHandler1, NULL);
1023 AE_CHECK_OK (AcpiInstallNotifyHandler, Status);
1025 Status = AcpiRemoveNotifyHandler (Handle, ACPI_ALL_NOTIFY,
1027 AE_CHECK_OK (AcpiRemoveNotifyHandler, Status);
1030 Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
1031 AeNotifyHandler1, NULL);
1032 if (ACPI_FAILURE (Status))
1034 printf ("Could not install a notify handler, %s\n",
1035 AcpiFormatException (Status));
1039 /* Install two handlers for _SB_ */
1041 Status = AcpiInstallNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY,
1042 AeNotifyHandler1, ACPI_CAST_PTR (void, 0x01234567));
1044 Status = AcpiInstallNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY,
1045 AeNotifyHandler2, ACPI_CAST_PTR (void, 0x89ABCDEF));
1047 /* Attempt duplicate handler installation, should fail */
1049 Status = AcpiInstallNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY,
1050 AeNotifyHandler1, ACPI_CAST_PTR (void, 0x77777777));
1052 Status = AcpiAttachData (Handle, AeAttachedDataHandler, Handle);
1053 AE_CHECK_OK (AcpiAttachData, Status);
1055 Status = AcpiDetachData (Handle, AeAttachedDataHandler);
1056 AE_CHECK_OK (AcpiDetachData, Status);
1058 Status = AcpiAttachData (Handle, AeAttachedDataHandler, Handle);
1059 AE_CHECK_OK (AcpiAttachData, Status);
1061 /* Test support for multiple attaches */
1063 Status = AcpiAttachData (Handle, AeAttachedDataHandler2, Handle);
1064 AE_CHECK_OK (AcpiAttachData, Status);
1068 printf ("No _SB_ found, %s\n", AcpiFormatException (Status));
1072 Status = AcpiGetHandle (NULL, "\\_TZ.TZ1", &Handle);
1073 if (ACPI_SUCCESS (Status))
1075 Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
1076 AeNotifyHandler1, ACPI_CAST_PTR (void, 0x01234567));
1078 Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
1079 AeNotifyHandler2, ACPI_CAST_PTR (void, 0x89ABCDEF));
1081 Status = AcpiRemoveNotifyHandler (Handle, ACPI_ALL_NOTIFY,
1083 Status = AcpiRemoveNotifyHandler (Handle, ACPI_ALL_NOTIFY,
1086 Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
1087 AeNotifyHandler2, ACPI_CAST_PTR (void, 0x89ABCDEF));
1089 Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
1090 AeNotifyHandler1, ACPI_CAST_PTR (void, 0x01234567));
1093 Status = AcpiGetHandle (NULL, "\\_PR.CPU0", &Handle);
1094 if (ACPI_SUCCESS (Status))
1096 Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
1097 AeNotifyHandler1, ACPI_CAST_PTR (void, 0x01234567));
1099 Status = AcpiInstallNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY,
1100 AeNotifyHandler2, ACPI_CAST_PTR (void, 0x89ABCDEF));
1104 * Install handlers that will override the default handlers for some of
1107 for (i = 0; i < ACPI_ARRAY_LENGTH (DefaultSpaceIdList); i++)
1109 /* Install handler at the root object */
1111 Status = AcpiInstallAddressSpaceHandler (ACPI_ROOT_OBJECT,
1112 DefaultSpaceIdList[i], AeRegionHandler,
1113 AeRegionInit, &AeMyContext);
1114 if (ACPI_FAILURE (Status))
1116 ACPI_EXCEPTION ((AE_INFO, Status,
1117 "Could not install a default OpRegion handler for %s space(%u)",
1118 AcpiUtGetRegionName ((UINT8) DefaultSpaceIdList[i]),
1119 DefaultSpaceIdList[i]));
1125 * Initialize the global Region Handler space
1128 AeRegions.NumberOfRegions = 0;
1129 AeRegions.RegionList = NULL;
1134 /******************************************************************************
1136 * FUNCTION: AeRegionHandler
1138 * PARAMETERS: Standard region handler parameters
1142 * DESCRIPTION: Test handler - Handles some dummy regions via memory that can
1143 * be manipulated in Ring 3. Simulates actual reads and writes.
1145 *****************************************************************************/
1150 ACPI_PHYSICAL_ADDRESS Address,
1153 void *HandlerContext,
1154 void *RegionContext)
1157 ACPI_OPERAND_OBJECT *RegionObject = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, RegionContext);
1158 UINT8 *Buffer = ACPI_CAST_PTR (UINT8, Value);
1161 ACPI_PHYSICAL_ADDRESS BaseAddress;
1162 ACPI_PHYSICAL_ADDRESS BaseAddressEnd;
1163 ACPI_PHYSICAL_ADDRESS RegionAddress;
1164 ACPI_PHYSICAL_ADDRESS RegionAddressEnd;
1166 BOOLEAN BufferExists;
1167 BOOLEAN BufferResize;
1168 AE_REGION *RegionElement;
1172 UINT32 RegionLength;
1175 ACPI_CONNECTION_INFO *MyContext;
1178 ACPI_RESOURCE *Resource;
1181 ACPI_FUNCTION_NAME (AeRegionHandler);
1184 * If the object is not a region, simply return
1186 if (RegionObject->Region.Type != ACPI_TYPE_REGION)
1191 /* Check that we actually got back our context parameter */
1193 if (HandlerContext != &AeMyContext)
1195 printf ("Region handler received incorrect context %p, should be %p\n",
1196 HandlerContext, &AeMyContext);
1199 MyContext = ACPI_CAST_PTR (ACPI_CONNECTION_INFO, HandlerContext);
1202 * Find the region's address space and length before searching
1205 BaseAddress = RegionObject->Region.Address;
1206 Length = (ACPI_SIZE) RegionObject->Region.Length;
1207 SpaceId = RegionObject->Region.SpaceId;
1209 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, "Operation Region request on %s at 0x%X\n",
1210 AcpiUtGetRegionName (RegionObject->Region.SpaceId),
1214 * Region support can be disabled with the -do option.
1215 * We use this to support dynamically loaded tables where we pass a valid
1216 * address to the AML.
1218 if (AcpiGbl_DbOpt_NoRegionSupport)
1220 BufferValue = ACPI_TO_POINTER (Address);
1221 ByteWidth = (BitWidth / 8);
1232 case ACPI_ADR_SPACE_SYSTEM_IO:
1234 * For I/O space, exercise the port validation
1235 * Note: ReadPort currently always returns all ones, length=BitLength
1237 switch (Function & ACPI_IO_MASK)
1243 /* Split the 64-bit request into two 32-bit requests */
1245 Status = AcpiHwReadPort (Address, &Value1, 32);
1246 AE_CHECK_OK (AcpiHwReadPort, Status);
1247 Status = AcpiHwReadPort (Address+4, &Value2, 32);
1248 AE_CHECK_OK (AcpiHwReadPort, Status);
1250 *Value = Value1 | ((UINT64) Value2 << 32);
1254 Status = AcpiHwReadPort (Address, &Value1, BitWidth);
1255 AE_CHECK_OK (AcpiHwReadPort, Status);
1256 *Value = (UINT64) Value1;
1264 /* Split the 64-bit request into two 32-bit requests */
1266 Status = AcpiHwWritePort (Address, ACPI_LODWORD (*Value), 32);
1267 AE_CHECK_OK (AcpiHwWritePort, Status);
1268 Status = AcpiHwWritePort (Address+4, ACPI_HIDWORD (*Value), 32);
1269 AE_CHECK_OK (AcpiHwWritePort, Status);
1273 Status = AcpiHwWritePort (Address, (UINT32) *Value, BitWidth);
1274 AE_CHECK_OK (AcpiHwWritePort, Status);
1280 Status = AE_BAD_PARAMETER;
1284 if (ACPI_FAILURE (Status))
1289 /* Now go ahead and simulate the hardware */
1293 * SMBus and GenericSerialBus support the various bidirectional
1296 case ACPI_ADR_SPACE_SMBUS:
1297 case ACPI_ADR_SPACE_GSBUS: /* ACPI 5.0 */
1301 switch (Function & ACPI_IO_MASK)
1305 switch (Function >> 16)
1307 case AML_FIELD_ATTRIB_QUICK:
1308 case AML_FIELD_ATTRIB_SEND_RCV:
1309 case AML_FIELD_ATTRIB_BYTE:
1314 case AML_FIELD_ATTRIB_WORD:
1315 case AML_FIELD_ATTRIB_WORD_CALL:
1320 case AML_FIELD_ATTRIB_BLOCK:
1321 case AML_FIELD_ATTRIB_BLOCK_CALL:
1326 case AML_FIELD_ATTRIB_MULTIBYTE:
1327 case AML_FIELD_ATTRIB_RAW_BYTES:
1328 case AML_FIELD_ATTRIB_RAW_PROCESS:
1330 /* (-2) for status/length */
1331 Length = MyContext->AccessLength - 2;
1342 switch (Function >> 16)
1344 case AML_FIELD_ATTRIB_QUICK:
1345 case AML_FIELD_ATTRIB_SEND_RCV:
1346 case AML_FIELD_ATTRIB_BYTE:
1347 case AML_FIELD_ATTRIB_WORD:
1348 case AML_FIELD_ATTRIB_BLOCK:
1353 case AML_FIELD_ATTRIB_WORD_CALL:
1357 case AML_FIELD_ATTRIB_BLOCK_CALL:
1361 case AML_FIELD_ATTRIB_MULTIBYTE:
1362 case AML_FIELD_ATTRIB_RAW_BYTES:
1363 case AML_FIELD_ATTRIB_RAW_PROCESS:
1365 /* (-2) for status/length */
1366 Length = MyContext->AccessLength - 2;
1380 if (AcpiGbl_DisplayRegionAccess)
1382 AcpiOsPrintf ("AcpiExec: %s "
1383 "%s: Attr %X Addr %.4X BaseAddr %.4X Len %.2X Width %X BufLen %X",
1384 AcpiUtGetRegionName (SpaceId),
1385 (Function & ACPI_IO_MASK) ? "Write" : "Read ",
1386 (UINT32) (Function >> 16),
1387 (UINT32) Address, (UINT32) BaseAddress,
1388 Length, BitWidth, Buffer[1]);
1390 /* GenericSerialBus has a Connection() parameter */
1392 if (SpaceId == ACPI_ADR_SPACE_GSBUS)
1394 Status = AcpiBufferToResource (MyContext->Connection,
1395 MyContext->Length, &Resource);
1397 AcpiOsPrintf (" [AccLen %.2X Conn %p]",
1398 MyContext->AccessLength, MyContext->Connection);
1400 AcpiOsPrintf ("\n");
1403 /* Setup the return buffer. Note: ASLTS depends on these fill values */
1405 for (i = 0; i < Length; i++)
1407 Buffer[i+2] = (UINT8) (0xA0 + i);
1411 Buffer[1] = (UINT8) Length;
1415 case ACPI_ADR_SPACE_IPMI: /* ACPI 4.0 */
1417 if (AcpiGbl_DisplayRegionAccess)
1419 AcpiOsPrintf ("AcpiExec: IPMI "
1420 "%s: Attr %X Addr %.4X BaseAddr %.4X Len %.2X Width %X BufLen %X\n",
1421 (Function & ACPI_IO_MASK) ? "Write" : "Read ",
1422 (UINT32) (Function >> 16), (UINT32) Address, (UINT32) BaseAddress,
1423 Length, BitWidth, Buffer[1]);
1427 * Regardless of a READ or WRITE, this handler is passed a 66-byte
1428 * buffer in which to return the IPMI status/length/data.
1430 * Return some example data to show use of the bidirectional buffer
1432 Buffer[0] = 0; /* Status byte */
1433 Buffer[1] = 64; /* Return buffer data length */
1434 Buffer[2] = 0; /* Completion code */
1435 Buffer[3] = 0; /* Reserved */
1438 * Fill the 66-byte buffer with the return data.
1439 * Note: ASLTS depends on these fill values.
1441 for (i = 4; i < 66; i++)
1443 Buffer[i] = (UINT8) (i);
1452 * Search through the linked list for this region's buffer
1454 BufferExists = FALSE;
1455 BufferResize = FALSE;
1456 RegionElement = AeRegions.RegionList;
1458 if (AeRegions.NumberOfRegions)
1460 BaseAddressEnd = BaseAddress + Length - 1;
1461 while (!BufferExists && RegionElement)
1463 RegionAddress = RegionElement->Address;
1464 RegionAddressEnd = RegionElement->Address + RegionElement->Length - 1;
1465 RegionLength = RegionElement->Length;
1468 * Overlapping Region Support
1470 * While searching through the region buffer list, determine if an
1471 * overlap exists between the requested buffer space and the current
1472 * RegionElement space. If there is an overlap then replace the old
1473 * buffer with a new buffer of increased size before continuing to
1474 * do the read or write
1476 if (RegionElement->SpaceId != SpaceId ||
1477 BaseAddressEnd < RegionAddress ||
1478 BaseAddress > RegionAddressEnd)
1481 * Requested buffer is outside of the current RegionElement
1484 RegionElement = RegionElement->NextRegion;
1489 * Some amount of buffer space sharing exists. There are 4 cases
1494 * 3. Left and right overlap
1495 * 4. Fully contained - no resizing required
1497 BufferExists = TRUE;
1499 if ((BaseAddress >= RegionAddress) &&
1500 (BaseAddress <= RegionAddressEnd) &&
1501 (BaseAddressEnd > RegionAddressEnd))
1505 RegionElement->Length = BaseAddress -
1506 RegionAddress + Length;
1507 BufferResize = TRUE;
1510 else if ((BaseAddressEnd >= RegionAddress) &&
1511 (BaseAddressEnd <= RegionAddressEnd) &&
1512 (BaseAddress < RegionAddress))
1516 RegionElement->Address = BaseAddress;
1517 RegionElement->Length = RegionAddress -
1518 BaseAddress + RegionElement->Length;
1519 BufferResize = TRUE;
1522 else if ((BaseAddress < RegionAddress) &&
1523 (BaseAddressEnd > RegionAddressEnd))
1525 /* Left and right overlap */
1527 RegionElement->Address = BaseAddress;
1528 RegionElement->Length = Length;
1529 BufferResize = TRUE;
1533 * only remaining case is fully contained for which we don't
1534 * need to do anything
1538 NewBuffer = AcpiOsAllocate (RegionElement->Length);
1541 return (AE_NO_MEMORY);
1544 OldBuffer = RegionElement->Buffer;
1545 RegionElement->Buffer = NewBuffer;
1548 /* Initialize the region with the default fill value */
1550 ACPI_MEMSET (RegionElement->Buffer,
1551 AcpiGbl_RegionFillValue, RegionElement->Length);
1554 * Get BufferValue to point (within the new buffer) to the
1555 * base address of the old buffer
1557 BufferValue = (UINT8 *) RegionElement->Buffer +
1558 (UINT64) RegionAddress -
1559 (UINT64) RegionElement->Address;
1562 * Copy the old buffer to its same location within the new
1565 ACPI_MEMCPY (BufferValue, OldBuffer, RegionLength);
1566 AcpiOsFree (OldBuffer);
1573 * If the Region buffer does not exist, create it now
1577 /* Do the memory allocations first */
1579 RegionElement = AcpiOsAllocate (sizeof (AE_REGION));
1582 return (AE_NO_MEMORY);
1585 RegionElement->Buffer = AcpiOsAllocate (Length);
1586 if (!RegionElement->Buffer)
1588 AcpiOsFree (RegionElement);
1589 return (AE_NO_MEMORY);
1592 /* Initialize the region with the default fill value */
1594 ACPI_MEMSET (RegionElement->Buffer, AcpiGbl_RegionFillValue, Length);
1596 RegionElement->Address = BaseAddress;
1597 RegionElement->Length = Length;
1598 RegionElement->SpaceId = SpaceId;
1599 RegionElement->NextRegion = NULL;
1602 * Increment the number of regions and put this one
1603 * at the head of the list as it will probably get accessed
1604 * more often anyway.
1606 AeRegions.NumberOfRegions += 1;
1608 if (AeRegions.RegionList)
1610 RegionElement->NextRegion = AeRegions.RegionList;
1613 AeRegions.RegionList = RegionElement;
1616 /* Calculate the size of the memory copy */
1618 ByteWidth = (BitWidth / 8);
1626 * The buffer exists and is pointed to by RegionElement.
1627 * We now need to verify the request is valid and perform the operation.
1629 * NOTE: RegionElement->Length is in bytes, therefore it we compare against
1630 * ByteWidth (see above)
1632 if (((UINT64) Address + ByteWidth) >
1633 ((UINT64)(RegionElement->Address) + RegionElement->Length))
1635 ACPI_WARNING ((AE_INFO,
1636 "Request on [%4.4s] is beyond region limit Req-0x%X+0x%X, Base=0x%X, Len-0x%X",
1637 (RegionObject->Region.Node)->Name.Ascii, (UINT32) Address,
1638 ByteWidth, (UINT32)(RegionElement->Address),
1639 RegionElement->Length));
1641 return (AE_AML_REGION_LIMIT);
1645 * Get BufferValue to point to the "address" in the buffer
1647 BufferValue = ((UINT8 *) RegionElement->Buffer +
1648 ((UINT64) Address - (UINT64) RegionElement->Address));
1652 * Perform a read or write to the buffer space
1658 * Set the pointer Value to whatever is in the buffer
1660 ACPI_MEMCPY (Value, BufferValue, ByteWidth);
1665 * Write the contents of Value to the buffer
1667 ACPI_MEMCPY (BufferValue, Value, ByteWidth);
1672 return (AE_BAD_PARAMETER);
1675 if (AcpiGbl_DisplayRegionAccess)
1679 case ACPI_ADR_SPACE_SYSTEM_MEMORY:
1681 AcpiOsPrintf ("AcpiExec: SystemMemory "
1682 "%s: Val %.8X Addr %.4X Width %X [REGION: BaseAddr %.4X Len %.2X]\n",
1683 (Function & ACPI_IO_MASK) ? "Write" : "Read ",
1684 (UINT32) *Value, (UINT32) Address, BitWidth, (UINT32) BaseAddress, Length);
1687 case ACPI_ADR_SPACE_GPIO: /* ACPI 5.0 */
1689 /* This space is required to always be ByteAcc */
1691 Status = AcpiBufferToResource (MyContext->Connection,
1692 MyContext->Length, &Resource);
1694 AcpiOsPrintf ("AcpiExec: GeneralPurposeIo "
1695 "%s: Val %.8X Addr %.4X BaseAddr %.4X Len %.2X Width %X AccLen %.2X Conn %p\n",
1696 (Function & ACPI_IO_MASK) ? "Write" : "Read ", (UINT32) *Value,
1697 (UINT32) Address, (UINT32) BaseAddress, Length, BitWidth,
1698 MyContext->AccessLength, MyContext->Connection);