1*385cc6b4SJerry Jelinek /****************************************************************************** 2*385cc6b4SJerry Jelinek * 3*385cc6b4SJerry Jelinek * Module Name: utaddress - OpRegion address range check 4*385cc6b4SJerry Jelinek * 5*385cc6b4SJerry Jelinek *****************************************************************************/ 6*385cc6b4SJerry Jelinek 7*385cc6b4SJerry Jelinek /* 8*385cc6b4SJerry Jelinek * Copyright (C) 2000 - 2016, Intel Corp. 9*385cc6b4SJerry Jelinek * All rights reserved. 10*385cc6b4SJerry Jelinek * 11*385cc6b4SJerry Jelinek * Redistribution and use in source and binary forms, with or without 12*385cc6b4SJerry Jelinek * modification, are permitted provided that the following conditions 13*385cc6b4SJerry Jelinek * are met: 14*385cc6b4SJerry Jelinek * 1. Redistributions of source code must retain the above copyright 15*385cc6b4SJerry Jelinek * notice, this list of conditions, and the following disclaimer, 16*385cc6b4SJerry Jelinek * without modification. 17*385cc6b4SJerry Jelinek * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18*385cc6b4SJerry Jelinek * substantially similar to the "NO WARRANTY" disclaimer below 19*385cc6b4SJerry Jelinek * ("Disclaimer") and any redistribution must be conditioned upon 20*385cc6b4SJerry Jelinek * including a substantially similar Disclaimer requirement for further 21*385cc6b4SJerry Jelinek * binary redistribution. 22*385cc6b4SJerry Jelinek * 3. Neither the names of the above-listed copyright holders nor the names 23*385cc6b4SJerry Jelinek * of any contributors may be used to endorse or promote products derived 24*385cc6b4SJerry Jelinek * from this software without specific prior written permission. 25*385cc6b4SJerry Jelinek * 26*385cc6b4SJerry Jelinek * Alternatively, this software may be distributed under the terms of the 27*385cc6b4SJerry Jelinek * GNU General Public License ("GPL") version 2 as published by the Free 28*385cc6b4SJerry Jelinek * Software Foundation. 29*385cc6b4SJerry Jelinek * 30*385cc6b4SJerry Jelinek * NO WARRANTY 31*385cc6b4SJerry Jelinek * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32*385cc6b4SJerry Jelinek * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33*385cc6b4SJerry Jelinek * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34*385cc6b4SJerry Jelinek * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35*385cc6b4SJerry Jelinek * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36*385cc6b4SJerry Jelinek * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37*385cc6b4SJerry Jelinek * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38*385cc6b4SJerry Jelinek * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39*385cc6b4SJerry Jelinek * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40*385cc6b4SJerry Jelinek * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41*385cc6b4SJerry Jelinek * POSSIBILITY OF SUCH DAMAGES. 42*385cc6b4SJerry Jelinek */ 43*385cc6b4SJerry Jelinek 44*385cc6b4SJerry Jelinek #include "acpi.h" 45*385cc6b4SJerry Jelinek #include "accommon.h" 46*385cc6b4SJerry Jelinek #include "acnamesp.h" 47*385cc6b4SJerry Jelinek 48*385cc6b4SJerry Jelinek 49*385cc6b4SJerry Jelinek #define _COMPONENT ACPI_UTILITIES 50*385cc6b4SJerry Jelinek ACPI_MODULE_NAME ("utaddress") 51*385cc6b4SJerry Jelinek 52*385cc6b4SJerry Jelinek 53*385cc6b4SJerry Jelinek /******************************************************************************* 54*385cc6b4SJerry Jelinek * 55*385cc6b4SJerry Jelinek * FUNCTION: AcpiUtAddAddressRange 56*385cc6b4SJerry Jelinek * 57*385cc6b4SJerry Jelinek * PARAMETERS: SpaceId - Address space ID 58*385cc6b4SJerry Jelinek * Address - OpRegion start address 59*385cc6b4SJerry Jelinek * Length - OpRegion length 60*385cc6b4SJerry Jelinek * RegionNode - OpRegion namespace node 61*385cc6b4SJerry Jelinek * 62*385cc6b4SJerry Jelinek * RETURN: Status 63*385cc6b4SJerry Jelinek * 64*385cc6b4SJerry Jelinek * DESCRIPTION: Add the Operation Region address range to the global list. 65*385cc6b4SJerry Jelinek * The only supported Space IDs are Memory and I/O. Called when 66*385cc6b4SJerry Jelinek * the OpRegion address/length operands are fully evaluated. 67*385cc6b4SJerry Jelinek * 68*385cc6b4SJerry Jelinek * MUTEX: Locks the namespace 69*385cc6b4SJerry Jelinek * 70*385cc6b4SJerry Jelinek * NOTE: Because this interface is only called when an OpRegion argument 71*385cc6b4SJerry Jelinek * list is evaluated, there cannot be any duplicate RegionNodes. 72*385cc6b4SJerry Jelinek * Duplicate Address/Length values are allowed, however, so that multiple 73*385cc6b4SJerry Jelinek * address conflicts can be detected. 74*385cc6b4SJerry Jelinek * 75*385cc6b4SJerry Jelinek ******************************************************************************/ 76*385cc6b4SJerry Jelinek 77*385cc6b4SJerry Jelinek ACPI_STATUS 78*385cc6b4SJerry Jelinek AcpiUtAddAddressRange ( 79*385cc6b4SJerry Jelinek ACPI_ADR_SPACE_TYPE SpaceId, 80*385cc6b4SJerry Jelinek ACPI_PHYSICAL_ADDRESS Address, 81*385cc6b4SJerry Jelinek UINT32 Length, 82*385cc6b4SJerry Jelinek ACPI_NAMESPACE_NODE *RegionNode) 83*385cc6b4SJerry Jelinek { 84*385cc6b4SJerry Jelinek ACPI_ADDRESS_RANGE *RangeInfo; 85*385cc6b4SJerry Jelinek ACPI_STATUS Status; 86*385cc6b4SJerry Jelinek 87*385cc6b4SJerry Jelinek 88*385cc6b4SJerry Jelinek ACPI_FUNCTION_TRACE (UtAddAddressRange); 89*385cc6b4SJerry Jelinek 90*385cc6b4SJerry Jelinek 91*385cc6b4SJerry Jelinek if ((SpaceId != ACPI_ADR_SPACE_SYSTEM_MEMORY) && 92*385cc6b4SJerry Jelinek (SpaceId != ACPI_ADR_SPACE_SYSTEM_IO)) 93*385cc6b4SJerry Jelinek { 94*385cc6b4SJerry Jelinek return_ACPI_STATUS (AE_OK); 95*385cc6b4SJerry Jelinek } 96*385cc6b4SJerry Jelinek 97*385cc6b4SJerry Jelinek /* Allocate/init a new info block, add it to the appropriate list */ 98*385cc6b4SJerry Jelinek 99*385cc6b4SJerry Jelinek RangeInfo = ACPI_ALLOCATE (sizeof (ACPI_ADDRESS_RANGE)); 100*385cc6b4SJerry Jelinek if (!RangeInfo) 101*385cc6b4SJerry Jelinek { 102*385cc6b4SJerry Jelinek return_ACPI_STATUS (AE_NO_MEMORY); 103*385cc6b4SJerry Jelinek } 104*385cc6b4SJerry Jelinek 105*385cc6b4SJerry Jelinek RangeInfo->StartAddress = Address; 106*385cc6b4SJerry Jelinek RangeInfo->EndAddress = (Address + Length - 1); 107*385cc6b4SJerry Jelinek RangeInfo->RegionNode = RegionNode; 108*385cc6b4SJerry Jelinek 109*385cc6b4SJerry Jelinek Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 110*385cc6b4SJerry Jelinek if (ACPI_FAILURE (Status)) 111*385cc6b4SJerry Jelinek { 112*385cc6b4SJerry Jelinek ACPI_FREE (RangeInfo); 113*385cc6b4SJerry Jelinek return_ACPI_STATUS (Status); 114*385cc6b4SJerry Jelinek } 115*385cc6b4SJerry Jelinek 116*385cc6b4SJerry Jelinek RangeInfo->Next = AcpiGbl_AddressRangeList[SpaceId]; 117*385cc6b4SJerry Jelinek AcpiGbl_AddressRangeList[SpaceId] = RangeInfo; 118*385cc6b4SJerry Jelinek 119*385cc6b4SJerry Jelinek ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 120*385cc6b4SJerry Jelinek "\nAdded [%4.4s] address range: 0x%8.8X%8.8X-0x%8.8X%8.8X\n", 121*385cc6b4SJerry Jelinek AcpiUtGetNodeName (RangeInfo->RegionNode), 122*385cc6b4SJerry Jelinek ACPI_FORMAT_UINT64 (Address), 123*385cc6b4SJerry Jelinek ACPI_FORMAT_UINT64 (RangeInfo->EndAddress))); 124*385cc6b4SJerry Jelinek 125*385cc6b4SJerry Jelinek (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 126*385cc6b4SJerry Jelinek return_ACPI_STATUS (AE_OK); 127*385cc6b4SJerry Jelinek } 128*385cc6b4SJerry Jelinek 129*385cc6b4SJerry Jelinek 130*385cc6b4SJerry Jelinek /******************************************************************************* 131*385cc6b4SJerry Jelinek * 132*385cc6b4SJerry Jelinek * FUNCTION: AcpiUtRemoveAddressRange 133*385cc6b4SJerry Jelinek * 134*385cc6b4SJerry Jelinek * PARAMETERS: SpaceId - Address space ID 135*385cc6b4SJerry Jelinek * RegionNode - OpRegion namespace node 136*385cc6b4SJerry Jelinek * 137*385cc6b4SJerry Jelinek * RETURN: None 138*385cc6b4SJerry Jelinek * 139*385cc6b4SJerry Jelinek * DESCRIPTION: Remove the Operation Region from the global list. The only 140*385cc6b4SJerry Jelinek * supported Space IDs are Memory and I/O. Called when an 141*385cc6b4SJerry Jelinek * OpRegion is deleted. 142*385cc6b4SJerry Jelinek * 143*385cc6b4SJerry Jelinek * MUTEX: Assumes the namespace is locked 144*385cc6b4SJerry Jelinek * 145*385cc6b4SJerry Jelinek ******************************************************************************/ 146*385cc6b4SJerry Jelinek 147*385cc6b4SJerry Jelinek void 148*385cc6b4SJerry Jelinek AcpiUtRemoveAddressRange ( 149*385cc6b4SJerry Jelinek ACPI_ADR_SPACE_TYPE SpaceId, 150*385cc6b4SJerry Jelinek ACPI_NAMESPACE_NODE *RegionNode) 151*385cc6b4SJerry Jelinek { 152*385cc6b4SJerry Jelinek ACPI_ADDRESS_RANGE *RangeInfo; 153*385cc6b4SJerry Jelinek ACPI_ADDRESS_RANGE *Prev; 154*385cc6b4SJerry Jelinek 155*385cc6b4SJerry Jelinek 156*385cc6b4SJerry Jelinek ACPI_FUNCTION_TRACE (UtRemoveAddressRange); 157*385cc6b4SJerry Jelinek 158*385cc6b4SJerry Jelinek 159*385cc6b4SJerry Jelinek if ((SpaceId != ACPI_ADR_SPACE_SYSTEM_MEMORY) && 160*385cc6b4SJerry Jelinek (SpaceId != ACPI_ADR_SPACE_SYSTEM_IO)) 161*385cc6b4SJerry Jelinek { 162*385cc6b4SJerry Jelinek return_VOID; 163*385cc6b4SJerry Jelinek } 164*385cc6b4SJerry Jelinek 165*385cc6b4SJerry Jelinek /* Get the appropriate list head and check the list */ 166*385cc6b4SJerry Jelinek 167*385cc6b4SJerry Jelinek RangeInfo = Prev = AcpiGbl_AddressRangeList[SpaceId]; 168*385cc6b4SJerry Jelinek while (RangeInfo) 169*385cc6b4SJerry Jelinek { 170*385cc6b4SJerry Jelinek if (RangeInfo->RegionNode == RegionNode) 171*385cc6b4SJerry Jelinek { 172*385cc6b4SJerry Jelinek if (RangeInfo == Prev) /* Found at list head */ 173*385cc6b4SJerry Jelinek { 174*385cc6b4SJerry Jelinek AcpiGbl_AddressRangeList[SpaceId] = RangeInfo->Next; 175*385cc6b4SJerry Jelinek } 176*385cc6b4SJerry Jelinek else 177*385cc6b4SJerry Jelinek { 178*385cc6b4SJerry Jelinek Prev->Next = RangeInfo->Next; 179*385cc6b4SJerry Jelinek } 180*385cc6b4SJerry Jelinek 181*385cc6b4SJerry Jelinek ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 182*385cc6b4SJerry Jelinek "\nRemoved [%4.4s] address range: 0x%8.8X%8.8X-0x%8.8X%8.8X\n", 183*385cc6b4SJerry Jelinek AcpiUtGetNodeName (RangeInfo->RegionNode), 184*385cc6b4SJerry Jelinek ACPI_FORMAT_UINT64 (RangeInfo->StartAddress), 185*385cc6b4SJerry Jelinek ACPI_FORMAT_UINT64 (RangeInfo->EndAddress))); 186*385cc6b4SJerry Jelinek 187*385cc6b4SJerry Jelinek ACPI_FREE (RangeInfo); 188*385cc6b4SJerry Jelinek return_VOID; 189*385cc6b4SJerry Jelinek } 190*385cc6b4SJerry Jelinek 191*385cc6b4SJerry Jelinek Prev = RangeInfo; 192*385cc6b4SJerry Jelinek RangeInfo = RangeInfo->Next; 193*385cc6b4SJerry Jelinek } 194*385cc6b4SJerry Jelinek 195*385cc6b4SJerry Jelinek return_VOID; 196*385cc6b4SJerry Jelinek } 197*385cc6b4SJerry Jelinek 198*385cc6b4SJerry Jelinek 199*385cc6b4SJerry Jelinek /******************************************************************************* 200*385cc6b4SJerry Jelinek * 201*385cc6b4SJerry Jelinek * FUNCTION: AcpiUtCheckAddressRange 202*385cc6b4SJerry Jelinek * 203*385cc6b4SJerry Jelinek * PARAMETERS: SpaceId - Address space ID 204*385cc6b4SJerry Jelinek * Address - Start address 205*385cc6b4SJerry Jelinek * Length - Length of address range 206*385cc6b4SJerry Jelinek * Warn - TRUE if warning on overlap desired 207*385cc6b4SJerry Jelinek * 208*385cc6b4SJerry Jelinek * RETURN: Count of the number of conflicts detected. Zero is always 209*385cc6b4SJerry Jelinek * returned for Space IDs other than Memory or I/O. 210*385cc6b4SJerry Jelinek * 211*385cc6b4SJerry Jelinek * DESCRIPTION: Check if the input address range overlaps any of the 212*385cc6b4SJerry Jelinek * ASL operation region address ranges. The only supported 213*385cc6b4SJerry Jelinek * Space IDs are Memory and I/O. 214*385cc6b4SJerry Jelinek * 215*385cc6b4SJerry Jelinek * MUTEX: Assumes the namespace is locked. 216*385cc6b4SJerry Jelinek * 217*385cc6b4SJerry Jelinek ******************************************************************************/ 218*385cc6b4SJerry Jelinek 219*385cc6b4SJerry Jelinek UINT32 220*385cc6b4SJerry Jelinek AcpiUtCheckAddressRange ( 221*385cc6b4SJerry Jelinek ACPI_ADR_SPACE_TYPE SpaceId, 222*385cc6b4SJerry Jelinek ACPI_PHYSICAL_ADDRESS Address, 223*385cc6b4SJerry Jelinek UINT32 Length, 224*385cc6b4SJerry Jelinek BOOLEAN Warn) 225*385cc6b4SJerry Jelinek { 226*385cc6b4SJerry Jelinek ACPI_ADDRESS_RANGE *RangeInfo; 227*385cc6b4SJerry Jelinek ACPI_PHYSICAL_ADDRESS EndAddress; 228*385cc6b4SJerry Jelinek char *Pathname; 229*385cc6b4SJerry Jelinek UINT32 OverlapCount = 0; 230*385cc6b4SJerry Jelinek 231*385cc6b4SJerry Jelinek 232*385cc6b4SJerry Jelinek ACPI_FUNCTION_TRACE (UtCheckAddressRange); 233*385cc6b4SJerry Jelinek 234*385cc6b4SJerry Jelinek 235*385cc6b4SJerry Jelinek if ((SpaceId != ACPI_ADR_SPACE_SYSTEM_MEMORY) && 236*385cc6b4SJerry Jelinek (SpaceId != ACPI_ADR_SPACE_SYSTEM_IO)) 237*385cc6b4SJerry Jelinek { 238*385cc6b4SJerry Jelinek return_UINT32 (0); 239*385cc6b4SJerry Jelinek } 240*385cc6b4SJerry Jelinek 241*385cc6b4SJerry Jelinek RangeInfo = AcpiGbl_AddressRangeList[SpaceId]; 242*385cc6b4SJerry Jelinek EndAddress = Address + Length - 1; 243*385cc6b4SJerry Jelinek 244*385cc6b4SJerry Jelinek /* Check entire list for all possible conflicts */ 245*385cc6b4SJerry Jelinek 246*385cc6b4SJerry Jelinek while (RangeInfo) 247*385cc6b4SJerry Jelinek { 248*385cc6b4SJerry Jelinek /* 249*385cc6b4SJerry Jelinek * Check if the requested address/length overlaps this 250*385cc6b4SJerry Jelinek * address range. There are four cases to consider: 251*385cc6b4SJerry Jelinek * 252*385cc6b4SJerry Jelinek * 1) Input address/length is contained completely in the 253*385cc6b4SJerry Jelinek * address range 254*385cc6b4SJerry Jelinek * 2) Input address/length overlaps range at the range start 255*385cc6b4SJerry Jelinek * 3) Input address/length overlaps range at the range end 256*385cc6b4SJerry Jelinek * 4) Input address/length completely encompasses the range 257*385cc6b4SJerry Jelinek */ 258*385cc6b4SJerry Jelinek if ((Address <= RangeInfo->EndAddress) && 259*385cc6b4SJerry Jelinek (EndAddress >= RangeInfo->StartAddress)) 260*385cc6b4SJerry Jelinek { 261*385cc6b4SJerry Jelinek /* Found an address range overlap */ 262*385cc6b4SJerry Jelinek 263*385cc6b4SJerry Jelinek OverlapCount++; 264*385cc6b4SJerry Jelinek if (Warn) /* Optional warning message */ 265*385cc6b4SJerry Jelinek { 266*385cc6b4SJerry Jelinek Pathname = AcpiNsGetNormalizedPathname (RangeInfo->RegionNode, TRUE); 267*385cc6b4SJerry Jelinek 268*385cc6b4SJerry Jelinek ACPI_WARNING ((AE_INFO, 269*385cc6b4SJerry Jelinek "%s range 0x%8.8X%8.8X-0x%8.8X%8.8X conflicts with OpRegion 0x%8.8X%8.8X-0x%8.8X%8.8X (%s)", 270*385cc6b4SJerry Jelinek AcpiUtGetRegionName (SpaceId), 271*385cc6b4SJerry Jelinek ACPI_FORMAT_UINT64 (Address), 272*385cc6b4SJerry Jelinek ACPI_FORMAT_UINT64 (EndAddress), 273*385cc6b4SJerry Jelinek ACPI_FORMAT_UINT64 (RangeInfo->StartAddress), 274*385cc6b4SJerry Jelinek ACPI_FORMAT_UINT64 (RangeInfo->EndAddress), 275*385cc6b4SJerry Jelinek Pathname)); 276*385cc6b4SJerry Jelinek ACPI_FREE (Pathname); 277*385cc6b4SJerry Jelinek } 278*385cc6b4SJerry Jelinek } 279*385cc6b4SJerry Jelinek 280*385cc6b4SJerry Jelinek RangeInfo = RangeInfo->Next; 281*385cc6b4SJerry Jelinek } 282*385cc6b4SJerry Jelinek 283*385cc6b4SJerry Jelinek return_UINT32 (OverlapCount); 284*385cc6b4SJerry Jelinek } 285*385cc6b4SJerry Jelinek 286*385cc6b4SJerry Jelinek 287*385cc6b4SJerry Jelinek /******************************************************************************* 288*385cc6b4SJerry Jelinek * 289*385cc6b4SJerry Jelinek * FUNCTION: AcpiUtDeleteAddressLists 290*385cc6b4SJerry Jelinek * 291*385cc6b4SJerry Jelinek * PARAMETERS: None 292*385cc6b4SJerry Jelinek * 293*385cc6b4SJerry Jelinek * RETURN: None 294*385cc6b4SJerry Jelinek * 295*385cc6b4SJerry Jelinek * DESCRIPTION: Delete all global address range lists (called during 296*385cc6b4SJerry Jelinek * subsystem shutdown). 297*385cc6b4SJerry Jelinek * 298*385cc6b4SJerry Jelinek ******************************************************************************/ 299*385cc6b4SJerry Jelinek 300*385cc6b4SJerry Jelinek void 301*385cc6b4SJerry Jelinek AcpiUtDeleteAddressLists ( 302*385cc6b4SJerry Jelinek void) 303*385cc6b4SJerry Jelinek { 304*385cc6b4SJerry Jelinek ACPI_ADDRESS_RANGE *Next; 305*385cc6b4SJerry Jelinek ACPI_ADDRESS_RANGE *RangeInfo; 306*385cc6b4SJerry Jelinek int i; 307*385cc6b4SJerry Jelinek 308*385cc6b4SJerry Jelinek 309*385cc6b4SJerry Jelinek /* Delete all elements in all address range lists */ 310*385cc6b4SJerry Jelinek 311*385cc6b4SJerry Jelinek for (i = 0; i < ACPI_ADDRESS_RANGE_MAX; i++) 312*385cc6b4SJerry Jelinek { 313*385cc6b4SJerry Jelinek Next = AcpiGbl_AddressRangeList[i]; 314*385cc6b4SJerry Jelinek 315*385cc6b4SJerry Jelinek while (Next) 316*385cc6b4SJerry Jelinek { 317*385cc6b4SJerry Jelinek RangeInfo = Next; 318*385cc6b4SJerry Jelinek Next = RangeInfo->Next; 319*385cc6b4SJerry Jelinek ACPI_FREE (RangeInfo); 320*385cc6b4SJerry Jelinek } 321*385cc6b4SJerry Jelinek 322*385cc6b4SJerry Jelinek AcpiGbl_AddressRangeList[i] = NULL; 323*385cc6b4SJerry Jelinek } 324*385cc6b4SJerry Jelinek } 325