evhandler.c (14517B)
1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 2/****************************************************************************** 3 * 4 * Module Name: evhandler - Support for Address Space handlers 5 * 6 * Copyright (C) 2000 - 2022, Intel Corp. 7 * 8 *****************************************************************************/ 9 10#include <acpi/acpi.h> 11#include "accommon.h" 12#include "acevents.h" 13#include "acnamesp.h" 14#include "acinterp.h" 15 16#define _COMPONENT ACPI_EVENTS 17ACPI_MODULE_NAME("evhandler") 18 19/* Local prototypes */ 20static acpi_status 21acpi_ev_install_handler(acpi_handle obj_handle, 22 u32 level, void *context, void **return_value); 23 24/* These are the address spaces that will get default handlers */ 25 26u8 acpi_gbl_default_address_spaces[ACPI_NUM_DEFAULT_SPACES] = { 27 ACPI_ADR_SPACE_SYSTEM_MEMORY, 28 ACPI_ADR_SPACE_SYSTEM_IO, 29 ACPI_ADR_SPACE_PCI_CONFIG, 30 ACPI_ADR_SPACE_DATA_TABLE 31}; 32 33/******************************************************************************* 34 * 35 * FUNCTION: acpi_ev_install_region_handlers 36 * 37 * PARAMETERS: None 38 * 39 * RETURN: Status 40 * 41 * DESCRIPTION: Installs the core subsystem default address space handlers. 42 * 43 ******************************************************************************/ 44 45acpi_status acpi_ev_install_region_handlers(void) 46{ 47 acpi_status status; 48 u32 i; 49 50 ACPI_FUNCTION_TRACE(ev_install_region_handlers); 51 52 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 53 if (ACPI_FAILURE(status)) { 54 return_ACPI_STATUS(status); 55 } 56 57 /* 58 * All address spaces (PCI Config, EC, SMBus) are scope dependent and 59 * registration must occur for a specific device. 60 * 61 * In the case of the system memory and IO address spaces there is 62 * currently no device associated with the address space. For these we 63 * use the root. 64 * 65 * We install the default PCI config space handler at the root so that 66 * this space is immediately available even though the we have not 67 * enumerated all the PCI Root Buses yet. This is to conform to the ACPI 68 * specification which states that the PCI config space must be always 69 * available -- even though we are nowhere near ready to find the PCI root 70 * buses at this point. 71 * 72 * NOTE: We ignore AE_ALREADY_EXISTS because this means that a handler 73 * has already been installed (via acpi_install_address_space_handler). 74 * Similar for AE_SAME_HANDLER. 75 */ 76 for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) { 77 status = acpi_ev_install_space_handler(acpi_gbl_root_node, 78 acpi_gbl_default_address_spaces 79 [i], 80 ACPI_DEFAULT_HANDLER, 81 NULL, NULL); 82 switch (status) { 83 case AE_OK: 84 case AE_SAME_HANDLER: 85 case AE_ALREADY_EXISTS: 86 87 /* These exceptions are all OK */ 88 89 status = AE_OK; 90 break; 91 92 default: 93 94 goto unlock_and_exit; 95 } 96 } 97 98unlock_and_exit: 99 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 100 return_ACPI_STATUS(status); 101} 102 103/******************************************************************************* 104 * 105 * FUNCTION: acpi_ev_has_default_handler 106 * 107 * PARAMETERS: node - Namespace node for the device 108 * space_id - The address space ID 109 * 110 * RETURN: TRUE if default handler is installed, FALSE otherwise 111 * 112 * DESCRIPTION: Check if the default handler is installed for the requested 113 * space ID. 114 * 115 ******************************************************************************/ 116 117u8 118acpi_ev_has_default_handler(struct acpi_namespace_node *node, 119 acpi_adr_space_type space_id) 120{ 121 union acpi_operand_object *obj_desc; 122 union acpi_operand_object *handler_obj; 123 124 /* Must have an existing internal object */ 125 126 obj_desc = acpi_ns_get_attached_object(node); 127 if (obj_desc) { 128 handler_obj = obj_desc->common_notify.handler; 129 130 /* Walk the linked list of handlers for this object */ 131 132 while (handler_obj) { 133 if (handler_obj->address_space.space_id == space_id) { 134 if (handler_obj->address_space.handler_flags & 135 ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) { 136 return (TRUE); 137 } 138 } 139 140 handler_obj = handler_obj->address_space.next; 141 } 142 } 143 144 return (FALSE); 145} 146 147/******************************************************************************* 148 * 149 * FUNCTION: acpi_ev_install_handler 150 * 151 * PARAMETERS: walk_namespace callback 152 * 153 * DESCRIPTION: This routine installs an address handler into objects that are 154 * of type Region or Device. 155 * 156 * If the Object is a Device, and the device has a handler of 157 * the same type then the search is terminated in that branch. 158 * 159 * This is because the existing handler is closer in proximity 160 * to any more regions than the one we are trying to install. 161 * 162 ******************************************************************************/ 163 164static acpi_status 165acpi_ev_install_handler(acpi_handle obj_handle, 166 u32 level, void *context, void **return_value) 167{ 168 union acpi_operand_object *handler_obj; 169 union acpi_operand_object *next_handler_obj; 170 union acpi_operand_object *obj_desc; 171 struct acpi_namespace_node *node; 172 acpi_status status; 173 174 ACPI_FUNCTION_NAME(ev_install_handler); 175 176 handler_obj = (union acpi_operand_object *)context; 177 178 /* Parameter validation */ 179 180 if (!handler_obj) { 181 return (AE_OK); 182 } 183 184 /* Convert and validate the device handle */ 185 186 node = acpi_ns_validate_handle(obj_handle); 187 if (!node) { 188 return (AE_BAD_PARAMETER); 189 } 190 191 /* 192 * We only care about regions and objects that are allowed to have 193 * address space handlers 194 */ 195 if ((node->type != ACPI_TYPE_DEVICE) && 196 (node->type != ACPI_TYPE_REGION) && (node != acpi_gbl_root_node)) { 197 return (AE_OK); 198 } 199 200 /* Check for an existing internal object */ 201 202 obj_desc = acpi_ns_get_attached_object(node); 203 if (!obj_desc) { 204 205 /* No object, just exit */ 206 207 return (AE_OK); 208 } 209 210 /* Devices are handled different than regions */ 211 212 if (obj_desc->common.type == ACPI_TYPE_DEVICE) { 213 214 /* Check if this Device already has a handler for this address space */ 215 216 next_handler_obj = 217 acpi_ev_find_region_handler(handler_obj->address_space. 218 space_id, 219 obj_desc->common_notify. 220 handler); 221 if (next_handler_obj) { 222 223 /* Found a handler, is it for the same address space? */ 224 225 ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, 226 "Found handler for region [%s] in device %p(%p) handler %p\n", 227 acpi_ut_get_region_name(handler_obj-> 228 address_space. 229 space_id), 230 obj_desc, next_handler_obj, 231 handler_obj)); 232 233 /* 234 * Since the object we found it on was a device, then it means 235 * that someone has already installed a handler for the branch 236 * of the namespace from this device on. Just bail out telling 237 * the walk routine to not traverse this branch. This preserves 238 * the scoping rule for handlers. 239 */ 240 return (AE_CTRL_DEPTH); 241 } 242 243 /* 244 * As long as the device didn't have a handler for this space we 245 * don't care about it. We just ignore it and proceed. 246 */ 247 return (AE_OK); 248 } 249 250 /* Object is a Region */ 251 252 if (obj_desc->region.space_id != handler_obj->address_space.space_id) { 253 254 /* This region is for a different address space, just ignore it */ 255 256 return (AE_OK); 257 } 258 259 /* 260 * Now we have a region and it is for the handler's address space type. 261 * 262 * First disconnect region for any previous handler (if any) 263 */ 264 acpi_ev_detach_region(obj_desc, FALSE); 265 266 /* Connect the region to the new handler */ 267 268 status = acpi_ev_attach_region(handler_obj, obj_desc, FALSE); 269 return (status); 270} 271 272/******************************************************************************* 273 * 274 * FUNCTION: acpi_ev_find_region_handler 275 * 276 * PARAMETERS: space_id - The address space ID 277 * handler_obj - Head of the handler object list 278 * 279 * RETURN: Matching handler object. NULL if space ID not matched 280 * 281 * DESCRIPTION: Search a handler object list for a match on the address 282 * space ID. 283 * 284 ******************************************************************************/ 285 286union acpi_operand_object *acpi_ev_find_region_handler(acpi_adr_space_type 287 space_id, 288 union acpi_operand_object 289 *handler_obj) 290{ 291 292 /* Walk the handler list for this device */ 293 294 while (handler_obj) { 295 296 /* Same space_id indicates a handler is installed */ 297 298 if (handler_obj->address_space.space_id == space_id) { 299 return (handler_obj); 300 } 301 302 /* Next handler object */ 303 304 handler_obj = handler_obj->address_space.next; 305 } 306 307 return (NULL); 308} 309 310/******************************************************************************* 311 * 312 * FUNCTION: acpi_ev_install_space_handler 313 * 314 * PARAMETERS: node - Namespace node for the device 315 * space_id - The address space ID 316 * handler - Address of the handler 317 * setup - Address of the setup function 318 * context - Value passed to the handler on each access 319 * 320 * RETURN: Status 321 * 322 * DESCRIPTION: Install a handler for all op_regions of a given space_id. 323 * Assumes namespace is locked 324 * 325 ******************************************************************************/ 326 327acpi_status 328acpi_ev_install_space_handler(struct acpi_namespace_node *node, 329 acpi_adr_space_type space_id, 330 acpi_adr_space_handler handler, 331 acpi_adr_space_setup setup, void *context) 332{ 333 union acpi_operand_object *obj_desc; 334 union acpi_operand_object *handler_obj; 335 acpi_status status = AE_OK; 336 acpi_object_type type; 337 u8 flags = 0; 338 339 ACPI_FUNCTION_TRACE(ev_install_space_handler); 340 341 /* 342 * This registration is valid for only the types below and the root. 343 * The root node is where the default handlers get installed. 344 */ 345 if ((node->type != ACPI_TYPE_DEVICE) && 346 (node->type != ACPI_TYPE_PROCESSOR) && 347 (node->type != ACPI_TYPE_THERMAL) && (node != acpi_gbl_root_node)) { 348 status = AE_BAD_PARAMETER; 349 goto unlock_and_exit; 350 } 351 352 if (handler == ACPI_DEFAULT_HANDLER) { 353 flags = ACPI_ADDR_HANDLER_DEFAULT_INSTALLED; 354 355 switch (space_id) { 356 case ACPI_ADR_SPACE_SYSTEM_MEMORY: 357 358 handler = acpi_ex_system_memory_space_handler; 359 setup = acpi_ev_system_memory_region_setup; 360 break; 361 362 case ACPI_ADR_SPACE_SYSTEM_IO: 363 364 handler = acpi_ex_system_io_space_handler; 365 setup = acpi_ev_io_space_region_setup; 366 break; 367#ifdef ACPI_PCI_CONFIGURED 368 case ACPI_ADR_SPACE_PCI_CONFIG: 369 370 handler = acpi_ex_pci_config_space_handler; 371 setup = acpi_ev_pci_config_region_setup; 372 break; 373#endif 374 case ACPI_ADR_SPACE_CMOS: 375 376 handler = acpi_ex_cmos_space_handler; 377 setup = acpi_ev_cmos_region_setup; 378 break; 379#ifdef ACPI_PCI_CONFIGURED 380 case ACPI_ADR_SPACE_PCI_BAR_TARGET: 381 382 handler = acpi_ex_pci_bar_space_handler; 383 setup = acpi_ev_pci_bar_region_setup; 384 break; 385#endif 386 case ACPI_ADR_SPACE_DATA_TABLE: 387 388 handler = acpi_ex_data_table_space_handler; 389 setup = acpi_ev_data_table_region_setup; 390 break; 391 392 default: 393 394 status = AE_BAD_PARAMETER; 395 goto unlock_and_exit; 396 } 397 } 398 399 /* If the caller hasn't specified a setup routine, use the default */ 400 401 if (!setup) { 402 setup = acpi_ev_default_region_setup; 403 } 404 405 /* Check for an existing internal object */ 406 407 obj_desc = acpi_ns_get_attached_object(node); 408 if (obj_desc) { 409 /* 410 * The attached device object already exists. Now make sure 411 * the handler is not already installed. 412 */ 413 handler_obj = acpi_ev_find_region_handler(space_id, 414 obj_desc-> 415 common_notify. 416 handler); 417 418 if (handler_obj) { 419 if (handler_obj->address_space.handler == handler) { 420 /* 421 * It is (relatively) OK to attempt to install the SAME 422 * handler twice. This can easily happen with the 423 * PCI_Config space. 424 */ 425 status = AE_SAME_HANDLER; 426 goto unlock_and_exit; 427 } else { 428 /* A handler is already installed */ 429 430 status = AE_ALREADY_EXISTS; 431 } 432 433 goto unlock_and_exit; 434 } 435 } else { 436 ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, 437 "Creating object on Device %p while installing handler\n", 438 node)); 439 440 /* obj_desc does not exist, create one */ 441 442 if (node->type == ACPI_TYPE_ANY) { 443 type = ACPI_TYPE_DEVICE; 444 } else { 445 type = node->type; 446 } 447 448 obj_desc = acpi_ut_create_internal_object(type); 449 if (!obj_desc) { 450 status = AE_NO_MEMORY; 451 goto unlock_and_exit; 452 } 453 454 /* Init new descriptor */ 455 456 obj_desc->common.type = (u8)type; 457 458 /* Attach the new object to the Node */ 459 460 status = acpi_ns_attach_object(node, obj_desc, type); 461 462 /* Remove local reference to the object */ 463 464 acpi_ut_remove_reference(obj_desc); 465 466 if (ACPI_FAILURE(status)) { 467 goto unlock_and_exit; 468 } 469 } 470 471 ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, 472 "Installing address handler for region %s(%X) " 473 "on Device %4.4s %p(%p)\n", 474 acpi_ut_get_region_name(space_id), space_id, 475 acpi_ut_get_node_name(node), node, obj_desc)); 476 477 /* 478 * Install the handler 479 * 480 * At this point there is no existing handler. Just allocate the object 481 * for the handler and link it into the list. 482 */ 483 handler_obj = 484 acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_ADDRESS_HANDLER); 485 if (!handler_obj) { 486 status = AE_NO_MEMORY; 487 goto unlock_and_exit; 488 } 489 490 /* Init handler obj */ 491 492 status = 493 acpi_os_create_mutex(&handler_obj->address_space.context_mutex); 494 if (ACPI_FAILURE(status)) { 495 acpi_ut_remove_reference(handler_obj); 496 goto unlock_and_exit; 497 } 498 499 handler_obj->address_space.space_id = (u8)space_id; 500 handler_obj->address_space.handler_flags = flags; 501 handler_obj->address_space.region_list = NULL; 502 handler_obj->address_space.node = node; 503 handler_obj->address_space.handler = handler; 504 handler_obj->address_space.context = context; 505 handler_obj->address_space.setup = setup; 506 507 /* Install at head of Device.address_space list */ 508 509 handler_obj->address_space.next = obj_desc->common_notify.handler; 510 511 /* 512 * The Device object is the first reference on the handler_obj. 513 * Each region that uses the handler adds a reference. 514 */ 515 obj_desc->common_notify.handler = handler_obj; 516 517 /* 518 * Walk the namespace finding all of the regions this handler will 519 * manage. 520 * 521 * Start at the device and search the branch toward the leaf nodes 522 * until either the leaf is encountered or a device is detected that 523 * has an address handler of the same type. 524 * 525 * In either case, back up and search down the remainder of the branch 526 */ 527 status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, 528 ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, 529 acpi_ev_install_handler, NULL, 530 handler_obj, NULL); 531 532unlock_and_exit: 533 return_ACPI_STATUS(status); 534}