1 /******************************************************************************
3 * Module Name: evhandler - Support for Address Space handlers
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2015, Intel Corp.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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.
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.
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.
50 #define _COMPONENT ACPI_EVENTS
51 ACPI_MODULE_NAME ("evhandler")
54 /* Local prototypes */
57 AcpiEvInstallHandler (
58 ACPI_HANDLE ObjHandle,
63 /* These are the address spaces that will get default handlers */
65 UINT8 AcpiGbl_DefaultAddressSpaces[ACPI_NUM_DEFAULT_SPACES] =
67 ACPI_ADR_SPACE_SYSTEM_MEMORY,
68 ACPI_ADR_SPACE_SYSTEM_IO,
69 ACPI_ADR_SPACE_PCI_CONFIG,
70 ACPI_ADR_SPACE_DATA_TABLE
74 /*******************************************************************************
76 * FUNCTION: AcpiEvInstallRegionHandlers
82 * DESCRIPTION: Installs the core subsystem default address space handlers.
84 ******************************************************************************/
87 AcpiEvInstallRegionHandlers (
94 ACPI_FUNCTION_TRACE (EvInstallRegionHandlers);
97 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
98 if (ACPI_FAILURE (Status))
100 return_ACPI_STATUS (Status);
104 * All address spaces (PCI Config, EC, SMBus) are scope dependent and
105 * registration must occur for a specific device.
107 * In the case of the system memory and IO address spaces there is
108 * currently no device associated with the address space. For these we
111 * We install the default PCI config space handler at the root so that
112 * this space is immediately available even though the we have not
113 * enumerated all the PCI Root Buses yet. This is to conform to the ACPI
114 * specification which states that the PCI config space must be always
115 * available -- even though we are nowhere near ready to find the PCI root
116 * buses at this point.
118 * NOTE: We ignore AE_ALREADY_EXISTS because this means that a handler
119 * has already been installed (via AcpiInstallAddressSpaceHandler).
120 * Similar for AE_SAME_HANDLER.
122 for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++)
124 Status = AcpiEvInstallSpaceHandler (AcpiGbl_RootNode,
125 AcpiGbl_DefaultAddressSpaces[i],
126 ACPI_DEFAULT_HANDLER, NULL, NULL);
130 case AE_SAME_HANDLER:
131 case AE_ALREADY_EXISTS:
133 /* These exceptions are all OK */
145 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
146 return_ACPI_STATUS (Status);
150 /*******************************************************************************
152 * FUNCTION: AcpiEvHasDefaultHandler
154 * PARAMETERS: Node - Namespace node for the device
155 * SpaceId - The address space ID
157 * RETURN: TRUE if default handler is installed, FALSE otherwise
159 * DESCRIPTION: Check if the default handler is installed for the requested
162 ******************************************************************************/
165 AcpiEvHasDefaultHandler (
166 ACPI_NAMESPACE_NODE *Node,
167 ACPI_ADR_SPACE_TYPE SpaceId)
169 ACPI_OPERAND_OBJECT *ObjDesc;
170 ACPI_OPERAND_OBJECT *HandlerObj;
173 /* Must have an existing internal object */
175 ObjDesc = AcpiNsGetAttachedObject (Node);
178 HandlerObj = ObjDesc->Device.Handler;
180 /* Walk the linked list of handlers for this object */
184 if (HandlerObj->AddressSpace.SpaceId == SpaceId)
186 if (HandlerObj->AddressSpace.HandlerFlags &
187 ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)
193 HandlerObj = HandlerObj->AddressSpace.Next;
201 /*******************************************************************************
203 * FUNCTION: AcpiEvInstallHandler
205 * PARAMETERS: WalkNamespace callback
207 * DESCRIPTION: This routine installs an address handler into objects that are
208 * of type Region or Device.
210 * If the Object is a Device, and the device has a handler of
211 * the same type then the search is terminated in that branch.
213 * This is because the existing handler is closer in proximity
214 * to any more regions than the one we are trying to install.
216 ******************************************************************************/
219 AcpiEvInstallHandler (
220 ACPI_HANDLE ObjHandle,
225 ACPI_OPERAND_OBJECT *HandlerObj;
226 ACPI_OPERAND_OBJECT *NextHandlerObj;
227 ACPI_OPERAND_OBJECT *ObjDesc;
228 ACPI_NAMESPACE_NODE *Node;
232 ACPI_FUNCTION_NAME (EvInstallHandler);
235 HandlerObj = (ACPI_OPERAND_OBJECT *) Context;
237 /* Parameter validation */
244 /* Convert and validate the device handle */
246 Node = AcpiNsValidateHandle (ObjHandle);
249 return (AE_BAD_PARAMETER);
253 * We only care about regions and objects that are allowed to have
254 * address space handlers
256 if ((Node->Type != ACPI_TYPE_DEVICE) &&
257 (Node->Type != ACPI_TYPE_REGION) &&
258 (Node != AcpiGbl_RootNode))
263 /* Check for an existing internal object */
265 ObjDesc = AcpiNsGetAttachedObject (Node);
268 /* No object, just exit */
273 /* Devices are handled different than regions */
275 if (ObjDesc->Common.Type == ACPI_TYPE_DEVICE)
277 /* Check if this Device already has a handler for this address space */
279 NextHandlerObj = ObjDesc->Device.Handler;
280 while (NextHandlerObj)
282 /* Found a handler, is it for the same address space? */
284 if (NextHandlerObj->AddressSpace.SpaceId ==
285 HandlerObj->AddressSpace.SpaceId)
287 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
288 "Found handler for region [%s] in device %p(%p) "
290 AcpiUtGetRegionName (HandlerObj->AddressSpace.SpaceId),
291 ObjDesc, NextHandlerObj, HandlerObj));
294 * Since the object we found it on was a device, then it
295 * means that someone has already installed a handler for
296 * the branch of the namespace from this device on. Just
297 * bail out telling the walk routine to not traverse this
298 * branch. This preserves the scoping rule for handlers.
300 return (AE_CTRL_DEPTH);
303 /* Walk the linked list of handlers attached to this device */
305 NextHandlerObj = NextHandlerObj->AddressSpace.Next;
309 * As long as the device didn't have a handler for this space we
310 * don't care about it. We just ignore it and proceed.
315 /* Object is a Region */
317 if (ObjDesc->Region.SpaceId != HandlerObj->AddressSpace.SpaceId)
319 /* This region is for a different address space, just ignore it */
325 * Now we have a region and it is for the handler's address space type.
327 * First disconnect region for any previous handler (if any)
329 AcpiEvDetachRegion (ObjDesc, FALSE);
331 /* Connect the region to the new handler */
333 Status = AcpiEvAttachRegion (HandlerObj, ObjDesc, FALSE);
338 /*******************************************************************************
340 * FUNCTION: AcpiEvInstallSpaceHandler
342 * PARAMETERS: Node - Namespace node for the device
343 * SpaceId - The address space ID
344 * Handler - Address of the handler
345 * Setup - Address of the setup function
346 * Context - Value passed to the handler on each access
350 * DESCRIPTION: Install a handler for all OpRegions of a given SpaceId.
351 * Assumes namespace is locked
353 ******************************************************************************/
356 AcpiEvInstallSpaceHandler (
357 ACPI_NAMESPACE_NODE *Node,
358 ACPI_ADR_SPACE_TYPE SpaceId,
359 ACPI_ADR_SPACE_HANDLER Handler,
360 ACPI_ADR_SPACE_SETUP Setup,
363 ACPI_OPERAND_OBJECT *ObjDesc;
364 ACPI_OPERAND_OBJECT *HandlerObj;
366 ACPI_OBJECT_TYPE Type;
370 ACPI_FUNCTION_TRACE (EvInstallSpaceHandler);
374 * This registration is valid for only the types below and the root. This
375 * is where the default handlers get placed.
377 if ((Node->Type != ACPI_TYPE_DEVICE) &&
378 (Node->Type != ACPI_TYPE_PROCESSOR) &&
379 (Node->Type != ACPI_TYPE_THERMAL) &&
380 (Node != AcpiGbl_RootNode))
382 Status = AE_BAD_PARAMETER;
386 if (Handler == ACPI_DEFAULT_HANDLER)
388 Flags = ACPI_ADDR_HANDLER_DEFAULT_INSTALLED;
392 case ACPI_ADR_SPACE_SYSTEM_MEMORY:
394 Handler = AcpiExSystemMemorySpaceHandler;
395 Setup = AcpiEvSystemMemoryRegionSetup;
398 case ACPI_ADR_SPACE_SYSTEM_IO:
400 Handler = AcpiExSystemIoSpaceHandler;
401 Setup = AcpiEvIoSpaceRegionSetup;
404 case ACPI_ADR_SPACE_PCI_CONFIG:
406 Handler = AcpiExPciConfigSpaceHandler;
407 Setup = AcpiEvPciConfigRegionSetup;
410 case ACPI_ADR_SPACE_CMOS:
412 Handler = AcpiExCmosSpaceHandler;
413 Setup = AcpiEvCmosRegionSetup;
416 case ACPI_ADR_SPACE_PCI_BAR_TARGET:
418 Handler = AcpiExPciBarSpaceHandler;
419 Setup = AcpiEvPciBarRegionSetup;
422 case ACPI_ADR_SPACE_DATA_TABLE:
424 Handler = AcpiExDataTableSpaceHandler;
430 Status = AE_BAD_PARAMETER;
435 /* If the caller hasn't specified a setup routine, use the default */
439 Setup = AcpiEvDefaultRegionSetup;
442 /* Check for an existing internal object */
444 ObjDesc = AcpiNsGetAttachedObject (Node);
448 * The attached device object already exists. Make sure the handler
449 * is not already installed.
451 HandlerObj = ObjDesc->Device.Handler;
453 /* Walk the handler list for this device */
457 /* Same SpaceId indicates a handler already installed */
459 if (HandlerObj->AddressSpace.SpaceId == SpaceId)
461 if (HandlerObj->AddressSpace.Handler == Handler)
464 * It is (relatively) OK to attempt to install the SAME
465 * handler twice. This can easily happen with the
468 Status = AE_SAME_HANDLER;
473 /* A handler is already installed */
475 Status = AE_ALREADY_EXISTS;
480 /* Walk the linked list of handlers */
482 HandlerObj = HandlerObj->AddressSpace.Next;
487 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
488 "Creating object on Device %p while installing handler\n", Node));
490 /* ObjDesc does not exist, create one */
492 if (Node->Type == ACPI_TYPE_ANY)
494 Type = ACPI_TYPE_DEVICE;
501 ObjDesc = AcpiUtCreateInternalObject (Type);
504 Status = AE_NO_MEMORY;
508 /* Init new descriptor */
510 ObjDesc->Common.Type = (UINT8) Type;
512 /* Attach the new object to the Node */
514 Status = AcpiNsAttachObject (Node, ObjDesc, Type);
516 /* Remove local reference to the object */
518 AcpiUtRemoveReference (ObjDesc);
520 if (ACPI_FAILURE (Status))
526 ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
527 "Installing address handler for region %s(%X) on Device %4.4s %p(%p)\n",
528 AcpiUtGetRegionName (SpaceId), SpaceId,
529 AcpiUtGetNodeName (Node), Node, ObjDesc));
532 * Install the handler
534 * At this point there is no existing handler. Just allocate the object
535 * for the handler and link it into the list.
537 HandlerObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_ADDRESS_HANDLER);
540 Status = AE_NO_MEMORY;
544 /* Init handler obj */
546 HandlerObj->AddressSpace.SpaceId = (UINT8) SpaceId;
547 HandlerObj->AddressSpace.HandlerFlags = Flags;
548 HandlerObj->AddressSpace.RegionList = NULL;
549 HandlerObj->AddressSpace.Node = Node;
550 HandlerObj->AddressSpace.Handler = Handler;
551 HandlerObj->AddressSpace.Context = Context;
552 HandlerObj->AddressSpace.Setup = Setup;
554 /* Install at head of Device.AddressSpace list */
556 HandlerObj->AddressSpace.Next = ObjDesc->Device.Handler;
559 * The Device object is the first reference on the HandlerObj.
560 * Each region that uses the handler adds a reference.
562 ObjDesc->Device.Handler = HandlerObj;
565 * Walk the namespace finding all of the regions this
566 * handler will manage.
568 * Start at the device and search the branch toward
569 * the leaf nodes until either the leaf is encountered or
570 * a device is detected that has an address handler of the
573 * In either case, back up and search down the remainder
576 Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, Node, ACPI_UINT32_MAX,
577 ACPI_NS_WALK_UNLOCK, AcpiEvInstallHandler, NULL,
581 return_ACPI_STATUS (Status);