1 /****************************************************************************** 2 * 3 * Module Name: utalloc - local memory allocation routines 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2019, 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 #include "acpi.h" 45 #include "accommon.h" 46 #include "acdebug.h" 47 48 #define _COMPONENT ACPI_UTILITIES 49 ACPI_MODULE_NAME ("utalloc") 50 51 52 #if !defined (USE_NATIVE_ALLOCATE_ZEROED) 53 /******************************************************************************* 54 * 55 * FUNCTION: AcpiOsAllocateZeroed 56 * 57 * PARAMETERS: Size - Size of the allocation 58 * 59 * RETURN: Address of the allocated memory on success, NULL on failure. 60 * 61 * DESCRIPTION: Subsystem equivalent of calloc. Allocate and zero memory. 62 * This is the default implementation. Can be overridden via the 63 * USE_NATIVE_ALLOCATE_ZEROED flag. 64 * 65 ******************************************************************************/ 66 67 void * 68 AcpiOsAllocateZeroed ( 69 ACPI_SIZE Size) 70 { 71 void *Allocation; 72 73 74 ACPI_FUNCTION_ENTRY (); 75 76 77 Allocation = AcpiOsAllocate (Size); 78 if (Allocation) 79 { 80 /* Clear the memory block */ 81 82 memset (Allocation, 0, Size); 83 } 84 85 return (Allocation); 86 } 87 88 #endif /* !USE_NATIVE_ALLOCATE_ZEROED */ 89 90 91 /******************************************************************************* 92 * 93 * FUNCTION: AcpiUtCreateCaches 94 * 95 * PARAMETERS: None 96 * 97 * RETURN: Status 98 * 99 * DESCRIPTION: Create all local caches 100 * 101 ******************************************************************************/ 102 103 ACPI_STATUS 104 AcpiUtCreateCaches ( 105 void) 106 { 107 ACPI_STATUS Status; 108 109 110 /* Object Caches, for frequently used objects */ 111 112 Status = AcpiOsCreateCache ("Acpi-Namespace", sizeof (ACPI_NAMESPACE_NODE), 113 ACPI_MAX_NAMESPACE_CACHE_DEPTH, &AcpiGbl_NamespaceCache); 114 if (ACPI_FAILURE (Status)) 115 { 116 return (Status); 117 } 118 119 Status = AcpiOsCreateCache ("Acpi-State", sizeof (ACPI_GENERIC_STATE), 120 ACPI_MAX_STATE_CACHE_DEPTH, &AcpiGbl_StateCache); 121 if (ACPI_FAILURE (Status)) 122 { 123 return (Status); 124 } 125 126 Status = AcpiOsCreateCache ("Acpi-Parse", sizeof (ACPI_PARSE_OBJ_COMMON), 127 ACPI_MAX_PARSE_CACHE_DEPTH, &AcpiGbl_PsNodeCache); 128 if (ACPI_FAILURE (Status)) 129 { 130 return (Status); 131 } 132 133 Status = AcpiOsCreateCache ("Acpi-ParseExt", sizeof (ACPI_PARSE_OBJ_NAMED), 134 ACPI_MAX_EXTPARSE_CACHE_DEPTH, &AcpiGbl_PsNodeExtCache); 135 if (ACPI_FAILURE (Status)) 136 { 137 return (Status); 138 } 139 140 Status = AcpiOsCreateCache ("Acpi-Operand", sizeof (ACPI_OPERAND_OBJECT), 141 ACPI_MAX_OBJECT_CACHE_DEPTH, &AcpiGbl_OperandCache); 142 if (ACPI_FAILURE (Status)) 143 { 144 return (Status); 145 } 146 147 #ifdef ACPI_ASL_COMPILER 148 /* 149 * For use with the ASL-/ASL+ option. This cache keeps track of regular 150 * 0xA9 0x01 comments. 151 */ 152 Status = AcpiOsCreateCache ("Acpi-Comment", sizeof (ACPI_COMMENT_NODE), 153 ACPI_MAX_COMMENT_CACHE_DEPTH, &AcpiGbl_RegCommentCache); 154 if (ACPI_FAILURE (Status)) 155 { 156 return (Status); 157 } 158 159 /* 160 * This cache keeps track of the starting addresses of where the comments 161 * lie. This helps prevent duplication of comments. 162 */ 163 Status = AcpiOsCreateCache ("Acpi-Comment-Addr", sizeof (ACPI_COMMENT_ADDR_NODE), 164 ACPI_MAX_COMMENT_CACHE_DEPTH, &AcpiGbl_CommentAddrCache); 165 if (ACPI_FAILURE (Status)) 166 { 167 return (Status); 168 } 169 170 /* 171 * This cache will be used for nodes that represent files. 172 */ 173 Status = AcpiOsCreateCache ("Acpi-File", sizeof (ACPI_FILE_NODE), 174 ACPI_MAX_COMMENT_CACHE_DEPTH, &AcpiGbl_FileCache); 175 if (ACPI_FAILURE (Status)) 176 { 177 return (Status); 178 } 179 #endif 180 181 182 #ifdef ACPI_DBG_TRACK_ALLOCATIONS 183 184 /* Memory allocation lists */ 185 186 Status = AcpiUtCreateList ("Acpi-Global", 0, 187 &AcpiGbl_GlobalList); 188 if (ACPI_FAILURE (Status)) 189 { 190 return (Status); 191 } 192 193 Status = AcpiUtCreateList ("Acpi-Namespace", sizeof (ACPI_NAMESPACE_NODE), 194 &AcpiGbl_NsNodeList); 195 if (ACPI_FAILURE (Status)) 196 { 197 return (Status); 198 } 199 #endif 200 201 return (AE_OK); 202 } 203 204 205 /******************************************************************************* 206 * 207 * FUNCTION: AcpiUtDeleteCaches 208 * 209 * PARAMETERS: None 210 * 211 * RETURN: Status 212 * 213 * DESCRIPTION: Purge and delete all local caches 214 * 215 ******************************************************************************/ 216 217 ACPI_STATUS 218 AcpiUtDeleteCaches ( 219 void) 220 { 221 #ifdef ACPI_DBG_TRACK_ALLOCATIONS 222 char Buffer[7]; 223 224 225 if (AcpiGbl_DisplayFinalMemStats) 226 { 227 strcpy (Buffer, "MEMORY"); 228 (void) AcpiDbDisplayStatistics (Buffer); 229 } 230 #endif 231 232 (void) AcpiOsDeleteCache (AcpiGbl_NamespaceCache); 233 AcpiGbl_NamespaceCache = NULL; 234 235 (void) AcpiOsDeleteCache (AcpiGbl_StateCache); 236 AcpiGbl_StateCache = NULL; 237 238 (void) AcpiOsDeleteCache (AcpiGbl_OperandCache); 239 AcpiGbl_OperandCache = NULL; 240 241 (void) AcpiOsDeleteCache (AcpiGbl_PsNodeCache); 242 AcpiGbl_PsNodeCache = NULL; 243 244 (void) AcpiOsDeleteCache (AcpiGbl_PsNodeExtCache); 245 AcpiGbl_PsNodeExtCache = NULL; 246 247 #ifdef ACPI_ASL_COMPILER 248 (void) AcpiOsDeleteCache (AcpiGbl_RegCommentCache); 249 AcpiGbl_RegCommentCache = NULL; 250 251 (void) AcpiOsDeleteCache (AcpiGbl_CommentAddrCache); 252 AcpiGbl_CommentAddrCache = NULL; 253 254 (void) AcpiOsDeleteCache (AcpiGbl_FileCache); 255 AcpiGbl_FileCache = NULL; 256 #endif 257 258 #ifdef ACPI_DBG_TRACK_ALLOCATIONS 259 260 /* Debug only - display leftover memory allocation, if any */ 261 262 AcpiUtDumpAllocations (ACPI_UINT32_MAX, NULL); 263 264 /* Free memory lists */ 265 266 AcpiOsFree (AcpiGbl_GlobalList); 267 AcpiGbl_GlobalList = NULL; 268 269 AcpiOsFree (AcpiGbl_NsNodeList); 270 AcpiGbl_NsNodeList = NULL; 271 #endif 272 273 return (AE_OK); 274 } 275 276 277 /******************************************************************************* 278 * 279 * FUNCTION: AcpiUtValidateBuffer 280 * 281 * PARAMETERS: Buffer - Buffer descriptor to be validated 282 * 283 * RETURN: Status 284 * 285 * DESCRIPTION: Perform parameter validation checks on an ACPI_BUFFER 286 * 287 ******************************************************************************/ 288 289 ACPI_STATUS 290 AcpiUtValidateBuffer ( 291 ACPI_BUFFER *Buffer) 292 { 293 294 /* Obviously, the structure pointer must be valid */ 295 296 if (!Buffer) 297 { 298 return (AE_BAD_PARAMETER); 299 } 300 301 /* Special semantics for the length */ 302 303 if ((Buffer->Length == ACPI_NO_BUFFER) || 304 (Buffer->Length == ACPI_ALLOCATE_BUFFER) || 305 (Buffer->Length == ACPI_ALLOCATE_LOCAL_BUFFER)) 306 { 307 return (AE_OK); 308 } 309 310 /* Length is valid, the buffer pointer must be also */ 311 312 if (!Buffer->Pointer) 313 { 314 return (AE_BAD_PARAMETER); 315 } 316 317 return (AE_OK); 318 } 319 320 321 /******************************************************************************* 322 * 323 * FUNCTION: AcpiUtInitializeBuffer 324 * 325 * PARAMETERS: Buffer - Buffer to be validated 326 * RequiredLength - Length needed 327 * 328 * RETURN: Status 329 * 330 * DESCRIPTION: Validate that the buffer is of the required length or 331 * allocate a new buffer. Returned buffer is always zeroed. 332 * 333 ******************************************************************************/ 334 335 ACPI_STATUS 336 AcpiUtInitializeBuffer ( 337 ACPI_BUFFER *Buffer, 338 ACPI_SIZE RequiredLength) 339 { 340 ACPI_SIZE InputBufferLength; 341 342 343 /* Parameter validation */ 344 345 if (!Buffer || !RequiredLength) 346 { 347 return (AE_BAD_PARAMETER); 348 } 349 350 /* 351 * Buffer->Length is used as both an input and output parameter. Get the 352 * input actual length and set the output required buffer length. 353 */ 354 InputBufferLength = Buffer->Length; 355 Buffer->Length = RequiredLength; 356 357 /* 358 * The input buffer length contains the actual buffer length, or the type 359 * of buffer to be allocated by this routine. 360 */ 361 switch (InputBufferLength) 362 { 363 case ACPI_NO_BUFFER: 364 365 /* Return the exception (and the required buffer length) */ 366 367 return (AE_BUFFER_OVERFLOW); 368 369 case ACPI_ALLOCATE_BUFFER: 370 /* 371 * Allocate a new buffer. We directectly call AcpiOsAllocate here to 372 * purposefully bypass the (optionally enabled) internal allocation 373 * tracking mechanism since we only want to track internal 374 * allocations. Note: The caller should use AcpiOsFree to free this 375 * buffer created via ACPI_ALLOCATE_BUFFER. 376 */ 377 Buffer->Pointer = AcpiOsAllocate (RequiredLength); 378 break; 379 380 case ACPI_ALLOCATE_LOCAL_BUFFER: 381 382 /* Allocate a new buffer with local interface to allow tracking */ 383 384 Buffer->Pointer = ACPI_ALLOCATE (RequiredLength); 385 break; 386 387 default: 388 389 /* Existing buffer: Validate the size of the buffer */ 390 391 if (InputBufferLength < RequiredLength) 392 { 393 return (AE_BUFFER_OVERFLOW); 394 } 395 break; 396 } 397 398 /* Validate allocation from above or input buffer pointer */ 399 400 if (!Buffer->Pointer) 401 { 402 return (AE_NO_MEMORY); 403 } 404 405 /* Have a valid buffer, clear it */ 406 407 memset (Buffer->Pointer, 0, RequiredLength); 408 return (AE_OK); 409 } 410