Home | History | Annotate | Line # | Download | only in acpiexec
aehandlers.c revision 1.1
      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