1ae115bc7Smrj /****************************************************************************** 2ae115bc7Smrj * 3ae115bc7Smrj * Module Name: utalloc - local memory allocation routines 4ae115bc7Smrj * 5ae115bc7Smrj *****************************************************************************/ 6ae115bc7Smrj 726f3cdf0SGordon Ross /* 8*385cc6b4SJerry Jelinek * Copyright (C) 2000 - 2016, Intel Corp. 9ae115bc7Smrj * All rights reserved. 10ae115bc7Smrj * 1126f3cdf0SGordon Ross * Redistribution and use in source and binary forms, with or without 1226f3cdf0SGordon Ross * modification, are permitted provided that the following conditions 1326f3cdf0SGordon Ross * are met: 1426f3cdf0SGordon Ross * 1. Redistributions of source code must retain the above copyright 1526f3cdf0SGordon Ross * notice, this list of conditions, and the following disclaimer, 1626f3cdf0SGordon Ross * without modification. 1726f3cdf0SGordon Ross * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1826f3cdf0SGordon Ross * substantially similar to the "NO WARRANTY" disclaimer below 1926f3cdf0SGordon Ross * ("Disclaimer") and any redistribution must be conditioned upon 2026f3cdf0SGordon Ross * including a substantially similar Disclaimer requirement for further 2126f3cdf0SGordon Ross * binary redistribution. 2226f3cdf0SGordon Ross * 3. Neither the names of the above-listed copyright holders nor the names 2326f3cdf0SGordon Ross * of any contributors may be used to endorse or promote products derived 2426f3cdf0SGordon Ross * from this software without specific prior written permission. 25ae115bc7Smrj * 2626f3cdf0SGordon Ross * Alternatively, this software may be distributed under the terms of the 2726f3cdf0SGordon Ross * GNU General Public License ("GPL") version 2 as published by the Free 2826f3cdf0SGordon Ross * Software Foundation. 29ae115bc7Smrj * 3026f3cdf0SGordon Ross * NO WARRANTY 3126f3cdf0SGordon Ross * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3226f3cdf0SGordon Ross * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3326f3cdf0SGordon Ross * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 3426f3cdf0SGordon Ross * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3526f3cdf0SGordon Ross * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3626f3cdf0SGordon Ross * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3726f3cdf0SGordon Ross * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3826f3cdf0SGordon Ross * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 3926f3cdf0SGordon Ross * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 4026f3cdf0SGordon Ross * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 4126f3cdf0SGordon Ross * POSSIBILITY OF SUCH DAMAGES. 4226f3cdf0SGordon Ross */ 43ae115bc7Smrj 44ae115bc7Smrj #include "acpi.h" 45aa2aa9a6SDana Myers #include "accommon.h" 46db2bae30SDana Myers #include "acdebug.h" 47ae115bc7Smrj 48ae115bc7Smrj #define _COMPONENT ACPI_UTILITIES 49ae115bc7Smrj ACPI_MODULE_NAME ("utalloc") 50ae115bc7Smrj 51ae115bc7Smrj 52*385cc6b4SJerry Jelinek #if !defined (USE_NATIVE_ALLOCATE_ZEROED) 53*385cc6b4SJerry Jelinek /******************************************************************************* 54*385cc6b4SJerry Jelinek * 55*385cc6b4SJerry Jelinek * FUNCTION: AcpiOsAllocateZeroed 56*385cc6b4SJerry Jelinek * 57*385cc6b4SJerry Jelinek * PARAMETERS: Size - Size of the allocation 58*385cc6b4SJerry Jelinek * 59*385cc6b4SJerry Jelinek * RETURN: Address of the allocated memory on success, NULL on failure. 60*385cc6b4SJerry Jelinek * 61*385cc6b4SJerry Jelinek * DESCRIPTION: Subsystem equivalent of calloc. Allocate and zero memory. 62*385cc6b4SJerry Jelinek * This is the default implementation. Can be overridden via the 63*385cc6b4SJerry Jelinek * USE_NATIVE_ALLOCATE_ZEROED flag. 64*385cc6b4SJerry Jelinek * 65*385cc6b4SJerry Jelinek ******************************************************************************/ 66*385cc6b4SJerry Jelinek 67*385cc6b4SJerry Jelinek void * 68*385cc6b4SJerry Jelinek AcpiOsAllocateZeroed ( 69*385cc6b4SJerry Jelinek ACPI_SIZE Size) 70*385cc6b4SJerry Jelinek { 71*385cc6b4SJerry Jelinek void *Allocation; 72*385cc6b4SJerry Jelinek 73*385cc6b4SJerry Jelinek 74*385cc6b4SJerry Jelinek ACPI_FUNCTION_ENTRY (); 75*385cc6b4SJerry Jelinek 76*385cc6b4SJerry Jelinek 77*385cc6b4SJerry Jelinek Allocation = AcpiOsAllocate (Size); 78*385cc6b4SJerry Jelinek if (Allocation) 79*385cc6b4SJerry Jelinek { 80*385cc6b4SJerry Jelinek /* Clear the memory block */ 81*385cc6b4SJerry Jelinek 82*385cc6b4SJerry Jelinek memset (Allocation, 0, Size); 83*385cc6b4SJerry Jelinek } 84*385cc6b4SJerry Jelinek 85*385cc6b4SJerry Jelinek return (Allocation); 86*385cc6b4SJerry Jelinek } 87*385cc6b4SJerry Jelinek 88*385cc6b4SJerry Jelinek #endif /* !USE_NATIVE_ALLOCATE_ZEROED */ 89*385cc6b4SJerry Jelinek 90*385cc6b4SJerry Jelinek 91ae115bc7Smrj /******************************************************************************* 92ae115bc7Smrj * 93ae115bc7Smrj * FUNCTION: AcpiUtCreateCaches 94ae115bc7Smrj * 95ae115bc7Smrj * PARAMETERS: None 96ae115bc7Smrj * 97ae115bc7Smrj * RETURN: Status 98ae115bc7Smrj * 99ae115bc7Smrj * DESCRIPTION: Create all local caches 100ae115bc7Smrj * 101ae115bc7Smrj ******************************************************************************/ 102ae115bc7Smrj 103ae115bc7Smrj ACPI_STATUS 104ae115bc7Smrj AcpiUtCreateCaches ( 105ae115bc7Smrj void) 106ae115bc7Smrj { 107ae115bc7Smrj ACPI_STATUS Status; 108ae115bc7Smrj 109ae115bc7Smrj 110ae115bc7Smrj /* Object Caches, for frequently used objects */ 111ae115bc7Smrj 112ae115bc7Smrj Status = AcpiOsCreateCache ("Acpi-Namespace", sizeof (ACPI_NAMESPACE_NODE), 113ae115bc7Smrj ACPI_MAX_NAMESPACE_CACHE_DEPTH, &AcpiGbl_NamespaceCache); 114ae115bc7Smrj if (ACPI_FAILURE (Status)) 115ae115bc7Smrj { 116ae115bc7Smrj return (Status); 117ae115bc7Smrj } 118ae115bc7Smrj 119ae115bc7Smrj Status = AcpiOsCreateCache ("Acpi-State", sizeof (ACPI_GENERIC_STATE), 120ae115bc7Smrj ACPI_MAX_STATE_CACHE_DEPTH, &AcpiGbl_StateCache); 121ae115bc7Smrj if (ACPI_FAILURE (Status)) 122ae115bc7Smrj { 123ae115bc7Smrj return (Status); 124ae115bc7Smrj } 125ae115bc7Smrj 126ae115bc7Smrj Status = AcpiOsCreateCache ("Acpi-Parse", sizeof (ACPI_PARSE_OBJ_COMMON), 127ae115bc7Smrj ACPI_MAX_PARSE_CACHE_DEPTH, &AcpiGbl_PsNodeCache); 128ae115bc7Smrj if (ACPI_FAILURE (Status)) 129ae115bc7Smrj { 130ae115bc7Smrj return (Status); 131ae115bc7Smrj } 132ae115bc7Smrj 133ae115bc7Smrj Status = AcpiOsCreateCache ("Acpi-ParseExt", sizeof (ACPI_PARSE_OBJ_NAMED), 134ae115bc7Smrj ACPI_MAX_EXTPARSE_CACHE_DEPTH, &AcpiGbl_PsNodeExtCache); 135ae115bc7Smrj if (ACPI_FAILURE (Status)) 136ae115bc7Smrj { 137ae115bc7Smrj return (Status); 138ae115bc7Smrj } 139ae115bc7Smrj 140ae115bc7Smrj Status = AcpiOsCreateCache ("Acpi-Operand", sizeof (ACPI_OPERAND_OBJECT), 141ae115bc7Smrj ACPI_MAX_OBJECT_CACHE_DEPTH, &AcpiGbl_OperandCache); 142ae115bc7Smrj if (ACPI_FAILURE (Status)) 143ae115bc7Smrj { 144ae115bc7Smrj return (Status); 145ae115bc7Smrj } 146ae115bc7Smrj 147ae115bc7Smrj 148ae115bc7Smrj #ifdef ACPI_DBG_TRACK_ALLOCATIONS 149ae115bc7Smrj 150ae115bc7Smrj /* Memory allocation lists */ 151ae115bc7Smrj 152ae115bc7Smrj Status = AcpiUtCreateList ("Acpi-Global", 0, 153ae115bc7Smrj &AcpiGbl_GlobalList); 154ae115bc7Smrj if (ACPI_FAILURE (Status)) 155ae115bc7Smrj { 156ae115bc7Smrj return (Status); 157ae115bc7Smrj } 158ae115bc7Smrj 159ae115bc7Smrj Status = AcpiUtCreateList ("Acpi-Namespace", sizeof (ACPI_NAMESPACE_NODE), 160ae115bc7Smrj &AcpiGbl_NsNodeList); 161ae115bc7Smrj if (ACPI_FAILURE (Status)) 162ae115bc7Smrj { 163ae115bc7Smrj return (Status); 164ae115bc7Smrj } 165ae115bc7Smrj #endif 166ae115bc7Smrj 167ae115bc7Smrj return (AE_OK); 168ae115bc7Smrj } 169ae115bc7Smrj 170ae115bc7Smrj 171ae115bc7Smrj /******************************************************************************* 172ae115bc7Smrj * 173ae115bc7Smrj * FUNCTION: AcpiUtDeleteCaches 174ae115bc7Smrj * 175ae115bc7Smrj * PARAMETERS: None 176ae115bc7Smrj * 177ae115bc7Smrj * RETURN: Status 178ae115bc7Smrj * 179ae115bc7Smrj * DESCRIPTION: Purge and delete all local caches 180ae115bc7Smrj * 181ae115bc7Smrj ******************************************************************************/ 182ae115bc7Smrj 183ae115bc7Smrj ACPI_STATUS 184ae115bc7Smrj AcpiUtDeleteCaches ( 185ae115bc7Smrj void) 186ae115bc7Smrj { 187db2bae30SDana Myers #ifdef ACPI_DBG_TRACK_ALLOCATIONS 188db2bae30SDana Myers char Buffer[7]; 189db2bae30SDana Myers 190*385cc6b4SJerry Jelinek 191db2bae30SDana Myers if (AcpiGbl_DisplayFinalMemStats) 192db2bae30SDana Myers { 193*385cc6b4SJerry Jelinek strcpy (Buffer, "MEMORY"); 194db2bae30SDana Myers (void) AcpiDbDisplayStatistics (Buffer); 195db2bae30SDana Myers } 196db2bae30SDana Myers #endif 197ae115bc7Smrj 198ae115bc7Smrj (void) AcpiOsDeleteCache (AcpiGbl_NamespaceCache); 199ae115bc7Smrj AcpiGbl_NamespaceCache = NULL; 200ae115bc7Smrj 201ae115bc7Smrj (void) AcpiOsDeleteCache (AcpiGbl_StateCache); 202ae115bc7Smrj AcpiGbl_StateCache = NULL; 203ae115bc7Smrj 204ae115bc7Smrj (void) AcpiOsDeleteCache (AcpiGbl_OperandCache); 205ae115bc7Smrj AcpiGbl_OperandCache = NULL; 206ae115bc7Smrj 207ae115bc7Smrj (void) AcpiOsDeleteCache (AcpiGbl_PsNodeCache); 208ae115bc7Smrj AcpiGbl_PsNodeCache = NULL; 209ae115bc7Smrj 210ae115bc7Smrj (void) AcpiOsDeleteCache (AcpiGbl_PsNodeExtCache); 211ae115bc7Smrj AcpiGbl_PsNodeExtCache = NULL; 212ae115bc7Smrj 213ae115bc7Smrj 214ae115bc7Smrj #ifdef ACPI_DBG_TRACK_ALLOCATIONS 215ae115bc7Smrj 216ae115bc7Smrj /* Debug only - display leftover memory allocation, if any */ 217ae115bc7Smrj 218ae115bc7Smrj AcpiUtDumpAllocations (ACPI_UINT32_MAX, NULL); 219ae115bc7Smrj 220ae115bc7Smrj /* Free memory lists */ 221ae115bc7Smrj 222ae115bc7Smrj AcpiOsFree (AcpiGbl_GlobalList); 223ae115bc7Smrj AcpiGbl_GlobalList = NULL; 224ae115bc7Smrj 225ae115bc7Smrj AcpiOsFree (AcpiGbl_NsNodeList); 226ae115bc7Smrj AcpiGbl_NsNodeList = NULL; 227ae115bc7Smrj #endif 228ae115bc7Smrj 229ae115bc7Smrj return (AE_OK); 230ae115bc7Smrj } 231ae115bc7Smrj 232ae115bc7Smrj 233ae115bc7Smrj /******************************************************************************* 234ae115bc7Smrj * 235ae115bc7Smrj * FUNCTION: AcpiUtValidateBuffer 236ae115bc7Smrj * 237ae115bc7Smrj * PARAMETERS: Buffer - Buffer descriptor to be validated 238ae115bc7Smrj * 239ae115bc7Smrj * RETURN: Status 240ae115bc7Smrj * 241ae115bc7Smrj * DESCRIPTION: Perform parameter validation checks on an ACPI_BUFFER 242ae115bc7Smrj * 243ae115bc7Smrj ******************************************************************************/ 244ae115bc7Smrj 245ae115bc7Smrj ACPI_STATUS 246ae115bc7Smrj AcpiUtValidateBuffer ( 247ae115bc7Smrj ACPI_BUFFER *Buffer) 248ae115bc7Smrj { 249ae115bc7Smrj 250ae115bc7Smrj /* Obviously, the structure pointer must be valid */ 251ae115bc7Smrj 252ae115bc7Smrj if (!Buffer) 253ae115bc7Smrj { 254ae115bc7Smrj return (AE_BAD_PARAMETER); 255ae115bc7Smrj } 256ae115bc7Smrj 257ae115bc7Smrj /* Special semantics for the length */ 258ae115bc7Smrj 259ae115bc7Smrj if ((Buffer->Length == ACPI_NO_BUFFER) || 260ae115bc7Smrj (Buffer->Length == ACPI_ALLOCATE_BUFFER) || 261ae115bc7Smrj (Buffer->Length == ACPI_ALLOCATE_LOCAL_BUFFER)) 262ae115bc7Smrj { 263ae115bc7Smrj return (AE_OK); 264ae115bc7Smrj } 265ae115bc7Smrj 266ae115bc7Smrj /* Length is valid, the buffer pointer must be also */ 267ae115bc7Smrj 268ae115bc7Smrj if (!Buffer->Pointer) 269ae115bc7Smrj { 270ae115bc7Smrj return (AE_BAD_PARAMETER); 271ae115bc7Smrj } 272ae115bc7Smrj 273ae115bc7Smrj return (AE_OK); 274ae115bc7Smrj } 275ae115bc7Smrj 276ae115bc7Smrj 277ae115bc7Smrj /******************************************************************************* 278ae115bc7Smrj * 279ae115bc7Smrj * FUNCTION: AcpiUtInitializeBuffer 280ae115bc7Smrj * 281ae115bc7Smrj * PARAMETERS: Buffer - Buffer to be validated 282ae115bc7Smrj * RequiredLength - Length needed 283ae115bc7Smrj * 284ae115bc7Smrj * RETURN: Status 285ae115bc7Smrj * 286ae115bc7Smrj * DESCRIPTION: Validate that the buffer is of the required length or 287ae115bc7Smrj * allocate a new buffer. Returned buffer is always zeroed. 288ae115bc7Smrj * 289ae115bc7Smrj ******************************************************************************/ 290ae115bc7Smrj 291ae115bc7Smrj ACPI_STATUS 292ae115bc7Smrj AcpiUtInitializeBuffer ( 293ae115bc7Smrj ACPI_BUFFER *Buffer, 294ae115bc7Smrj ACPI_SIZE RequiredLength) 295ae115bc7Smrj { 296aa2aa9a6SDana Myers ACPI_SIZE InputBufferLength; 297ae115bc7Smrj 298ae115bc7Smrj 299db2bae30SDana Myers /* Parameter validation */ 300db2bae30SDana Myers 301db2bae30SDana Myers if (!Buffer || !RequiredLength) 302db2bae30SDana Myers { 303db2bae30SDana Myers return (AE_BAD_PARAMETER); 304db2bae30SDana Myers } 305db2bae30SDana Myers 306aa2aa9a6SDana Myers /* 307aa2aa9a6SDana Myers * Buffer->Length is used as both an input and output parameter. Get the 308aa2aa9a6SDana Myers * input actual length and set the output required buffer length. 309aa2aa9a6SDana Myers */ 310aa2aa9a6SDana Myers InputBufferLength = Buffer->Length; 311aa2aa9a6SDana Myers Buffer->Length = RequiredLength; 312aa2aa9a6SDana Myers 313aa2aa9a6SDana Myers /* 314aa2aa9a6SDana Myers * The input buffer length contains the actual buffer length, or the type 315aa2aa9a6SDana Myers * of buffer to be allocated by this routine. 316aa2aa9a6SDana Myers */ 317aa2aa9a6SDana Myers switch (InputBufferLength) 318ae115bc7Smrj { 319ae115bc7Smrj case ACPI_NO_BUFFER: 320ae115bc7Smrj 321aa2aa9a6SDana Myers /* Return the exception (and the required buffer length) */ 322ae115bc7Smrj 323aa2aa9a6SDana Myers return (AE_BUFFER_OVERFLOW); 324ae115bc7Smrj 325ae115bc7Smrj case ACPI_ALLOCATE_BUFFER: 326*385cc6b4SJerry Jelinek /* 327*385cc6b4SJerry Jelinek * Allocate a new buffer. We directectly call AcpiOsAllocate here to 328*385cc6b4SJerry Jelinek * purposefully bypass the (optionally enabled) internal allocation 329*385cc6b4SJerry Jelinek * tracking mechanism since we only want to track internal 330*385cc6b4SJerry Jelinek * allocations. Note: The caller should use AcpiOsFree to free this 331*385cc6b4SJerry Jelinek * buffer created via ACPI_ALLOCATE_BUFFER. 332*385cc6b4SJerry Jelinek */ 333ae115bc7Smrj Buffer->Pointer = AcpiOsAllocate (RequiredLength); 334ae115bc7Smrj break; 335ae115bc7Smrj 336ae115bc7Smrj case ACPI_ALLOCATE_LOCAL_BUFFER: 337ae115bc7Smrj 338ae115bc7Smrj /* Allocate a new buffer with local interface to allow tracking */ 339ae115bc7Smrj 340aa2aa9a6SDana Myers Buffer->Pointer = ACPI_ALLOCATE (RequiredLength); 341ae115bc7Smrj break; 342ae115bc7Smrj 343ae115bc7Smrj default: 344ae115bc7Smrj 345ae115bc7Smrj /* Existing buffer: Validate the size of the buffer */ 346ae115bc7Smrj 347aa2aa9a6SDana Myers if (InputBufferLength < RequiredLength) 348ae115bc7Smrj { 349aa2aa9a6SDana Myers return (AE_BUFFER_OVERFLOW); 350aa2aa9a6SDana Myers } 351ae115bc7Smrj break; 352ae115bc7Smrj } 353ae115bc7Smrj 354aa2aa9a6SDana Myers /* Validate allocation from above or input buffer pointer */ 355aa2aa9a6SDana Myers 356aa2aa9a6SDana Myers if (!Buffer->Pointer) 357aa2aa9a6SDana Myers { 358aa2aa9a6SDana Myers return (AE_NO_MEMORY); 359aa2aa9a6SDana Myers } 360aa2aa9a6SDana Myers 361aa2aa9a6SDana Myers /* Have a valid buffer, clear it */ 362ae115bc7Smrj 363*385cc6b4SJerry Jelinek memset (Buffer->Pointer, 0, RequiredLength); 364aa2aa9a6SDana Myers return (AE_OK); 365ae115bc7Smrj } 366