1 /******************************************************************************
3 * Module Name: aehandlers - Various handlers for acpiexec
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2013, 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 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
,
177 ACPI_ADR_SPACE_PCI_BAR_TARGET
,
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
197 * DESCRIPTION: Control-C handler. Abort running control method if any.
199 *****************************************************************************/
201 void ACPI_SYSTEM_XFACE
206 signal (SIGINT
, SIG_IGN
);
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)
222 (void) AcpiOsTerminate ();
227 /******************************************************************************
229 * FUNCTION: AeNotifyHandler(s)
231 * PARAMETERS: Standard notify handler parameters
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 *****************************************************************************/
248 AeCommonNotifyHandler (Device
, Value
, 1);
257 AeCommonNotifyHandler (Device
, Value
, 2);
261 AeCommonNotifyHandler (
270 if (Value
<= ACPI_MAX_SYS_NOTIFY
)
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");
289 printf ("[AcpiExec] Method Error: Incorrect numeric result\n");
290 if (AcpiGbl_DebugFile
)
292 AcpiOsPrintf ("[AcpiExec] Method Error: Incorrect numeric result\n");
298 printf ("[AcpiExec] Method Error: An operand was overwritten\n");
299 if (AcpiGbl_DebugFile
)
301 AcpiOsPrintf ("[AcpiExec] Method Error: An operand was overwritten\n");
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
);
324 /******************************************************************************
326 * FUNCTION: AeSystemNotifyHandler
328 * PARAMETERS: Standard notify handler parameters
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 *****************************************************************************/
339 AeSystemNotifyHandler (
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
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 *****************************************************************************/
372 AeDeviceNotifyHandler (
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
398 * DESCRIPTION: System exception handler for AcpiExec utility.
400 *****************************************************************************/
404 ACPI_STATUS AmlStatus
,
410 ACPI_STATUS NewAmlStatus
= AmlStatus
;
412 ACPI_BUFFER ReturnObj
;
413 ACPI_OBJECT_LIST ArgList
;
415 const char *Exception
;
418 Exception
= AcpiFormatException (AmlStatus
);
419 AcpiOsPrintf ("[AcpiExec] Exception %s during execution ", Exception
);
422 AcpiOsPrintf ("of method [%4.4s]", (char *) &Name
);
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
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
497 * DESCRIPTION: System table handler for AcpiExec utility.
499 *****************************************************************************/
507 #if (!ACPI_REDUCED_HARDWARE)
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 */
531 /******************************************************************************
533 * FUNCTION: AeGpeHandler
535 * DESCRIPTION: Common GPE handler for acpiexec
537 *****************************************************************************/
541 ACPI_HANDLE GpeDevice
,
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 *****************************************************************************/
564 AeGlobalEventHandler (
575 case ACPI_EVENT_TYPE_GPE
:
580 case ACPI_EVENT_TYPE_FIXED
:
582 TypeName
= "FixedEvent";
587 TypeName
= "UNKNOWN";
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
603 *****************************************************************************/
606 AeAttachedDataHandler (
610 ACPI_NAMESPACE_NODE
*Node
= ACPI_CAST_PTR (ACPI_NAMESPACE_NODE
, Data
);
613 AcpiOsPrintf ("Received an attached data deletion (1) on %4.4s\n",
618 /******************************************************************************
620 * FUNCTION: AeAttachedDataHandler2
622 * DESCRIPTION: Handler for deletion of nodes with attached data (attached via
625 *****************************************************************************/
628 AeAttachedDataHandler2 (
632 ACPI_NAMESPACE_NODE
*Node
= ACPI_CAST_PTR (ACPI_NAMESPACE_NODE
, Data
);
635 AcpiOsPrintf ("Received an attached data deletion (2) on %4.4s\n",
640 /******************************************************************************
642 * FUNCTION: AeInterfaceHandler
644 * DESCRIPTION: Handler for _OSI invocations
646 *****************************************************************************/
650 ACPI_STRING InterfaceName
,
653 ACPI_FUNCTION_NAME (AeInterfaceHandler
);
656 ACPI_DEBUG_PRINT ((ACPI_DB_INFO
,
657 "Received _OSI (\"%s\"), is %ssupported\n",
658 InterfaceName
, Supported
== 0 ? "not " : ""));
664 #if (!ACPI_REDUCED_HARDWARE)
665 /******************************************************************************
667 * FUNCTION: AeEventHandler, AeSciHandler
669 * DESCRIPTION: Handler for Fixed Events and SCIs
671 *****************************************************************************/
685 AcpiOsPrintf ("[AcpiExec] Received an SCI at handler\n");
689 #endif /* !ACPI_REDUCED_HARDWARE */
692 /******************************************************************************
694 * FUNCTION: AeRegionInit
700 * DESCRIPTION: Opregion init function.
702 *****************************************************************************/
706 ACPI_HANDLE RegionHandle
,
708 void *HandlerContext
,
709 void **RegionContext
)
712 if (Function
== ACPI_REGION_DEACTIVATE
)
714 *RegionContext
= NULL
;
718 *RegionContext
= RegionHandle
;
725 /*******************************************************************************
727 * FUNCTION: AeInstallSciHandler
733 * DESCRIPTION: Install handler for SCIs. Exercise the code by doing an
734 * install/remove/install.
736 ******************************************************************************/
739 AeInstallSciHandler (
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)"));
770 /*******************************************************************************
772 * FUNCTION: AeInstallDeviceHandlers, AeInstallEcHandler,
773 * AeInstallPciHandler
775 * PARAMETERS: ACPI_WALK_NAMESPACE callback
779 * DESCRIPTION: Walk entire namespace, install a handler for every EC
780 * and PCI device found.
782 ******************************************************************************/
786 ACPI_HANDLE ObjHandle
,
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)",
809 AeInstallPciHandler (
810 ACPI_HANDLE ObjHandle
,
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)",
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)",
838 return (AE_CTRL_TERMINATE
);
842 AeInstallDeviceHandlers (
846 /* Find all Embedded Controller devices */
848 AcpiGetDevices ("PNP0C09", AeInstallEcHandler
, NULL
, NULL
);
850 /* Install a PCI handler */
852 AcpiGetDevices ("PNP0A08", AeInstallPciHandler
, NULL
, NULL
);
857 /******************************************************************************
859 * FUNCTION: AeInstallLateHandlers
865 * DESCRIPTION: Install handlers for the AcpiExec utility.
867 *****************************************************************************/
870 AeInstallLateHandlers (
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
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
]));
930 /******************************************************************************
932 * FUNCTION: AeInstallEarlyHandlers
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 *****************************************************************************/
946 AeInstallEarlyHandlers (
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
,
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
,
1021 AE_CHECK_OK (AcpiRemoveNotifyHandler
, Status
);
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
));
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
,
1056 AE_CHECK_OK (AcpiAttachData
, Status
);
1058 Status
= AcpiAttachData (ACPI_ROOT_OBJECT
, AeAttachedDataHandler2
,
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
);
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
,
1087 Status
= AcpiRemoveNotifyHandler (Handle
, ACPI_ALL_NOTIFY
,
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
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
]));
1129 * Initialize the global Region Handler space
1132 AeRegions
.NumberOfRegions
= 0;
1133 AeRegions
.RegionList
= NULL
;
1138 /******************************************************************************
1140 * FUNCTION: AeRegionHandler
1142 * PARAMETERS: Standard region handler parameters
1146 * DESCRIPTION: Test handler - Handles some dummy regions via memory that can
1147 * be manipulated in Ring 3. Simulates actual reads and writes.
1149 *****************************************************************************/
1154 ACPI_PHYSICAL_ADDRESS Address
,
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
;
1165 BOOLEAN BufferExists
;
1166 AE_REGION
*RegionElement
;
1172 ACPI_CONNECTION_INFO
*MyContext
;
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
)
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
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
),
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);
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
)
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);
1251 Status
= AcpiHwReadPort (Address
, &Value1
, BitWidth
);
1252 AE_CHECK_OK (AcpiHwReadPort
, Status
);
1253 *Value
= (UINT64
) Value1
;
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
);
1270 Status
= AcpiHwWritePort (Address
, (UINT32
) *Value
, BitWidth
);
1271 AE_CHECK_OK (AcpiHwWritePort
, Status
);
1277 Status
= AE_BAD_PARAMETER
;
1281 if (ACPI_FAILURE (Status
))
1286 /* Now go ahead and simulate the hardware */
1290 * SMBus and GenericSerialBus support the various bidirectional
1293 case ACPI_ADR_SPACE_SMBUS
:
1294 case ACPI_ADR_SPACE_GSBUS
: /* ACPI 5.0 */
1298 switch (Function
& ACPI_IO_MASK
)
1302 switch (Function
>> 16)
1304 case AML_FIELD_ATTRIB_QUICK
:
1305 case AML_FIELD_ATTRIB_SEND_RCV
:
1306 case AML_FIELD_ATTRIB_BYTE
:
1311 case AML_FIELD_ATTRIB_WORD
:
1312 case AML_FIELD_ATTRIB_WORD_CALL
:
1317 case AML_FIELD_ATTRIB_BLOCK
:
1318 case AML_FIELD_ATTRIB_BLOCK_CALL
:
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;
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
:
1350 case AML_FIELD_ATTRIB_WORD_CALL
:
1354 case AML_FIELD_ATTRIB_BLOCK_CALL
:
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;
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
);
1408 Buffer
[1] = (UINT8
) Length
;
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
);
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
;
1466 RegionElement
= RegionElement
->NextRegion
;
1472 * If the Region buffer does not exist, create it now
1477 * Do the memory allocations first
1479 RegionElement
= AcpiOsAllocate (sizeof (AE_REGION
));
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);
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
));
1553 * Perform a read or write to the buffer space
1559 * Set the pointer Value to whatever is in the buffer
1561 ACPI_MEMCPY (Value
, BufferValue
, ByteWidth
);
1566 * Write the contents of Value to the buffer
1568 ACPI_MEMCPY (BufferValue
, Value
, ByteWidth
);
1573 return (AE_BAD_PARAMETER
);
1576 if (AcpiGbl_DisplayRegionAccess
)
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
);
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
);