Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
0002 /******************************************************************************
0003  *
0004  * Module Name: evhandler - Support for Address Space handlers
0005  *
0006  * Copyright (C) 2000 - 2022, Intel Corp.
0007  *
0008  *****************************************************************************/
0009 
0010 #include <acpi/acpi.h>
0011 #include "accommon.h"
0012 #include "acevents.h"
0013 #include "acnamesp.h"
0014 #include "acinterp.h"
0015 
0016 #define _COMPONENT          ACPI_EVENTS
0017 ACPI_MODULE_NAME("evhandler")
0018 
0019 /* Local prototypes */
0020 static acpi_status
0021 acpi_ev_install_handler(acpi_handle obj_handle,
0022             u32 level, void *context, void **return_value);
0023 
0024 /* These are the address spaces that will get default handlers */
0025 
0026 u8 acpi_gbl_default_address_spaces[ACPI_NUM_DEFAULT_SPACES] = {
0027     ACPI_ADR_SPACE_SYSTEM_MEMORY,
0028     ACPI_ADR_SPACE_SYSTEM_IO,
0029     ACPI_ADR_SPACE_PCI_CONFIG,
0030     ACPI_ADR_SPACE_DATA_TABLE
0031 };
0032 
0033 /*******************************************************************************
0034  *
0035  * FUNCTION:    acpi_ev_install_region_handlers
0036  *
0037  * PARAMETERS:  None
0038  *
0039  * RETURN:      Status
0040  *
0041  * DESCRIPTION: Installs the core subsystem default address space handlers.
0042  *
0043  ******************************************************************************/
0044 
0045 acpi_status acpi_ev_install_region_handlers(void)
0046 {
0047     acpi_status status;
0048     u32 i;
0049 
0050     ACPI_FUNCTION_TRACE(ev_install_region_handlers);
0051 
0052     status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
0053     if (ACPI_FAILURE(status)) {
0054         return_ACPI_STATUS(status);
0055     }
0056 
0057     /*
0058      * All address spaces (PCI Config, EC, SMBus) are scope dependent and
0059      * registration must occur for a specific device.
0060      *
0061      * In the case of the system memory and IO address spaces there is
0062      * currently no device associated with the address space. For these we
0063      * use the root.
0064      *
0065      * We install the default PCI config space handler at the root so that
0066      * this space is immediately available even though the we have not
0067      * enumerated all the PCI Root Buses yet. This is to conform to the ACPI
0068      * specification which states that the PCI config space must be always
0069      * available -- even though we are nowhere near ready to find the PCI root
0070      * buses at this point.
0071      *
0072      * NOTE: We ignore AE_ALREADY_EXISTS because this means that a handler
0073      * has already been installed (via acpi_install_address_space_handler).
0074      * Similar for AE_SAME_HANDLER.
0075      */
0076     for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) {
0077         status = acpi_ev_install_space_handler(acpi_gbl_root_node,
0078                                acpi_gbl_default_address_spaces
0079                                [i],
0080                                ACPI_DEFAULT_HANDLER,
0081                                NULL, NULL);
0082         switch (status) {
0083         case AE_OK:
0084         case AE_SAME_HANDLER:
0085         case AE_ALREADY_EXISTS:
0086 
0087             /* These exceptions are all OK */
0088 
0089             status = AE_OK;
0090             break;
0091 
0092         default:
0093 
0094             goto unlock_and_exit;
0095         }
0096     }
0097 
0098 unlock_and_exit:
0099     (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
0100     return_ACPI_STATUS(status);
0101 }
0102 
0103 /*******************************************************************************
0104  *
0105  * FUNCTION:    acpi_ev_has_default_handler
0106  *
0107  * PARAMETERS:  node                - Namespace node for the device
0108  *              space_id            - The address space ID
0109  *
0110  * RETURN:      TRUE if default handler is installed, FALSE otherwise
0111  *
0112  * DESCRIPTION: Check if the default handler is installed for the requested
0113  *              space ID.
0114  *
0115  ******************************************************************************/
0116 
0117 u8
0118 acpi_ev_has_default_handler(struct acpi_namespace_node *node,
0119                 acpi_adr_space_type space_id)
0120 {
0121     union acpi_operand_object *obj_desc;
0122     union acpi_operand_object *handler_obj;
0123 
0124     /* Must have an existing internal object */
0125 
0126     obj_desc = acpi_ns_get_attached_object(node);
0127     if (obj_desc) {
0128         handler_obj = obj_desc->common_notify.handler;
0129 
0130         /* Walk the linked list of handlers for this object */
0131 
0132         while (handler_obj) {
0133             if (handler_obj->address_space.space_id == space_id) {
0134                 if (handler_obj->address_space.handler_flags &
0135                     ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) {
0136                     return (TRUE);
0137                 }
0138             }
0139 
0140             handler_obj = handler_obj->address_space.next;
0141         }
0142     }
0143 
0144     return (FALSE);
0145 }
0146 
0147 /*******************************************************************************
0148  *
0149  * FUNCTION:    acpi_ev_install_handler
0150  *
0151  * PARAMETERS:  walk_namespace callback
0152  *
0153  * DESCRIPTION: This routine installs an address handler into objects that are
0154  *              of type Region or Device.
0155  *
0156  *              If the Object is a Device, and the device has a handler of
0157  *              the same type then the search is terminated in that branch.
0158  *
0159  *              This is because the existing handler is closer in proximity
0160  *              to any more regions than the one we are trying to install.
0161  *
0162  ******************************************************************************/
0163 
0164 static acpi_status
0165 acpi_ev_install_handler(acpi_handle obj_handle,
0166             u32 level, void *context, void **return_value)
0167 {
0168     union acpi_operand_object *handler_obj;
0169     union acpi_operand_object *next_handler_obj;
0170     union acpi_operand_object *obj_desc;
0171     struct acpi_namespace_node *node;
0172     acpi_status status;
0173 
0174     ACPI_FUNCTION_NAME(ev_install_handler);
0175 
0176     handler_obj = (union acpi_operand_object *)context;
0177 
0178     /* Parameter validation */
0179 
0180     if (!handler_obj) {
0181         return (AE_OK);
0182     }
0183 
0184     /* Convert and validate the device handle */
0185 
0186     node = acpi_ns_validate_handle(obj_handle);
0187     if (!node) {
0188         return (AE_BAD_PARAMETER);
0189     }
0190 
0191     /*
0192      * We only care about regions and objects that are allowed to have
0193      * address space handlers
0194      */
0195     if ((node->type != ACPI_TYPE_DEVICE) &&
0196         (node->type != ACPI_TYPE_REGION) && (node != acpi_gbl_root_node)) {
0197         return (AE_OK);
0198     }
0199 
0200     /* Check for an existing internal object */
0201 
0202     obj_desc = acpi_ns_get_attached_object(node);
0203     if (!obj_desc) {
0204 
0205         /* No object, just exit */
0206 
0207         return (AE_OK);
0208     }
0209 
0210     /* Devices are handled different than regions */
0211 
0212     if (obj_desc->common.type == ACPI_TYPE_DEVICE) {
0213 
0214         /* Check if this Device already has a handler for this address space */
0215 
0216         next_handler_obj =
0217             acpi_ev_find_region_handler(handler_obj->address_space.
0218                         space_id,
0219                         obj_desc->common_notify.
0220                         handler);
0221         if (next_handler_obj) {
0222 
0223             /* Found a handler, is it for the same address space? */
0224 
0225             ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
0226                       "Found handler for region [%s] in device %p(%p) handler %p\n",
0227                       acpi_ut_get_region_name(handler_obj->
0228                                   address_space.
0229                                   space_id),
0230                       obj_desc, next_handler_obj,
0231                       handler_obj));
0232 
0233             /*
0234              * Since the object we found it on was a device, then it means
0235              * that someone has already installed a handler for the branch
0236              * of the namespace from this device on. Just bail out telling
0237              * the walk routine to not traverse this branch. This preserves
0238              * the scoping rule for handlers.
0239              */
0240             return (AE_CTRL_DEPTH);
0241         }
0242 
0243         /*
0244          * As long as the device didn't have a handler for this space we
0245          * don't care about it. We just ignore it and proceed.
0246          */
0247         return (AE_OK);
0248     }
0249 
0250     /* Object is a Region */
0251 
0252     if (obj_desc->region.space_id != handler_obj->address_space.space_id) {
0253 
0254         /* This region is for a different address space, just ignore it */
0255 
0256         return (AE_OK);
0257     }
0258 
0259     /*
0260      * Now we have a region and it is for the handler's address space type.
0261      *
0262      * First disconnect region for any previous handler (if any)
0263      */
0264     acpi_ev_detach_region(obj_desc, FALSE);
0265 
0266     /* Connect the region to the new handler */
0267 
0268     status = acpi_ev_attach_region(handler_obj, obj_desc, FALSE);
0269     return (status);
0270 }
0271 
0272 /*******************************************************************************
0273  *
0274  * FUNCTION:    acpi_ev_find_region_handler
0275  *
0276  * PARAMETERS:  space_id        - The address space ID
0277  *              handler_obj     - Head of the handler object list
0278  *
0279  * RETURN:      Matching handler object. NULL if space ID not matched
0280  *
0281  * DESCRIPTION: Search a handler object list for a match on the address
0282  *              space ID.
0283  *
0284  ******************************************************************************/
0285 
0286 union acpi_operand_object *acpi_ev_find_region_handler(acpi_adr_space_type
0287                                space_id,
0288                                union acpi_operand_object
0289                                *handler_obj)
0290 {
0291 
0292     /* Walk the handler list for this device */
0293 
0294     while (handler_obj) {
0295 
0296         /* Same space_id indicates a handler is installed */
0297 
0298         if (handler_obj->address_space.space_id == space_id) {
0299             return (handler_obj);
0300         }
0301 
0302         /* Next handler object */
0303 
0304         handler_obj = handler_obj->address_space.next;
0305     }
0306 
0307     return (NULL);
0308 }
0309 
0310 /*******************************************************************************
0311  *
0312  * FUNCTION:    acpi_ev_install_space_handler
0313  *
0314  * PARAMETERS:  node            - Namespace node for the device
0315  *              space_id        - The address space ID
0316  *              handler         - Address of the handler
0317  *              setup           - Address of the setup function
0318  *              context         - Value passed to the handler on each access
0319  *
0320  * RETURN:      Status
0321  *
0322  * DESCRIPTION: Install a handler for all op_regions of a given space_id.
0323  *              Assumes namespace is locked
0324  *
0325  ******************************************************************************/
0326 
0327 acpi_status
0328 acpi_ev_install_space_handler(struct acpi_namespace_node *node,
0329                   acpi_adr_space_type space_id,
0330                   acpi_adr_space_handler handler,
0331                   acpi_adr_space_setup setup, void *context)
0332 {
0333     union acpi_operand_object *obj_desc;
0334     union acpi_operand_object *handler_obj;
0335     acpi_status status = AE_OK;
0336     acpi_object_type type;
0337     u8 flags = 0;
0338 
0339     ACPI_FUNCTION_TRACE(ev_install_space_handler);
0340 
0341     /*
0342      * This registration is valid for only the types below and the root.
0343      * The root node is where the default handlers get installed.
0344      */
0345     if ((node->type != ACPI_TYPE_DEVICE) &&
0346         (node->type != ACPI_TYPE_PROCESSOR) &&
0347         (node->type != ACPI_TYPE_THERMAL) && (node != acpi_gbl_root_node)) {
0348         status = AE_BAD_PARAMETER;
0349         goto unlock_and_exit;
0350     }
0351 
0352     if (handler == ACPI_DEFAULT_HANDLER) {
0353         flags = ACPI_ADDR_HANDLER_DEFAULT_INSTALLED;
0354 
0355         switch (space_id) {
0356         case ACPI_ADR_SPACE_SYSTEM_MEMORY:
0357 
0358             handler = acpi_ex_system_memory_space_handler;
0359             setup = acpi_ev_system_memory_region_setup;
0360             break;
0361 
0362         case ACPI_ADR_SPACE_SYSTEM_IO:
0363 
0364             handler = acpi_ex_system_io_space_handler;
0365             setup = acpi_ev_io_space_region_setup;
0366             break;
0367 #ifdef ACPI_PCI_CONFIGURED
0368         case ACPI_ADR_SPACE_PCI_CONFIG:
0369 
0370             handler = acpi_ex_pci_config_space_handler;
0371             setup = acpi_ev_pci_config_region_setup;
0372             break;
0373 #endif
0374         case ACPI_ADR_SPACE_CMOS:
0375 
0376             handler = acpi_ex_cmos_space_handler;
0377             setup = acpi_ev_cmos_region_setup;
0378             break;
0379 #ifdef ACPI_PCI_CONFIGURED
0380         case ACPI_ADR_SPACE_PCI_BAR_TARGET:
0381 
0382             handler = acpi_ex_pci_bar_space_handler;
0383             setup = acpi_ev_pci_bar_region_setup;
0384             break;
0385 #endif
0386         case ACPI_ADR_SPACE_DATA_TABLE:
0387 
0388             handler = acpi_ex_data_table_space_handler;
0389             setup = acpi_ev_data_table_region_setup;
0390             break;
0391 
0392         default:
0393 
0394             status = AE_BAD_PARAMETER;
0395             goto unlock_and_exit;
0396         }
0397     }
0398 
0399     /* If the caller hasn't specified a setup routine, use the default */
0400 
0401     if (!setup) {
0402         setup = acpi_ev_default_region_setup;
0403     }
0404 
0405     /* Check for an existing internal object */
0406 
0407     obj_desc = acpi_ns_get_attached_object(node);
0408     if (obj_desc) {
0409         /*
0410          * The attached device object already exists. Now make sure
0411          * the handler is not already installed.
0412          */
0413         handler_obj = acpi_ev_find_region_handler(space_id,
0414                               obj_desc->
0415                               common_notify.
0416                               handler);
0417 
0418         if (handler_obj) {
0419             if (handler_obj->address_space.handler == handler) {
0420                 /*
0421                  * It is (relatively) OK to attempt to install the SAME
0422                  * handler twice. This can easily happen with the
0423                  * PCI_Config space.
0424                  */
0425                 status = AE_SAME_HANDLER;
0426                 goto unlock_and_exit;
0427             } else {
0428                 /* A handler is already installed */
0429 
0430                 status = AE_ALREADY_EXISTS;
0431             }
0432 
0433             goto unlock_and_exit;
0434         }
0435     } else {
0436         ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
0437                   "Creating object on Device %p while installing handler\n",
0438                   node));
0439 
0440         /* obj_desc does not exist, create one */
0441 
0442         if (node->type == ACPI_TYPE_ANY) {
0443             type = ACPI_TYPE_DEVICE;
0444         } else {
0445             type = node->type;
0446         }
0447 
0448         obj_desc = acpi_ut_create_internal_object(type);
0449         if (!obj_desc) {
0450             status = AE_NO_MEMORY;
0451             goto unlock_and_exit;
0452         }
0453 
0454         /* Init new descriptor */
0455 
0456         obj_desc->common.type = (u8)type;
0457 
0458         /* Attach the new object to the Node */
0459 
0460         status = acpi_ns_attach_object(node, obj_desc, type);
0461 
0462         /* Remove local reference to the object */
0463 
0464         acpi_ut_remove_reference(obj_desc);
0465 
0466         if (ACPI_FAILURE(status)) {
0467             goto unlock_and_exit;
0468         }
0469     }
0470 
0471     ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
0472               "Installing address handler for region %s(%X) "
0473               "on Device %4.4s %p(%p)\n",
0474               acpi_ut_get_region_name(space_id), space_id,
0475               acpi_ut_get_node_name(node), node, obj_desc));
0476 
0477     /*
0478      * Install the handler
0479      *
0480      * At this point there is no existing handler. Just allocate the object
0481      * for the handler and link it into the list.
0482      */
0483     handler_obj =
0484         acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_ADDRESS_HANDLER);
0485     if (!handler_obj) {
0486         status = AE_NO_MEMORY;
0487         goto unlock_and_exit;
0488     }
0489 
0490     /* Init handler obj */
0491 
0492     status =
0493         acpi_os_create_mutex(&handler_obj->address_space.context_mutex);
0494     if (ACPI_FAILURE(status)) {
0495         acpi_ut_remove_reference(handler_obj);
0496         goto unlock_and_exit;
0497     }
0498 
0499     handler_obj->address_space.space_id = (u8)space_id;
0500     handler_obj->address_space.handler_flags = flags;
0501     handler_obj->address_space.region_list = NULL;
0502     handler_obj->address_space.node = node;
0503     handler_obj->address_space.handler = handler;
0504     handler_obj->address_space.context = context;
0505     handler_obj->address_space.setup = setup;
0506 
0507     /* Install at head of Device.address_space list */
0508 
0509     handler_obj->address_space.next = obj_desc->common_notify.handler;
0510 
0511     /*
0512      * The Device object is the first reference on the handler_obj.
0513      * Each region that uses the handler adds a reference.
0514      */
0515     obj_desc->common_notify.handler = handler_obj;
0516 
0517     /*
0518      * Walk the namespace finding all of the regions this handler will
0519      * manage.
0520      *
0521      * Start at the device and search the branch toward the leaf nodes
0522      * until either the leaf is encountered or a device is detected that
0523      * has an address handler of the same type.
0524      *
0525      * In either case, back up and search down the remainder of the branch
0526      */
0527     status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, node,
0528                     ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
0529                     acpi_ev_install_handler, NULL,
0530                     handler_obj, NULL);
0531 
0532 unlock_and_exit:
0533     return_ACPI_STATUS(status);
0534 }