utalloc.c revision 281075
1/****************************************************************************** 2 * 3 * Module Name: utalloc - local memory allocation routines 4 * 5 *****************************************************************************/ 6 7/* 8 * Copyright (C) 2000 - 2015, 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 <contrib/dev/acpica/include/acpi.h> 45#include <contrib/dev/acpica/include/accommon.h> 46#include <contrib/dev/acpica/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 67void * 68AcpiOsAllocateZeroed ( 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 ACPI_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 103ACPI_STATUS 104AcpiUtCreateCaches ( 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 148#ifdef ACPI_DBG_TRACK_ALLOCATIONS 149 150 /* Memory allocation lists */ 151 152 Status = AcpiUtCreateList ("Acpi-Global", 0, 153 &AcpiGbl_GlobalList); 154 if (ACPI_FAILURE (Status)) 155 { 156 return (Status); 157 } 158 159 Status = AcpiUtCreateList ("Acpi-Namespace", sizeof (ACPI_NAMESPACE_NODE), 160 &AcpiGbl_NsNodeList); 161 if (ACPI_FAILURE (Status)) 162 { 163 return (Status); 164 } 165#endif 166 167 return (AE_OK); 168} 169 170 171/******************************************************************************* 172 * 173 * FUNCTION: AcpiUtDeleteCaches 174 * 175 * PARAMETERS: None 176 * 177 * RETURN: Status 178 * 179 * DESCRIPTION: Purge and delete all local caches 180 * 181 ******************************************************************************/ 182 183ACPI_STATUS 184AcpiUtDeleteCaches ( 185 void) 186{ 187#ifdef ACPI_DBG_TRACK_ALLOCATIONS 188 char Buffer[7]; 189 190 if (AcpiGbl_DisplayFinalMemStats) 191 { 192 ACPI_STRCPY (Buffer, "MEMORY"); 193 (void) AcpiDbDisplayStatistics (Buffer); 194 } 195#endif 196 197 (void) AcpiOsDeleteCache (AcpiGbl_NamespaceCache); 198 AcpiGbl_NamespaceCache = NULL; 199 200 (void) AcpiOsDeleteCache (AcpiGbl_StateCache); 201 AcpiGbl_StateCache = NULL; 202 203 (void) AcpiOsDeleteCache (AcpiGbl_OperandCache); 204 AcpiGbl_OperandCache = NULL; 205 206 (void) AcpiOsDeleteCache (AcpiGbl_PsNodeCache); 207 AcpiGbl_PsNodeCache = NULL; 208 209 (void) AcpiOsDeleteCache (AcpiGbl_PsNodeExtCache); 210 AcpiGbl_PsNodeExtCache = NULL; 211 212 213#ifdef ACPI_DBG_TRACK_ALLOCATIONS 214 215 /* Debug only - display leftover memory allocation, if any */ 216 217 AcpiUtDumpAllocations (ACPI_UINT32_MAX, NULL); 218 219 /* Free memory lists */ 220 221 AcpiOsFree (AcpiGbl_GlobalList); 222 AcpiGbl_GlobalList = NULL; 223 224 AcpiOsFree (AcpiGbl_NsNodeList); 225 AcpiGbl_NsNodeList = NULL; 226#endif 227 228 return (AE_OK); 229} 230 231 232/******************************************************************************* 233 * 234 * FUNCTION: AcpiUtValidateBuffer 235 * 236 * PARAMETERS: Buffer - Buffer descriptor to be validated 237 * 238 * RETURN: Status 239 * 240 * DESCRIPTION: Perform parameter validation checks on an ACPI_BUFFER 241 * 242 ******************************************************************************/ 243 244ACPI_STATUS 245AcpiUtValidateBuffer ( 246 ACPI_BUFFER *Buffer) 247{ 248 249 /* Obviously, the structure pointer must be valid */ 250 251 if (!Buffer) 252 { 253 return (AE_BAD_PARAMETER); 254 } 255 256 /* Special semantics for the length */ 257 258 if ((Buffer->Length == ACPI_NO_BUFFER) || 259 (Buffer->Length == ACPI_ALLOCATE_BUFFER) || 260 (Buffer->Length == ACPI_ALLOCATE_LOCAL_BUFFER)) 261 { 262 return (AE_OK); 263 } 264 265 /* Length is valid, the buffer pointer must be also */ 266 267 if (!Buffer->Pointer) 268 { 269 return (AE_BAD_PARAMETER); 270 } 271 272 return (AE_OK); 273} 274 275 276/******************************************************************************* 277 * 278 * FUNCTION: AcpiUtInitializeBuffer 279 * 280 * PARAMETERS: Buffer - Buffer to be validated 281 * RequiredLength - Length needed 282 * 283 * RETURN: Status 284 * 285 * DESCRIPTION: Validate that the buffer is of the required length or 286 * allocate a new buffer. Returned buffer is always zeroed. 287 * 288 ******************************************************************************/ 289 290ACPI_STATUS 291AcpiUtInitializeBuffer ( 292 ACPI_BUFFER *Buffer, 293 ACPI_SIZE RequiredLength) 294{ 295 ACPI_SIZE InputBufferLength; 296 297 298 /* Parameter validation */ 299 300 if (!Buffer || !RequiredLength) 301 { 302 return (AE_BAD_PARAMETER); 303 } 304 305 /* 306 * Buffer->Length is used as both an input and output parameter. Get the 307 * input actual length and set the output required buffer length. 308 */ 309 InputBufferLength = Buffer->Length; 310 Buffer->Length = RequiredLength; 311 312 /* 313 * The input buffer length contains the actual buffer length, or the type 314 * of buffer to be allocated by this routine. 315 */ 316 switch (InputBufferLength) 317 { 318 case ACPI_NO_BUFFER: 319 320 /* Return the exception (and the required buffer length) */ 321 322 return (AE_BUFFER_OVERFLOW); 323 324 case ACPI_ALLOCATE_BUFFER: 325 /* 326 * Allocate a new buffer. We directectly call AcpiOsAllocate here to 327 * purposefully bypass the (optionally enabled) internal allocation 328 * tracking mechanism since we only want to track internal 329 * allocations. Note: The caller should use AcpiOsFree to free this 330 * buffer created via ACPI_ALLOCATE_BUFFER. 331 */ 332 Buffer->Pointer = AcpiOsAllocate (RequiredLength); 333 break; 334 335 case ACPI_ALLOCATE_LOCAL_BUFFER: 336 337 /* Allocate a new buffer with local interface to allow tracking */ 338 339 Buffer->Pointer = ACPI_ALLOCATE (RequiredLength); 340 break; 341 342 default: 343 344 /* Existing buffer: Validate the size of the buffer */ 345 346 if (InputBufferLength < RequiredLength) 347 { 348 return (AE_BUFFER_OVERFLOW); 349 } 350 break; 351 } 352 353 /* Validate allocation from above or input buffer pointer */ 354 355 if (!Buffer->Pointer) 356 { 357 return (AE_NO_MEMORY); 358 } 359 360 /* Have a valid buffer, clear it */ 361 362 ACPI_MEMSET (Buffer->Pointer, 0, RequiredLength); 363 return (AE_OK); 364} 365