Subversion Repositories Kolibri OS

Rev

Rev 1498 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /******************************************************************************
  2.  *
  3.  * Module Name: aehandlers - Various handlers for acpiexec
  4.  *
  5.  *****************************************************************************/
  6.  
  7. /******************************************************************************
  8.  *
  9.  * 1. Copyright Notice
  10.  *
  11.  * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
  12.  * All rights reserved.
  13.  *
  14.  * 2. License
  15.  *
  16.  * 2.1. This is your license from Intel Corp. under its intellectual property
  17.  * rights.  You may have additional license terms from the party that provided
  18.  * you this software, covering your right to use that party's intellectual
  19.  * property rights.
  20.  *
  21.  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
  22.  * copy of the source code appearing in this file ("Covered Code") an
  23.  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
  24.  * base code distributed originally by Intel ("Original Intel Code") to copy,
  25.  * make derivatives, distribute, use and display any portion of the Covered
  26.  * Code in any form, with the right to sublicense such rights; and
  27.  *
  28.  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
  29.  * license (with the right to sublicense), under only those claims of Intel
  30.  * patents that are infringed by the Original Intel Code, to make, use, sell,
  31.  * offer to sell, and import the Covered Code and derivative works thereof
  32.  * solely to the minimum extent necessary to exercise the above copyright
  33.  * license, and in no event shall the patent license extend to any additions
  34.  * to or modifications of the Original Intel Code.  No other license or right
  35.  * is granted directly or by implication, estoppel or otherwise;
  36.  *
  37.  * The above copyright and patent license is granted only if the following
  38.  * conditions are met:
  39.  *
  40.  * 3. Conditions
  41.  *
  42.  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
  43.  * Redistribution of source code of any substantial portion of the Covered
  44.  * Code or modification with rights to further distribute source must include
  45.  * the above Copyright Notice, the above License, this list of Conditions,
  46.  * and the following Disclaimer and Export Compliance provision.  In addition,
  47.  * Licensee must cause all Covered Code to which Licensee contributes to
  48.  * contain a file documenting the changes Licensee made to create that Covered
  49.  * Code and the date of any change.  Licensee must include in that file the
  50.  * documentation of any changes made by any predecessor Licensee.  Licensee
  51.  * must include a prominent statement that the modification is derived,
  52.  * directly or indirectly, from Original Intel Code.
  53.  *
  54.  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
  55.  * Redistribution of source code of any substantial portion of the Covered
  56.  * Code or modification without rights to further distribute source must
  57.  * include the following Disclaimer and Export Compliance provision in the
  58.  * documentation and/or other materials provided with distribution.  In
  59.  * addition, Licensee may not authorize further sublicense of source of any
  60.  * portion of the Covered Code, and must include terms to the effect that the
  61.  * license from Licensee to its licensee is limited to the intellectual
  62.  * property embodied in the software Licensee provides to its licensee, and
  63.  * not to intellectual property embodied in modifications its licensee may
  64.  * make.
  65.  *
  66.  * 3.3. Redistribution of Executable. Redistribution in executable form of any
  67.  * substantial portion of the Covered Code or modification must reproduce the
  68.  * above Copyright Notice, and the following Disclaimer and Export Compliance
  69.  * provision in the documentation and/or other materials provided with the
  70.  * distribution.
  71.  *
  72.  * 3.4. Intel retains all right, title, and interest in and to the Original
  73.  * Intel Code.
  74.  *
  75.  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
  76.  * Intel shall be used in advertising or otherwise to promote the sale, use or
  77.  * other dealings in products derived from or relating to the Covered Code
  78.  * without prior written authorization from Intel.
  79.  *
  80.  * 4. Disclaimer and Export Compliance
  81.  *
  82.  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
  83.  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
  84.  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
  85.  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
  86.  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
  87.  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
  88.  * PARTICULAR PURPOSE.
  89.  *
  90.  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
  91.  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
  92.  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
  93.  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
  94.  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
  95.  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
  96.  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
  97.  * LIMITED REMEDY.
  98.  *
  99.  * 4.3. Licensee shall not export, either directly or indirectly, any of this
  100.  * software or system incorporating such software without first obtaining any
  101.  * required license or other approval from the U. S. Department of Commerce or
  102.  * any other agency or department of the United States Government.  In the
  103.  * event Licensee exports any such software from the United States or
  104.  * re-exports any such software from a foreign destination, Licensee shall
  105.  * ensure that the distribution and export/re-export of the software is in
  106.  * compliance with all laws, regulations, orders, or other restrictions of the
  107.  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
  108.  * any of its subsidiaries will export/re-export any technical data, process,
  109.  * software, or service, directly or indirectly, to any country for which the
  110.  * United States government or any agency thereof requires an export license,
  111.  * other governmental approval, or letter of assurance, without first obtaining
  112.  * such license, approval or letter.
  113.  *
  114.  *****************************************************************************/
  115.  
  116. #include "aecommon.h"
  117.  
  118. #define _COMPONENT          ACPI_TOOLS
  119.         ACPI_MODULE_NAME    ("aehandlers")
  120.  
  121. /* Local prototypes */
  122.  
  123. static void
  124. AeNotifyHandler (
  125.     ACPI_HANDLE             Device,
  126.     UINT32                  Value,
  127.     void                    *Context);
  128.  
  129. static void
  130. AeDeviceNotifyHandler (
  131.     ACPI_HANDLE             Device,
  132.     UINT32                  Value,
  133.     void                    *Context);
  134.  
  135. static ACPI_STATUS
  136. AeExceptionHandler (
  137.     ACPI_STATUS             AmlStatus,
  138.     ACPI_NAME               Name,
  139.     UINT16                  Opcode,
  140.     UINT32                  AmlOffset,
  141.     void                    *Context);
  142.  
  143. static ACPI_STATUS
  144. AeTableHandler (
  145.     UINT32                  Event,
  146.     void                    *Table,
  147.     void                    *Context);
  148.  
  149. static ACPI_STATUS
  150. AeRegionInit (
  151.     ACPI_HANDLE             RegionHandle,
  152.     UINT32                  Function,
  153.     void                    *HandlerContext,
  154.     void                    **RegionContext);
  155.  
  156. static void
  157. AeAttachedDataHandler (
  158.     ACPI_HANDLE             Object,
  159.     void                    *Data);
  160.  
  161. static UINT32
  162. AeInterfaceHandler (
  163.     ACPI_STRING             InterfaceName,
  164.     UINT32                  Supported);
  165.  
  166. static UINT32
  167. AeEventHandler (
  168.     void                    *Context);
  169.  
  170. static UINT32               SigintCount = 0;
  171. static AE_DEBUG_REGIONS     AeRegions;
  172.  
  173.  
  174. /*
  175.  * We will override some of the default region handlers, especially the
  176.  * SystemMemory handler, which must be implemented locally. Do not override
  177.  * the PCI_Config handler since we would like to exercise the default handler
  178.  * code. These handlers are installed "early" - before any _REG methods
  179.  * are executed - since they are special in the sense that tha ACPI spec
  180.  * declares that they must "always be available". Cannot override the
  181.  * DataTable region handler either -- needed for test execution.
  182.  */
  183. static ACPI_ADR_SPACE_TYPE  DefaultSpaceIdList[] = {
  184.     ACPI_ADR_SPACE_SYSTEM_MEMORY,
  185.     ACPI_ADR_SPACE_SYSTEM_IO
  186. };
  187.  
  188. /*
  189.  * We will install handlers for some of the various address space IDs
  190.  * Test one user-defined address space (used by aslts.)
  191.  */
  192. #define ACPI_ADR_SPACE_USER_DEFINED     0x80
  193.  
  194. static ACPI_ADR_SPACE_TYPE  SpaceIdList[] = {
  195.     ACPI_ADR_SPACE_EC,
  196.     ACPI_ADR_SPACE_SMBUS,
  197.     ACPI_ADR_SPACE_PCI_BAR_TARGET,
  198.     ACPI_ADR_SPACE_IPMI,
  199.     ACPI_ADR_SPACE_FIXED_HARDWARE,
  200.     ACPI_ADR_SPACE_USER_DEFINED
  201. };
  202.  
  203.  
  204. /******************************************************************************
  205.  *
  206.  * FUNCTION:    AeCtrlCHandler
  207.  *
  208.  * PARAMETERS:  Sig
  209.  *
  210.  * RETURN:      none
  211.  *
  212.  * DESCRIPTION: Control-C handler.  Abort running control method if any.
  213.  *
  214.  *****************************************************************************/
  215.  
  216. void ACPI_SYSTEM_XFACE
  217. AeCtrlCHandler (
  218.     int                     Sig)
  219. {
  220.  
  221.     signal (SIGINT, SIG_IGN);
  222.     SigintCount++;
  223.  
  224.     AcpiOsPrintf ("Caught a ctrl-c (#%u)\n\n", SigintCount);
  225.  
  226.     if (AcpiGbl_MethodExecuting)
  227.     {
  228.         AcpiGbl_AbortMethod = TRUE;
  229.         signal (SIGINT, AeCtrlCHandler);
  230.  
  231.         if (SigintCount < 10)
  232.         {
  233.             return;
  234.         }
  235.     }
  236.  
  237.     exit (0);
  238. }
  239.  
  240.  
  241. /******************************************************************************
  242.  *
  243.  * FUNCTION:    AeNotifyHandler
  244.  *
  245.  * PARAMETERS:  Standard notify handler parameters
  246.  *
  247.  * RETURN:      Status
  248.  *
  249.  * DESCRIPTION: System notify handler for AcpiExec utility.  Used by the ASL
  250.  *              test suite(s) to communicate errors and other information to
  251.  *              this utility via the Notify() operator.
  252.  *
  253.  *****************************************************************************/
  254.  
  255. static void
  256. AeNotifyHandler (
  257.     ACPI_HANDLE                 Device,
  258.     UINT32                      Value,
  259.     void                        *Context)
  260. {
  261.  
  262.     switch (Value)
  263.     {
  264. #if 0
  265.     case 0:
  266.         printf ("[AcpiExec] Method Error 0x%X: Results not equal\n", Value);
  267.         if (AcpiGbl_DebugFile)
  268.         {
  269.             AcpiOsPrintf ("[AcpiExec] Method Error: Results not equal\n");
  270.         }
  271.         break;
  272.  
  273.  
  274.     case 1:
  275.         printf ("[AcpiExec] Method Error: Incorrect numeric result\n");
  276.         if (AcpiGbl_DebugFile)
  277.         {
  278.             AcpiOsPrintf ("[AcpiExec] Method Error: Incorrect numeric result\n");
  279.         }
  280.         break;
  281.  
  282.  
  283.     case 2:
  284.         printf ("[AcpiExec] Method Error: An operand was overwritten\n");
  285.         if (AcpiGbl_DebugFile)
  286.         {
  287.             AcpiOsPrintf ("[AcpiExec] Method Error: An operand was overwritten\n");
  288.         }
  289.         break;
  290.  
  291. #endif
  292.  
  293.     default:
  294.         printf ("[AcpiExec] Received a System Notify on [%4.4s] %p Value 0x%2.2X (%s)\n",
  295.             AcpiUtGetNodeName (Device), Device, Value,
  296.             AcpiUtGetNotifyName (Value));
  297.         if (AcpiGbl_DebugFile)
  298.         {
  299.             AcpiOsPrintf ("[AcpiExec] Received a system notify, Value 0x%2.2X\n", Value);
  300.         }
  301.  
  302.         (void) AcpiEvaluateObject (Device, "_NOT", NULL, NULL);
  303.         break;
  304.     }
  305. }
  306.  
  307.  
  308. /******************************************************************************
  309.  *
  310.  * FUNCTION:    AeDeviceNotifyHandler
  311.  *
  312.  * PARAMETERS:  Standard notify handler parameters
  313.  *
  314.  * RETURN:      Status
  315.  *
  316.  * DESCRIPTION: Device notify handler for AcpiExec utility.  Used by the ASL
  317.  *              test suite(s) to communicate errors and other information to
  318.  *              this utility via the Notify() operator.
  319.  *
  320.  *****************************************************************************/
  321.  
  322. static void
  323. AeDeviceNotifyHandler (
  324.     ACPI_HANDLE                 Device,
  325.     UINT32                      Value,
  326.     void                        *Context)
  327. {
  328.  
  329.     printf ("[AcpiExec] Received a Device Notify on [%4.4s] %p Value 0x%2.2X (%s)\n",
  330.         AcpiUtGetNodeName (Device), Device, Value,
  331.         AcpiUtGetNotifyName (Value));
  332.     if (AcpiGbl_DebugFile)
  333.     {
  334.         AcpiOsPrintf ("[AcpiExec] Received a device notify, Value 0x%2.2X\n", Value);
  335.     }
  336.  
  337.     (void) AcpiEvaluateObject (Device, "_NOT", NULL, NULL);
  338. }
  339.  
  340.  
  341. /******************************************************************************
  342.  *
  343.  * FUNCTION:    AeExceptionHandler
  344.  *
  345.  * PARAMETERS:  Standard exception handler parameters
  346.  *
  347.  * RETURN:      Status
  348.  *
  349.  * DESCRIPTION: System exception handler for AcpiExec utility.
  350.  *
  351.  *****************************************************************************/
  352.  
  353. static ACPI_STATUS
  354. AeExceptionHandler (
  355.     ACPI_STATUS             AmlStatus,
  356.     ACPI_NAME               Name,
  357.     UINT16                  Opcode,
  358.     UINT32                  AmlOffset,
  359.     void                    *Context)
  360. {
  361.     ACPI_STATUS             NewAmlStatus = AmlStatus;
  362.     ACPI_STATUS             Status;
  363.     ACPI_BUFFER             ReturnObj;
  364.     ACPI_OBJECT_LIST        ArgList;
  365.     ACPI_OBJECT             Arg[3];
  366.     const char              *Exception;
  367.  
  368.  
  369.     Exception = AcpiFormatException (AmlStatus);
  370.     AcpiOsPrintf ("[AcpiExec] Exception %s during execution ", Exception);
  371.     if (Name)
  372.     {
  373.         AcpiOsPrintf ("of method [%4.4s]", (char *) &Name);
  374.     }
  375.     else
  376.     {
  377.         AcpiOsPrintf ("at module level (table load)");
  378.     }
  379.     AcpiOsPrintf (" Opcode [%s] @%X\n", AcpiPsGetOpcodeName (Opcode), AmlOffset);
  380.  
  381.     /*
  382.      * Invoke the _ERR method if present
  383.      *
  384.      * Setup parameter object
  385.      */
  386.     ArgList.Count = 3;
  387.     ArgList.Pointer = Arg;
  388.  
  389.     Arg[0].Type = ACPI_TYPE_INTEGER;
  390.     Arg[0].Integer.Value = AmlStatus;
  391.  
  392.     Arg[1].Type = ACPI_TYPE_STRING;
  393.     Arg[1].String.Pointer = ACPI_CAST_PTR (char, Exception);
  394.     Arg[1].String.Length = ACPI_STRLEN (Exception);
  395.  
  396.     Arg[2].Type = ACPI_TYPE_INTEGER;
  397.     Arg[2].Integer.Value = AcpiOsGetThreadId();
  398.  
  399.     /* Setup return buffer */
  400.  
  401.     ReturnObj.Pointer = NULL;
  402.     ReturnObj.Length = ACPI_ALLOCATE_BUFFER;
  403.  
  404.     Status = AcpiEvaluateObject (NULL, "\\_ERR", &ArgList, &ReturnObj);
  405.     if (ACPI_SUCCESS (Status))
  406.     {
  407.         if (ReturnObj.Pointer)
  408.         {
  409.             /* Override original status */
  410.  
  411.             NewAmlStatus = (ACPI_STATUS)
  412.                 ((ACPI_OBJECT *) ReturnObj.Pointer)->Integer.Value;
  413.  
  414.             AcpiOsFree (ReturnObj.Pointer);
  415.         }
  416.     }
  417.     else if (Status != AE_NOT_FOUND)
  418.     {
  419.         AcpiOsPrintf ("[AcpiExec] Could not execute _ERR method, %s\n",
  420.             AcpiFormatException (Status));
  421.     }
  422.  
  423.     /* Global override */
  424.  
  425.     if (AcpiGbl_IgnoreErrors)
  426.     {
  427.         NewAmlStatus = AE_OK;
  428.     }
  429.  
  430.     if (NewAmlStatus != AmlStatus)
  431.     {
  432.         AcpiOsPrintf ("[AcpiExec] Exception override, new status %s\n",
  433.             AcpiFormatException (NewAmlStatus));
  434.     }
  435.  
  436.     return (NewAmlStatus);
  437. }
  438.  
  439.  
  440. /******************************************************************************
  441.  *
  442.  * FUNCTION:    AeTableHandler
  443.  *
  444.  * PARAMETERS:  Table handler
  445.  *
  446.  * RETURN:      Status
  447.  *
  448.  * DESCRIPTION: System table handler for AcpiExec utility.
  449.  *
  450.  *****************************************************************************/
  451.  
  452. static char                *TableEvents[] =
  453. {
  454.     "LOAD",
  455.     "UNLOAD",
  456.     "UNKNOWN"
  457. };
  458.  
  459. static ACPI_STATUS
  460. AeTableHandler (
  461.     UINT32                  Event,
  462.     void                    *Table,
  463.     void                    *Context)
  464. {
  465.     ACPI_STATUS             Status;
  466.  
  467.  
  468.     if (Event > ACPI_NUM_TABLE_EVENTS)
  469.     {
  470.         Event = ACPI_NUM_TABLE_EVENTS;
  471.     }
  472.  
  473.     /* Enable any GPEs associated with newly-loaded GPE methods */
  474.  
  475.     Status = AcpiUpdateAllGpes ();
  476.     AE_CHECK_OK (AcpiUpdateAllGpes, Status);
  477.  
  478.     printf ("[AcpiExec] Table Event %s, [%4.4s] %p\n",
  479.         TableEvents[Event], ((ACPI_TABLE_HEADER *) Table)->Signature, Table);
  480.     return (AE_OK);
  481. }
  482.  
  483.  
  484. /******************************************************************************
  485.  *
  486.  * FUNCTION:    AeGpeHandler
  487.  *
  488.  * DESCRIPTION: Common GPE handler for acpiexec
  489.  *
  490.  *****************************************************************************/
  491.  
  492. UINT32
  493. AeGpeHandler (
  494.     ACPI_HANDLE             GpeDevice,
  495.     UINT32                  GpeNumber,
  496.     void                    *Context)
  497. {
  498.     ACPI_NAMESPACE_NODE     *DeviceNode = (ACPI_NAMESPACE_NODE *) GpeDevice;
  499.  
  500.  
  501.     AcpiOsPrintf ("[AcpiExec] GPE Handler received GPE%02X (GPE block %4.4s)\n",
  502.         GpeNumber, GpeDevice ? DeviceNode->Name.Ascii : "FADT");
  503.  
  504.     return (ACPI_REENABLE_GPE);
  505. }
  506.  
  507.  
  508. /******************************************************************************
  509.  *
  510.  * FUNCTION:    AeGlobalEventHandler
  511.  *
  512.  * DESCRIPTION: Global GPE/Fixed event handler
  513.  *
  514.  *****************************************************************************/
  515.  
  516. void
  517. AeGlobalEventHandler (
  518.     UINT32                  Type,
  519.     ACPI_HANDLE             Device,
  520.     UINT32                  EventNumber,
  521.     void                    *Context)
  522. {
  523.     char                    *TypeName;
  524.  
  525.  
  526.     switch (Type)
  527.     {
  528.     case ACPI_EVENT_TYPE_GPE:
  529.         TypeName = "GPE";
  530.         break;
  531.  
  532.     case ACPI_EVENT_TYPE_FIXED:
  533.         TypeName = "FixedEvent";
  534.         break;
  535.  
  536.     default:
  537.         TypeName = "UNKNOWN";
  538.         break;
  539.     }
  540.  
  541.     AcpiOsPrintf ("[AcpiExec] Global Event Handler received: Type %s Number %.2X Dev %p\n",
  542.         TypeName, EventNumber, Device);
  543. }
  544.  
  545.  
  546. /******************************************************************************
  547.  *
  548.  * FUNCTION:    AeAttachedDataHandler
  549.  *
  550.  * DESCRIPTION: Handler for deletion of nodes with attached data (attached via
  551.  *              AcpiAttachData)
  552.  *
  553.  *****************************************************************************/
  554.  
  555. static void
  556. AeAttachedDataHandler (
  557.     ACPI_HANDLE             Object,
  558.     void                    *Data)
  559. {
  560.     ACPI_NAMESPACE_NODE     *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Data);
  561.  
  562.  
  563.     AcpiOsPrintf ("Received an attached data deletion on %4.4s\n",
  564.         Node->Name.Ascii);
  565. }
  566.  
  567.  
  568. /******************************************************************************
  569.  *
  570.  * FUNCTION:    AeInterfaceHandler
  571.  *
  572.  * DESCRIPTION: Handler for _OSI invocations
  573.  *
  574.  *****************************************************************************/
  575.  
  576. static UINT32
  577. AeInterfaceHandler (
  578.     ACPI_STRING             InterfaceName,
  579.     UINT32                  Supported)
  580. {
  581.     ACPI_FUNCTION_NAME (AeInterfaceHandler);
  582.  
  583.  
  584.     ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
  585.         "Received _OSI (\"%s\"), is %ssupported\n",
  586.         InterfaceName, Supported == 0 ? "not " : ""));
  587.  
  588.     return (Supported);
  589. }
  590.  
  591.  
  592. /******************************************************************************
  593.  *
  594.  * FUNCTION:    AeEventHandler
  595.  *
  596.  * DESCRIPTION: Handler for Fixed Events
  597.  *
  598.  *****************************************************************************/
  599.  
  600. static UINT32
  601. AeEventHandler (
  602.     void                    *Context)
  603. {
  604.     return (0);
  605. }
  606.  
  607.  
  608. /******************************************************************************
  609.  *
  610.  * FUNCTION:    AeRegionInit
  611.  *
  612.  * PARAMETERS:  None
  613.  *
  614.  * RETURN:      Status
  615.  *
  616.  * DESCRIPTION: Opregion init function.
  617.  *
  618.  *****************************************************************************/
  619.  
  620. static ACPI_STATUS
  621. AeRegionInit (
  622.     ACPI_HANDLE                 RegionHandle,
  623.     UINT32                      Function,
  624.     void                        *HandlerContext,
  625.     void                        **RegionContext)
  626. {
  627.     /*
  628.      * Real simple, set the RegionContext to the RegionHandle
  629.      */
  630.     *RegionContext = RegionHandle;
  631.  
  632.     return (AE_OK);
  633. }
  634.  
  635.  
  636. /******************************************************************************
  637.  *
  638.  * FUNCTION:    AeInstallLateHandlers
  639.  *
  640.  * PARAMETERS:  None
  641.  *
  642.  * RETURN:      Status
  643.  *
  644.  * DESCRIPTION: Install handlers for the AcpiExec utility.
  645.  *
  646.  *****************************************************************************/
  647.  
  648. ACPI_STATUS
  649. AeInstallLateHandlers (
  650.     void)
  651. {
  652.     ACPI_STATUS             Status;
  653.     UINT32                  i;
  654.  
  655.  
  656.     /* Install some fixed event handlers */
  657.  
  658.     Status = AcpiInstallFixedEventHandler (ACPI_EVENT_GLOBAL, AeEventHandler, NULL);
  659.     AE_CHECK_OK (AcpiInstallFixedEventHandler, Status);
  660.  
  661.     Status = AcpiInstallFixedEventHandler (ACPI_EVENT_RTC, AeEventHandler, NULL);
  662.     AE_CHECK_OK (AcpiInstallFixedEventHandler, Status);
  663.  
  664.     /*
  665.      * Install handlers for some of the "device driver" address spaces
  666.      * such as EC, SMBus, etc.
  667.      */
  668.     for (i = 0; i < ACPI_ARRAY_LENGTH (SpaceIdList); i++)
  669.     {
  670.         /* Install handler at the root object */
  671.  
  672.         Status = AcpiInstallAddressSpaceHandler (AcpiGbl_RootNode,
  673.                         SpaceIdList[i], AeRegionHandler, AeRegionInit, NULL);
  674.         if (ACPI_FAILURE (Status))
  675.         {
  676.             ACPI_EXCEPTION ((AE_INFO, Status,
  677.                 "Could not install an OpRegion handler for %s space(%u)",
  678.                 AcpiUtGetRegionName((UINT8) SpaceIdList[i]), SpaceIdList[i]));
  679.             return (Status);
  680.         }
  681.     }
  682.  
  683.     return (AE_OK);
  684. }
  685.  
  686.  
  687. /******************************************************************************
  688.  *
  689.  * FUNCTION:    AeInstallEarlyHandlers
  690.  *
  691.  * PARAMETERS:  None
  692.  *
  693.  * RETURN:      Status
  694.  *
  695.  * DESCRIPTION: Install handlers for the AcpiExec utility.
  696.  *
  697.  * Notes:       Don't install handler for PCI_Config, we want to use the
  698.  *              default handler to exercise that code.
  699.  *
  700.  *****************************************************************************/
  701.  
  702. ACPI_STATUS
  703. AeInstallEarlyHandlers (
  704.     void)
  705. {
  706.     ACPI_STATUS             Status;
  707.     UINT32                  i;
  708.     ACPI_HANDLE             Handle;
  709.  
  710.  
  711.     ACPI_FUNCTION_ENTRY ();
  712.  
  713.  
  714.     Status = AcpiInstallInterfaceHandler (AeInterfaceHandler);
  715.     if (ACPI_FAILURE (Status))
  716.     {
  717.         printf ("Could not install interface handler, %s\n",
  718.             AcpiFormatException (Status));
  719.     }
  720.  
  721.     Status = AcpiInstallTableHandler (AeTableHandler, NULL);
  722.     if (ACPI_FAILURE (Status))
  723.     {
  724.         printf ("Could not install table handler, %s\n",
  725.             AcpiFormatException (Status));
  726.     }
  727.  
  728.     Status = AcpiInstallExceptionHandler (AeExceptionHandler);
  729.     if (ACPI_FAILURE (Status))
  730.     {
  731.         printf ("Could not install exception handler, %s\n",
  732.             AcpiFormatException (Status));
  733.     }
  734.  
  735.     /* Install global notify handler */
  736.  
  737.     Status = AcpiInstallNotifyHandler (ACPI_ROOT_OBJECT, ACPI_SYSTEM_NOTIFY,
  738.                                         AeNotifyHandler, NULL);
  739.     if (ACPI_FAILURE (Status))
  740.     {
  741.         printf ("Could not install a global notify handler, %s\n",
  742.             AcpiFormatException (Status));
  743.     }
  744.  
  745.     Status = AcpiInstallNotifyHandler (ACPI_ROOT_OBJECT, ACPI_DEVICE_NOTIFY,
  746.                                         AeDeviceNotifyHandler, NULL);
  747.     if (ACPI_FAILURE (Status))
  748.     {
  749.         printf ("Could not install a global notify handler, %s\n",
  750.             AcpiFormatException (Status));
  751.     }
  752.  
  753.     Status = AcpiGetHandle (NULL, "\\_SB", &Handle);
  754.     if (ACPI_SUCCESS (Status))
  755.     {
  756.         Status = AcpiInstallNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY,
  757.                                             AeNotifyHandler, NULL);
  758.         if (ACPI_FAILURE (Status))
  759.         {
  760.             printf ("Could not install a notify handler, %s\n",
  761.                 AcpiFormatException (Status));
  762.         }
  763.  
  764.         Status = AcpiRemoveNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY,
  765.                                             AeNotifyHandler);
  766.         if (ACPI_FAILURE (Status))
  767.         {
  768.             printf ("Could not remove a notify handler, %s\n",
  769.                 AcpiFormatException (Status));
  770.         }
  771.  
  772.         Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
  773.                                             AeNotifyHandler, NULL);
  774.         AE_CHECK_OK (AcpiInstallNotifyHandler, Status);
  775.  
  776.         Status = AcpiRemoveNotifyHandler (Handle, ACPI_ALL_NOTIFY,
  777.                                             AeNotifyHandler);
  778.         AE_CHECK_OK (AcpiRemoveNotifyHandler, Status);
  779.  
  780.         Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
  781.                                             AeNotifyHandler, NULL);
  782.         if (ACPI_FAILURE (Status))
  783.         {
  784.             printf ("Could not install a notify handler, %s\n",
  785.                 AcpiFormatException (Status));
  786.         }
  787.  
  788.         Status = AcpiAttachData (Handle, AeAttachedDataHandler, Handle);
  789.         AE_CHECK_OK (AcpiAttachData, Status);
  790.  
  791.         Status = AcpiDetachData (Handle, AeAttachedDataHandler);
  792.         AE_CHECK_OK (AcpiDetachData, Status);
  793.  
  794.         Status = AcpiAttachData (Handle, AeAttachedDataHandler, Handle);
  795.         AE_CHECK_OK (AcpiAttachData, Status);
  796.     }
  797.     else
  798.     {
  799.         printf ("No _SB_ found, %s\n", AcpiFormatException (Status));
  800.     }
  801.  
  802.  
  803.     /*
  804.      * Install handlers that will override the default handlers for some of
  805.      * the space IDs.
  806.      */
  807.     for (i = 0; i < ACPI_ARRAY_LENGTH (DefaultSpaceIdList); i++)
  808.     {
  809.         /* Install handler at the root object */
  810.  
  811.         Status = AcpiInstallAddressSpaceHandler (AcpiGbl_RootNode,
  812.                     DefaultSpaceIdList[i], AeRegionHandler,
  813.                     AeRegionInit, NULL);
  814.         if (ACPI_FAILURE (Status))
  815.         {
  816.             ACPI_EXCEPTION ((AE_INFO, Status,
  817.                 "Could not install a default OpRegion handler for %s space(%u)",
  818.                 AcpiUtGetRegionName ((UINT8) DefaultSpaceIdList[i]),
  819.                 DefaultSpaceIdList[i]));
  820.             return (Status);
  821.         }
  822.     }
  823.  
  824.     /*
  825.      * Initialize the global Region Handler space
  826.      * MCW 3/23/00
  827.      */
  828.     AeRegions.NumberOfRegions = 0;
  829.     AeRegions.RegionList = NULL;
  830.     return (Status);
  831. }
  832.  
  833.  
  834. /******************************************************************************
  835.  *
  836.  * FUNCTION:    AeRegionHandler
  837.  *
  838.  * PARAMETERS:  Standard region handler parameters
  839.  *
  840.  * RETURN:      Status
  841.  *
  842.  * DESCRIPTION: Test handler - Handles some dummy regions via memory that can
  843.  *              be manipulated in Ring 3. Simulates actual reads and writes.
  844.  *
  845.  *****************************************************************************/
  846.  
  847. ACPI_STATUS
  848. AeRegionHandler (
  849.     UINT32                  Function,
  850.     ACPI_PHYSICAL_ADDRESS   Address,
  851.     UINT32                  BitWidth,
  852.     UINT64                  *Value,
  853.     void                    *HandlerContext,
  854.     void                    *RegionContext)
  855. {
  856.  
  857.     ACPI_OPERAND_OBJECT     *RegionObject = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, RegionContext);
  858.     UINT8                   *Buffer = ACPI_CAST_PTR (UINT8, Value);
  859.     ACPI_PHYSICAL_ADDRESS   BaseAddress;
  860.     ACPI_SIZE               Length;
  861.     BOOLEAN                 BufferExists;
  862.     AE_REGION               *RegionElement;
  863.     void                    *BufferValue;
  864.     ACPI_STATUS             Status;
  865.     UINT32                  ByteWidth;
  866.     UINT32                  i;
  867.     UINT8                   SpaceId;
  868.  
  869.  
  870.     ACPI_FUNCTION_NAME (AeRegionHandler);
  871.  
  872.     /*
  873.      * If the object is not a region, simply return
  874.      */
  875.     if (RegionObject->Region.Type != ACPI_TYPE_REGION)
  876.     {
  877.         return (AE_OK);
  878.     }
  879.  
  880.     /*
  881.      * Region support can be disabled with the -r option.
  882.      * We use this to support dynamically loaded tables where we pass a valid
  883.      * address to the AML.
  884.      */
  885.     if (AcpiGbl_DbOpt_NoRegionSupport)
  886.     {
  887.         BufferValue = ACPI_TO_POINTER (Address);
  888.         ByteWidth = (BitWidth / 8);
  889.  
  890.         if (BitWidth % 8)
  891.         {
  892.             ByteWidth += 1;
  893.         }
  894.         goto DoFunction;
  895.     }
  896.  
  897.     /*
  898.      * Find the region's address space and length before searching
  899.      * the linked list.
  900.      */
  901.     BaseAddress = RegionObject->Region.Address;
  902.     Length = (ACPI_SIZE) RegionObject->Region.Length;
  903.     SpaceId = RegionObject->Region.SpaceId;
  904.  
  905.     ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, "Operation Region request on %s at 0x%X\n",
  906.             AcpiUtGetRegionName (RegionObject->Region.SpaceId),
  907.             (UINT32) Address));
  908.  
  909.     switch (SpaceId)
  910.     {
  911.     case ACPI_ADR_SPACE_SYSTEM_IO:
  912.         /*
  913.          * For I/O space, exercise the port validation
  914.          */
  915.         switch (Function & ACPI_IO_MASK)
  916.         {
  917.         case ACPI_READ:
  918.             Status = AcpiHwReadPort (Address, (UINT32 *) Value, BitWidth);
  919.             AE_CHECK_OK (AcpiHwReadPort, Status);
  920.             break;
  921.  
  922.         case ACPI_WRITE:
  923.             Status = AcpiHwWritePort (Address, (UINT32) *Value, BitWidth);
  924.             AE_CHECK_OK (AcpiHwWritePort, Status);
  925.             break;
  926.  
  927.         default:
  928.             Status = AE_BAD_PARAMETER;
  929.             break;
  930.         }
  931.  
  932.         if (ACPI_FAILURE (Status))
  933.         {
  934.             return (Status);
  935.         }
  936.  
  937.         /* Now go ahead and simulate the hardware */
  938.         break;
  939.  
  940.  
  941.     case ACPI_ADR_SPACE_SMBUS:
  942.  
  943.         Length = 0;
  944.  
  945.         switch (Function & ACPI_IO_MASK)
  946.         {
  947.         case ACPI_READ:
  948.             switch (Function >> 16)
  949.             {
  950.             case AML_FIELD_ATTRIB_SMB_QUICK:
  951.             case AML_FIELD_ATTRIB_SMB_SEND_RCV:
  952.             case AML_FIELD_ATTRIB_SMB_BYTE:
  953.                 Length = 1;
  954.                 break;
  955.  
  956.             case AML_FIELD_ATTRIB_SMB_WORD:
  957.             case AML_FIELD_ATTRIB_SMB_WORD_CALL:
  958.                 Length = 2;
  959.                 break;
  960.  
  961.             case AML_FIELD_ATTRIB_SMB_BLOCK:
  962.             case AML_FIELD_ATTRIB_SMB_BLOCK_CALL:
  963.                 Length = 32;
  964.                 break;
  965.  
  966.             default:
  967.                 break;
  968.             }
  969.             break;
  970.  
  971.         case ACPI_WRITE:
  972.             switch (Function >> 16)
  973.             {
  974.             case AML_FIELD_ATTRIB_SMB_QUICK:
  975.             case AML_FIELD_ATTRIB_SMB_SEND_RCV:
  976.             case AML_FIELD_ATTRIB_SMB_BYTE:
  977.             case AML_FIELD_ATTRIB_SMB_WORD:
  978.             case AML_FIELD_ATTRIB_SMB_BLOCK:
  979.                 Length = 0;
  980.                 break;
  981.  
  982.             case AML_FIELD_ATTRIB_SMB_WORD_CALL:
  983.                 Length = 2;
  984.                 break;
  985.  
  986.             case AML_FIELD_ATTRIB_SMB_BLOCK_CALL:
  987.                 Length = 32;
  988.                 break;
  989.  
  990.             default:
  991.                 break;
  992.             }
  993.             break;
  994.  
  995.         default:
  996.             break;
  997.         }
  998.  
  999.         for (i = 0; i < Length; i++)
  1000.         {
  1001.             Buffer[i+2] = (UINT8) (0xA0 + i);
  1002.         }
  1003.  
  1004.         Buffer[0] = 0x7A;
  1005.         Buffer[1] = (UINT8) Length;
  1006.         return (AE_OK);
  1007.  
  1008.  
  1009.     case ACPI_ADR_SPACE_IPMI: /* ACPI 4.0 */
  1010.  
  1011.         AcpiOsPrintf ("AcpiExec: Received IPMI request: "
  1012.             "Address %X BaseAddress %X Length %X Width %X BufferLength %u\n",
  1013.             (UINT32) Address, (UINT32) BaseAddress,
  1014.             Length, BitWidth, Buffer[1]);
  1015.  
  1016.         /*
  1017.          * Regardless of a READ or WRITE, this handler is passed a 66-byte
  1018.          * buffer in which to return the IPMI status/length/data.
  1019.          *
  1020.          * Return some example data to show use of the bidirectional buffer
  1021.          */
  1022.         Buffer[0] = 0;       /* Status byte */
  1023.         Buffer[1] = 64;      /* Return buffer data length */
  1024.         Buffer[2] = 0;       /* Completion code */
  1025.         Buffer[3] = 0x34;    /* Power measurement */
  1026.         Buffer[4] = 0x12;    /* Power measurement */
  1027.         Buffer[65] = 0xEE;   /* last buffer byte */
  1028.         return (AE_OK);
  1029.  
  1030.     default:
  1031.         break;
  1032.     }
  1033.  
  1034.     /*
  1035.      * Search through the linked list for this region's buffer
  1036.      */
  1037.     BufferExists = FALSE;
  1038.     RegionElement = AeRegions.RegionList;
  1039.  
  1040.     if (AeRegions.NumberOfRegions)
  1041.     {
  1042.         while (!BufferExists && RegionElement)
  1043.         {
  1044.             if (RegionElement->Address == BaseAddress &&
  1045.                 RegionElement->Length == Length &&
  1046.                 RegionElement->SpaceId == SpaceId)
  1047.             {
  1048.                 BufferExists = TRUE;
  1049.             }
  1050.             else
  1051.             {
  1052.                 RegionElement = RegionElement->NextRegion;
  1053.             }
  1054.         }
  1055.     }
  1056.  
  1057.     /*
  1058.      * If the Region buffer does not exist, create it now
  1059.      */
  1060.     if (!BufferExists)
  1061.     {
  1062.         /*
  1063.          * Do the memory allocations first
  1064.          */
  1065.         RegionElement = AcpiOsAllocate (sizeof (AE_REGION));
  1066.         if (!RegionElement)
  1067.         {
  1068.             return (AE_NO_MEMORY);
  1069.         }
  1070.  
  1071.         RegionElement->Buffer = AcpiOsAllocate (Length);
  1072.         if (!RegionElement->Buffer)
  1073.         {
  1074.             AcpiOsFree (RegionElement);
  1075.             return (AE_NO_MEMORY);
  1076.         }
  1077.  
  1078.         /* Initialize the region with the default fill value */
  1079.  
  1080.         ACPI_MEMSET (RegionElement->Buffer, AcpiGbl_RegionFillValue, Length);
  1081.  
  1082.         RegionElement->Address      = BaseAddress;
  1083.         RegionElement->Length       = Length;
  1084.         RegionElement->SpaceId      = SpaceId;
  1085.         RegionElement->NextRegion   = NULL;
  1086.  
  1087.         /*
  1088.          * Increment the number of regions and put this one
  1089.          *  at the head of the list as it will probably get accessed
  1090.          *  more often anyway.
  1091.          */
  1092.         AeRegions.NumberOfRegions += 1;
  1093.  
  1094.         if (AeRegions.RegionList)
  1095.         {
  1096.             RegionElement->NextRegion = AeRegions.RegionList;
  1097.         }
  1098.  
  1099.         AeRegions.RegionList = RegionElement;
  1100.     }
  1101.  
  1102.     /*
  1103.      * Calculate the size of the memory copy
  1104.      */
  1105.     ByteWidth = (BitWidth / 8);
  1106.  
  1107.     if (BitWidth % 8)
  1108.     {
  1109.         ByteWidth += 1;
  1110.     }
  1111.  
  1112.     /*
  1113.      * The buffer exists and is pointed to by RegionElement.
  1114.      * We now need to verify the request is valid and perform the operation.
  1115.      *
  1116.      * NOTE: RegionElement->Length is in bytes, therefore it we compare against
  1117.      * ByteWidth (see above)
  1118.      */
  1119.     if (((UINT64) Address + ByteWidth) >
  1120.         ((UINT64)(RegionElement->Address) + RegionElement->Length))
  1121.     {
  1122.         ACPI_WARNING ((AE_INFO,
  1123.             "Request on [%4.4s] is beyond region limit Req-0x%X+0x%X, Base=0x%X, Len-0x%X",
  1124.             (RegionObject->Region.Node)->Name.Ascii, (UINT32) Address,
  1125.             ByteWidth, (UINT32)(RegionElement->Address),
  1126.             RegionElement->Length));
  1127.  
  1128.         return (AE_AML_REGION_LIMIT);
  1129.     }
  1130.  
  1131.     /*
  1132.      * Get BufferValue to point to the "address" in the buffer
  1133.      */
  1134.     BufferValue = ((UINT8 *) RegionElement->Buffer +
  1135.                     ((UINT64) Address - (UINT64) RegionElement->Address));
  1136.  
  1137. DoFunction:
  1138.  
  1139.     /*
  1140.      * Perform a read or write to the buffer space
  1141.      */
  1142.     switch (Function)
  1143.     {
  1144.     case ACPI_READ:
  1145.         /*
  1146.          * Set the pointer Value to whatever is in the buffer
  1147.          */
  1148.         ACPI_MEMCPY (Value, BufferValue, ByteWidth);
  1149.         break;
  1150.  
  1151.     case ACPI_WRITE:
  1152.         /*
  1153.          * Write the contents of Value to the buffer
  1154.          */
  1155.         ACPI_MEMCPY (BufferValue, Value, ByteWidth);
  1156.         break;
  1157.  
  1158.     default:
  1159.         return (AE_BAD_PARAMETER);
  1160.     }
  1161.  
  1162.     return (AE_OK);
  1163. }
  1164.  
  1165.  
  1166.