1230557Sjimharris/****************************************************************************** 2230557Sjimharris * 3230557Sjimharris * Module Name: utalloc - local memory allocation routines 4230557Sjimharris * 5230557Sjimharris *****************************************************************************/ 6230557Sjimharris 7230557Sjimharris/* 8230557Sjimharris * Copyright (C) 2000 - 2015, Intel Corp. 9230557Sjimharris * All rights reserved. 10230557Sjimharris * 11230557Sjimharris * Redistribution and use in source and binary forms, with or without 12230557Sjimharris * modification, are permitted provided that the following conditions 13230557Sjimharris * are met: 14230557Sjimharris * 1. Redistributions of source code must retain the above copyright 15230557Sjimharris * notice, this list of conditions, and the following disclaimer, 16230557Sjimharris * without modification. 17230557Sjimharris * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18230557Sjimharris * substantially similar to the "NO WARRANTY" disclaimer below 19230557Sjimharris * ("Disclaimer") and any redistribution must be conditioned upon 20230557Sjimharris * including a substantially similar Disclaimer requirement for further 21230557Sjimharris * binary redistribution. 22230557Sjimharris * 3. Neither the names of the above-listed copyright holders nor the names 23230557Sjimharris * of any contributors may be used to endorse or promote products derived 24230557Sjimharris * from this software without specific prior written permission. 25230557Sjimharris * 26230557Sjimharris * Alternatively, this software may be distributed under the terms of the 27230557Sjimharris * GNU General Public License ("GPL") version 2 as published by the Free 28230557Sjimharris * Software Foundation. 29230557Sjimharris * 30230557Sjimharris * NO WARRANTY 31230557Sjimharris * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32230557Sjimharris * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33230557Sjimharris * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34230557Sjimharris * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35230557Sjimharris * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36230557Sjimharris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37230557Sjimharris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38230557Sjimharris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39230557Sjimharris * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40230557Sjimharris * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41230557Sjimharris * POSSIBILITY OF SUCH DAMAGES. 42230557Sjimharris */ 43230557Sjimharris 44230557Sjimharris#include <contrib/dev/acpica/include/acpi.h> 45230557Sjimharris#include <contrib/dev/acpica/include/accommon.h> 46230557Sjimharris#include <contrib/dev/acpica/include/acdebug.h> 47230557Sjimharris 48230557Sjimharris#define _COMPONENT ACPI_UTILITIES 49230557Sjimharris ACPI_MODULE_NAME ("utalloc") 50230557Sjimharris 51230557Sjimharris 52230557Sjimharris#if !defined (USE_NATIVE_ALLOCATE_ZEROED) 53230557Sjimharris/******************************************************************************* 54230557Sjimharris * 55230557Sjimharris * FUNCTION: AcpiOsAllocateZeroed 56230557Sjimharris * 57230557Sjimharris * PARAMETERS: Size - Size of the allocation 58230557Sjimharris * 59230557Sjimharris * RETURN: Address of the allocated memory on success, NULL on failure. 60230557Sjimharris * 61230557Sjimharris * DESCRIPTION: Subsystem equivalent of calloc. Allocate and zero memory. 62230557Sjimharris * This is the default implementation. Can be overridden via the 63230557Sjimharris * USE_NATIVE_ALLOCATE_ZEROED flag. 64230557Sjimharris * 65230557Sjimharris ******************************************************************************/ 66230557Sjimharris 67230557Sjimharrisvoid * 68230557SjimharrisAcpiOsAllocateZeroed ( 69230557Sjimharris ACPI_SIZE Size) 70230557Sjimharris{ 71230557Sjimharris void *Allocation; 72230557Sjimharris 73230557Sjimharris 74230557Sjimharris ACPI_FUNCTION_ENTRY (); 75230557Sjimharris 76230557Sjimharris 77230557Sjimharris Allocation = AcpiOsAllocate (Size); 78230557Sjimharris if (Allocation) 79230557Sjimharris { 80230557Sjimharris /* Clear the memory block */ 81230557Sjimharris 82230557Sjimharris ACPI_MEMSET (Allocation, 0, Size); 83230557Sjimharris } 84230557Sjimharris 85230557Sjimharris return (Allocation); 86230557Sjimharris} 87230557Sjimharris 88230557Sjimharris#endif /* !USE_NATIVE_ALLOCATE_ZEROED */ 89230557Sjimharris 90230557Sjimharris 91230557Sjimharris/******************************************************************************* 92230557Sjimharris * 93230557Sjimharris * FUNCTION: AcpiUtCreateCaches 94230557Sjimharris * 95230557Sjimharris * PARAMETERS: None 96230557Sjimharris * 97230557Sjimharris * RETURN: Status 98230557Sjimharris * 99230557Sjimharris * DESCRIPTION: Create all local caches 100230557Sjimharris * 101230557Sjimharris ******************************************************************************/ 102230557Sjimharris 103230557SjimharrisACPI_STATUS 104230557SjimharrisAcpiUtCreateCaches ( 105240518Seadler void) 106230557Sjimharris{ 107230557Sjimharris ACPI_STATUS Status; 108230557Sjimharris 109230557Sjimharris 110230557Sjimharris /* Object Caches, for frequently used objects */ 111230557Sjimharris 112230557Sjimharris Status = AcpiOsCreateCache ("Acpi-Namespace", sizeof (ACPI_NAMESPACE_NODE), 113230557Sjimharris ACPI_MAX_NAMESPACE_CACHE_DEPTH, &AcpiGbl_NamespaceCache); 114230557Sjimharris if (ACPI_FAILURE (Status)) 115230557Sjimharris { 116230557Sjimharris return (Status); 117230557Sjimharris } 118230557Sjimharris 119230557Sjimharris Status = AcpiOsCreateCache ("Acpi-State", sizeof (ACPI_GENERIC_STATE), 120230557Sjimharris ACPI_MAX_STATE_CACHE_DEPTH, &AcpiGbl_StateCache); 121230557Sjimharris if (ACPI_FAILURE (Status)) 122230557Sjimharris { 123230557Sjimharris return (Status); 124230557Sjimharris } 125230557Sjimharris 126230557Sjimharris Status = AcpiOsCreateCache ("Acpi-Parse", sizeof (ACPI_PARSE_OBJ_COMMON), 127230557Sjimharris ACPI_MAX_PARSE_CACHE_DEPTH, &AcpiGbl_PsNodeCache); 128230557Sjimharris if (ACPI_FAILURE (Status)) 129230557Sjimharris { 130230557Sjimharris return (Status); 131230557Sjimharris } 132230557Sjimharris 133230557Sjimharris Status = AcpiOsCreateCache ("Acpi-ParseExt", sizeof (ACPI_PARSE_OBJ_NAMED), 134230557Sjimharris ACPI_MAX_EXTPARSE_CACHE_DEPTH, &AcpiGbl_PsNodeExtCache); 135230557Sjimharris if (ACPI_FAILURE (Status)) 136230557Sjimharris { 137230557Sjimharris return (Status); 138230557Sjimharris } 139230557Sjimharris 140230557Sjimharris Status = AcpiOsCreateCache ("Acpi-Operand", sizeof (ACPI_OPERAND_OBJECT), 141230557Sjimharris ACPI_MAX_OBJECT_CACHE_DEPTH, &AcpiGbl_OperandCache); 142230557Sjimharris if (ACPI_FAILURE (Status)) 143230557Sjimharris { 144230557Sjimharris return (Status); 145230557Sjimharris } 146230557Sjimharris 147230557Sjimharris 148230557Sjimharris#ifdef ACPI_DBG_TRACK_ALLOCATIONS 149230557Sjimharris 150230557Sjimharris /* Memory allocation lists */ 151230557Sjimharris 152230557Sjimharris Status = AcpiUtCreateList ("Acpi-Global", 0, 153230557Sjimharris &AcpiGbl_GlobalList); 154230557Sjimharris if (ACPI_FAILURE (Status)) 155230557Sjimharris { 156230557Sjimharris return (Status); 157230557Sjimharris } 158230557Sjimharris 159230557Sjimharris Status = AcpiUtCreateList ("Acpi-Namespace", sizeof (ACPI_NAMESPACE_NODE), 160230557Sjimharris &AcpiGbl_NsNodeList); 161230557Sjimharris if (ACPI_FAILURE (Status)) 162230557Sjimharris { 163230557Sjimharris return (Status); 164230557Sjimharris } 165230557Sjimharris#endif 166230557Sjimharris 167230557Sjimharris return (AE_OK); 168230557Sjimharris} 169230557Sjimharris 170230557Sjimharris 171230557Sjimharris/******************************************************************************* 172230557Sjimharris * 173230557Sjimharris * FUNCTION: AcpiUtDeleteCaches 174230557Sjimharris * 175230557Sjimharris * PARAMETERS: None 176230557Sjimharris * 177230557Sjimharris * RETURN: Status 178230557Sjimharris * 179230557Sjimharris * DESCRIPTION: Purge and delete all local caches 180230557Sjimharris * 181230557Sjimharris ******************************************************************************/ 182230557Sjimharris 183230557SjimharrisACPI_STATUS 184230557SjimharrisAcpiUtDeleteCaches ( 185230557Sjimharris void) 186230557Sjimharris{ 187230557Sjimharris#ifdef ACPI_DBG_TRACK_ALLOCATIONS 188230557Sjimharris char Buffer[7]; 189230557Sjimharris 190230557Sjimharris if (AcpiGbl_DisplayFinalMemStats) 191230557Sjimharris { 192230557Sjimharris ACPI_STRCPY (Buffer, "MEMORY"); 193230557Sjimharris (void) AcpiDbDisplayStatistics (Buffer); 194230557Sjimharris } 195230557Sjimharris#endif 196230557Sjimharris 197230557Sjimharris (void) AcpiOsDeleteCache (AcpiGbl_NamespaceCache); 198230557Sjimharris AcpiGbl_NamespaceCache = NULL; 199230557Sjimharris 200230557Sjimharris (void) AcpiOsDeleteCache (AcpiGbl_StateCache); 201230557Sjimharris AcpiGbl_StateCache = NULL; 202230557Sjimharris 203230557Sjimharris (void) AcpiOsDeleteCache (AcpiGbl_OperandCache); 204230557Sjimharris AcpiGbl_OperandCache = NULL; 205230557Sjimharris 206230557Sjimharris (void) AcpiOsDeleteCache (AcpiGbl_PsNodeCache); 207230557Sjimharris AcpiGbl_PsNodeCache = NULL; 208230557Sjimharris 209230557Sjimharris (void) AcpiOsDeleteCache (AcpiGbl_PsNodeExtCache); 210230557Sjimharris AcpiGbl_PsNodeExtCache = NULL; 211230557Sjimharris 212230557Sjimharris 213230557Sjimharris#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