utalloc.c revision 192384
1178172Simp/******************************************************************************
2178172Simp *
3178172Simp * Module Name: utalloc - local memory allocation routines
4178172Simp *              $Revision: 1.164 $
5178172Simp *
6178172Simp *****************************************************************************/
7178172Simp
8178172Simp/******************************************************************************
9178172Simp *
10178172Simp * 1. Copyright Notice
11178172Simp *
12178172Simp * Some or all of this work - Copyright (c) 1999 - 2007, Intel Corp.
13178172Simp * All rights reserved.
14178172Simp *
15178172Simp * 2. License
16178172Simp *
17178172Simp * 2.1. This is your license from Intel Corp. under its intellectual property
18178172Simp * rights.  You may have additional license terms from the party that provided
19178172Simp * you this software, covering your right to use that party's intellectual
20178172Simp * property rights.
21178172Simp *
22178172Simp * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23178172Simp * copy of the source code appearing in this file ("Covered Code") an
24178172Simp * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25178172Simp * base code distributed originally by Intel ("Original Intel Code") to copy,
26178172Simp * make derivatives, distribute, use and display any portion of the Covered
27178172Simp * Code in any form, with the right to sublicense such rights; and
28178172Simp *
29178172Simp * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30178172Simp * license (with the right to sublicense), under only those claims of Intel
31178172Simp * patents that are infringed by the Original Intel Code, to make, use, sell,
32178172Simp * offer to sell, and import the Covered Code and derivative works thereof
33178172Simp * solely to the minimum extent necessary to exercise the above copyright
34178172Simp * license, and in no event shall the patent license extend to any additions
35178172Simp * to or modifications of the Original Intel Code.  No other license or right
36178172Simp * is granted directly or by implication, estoppel or otherwise;
37178172Simp *
38178172Simp * The above copyright and patent license is granted only if the following
39178172Simp * conditions are met:
40178172Simp *
41178172Simp * 3. Conditions
42178172Simp *
43178172Simp * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44178172Simp * Redistribution of source code of any substantial portion of the Covered
45178172Simp * Code or modification with rights to further distribute source must include
46178172Simp * the above Copyright Notice, the above License, this list of Conditions,
47178172Simp * and the following Disclaimer and Export Compliance provision.  In addition,
48178172Simp * Licensee must cause all Covered Code to which Licensee contributes to
49178172Simp * contain a file documenting the changes Licensee made to create that Covered
50178172Simp * Code and the date of any change.  Licensee must include in that file the
51178172Simp * documentation of any changes made by any predecessor Licensee.  Licensee
52178172Simp * must include a prominent statement that the modification is derived,
53178172Simp * directly or indirectly, from Original Intel Code.
54178172Simp *
55178172Simp * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56178172Simp * Redistribution of source code of any substantial portion of the Covered
57178172Simp * Code or modification without rights to further distribute source must
58178172Simp * include the following Disclaimer and Export Compliance provision in the
59178172Simp * documentation and/or other materials provided with distribution.  In
60178172Simp * addition, Licensee may not authorize further sublicense of source of any
61178172Simp * portion of the Covered Code, and must include terms to the effect that the
62178172Simp * license from Licensee to its licensee is limited to the intellectual
63178172Simp * property embodied in the software Licensee provides to its licensee, and
64178172Simp * not to intellectual property embodied in modifications its licensee may
65202046Simp * make.
66202046Simp *
67178172Simp * 3.3. Redistribution of Executable. Redistribution in executable form of any
68178172Simp * substantial portion of the Covered Code or modification must reproduce the
69206834Sjmallett * above Copyright Notice, and the following Disclaimer and Export Compliance
70206834Sjmallett * provision in the documentation and/or other materials provided with the
71206834Sjmallett * distribution.
72206834Sjmallett *
73206834Sjmallett * 3.4. Intel retains all right, title, and interest in and to the Original
74206834Sjmallett * Intel Code.
75178172Simp *
76178172Simp * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77178172Simp * Intel shall be used in advertising or otherwise to promote the sale, use or
78178172Simp * other dealings in products derived from or relating to the Covered Code
79202046Simp * without prior written authorization from Intel.
80202046Simp *
81202046Simp * 4. Disclaimer and Export Compliance
82202046Simp *
83209500Sjchandra * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84209500Sjchandra * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85209500Sjchandra * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
86209500Sjchandra * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
87209500Sjchandra * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
88209500Sjchandra * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89209500Sjchandra * PARTICULAR PURPOSE.
90209500Sjchandra *
91209500Sjchandra * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92178172Simp * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93178172Simp * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94178172Simp * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95178172Simp * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96178172Simp * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
97178172Simp * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98178172Simp * LIMITED REMEDY.
99178172Simp *
100178172Simp * 4.3. Licensee shall not export, either directly or indirectly, any of this
101178172Simp * software or system incorporating such software without first obtaining any
102178172Simp * required license or other approval from the U. S. Department of Commerce or
103178172Simp * any other agency or department of the United States Government.  In the
104178172Simp * event Licensee exports any such software from the United States or
105178172Simp * re-exports any such software from a foreign destination, Licensee shall
106206834Sjmallett * ensure that the distribution and export/re-export of the software is in
107206834Sjmallett * compliance with all laws, regulations, orders, or other restrictions of the
108206834Sjmallett * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109210038Simp * any of its subsidiaries will export/re-export any technical data, process,
110206834Sjmallett * software, or service, directly or indirectly, to any country for which the
111178172Simp * United States government or any agency thereof requires an export license,
112178172Simp * other governmental approval, or letter of assurance, without first obtaining
113178172Simp * such license, approval or letter.
114178172Simp *
115178172Simp *****************************************************************************/
116178172Simp
117178172Simp#define __UTALLOC_C__
118178172Simp
119178172Simp#include <contrib/dev/acpica/acpi.h>
120178172Simp#include <contrib/dev/acpica/acdebug.h>
121178172Simp
122178172Simp#define _COMPONENT          ACPI_UTILITIES
123178172Simp        ACPI_MODULE_NAME    ("utalloc")
124178172Simp
125206834Sjmallett
126206834Sjmallett/*******************************************************************************
127178172Simp *
128206834Sjmallett * FUNCTION:    AcpiUtCreateCaches
129209500Sjchandra *
130206834Sjmallett * PARAMETERS:  None
131178172Simp *
132206834Sjmallett * RETURN:      Status
133206834Sjmallett *
134209500Sjchandra * DESCRIPTION: Create all local caches
135206834Sjmallett *
136178172Simp ******************************************************************************/
137206834Sjmallett
138210038SimpACPI_STATUS
139206834SjmallettAcpiUtCreateCaches (
140206834Sjmallett    void)
141206834Sjmallett{
142206834Sjmallett    ACPI_STATUS             Status;
143206834Sjmallett
144206834Sjmallett
145206834Sjmallett    /* Object Caches, for frequently used objects */
146210038Simp
147206834Sjmallett    Status = AcpiOsCreateCache ("Acpi-Namespace", sizeof (ACPI_NAMESPACE_NODE),
148206834Sjmallett                ACPI_MAX_NAMESPACE_CACHE_DEPTH, &AcpiGbl_NamespaceCache);
149210038Simp    if (ACPI_FAILURE (Status))
150206834Sjmallett    {
151206834Sjmallett        return (Status);
152178172Simp    }
153206834Sjmallett
154206834Sjmallett    Status = AcpiOsCreateCache ("Acpi-State", sizeof (ACPI_GENERIC_STATE),
155206834Sjmallett                ACPI_MAX_STATE_CACHE_DEPTH, &AcpiGbl_StateCache);
156206834Sjmallett    if (ACPI_FAILURE (Status))
157206834Sjmallett    {
158206834Sjmallett        return (Status);
159178172Simp    }
160178172Simp
161178172Simp    Status = AcpiOsCreateCache ("Acpi-Parse", sizeof (ACPI_PARSE_OBJ_COMMON),
162178172Simp                ACPI_MAX_PARSE_CACHE_DEPTH, &AcpiGbl_PsNodeCache);
163178172Simp    if (ACPI_FAILURE (Status))
164178172Simp    {
165178172Simp        return (Status);
166178172Simp    }
167178172Simp
168178172Simp    Status = AcpiOsCreateCache ("Acpi-ParseExt", sizeof (ACPI_PARSE_OBJ_NAMED),
169178172Simp                ACPI_MAX_EXTPARSE_CACHE_DEPTH, &AcpiGbl_PsNodeExtCache);
170210038Simp    if (ACPI_FAILURE (Status))
171210038Simp    {
172178172Simp        return (Status);
173178172Simp    }
174178172Simp
175178172Simp    Status = AcpiOsCreateCache ("Acpi-Operand", sizeof (ACPI_OPERAND_OBJECT),
176210038Simp                ACPI_MAX_OBJECT_CACHE_DEPTH, &AcpiGbl_OperandCache);
177178172Simp    if (ACPI_FAILURE (Status))
178209500Sjchandra    {
179209500Sjchandra        return (Status);
180209500Sjchandra    }
181178172Simp
182202046Simp
183202046Simp#ifdef ACPI_DBG_TRACK_ALLOCATIONS
184178172Simp
185178172Simp    /* Memory allocation lists */
186178172Simp
187178172Simp    Status = AcpiUtCreateList ("Acpi-Global", 0,
188206834Sjmallett                &AcpiGbl_GlobalList);
189178172Simp    if (ACPI_FAILURE (Status))
190178172Simp    {
191178172Simp        return (Status);
192178172Simp    }
193178172Simp
194178172Simp    Status = AcpiUtCreateList ("Acpi-Namespace", sizeof (ACPI_NAMESPACE_NODE),
195178172Simp                &AcpiGbl_NsNodeList);
196178172Simp    if (ACPI_FAILURE (Status))
197178172Simp    {
198178172Simp        return (Status);
199178172Simp    }
200178172Simp#endif
201210038Simp
202178172Simp    return (AE_OK);
203178172Simp}
204178172Simp
205178172Simp
206178172Simp/*******************************************************************************
207178172Simp *
208178172Simp * FUNCTION:    AcpiUtDeleteCaches
209178172Simp *
210178172Simp * PARAMETERS:  None
211178172Simp *
212178172Simp * RETURN:      Status
213178172Simp *
214178172Simp * DESCRIPTION: Purge and delete all local caches
215178172Simp *
216178172Simp ******************************************************************************/
217178172Simp
218178172SimpACPI_STATUS
219178172SimpAcpiUtDeleteCaches (
220178172Simp    void)
221178172Simp{
222178172Simp#ifdef ACPI_DBG_TRACK_ALLOCATIONS
223178172Simp    char                    Buffer[7];
224178172Simp
225178172Simp    if (AcpiGbl_DisplayFinalMemStats)
226178172Simp    {
227206834Sjmallett        ACPI_STRCPY (Buffer, "MEMORY");
228178172Simp        AcpiDbDisplayStatistics (Buffer);
229210311Sjmallett    }
230178172Simp#endif
231210038Simp
232178172Simp    (void) AcpiOsDeleteCache (AcpiGbl_NamespaceCache);
233178172Simp    AcpiGbl_NamespaceCache = NULL;
234205360Sneel
235178172Simp    (void) AcpiOsDeleteCache (AcpiGbl_StateCache);
236210038Simp    AcpiGbl_StateCache = NULL;
237207134Sjmallett
238209810Sjchandra    (void) AcpiOsDeleteCache (AcpiGbl_OperandCache);
239209810Sjchandra    AcpiGbl_OperandCache = NULL;
240210038Simp
241210644Sjchandra    (void) AcpiOsDeleteCache (AcpiGbl_PsNodeCache);
242209810Sjchandra    AcpiGbl_PsNodeCache = NULL;
243209810Sjchandra
244209810Sjchandra    (void) AcpiOsDeleteCache (AcpiGbl_PsNodeExtCache);
245210038Simp    AcpiGbl_PsNodeExtCache = NULL;
246209810Sjchandra
247178172Simp
248178172Simp#ifdef ACPI_DBG_TRACK_ALLOCATIONS
249210038Simp
250205360Sneel    /* Debug only - display leftover memory allocation, if any */
251178172Simp
252210038Simp    AcpiUtDumpAllocations (ACPI_UINT32_MAX, NULL);
253207134Sjmallett
254178172Simp    /* Free memory lists */
255206834Sjmallett
256204109Sneel    AcpiOsFree (AcpiGbl_GlobalList);
257204109Sneel    AcpiGbl_GlobalList = NULL;
258204109Sneel
259204109Sneel    AcpiOsFree (AcpiGbl_NsNodeList);
260204109Sneel    AcpiGbl_NsNodeList = NULL;
261204109Sneel#endif
262204109Sneel
263204109Sneel    return (AE_OK);
264204109Sneel}
265178172Simp
266178172Simp
267178172Simp/*******************************************************************************
268178172Simp *
269178172Simp * FUNCTION:    AcpiUtValidateBuffer
270178172Simp *
271178172Simp * PARAMETERS:  Buffer              - Buffer descriptor to be validated
272178172Simp *
273178172Simp * RETURN:      Status
274178172Simp *
275178172Simp * DESCRIPTION: Perform parameter validation checks on an ACPI_BUFFER
276178172Simp *
277178172Simp ******************************************************************************/
278202046Simp
279202046SimpACPI_STATUS
280202046SimpAcpiUtValidateBuffer (
281202046Simp    ACPI_BUFFER             *Buffer)
282178172Simp{
283178172Simp
284178172Simp    /* Obviously, the structure pointer must be valid */
285178172Simp
286178172Simp    if (!Buffer)
287178172Simp    {
288178172Simp        return (AE_BAD_PARAMETER);
289178172Simp    }
290178172Simp
291178172Simp    /* Special semantics for the length */
292178172Simp
293178172Simp    if ((Buffer->Length == ACPI_NO_BUFFER)              ||
294178172Simp        (Buffer->Length == ACPI_ALLOCATE_BUFFER)        ||
295178172Simp        (Buffer->Length == ACPI_ALLOCATE_LOCAL_BUFFER))
296210038Simp    {
297210038Simp        return (AE_OK);
298210038Simp    }
299210038Simp
300178172Simp    /* Length is valid, the buffer pointer must be also */
301178172Simp
302178172Simp    if (!Buffer->Pointer)
303178172Simp    {
304204109Sneel        return (AE_BAD_PARAMETER);
305204109Sneel    }
306204109Sneel
307204109Sneel    return (AE_OK);
308204109Sneel}
309178172Simp
310202046Simp
311178172Simp/*******************************************************************************
312178172Simp *
313206834Sjmallett * FUNCTION:    AcpiUtInitializeBuffer
314178172Simp *
315178172Simp * PARAMETERS:  Buffer              - Buffer to be validated
316178172Simp *              RequiredLength      - Length needed
317206834Sjmallett *
318178172Simp * RETURN:      Status
319178172Simp *
320206834Sjmallett * DESCRIPTION: Validate that the buffer is of the required length or
321202046Simp *              allocate a new buffer.  Returned buffer is always zeroed.
322178172Simp *
323178172Simp ******************************************************************************/
324178172Simp
325178172SimpACPI_STATUS
326210038SimpAcpiUtInitializeBuffer (
327202046Simp    ACPI_BUFFER             *Buffer,
328178172Simp    ACPI_SIZE               RequiredLength)
329178172Simp{
330178172Simp    ACPI_STATUS             Status = AE_OK;
331178172Simp
332178172Simp
333178172Simp    switch (Buffer->Length)
334178172Simp    {
335178172Simp    case ACPI_NO_BUFFER:
336178172Simp
337178172Simp        /* Set the exception and returned the required length */
338178172Simp
339202046Simp        Status = AE_BUFFER_OVERFLOW;
340202046Simp        break;
341202046Simp
342202046Simp
343178172Simp    case ACPI_ALLOCATE_BUFFER:
344178172Simp
345178172Simp        /* Allocate a new buffer */
346178172Simp
347178172Simp        Buffer->Pointer = AcpiOsAllocate (RequiredLength);
348178172Simp        if (!Buffer->Pointer)
349178172Simp        {
350178172Simp            return (AE_NO_MEMORY);
351178172Simp        }
352178172Simp
353178172Simp        /* Clear the buffer */
354178172Simp
355178172Simp        ACPI_MEMSET (Buffer->Pointer, 0, RequiredLength);
356202046Simp        break;
357210038Simp
358178172Simp
359178172Simp    case ACPI_ALLOCATE_LOCAL_BUFFER:
360178172Simp
361178172Simp        /* Allocate a new buffer with local interface to allow tracking */
362178172Simp
363178172Simp        Buffer->Pointer = ACPI_ALLOCATE_ZEROED (RequiredLength);
364178172Simp        if (!Buffer->Pointer)
365206834Sjmallett        {
366206834Sjmallett            return (AE_NO_MEMORY);
367178172Simp        }
368178172Simp        break;
369178172Simp
370206834Sjmallett
371206834Sjmallett    default:
372178172Simp
373178172Simp        /* Existing buffer: Validate the size of the buffer */
374178172Simp
375178172Simp        if (Buffer->Length < RequiredLength)
376178172Simp        {
377178172Simp            Status = AE_BUFFER_OVERFLOW;
378178172Simp            break;
379202046Simp        }
380202046Simp
381178172Simp        /* Clear the buffer */
382206834Sjmallett
383178172Simp        ACPI_MEMSET (Buffer->Pointer, 0, RequiredLength);
384202046Simp        break;
385202046Simp    }
386202046Simp
387202046Simp    Buffer->Length = RequiredLength;
388202046Simp    return (Status);
389202046Simp}
390210038Simp
391210038Simp
392202046Simp/*******************************************************************************
393210038Simp *
394202046Simp * FUNCTION:    AcpiUtAllocate
395202046Simp *
396178172Simp * PARAMETERS:  Size                - Size of the allocation
397178172Simp *              Component           - Component type of caller
398178172Simp *              Module              - Source file name of caller
399178172Simp *              Line                - Line number of caller
400178172Simp *
401178172Simp * RETURN:      Address of the allocated memory on success, NULL on failure.
402178172Simp *
403178172Simp * DESCRIPTION: Subsystem equivalent of malloc.
404206834Sjmallett *
405178172Simp ******************************************************************************/
406178172Simp
407206834Sjmallettvoid *
408178172SimpAcpiUtAllocate (
409178172Simp    ACPI_SIZE               Size,
410178172Simp    UINT32                  Component,
411178172Simp    char                    *Module,
412178172Simp    UINT32                  Line)
413178172Simp{
414178172Simp    void                    *Allocation;
415178172Simp
416178172Simp
417178172Simp    ACPI_FUNCTION_TRACE_U32 (UtAllocate, Size);
418178172Simp
419178172Simp
420178172Simp    /* Check for an inadvertent size of zero bytes */
421178172Simp
422178172Simp    if (!Size)
423206834Sjmallett    {
424178172Simp        ACPI_WARNING ((Module, Line,
425206834Sjmallett            "Attempt to allocate zero bytes, allocating 1 byte"));
426178172Simp        Size = 1;
427178172Simp    }
428178172Simp
429210638Sjchandra    Allocation = AcpiOsAllocate (Size);
430210638Sjchandra    if (!Allocation)
431210638Sjchandra    {
432210638Sjchandra        /* Report allocation error */
433210638Sjchandra
434210638Sjchandra        ACPI_WARNING ((Module, Line,
435178172Simp            "Could not allocate size %X", (UINT32) Size));
436206834Sjmallett
437178172Simp        return_PTR (NULL);
438178172Simp    }
439178172Simp
440178172Simp    return_PTR (Allocation);
441178172Simp}
442178172Simp
443178172Simp
444178172Simp/*******************************************************************************
445178172Simp *
446178172Simp * FUNCTION:    AcpiUtAllocateZeroed
447178172Simp *
448178172Simp * PARAMETERS:  Size                - Size of the allocation
449178172Simp *              Component           - Component type of caller
450178172Simp *              Module              - Source file name of caller
451202046Simp *              Line                - Line number of caller
452210638Sjchandra *
453202046Simp * RETURN:      Address of the allocated memory on success, NULL on failure.
454202046Simp *
455202046Simp * DESCRIPTION: Subsystem equivalent of calloc. Allocate and zero memory.
456178172Simp *
457210038Simp ******************************************************************************/
458178172Simp
459178172Simpvoid *
460178172SimpAcpiUtAllocateZeroed (
461178172Simp    ACPI_SIZE               Size,
462210038Simp    UINT32                  Component,
463178172Simp    char                    *Module,
464178172Simp    UINT32                  Line)
465178172Simp{
466178172Simp    void                    *Allocation;
467210038Simp
468178172Simp
469178172Simp    ACPI_FUNCTION_ENTRY ();
470178172Simp
471178172Simp
472206834Sjmallett    Allocation = AcpiUtAllocate (Size, Component, Module, Line);
473178172Simp    if (Allocation)
474178172Simp    {
475178172Simp        /* Clear the memory block */
476178172Simp
477178172Simp        ACPI_MEMSET (Allocation, 0, Size);
478178172Simp    }
479178172Simp
480206834Sjmallett    return (Allocation);
481202046Simp}
482178172Simp
483210038Simp