Subversion Repositories Kolibri OS

Rev

Go to most recent revision | 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 - 2010, 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. void
  124. AeNotifyHandler (
  125.     ACPI_HANDLE             Device,
  126.     UINT32                  Value,
  127.     void                    *Context);
  128.  
  129. void
  130. AeDeviceNotifyHandler (
  131.     ACPI_HANDLE             Device,
  132.     UINT32                  Value,
  133.     void                    *Context);
  134.  
  135. ACPI_STATUS
  136. AeExceptionHandler (
  137.     ACPI_STATUS             AmlStatus,
  138.     ACPI_NAME               Name,
  139.     UINT16                  Opcode,
  140.     UINT32                  AmlOffset,
  141.     void                    *Context);
  142.  
  143. ACPI_STATUS
  144. AeTableHandler (
  145.     UINT32                  Event,
  146.     void                    *Table,
  147.     void                    *Context);
  148.  
  149. ACPI_STATUS
  150. AeRegionInit (
  151.     ACPI_HANDLE             RegionHandle,
  152.     UINT32                  Function,
  153.     void                    *HandlerContext,
  154.     void                    **RegionContext);
  155.  
  156. void
  157. AeAttachedDataHandler (
  158.     ACPI_HANDLE             Object,
  159.     void                    *Data);
  160.  
  161. UINT32                      SigintCount = 0;
  162. AE_DEBUG_REGIONS            AeRegions;
  163.  
  164.  
  165. /******************************************************************************
  166.  *
  167.  * FUNCTION:    AeCtrlCHandler
  168.  *
  169.  * PARAMETERS:  Sig
  170.  *
  171.  * RETURN:      none
  172.  *
  173.  * DESCRIPTION: Control-C handler.  Abort running control method if any.
  174.  *
  175.  *****************************************************************************/
  176.  
  177. void __cdecl
  178. AeCtrlCHandler (
  179.     int                     Sig)
  180. {
  181.  
  182.     signal (SIGINT, SIG_IGN);
  183.     SigintCount++;
  184.  
  185.     AcpiOsPrintf ("Caught a ctrl-c (#%u)\n\n", SigintCount);
  186.  
  187.     if (AcpiGbl_MethodExecuting)
  188.     {
  189.         AcpiGbl_AbortMethod = TRUE;
  190.         signal (SIGINT, AeCtrlCHandler);
  191.  
  192.         if (SigintCount < 10)
  193.         {
  194.             return;
  195.         }
  196.     }
  197.  
  198.     exit (0);
  199. }
  200.  
  201.  
  202. /******************************************************************************
  203.  *
  204.  * FUNCTION:    AeNotifyHandler
  205.  *
  206.  * PARAMETERS:  Standard notify handler parameters
  207.  *
  208.  * RETURN:      Status
  209.  *
  210.  * DESCRIPTION: System notify handler for AcpiExec utility.  Used by the ASL
  211.  *              test suite(s) to communicate errors and other information to
  212.  *              this utility via the Notify() operator.
  213.  *
  214.  *****************************************************************************/
  215.  
  216. void
  217. AeNotifyHandler (
  218.     ACPI_HANDLE                 Device,
  219.     UINT32                      Value,
  220.     void                        *Context)
  221. {
  222.  
  223.     switch (Value)
  224.     {
  225. #if 0
  226.     case 0:
  227.         printf ("[AcpiExec] Method Error 0x%X: Results not equal\n", Value);
  228.         if (AcpiGbl_DebugFile)
  229.         {
  230.             AcpiOsPrintf ("[AcpiExec] Method Error: Results not equal\n");
  231.         }
  232.         break;
  233.  
  234.  
  235.     case 1:
  236.         printf ("[AcpiExec] Method Error: Incorrect numeric result\n");
  237.         if (AcpiGbl_DebugFile)
  238.         {
  239.             AcpiOsPrintf ("[AcpiExec] Method Error: Incorrect numeric result\n");
  240.         }
  241.         break;
  242.  
  243.  
  244.     case 2:
  245.         printf ("[AcpiExec] Method Error: An operand was overwritten\n");
  246.         if (AcpiGbl_DebugFile)
  247.         {
  248.             AcpiOsPrintf ("[AcpiExec] Method Error: An operand was overwritten\n");
  249.         }
  250.         break;
  251.  
  252. #endif
  253.  
  254.     default:
  255.         printf ("[AcpiExec] Received a System Notify on [%4.4s] %p Value 0x%2.2X (%s)\n",
  256.             AcpiUtGetNodeName (Device), Device, Value,
  257.             AcpiUtGetNotifyName (Value));
  258.         if (AcpiGbl_DebugFile)
  259.         {
  260.             AcpiOsPrintf ("[AcpiExec] Received a system notify, Value 0x%2.2X\n", Value);
  261.         }
  262.  
  263.         (void) AcpiEvaluateObject (Device, "_NOT", NULL, NULL);
  264.         break;
  265.     }
  266.  
  267. }
  268.  
  269.  
  270. /******************************************************************************
  271.  *
  272.  * FUNCTION:    AeDeviceNotifyHandler
  273.  *
  274.  * PARAMETERS:  Standard notify handler parameters
  275.  *
  276.  * RETURN:      Status
  277.  *
  278.  * DESCRIPTION: Device notify handler for AcpiExec utility.  Used by the ASL
  279.  *              test suite(s) to communicate errors and other information to
  280.  *              this utility via the Notify() operator.
  281.  *
  282.  *****************************************************************************/
  283.  
  284. void
  285. AeDeviceNotifyHandler (
  286.     ACPI_HANDLE                 Device,
  287.     UINT32                      Value,
  288.     void                        *Context)
  289. {
  290.  
  291.     printf ("[AcpiExec] Received a Device Notify on [%4.4s] %p Value 0x%2.2X (%s)\n",
  292.         AcpiUtGetNodeName (Device), Device, Value,
  293.         AcpiUtGetNotifyName (Value));
  294.     if (AcpiGbl_DebugFile)
  295.     {
  296.         AcpiOsPrintf ("[AcpiExec] Received a device notify, Value 0x%2.2X\n", Value);
  297.     }
  298.  
  299.     (void) AcpiEvaluateObject (Device, "_NOT", NULL, NULL);
  300. }
  301.  
  302.  
  303. /******************************************************************************
  304.  *
  305.  * FUNCTION:    AeExceptionHandler
  306.  *
  307.  * PARAMETERS:  Standard exception handler parameters
  308.  *
  309.  * RETURN:      Status
  310.  *
  311.  * DESCRIPTION: System exception handler for AcpiExec utility.
  312.  *
  313.  *****************************************************************************/
  314.  
  315. ACPI_STATUS
  316. AeExceptionHandler (
  317.     ACPI_STATUS             AmlStatus,
  318.     ACPI_NAME               Name,
  319.     UINT16                  Opcode,
  320.     UINT32                  AmlOffset,
  321.     void                    *Context)
  322. {
  323.     ACPI_STATUS             NewAmlStatus = AmlStatus;
  324.     ACPI_STATUS             Status;
  325.     ACPI_BUFFER             ReturnObj;
  326.     ACPI_OBJECT_LIST        ArgList;
  327.     ACPI_OBJECT             Arg[3];
  328.     const char              *Exception;
  329.  
  330.  
  331.     Exception = AcpiFormatException (AmlStatus);
  332.     AcpiOsPrintf ("[AcpiExec] Exception %s during execution ", Exception);
  333.     if (Name)
  334.     {
  335.         AcpiOsPrintf ("of method [%4.4s]", (char *) &Name);
  336.     }
  337.     else
  338.     {
  339.         AcpiOsPrintf ("at module level (table load)");
  340.     }
  341.     AcpiOsPrintf (" Opcode [%s] @%X\n", AcpiPsGetOpcodeName (Opcode), AmlOffset);
  342.  
  343.     /*
  344.      * Invoke the _ERR method if present
  345.      *
  346.      * Setup parameter object
  347.      */
  348.     ArgList.Count = 3;
  349.     ArgList.Pointer = Arg;
  350.  
  351.     Arg[0].Type = ACPI_TYPE_INTEGER;
  352.     Arg[0].Integer.Value = AmlStatus;
  353.  
  354.     Arg[1].Type = ACPI_TYPE_STRING;
  355.     Arg[1].String.Pointer = ACPI_CAST_PTR (char, Exception);
  356.     Arg[1].String.Length = ACPI_STRLEN (Exception);
  357.  
  358.     Arg[2].Type = ACPI_TYPE_INTEGER;
  359.     Arg[2].Integer.Value = ACPI_TO_INTEGER (AcpiOsGetThreadId());
  360.  
  361.     /* Setup return buffer */
  362.  
  363.     ReturnObj.Pointer = NULL;
  364.     ReturnObj.Length = ACPI_ALLOCATE_BUFFER;
  365.  
  366.     Status = AcpiEvaluateObject (NULL, "\\_ERR", &ArgList, &ReturnObj);
  367.     if (ACPI_SUCCESS (Status))
  368.     {
  369.         if (ReturnObj.Pointer)
  370.         {
  371.             /* Override original status */
  372.  
  373.             NewAmlStatus = (ACPI_STATUS)
  374.                 ((ACPI_OBJECT *) ReturnObj.Pointer)->Integer.Value;
  375.  
  376.             AcpiOsFree (ReturnObj.Pointer);
  377.         }
  378.     }
  379.     else if (Status != AE_NOT_FOUND)
  380.     {
  381.         AcpiOsPrintf ("[AcpiExec] Could not execute _ERR method, %s\n",
  382.             AcpiFormatException (Status));
  383.     }
  384.  
  385.     /* Global override */
  386.  
  387.     if (AcpiGbl_IgnoreErrors)
  388.     {
  389.         NewAmlStatus = AE_OK;
  390.     }
  391.  
  392.     if (NewAmlStatus != AmlStatus)
  393.     {
  394.         AcpiOsPrintf ("[AcpiExec] Exception override, new status %s\n",
  395.             AcpiFormatException (NewAmlStatus));
  396.     }
  397.  
  398.     return (NewAmlStatus);
  399. }
  400.  
  401.  
  402. /******************************************************************************
  403.  *
  404.  * FUNCTION:    AeTableHandler
  405.  *
  406.  * PARAMETERS:  Table handler
  407.  *
  408.  * RETURN:      Status
  409.  *
  410.  * DESCRIPTION: System table handler for AcpiExec utility.
  411.  *
  412.  *****************************************************************************/
  413.  
  414. char                *TableEvents[] =
  415. {
  416.     "LOAD",
  417.     "UNLOAD",
  418.     "UNKNOWN"
  419. };
  420.  
  421. ACPI_STATUS
  422. AeTableHandler (
  423.     UINT32                  Event,
  424.     void                    *Table,
  425.     void                    *Context)
  426. {
  427.  
  428.     if (Event > ACPI_NUM_TABLE_EVENTS)
  429.     {
  430.         Event = ACPI_NUM_TABLE_EVENTS;
  431.     }
  432.  
  433.     /* TBD: could dump entire table header, need a header dump routine */
  434.  
  435.     printf ("[AcpiExec] Table Event %s, [%4.4s] %p\n",
  436.         TableEvents[Event], ((ACPI_TABLE_HEADER *) Table)->Signature, Table);
  437.     return (AE_OK);
  438. }
  439.  
  440.  
  441. /******************************************************************************
  442.  *
  443.  * FUNCTION:    AeGpeHandler
  444.  *
  445.  * DESCRIPTION: GPE handler for acpiexec
  446.  *
  447.  *****************************************************************************/
  448.  
  449. UINT32
  450. AeGpeHandler (
  451.     void                    *Context)
  452. {
  453.     AcpiOsPrintf ("Received a GPE at handler\n");
  454.     return (0);
  455. }
  456.  
  457.  
  458. /******************************************************************************
  459.  *
  460.  * FUNCTION:    AeAttachedDataHandler
  461.  *
  462.  * DESCRIPTION: Handler for deletion of nodes with attached data (attached via
  463.  *              AcpiAttachData)
  464.  *
  465.  *****************************************************************************/
  466.  
  467. void
  468. AeAttachedDataHandler (
  469.     ACPI_HANDLE             Object,
  470.     void                    *Data)
  471. {
  472.     ACPI_NAMESPACE_NODE     *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Data);
  473.  
  474.  
  475.     AcpiOsPrintf ("Received an attached data deletion on %4.4s\n",
  476.         Node->Name.Ascii);
  477. }
  478.  
  479.  
  480. /******************************************************************************
  481.  *
  482.  * FUNCTION:    AeRegionInit
  483.  *
  484.  * PARAMETERS:  None
  485.  *
  486.  * RETURN:      Status
  487.  *
  488.  * DESCRIPTION: Opregion init function.
  489.  *
  490.  *****************************************************************************/
  491.  
  492. ACPI_STATUS
  493. AeRegionInit (
  494.     ACPI_HANDLE                 RegionHandle,
  495.     UINT32                      Function,
  496.     void                        *HandlerContext,
  497.     void                        **RegionContext)
  498. {
  499.     /*
  500.      * Real simple, set the RegionContext to the RegionHandle
  501.      */
  502.     *RegionContext = RegionHandle;
  503.  
  504.     return AE_OK;
  505. }
  506.  
  507.  
  508. /******************************************************************************
  509.  *
  510.  * FUNCTION:    AeInstallHandlers
  511.  *
  512.  * PARAMETERS:  None
  513.  *
  514.  * RETURN:      Status
  515.  *
  516.  * DESCRIPTION: Install handlers for the AcpiExec utility.
  517.  *
  518.  *****************************************************************************/
  519.  
  520. ACPI_ADR_SPACE_TYPE         SpaceId[] = {0, 1, 2, 3, 4, 5, 6, 7, 0x80};
  521. #define AEXEC_NUM_REGIONS   9
  522.  
  523. ACPI_STATUS
  524. AeInstallHandlers (void)
  525. {
  526.     ACPI_STATUS             Status;
  527.     UINT32                  i;
  528.     ACPI_HANDLE             Handle;
  529.  
  530.  
  531.     ACPI_FUNCTION_ENTRY ();
  532.  
  533.  
  534.     Status = AcpiInstallTableHandler (AeTableHandler, NULL);
  535.     if (ACPI_FAILURE (Status))
  536.     {
  537.         printf ("Could not install table handler, %s\n",
  538.             AcpiFormatException (Status));
  539.     }
  540.  
  541.     Status = AcpiInstallExceptionHandler (AeExceptionHandler);
  542.     if (ACPI_FAILURE (Status))
  543.     {
  544.         printf ("Could not install exception handler, %s\n",
  545.             AcpiFormatException (Status));
  546.     }
  547.  
  548.     /* Install global notify handler */
  549.  
  550.     Status = AcpiInstallNotifyHandler (ACPI_ROOT_OBJECT, ACPI_SYSTEM_NOTIFY,
  551.                                         AeNotifyHandler, NULL);
  552.     if (ACPI_FAILURE (Status))
  553.     {
  554.         printf ("Could not install a global notify handler, %s\n",
  555.             AcpiFormatException (Status));
  556.     }
  557.  
  558.     Status = AcpiInstallNotifyHandler (ACPI_ROOT_OBJECT, ACPI_DEVICE_NOTIFY,
  559.                                         AeDeviceNotifyHandler, NULL);
  560.     if (ACPI_FAILURE (Status))
  561.     {
  562.         printf ("Could not install a global notify handler, %s\n",
  563.             AcpiFormatException (Status));
  564.     }
  565.  
  566.     Status = AcpiGetHandle (NULL, "\\_SB", &Handle);
  567.     if (ACPI_SUCCESS (Status))
  568.     {
  569.         Status = AcpiInstallNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY,
  570.                                             AeNotifyHandler, NULL);
  571.         if (ACPI_FAILURE (Status))
  572.         {
  573.             printf ("Could not install a notify handler, %s\n",
  574.                 AcpiFormatException (Status));
  575.         }
  576.  
  577.         Status = AcpiRemoveNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY,
  578.                                             AeNotifyHandler);
  579.         if (ACPI_FAILURE (Status))
  580.         {
  581.             printf ("Could not remove a notify handler, %s\n",
  582.                 AcpiFormatException (Status));
  583.         }
  584.  
  585.         Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
  586.                                             AeNotifyHandler, NULL);
  587.         Status = AcpiRemoveNotifyHandler (Handle, ACPI_ALL_NOTIFY,
  588.                                             AeNotifyHandler);
  589.         Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
  590.                                             AeNotifyHandler, NULL);
  591.         if (ACPI_FAILURE (Status))
  592.         {
  593.             printf ("Could not install a notify handler, %s\n",
  594.                 AcpiFormatException (Status));
  595.         }
  596.  
  597.         Status = AcpiAttachData (Handle, AeAttachedDataHandler, Handle);
  598.         Status = AcpiDetachData (Handle, AeAttachedDataHandler);
  599.         Status = AcpiAttachData (Handle, AeAttachedDataHandler, Handle);
  600.     }
  601.     else
  602.     {
  603.         printf ("No _SB_ found, %s\n", AcpiFormatException (Status));
  604.     }
  605.  
  606.     /* Set a handler for all supported operation regions */
  607.  
  608.     for (i = 0; i < AEXEC_NUM_REGIONS; i++)
  609.     {
  610.         Status = AcpiRemoveAddressSpaceHandler (AcpiGbl_RootNode,
  611.                         SpaceId[i], AeRegionHandler);
  612.  
  613.         /* Install handler at the root object.
  614.          * TBD: all default handlers should be installed here!
  615.          */
  616.         Status = AcpiInstallAddressSpaceHandler (AcpiGbl_RootNode,
  617.                         SpaceId[i], AeRegionHandler, AeRegionInit, NULL);
  618.         if (ACPI_FAILURE (Status))
  619.         {
  620.             ACPI_EXCEPTION ((AE_INFO, Status,
  621.                 "Could not install an OpRegion handler for %s space(%u)",
  622.                 AcpiUtGetRegionName((UINT8) SpaceId[i]), SpaceId[i]));
  623.             return (Status);
  624.         }
  625.     }
  626.  
  627.     /*
  628.      * Initialize the global Region Handler space
  629.      * MCW 3/23/00
  630.      */
  631.     AeRegions.NumberOfRegions = 0;
  632.     AeRegions.RegionList = NULL;
  633.  
  634.     return Status;
  635. }
  636.  
  637.  
  638. /******************************************************************************
  639.  *
  640.  * FUNCTION:    AeRegionHandler
  641.  *
  642.  * PARAMETERS:  Standard region handler parameters
  643.  *
  644.  * RETURN:      Status
  645.  *
  646.  * DESCRIPTION: Test handler - Handles some dummy regions via memory that can
  647.  *              be manipulated in Ring 3. Simulates actual reads and writes.
  648.  *
  649.  *****************************************************************************/
  650.  
  651. ACPI_STATUS
  652. AeRegionHandler (
  653.     UINT32                  Function,
  654.     ACPI_PHYSICAL_ADDRESS   Address,
  655.     UINT32                  BitWidth,
  656.     UINT64                  *Value,
  657.     void                    *HandlerContext,
  658.     void                    *RegionContext)
  659. {
  660.  
  661.     ACPI_OPERAND_OBJECT     *RegionObject = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, RegionContext);
  662.     UINT8                   *Buffer = ACPI_CAST_PTR (UINT8, Value);
  663.     ACPI_PHYSICAL_ADDRESS   BaseAddress;
  664.     ACPI_SIZE               Length;
  665.     BOOLEAN                 BufferExists;
  666.     AE_REGION               *RegionElement;
  667.     void                    *BufferValue;
  668.     ACPI_STATUS             Status;
  669.     UINT32                  ByteWidth;
  670.     UINT32                  i;
  671.     UINT8                   SpaceId;
  672.  
  673.  
  674.     ACPI_FUNCTION_NAME (AeRegionHandler);
  675.  
  676.     /*
  677.      * If the object is not a region, simply return
  678.      */
  679.     if (RegionObject->Region.Type != ACPI_TYPE_REGION)
  680.     {
  681.         return AE_OK;
  682.     }
  683.  
  684.     /*
  685.      * Region support can be disabled with the -r option.
  686.      * We use this to support dynamically loaded tables where we pass a valid
  687.      * address to the AML.
  688.      */
  689.     if (AcpiGbl_DbOpt_NoRegionSupport)
  690.     {
  691.         BufferValue = ACPI_TO_POINTER (Address);
  692.         ByteWidth = (BitWidth / 8);
  693.  
  694.         if (BitWidth % 8)
  695.         {
  696.             ByteWidth += 1;
  697.         }
  698.         goto DoFunction;
  699.     }
  700.  
  701.     /*
  702.      * Find the region's address space and length before searching
  703.      * the linked list.
  704.      */
  705.     BaseAddress = RegionObject->Region.Address;
  706.     Length = (ACPI_SIZE) RegionObject->Region.Length;
  707.     SpaceId = RegionObject->Region.SpaceId;
  708.  
  709.     ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, "Operation Region request on %s at 0x%X\n",
  710.             AcpiUtGetRegionName (RegionObject->Region.SpaceId),
  711.             (UINT32) Address));
  712.  
  713.     switch (SpaceId)
  714.     {
  715.     case ACPI_ADR_SPACE_SYSTEM_IO:
  716.         /*
  717.          * For I/O space, exercise the port validation
  718.          */
  719.         switch (Function & ACPI_IO_MASK)
  720.         {
  721.         case ACPI_READ:
  722.             Status = AcpiHwReadPort (Address, (UINT32 *) Value, BitWidth);
  723.             break;
  724.  
  725.         case ACPI_WRITE:
  726.             Status = AcpiHwWritePort (Address, (UINT32) *Value, BitWidth);
  727.             break;
  728.  
  729.         default:
  730.             Status = AE_BAD_PARAMETER;
  731.             break;
  732.         }
  733.  
  734.         if (ACPI_FAILURE (Status))
  735.         {
  736.             return (Status);
  737.         }
  738.  
  739.         /* Now go ahead and simulate the hardware */
  740.         break;
  741.  
  742.  
  743.     case ACPI_ADR_SPACE_SMBUS:
  744.  
  745.         Length = 0;
  746.  
  747.         switch (Function & ACPI_IO_MASK)
  748.         {
  749.         case ACPI_READ:
  750.             switch (Function >> 16)
  751.             {
  752.             case AML_FIELD_ATTRIB_SMB_QUICK:
  753.             case AML_FIELD_ATTRIB_SMB_SEND_RCV:
  754.             case AML_FIELD_ATTRIB_SMB_BYTE:
  755.                 Length = 1;
  756.                 break;
  757.  
  758.             case AML_FIELD_ATTRIB_SMB_WORD:
  759.             case AML_FIELD_ATTRIB_SMB_WORD_CALL:
  760.                 Length = 2;
  761.                 break;
  762.  
  763.             case AML_FIELD_ATTRIB_SMB_BLOCK:
  764.             case AML_FIELD_ATTRIB_SMB_BLOCK_CALL:
  765.                 Length = 32;
  766.                 break;
  767.  
  768.             default:
  769.                 break;
  770.             }
  771.             break;
  772.  
  773.         case ACPI_WRITE:
  774.             switch (Function >> 16)
  775.             {
  776.             case AML_FIELD_ATTRIB_SMB_QUICK:
  777.             case AML_FIELD_ATTRIB_SMB_SEND_RCV:
  778.             case AML_FIELD_ATTRIB_SMB_BYTE:
  779.             case AML_FIELD_ATTRIB_SMB_WORD:
  780.             case AML_FIELD_ATTRIB_SMB_BLOCK:
  781.                 Length = 0;
  782.                 break;
  783.  
  784.             case AML_FIELD_ATTRIB_SMB_WORD_CALL:
  785.                 Length = 2;
  786.                 break;
  787.  
  788.             case AML_FIELD_ATTRIB_SMB_BLOCK_CALL:
  789.                 Length = 32;
  790.                 break;
  791.  
  792.             default:
  793.                 break;
  794.             }
  795.             break;
  796.  
  797.         default:
  798.             break;
  799.         }
  800.  
  801.         for (i = 0; i < Length; i++)
  802.         {
  803.             Buffer[i+2] = (UINT8) (0xA0 + i);
  804.         }
  805.  
  806.         Buffer[0] = 0x7A;
  807.         Buffer[1] = (UINT8) Length;
  808.         return (AE_OK);
  809.  
  810.  
  811.     case ACPI_ADR_SPACE_IPMI: /* ACPI 4.0 */
  812.  
  813.         AcpiOsPrintf ("AcpiExec: Received IPMI request: "
  814.             "Address %X BaseAddress %X Length %X Width %X BufferLength %u\n",
  815.             (UINT32) Address, (UINT32) BaseAddress,
  816.             Length, BitWidth, Buffer[1]);
  817.  
  818.         /*
  819.          * Regardless of a READ or WRITE, this handler is passed a 66-byte
  820.          * buffer in which to return the IPMI status/length/data.
  821.          *
  822.          * Return some example data to show use of the bidirectional buffer
  823.          */
  824.         Buffer[0] = 0;       /* Status byte */
  825.         Buffer[1] = 64;      /* Return buffer data length */
  826.         Buffer[2] = 0;       /* Completion code */
  827.         Buffer[3] = 0x34;    /* Power measurement */
  828.         Buffer[4] = 0x12;    /* Power measurement */
  829.         Buffer[65] = 0xEE;   /* last buffer byte */
  830.         return (AE_OK);
  831.  
  832.     default:
  833.         break;
  834.     }
  835.  
  836.     /*
  837.      * Search through the linked list for this region's buffer
  838.      */
  839.     BufferExists = FALSE;
  840.     RegionElement = AeRegions.RegionList;
  841.  
  842.     if (AeRegions.NumberOfRegions)
  843.     {
  844.         while (!BufferExists && RegionElement)
  845.         {
  846.             if (RegionElement->Address == BaseAddress &&
  847.                 RegionElement->Length == Length &&
  848.                 RegionElement->SpaceId == SpaceId)
  849.             {
  850.                 BufferExists = TRUE;
  851.             }
  852.             else
  853.             {
  854.                 RegionElement = RegionElement->NextRegion;
  855.             }
  856.         }
  857.     }
  858.  
  859.     /*
  860.      * If the Region buffer does not exist, create it now
  861.      */
  862.     if (!BufferExists)
  863.     {
  864.         /*
  865.          * Do the memory allocations first
  866.          */
  867.         RegionElement = AcpiOsAllocate (sizeof (AE_REGION));
  868.         if (!RegionElement)
  869.         {
  870.             return AE_NO_MEMORY;
  871.         }
  872.  
  873.         RegionElement->Buffer = AcpiOsAllocate (Length);
  874.         if (!RegionElement->Buffer)
  875.         {
  876.             AcpiOsFree (RegionElement);
  877.             return AE_NO_MEMORY;
  878.         }
  879.  
  880.         /* Initialize the region with the default fill value */
  881.  
  882.         ACPI_MEMSET (RegionElement->Buffer, AcpiGbl_RegionFillValue, Length);
  883.  
  884.         RegionElement->Address      = BaseAddress;
  885.         RegionElement->Length       = Length;
  886.         RegionElement->SpaceId      = SpaceId;
  887.         RegionElement->NextRegion   = NULL;
  888.  
  889.         /*
  890.          * Increment the number of regions and put this one
  891.          *  at the head of the list as it will probably get accessed
  892.          *  more often anyway.
  893.          */
  894.         AeRegions.NumberOfRegions += 1;
  895.  
  896.         if (AeRegions.RegionList)
  897.         {
  898.             RegionElement->NextRegion = AeRegions.RegionList;
  899.         }
  900.  
  901.         AeRegions.RegionList = RegionElement;
  902.     }
  903.  
  904.     /*
  905.      * Calculate the size of the memory copy
  906.      */
  907.     ByteWidth = (BitWidth / 8);
  908.  
  909.     if (BitWidth % 8)
  910.     {
  911.         ByteWidth += 1;
  912.     }
  913.  
  914.     /*
  915.      * The buffer exists and is pointed to by RegionElement.
  916.      * We now need to verify the request is valid and perform the operation.
  917.      *
  918.      * NOTE: RegionElement->Length is in bytes, therefore it we compare against
  919.      * ByteWidth (see above)
  920.      */
  921.     if (((UINT64) Address + ByteWidth) >
  922.         ((UINT64)(RegionElement->Address) + RegionElement->Length))
  923.     {
  924.         ACPI_WARNING ((AE_INFO,
  925.             "Request on [%4.4s] is beyond region limit Req-0x%X+0x%X, Base=0x%X, Len-0x%X",
  926.             (RegionObject->Region.Node)->Name.Ascii, (UINT32) Address,
  927.             ByteWidth, (UINT32)(RegionElement->Address),
  928.             RegionElement->Length));
  929.  
  930.         return AE_AML_REGION_LIMIT;
  931.     }
  932.  
  933.     /*
  934.      * Get BufferValue to point to the "address" in the buffer
  935.      */
  936.     BufferValue = ((UINT8 *) RegionElement->Buffer +
  937.                     ((UINT64) Address - (UINT64) RegionElement->Address));
  938.  
  939. DoFunction:
  940.  
  941.     /*
  942.      * Perform a read or write to the buffer space
  943.      */
  944.     switch (Function)
  945.     {
  946.     case ACPI_READ:
  947.         /*
  948.          * Set the pointer Value to whatever is in the buffer
  949.          */
  950.         ACPI_MEMCPY (Value, BufferValue, ByteWidth);
  951.         break;
  952.  
  953.     case ACPI_WRITE:
  954.         /*
  955.          * Write the contents of Value to the buffer
  956.          */
  957.         ACPI_MEMCPY (BufferValue, Value, ByteWidth);
  958.         break;
  959.  
  960.     default:
  961.         return AE_BAD_PARAMETER;
  962.     }
  963.     return AE_OK;
  964. }
  965.  
  966.  
  967.