13446Smrj /******************************************************************************
23446Smrj *
33446Smrj * Module Name: utalloc - local memory allocation routines
43446Smrj *
53446Smrj *****************************************************************************/
63446Smrj
73446Smrj /******************************************************************************
83446Smrj *
93446Smrj * 1. Copyright Notice
103446Smrj *
11*9980SDana.Myers@Sun.COM * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp.
123446Smrj * All rights reserved.
133446Smrj *
143446Smrj * 2. License
153446Smrj *
163446Smrj * 2.1. This is your license from Intel Corp. under its intellectual property
173446Smrj * rights. You may have additional license terms from the party that provided
183446Smrj * you this software, covering your right to use that party's intellectual
193446Smrj * property rights.
203446Smrj *
213446Smrj * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
223446Smrj * copy of the source code appearing in this file ("Covered Code") an
233446Smrj * irrevocable, perpetual, worldwide license under Intel's copyrights in the
243446Smrj * base code distributed originally by Intel ("Original Intel Code") to copy,
253446Smrj * make derivatives, distribute, use and display any portion of the Covered
263446Smrj * Code in any form, with the right to sublicense such rights; and
273446Smrj *
283446Smrj * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
293446Smrj * license (with the right to sublicense), under only those claims of Intel
303446Smrj * patents that are infringed by the Original Intel Code, to make, use, sell,
313446Smrj * offer to sell, and import the Covered Code and derivative works thereof
323446Smrj * solely to the minimum extent necessary to exercise the above copyright
333446Smrj * license, and in no event shall the patent license extend to any additions
343446Smrj * to or modifications of the Original Intel Code. No other license or right
353446Smrj * is granted directly or by implication, estoppel or otherwise;
363446Smrj *
373446Smrj * The above copyright and patent license is granted only if the following
383446Smrj * conditions are met:
393446Smrj *
403446Smrj * 3. Conditions
413446Smrj *
423446Smrj * 3.1. Redistribution of Source with Rights to Further Distribute Source.
433446Smrj * Redistribution of source code of any substantial portion of the Covered
443446Smrj * Code or modification with rights to further distribute source must include
453446Smrj * the above Copyright Notice, the above License, this list of Conditions,
463446Smrj * and the following Disclaimer and Export Compliance provision. In addition,
473446Smrj * Licensee must cause all Covered Code to which Licensee contributes to
483446Smrj * contain a file documenting the changes Licensee made to create that Covered
493446Smrj * Code and the date of any change. Licensee must include in that file the
503446Smrj * documentation of any changes made by any predecessor Licensee. Licensee
513446Smrj * must include a prominent statement that the modification is derived,
523446Smrj * directly or indirectly, from Original Intel Code.
533446Smrj *
543446Smrj * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
553446Smrj * Redistribution of source code of any substantial portion of the Covered
563446Smrj * Code or modification without rights to further distribute source must
573446Smrj * include the following Disclaimer and Export Compliance provision in the
583446Smrj * documentation and/or other materials provided with distribution. In
593446Smrj * addition, Licensee may not authorize further sublicense of source of any
603446Smrj * portion of the Covered Code, and must include terms to the effect that the
613446Smrj * license from Licensee to its licensee is limited to the intellectual
623446Smrj * property embodied in the software Licensee provides to its licensee, and
633446Smrj * not to intellectual property embodied in modifications its licensee may
643446Smrj * make.
653446Smrj *
663446Smrj * 3.3. Redistribution of Executable. Redistribution in executable form of any
673446Smrj * substantial portion of the Covered Code or modification must reproduce the
683446Smrj * above Copyright Notice, and the following Disclaimer and Export Compliance
693446Smrj * provision in the documentation and/or other materials provided with the
703446Smrj * distribution.
713446Smrj *
723446Smrj * 3.4. Intel retains all right, title, and interest in and to the Original
733446Smrj * Intel Code.
743446Smrj *
753446Smrj * 3.5. Neither the name Intel nor any other trademark owned or controlled by
763446Smrj * Intel shall be used in advertising or otherwise to promote the sale, use or
773446Smrj * other dealings in products derived from or relating to the Covered Code
783446Smrj * without prior written authorization from Intel.
793446Smrj *
803446Smrj * 4. Disclaimer and Export Compliance
813446Smrj *
823446Smrj * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
833446Smrj * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
843446Smrj * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
853446Smrj * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
863446Smrj * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
873446Smrj * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
883446Smrj * PARTICULAR PURPOSE.
893446Smrj *
903446Smrj * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
913446Smrj * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
923446Smrj * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
933446Smrj * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
943446Smrj * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
953446Smrj * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
963446Smrj * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
973446Smrj * LIMITED REMEDY.
983446Smrj *
993446Smrj * 4.3. Licensee shall not export, either directly or indirectly, any of this
1003446Smrj * software or system incorporating such software without first obtaining any
1013446Smrj * required license or other approval from the U. S. Department of Commerce or
1023446Smrj * any other agency or department of the United States Government. In the
1033446Smrj * event Licensee exports any such software from the United States or
1043446Smrj * re-exports any such software from a foreign destination, Licensee shall
1053446Smrj * ensure that the distribution and export/re-export of the software is in
1063446Smrj * compliance with all laws, regulations, orders, or other restrictions of the
1073446Smrj * U.S. Export Administration Regulations. Licensee agrees that neither it nor
1083446Smrj * any of its subsidiaries will export/re-export any technical data, process,
1093446Smrj * software, or service, directly or indirectly, to any country for which the
1103446Smrj * United States government or any agency thereof requires an export license,
1113446Smrj * other governmental approval, or letter of assurance, without first obtaining
1123446Smrj * such license, approval or letter.
1133446Smrj *
1143446Smrj *****************************************************************************/
1153446Smrj
1163446Smrj #define __UTALLOC_C__
1173446Smrj
1183446Smrj #include "acpi.h"
119*9980SDana.Myers@Sun.COM #include "accommon.h"
1207851SDana.Myers@Sun.COM #include "acdebug.h"
1213446Smrj
1223446Smrj #define _COMPONENT ACPI_UTILITIES
1233446Smrj ACPI_MODULE_NAME ("utalloc")
1243446Smrj
1253446Smrj
1263446Smrj /*******************************************************************************
1273446Smrj *
1283446Smrj * FUNCTION: AcpiUtCreateCaches
1293446Smrj *
1303446Smrj * PARAMETERS: None
1313446Smrj *
1323446Smrj * RETURN: Status
1333446Smrj *
1343446Smrj * DESCRIPTION: Create all local caches
1353446Smrj *
1363446Smrj ******************************************************************************/
1373446Smrj
1383446Smrj ACPI_STATUS
AcpiUtCreateCaches(void)1393446Smrj AcpiUtCreateCaches (
1403446Smrj void)
1413446Smrj {
1423446Smrj ACPI_STATUS Status;
1433446Smrj
1443446Smrj
1453446Smrj /* Object Caches, for frequently used objects */
1463446Smrj
1473446Smrj Status = AcpiOsCreateCache ("Acpi-Namespace", sizeof (ACPI_NAMESPACE_NODE),
1483446Smrj ACPI_MAX_NAMESPACE_CACHE_DEPTH, &AcpiGbl_NamespaceCache);
1493446Smrj if (ACPI_FAILURE (Status))
1503446Smrj {
1513446Smrj return (Status);
1523446Smrj }
1533446Smrj
1543446Smrj Status = AcpiOsCreateCache ("Acpi-State", sizeof (ACPI_GENERIC_STATE),
1553446Smrj ACPI_MAX_STATE_CACHE_DEPTH, &AcpiGbl_StateCache);
1563446Smrj if (ACPI_FAILURE (Status))
1573446Smrj {
1583446Smrj return (Status);
1593446Smrj }
1603446Smrj
1613446Smrj Status = AcpiOsCreateCache ("Acpi-Parse", sizeof (ACPI_PARSE_OBJ_COMMON),
1623446Smrj ACPI_MAX_PARSE_CACHE_DEPTH, &AcpiGbl_PsNodeCache);
1633446Smrj if (ACPI_FAILURE (Status))
1643446Smrj {
1653446Smrj return (Status);
1663446Smrj }
1673446Smrj
1683446Smrj Status = AcpiOsCreateCache ("Acpi-ParseExt", sizeof (ACPI_PARSE_OBJ_NAMED),
1693446Smrj ACPI_MAX_EXTPARSE_CACHE_DEPTH, &AcpiGbl_PsNodeExtCache);
1703446Smrj if (ACPI_FAILURE (Status))
1713446Smrj {
1723446Smrj return (Status);
1733446Smrj }
1743446Smrj
1753446Smrj Status = AcpiOsCreateCache ("Acpi-Operand", sizeof (ACPI_OPERAND_OBJECT),
1763446Smrj ACPI_MAX_OBJECT_CACHE_DEPTH, &AcpiGbl_OperandCache);
1773446Smrj if (ACPI_FAILURE (Status))
1783446Smrj {
1793446Smrj return (Status);
1803446Smrj }
1813446Smrj
1823446Smrj
1833446Smrj #ifdef ACPI_DBG_TRACK_ALLOCATIONS
1843446Smrj
1853446Smrj /* Memory allocation lists */
1863446Smrj
1873446Smrj Status = AcpiUtCreateList ("Acpi-Global", 0,
1883446Smrj &AcpiGbl_GlobalList);
1893446Smrj if (ACPI_FAILURE (Status))
1903446Smrj {
1913446Smrj return (Status);
1923446Smrj }
1933446Smrj
1943446Smrj Status = AcpiUtCreateList ("Acpi-Namespace", sizeof (ACPI_NAMESPACE_NODE),
1953446Smrj &AcpiGbl_NsNodeList);
1963446Smrj if (ACPI_FAILURE (Status))
1973446Smrj {
1983446Smrj return (Status);
1993446Smrj }
2003446Smrj #endif
2013446Smrj
2023446Smrj return (AE_OK);
2033446Smrj }
2043446Smrj
2053446Smrj
2063446Smrj /*******************************************************************************
2073446Smrj *
2083446Smrj * FUNCTION: AcpiUtDeleteCaches
2093446Smrj *
2103446Smrj * PARAMETERS: None
2113446Smrj *
2123446Smrj * RETURN: Status
2133446Smrj *
2143446Smrj * DESCRIPTION: Purge and delete all local caches
2153446Smrj *
2163446Smrj ******************************************************************************/
2173446Smrj
2183446Smrj ACPI_STATUS
AcpiUtDeleteCaches(void)2193446Smrj AcpiUtDeleteCaches (
2203446Smrj void)
2213446Smrj {
2227851SDana.Myers@Sun.COM #ifdef ACPI_DBG_TRACK_ALLOCATIONS
2237851SDana.Myers@Sun.COM char Buffer[7];
2247851SDana.Myers@Sun.COM
2257851SDana.Myers@Sun.COM if (AcpiGbl_DisplayFinalMemStats)
2267851SDana.Myers@Sun.COM {
2277851SDana.Myers@Sun.COM ACPI_STRCPY (Buffer, "MEMORY");
2287851SDana.Myers@Sun.COM (void) AcpiDbDisplayStatistics (Buffer);
2297851SDana.Myers@Sun.COM }
2307851SDana.Myers@Sun.COM #endif
2313446Smrj
2323446Smrj (void) AcpiOsDeleteCache (AcpiGbl_NamespaceCache);
2333446Smrj AcpiGbl_NamespaceCache = NULL;
2343446Smrj
2353446Smrj (void) AcpiOsDeleteCache (AcpiGbl_StateCache);
2363446Smrj AcpiGbl_StateCache = NULL;
2373446Smrj
2383446Smrj (void) AcpiOsDeleteCache (AcpiGbl_OperandCache);
2393446Smrj AcpiGbl_OperandCache = NULL;
2403446Smrj
2413446Smrj (void) AcpiOsDeleteCache (AcpiGbl_PsNodeCache);
2423446Smrj AcpiGbl_PsNodeCache = NULL;
2433446Smrj
2443446Smrj (void) AcpiOsDeleteCache (AcpiGbl_PsNodeExtCache);
2453446Smrj AcpiGbl_PsNodeExtCache = NULL;
2463446Smrj
2473446Smrj
2483446Smrj #ifdef ACPI_DBG_TRACK_ALLOCATIONS
2493446Smrj
2503446Smrj /* Debug only - display leftover memory allocation, if any */
2513446Smrj
2523446Smrj AcpiUtDumpAllocations (ACPI_UINT32_MAX, NULL);
2533446Smrj
2543446Smrj /* Free memory lists */
2553446Smrj
2563446Smrj AcpiOsFree (AcpiGbl_GlobalList);
2573446Smrj AcpiGbl_GlobalList = NULL;
2583446Smrj
2593446Smrj AcpiOsFree (AcpiGbl_NsNodeList);
2603446Smrj AcpiGbl_NsNodeList = NULL;
2613446Smrj #endif
2623446Smrj
2633446Smrj return (AE_OK);
2643446Smrj }
2653446Smrj
2663446Smrj
2673446Smrj /*******************************************************************************
2683446Smrj *
2693446Smrj * FUNCTION: AcpiUtValidateBuffer
2703446Smrj *
2713446Smrj * PARAMETERS: Buffer - Buffer descriptor to be validated
2723446Smrj *
2733446Smrj * RETURN: Status
2743446Smrj *
2753446Smrj * DESCRIPTION: Perform parameter validation checks on an ACPI_BUFFER
2763446Smrj *
2773446Smrj ******************************************************************************/
2783446Smrj
2793446Smrj ACPI_STATUS
AcpiUtValidateBuffer(ACPI_BUFFER * Buffer)2803446Smrj AcpiUtValidateBuffer (
2813446Smrj ACPI_BUFFER *Buffer)
2823446Smrj {
2833446Smrj
2843446Smrj /* Obviously, the structure pointer must be valid */
2853446Smrj
2863446Smrj if (!Buffer)
2873446Smrj {
2883446Smrj return (AE_BAD_PARAMETER);
2893446Smrj }
2903446Smrj
2913446Smrj /* Special semantics for the length */
2923446Smrj
2933446Smrj if ((Buffer->Length == ACPI_NO_BUFFER) ||
2943446Smrj (Buffer->Length == ACPI_ALLOCATE_BUFFER) ||
2953446Smrj (Buffer->Length == ACPI_ALLOCATE_LOCAL_BUFFER))
2963446Smrj {
2973446Smrj return (AE_OK);
2983446Smrj }
2993446Smrj
3003446Smrj /* Length is valid, the buffer pointer must be also */
3013446Smrj
3023446Smrj if (!Buffer->Pointer)
3033446Smrj {
3043446Smrj return (AE_BAD_PARAMETER);
3053446Smrj }
3063446Smrj
3073446Smrj return (AE_OK);
3083446Smrj }
3093446Smrj
3103446Smrj
3113446Smrj /*******************************************************************************
3123446Smrj *
3133446Smrj * FUNCTION: AcpiUtInitializeBuffer
3143446Smrj *
3153446Smrj * PARAMETERS: Buffer - Buffer to be validated
3163446Smrj * RequiredLength - Length needed
3173446Smrj *
3183446Smrj * RETURN: Status
3193446Smrj *
3203446Smrj * DESCRIPTION: Validate that the buffer is of the required length or
321*9980SDana.Myers@Sun.COM * allocate a new buffer. Returned buffer is always zeroed.
3223446Smrj *
3233446Smrj ******************************************************************************/
3243446Smrj
3253446Smrj ACPI_STATUS
AcpiUtInitializeBuffer(ACPI_BUFFER * Buffer,ACPI_SIZE RequiredLength)3263446Smrj AcpiUtInitializeBuffer (
3273446Smrj ACPI_BUFFER *Buffer,
3283446Smrj ACPI_SIZE RequiredLength)
3293446Smrj {
330*9980SDana.Myers@Sun.COM ACPI_SIZE InputBufferLength;
3313446Smrj
3323446Smrj
3337851SDana.Myers@Sun.COM /* Parameter validation */
3347851SDana.Myers@Sun.COM
3357851SDana.Myers@Sun.COM if (!Buffer || !RequiredLength)
3367851SDana.Myers@Sun.COM {
3377851SDana.Myers@Sun.COM return (AE_BAD_PARAMETER);
3387851SDana.Myers@Sun.COM }
3397851SDana.Myers@Sun.COM
340*9980SDana.Myers@Sun.COM /*
341*9980SDana.Myers@Sun.COM * Buffer->Length is used as both an input and output parameter. Get the
342*9980SDana.Myers@Sun.COM * input actual length and set the output required buffer length.
343*9980SDana.Myers@Sun.COM */
344*9980SDana.Myers@Sun.COM InputBufferLength = Buffer->Length;
345*9980SDana.Myers@Sun.COM Buffer->Length = RequiredLength;
346*9980SDana.Myers@Sun.COM
347*9980SDana.Myers@Sun.COM /*
348*9980SDana.Myers@Sun.COM * The input buffer length contains the actual buffer length, or the type
349*9980SDana.Myers@Sun.COM * of buffer to be allocated by this routine.
350*9980SDana.Myers@Sun.COM */
351*9980SDana.Myers@Sun.COM switch (InputBufferLength)
3523446Smrj {
3533446Smrj case ACPI_NO_BUFFER:
3543446Smrj
355*9980SDana.Myers@Sun.COM /* Return the exception (and the required buffer length) */
3563446Smrj
357*9980SDana.Myers@Sun.COM return (AE_BUFFER_OVERFLOW);
3583446Smrj
3593446Smrj case ACPI_ALLOCATE_BUFFER:
3603446Smrj
3613446Smrj /* Allocate a new buffer */
3623446Smrj
3633446Smrj Buffer->Pointer = AcpiOsAllocate (RequiredLength);
3643446Smrj break;
3653446Smrj
3663446Smrj case ACPI_ALLOCATE_LOCAL_BUFFER:
3673446Smrj
3683446Smrj /* Allocate a new buffer with local interface to allow tracking */
3693446Smrj
370*9980SDana.Myers@Sun.COM Buffer->Pointer = ACPI_ALLOCATE (RequiredLength);
3713446Smrj break;
3723446Smrj
3733446Smrj default:
3743446Smrj
3753446Smrj /* Existing buffer: Validate the size of the buffer */
3763446Smrj
377*9980SDana.Myers@Sun.COM if (InputBufferLength < RequiredLength)
3783446Smrj {
379*9980SDana.Myers@Sun.COM return (AE_BUFFER_OVERFLOW);
3803446Smrj }
3813446Smrj break;
3823446Smrj }
3833446Smrj
384*9980SDana.Myers@Sun.COM /* Validate allocation from above or input buffer pointer */
385*9980SDana.Myers@Sun.COM
386*9980SDana.Myers@Sun.COM if (!Buffer->Pointer)
387*9980SDana.Myers@Sun.COM {
388*9980SDana.Myers@Sun.COM return (AE_NO_MEMORY);
389*9980SDana.Myers@Sun.COM }
390*9980SDana.Myers@Sun.COM
391*9980SDana.Myers@Sun.COM /* Have a valid buffer, clear it */
392*9980SDana.Myers@Sun.COM
393*9980SDana.Myers@Sun.COM ACPI_MEMSET (Buffer->Pointer, 0, RequiredLength);
394*9980SDana.Myers@Sun.COM return (AE_OK);
3953446Smrj }
3963446Smrj
3973446Smrj
3983446Smrj /*******************************************************************************
3993446Smrj *
4003446Smrj * FUNCTION: AcpiUtAllocate
4013446Smrj *
4023446Smrj * PARAMETERS: Size - Size of the allocation
4033446Smrj * Component - Component type of caller
4043446Smrj * Module - Source file name of caller
4053446Smrj * Line - Line number of caller
4063446Smrj *
4073446Smrj * RETURN: Address of the allocated memory on success, NULL on failure.
4083446Smrj *
4093446Smrj * DESCRIPTION: Subsystem equivalent of malloc.
4103446Smrj *
4113446Smrj ******************************************************************************/
4123446Smrj
4133446Smrj void *
AcpiUtAllocate(ACPI_SIZE Size,UINT32 Component,const char * Module,UINT32 Line)4143446Smrj AcpiUtAllocate (
4153446Smrj ACPI_SIZE Size,
4163446Smrj UINT32 Component,
4177851SDana.Myers@Sun.COM const char *Module,
4183446Smrj UINT32 Line)
4193446Smrj {
4203446Smrj void *Allocation;
4213446Smrj
4223446Smrj
4233446Smrj ACPI_FUNCTION_TRACE_U32 (UtAllocate, Size);
4243446Smrj
4253446Smrj
4263446Smrj /* Check for an inadvertent size of zero bytes */
4273446Smrj
4283446Smrj if (!Size)
4293446Smrj {
4303446Smrj ACPI_WARNING ((Module, Line,
4313446Smrj "Attempt to allocate zero bytes, allocating 1 byte"));
4323446Smrj Size = 1;
4333446Smrj }
4343446Smrj
4353446Smrj Allocation = AcpiOsAllocate (Size);
4363446Smrj if (!Allocation)
4373446Smrj {
4383446Smrj /* Report allocation error */
4393446Smrj
4403446Smrj ACPI_WARNING ((Module, Line,
4413446Smrj "Could not allocate size %X", (UINT32) Size));
4423446Smrj
4433446Smrj return_PTR (NULL);
4443446Smrj }
4453446Smrj
4463446Smrj return_PTR (Allocation);
4473446Smrj }
4483446Smrj
4493446Smrj
4503446Smrj /*******************************************************************************
4513446Smrj *
4523446Smrj * FUNCTION: AcpiUtAllocateZeroed
4533446Smrj *
4543446Smrj * PARAMETERS: Size - Size of the allocation
4553446Smrj * Component - Component type of caller
4563446Smrj * Module - Source file name of caller
4573446Smrj * Line - Line number of caller
4583446Smrj *
4593446Smrj * RETURN: Address of the allocated memory on success, NULL on failure.
4603446Smrj *
4613446Smrj * DESCRIPTION: Subsystem equivalent of calloc. Allocate and zero memory.
4623446Smrj *
4633446Smrj ******************************************************************************/
4643446Smrj
4653446Smrj void *
AcpiUtAllocateZeroed(ACPI_SIZE Size,UINT32 Component,const char * Module,UINT32 Line)4663446Smrj AcpiUtAllocateZeroed (
4673446Smrj ACPI_SIZE Size,
4683446Smrj UINT32 Component,
4697851SDana.Myers@Sun.COM const char *Module,
4703446Smrj UINT32 Line)
4713446Smrj {
4723446Smrj void *Allocation;
4733446Smrj
4743446Smrj
4753446Smrj ACPI_FUNCTION_ENTRY ();
4763446Smrj
4773446Smrj
4783446Smrj Allocation = AcpiUtAllocate (Size, Component, Module, Line);
4793446Smrj if (Allocation)
4803446Smrj {
4813446Smrj /* Clear the memory block */
4823446Smrj
4833446Smrj ACPI_MEMSET (Allocation, 0, Size);
4843446Smrj }
4853446Smrj
4863446Smrj return (Allocation);
4873446Smrj }
4883446Smrj
489