1ae115bc7Smrj /****************************************************************************** 2ae115bc7Smrj * 3ae115bc7Smrj * Module Name: evrgnini- ACPI AddressSpace (OpRegion) init 4ae115bc7Smrj * 5ae115bc7Smrj *****************************************************************************/ 6ae115bc7Smrj 726f3cdf0SGordon Ross /* 8*385cc6b4SJerry Jelinek * Copyright (C) 2000 - 2016, Intel Corp. 9ae115bc7Smrj * All rights reserved. 10ae115bc7Smrj * 1126f3cdf0SGordon Ross * Redistribution and use in source and binary forms, with or without 1226f3cdf0SGordon Ross * modification, are permitted provided that the following conditions 1326f3cdf0SGordon Ross * are met: 1426f3cdf0SGordon Ross * 1. Redistributions of source code must retain the above copyright 1526f3cdf0SGordon Ross * notice, this list of conditions, and the following disclaimer, 1626f3cdf0SGordon Ross * without modification. 1726f3cdf0SGordon Ross * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1826f3cdf0SGordon Ross * substantially similar to the "NO WARRANTY" disclaimer below 1926f3cdf0SGordon Ross * ("Disclaimer") and any redistribution must be conditioned upon 2026f3cdf0SGordon Ross * including a substantially similar Disclaimer requirement for further 2126f3cdf0SGordon Ross * binary redistribution. 2226f3cdf0SGordon Ross * 3. Neither the names of the above-listed copyright holders nor the names 2326f3cdf0SGordon Ross * of any contributors may be used to endorse or promote products derived 2426f3cdf0SGordon Ross * from this software without specific prior written permission. 25ae115bc7Smrj * 2626f3cdf0SGordon Ross * Alternatively, this software may be distributed under the terms of the 2726f3cdf0SGordon Ross * GNU General Public License ("GPL") version 2 as published by the Free 2826f3cdf0SGordon Ross * Software Foundation. 29ae115bc7Smrj * 3026f3cdf0SGordon Ross * NO WARRANTY 3126f3cdf0SGordon Ross * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3226f3cdf0SGordon Ross * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3326f3cdf0SGordon Ross * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 3426f3cdf0SGordon Ross * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3526f3cdf0SGordon Ross * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3626f3cdf0SGordon Ross * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3726f3cdf0SGordon Ross * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3826f3cdf0SGordon Ross * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 3926f3cdf0SGordon Ross * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 4026f3cdf0SGordon Ross * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 4126f3cdf0SGordon Ross * POSSIBILITY OF SUCH DAMAGES. 4226f3cdf0SGordon Ross */ 43ae115bc7Smrj 44ae115bc7Smrj #include "acpi.h" 45aa2aa9a6SDana Myers #include "accommon.h" 46ae115bc7Smrj #include "acevents.h" 47ae115bc7Smrj #include "acnamesp.h" 48ae115bc7Smrj 49ae115bc7Smrj #define _COMPONENT ACPI_EVENTS 50ae115bc7Smrj ACPI_MODULE_NAME ("evrgnini") 51ae115bc7Smrj 52db2bae30SDana Myers /* Local prototypes */ 53db2bae30SDana Myers 54db2bae30SDana Myers static BOOLEAN 55db2bae30SDana Myers AcpiEvIsPciRootBridge ( 56db2bae30SDana Myers ACPI_NAMESPACE_NODE *Node); 57db2bae30SDana Myers 58ae115bc7Smrj 59ae115bc7Smrj /******************************************************************************* 60ae115bc7Smrj * 61ae115bc7Smrj * FUNCTION: AcpiEvSystemMemoryRegionSetup 62ae115bc7Smrj * 63ae115bc7Smrj * PARAMETERS: Handle - Region we are interested in 64ae115bc7Smrj * Function - Start or stop 65ae115bc7Smrj * HandlerContext - Address space handler context 66ae115bc7Smrj * RegionContext - Region specific context 67ae115bc7Smrj * 68ae115bc7Smrj * RETURN: Status 69ae115bc7Smrj * 70ae115bc7Smrj * DESCRIPTION: Setup a SystemMemory operation region 71ae115bc7Smrj * 72ae115bc7Smrj ******************************************************************************/ 73ae115bc7Smrj 74ae115bc7Smrj ACPI_STATUS 75ae115bc7Smrj AcpiEvSystemMemoryRegionSetup ( 76ae115bc7Smrj ACPI_HANDLE Handle, 77ae115bc7Smrj UINT32 Function, 78ae115bc7Smrj void *HandlerContext, 79ae115bc7Smrj void **RegionContext) 80ae115bc7Smrj { 81ae115bc7Smrj ACPI_OPERAND_OBJECT *RegionDesc = (ACPI_OPERAND_OBJECT *) Handle; 82ae115bc7Smrj ACPI_MEM_SPACE_CONTEXT *LocalRegionContext; 83ae115bc7Smrj 84ae115bc7Smrj 85ae115bc7Smrj ACPI_FUNCTION_TRACE (EvSystemMemoryRegionSetup); 86ae115bc7Smrj 87ae115bc7Smrj 88ae115bc7Smrj if (Function == ACPI_REGION_DEACTIVATE) 89ae115bc7Smrj { 90ae115bc7Smrj if (*RegionContext) 91ae115bc7Smrj { 92ae115bc7Smrj LocalRegionContext = (ACPI_MEM_SPACE_CONTEXT *) *RegionContext; 93ae115bc7Smrj 94ae115bc7Smrj /* Delete a cached mapping if present */ 95ae115bc7Smrj 96ae115bc7Smrj if (LocalRegionContext->MappedLength) 97ae115bc7Smrj { 98ae115bc7Smrj AcpiOsUnmapMemory (LocalRegionContext->MappedLogicalAddress, 99ae115bc7Smrj LocalRegionContext->MappedLength); 100ae115bc7Smrj } 101ae115bc7Smrj ACPI_FREE (LocalRegionContext); 102ae115bc7Smrj *RegionContext = NULL; 103ae115bc7Smrj } 104ae115bc7Smrj return_ACPI_STATUS (AE_OK); 105ae115bc7Smrj } 106ae115bc7Smrj 107ae115bc7Smrj /* Create a new context */ 108ae115bc7Smrj 109ae115bc7Smrj LocalRegionContext = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_MEM_SPACE_CONTEXT)); 110ae115bc7Smrj if (!(LocalRegionContext)) 111ae115bc7Smrj { 112ae115bc7Smrj return_ACPI_STATUS (AE_NO_MEMORY); 113ae115bc7Smrj } 114ae115bc7Smrj 115ae115bc7Smrj /* Save the region length and address for use in the handler */ 116ae115bc7Smrj 117ae115bc7Smrj LocalRegionContext->Length = RegionDesc->Region.Length; 118ae115bc7Smrj LocalRegionContext->Address = RegionDesc->Region.Address; 119ae115bc7Smrj 120ae115bc7Smrj *RegionContext = LocalRegionContext; 121ae115bc7Smrj return_ACPI_STATUS (AE_OK); 122ae115bc7Smrj } 123ae115bc7Smrj 124ae115bc7Smrj 125ae115bc7Smrj /******************************************************************************* 126ae115bc7Smrj * 127ae115bc7Smrj * FUNCTION: AcpiEvIoSpaceRegionSetup 128ae115bc7Smrj * 129ae115bc7Smrj * PARAMETERS: Handle - Region we are interested in 130ae115bc7Smrj * Function - Start or stop 131ae115bc7Smrj * HandlerContext - Address space handler context 132ae115bc7Smrj * RegionContext - Region specific context 133ae115bc7Smrj * 134ae115bc7Smrj * RETURN: Status 135ae115bc7Smrj * 136ae115bc7Smrj * DESCRIPTION: Setup a IO operation region 137ae115bc7Smrj * 138ae115bc7Smrj ******************************************************************************/ 139ae115bc7Smrj 140ae115bc7Smrj ACPI_STATUS 141ae115bc7Smrj AcpiEvIoSpaceRegionSetup ( 142ae115bc7Smrj ACPI_HANDLE Handle, 143ae115bc7Smrj UINT32 Function, 144ae115bc7Smrj void *HandlerContext, 145ae115bc7Smrj void **RegionContext) 146ae115bc7Smrj { 147ae115bc7Smrj ACPI_FUNCTION_TRACE (EvIoSpaceRegionSetup); 148ae115bc7Smrj 149ae115bc7Smrj 150ae115bc7Smrj if (Function == ACPI_REGION_DEACTIVATE) 151ae115bc7Smrj { 152ae115bc7Smrj *RegionContext = NULL; 153ae115bc7Smrj } 154ae115bc7Smrj else 155ae115bc7Smrj { 156ae115bc7Smrj *RegionContext = HandlerContext; 157ae115bc7Smrj } 158ae115bc7Smrj 159ae115bc7Smrj return_ACPI_STATUS (AE_OK); 160ae115bc7Smrj } 161ae115bc7Smrj 162ae115bc7Smrj 163ae115bc7Smrj /******************************************************************************* 164ae115bc7Smrj * 165ae115bc7Smrj * FUNCTION: AcpiEvPciConfigRegionSetup 166ae115bc7Smrj * 167ae115bc7Smrj * PARAMETERS: Handle - Region we are interested in 168ae115bc7Smrj * Function - Start or stop 169ae115bc7Smrj * HandlerContext - Address space handler context 170ae115bc7Smrj * RegionContext - Region specific context 171ae115bc7Smrj * 172ae115bc7Smrj * RETURN: Status 173ae115bc7Smrj * 174ae115bc7Smrj * DESCRIPTION: Setup a PCI_Config operation region 175ae115bc7Smrj * 176ae115bc7Smrj * MUTEX: Assumes namespace is not locked 177ae115bc7Smrj * 178ae115bc7Smrj ******************************************************************************/ 179ae115bc7Smrj 180ae115bc7Smrj ACPI_STATUS 181ae115bc7Smrj AcpiEvPciConfigRegionSetup ( 182ae115bc7Smrj ACPI_HANDLE Handle, 183ae115bc7Smrj UINT32 Function, 184ae115bc7Smrj void *HandlerContext, 185ae115bc7Smrj void **RegionContext) 186ae115bc7Smrj { 187ae115bc7Smrj ACPI_STATUS Status = AE_OK; 18826f3cdf0SGordon Ross UINT64 PciValue; 189ae115bc7Smrj ACPI_PCI_ID *PciId = *RegionContext; 190ae115bc7Smrj ACPI_OPERAND_OBJECT *HandlerObj; 191ae115bc7Smrj ACPI_NAMESPACE_NODE *ParentNode; 192ae115bc7Smrj ACPI_NAMESPACE_NODE *PciRootNode; 193db2bae30SDana Myers ACPI_NAMESPACE_NODE *PciDeviceNode; 194ae115bc7Smrj ACPI_OPERAND_OBJECT *RegionObj = (ACPI_OPERAND_OBJECT *) Handle; 195ae115bc7Smrj 196ae115bc7Smrj 197ae115bc7Smrj ACPI_FUNCTION_TRACE (EvPciConfigRegionSetup); 198ae115bc7Smrj 199ae115bc7Smrj 200ae115bc7Smrj HandlerObj = RegionObj->Region.Handler; 201ae115bc7Smrj if (!HandlerObj) 202ae115bc7Smrj { 203ae115bc7Smrj /* 204ae115bc7Smrj * No installed handler. This shouldn't happen because the dispatch 205ae115bc7Smrj * routine checks before we get here, but we check again just in case. 206ae115bc7Smrj */ 207ae115bc7Smrj ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 208ae115bc7Smrj "Attempting to init a region %p, with no handler\n", RegionObj)); 209ae115bc7Smrj return_ACPI_STATUS (AE_NOT_EXIST); 210ae115bc7Smrj } 211ae115bc7Smrj 212ae115bc7Smrj *RegionContext = NULL; 213ae115bc7Smrj if (Function == ACPI_REGION_DEACTIVATE) 214ae115bc7Smrj { 215ae115bc7Smrj if (PciId) 216ae115bc7Smrj { 217ae115bc7Smrj ACPI_FREE (PciId); 218ae115bc7Smrj } 219ae115bc7Smrj return_ACPI_STATUS (Status); 220ae115bc7Smrj } 221ae115bc7Smrj 22226f3cdf0SGordon Ross ParentNode = RegionObj->Region.Node->Parent; 223ae115bc7Smrj 224ae115bc7Smrj /* 225ae115bc7Smrj * Get the _SEG and _BBN values from the device upon which the handler 226ae115bc7Smrj * is installed. 227ae115bc7Smrj * 228ae115bc7Smrj * We need to get the _SEG and _BBN objects relative to the PCI BUS device. 229ae115bc7Smrj * This is the device the handler has been registered to handle. 230ae115bc7Smrj */ 231ae115bc7Smrj 232ae115bc7Smrj /* 233ae115bc7Smrj * If the AddressSpace.Node is still pointing to the root, we need 234ae115bc7Smrj * to scan upward for a PCI Root bridge and re-associate the OpRegion 235ae115bc7Smrj * handlers with that device. 236ae115bc7Smrj */ 237ae115bc7Smrj if (HandlerObj->AddressSpace.Node == AcpiGbl_RootNode) 238ae115bc7Smrj { 239ae115bc7Smrj /* Start search from the parent object */ 240ae115bc7Smrj 241ae115bc7Smrj PciRootNode = ParentNode; 242ae115bc7Smrj while (PciRootNode != AcpiGbl_RootNode) 243ae115bc7Smrj { 244db2bae30SDana Myers /* Get the _HID/_CID in order to detect a RootBridge */ 245db2bae30SDana Myers 246db2bae30SDana Myers if (AcpiEvIsPciRootBridge (PciRootNode)) 247ae115bc7Smrj { 248ae115bc7Smrj /* Install a handler for this PCI root bridge */ 249ae115bc7Smrj 250db2bae30SDana Myers Status = AcpiInstallAddressSpaceHandler ( 251db2bae30SDana Myers (ACPI_HANDLE) PciRootNode, 252ae115bc7Smrj ACPI_ADR_SPACE_PCI_CONFIG, 253ae115bc7Smrj ACPI_DEFAULT_HANDLER, NULL, NULL); 254ae115bc7Smrj if (ACPI_FAILURE (Status)) 255ae115bc7Smrj { 256ae115bc7Smrj if (Status == AE_SAME_HANDLER) 257ae115bc7Smrj { 258ae115bc7Smrj /* 259aa2aa9a6SDana Myers * It is OK if the handler is already installed on the 260aa2aa9a6SDana Myers * root bridge. Still need to return a context object 261aa2aa9a6SDana Myers * for the new PCI_Config operation region, however. 262ae115bc7Smrj */ 263ae115bc7Smrj Status = AE_OK; 264ae115bc7Smrj } 265ae115bc7Smrj else 266ae115bc7Smrj { 267ae115bc7Smrj ACPI_EXCEPTION ((AE_INFO, Status, 268aa2aa9a6SDana Myers "Could not install PciConfig handler " 269aa2aa9a6SDana Myers "for Root Bridge %4.4s", 270ae115bc7Smrj AcpiUtGetNodeName (PciRootNode))); 271ae115bc7Smrj } 272ae115bc7Smrj } 273ae115bc7Smrj break; 274ae115bc7Smrj } 275ae115bc7Smrj 27626f3cdf0SGordon Ross PciRootNode = PciRootNode->Parent; 277ae115bc7Smrj } 278ae115bc7Smrj 279ae115bc7Smrj /* PCI root bridge not found, use namespace root node */ 280ae115bc7Smrj } 281ae115bc7Smrj else 282ae115bc7Smrj { 283ae115bc7Smrj PciRootNode = HandlerObj->AddressSpace.Node; 284ae115bc7Smrj } 285ae115bc7Smrj 286ae115bc7Smrj /* 287ae115bc7Smrj * If this region is now initialized, we are done. 288ae115bc7Smrj * (InstallAddressSpaceHandler could have initialized it) 289ae115bc7Smrj */ 290ae115bc7Smrj if (RegionObj->Region.Flags & AOPOBJ_SETUP_COMPLETE) 291ae115bc7Smrj { 292ae115bc7Smrj return_ACPI_STATUS (AE_OK); 293ae115bc7Smrj } 294ae115bc7Smrj 295ae115bc7Smrj /* Region is still not initialized. Create a new context */ 296ae115bc7Smrj 297ae115bc7Smrj PciId = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PCI_ID)); 298ae115bc7Smrj if (!PciId) 299ae115bc7Smrj { 300ae115bc7Smrj return_ACPI_STATUS (AE_NO_MEMORY); 301ae115bc7Smrj } 302ae115bc7Smrj 303ae115bc7Smrj /* 304aa2aa9a6SDana Myers * For PCI_Config space access, we need the segment, bus, device and 305aa2aa9a6SDana Myers * function numbers. Acquire them here. 306db2bae30SDana Myers * 307db2bae30SDana Myers * Find the parent device object. (This allows the operation region to be 308db2bae30SDana Myers * within a subscope under the device, such as a control method.) 309ae115bc7Smrj */ 310db2bae30SDana Myers PciDeviceNode = RegionObj->Region.Node; 311db2bae30SDana Myers while (PciDeviceNode && (PciDeviceNode->Type != ACPI_TYPE_DEVICE)) 312db2bae30SDana Myers { 31326f3cdf0SGordon Ross PciDeviceNode = PciDeviceNode->Parent; 314db2bae30SDana Myers } 315db2bae30SDana Myers 316db2bae30SDana Myers if (!PciDeviceNode) 317db2bae30SDana Myers { 318db2bae30SDana Myers ACPI_FREE (PciId); 319db2bae30SDana Myers return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 320db2bae30SDana Myers } 321ae115bc7Smrj 322ae115bc7Smrj /* 32326f3cdf0SGordon Ross * Get the PCI device and function numbers from the _ADR object 32426f3cdf0SGordon Ross * contained in the parent's scope. 325ae115bc7Smrj */ 326aa2aa9a6SDana Myers Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR, 327aa2aa9a6SDana Myers PciDeviceNode, &PciValue); 328ae115bc7Smrj 329ae115bc7Smrj /* 330aa2aa9a6SDana Myers * The default is zero, and since the allocation above zeroed the data, 331aa2aa9a6SDana Myers * just do nothing on failure. 332ae115bc7Smrj */ 333ae115bc7Smrj if (ACPI_SUCCESS (Status)) 334ae115bc7Smrj { 335ae115bc7Smrj PciId->Device = ACPI_HIWORD (ACPI_LODWORD (PciValue)); 336ae115bc7Smrj PciId->Function = ACPI_LOWORD (ACPI_LODWORD (PciValue)); 337ae115bc7Smrj } 338ae115bc7Smrj 339ae115bc7Smrj /* The PCI segment number comes from the _SEG method */ 340ae115bc7Smrj 341aa2aa9a6SDana Myers Status = AcpiUtEvaluateNumericObject (METHOD_NAME__SEG, 342aa2aa9a6SDana Myers PciRootNode, &PciValue); 343ae115bc7Smrj if (ACPI_SUCCESS (Status)) 344ae115bc7Smrj { 345ae115bc7Smrj PciId->Segment = ACPI_LOWORD (PciValue); 346ae115bc7Smrj } 347ae115bc7Smrj 348ae115bc7Smrj /* The PCI bus number comes from the _BBN method */ 349ae115bc7Smrj 350aa2aa9a6SDana Myers Status = AcpiUtEvaluateNumericObject (METHOD_NAME__BBN, 351aa2aa9a6SDana Myers PciRootNode, &PciValue); 352ae115bc7Smrj if (ACPI_SUCCESS (Status)) 353ae115bc7Smrj { 354ae115bc7Smrj PciId->Bus = ACPI_LOWORD (PciValue); 355ae115bc7Smrj } 356ae115bc7Smrj 35726f3cdf0SGordon Ross /* Complete/update the PCI ID for this device */ 358ae115bc7Smrj 35926f3cdf0SGordon Ross Status = AcpiHwDerivePciId (PciId, PciRootNode, RegionObj->Region.Node); 36026f3cdf0SGordon Ross if (ACPI_FAILURE (Status)) 36126f3cdf0SGordon Ross { 36226f3cdf0SGordon Ross ACPI_FREE (PciId); 36326f3cdf0SGordon Ross return_ACPI_STATUS (Status); 36426f3cdf0SGordon Ross } 365ae115bc7Smrj 366ae115bc7Smrj *RegionContext = PciId; 367ae115bc7Smrj return_ACPI_STATUS (AE_OK); 368ae115bc7Smrj } 369ae115bc7Smrj 370ae115bc7Smrj 371ae115bc7Smrj /******************************************************************************* 372ae115bc7Smrj * 373db2bae30SDana Myers * FUNCTION: AcpiEvIsPciRootBridge 374db2bae30SDana Myers * 375db2bae30SDana Myers * PARAMETERS: Node - Device node being examined 376db2bae30SDana Myers * 377db2bae30SDana Myers * RETURN: TRUE if device is a PCI/PCI-Express Root Bridge 378db2bae30SDana Myers * 379db2bae30SDana Myers * DESCRIPTION: Determine if the input device represents a PCI Root Bridge by 380db2bae30SDana Myers * examining the _HID and _CID for the device. 381db2bae30SDana Myers * 382db2bae30SDana Myers ******************************************************************************/ 383db2bae30SDana Myers 384db2bae30SDana Myers static BOOLEAN 385db2bae30SDana Myers AcpiEvIsPciRootBridge ( 386db2bae30SDana Myers ACPI_NAMESPACE_NODE *Node) 387db2bae30SDana Myers { 388db2bae30SDana Myers ACPI_STATUS Status; 389*385cc6b4SJerry Jelinek ACPI_PNP_DEVICE_ID *Hid; 390*385cc6b4SJerry Jelinek ACPI_PNP_DEVICE_ID_LIST *Cid; 391db2bae30SDana Myers UINT32 i; 39257190917SDana Myers BOOLEAN Match; 393db2bae30SDana Myers 394db2bae30SDana Myers 395aa2aa9a6SDana Myers /* Get the _HID and check for a PCI Root Bridge */ 396aa2aa9a6SDana Myers 397db2bae30SDana Myers Status = AcpiUtExecute_HID (Node, &Hid); 398db2bae30SDana Myers if (ACPI_FAILURE (Status)) 399db2bae30SDana Myers { 400db2bae30SDana Myers return (FALSE); 401db2bae30SDana Myers } 402db2bae30SDana Myers 40357190917SDana Myers Match = AcpiUtIsPciRootBridge (Hid->String); 40457190917SDana Myers ACPI_FREE (Hid); 40557190917SDana Myers 40657190917SDana Myers if (Match) 407db2bae30SDana Myers { 408db2bae30SDana Myers return (TRUE); 409db2bae30SDana Myers } 410db2bae30SDana Myers 411aa2aa9a6SDana Myers /* The _HID did not match. Get the _CID and check for a PCI Root Bridge */ 412aa2aa9a6SDana Myers 413db2bae30SDana Myers Status = AcpiUtExecute_CID (Node, &Cid); 414db2bae30SDana Myers if (ACPI_FAILURE (Status)) 415db2bae30SDana Myers { 416db2bae30SDana Myers return (FALSE); 417db2bae30SDana Myers } 418db2bae30SDana Myers 419db2bae30SDana Myers /* Check all _CIDs in the returned list */ 420db2bae30SDana Myers 421db2bae30SDana Myers for (i = 0; i < Cid->Count; i++) 422db2bae30SDana Myers { 42357190917SDana Myers if (AcpiUtIsPciRootBridge (Cid->Ids[i].String)) 424db2bae30SDana Myers { 425db2bae30SDana Myers ACPI_FREE (Cid); 426db2bae30SDana Myers return (TRUE); 427db2bae30SDana Myers } 428db2bae30SDana Myers } 429db2bae30SDana Myers 430db2bae30SDana Myers ACPI_FREE (Cid); 431db2bae30SDana Myers return (FALSE); 432db2bae30SDana Myers } 433db2bae30SDana Myers 434db2bae30SDana Myers 435db2bae30SDana Myers /******************************************************************************* 436db2bae30SDana Myers * 437ae115bc7Smrj * FUNCTION: AcpiEvPciBarRegionSetup 438ae115bc7Smrj * 439ae115bc7Smrj * PARAMETERS: Handle - Region we are interested in 440ae115bc7Smrj * Function - Start or stop 441ae115bc7Smrj * HandlerContext - Address space handler context 442ae115bc7Smrj * RegionContext - Region specific context 443ae115bc7Smrj * 444ae115bc7Smrj * RETURN: Status 445ae115bc7Smrj * 446ae115bc7Smrj * DESCRIPTION: Setup a PciBAR operation region 447ae115bc7Smrj * 448ae115bc7Smrj * MUTEX: Assumes namespace is not locked 449ae115bc7Smrj * 450ae115bc7Smrj ******************************************************************************/ 451ae115bc7Smrj 452ae115bc7Smrj ACPI_STATUS 453ae115bc7Smrj AcpiEvPciBarRegionSetup ( 454ae115bc7Smrj ACPI_HANDLE Handle, 455ae115bc7Smrj UINT32 Function, 456ae115bc7Smrj void *HandlerContext, 457ae115bc7Smrj void **RegionContext) 458ae115bc7Smrj { 459ae115bc7Smrj ACPI_FUNCTION_TRACE (EvPciBarRegionSetup); 460ae115bc7Smrj 461ae115bc7Smrj 462ae115bc7Smrj return_ACPI_STATUS (AE_OK); 463ae115bc7Smrj } 464ae115bc7Smrj 465ae115bc7Smrj 466ae115bc7Smrj /******************************************************************************* 467ae115bc7Smrj * 468ae115bc7Smrj * FUNCTION: AcpiEvCmosRegionSetup 469ae115bc7Smrj * 470ae115bc7Smrj * PARAMETERS: Handle - Region we are interested in 471ae115bc7Smrj * Function - Start or stop 472ae115bc7Smrj * HandlerContext - Address space handler context 473ae115bc7Smrj * RegionContext - Region specific context 474ae115bc7Smrj * 475ae115bc7Smrj * RETURN: Status 476ae115bc7Smrj * 477ae115bc7Smrj * DESCRIPTION: Setup a CMOS operation region 478ae115bc7Smrj * 479ae115bc7Smrj * MUTEX: Assumes namespace is not locked 480ae115bc7Smrj * 481ae115bc7Smrj ******************************************************************************/ 482ae115bc7Smrj 483ae115bc7Smrj ACPI_STATUS 484ae115bc7Smrj AcpiEvCmosRegionSetup ( 485ae115bc7Smrj ACPI_HANDLE Handle, 486ae115bc7Smrj UINT32 Function, 487ae115bc7Smrj void *HandlerContext, 488ae115bc7Smrj void **RegionContext) 489ae115bc7Smrj { 490ae115bc7Smrj ACPI_FUNCTION_TRACE (EvCmosRegionSetup); 491ae115bc7Smrj 492ae115bc7Smrj 493ae115bc7Smrj return_ACPI_STATUS (AE_OK); 494ae115bc7Smrj } 495ae115bc7Smrj 496ae115bc7Smrj 497ae115bc7Smrj /******************************************************************************* 498ae115bc7Smrj * 499ae115bc7Smrj * FUNCTION: AcpiEvDefaultRegionSetup 500ae115bc7Smrj * 501ae115bc7Smrj * PARAMETERS: Handle - Region we are interested in 502ae115bc7Smrj * Function - Start or stop 503ae115bc7Smrj * HandlerContext - Address space handler context 504ae115bc7Smrj * RegionContext - Region specific context 505ae115bc7Smrj * 506ae115bc7Smrj * RETURN: Status 507ae115bc7Smrj * 508ae115bc7Smrj * DESCRIPTION: Default region initialization 509ae115bc7Smrj * 510ae115bc7Smrj ******************************************************************************/ 511ae115bc7Smrj 512ae115bc7Smrj ACPI_STATUS 513ae115bc7Smrj AcpiEvDefaultRegionSetup ( 514ae115bc7Smrj ACPI_HANDLE Handle, 515ae115bc7Smrj UINT32 Function, 516ae115bc7Smrj void *HandlerContext, 517ae115bc7Smrj void **RegionContext) 518ae115bc7Smrj { 519ae115bc7Smrj ACPI_FUNCTION_TRACE (EvDefaultRegionSetup); 520ae115bc7Smrj 521ae115bc7Smrj 522ae115bc7Smrj if (Function == ACPI_REGION_DEACTIVATE) 523ae115bc7Smrj { 524ae115bc7Smrj *RegionContext = NULL; 525ae115bc7Smrj } 526ae115bc7Smrj else 527ae115bc7Smrj { 528ae115bc7Smrj *RegionContext = HandlerContext; 529ae115bc7Smrj } 530ae115bc7Smrj 531ae115bc7Smrj return_ACPI_STATUS (AE_OK); 532ae115bc7Smrj } 533ae115bc7Smrj 534ae115bc7Smrj 535ae115bc7Smrj /******************************************************************************* 536ae115bc7Smrj * 537ae115bc7Smrj * FUNCTION: AcpiEvInitializeRegion 538ae115bc7Smrj * 539ae115bc7Smrj * PARAMETERS: RegionObj - Region we are initializing 540ae115bc7Smrj * AcpiNsLocked - Is namespace locked? 541ae115bc7Smrj * 542ae115bc7Smrj * RETURN: Status 543ae115bc7Smrj * 544ae115bc7Smrj * DESCRIPTION: Initializes the region, finds any _REG methods and saves them 545ae115bc7Smrj * for execution at a later time 546ae115bc7Smrj * 547ae115bc7Smrj * Get the appropriate address space handler for a newly 548ae115bc7Smrj * created region. 549ae115bc7Smrj * 550ae115bc7Smrj * This also performs address space specific initialization. For 551ae115bc7Smrj * example, PCI regions must have an _ADR object that contains 552ae115bc7Smrj * a PCI address in the scope of the definition. This address is 553ae115bc7Smrj * required to perform an access to PCI config space. 554ae115bc7Smrj * 555ae115bc7Smrj * MUTEX: Interpreter should be unlocked, because we may run the _REG 556ae115bc7Smrj * method for this region. 557ae115bc7Smrj * 558ae115bc7Smrj ******************************************************************************/ 559ae115bc7Smrj 560ae115bc7Smrj ACPI_STATUS 561ae115bc7Smrj AcpiEvInitializeRegion ( 562ae115bc7Smrj ACPI_OPERAND_OBJECT *RegionObj, 563ae115bc7Smrj BOOLEAN AcpiNsLocked) 564ae115bc7Smrj { 565ae115bc7Smrj ACPI_OPERAND_OBJECT *HandlerObj; 566ae115bc7Smrj ACPI_OPERAND_OBJECT *ObjDesc; 567ae115bc7Smrj ACPI_ADR_SPACE_TYPE SpaceId; 568ae115bc7Smrj ACPI_NAMESPACE_NODE *Node; 569ae115bc7Smrj ACPI_STATUS Status; 570ae115bc7Smrj 571ae115bc7Smrj 572ae115bc7Smrj ACPI_FUNCTION_TRACE_U32 (EvInitializeRegion, AcpiNsLocked); 573ae115bc7Smrj 574ae115bc7Smrj 575ae115bc7Smrj if (!RegionObj) 576ae115bc7Smrj { 577ae115bc7Smrj return_ACPI_STATUS (AE_BAD_PARAMETER); 578ae115bc7Smrj } 579ae115bc7Smrj 580ae115bc7Smrj if (RegionObj->Common.Flags & AOPOBJ_OBJECT_INITIALIZED) 581ae115bc7Smrj { 582ae115bc7Smrj return_ACPI_STATUS (AE_OK); 583ae115bc7Smrj } 584ae115bc7Smrj 585*385cc6b4SJerry Jelinek RegionObj->Common.Flags |= AOPOBJ_OBJECT_INITIALIZED; 586ae115bc7Smrj 58726f3cdf0SGordon Ross Node = RegionObj->Region.Node->Parent; 588ae115bc7Smrj SpaceId = RegionObj->Region.SpaceId; 589ae115bc7Smrj 590ae115bc7Smrj /* 591ae115bc7Smrj * The following loop depends upon the root Node having no parent 592*385cc6b4SJerry Jelinek * ie: AcpiGbl_RootNode->Parent being set to NULL 593ae115bc7Smrj */ 594ae115bc7Smrj while (Node) 595ae115bc7Smrj { 596ae115bc7Smrj /* Check to see if a handler exists */ 597ae115bc7Smrj 598ae115bc7Smrj HandlerObj = NULL; 599ae115bc7Smrj ObjDesc = AcpiNsGetAttachedObject (Node); 600ae115bc7Smrj if (ObjDesc) 601ae115bc7Smrj { 602ae115bc7Smrj /* Can only be a handler if the object exists */ 603ae115bc7Smrj 604ae115bc7Smrj switch (Node->Type) 605ae115bc7Smrj { 606ae115bc7Smrj case ACPI_TYPE_DEVICE: 607ae115bc7Smrj case ACPI_TYPE_PROCESSOR: 608ae115bc7Smrj case ACPI_TYPE_THERMAL: 609ae115bc7Smrj 610*385cc6b4SJerry Jelinek HandlerObj = ObjDesc->CommonNotify.Handler; 611ae115bc7Smrj break; 612ae115bc7Smrj 61326f3cdf0SGordon Ross case ACPI_TYPE_METHOD: 61426f3cdf0SGordon Ross /* 61526f3cdf0SGordon Ross * If we are executing module level code, the original 61626f3cdf0SGordon Ross * Node's object was replaced by this Method object and we 61726f3cdf0SGordon Ross * saved the handler in the method object. 61826f3cdf0SGordon Ross * 61926f3cdf0SGordon Ross * See AcpiNsExecModuleCode 62026f3cdf0SGordon Ross */ 62126f3cdf0SGordon Ross if (ObjDesc->Method.InfoFlags & ACPI_METHOD_MODULE_LEVEL) 62226f3cdf0SGordon Ross { 62326f3cdf0SGordon Ross HandlerObj = ObjDesc->Method.Dispatch.Handler; 62426f3cdf0SGordon Ross } 62526f3cdf0SGordon Ross break; 62626f3cdf0SGordon Ross 627ae115bc7Smrj default: 628*385cc6b4SJerry Jelinek 629ae115bc7Smrj /* Ignore other objects */ 630*385cc6b4SJerry Jelinek 631ae115bc7Smrj break; 632ae115bc7Smrj } 633ae115bc7Smrj 634*385cc6b4SJerry Jelinek HandlerObj = AcpiEvFindRegionHandler (SpaceId, HandlerObj); 635*385cc6b4SJerry Jelinek if (HandlerObj) 636ae115bc7Smrj { 637ae115bc7Smrj /* Found correct handler */ 638ae115bc7Smrj 639ae115bc7Smrj ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 640ae115bc7Smrj "Found handler %p for region %p in obj %p\n", 641ae115bc7Smrj HandlerObj, RegionObj, ObjDesc)); 642ae115bc7Smrj 643ae115bc7Smrj Status = AcpiEvAttachRegion (HandlerObj, RegionObj, 644ae115bc7Smrj AcpiNsLocked); 645ae115bc7Smrj 646ae115bc7Smrj /* 647aa2aa9a6SDana Myers * Tell all users that this region is usable by 648aa2aa9a6SDana Myers * running the _REG method 649ae115bc7Smrj */ 650ae115bc7Smrj if (AcpiNsLocked) 651ae115bc7Smrj { 652ae115bc7Smrj Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 653ae115bc7Smrj if (ACPI_FAILURE (Status)) 654ae115bc7Smrj { 655ae115bc7Smrj return_ACPI_STATUS (Status); 656ae115bc7Smrj } 657ae115bc7Smrj } 658ae115bc7Smrj 65926f3cdf0SGordon Ross Status = AcpiEvExecuteRegMethod (RegionObj, ACPI_REG_CONNECT); 660ae115bc7Smrj 661ae115bc7Smrj if (AcpiNsLocked) 662ae115bc7Smrj { 663ae115bc7Smrj Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 664ae115bc7Smrj if (ACPI_FAILURE (Status)) 665ae115bc7Smrj { 666ae115bc7Smrj return_ACPI_STATUS (Status); 667ae115bc7Smrj } 668ae115bc7Smrj } 669ae115bc7Smrj 670ae115bc7Smrj return_ACPI_STATUS (AE_OK); 671ae115bc7Smrj } 672ae115bc7Smrj } 673ae115bc7Smrj 674aa2aa9a6SDana Myers /* This node does not have the handler we need; Pop up one level */ 675aa2aa9a6SDana Myers 67626f3cdf0SGordon Ross Node = Node->Parent; 677ae115bc7Smrj } 678ae115bc7Smrj 679ae115bc7Smrj /* If we get here, there is no handler for this region */ 680ae115bc7Smrj 681ae115bc7Smrj ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, 682ae115bc7Smrj "No handler for RegionType %s(%X) (RegionObj %p)\n", 683ae115bc7Smrj AcpiUtGetRegionName (SpaceId), SpaceId, RegionObj)); 684ae115bc7Smrj 685ae115bc7Smrj return_ACPI_STATUS (AE_NOT_EXIST); 686ae115bc7Smrj } 687