Home | History | Annotate | Line # | Download | only in acpiexec
aeinstall.c revision 1.1.1.8
      1 /******************************************************************************
      2  *
      3  * Module Name: aeinstall - Installation of operation region handlers
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2023, 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 MERCHANTABILITY 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    ("aeinstall")
     48 
     49 
     50 static ACPI_STATUS
     51 AeRegionInit (
     52     ACPI_HANDLE             RegionHandle,
     53     UINT32                  Function,
     54     void                    *HandlerContext,
     55     void                    **RegionContext);
     56 
     57 static ACPI_STATUS
     58 AeInstallEcHandler (
     59     ACPI_HANDLE             ObjHandle,
     60     UINT32                  Level,
     61     void                    *Context,
     62     void                    **ReturnValue);
     63 
     64 static ACPI_STATUS
     65 AeInstallPciHandler (
     66     ACPI_HANDLE             ObjHandle,
     67     UINT32                  Level,
     68     void                    *Context,
     69     void                    **ReturnValue);
     70 
     71 static ACPI_STATUS
     72 AeInstallGedHandler (
     73     ACPI_HANDLE             ObjHandle,
     74     UINT32                  Level,
     75     void                    *Context,
     76     void                    **ReturnValue);
     77 
     78 
     79 BOOLEAN                     AcpiGbl_DisplayRegionAccess = FALSE;
     80 ACPI_CONNECTION_INFO        AeMyContext;
     81 
     82 
     83 /*
     84  * We will override some of the default region handlers, especially
     85  * the SystemMemory handler, which must be implemented locally.
     86  * These handlers are installed "early" - before any _REG methods
     87  * are executed - since they are special in the sense that the ACPI spec
     88  * declares that they must "always be available". Cannot override the
     89  * DataTable region handler either -- needed for test execution.
     90  *
     91  * NOTE: The local region handler will simulate access to these address
     92  * spaces by creating a memory buffer behind each operation region.
     93  */
     94 static ACPI_ADR_SPACE_TYPE  DefaultSpaceIdList[] =
     95 {
     96     ACPI_ADR_SPACE_SYSTEM_MEMORY,
     97     ACPI_ADR_SPACE_SYSTEM_IO,
     98     ACPI_ADR_SPACE_PCI_CONFIG,
     99     ACPI_ADR_SPACE_EC
    100 };
    101 
    102 /*
    103  * We will install handlers for some of the various address space IDs.
    104  * Test one user-defined address space (used by aslts).
    105  */
    106 #define ACPI_ADR_SPACE_USER_DEFINED1        0x80
    107 #define ACPI_ADR_SPACE_USER_DEFINED2        0xE4
    108 
    109 static ACPI_ADR_SPACE_TYPE  SpaceIdList[] =
    110 {
    111     ACPI_ADR_SPACE_SMBUS,
    112     ACPI_ADR_SPACE_CMOS,
    113     ACPI_ADR_SPACE_PCI_BAR_TARGET,
    114     ACPI_ADR_SPACE_IPMI,
    115     ACPI_ADR_SPACE_GPIO,
    116     ACPI_ADR_SPACE_GSBUS,
    117     ACPI_ADR_SPACE_PLATFORM_COMM,
    118     ACPI_ADR_SPACE_PLATFORM_RT,
    119     ACPI_ADR_SPACE_FIXED_HARDWARE,
    120     ACPI_ADR_SPACE_USER_DEFINED1,
    121     ACPI_ADR_SPACE_USER_DEFINED2
    122 };
    123 
    124 
    125 /******************************************************************************
    126  *
    127  * FUNCTION:    AeRegionInit
    128  *
    129  * PARAMETERS:  Region init handler
    130  *
    131  * RETURN:      Status
    132  *
    133  * DESCRIPTION: Opregion init function.
    134  *
    135  *****************************************************************************/
    136 
    137 static ACPI_STATUS
    138 AeRegionInit (
    139     ACPI_HANDLE                 RegionHandle,
    140     UINT32                      Function,
    141     void                        *HandlerContext,
    142     void                        **RegionContext)
    143 {
    144 
    145     if (Function == ACPI_REGION_DEACTIVATE)
    146     {
    147         *RegionContext = NULL;
    148     }
    149     else
    150     {
    151         *RegionContext = RegionHandle;
    152     }
    153 
    154     return (AE_OK);
    155 }
    156 
    157 
    158 /******************************************************************************
    159  *
    160  * FUNCTION:    AeOverrideRegionHandlers
    161  *
    162  * PARAMETERS:  None
    163  *
    164  * RETURN:      None
    165  *
    166  * DESCRIPTION: Override the default region handlers for memory, i/o, and
    167  *              pci_config. Also install a handler for EC. This is part of
    168  *              the "install early handlers" functionality.
    169  *
    170  *****************************************************************************/
    171 
    172 void
    173 AeOverrideRegionHandlers (
    174     void)
    175 {
    176     UINT32                  i;
    177     ACPI_STATUS             Status;
    178 
    179     /*
    180      * Install handlers that will override the default handlers for some of
    181      * the space IDs.
    182      */
    183     for (i = 0; i < ACPI_ARRAY_LENGTH (DefaultSpaceIdList); i++)
    184     {
    185         /* Install handler at the root object */
    186 
    187         Status = AcpiInstallAddressSpaceHandler (ACPI_ROOT_OBJECT,
    188             DefaultSpaceIdList[i], AeRegionHandler, AeRegionInit,
    189             &AeMyContext);
    190 
    191         if (ACPI_FAILURE (Status))
    192         {
    193             ACPI_EXCEPTION ((AE_INFO, Status,
    194                 "Could not install an OpRegion handler for %s space(%u)",
    195                 AcpiUtGetRegionName ((UINT8) DefaultSpaceIdList[i]),
    196                 DefaultSpaceIdList[i]));
    197         }
    198     }
    199 }
    200 
    201 
    202 /******************************************************************************
    203  *
    204  * FUNCTION:    AeInstallRegionHandlers
    205  *
    206  * PARAMETERS:  None
    207  *
    208  * RETURN:      None
    209  *
    210  * DESCRIPTION: Install handlers for the address spaces other than
    211  *              SystemMemory, SystemIO, and PCI_CONFIG.
    212  *
    213  *****************************************************************************/
    214 
    215 void
    216 AeInstallRegionHandlers (
    217     void)
    218 {
    219     UINT32                  i;
    220     ACPI_STATUS             Status;
    221 
    222 
    223     /*
    224      * Install handlers for some of the "device driver" address spaces
    225      * such as SMBus, etc.
    226      */
    227     for (i = 0; i < ACPI_ARRAY_LENGTH (SpaceIdList); i++)
    228     {
    229         /* Install handler at the root object */
    230 
    231         Status = AcpiInstallAddressSpaceHandler (ACPI_ROOT_OBJECT,
    232             SpaceIdList[i], AeRegionHandler, AeRegionInit,
    233             &AeMyContext);
    234 
    235         if (ACPI_FAILURE (Status))
    236         {
    237             ACPI_EXCEPTION ((AE_INFO, Status,
    238                 "Could not install an OpRegion handler for %s space(%u)",
    239                 AcpiUtGetRegionName((UINT8) SpaceIdList[i]), SpaceIdList[i]));
    240             return;
    241         }
    242     }
    243 }
    244 
    245 /*******************************************************************************
    246  *
    247  * FUNCTION:    AeInstallGedHandler
    248  *
    249  * PARAMETERS:  ACPI_WALK_NAMESPACE callback
    250  *
    251  * RETURN:      Status
    252  *
    253  * DESCRIPTION: Walk entire namespace, install a handler for every GED
    254  *              device found.
    255  *
    256  ******************************************************************************/
    257 static ACPI_STATUS
    258 AeInstallGedHandler (
    259     ACPI_HANDLE             ObjHandle,
    260     UINT32                  Level,
    261     void                    *Context,
    262     void                    **ReturnValue)
    263 {
    264 
    265 	ACPI_BUFFER             ReturnBuffer;
    266 	ACPI_STATUS Status;
    267 	ACPI_RESOURCE *ResourceList;
    268 	ACPI_RESOURCE_EXTENDED_IRQ *extended_irq_rsc;
    269     ACPI_NAMESPACE_NODE     *Node;
    270 	ACPI_NAMESPACE_NODE		*EvtMethodNode;
    271 
    272     ACPI_FUNCTION_ENTRY();
    273 
    274 	/* Obtain the Namespace Node of this GED object handle. */
    275 	Node = AcpiNsValidateHandle (ObjHandle);
    276 	if (!Node)
    277 	{
    278 		return (AE_BAD_PARAMETER);
    279 	}
    280 
    281 	/*
    282 	 * A GED device must have one _EVT method.
    283 	 * Obtain the _EVT method and store it in the global
    284 	 * GED register.
    285 	 */
    286 	Status = AcpiNsSearchOneScope (
    287 		*ACPI_CAST_PTR (ACPI_NAME, METHOD_NAME__EVT),
    288 		Node,
    289 		ACPI_TYPE_METHOD,
    290 		&EvtMethodNode
    291 	);
    292 	if (ACPI_FAILURE (Status))
    293 	{
    294 		AcpiOsPrintf ("Failed to obtain _EVT method for the GED device.\n");
    295 		return Status;
    296 	}
    297 
    298 	ReturnBuffer.Pointer = NULL;
    299     ReturnBuffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
    300 
    301 	Status = AcpiGetCurrentResources (ObjHandle, &ReturnBuffer);
    302 	if (ACPI_FAILURE (Status))
    303 	{
    304 		AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n",
    305 			AcpiFormatException (Status));
    306 		return Status;
    307 	}
    308 
    309 	/* Traverse the _CRS resource list */
    310 	ResourceList = ACPI_CAST_PTR (ACPI_RESOURCE, ReturnBuffer.Pointer);
    311 	while (ResourceList->Type != ACPI_RESOURCE_TYPE_END_TAG) {
    312 
    313 		switch (ResourceList->Type) {
    314 		 case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: {
    315 
    316 			/*
    317 			 * Found an Interrupt resource. Link the interrupt resource
    318 			 * and the _EVT method of this GED device in the GED event handler list.
    319 			 */
    320 			ACPI_GED_HANDLER_INFO *GedHandler =
    321 			ACPI_ALLOCATE (sizeof (ACPI_SCI_HANDLER_INFO));
    322 			if (!GedHandler)
    323 			{
    324 				return AE_NO_MEMORY;
    325 			}
    326 
    327 			GedHandler->Next = AcpiGbl_GedHandlerList;
    328 			AcpiGbl_GedHandlerList = GedHandler;
    329 
    330 			extended_irq_rsc = &ResourceList->Data.ExtendedIrq;
    331 
    332 			GedHandler->IntId = extended_irq_rsc->Interrupts[0];
    333 			GedHandler->EvtMethod = EvtMethodNode;
    334 
    335 			AcpiOsPrintf ("Interrupt ID %d\n", extended_irq_rsc->Interrupts[0]);
    336 
    337 			break;
    338 		 }
    339 		 default:
    340 
    341 			AcpiOsPrintf ("Resource type %X\n", ResourceList->Type);
    342 		}
    343 
    344 		ResourceList = ACPI_NEXT_RESOURCE (ResourceList);
    345 	}
    346 
    347 	return AE_OK;
    348 }
    349 
    350 /*******************************************************************************
    351  *
    352  * FUNCTION:    AeInstallDeviceHandlers
    353  *
    354  * PARAMETERS:  None
    355  *
    356  * RETURN:      Status
    357  *
    358  * DESCRIPTION: Install handlers for all EC, PCI and GED devices in the namespace
    359  *
    360  ******************************************************************************/
    361 
    362 ACPI_STATUS
    363 AeInstallDeviceHandlers (
    364     void)
    365 {
    366 
    367     /* Find all Embedded Controller devices */
    368 
    369     AcpiGetDevices ("PNP0C09", AeInstallEcHandler, NULL, NULL);
    370 
    371     /* Install a PCI handler */
    372 
    373     AcpiGetDevices ("PNP0A08", AeInstallPciHandler, NULL, NULL);
    374 
    375     /* Install a GED handler */
    376 
    377     AcpiGetDevices ("ACPI0013", AeInstallGedHandler, NULL, NULL);
    378 
    379     return (AE_OK);
    380 }
    381 
    382 
    383 /*******************************************************************************
    384  *
    385  * FUNCTION:    AeInstallEcHandler
    386  *
    387  * PARAMETERS:  ACPI_WALK_NAMESPACE callback
    388  *
    389  * RETURN:      Status
    390  *
    391  * DESCRIPTION: Walk entire namespace, install a handler for every EC
    392  *              device found.
    393  *
    394  ******************************************************************************/
    395 
    396 static ACPI_STATUS
    397 AeInstallEcHandler (
    398     ACPI_HANDLE             ObjHandle,
    399     UINT32                  Level,
    400     void                    *Context,
    401     void                    **ReturnValue)
    402 {
    403     ACPI_STATUS             Status;
    404 
    405 
    406     /* Install the handler for this EC device */
    407 
    408     Status = AcpiInstallAddressSpaceHandler (ObjHandle,
    409         ACPI_ADR_SPACE_EC, AeRegionHandler, AeRegionInit, &AeMyContext);
    410     if (ACPI_FAILURE (Status))
    411     {
    412         ACPI_EXCEPTION ((AE_INFO, Status,
    413             "Could not install an OpRegion handler for EC device (%p)",
    414             ObjHandle));
    415     }
    416 
    417     return (Status);
    418 }
    419 
    420 
    421 /*******************************************************************************
    422  *
    423  * FUNCTION:    AeInstallPciHandler
    424  *
    425  * PARAMETERS:  ACPI_WALK_NAMESPACE callback
    426  *
    427  * RETURN:      Status
    428  *
    429  * DESCRIPTION: Walk entire namespace, install a handler for every PCI
    430  *              device found.
    431  *
    432  ******************************************************************************/
    433 
    434 static ACPI_STATUS
    435 AeInstallPciHandler (
    436     ACPI_HANDLE             ObjHandle,
    437     UINT32                  Level,
    438     void                    *Context,
    439     void                    **ReturnValue)
    440 {
    441     ACPI_STATUS             Status;
    442 
    443 
    444     /* Install memory and I/O handlers for the PCI device */
    445 
    446     Status = AcpiInstallAddressSpaceHandler (ObjHandle,
    447         ACPI_ADR_SPACE_SYSTEM_IO, AeRegionHandler, AeRegionInit,
    448         &AeMyContext);
    449     if (ACPI_FAILURE (Status))
    450     {
    451         ACPI_EXCEPTION ((AE_INFO, Status,
    452             "Could not install an OpRegion handler for PCI device (%p)",
    453             ObjHandle));
    454     }
    455 
    456     Status = AcpiInstallAddressSpaceHandler (ObjHandle,
    457         ACPI_ADR_SPACE_SYSTEM_MEMORY, AeRegionHandler, AeRegionInit,
    458         &AeMyContext);
    459     if (ACPI_FAILURE (Status))
    460     {
    461         ACPI_EXCEPTION ((AE_INFO, Status,
    462             "Could not install an OpRegion handler for PCI device (%p)",
    463             ObjHandle));
    464     }
    465 
    466     return (AE_CTRL_TERMINATE);
    467 }
    468