Home | History | Annotate | Line # | Download | only in acpiexec
aehandlers.c revision 1.1.1.4
      1 /******************************************************************************
      2  *
      3  * Module Name: aehandlers - Various handlers for acpiexec
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2013, Intel Corp.
      9  * All rights reserved.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions, and the following disclaimer,
     16  *    without modification.
     17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     18  *    substantially similar to the "NO WARRANTY" disclaimer below
     19  *    ("Disclaimer") and any redistribution must be conditioned upon
     20  *    including a substantially similar Disclaimer requirement for further
     21  *    binary redistribution.
     22  * 3. Neither the names of the above-listed copyright holders nor the names
     23  *    of any contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * Alternatively, this software may be distributed under the terms of the
     27  * GNU General Public License ("GPL") version 2 as published by the Free
     28  * Software Foundation.
     29  *
     30  * NO WARRANTY
     31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
     34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     41  * POSSIBILITY OF SUCH DAMAGES.
     42  */
     43 
     44 #include "aecommon.h"
     45 
     46 #define _COMPONENT          ACPI_TOOLS
     47         ACPI_MODULE_NAME    ("aehandlers")
     48 
     49 /* Local prototypes */
     50 
     51 static void
     52 AeNotifyHandler1 (
     53     ACPI_HANDLE             Device,
     54     UINT32                  Value,
     55     void                    *Context);
     56 
     57 static void
     58 AeNotifyHandler2 (
     59     ACPI_HANDLE             Device,
     60     UINT32                  Value,
     61     void                    *Context);
     62 
     63 static void
     64 AeCommonNotifyHandler (
     65     ACPI_HANDLE             Device,
     66     UINT32                  Value,
     67     UINT32                  HandlerId);
     68 
     69 static void
     70 AeDeviceNotifyHandler (
     71     ACPI_HANDLE             Device,
     72     UINT32                  Value,
     73     void                    *Context);
     74 
     75 static ACPI_STATUS
     76 AeExceptionHandler (
     77     ACPI_STATUS             AmlStatus,
     78     ACPI_NAME               Name,
     79     UINT16                  Opcode,
     80     UINT32                  AmlOffset,
     81     void                    *Context);
     82 
     83 static ACPI_STATUS
     84 AeTableHandler (
     85     UINT32                  Event,
     86     void                    *Table,
     87     void                    *Context);
     88 
     89 static ACPI_STATUS
     90 AeRegionInit (
     91     ACPI_HANDLE             RegionHandle,
     92     UINT32                  Function,
     93     void                    *HandlerContext,
     94     void                    **RegionContext);
     95 
     96 static void
     97 AeAttachedDataHandler (
     98     ACPI_HANDLE             Object,
     99     void                    *Data);
    100 
    101 static void
    102 AeAttachedDataHandler2 (
    103     ACPI_HANDLE             Object,
    104     void                    *Data);
    105 
    106 static UINT32
    107 AeInterfaceHandler (
    108     ACPI_STRING             InterfaceName,
    109     UINT32                  Supported);
    110 
    111 static ACPI_STATUS
    112 AeInstallEcHandler (
    113     ACPI_HANDLE             ObjHandle,
    114     UINT32                  Level,
    115     void                    *Context,
    116     void                    **ReturnValue);
    117 
    118 static ACPI_STATUS
    119 AeInstallPciHandler (
    120     ACPI_HANDLE             ObjHandle,
    121     UINT32                  Level,
    122     void                    *Context,
    123     void                    **ReturnValue);
    124 
    125 static ACPI_STATUS
    126 AeInstallDeviceHandlers (
    127     void);
    128 
    129 #if (!ACPI_REDUCED_HARDWARE)
    130 static UINT32
    131 AeEventHandler (
    132     void                    *Context);
    133 
    134 static UINT32
    135 AeSciHandler (
    136     void                    *Context);
    137 
    138 static char                *TableEvents[] =
    139 {
    140     "LOAD",
    141     "UNLOAD",
    142     "UNKNOWN"
    143 };
    144 #endif /* !ACPI_REDUCED_HARDWARE */
    145 
    146 
    147 static UINT32               SigintCount = 0;
    148 static AE_DEBUG_REGIONS     AeRegions;
    149 BOOLEAN                     AcpiGbl_DisplayRegionAccess = FALSE;
    150 
    151 /*
    152  * We will override some of the default region handlers, especially the
    153  * SystemMemory handler, which must be implemented locally. Do not override
    154  * the PCI_Config handler since we would like to exercise the default handler
    155  * code. These handlers are installed "early" - before any _REG methods
    156  * are executed - since they are special in the sense that the ACPI spec
    157  * declares that they must "always be available". Cannot override the
    158  * DataTable region handler either -- needed for test execution.
    159  */
    160 static ACPI_ADR_SPACE_TYPE  DefaultSpaceIdList[] =
    161 {
    162     ACPI_ADR_SPACE_SYSTEM_MEMORY,
    163     ACPI_ADR_SPACE_SYSTEM_IO
    164 };
    165 
    166 /*
    167  * We will install handlers for some of the various address space IDs.
    168  * Test one user-defined address space (used by aslts).
    169  */
    170 #define ACPI_ADR_SPACE_USER_DEFINED1        0x80
    171 #define ACPI_ADR_SPACE_USER_DEFINED2        0xE4
    172 
    173 static ACPI_ADR_SPACE_TYPE  SpaceIdList[] =
    174 {
    175     ACPI_ADR_SPACE_SMBUS,
    176     ACPI_ADR_SPACE_CMOS,
    177     ACPI_ADR_SPACE_PCI_BAR_TARGET,
    178     ACPI_ADR_SPACE_IPMI,
    179     ACPI_ADR_SPACE_GPIO,
    180     ACPI_ADR_SPACE_GSBUS,
    181     ACPI_ADR_SPACE_FIXED_HARDWARE,
    182     ACPI_ADR_SPACE_USER_DEFINED1,
    183     ACPI_ADR_SPACE_USER_DEFINED2
    184 };
    185 
    186 static ACPI_CONNECTION_INFO   AeMyContext;
    187 
    188 
    189 /******************************************************************************
    190  *
    191  * FUNCTION:    AeCtrlCHandler
    192  *
    193  * PARAMETERS:  Sig
    194  *
    195  * RETURN:      none
    196  *
    197  * DESCRIPTION: Control-C handler. Abort running control method if any.
    198  *
    199  *****************************************************************************/
    200 
    201 void ACPI_SYSTEM_XFACE
    202 AeCtrlCHandler (
    203     int                     Sig)
    204 {
    205 
    206     signal (SIGINT, SIG_IGN);
    207     SigintCount++;
    208 
    209     AcpiOsPrintf ("Caught a ctrl-c (#%u)\n\n", SigintCount);
    210 
    211     if (AcpiGbl_MethodExecuting)
    212     {
    213         AcpiGbl_AbortMethod = TRUE;
    214         signal (SIGINT, AeCtrlCHandler);
    215 
    216         if (SigintCount < 10)
    217         {
    218             return;
    219         }
    220     }
    221 
    222     (void) AcpiOsTerminate ();
    223     exit (0);
    224 }
    225 
    226 
    227 /******************************************************************************
    228  *
    229  * FUNCTION:    AeNotifyHandler(s)
    230  *
    231  * PARAMETERS:  Standard notify handler parameters
    232  *
    233  * RETURN:      Status
    234  *
    235  * DESCRIPTION: Notify handlers for AcpiExec utility. Used by the ASL
    236  *              test suite(s) to communicate errors and other information to
    237  *              this utility via the Notify() operator. Tests notify handling
    238  *              and multiple notify handler support.
    239  *
    240  *****************************************************************************/
    241 
    242 static void
    243 AeNotifyHandler1 (
    244     ACPI_HANDLE             Device,
    245     UINT32                  Value,
    246     void                    *Context)
    247 {
    248     AeCommonNotifyHandler (Device, Value, 1);
    249 }
    250 
    251 static void
    252 AeNotifyHandler2 (
    253     ACPI_HANDLE             Device,
    254     UINT32                  Value,
    255     void                    *Context)
    256 {
    257     AeCommonNotifyHandler (Device, Value, 2);
    258 }
    259 
    260 static void
    261 AeCommonNotifyHandler (
    262     ACPI_HANDLE             Device,
    263     UINT32                  Value,
    264     UINT32                  HandlerId)
    265 {
    266     char                    *Type;
    267 
    268 
    269     Type = "Device";
    270     if (Value <= ACPI_MAX_SYS_NOTIFY)
    271     {
    272         Type = "System";
    273     }
    274 
    275     switch (Value)
    276     {
    277 #if 0
    278     case 0:
    279 
    280         printf ("[AcpiExec] Method Error 0x%X: Results not equal\n", Value);
    281         if (AcpiGbl_DebugFile)
    282         {
    283             AcpiOsPrintf ("[AcpiExec] Method Error: Results not equal\n");
    284         }
    285         break;
    286 
    287     case 1:
    288 
    289         printf ("[AcpiExec] Method Error: Incorrect numeric result\n");
    290         if (AcpiGbl_DebugFile)
    291         {
    292             AcpiOsPrintf ("[AcpiExec] Method Error: Incorrect numeric result\n");
    293         }
    294         break;
    295 
    296     case 2:
    297 
    298         printf ("[AcpiExec] Method Error: An operand was overwritten\n");
    299         if (AcpiGbl_DebugFile)
    300         {
    301             AcpiOsPrintf ("[AcpiExec] Method Error: An operand was overwritten\n");
    302         }
    303         break;
    304 
    305 #endif
    306 
    307     default:
    308 
    309         printf ("[AcpiExec] Handler %u: Received a %s Notify on [%4.4s] %p Value 0x%2.2X (%s)\n",
    310             HandlerId, Type, AcpiUtGetNodeName (Device), Device, Value,
    311             AcpiUtGetNotifyName (Value));
    312         if (AcpiGbl_DebugFile)
    313         {
    314             AcpiOsPrintf ("[AcpiExec] Handler %u: Received a %s notify, Value 0x%2.2X\n",
    315                 HandlerId, Type, Value);
    316         }
    317 
    318         (void) AcpiEvaluateObject (Device, "_NOT", NULL, NULL);
    319         break;
    320     }
    321 }
    322 
    323 
    324 /******************************************************************************
    325  *
    326  * FUNCTION:    AeSystemNotifyHandler
    327  *
    328  * PARAMETERS:  Standard notify handler parameters
    329  *
    330  * RETURN:      Status
    331  *
    332  * DESCRIPTION: System notify handler for AcpiExec utility. Used by the ASL
    333  *              test suite(s) to communicate errors and other information to
    334  *              this utility via the Notify() operator.
    335  *
    336  *****************************************************************************/
    337 
    338 static void
    339 AeSystemNotifyHandler (
    340     ACPI_HANDLE                 Device,
    341     UINT32                      Value,
    342     void                        *Context)
    343 {
    344 
    345     printf ("[AcpiExec] Global:    Received a System Notify on [%4.4s] %p Value 0x%2.2X (%s)\n",
    346         AcpiUtGetNodeName (Device), Device, Value,
    347         AcpiUtGetNotifyName (Value));
    348     if (AcpiGbl_DebugFile)
    349     {
    350         AcpiOsPrintf ("[AcpiExec] Global:    Received a System Notify, Value 0x%2.2X\n", Value);
    351     }
    352 
    353     (void) AcpiEvaluateObject (Device, "_NOT", NULL, NULL);
    354 }
    355 
    356 
    357 /******************************************************************************
    358  *
    359  * FUNCTION:    AeDeviceNotifyHandler
    360  *
    361  * PARAMETERS:  Standard notify handler parameters
    362  *
    363  * RETURN:      Status
    364  *
    365  * DESCRIPTION: Device notify handler for AcpiExec utility. Used by the ASL
    366  *              test suite(s) to communicate errors and other information to
    367  *              this utility via the Notify() operator.
    368  *
    369  *****************************************************************************/
    370 
    371 static void
    372 AeDeviceNotifyHandler (
    373     ACPI_HANDLE                 Device,
    374     UINT32                      Value,
    375     void                        *Context)
    376 {
    377 
    378     printf ("[AcpiExec] Global:    Received a Device Notify on [%4.4s] %p Value 0x%2.2X (%s)\n",
    379         AcpiUtGetNodeName (Device), Device, Value,
    380         AcpiUtGetNotifyName (Value));
    381     if (AcpiGbl_DebugFile)
    382     {
    383         AcpiOsPrintf ("[AcpiExec] Global:    Received a Device Notify, Value 0x%2.2X\n", Value);
    384     }
    385 
    386     (void) AcpiEvaluateObject (Device, "_NOT", NULL, NULL);
    387 }
    388 
    389 
    390 /******************************************************************************
    391  *
    392  * FUNCTION:    AeExceptionHandler
    393  *
    394  * PARAMETERS:  Standard exception handler parameters
    395  *
    396  * RETURN:      Status
    397  *
    398  * DESCRIPTION: System exception handler for AcpiExec utility.
    399  *
    400  *****************************************************************************/
    401 
    402 static ACPI_STATUS
    403 AeExceptionHandler (
    404     ACPI_STATUS             AmlStatus,
    405     ACPI_NAME               Name,
    406     UINT16                  Opcode,
    407     UINT32                  AmlOffset,
    408     void                    *Context)
    409 {
    410     ACPI_STATUS             NewAmlStatus = AmlStatus;
    411     ACPI_STATUS             Status;
    412     ACPI_BUFFER             ReturnObj;
    413     ACPI_OBJECT_LIST        ArgList;
    414     ACPI_OBJECT             Arg[3];
    415     const char              *Exception;
    416 
    417 
    418     Exception = AcpiFormatException (AmlStatus);
    419     AcpiOsPrintf ("[AcpiExec] Exception %s during execution ", Exception);
    420     if (Name)
    421     {
    422         AcpiOsPrintf ("of method [%4.4s]", (char *) &Name);
    423     }
    424     else
    425     {
    426         AcpiOsPrintf ("at module level (table load)");
    427     }
    428     AcpiOsPrintf (" Opcode [%s] @%X\n", AcpiPsGetOpcodeName (Opcode), AmlOffset);
    429 
    430     /*
    431      * Invoke the _ERR method if present
    432      *
    433      * Setup parameter object
    434      */
    435     ArgList.Count = 3;
    436     ArgList.Pointer = Arg;
    437 
    438     Arg[0].Type = ACPI_TYPE_INTEGER;
    439     Arg[0].Integer.Value = AmlStatus;
    440 
    441     Arg[1].Type = ACPI_TYPE_STRING;
    442     Arg[1].String.Pointer = ACPI_CAST_PTR (char, Exception);
    443     Arg[1].String.Length = ACPI_STRLEN (Exception);
    444 
    445     Arg[2].Type = ACPI_TYPE_INTEGER;
    446     Arg[2].Integer.Value = AcpiOsGetThreadId();
    447 
    448     /* Setup return buffer */
    449 
    450     ReturnObj.Pointer = NULL;
    451     ReturnObj.Length = ACPI_ALLOCATE_BUFFER;
    452 
    453     Status = AcpiEvaluateObject (NULL, "\\_ERR", &ArgList, &ReturnObj);
    454     if (ACPI_SUCCESS (Status))
    455     {
    456         if (ReturnObj.Pointer)
    457         {
    458             /* Override original status */
    459 
    460             NewAmlStatus = (ACPI_STATUS)
    461                 ((ACPI_OBJECT *) ReturnObj.Pointer)->Integer.Value;
    462 
    463             /* Free a buffer created via ACPI_ALLOCATE_BUFFER */
    464 
    465             AcpiOsFree (ReturnObj.Pointer);
    466         }
    467     }
    468     else if (Status != AE_NOT_FOUND)
    469     {
    470         AcpiOsPrintf ("[AcpiExec] Could not execute _ERR method, %s\n",
    471             AcpiFormatException (Status));
    472     }
    473 
    474     /* Global override */
    475 
    476     if (AcpiGbl_IgnoreErrors)
    477     {
    478         NewAmlStatus = AE_OK;
    479     }
    480 
    481     if (NewAmlStatus != AmlStatus)
    482     {
    483         AcpiOsPrintf ("[AcpiExec] Exception override, new status %s\n",
    484             AcpiFormatException (NewAmlStatus));
    485     }
    486 
    487     return (NewAmlStatus);
    488 }
    489 
    490 
    491 /******************************************************************************
    492  *
    493  * FUNCTION:    AeTableHandler
    494  *
    495  * PARAMETERS:  Table handler
    496  *
    497  * RETURN:      Status
    498  *
    499  * DESCRIPTION: System table handler for AcpiExec utility.
    500  *
    501  *****************************************************************************/
    502 
    503 static ACPI_STATUS
    504 AeTableHandler (
    505     UINT32                  Event,
    506     void                    *Table,
    507     void                    *Context)
    508 {
    509 #if (!ACPI_REDUCED_HARDWARE)
    510     ACPI_STATUS             Status;
    511 #endif /* !ACPI_REDUCED_HARDWARE */
    512 
    513 
    514     if (Event > ACPI_NUM_TABLE_EVENTS)
    515     {
    516         Event = ACPI_NUM_TABLE_EVENTS;
    517     }
    518 
    519 #if (!ACPI_REDUCED_HARDWARE)
    520     /* Enable any GPEs associated with newly-loaded GPE methods */
    521 
    522     Status = AcpiUpdateAllGpes ();
    523     AE_CHECK_OK (AcpiUpdateAllGpes, Status);
    524 
    525     printf ("[AcpiExec] Table Event %s, [%4.4s] %p\n",
    526         TableEvents[Event], ((ACPI_TABLE_HEADER *) Table)->Signature, Table);
    527 #endif /* !ACPI_REDUCED_HARDWARE */
    528 
    529     return (AE_OK);
    530 }
    531 
    532 
    533 /******************************************************************************
    534  *
    535  * FUNCTION:    AeGpeHandler
    536  *
    537  * DESCRIPTION: Common GPE handler for acpiexec
    538  *
    539  *****************************************************************************/
    540 
    541 UINT32
    542 AeGpeHandler (
    543     ACPI_HANDLE             GpeDevice,
    544     UINT32                  GpeNumber,
    545     void                    *Context)
    546 {
    547     ACPI_NAMESPACE_NODE     *DeviceNode = (ACPI_NAMESPACE_NODE *) GpeDevice;
    548 
    549 
    550     AcpiOsPrintf ("[AcpiExec] GPE Handler received GPE%02X (GPE block %4.4s)\n",
    551         GpeNumber, GpeDevice ? DeviceNode->Name.Ascii : "FADT");
    552 
    553     return (ACPI_REENABLE_GPE);
    554 }
    555 
    556 
    557 /******************************************************************************
    558  *
    559  * FUNCTION:    AeGlobalEventHandler
    560  *
    561  * DESCRIPTION: Global GPE/Fixed event handler
    562  *
    563  *****************************************************************************/
    564 
    565 void
    566 AeGlobalEventHandler (
    567     UINT32                  Type,
    568     ACPI_HANDLE             Device,
    569     UINT32                  EventNumber,
    570     void                    *Context)
    571 {
    572     char                    *TypeName;
    573 
    574 
    575     switch (Type)
    576     {
    577     case ACPI_EVENT_TYPE_GPE:
    578 
    579         TypeName = "GPE";
    580         break;
    581 
    582     case ACPI_EVENT_TYPE_FIXED:
    583 
    584         TypeName = "FixedEvent";
    585         break;
    586 
    587     default:
    588 
    589         TypeName = "UNKNOWN";
    590         break;
    591     }
    592 
    593     AcpiOsPrintf ("[AcpiExec] Global Event Handler received: Type %s Number %.2X Dev %p\n",
    594         TypeName, EventNumber, Device);
    595 }
    596 
    597 
    598 /******************************************************************************
    599  *
    600  * FUNCTION:    AeAttachedDataHandler
    601  *
    602  * DESCRIPTION: Handler for deletion of nodes with attached data (attached via
    603  *              AcpiAttachData)
    604  *
    605  *****************************************************************************/
    606 
    607 static void
    608 AeAttachedDataHandler (
    609     ACPI_HANDLE             Object,
    610     void                    *Data)
    611 {
    612     ACPI_NAMESPACE_NODE     *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Data);
    613 
    614 
    615     AcpiOsPrintf ("Received an attached data deletion (1) on %4.4s\n",
    616         Node->Name.Ascii);
    617 }
    618 
    619 
    620 /******************************************************************************
    621  *
    622  * FUNCTION:    AeAttachedDataHandler2
    623  *
    624  * DESCRIPTION: Handler for deletion of nodes with attached data (attached via
    625  *              AcpiAttachData)
    626  *
    627  *****************************************************************************/
    628 
    629 static void
    630 AeAttachedDataHandler2 (
    631     ACPI_HANDLE             Object,
    632     void                    *Data)
    633 {
    634     ACPI_NAMESPACE_NODE     *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Data);
    635 
    636 
    637     AcpiOsPrintf ("Received an attached data deletion (2) on %4.4s\n",
    638         Node->Name.Ascii);
    639 }
    640 
    641 
    642 /******************************************************************************
    643  *
    644  * FUNCTION:    AeInterfaceHandler
    645  *
    646  * DESCRIPTION: Handler for _OSI invocations
    647  *
    648  *****************************************************************************/
    649 
    650 static UINT32
    651 AeInterfaceHandler (
    652     ACPI_STRING             InterfaceName,
    653     UINT32                  Supported)
    654 {
    655     ACPI_FUNCTION_NAME (AeInterfaceHandler);
    656 
    657 
    658     ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
    659         "Received _OSI (\"%s\"), is %ssupported\n",
    660         InterfaceName, Supported == 0 ? "not " : ""));
    661 
    662     return (Supported);
    663 }
    664 
    665 
    666 #if (!ACPI_REDUCED_HARDWARE)
    667 /******************************************************************************
    668  *
    669  * FUNCTION:    AeEventHandler, AeSciHandler
    670  *
    671  * DESCRIPTION: Handler for Fixed Events and SCIs
    672  *
    673  *****************************************************************************/
    674 
    675 static UINT32
    676 AeEventHandler (
    677     void                    *Context)
    678 {
    679     return (0);
    680 }
    681 
    682 static UINT32
    683 AeSciHandler (
    684     void                    *Context)
    685 {
    686 
    687     AcpiOsPrintf ("[AcpiExec] Received an SCI at handler\n");
    688     return (0);
    689 }
    690 
    691 #endif /* !ACPI_REDUCED_HARDWARE */
    692 
    693 
    694 /******************************************************************************
    695  *
    696  * FUNCTION:    AeRegionInit
    697  *
    698  * PARAMETERS:  None
    699  *
    700  * RETURN:      Status
    701  *
    702  * DESCRIPTION: Opregion init function.
    703  *
    704  *****************************************************************************/
    705 
    706 static ACPI_STATUS
    707 AeRegionInit (
    708     ACPI_HANDLE                 RegionHandle,
    709     UINT32                      Function,
    710     void                        *HandlerContext,
    711     void                        **RegionContext)
    712 {
    713 
    714     if (Function == ACPI_REGION_DEACTIVATE)
    715     {
    716         *RegionContext = NULL;
    717     }
    718     else
    719     {
    720         *RegionContext = RegionHandle;
    721     }
    722 
    723     return (AE_OK);
    724 }
    725 
    726 
    727 /*******************************************************************************
    728  *
    729  * FUNCTION:    AeInstallSciHandler
    730  *
    731  * PARAMETERS:  None
    732  *
    733  * RETURN:      Status
    734  *
    735  * DESCRIPTION: Install handler for SCIs. Exercise the code by doing an
    736  *              install/remove/install.
    737  *
    738  ******************************************************************************/
    739 
    740 static ACPI_STATUS
    741 AeInstallSciHandler (
    742     void)
    743 {
    744     ACPI_STATUS             Status;
    745 
    746 
    747     Status = AcpiInstallSciHandler (AeSciHandler, &AeMyContext);
    748     if (ACPI_FAILURE (Status))
    749     {
    750         ACPI_EXCEPTION ((AE_INFO, Status,
    751             "Could not install an SCI handler (1)"));
    752     }
    753 
    754     Status = AcpiRemoveSciHandler (AeSciHandler);
    755     if (ACPI_FAILURE (Status))
    756     {
    757         ACPI_EXCEPTION ((AE_INFO, Status,
    758             "Could not remove an SCI handler"));
    759     }
    760 
    761     Status = AcpiInstallSciHandler (AeSciHandler, &AeMyContext);
    762     if (ACPI_FAILURE (Status))
    763     {
    764         ACPI_EXCEPTION ((AE_INFO, Status,
    765             "Could not install an SCI handler (2)"));
    766     }
    767 
    768     return (Status);
    769 }
    770 
    771 
    772 /*******************************************************************************
    773  *
    774  * FUNCTION:    AeInstallDeviceHandlers, AeInstallEcHandler,
    775  *              AeInstallPciHandler
    776  *
    777  * PARAMETERS:  ACPI_WALK_NAMESPACE callback
    778  *
    779  * RETURN:      Status
    780  *
    781  * DESCRIPTION: Walk entire namespace, install a handler for every EC
    782  *              and PCI device found.
    783  *
    784  ******************************************************************************/
    785 
    786 static ACPI_STATUS
    787 AeInstallEcHandler (
    788     ACPI_HANDLE             ObjHandle,
    789     UINT32                  Level,
    790     void                    *Context,
    791     void                    **ReturnValue)
    792 {
    793     ACPI_STATUS             Status;
    794 
    795 
    796     /* Install the handler for this EC device */
    797 
    798     Status = AcpiInstallAddressSpaceHandler (ObjHandle, ACPI_ADR_SPACE_EC,
    799         AeRegionHandler, AeRegionInit, &AeMyContext);
    800     if (ACPI_FAILURE (Status))
    801     {
    802         ACPI_EXCEPTION ((AE_INFO, Status,
    803             "Could not install an OpRegion handler for EC device (%p)",
    804             ObjHandle));
    805     }
    806 
    807     return (Status);
    808 }
    809 
    810 static ACPI_STATUS
    811 AeInstallPciHandler (
    812     ACPI_HANDLE             ObjHandle,
    813     UINT32                  Level,
    814     void                    *Context,
    815     void                    **ReturnValue)
    816 {
    817     ACPI_STATUS             Status;
    818 
    819 
    820     /* Install memory and I/O handlers for the PCI device */
    821 
    822     Status = AcpiInstallAddressSpaceHandler (ObjHandle, ACPI_ADR_SPACE_SYSTEM_IO,
    823         AeRegionHandler, AeRegionInit, &AeMyContext);
    824     if (ACPI_FAILURE (Status))
    825     {
    826         ACPI_EXCEPTION ((AE_INFO, Status,
    827             "Could not install an OpRegion handler for PCI device (%p)",
    828             ObjHandle));
    829     }
    830 
    831     Status = AcpiInstallAddressSpaceHandler (ObjHandle, ACPI_ADR_SPACE_SYSTEM_MEMORY,
    832         AeRegionHandler, AeRegionInit, &AeMyContext);
    833     if (ACPI_FAILURE (Status))
    834     {
    835         ACPI_EXCEPTION ((AE_INFO, Status,
    836             "Could not install an OpRegion handler for PCI device (%p)",
    837             ObjHandle));
    838     }
    839 
    840     return (AE_CTRL_TERMINATE);
    841 }
    842 
    843 static ACPI_STATUS
    844 AeInstallDeviceHandlers (
    845     void)
    846 {
    847 
    848     /* Find all Embedded Controller devices */
    849 
    850     AcpiGetDevices ("PNP0C09", AeInstallEcHandler, NULL, NULL);
    851 
    852     /* Install a PCI handler */
    853 
    854     AcpiGetDevices ("PNP0A08", AeInstallPciHandler, NULL, NULL);
    855     return (AE_OK);
    856 }
    857 
    858 
    859 /******************************************************************************
    860  *
    861  * FUNCTION:    AeInstallLateHandlers
    862  *
    863  * PARAMETERS:  None
    864  *
    865  * RETURN:      Status
    866  *
    867  * DESCRIPTION: Install handlers for the AcpiExec utility.
    868  *
    869  *****************************************************************************/
    870 
    871 ACPI_STATUS
    872 AeInstallLateHandlers (
    873     void)
    874 {
    875     ACPI_STATUS             Status;
    876     UINT32                  i;
    877 
    878 
    879 #if (!ACPI_REDUCED_HARDWARE)
    880     if (!AcpiGbl_ReducedHardware)
    881     {
    882         /* Install a user SCI handler */
    883 
    884         Status = AeInstallSciHandler ();
    885         AE_CHECK_OK (AeInstallSciHandler, Status);
    886 
    887         /* Install some fixed event handlers */
    888 
    889         Status = AcpiInstallFixedEventHandler (ACPI_EVENT_GLOBAL, AeEventHandler, NULL);
    890         AE_CHECK_OK (AcpiInstallFixedEventHandler, Status);
    891 
    892         Status = AcpiInstallFixedEventHandler (ACPI_EVENT_RTC, AeEventHandler, NULL);
    893         AE_CHECK_OK (AcpiInstallFixedEventHandler, Status);
    894     }
    895 #endif /* !ACPI_REDUCED_HARDWARE */
    896 
    897     AeMyContext.Connection = NULL;
    898     AeMyContext.AccessLength = 0xA5;
    899 
    900     /*
    901      * We will install a handler for each EC device, directly under the EC
    902      * device definition. This is unlike the other handlers which we install
    903      * at the root node. Also install memory and I/O handlers at any PCI
    904      * devices.
    905      */
    906     AeInstallDeviceHandlers ();
    907 
    908     /*
    909      * Install handlers for some of the "device driver" address spaces
    910      * such as SMBus, etc.
    911      */
    912     for (i = 0; i < ACPI_ARRAY_LENGTH (SpaceIdList); i++)
    913     {
    914         /* Install handler at the root object */
    915 
    916         Status = AcpiInstallAddressSpaceHandler (ACPI_ROOT_OBJECT,
    917                     SpaceIdList[i], AeRegionHandler,
    918                     AeRegionInit, &AeMyContext);
    919         if (ACPI_FAILURE (Status))
    920         {
    921             ACPI_EXCEPTION ((AE_INFO, Status,
    922                 "Could not install an OpRegion handler for %s space(%u)",
    923                 AcpiUtGetRegionName((UINT8) SpaceIdList[i]), SpaceIdList[i]));
    924             return (Status);
    925         }
    926     }
    927 
    928     return (AE_OK);
    929 }
    930 
    931 
    932 /******************************************************************************
    933  *
    934  * FUNCTION:    AeInstallEarlyHandlers
    935  *
    936  * PARAMETERS:  None
    937  *
    938  * RETURN:      Status
    939  *
    940  * DESCRIPTION: Install handlers for the AcpiExec utility.
    941  *
    942  * Notes:       Don't install handler for PCI_Config, we want to use the
    943  *              default handler to exercise that code.
    944  *
    945  *****************************************************************************/
    946 
    947 ACPI_STATUS
    948 AeInstallEarlyHandlers (
    949     void)
    950 {
    951     ACPI_STATUS             Status;
    952     UINT32                  i;
    953     ACPI_HANDLE             Handle;
    954 
    955 
    956     ACPI_FUNCTION_ENTRY ();
    957 
    958 
    959     Status = AcpiInstallInterfaceHandler (AeInterfaceHandler);
    960     if (ACPI_FAILURE (Status))
    961     {
    962         printf ("Could not install interface handler, %s\n",
    963             AcpiFormatException (Status));
    964     }
    965 
    966     Status = AcpiInstallTableHandler (AeTableHandler, NULL);
    967     if (ACPI_FAILURE (Status))
    968     {
    969         printf ("Could not install table handler, %s\n",
    970             AcpiFormatException (Status));
    971     }
    972 
    973     Status = AcpiInstallExceptionHandler (AeExceptionHandler);
    974     if (ACPI_FAILURE (Status))
    975     {
    976         printf ("Could not install exception handler, %s\n",
    977             AcpiFormatException (Status));
    978     }
    979 
    980     /* Install global notify handlers */
    981 
    982     Status = AcpiInstallNotifyHandler (ACPI_ROOT_OBJECT, ACPI_SYSTEM_NOTIFY,
    983         AeSystemNotifyHandler, NULL);
    984     if (ACPI_FAILURE (Status))
    985     {
    986         printf ("Could not install a global system notify handler, %s\n",
    987             AcpiFormatException (Status));
    988     }
    989 
    990     Status = AcpiInstallNotifyHandler (ACPI_ROOT_OBJECT, ACPI_DEVICE_NOTIFY,
    991         AeDeviceNotifyHandler, NULL);
    992     if (ACPI_FAILURE (Status))
    993     {
    994         printf ("Could not install a global notify handler, %s\n",
    995             AcpiFormatException (Status));
    996     }
    997 
    998     Status = AcpiGetHandle (NULL, "\\_SB", &Handle);
    999     if (ACPI_SUCCESS (Status))
   1000     {
   1001         Status = AcpiInstallNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY,
   1002             AeNotifyHandler1, NULL);
   1003         if (ACPI_FAILURE (Status))
   1004         {
   1005             printf ("Could not install a notify handler, %s\n",
   1006                 AcpiFormatException (Status));
   1007         }
   1008 
   1009         Status = AcpiRemoveNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY,
   1010             AeNotifyHandler1);
   1011         if (ACPI_FAILURE (Status))
   1012         {
   1013             printf ("Could not remove a notify handler, %s\n",
   1014                 AcpiFormatException (Status));
   1015         }
   1016 
   1017         Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
   1018             AeNotifyHandler1, NULL);
   1019         AE_CHECK_OK (AcpiInstallNotifyHandler, Status);
   1020 
   1021         Status = AcpiRemoveNotifyHandler (Handle, ACPI_ALL_NOTIFY,
   1022             AeNotifyHandler1);
   1023         AE_CHECK_OK (AcpiRemoveNotifyHandler, Status);
   1024 
   1025 #if 0
   1026         Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
   1027             AeNotifyHandler1, NULL);
   1028         if (ACPI_FAILURE (Status))
   1029         {
   1030             printf ("Could not install a notify handler, %s\n",
   1031                 AcpiFormatException (Status));
   1032         }
   1033 #endif
   1034 
   1035         /* Install two handlers for _SB_ */
   1036 
   1037         Status = AcpiInstallNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY,
   1038             AeNotifyHandler1, ACPI_CAST_PTR (void, 0x01234567));
   1039 
   1040         Status = AcpiInstallNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY,
   1041             AeNotifyHandler2, ACPI_CAST_PTR (void, 0x89ABCDEF));
   1042 
   1043         /* Attempt duplicate handler installation, should fail */
   1044 
   1045         Status = AcpiInstallNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY,
   1046             AeNotifyHandler1, ACPI_CAST_PTR (void, 0x77777777));
   1047 
   1048         Status = AcpiAttachData (Handle, AeAttachedDataHandler, Handle);
   1049         AE_CHECK_OK (AcpiAttachData, Status);
   1050 
   1051         Status = AcpiDetachData (Handle, AeAttachedDataHandler);
   1052         AE_CHECK_OK (AcpiDetachData, Status);
   1053 
   1054         Status = AcpiAttachData (Handle, AeAttachedDataHandler, Handle);
   1055         AE_CHECK_OK (AcpiAttachData, Status);
   1056 
   1057         /* Test support for multiple attaches */
   1058 
   1059         Status = AcpiAttachData (Handle, AeAttachedDataHandler2, Handle);
   1060         AE_CHECK_OK (AcpiAttachData, Status);
   1061     }
   1062     else
   1063     {
   1064         printf ("No _SB_ found, %s\n", AcpiFormatException (Status));
   1065     }
   1066 
   1067 
   1068     Status = AcpiGetHandle (NULL, "\\_TZ.TZ1", &Handle);
   1069     if (ACPI_SUCCESS (Status))
   1070     {
   1071         Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
   1072             AeNotifyHandler1, ACPI_CAST_PTR (void, 0x01234567));
   1073 
   1074         Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
   1075             AeNotifyHandler2, ACPI_CAST_PTR (void, 0x89ABCDEF));
   1076 
   1077         Status = AcpiRemoveNotifyHandler (Handle, ACPI_ALL_NOTIFY,
   1078             AeNotifyHandler1);
   1079         Status = AcpiRemoveNotifyHandler (Handle, ACPI_ALL_NOTIFY,
   1080             AeNotifyHandler2);
   1081 
   1082         Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
   1083             AeNotifyHandler2, ACPI_CAST_PTR (void, 0x89ABCDEF));
   1084 
   1085         Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
   1086             AeNotifyHandler1, ACPI_CAST_PTR (void, 0x01234567));
   1087     }
   1088 
   1089     Status = AcpiGetHandle (NULL, "\\_PR.CPU0", &Handle);
   1090     if (ACPI_SUCCESS (Status))
   1091     {
   1092         Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY,
   1093             AeNotifyHandler1, ACPI_CAST_PTR (void, 0x01234567));
   1094 
   1095         Status = AcpiInstallNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY,
   1096             AeNotifyHandler2, ACPI_CAST_PTR (void, 0x89ABCDEF));
   1097     }
   1098 
   1099     /*
   1100      * Install handlers that will override the default handlers for some of
   1101      * the space IDs.
   1102      */
   1103     for (i = 0; i < ACPI_ARRAY_LENGTH (DefaultSpaceIdList); i++)
   1104     {
   1105         /* Install handler at the root object */
   1106 
   1107         Status = AcpiInstallAddressSpaceHandler (ACPI_ROOT_OBJECT,
   1108                     DefaultSpaceIdList[i], AeRegionHandler,
   1109                     AeRegionInit, &AeMyContext);
   1110         if (ACPI_FAILURE (Status))
   1111         {
   1112             ACPI_EXCEPTION ((AE_INFO, Status,
   1113                 "Could not install a default OpRegion handler for %s space(%u)",
   1114                 AcpiUtGetRegionName ((UINT8) DefaultSpaceIdList[i]),
   1115                 DefaultSpaceIdList[i]));
   1116             return (Status);
   1117         }
   1118     }
   1119 
   1120     /*
   1121      * Initialize the global Region Handler space
   1122      * MCW 3/23/00
   1123      */
   1124     AeRegions.NumberOfRegions = 0;
   1125     AeRegions.RegionList = NULL;
   1126     return (Status);
   1127 }
   1128 
   1129 
   1130 /******************************************************************************
   1131  *
   1132  * FUNCTION:    AeRegionHandler
   1133  *
   1134  * PARAMETERS:  Standard region handler parameters
   1135  *
   1136  * RETURN:      Status
   1137  *
   1138  * DESCRIPTION: Test handler - Handles some dummy regions via memory that can
   1139  *              be manipulated in Ring 3. Simulates actual reads and writes.
   1140  *
   1141  *****************************************************************************/
   1142 
   1143 ACPI_STATUS
   1144 AeRegionHandler (
   1145     UINT32                  Function,
   1146     ACPI_PHYSICAL_ADDRESS   Address,
   1147     UINT32                  BitWidth,
   1148     UINT64                  *Value,
   1149     void                    *HandlerContext,
   1150     void                    *RegionContext)
   1151 {
   1152 
   1153     ACPI_OPERAND_OBJECT     *RegionObject = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, RegionContext);
   1154     UINT8                   *Buffer = ACPI_CAST_PTR (UINT8, Value);
   1155     ACPI_PHYSICAL_ADDRESS   BaseAddress;
   1156     ACPI_SIZE               Length;
   1157     BOOLEAN                 BufferExists;
   1158     AE_REGION               *RegionElement;
   1159     void                    *BufferValue;
   1160     ACPI_STATUS             Status;
   1161     UINT32                  ByteWidth;
   1162     UINT32                  i;
   1163     UINT8                   SpaceId;
   1164     ACPI_CONNECTION_INFO    *MyContext;
   1165     UINT32                  Value1;
   1166     UINT32                  Value2;
   1167     ACPI_RESOURCE           *Resource;
   1168 
   1169 
   1170     ACPI_FUNCTION_NAME (AeRegionHandler);
   1171 
   1172     /*
   1173      * If the object is not a region, simply return
   1174      */
   1175     if (RegionObject->Region.Type != ACPI_TYPE_REGION)
   1176     {
   1177         return (AE_OK);
   1178     }
   1179 
   1180     /* Check that we actually got back our context parameter */
   1181 
   1182     if (HandlerContext != &AeMyContext)
   1183     {
   1184         printf ("Region handler received incorrect context %p, should be %p\n",
   1185             HandlerContext, &AeMyContext);
   1186     }
   1187 
   1188     MyContext = ACPI_CAST_PTR (ACPI_CONNECTION_INFO, HandlerContext);
   1189 
   1190     /*
   1191      * Find the region's address space and length before searching
   1192      * the linked list.
   1193      */
   1194     BaseAddress = RegionObject->Region.Address;
   1195     Length = (ACPI_SIZE) RegionObject->Region.Length;
   1196     SpaceId = RegionObject->Region.SpaceId;
   1197 
   1198     ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, "Operation Region request on %s at 0x%X\n",
   1199             AcpiUtGetRegionName (RegionObject->Region.SpaceId),
   1200             (UINT32) Address));
   1201 
   1202     /*
   1203      * Region support can be disabled with the -do option.
   1204      * We use this to support dynamically loaded tables where we pass a valid
   1205      * address to the AML.
   1206      */
   1207     if (AcpiGbl_DbOpt_NoRegionSupport)
   1208     {
   1209         BufferValue = ACPI_TO_POINTER (Address);
   1210         ByteWidth = (BitWidth / 8);
   1211 
   1212         if (BitWidth % 8)
   1213         {
   1214             ByteWidth += 1;
   1215         }
   1216         goto DoFunction;
   1217     }
   1218 
   1219     switch (SpaceId)
   1220     {
   1221     case ACPI_ADR_SPACE_SYSTEM_IO:
   1222         /*
   1223          * For I/O space, exercise the port validation
   1224          * Note: ReadPort currently always returns all ones, length=BitLength
   1225          */
   1226         switch (Function & ACPI_IO_MASK)
   1227         {
   1228         case ACPI_READ:
   1229 
   1230             if (BitWidth == 64)
   1231             {
   1232                 /* Split the 64-bit request into two 32-bit requests */
   1233 
   1234                 Status = AcpiHwReadPort (Address, &Value1, 32);
   1235                 AE_CHECK_OK (AcpiHwReadPort, Status);
   1236                 Status = AcpiHwReadPort (Address+4, &Value2, 32);
   1237                 AE_CHECK_OK (AcpiHwReadPort, Status);
   1238 
   1239                 *Value = Value1 | ((UINT64) Value2 << 32);
   1240             }
   1241             else
   1242             {
   1243                 Status = AcpiHwReadPort (Address, &Value1, BitWidth);
   1244                 AE_CHECK_OK (AcpiHwReadPort, Status);
   1245                 *Value = (UINT64) Value1;
   1246             }
   1247             break;
   1248 
   1249         case ACPI_WRITE:
   1250 
   1251             if (BitWidth == 64)
   1252             {
   1253                 /* Split the 64-bit request into two 32-bit requests */
   1254 
   1255                 Status = AcpiHwWritePort (Address, ACPI_LODWORD (*Value), 32);
   1256                 AE_CHECK_OK (AcpiHwWritePort, Status);
   1257                 Status = AcpiHwWritePort (Address+4, ACPI_HIDWORD (*Value), 32);
   1258                 AE_CHECK_OK (AcpiHwWritePort, Status);
   1259             }
   1260             else
   1261             {
   1262                 Status = AcpiHwWritePort (Address, (UINT32) *Value, BitWidth);
   1263                 AE_CHECK_OK (AcpiHwWritePort, Status);
   1264             }
   1265             break;
   1266 
   1267         default:
   1268 
   1269             Status = AE_BAD_PARAMETER;
   1270             break;
   1271         }
   1272 
   1273         if (ACPI_FAILURE (Status))
   1274         {
   1275             return (Status);
   1276         }
   1277 
   1278         /* Now go ahead and simulate the hardware */
   1279         break;
   1280 
   1281     /*
   1282      * SMBus and GenericSerialBus support the various bidirectional
   1283      * protocols.
   1284      */
   1285     case ACPI_ADR_SPACE_SMBUS:
   1286     case ACPI_ADR_SPACE_GSBUS:  /* ACPI 5.0 */
   1287 
   1288         Length = 0;
   1289 
   1290         switch (Function & ACPI_IO_MASK)
   1291         {
   1292         case ACPI_READ:
   1293 
   1294             switch (Function >> 16)
   1295             {
   1296             case AML_FIELD_ATTRIB_QUICK:
   1297             case AML_FIELD_ATTRIB_SEND_RCV:
   1298             case AML_FIELD_ATTRIB_BYTE:
   1299 
   1300                 Length = 1;
   1301                 break;
   1302 
   1303             case AML_FIELD_ATTRIB_WORD:
   1304             case AML_FIELD_ATTRIB_WORD_CALL:
   1305 
   1306                 Length = 2;
   1307                 break;
   1308 
   1309             case AML_FIELD_ATTRIB_BLOCK:
   1310             case AML_FIELD_ATTRIB_BLOCK_CALL:
   1311 
   1312                 Length = 32;
   1313                 break;
   1314 
   1315             case AML_FIELD_ATTRIB_MULTIBYTE:
   1316             case AML_FIELD_ATTRIB_RAW_BYTES:
   1317             case AML_FIELD_ATTRIB_RAW_PROCESS:
   1318 
   1319                 /* (-2) for status/length */
   1320                 Length = MyContext->AccessLength - 2;
   1321                 break;
   1322 
   1323             default:
   1324 
   1325                 break;
   1326             }
   1327             break;
   1328 
   1329         case ACPI_WRITE:
   1330 
   1331             switch (Function >> 16)
   1332             {
   1333             case AML_FIELD_ATTRIB_QUICK:
   1334             case AML_FIELD_ATTRIB_SEND_RCV:
   1335             case AML_FIELD_ATTRIB_BYTE:
   1336             case AML_FIELD_ATTRIB_WORD:
   1337             case AML_FIELD_ATTRIB_BLOCK:
   1338 
   1339                 Length = 0;
   1340                 break;
   1341 
   1342             case AML_FIELD_ATTRIB_WORD_CALL:
   1343                 Length = 2;
   1344                 break;
   1345 
   1346             case AML_FIELD_ATTRIB_BLOCK_CALL:
   1347                 Length = 32;
   1348                 break;
   1349 
   1350             case AML_FIELD_ATTRIB_MULTIBYTE:
   1351             case AML_FIELD_ATTRIB_RAW_BYTES:
   1352             case AML_FIELD_ATTRIB_RAW_PROCESS:
   1353 
   1354                 /* (-2) for status/length */
   1355                 Length = MyContext->AccessLength - 2;
   1356                 break;
   1357 
   1358             default:
   1359 
   1360                 break;
   1361             }
   1362             break;
   1363 
   1364         default:
   1365 
   1366             break;
   1367         }
   1368 
   1369         if (AcpiGbl_DisplayRegionAccess)
   1370         {
   1371             AcpiOsPrintf ("AcpiExec: %s "
   1372                 "%s: Attr %X Addr %.4X BaseAddr %.4X Len %.2X Width %X BufLen %X",
   1373                 AcpiUtGetRegionName (SpaceId),
   1374                 (Function & ACPI_IO_MASK) ? "Write" : "Read ",
   1375                 (UINT32) (Function >> 16),
   1376                 (UINT32) Address, (UINT32) BaseAddress,
   1377                 Length, BitWidth, Buffer[1]);
   1378 
   1379             /* GenericSerialBus has a Connection() parameter */
   1380 
   1381             if (SpaceId == ACPI_ADR_SPACE_GSBUS)
   1382             {
   1383                 Status = AcpiBufferToResource (MyContext->Connection,
   1384                     MyContext->Length, &Resource);
   1385 
   1386                 AcpiOsPrintf (" [AccLen %.2X Conn %p]",
   1387                     MyContext->AccessLength, MyContext->Connection);
   1388             }
   1389             AcpiOsPrintf ("\n");
   1390         }
   1391 
   1392         /* Setup the return buffer. Note: ASLTS depends on these fill values */
   1393 
   1394         for (i = 0; i < Length; i++)
   1395         {
   1396             Buffer[i+2] = (UINT8) (0xA0 + i);
   1397         }
   1398 
   1399         Buffer[0] = 0x7A;
   1400         Buffer[1] = (UINT8) Length;
   1401         return (AE_OK);
   1402 
   1403 
   1404     case ACPI_ADR_SPACE_IPMI: /* ACPI 4.0 */
   1405 
   1406         if (AcpiGbl_DisplayRegionAccess)
   1407         {
   1408             AcpiOsPrintf ("AcpiExec: IPMI "
   1409                 "%s: Attr %X Addr %.4X BaseAddr %.4X Len %.2X Width %X BufLen %X\n",
   1410                 (Function & ACPI_IO_MASK) ? "Write" : "Read ",
   1411                 (UINT32) (Function >> 16), (UINT32) Address, (UINT32) BaseAddress,
   1412                 Length, BitWidth, Buffer[1]);
   1413         }
   1414 
   1415         /*
   1416          * Regardless of a READ or WRITE, this handler is passed a 66-byte
   1417          * buffer in which to return the IPMI status/length/data.
   1418          *
   1419          * Return some example data to show use of the bidirectional buffer
   1420          */
   1421         Buffer[0] = 0;       /* Status byte */
   1422         Buffer[1] = 64;      /* Return buffer data length */
   1423         Buffer[2] = 0;       /* Completion code */
   1424         Buffer[3] = 0;       /* Reserved */
   1425 
   1426         /*
   1427          * Fill the 66-byte buffer with the return data.
   1428          * Note: ASLTS depends on these fill values.
   1429          */
   1430         for (i = 4; i < 66; i++)
   1431         {
   1432             Buffer[i] = (UINT8) (i);
   1433         }
   1434         return (AE_OK);
   1435 
   1436     default:
   1437         break;
   1438     }
   1439 
   1440     /*
   1441      * Search through the linked list for this region's buffer
   1442      */
   1443     BufferExists = FALSE;
   1444     RegionElement = AeRegions.RegionList;
   1445 
   1446     if (AeRegions.NumberOfRegions)
   1447     {
   1448         while (!BufferExists && RegionElement)
   1449         {
   1450             if (RegionElement->Address == BaseAddress &&
   1451                 RegionElement->Length == Length &&
   1452                 RegionElement->SpaceId == SpaceId)
   1453             {
   1454                 BufferExists = TRUE;
   1455             }
   1456             else
   1457             {
   1458                 RegionElement = RegionElement->NextRegion;
   1459             }
   1460         }
   1461     }
   1462 
   1463     /*
   1464      * If the Region buffer does not exist, create it now
   1465      */
   1466     if (!BufferExists)
   1467     {
   1468         /*
   1469          * Do the memory allocations first
   1470          */
   1471         RegionElement = AcpiOsAllocate (sizeof (AE_REGION));
   1472         if (!RegionElement)
   1473         {
   1474             return (AE_NO_MEMORY);
   1475         }
   1476 
   1477         RegionElement->Buffer = AcpiOsAllocate (Length);
   1478         if (!RegionElement->Buffer)
   1479         {
   1480             AcpiOsFree (RegionElement);
   1481             return (AE_NO_MEMORY);
   1482         }
   1483 
   1484         /* Initialize the region with the default fill value */
   1485 
   1486         ACPI_MEMSET (RegionElement->Buffer, AcpiGbl_RegionFillValue, Length);
   1487 
   1488         RegionElement->Address      = BaseAddress;
   1489         RegionElement->Length       = Length;
   1490         RegionElement->SpaceId      = SpaceId;
   1491         RegionElement->NextRegion   = NULL;
   1492 
   1493         /*
   1494          * Increment the number of regions and put this one
   1495          *  at the head of the list as it will probably get accessed
   1496          *  more often anyway.
   1497          */
   1498         AeRegions.NumberOfRegions += 1;
   1499 
   1500         if (AeRegions.RegionList)
   1501         {
   1502             RegionElement->NextRegion = AeRegions.RegionList;
   1503         }
   1504 
   1505         AeRegions.RegionList = RegionElement;
   1506     }
   1507 
   1508     /*
   1509      * Calculate the size of the memory copy
   1510      */
   1511     ByteWidth = (BitWidth / 8);
   1512 
   1513     if (BitWidth % 8)
   1514     {
   1515         ByteWidth += 1;
   1516     }
   1517 
   1518     /*
   1519      * The buffer exists and is pointed to by RegionElement.
   1520      * We now need to verify the request is valid and perform the operation.
   1521      *
   1522      * NOTE: RegionElement->Length is in bytes, therefore it we compare against
   1523      * ByteWidth (see above)
   1524      */
   1525     if (((UINT64) Address + ByteWidth) >
   1526         ((UINT64)(RegionElement->Address) + RegionElement->Length))
   1527     {
   1528         ACPI_WARNING ((AE_INFO,
   1529             "Request on [%4.4s] is beyond region limit Req-0x%X+0x%X, Base=0x%X, Len-0x%X",
   1530             (RegionObject->Region.Node)->Name.Ascii, (UINT32) Address,
   1531             ByteWidth, (UINT32)(RegionElement->Address),
   1532             RegionElement->Length));
   1533 
   1534         return (AE_AML_REGION_LIMIT);
   1535     }
   1536 
   1537     /*
   1538      * Get BufferValue to point to the "address" in the buffer
   1539      */
   1540     BufferValue = ((UINT8 *) RegionElement->Buffer +
   1541                     ((UINT64) Address - (UINT64) RegionElement->Address));
   1542 
   1543 DoFunction:
   1544     /*
   1545      * Perform a read or write to the buffer space
   1546      */
   1547     switch (Function)
   1548     {
   1549     case ACPI_READ:
   1550         /*
   1551          * Set the pointer Value to whatever is in the buffer
   1552          */
   1553         ACPI_MEMCPY (Value, BufferValue, ByteWidth);
   1554         break;
   1555 
   1556     case ACPI_WRITE:
   1557         /*
   1558          * Write the contents of Value to the buffer
   1559          */
   1560         ACPI_MEMCPY (BufferValue, Value, ByteWidth);
   1561         break;
   1562 
   1563     default:
   1564 
   1565         return (AE_BAD_PARAMETER);
   1566     }
   1567 
   1568     if (AcpiGbl_DisplayRegionAccess)
   1569     {
   1570         switch (SpaceId)
   1571         {
   1572         case ACPI_ADR_SPACE_SYSTEM_MEMORY:
   1573 
   1574             AcpiOsPrintf ("AcpiExec: SystemMemory "
   1575                 "%s: Val %.8X Addr %.4X Width %X [REGION: BaseAddr %.4X Len %.2X]\n",
   1576                 (Function & ACPI_IO_MASK) ? "Write" : "Read ",
   1577                 (UINT32) *Value, (UINT32) Address, BitWidth, (UINT32) BaseAddress, Length);
   1578             break;
   1579 
   1580         case ACPI_ADR_SPACE_GPIO:   /* ACPI 5.0 */
   1581 
   1582             /* This space is required to always be ByteAcc */
   1583 
   1584             Status = AcpiBufferToResource (MyContext->Connection,
   1585                 MyContext->Length, &Resource);
   1586 
   1587             AcpiOsPrintf ("AcpiExec: GeneralPurposeIo "
   1588                 "%s: Val %.8X Addr %.4X BaseAddr %.4X Len %.2X Width %X AccLen %.2X Conn %p\n",
   1589                 (Function & ACPI_IO_MASK) ? "Write" : "Read ", (UINT32) *Value,
   1590                 (UINT32) Address, (UINT32) BaseAddress, Length, BitWidth,
   1591                 MyContext->AccessLength, MyContext->Connection);
   1592             break;
   1593 
   1594         default:
   1595 
   1596             break;
   1597         }
   1598     }
   1599 
   1600     return (AE_OK);
   1601 }
   1602