1/****************************************************************************** 2 * 3 * Module Name: utaddress - OpRegion address range check 4 * 5 *****************************************************************************/ 6 7/* 8 * Copyright (C) 2000 - 2012, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 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. 25 * 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. 29 * 30 * NO WARRANTY 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. 42 */ 43 44#define __UTADDRESS_C__ 45
| 1/****************************************************************************** 2 * 3 * Module Name: utaddress - OpRegion address range check 4 * 5 *****************************************************************************/ 6 7/* 8 * Copyright (C) 2000 - 2012, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 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. 25 * 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. 29 * 30 * NO WARRANTY 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. 42 */ 43 44#define __UTADDRESS_C__ 45
|
49 50 51#define _COMPONENT ACPI_UTILITIES 52 ACPI_MODULE_NAME ("utaddress") 53 54 55/******************************************************************************* 56 * 57 * FUNCTION: AcpiUtAddAddressRange 58 * 59 * PARAMETERS: SpaceId - Address space ID 60 * Address - OpRegion start address 61 * Length - OpRegion length 62 * RegionNode - OpRegion namespace node 63 * 64 * RETURN: Status 65 * 66 * DESCRIPTION: Add the Operation Region address range to the global list. 67 * The only supported Space IDs are Memory and I/O. Called when 68 * the OpRegion address/length operands are fully evaluated. 69 * 70 * MUTEX: Locks the namespace 71 * 72 * NOTE: Because this interface is only called when an OpRegion argument 73 * list is evaluated, there cannot be any duplicate RegionNodes. 74 * Duplicate Address/Length values are allowed, however, so that multiple 75 * address conflicts can be detected. 76 * 77 ******************************************************************************/ 78 79ACPI_STATUS 80AcpiUtAddAddressRange ( 81 ACPI_ADR_SPACE_TYPE SpaceId, 82 ACPI_PHYSICAL_ADDRESS Address, 83 UINT32 Length, 84 ACPI_NAMESPACE_NODE *RegionNode) 85{ 86 ACPI_ADDRESS_RANGE *RangeInfo; 87 ACPI_STATUS Status; 88 89 90 ACPI_FUNCTION_TRACE (UtAddAddressRange); 91 92 93 if ((SpaceId != ACPI_ADR_SPACE_SYSTEM_MEMORY) && 94 (SpaceId != ACPI_ADR_SPACE_SYSTEM_IO)) 95 { 96 return_ACPI_STATUS (AE_OK); 97 } 98 99 /* Allocate/init a new info block, add it to the appropriate list */ 100 101 RangeInfo = ACPI_ALLOCATE (sizeof (ACPI_ADDRESS_RANGE)); 102 if (!RangeInfo) 103 { 104 return_ACPI_STATUS (AE_NO_MEMORY); 105 } 106 107 RangeInfo->StartAddress = Address; 108 RangeInfo->EndAddress = (Address + Length - 1); 109 RangeInfo->RegionNode = RegionNode; 110 111 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 112 if (ACPI_FAILURE (Status)) 113 { 114 ACPI_FREE (RangeInfo); 115 return_ACPI_STATUS (Status); 116 } 117 118 RangeInfo->Next = AcpiGbl_AddressRangeList[SpaceId]; 119 AcpiGbl_AddressRangeList[SpaceId] = RangeInfo; 120 121 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 122 "\nAdded [%4.4s] address range: 0x%p-0x%p\n", 123 AcpiUtGetNodeName (RangeInfo->RegionNode), 124 ACPI_CAST_PTR (void, Address), 125 ACPI_CAST_PTR (void, RangeInfo->EndAddress))); 126 127 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 128 return_ACPI_STATUS (AE_OK); 129} 130 131 132/******************************************************************************* 133 * 134 * FUNCTION: AcpiUtRemoveAddressRange 135 * 136 * PARAMETERS: SpaceId - Address space ID 137 * RegionNode - OpRegion namespace node 138 * 139 * RETURN: None 140 * 141 * DESCRIPTION: Remove the Operation Region from the global list. The only 142 * supported Space IDs are Memory and I/O. Called when an 143 * OpRegion is deleted. 144 * 145 * MUTEX: Assumes the namespace is locked 146 * 147 ******************************************************************************/ 148 149void 150AcpiUtRemoveAddressRange ( 151 ACPI_ADR_SPACE_TYPE SpaceId, 152 ACPI_NAMESPACE_NODE *RegionNode) 153{ 154 ACPI_ADDRESS_RANGE *RangeInfo; 155 ACPI_ADDRESS_RANGE *Prev; 156 157 158 ACPI_FUNCTION_TRACE (UtRemoveAddressRange); 159 160 161 if ((SpaceId != ACPI_ADR_SPACE_SYSTEM_MEMORY) && 162 (SpaceId != ACPI_ADR_SPACE_SYSTEM_IO)) 163 { 164 return_VOID; 165 } 166 167 /* Get the appropriate list head and check the list */ 168 169 RangeInfo = Prev = AcpiGbl_AddressRangeList[SpaceId]; 170 while (RangeInfo) 171 { 172 if (RangeInfo->RegionNode == RegionNode) 173 { 174 if (RangeInfo == Prev) /* Found at list head */ 175 { 176 AcpiGbl_AddressRangeList[SpaceId] = RangeInfo->Next; 177 } 178 else 179 { 180 Prev->Next = RangeInfo->Next; 181 } 182 183 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 184 "\nRemoved [%4.4s] address range: 0x%p-0x%p\n", 185 AcpiUtGetNodeName (RangeInfo->RegionNode), 186 ACPI_CAST_PTR (void, RangeInfo->StartAddress), 187 ACPI_CAST_PTR (void, RangeInfo->EndAddress))); 188 189 ACPI_FREE (RangeInfo); 190 return_VOID; 191 } 192 193 Prev = RangeInfo; 194 RangeInfo = RangeInfo->Next; 195 } 196 197 return_VOID; 198} 199 200 201/******************************************************************************* 202 * 203 * FUNCTION: AcpiUtCheckAddressRange 204 * 205 * PARAMETERS: SpaceId - Address space ID 206 * Address - Start address 207 * Length - Length of address range 208 * Warn - TRUE if warning on overlap desired 209 * 210 * RETURN: Count of the number of conflicts detected. Zero is always 211 * returned for Space IDs other than Memory or I/O. 212 * 213 * DESCRIPTION: Check if the input address range overlaps any of the 214 * ASL operation region address ranges. The only supported 215 * Space IDs are Memory and I/O. 216 * 217 * MUTEX: Assumes the namespace is locked. 218 * 219 ******************************************************************************/ 220 221UINT32 222AcpiUtCheckAddressRange ( 223 ACPI_ADR_SPACE_TYPE SpaceId, 224 ACPI_PHYSICAL_ADDRESS Address, 225 UINT32 Length, 226 BOOLEAN Warn) 227{ 228 ACPI_ADDRESS_RANGE *RangeInfo; 229 ACPI_PHYSICAL_ADDRESS EndAddress; 230 char *Pathname; 231 UINT32 OverlapCount = 0; 232 233 234 ACPI_FUNCTION_TRACE (UtCheckAddressRange); 235 236 237 if ((SpaceId != ACPI_ADR_SPACE_SYSTEM_MEMORY) && 238 (SpaceId != ACPI_ADR_SPACE_SYSTEM_IO)) 239 { 240 return_UINT32 (0); 241 } 242 243 RangeInfo = AcpiGbl_AddressRangeList[SpaceId]; 244 EndAddress = Address + Length - 1; 245 246 /* Check entire list for all possible conflicts */ 247 248 while (RangeInfo) 249 { 250 /* 251 * Check if the requested Address/Length overlaps this AddressRange. 252 * Four cases to consider: 253 * 254 * 1) Input address/length is contained completely in the address range 255 * 2) Input address/length overlaps range at the range start 256 * 3) Input address/length overlaps range at the range end 257 * 4) Input address/length completely encompasses the range 258 */ 259 if ((Address <= RangeInfo->EndAddress) && 260 (EndAddress >= RangeInfo->StartAddress)) 261 { 262 /* Found an address range overlap */ 263 264 OverlapCount++; 265 if (Warn) /* Optional warning message */ 266 { 267 Pathname = AcpiNsGetExternalPathname (RangeInfo->RegionNode); 268 269 ACPI_WARNING ((AE_INFO, 270 "0x%p-0x%p %s conflicts with Region %s %d", 271 ACPI_CAST_PTR (void, Address), 272 ACPI_CAST_PTR (void, EndAddress), 273 AcpiUtGetRegionName (SpaceId), Pathname, OverlapCount)); 274 ACPI_FREE (Pathname); 275 } 276 } 277 278 RangeInfo = RangeInfo->Next; 279 } 280 281 return_UINT32 (OverlapCount); 282} 283 284 285/******************************************************************************* 286 * 287 * FUNCTION: AcpiUtDeleteAddressLists 288 * 289 * PARAMETERS: None 290 * 291 * RETURN: None 292 * 293 * DESCRIPTION: Delete all global address range lists (called during 294 * subsystem shutdown). 295 * 296 ******************************************************************************/ 297 298void 299AcpiUtDeleteAddressLists ( 300 void) 301{ 302 ACPI_ADDRESS_RANGE *Next; 303 ACPI_ADDRESS_RANGE *RangeInfo; 304 int i; 305 306 307 /* Delete all elements in all address range lists */ 308 309 for (i = 0; i < ACPI_ADDRESS_RANGE_MAX; i++) 310 { 311 Next = AcpiGbl_AddressRangeList[i]; 312 313 while (Next) 314 { 315 RangeInfo = Next; 316 Next = RangeInfo->Next; 317 ACPI_FREE (RangeInfo); 318 } 319 320 AcpiGbl_AddressRangeList[i] = NULL; 321 } 322}
| 49 50 51#define _COMPONENT ACPI_UTILITIES 52 ACPI_MODULE_NAME ("utaddress") 53 54 55/******************************************************************************* 56 * 57 * FUNCTION: AcpiUtAddAddressRange 58 * 59 * PARAMETERS: SpaceId - Address space ID 60 * Address - OpRegion start address 61 * Length - OpRegion length 62 * RegionNode - OpRegion namespace node 63 * 64 * RETURN: Status 65 * 66 * DESCRIPTION: Add the Operation Region address range to the global list. 67 * The only supported Space IDs are Memory and I/O. Called when 68 * the OpRegion address/length operands are fully evaluated. 69 * 70 * MUTEX: Locks the namespace 71 * 72 * NOTE: Because this interface is only called when an OpRegion argument 73 * list is evaluated, there cannot be any duplicate RegionNodes. 74 * Duplicate Address/Length values are allowed, however, so that multiple 75 * address conflicts can be detected. 76 * 77 ******************************************************************************/ 78 79ACPI_STATUS 80AcpiUtAddAddressRange ( 81 ACPI_ADR_SPACE_TYPE SpaceId, 82 ACPI_PHYSICAL_ADDRESS Address, 83 UINT32 Length, 84 ACPI_NAMESPACE_NODE *RegionNode) 85{ 86 ACPI_ADDRESS_RANGE *RangeInfo; 87 ACPI_STATUS Status; 88 89 90 ACPI_FUNCTION_TRACE (UtAddAddressRange); 91 92 93 if ((SpaceId != ACPI_ADR_SPACE_SYSTEM_MEMORY) && 94 (SpaceId != ACPI_ADR_SPACE_SYSTEM_IO)) 95 { 96 return_ACPI_STATUS (AE_OK); 97 } 98 99 /* Allocate/init a new info block, add it to the appropriate list */ 100 101 RangeInfo = ACPI_ALLOCATE (sizeof (ACPI_ADDRESS_RANGE)); 102 if (!RangeInfo) 103 { 104 return_ACPI_STATUS (AE_NO_MEMORY); 105 } 106 107 RangeInfo->StartAddress = Address; 108 RangeInfo->EndAddress = (Address + Length - 1); 109 RangeInfo->RegionNode = RegionNode; 110 111 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 112 if (ACPI_FAILURE (Status)) 113 { 114 ACPI_FREE (RangeInfo); 115 return_ACPI_STATUS (Status); 116 } 117 118 RangeInfo->Next = AcpiGbl_AddressRangeList[SpaceId]; 119 AcpiGbl_AddressRangeList[SpaceId] = RangeInfo; 120 121 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 122 "\nAdded [%4.4s] address range: 0x%p-0x%p\n", 123 AcpiUtGetNodeName (RangeInfo->RegionNode), 124 ACPI_CAST_PTR (void, Address), 125 ACPI_CAST_PTR (void, RangeInfo->EndAddress))); 126 127 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 128 return_ACPI_STATUS (AE_OK); 129} 130 131 132/******************************************************************************* 133 * 134 * FUNCTION: AcpiUtRemoveAddressRange 135 * 136 * PARAMETERS: SpaceId - Address space ID 137 * RegionNode - OpRegion namespace node 138 * 139 * RETURN: None 140 * 141 * DESCRIPTION: Remove the Operation Region from the global list. The only 142 * supported Space IDs are Memory and I/O. Called when an 143 * OpRegion is deleted. 144 * 145 * MUTEX: Assumes the namespace is locked 146 * 147 ******************************************************************************/ 148 149void 150AcpiUtRemoveAddressRange ( 151 ACPI_ADR_SPACE_TYPE SpaceId, 152 ACPI_NAMESPACE_NODE *RegionNode) 153{ 154 ACPI_ADDRESS_RANGE *RangeInfo; 155 ACPI_ADDRESS_RANGE *Prev; 156 157 158 ACPI_FUNCTION_TRACE (UtRemoveAddressRange); 159 160 161 if ((SpaceId != ACPI_ADR_SPACE_SYSTEM_MEMORY) && 162 (SpaceId != ACPI_ADR_SPACE_SYSTEM_IO)) 163 { 164 return_VOID; 165 } 166 167 /* Get the appropriate list head and check the list */ 168 169 RangeInfo = Prev = AcpiGbl_AddressRangeList[SpaceId]; 170 while (RangeInfo) 171 { 172 if (RangeInfo->RegionNode == RegionNode) 173 { 174 if (RangeInfo == Prev) /* Found at list head */ 175 { 176 AcpiGbl_AddressRangeList[SpaceId] = RangeInfo->Next; 177 } 178 else 179 { 180 Prev->Next = RangeInfo->Next; 181 } 182 183 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 184 "\nRemoved [%4.4s] address range: 0x%p-0x%p\n", 185 AcpiUtGetNodeName (RangeInfo->RegionNode), 186 ACPI_CAST_PTR (void, RangeInfo->StartAddress), 187 ACPI_CAST_PTR (void, RangeInfo->EndAddress))); 188 189 ACPI_FREE (RangeInfo); 190 return_VOID; 191 } 192 193 Prev = RangeInfo; 194 RangeInfo = RangeInfo->Next; 195 } 196 197 return_VOID; 198} 199 200 201/******************************************************************************* 202 * 203 * FUNCTION: AcpiUtCheckAddressRange 204 * 205 * PARAMETERS: SpaceId - Address space ID 206 * Address - Start address 207 * Length - Length of address range 208 * Warn - TRUE if warning on overlap desired 209 * 210 * RETURN: Count of the number of conflicts detected. Zero is always 211 * returned for Space IDs other than Memory or I/O. 212 * 213 * DESCRIPTION: Check if the input address range overlaps any of the 214 * ASL operation region address ranges. The only supported 215 * Space IDs are Memory and I/O. 216 * 217 * MUTEX: Assumes the namespace is locked. 218 * 219 ******************************************************************************/ 220 221UINT32 222AcpiUtCheckAddressRange ( 223 ACPI_ADR_SPACE_TYPE SpaceId, 224 ACPI_PHYSICAL_ADDRESS Address, 225 UINT32 Length, 226 BOOLEAN Warn) 227{ 228 ACPI_ADDRESS_RANGE *RangeInfo; 229 ACPI_PHYSICAL_ADDRESS EndAddress; 230 char *Pathname; 231 UINT32 OverlapCount = 0; 232 233 234 ACPI_FUNCTION_TRACE (UtCheckAddressRange); 235 236 237 if ((SpaceId != ACPI_ADR_SPACE_SYSTEM_MEMORY) && 238 (SpaceId != ACPI_ADR_SPACE_SYSTEM_IO)) 239 { 240 return_UINT32 (0); 241 } 242 243 RangeInfo = AcpiGbl_AddressRangeList[SpaceId]; 244 EndAddress = Address + Length - 1; 245 246 /* Check entire list for all possible conflicts */ 247 248 while (RangeInfo) 249 { 250 /* 251 * Check if the requested Address/Length overlaps this AddressRange. 252 * Four cases to consider: 253 * 254 * 1) Input address/length is contained completely in the address range 255 * 2) Input address/length overlaps range at the range start 256 * 3) Input address/length overlaps range at the range end 257 * 4) Input address/length completely encompasses the range 258 */ 259 if ((Address <= RangeInfo->EndAddress) && 260 (EndAddress >= RangeInfo->StartAddress)) 261 { 262 /* Found an address range overlap */ 263 264 OverlapCount++; 265 if (Warn) /* Optional warning message */ 266 { 267 Pathname = AcpiNsGetExternalPathname (RangeInfo->RegionNode); 268 269 ACPI_WARNING ((AE_INFO, 270 "0x%p-0x%p %s conflicts with Region %s %d", 271 ACPI_CAST_PTR (void, Address), 272 ACPI_CAST_PTR (void, EndAddress), 273 AcpiUtGetRegionName (SpaceId), Pathname, OverlapCount)); 274 ACPI_FREE (Pathname); 275 } 276 } 277 278 RangeInfo = RangeInfo->Next; 279 } 280 281 return_UINT32 (OverlapCount); 282} 283 284 285/******************************************************************************* 286 * 287 * FUNCTION: AcpiUtDeleteAddressLists 288 * 289 * PARAMETERS: None 290 * 291 * RETURN: None 292 * 293 * DESCRIPTION: Delete all global address range lists (called during 294 * subsystem shutdown). 295 * 296 ******************************************************************************/ 297 298void 299AcpiUtDeleteAddressLists ( 300 void) 301{ 302 ACPI_ADDRESS_RANGE *Next; 303 ACPI_ADDRESS_RANGE *RangeInfo; 304 int i; 305 306 307 /* Delete all elements in all address range lists */ 308 309 for (i = 0; i < ACPI_ADDRESS_RANGE_MAX; i++) 310 { 311 Next = AcpiGbl_AddressRangeList[i]; 312 313 while (Next) 314 { 315 RangeInfo = Next; 316 Next = RangeInfo->Next; 317 ACPI_FREE (RangeInfo); 318 } 319 320 AcpiGbl_AddressRangeList[i] = NULL; 321 } 322}
|