utalloc.c revision 217365
1/******************************************************************************
2 *
3 * Module Name: utalloc - local memory allocation routines
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2011, 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#define __UTALLOC_C__
45
46#include <contrib/dev/acpica/include/acpi.h>
47#include <contrib/dev/acpica/include/accommon.h>
48#include <contrib/dev/acpica/include/acdebug.h>
49
50#define _COMPONENT          ACPI_UTILITIES
51        ACPI_MODULE_NAME    ("utalloc")
52
53
54/*******************************************************************************
55 *
56 * FUNCTION:    AcpiUtCreateCaches
57 *
58 * PARAMETERS:  None
59 *
60 * RETURN:      Status
61 *
62 * DESCRIPTION: Create all local caches
63 *
64 ******************************************************************************/
65
66ACPI_STATUS
67AcpiUtCreateCaches (
68    void)
69{
70    ACPI_STATUS             Status;
71
72
73    /* Object Caches, for frequently used objects */
74
75    Status = AcpiOsCreateCache ("Acpi-Namespace", sizeof (ACPI_NAMESPACE_NODE),
76                ACPI_MAX_NAMESPACE_CACHE_DEPTH, &AcpiGbl_NamespaceCache);
77    if (ACPI_FAILURE (Status))
78    {
79        return (Status);
80    }
81
82    Status = AcpiOsCreateCache ("Acpi-State", sizeof (ACPI_GENERIC_STATE),
83                ACPI_MAX_STATE_CACHE_DEPTH, &AcpiGbl_StateCache);
84    if (ACPI_FAILURE (Status))
85    {
86        return (Status);
87    }
88
89    Status = AcpiOsCreateCache ("Acpi-Parse", sizeof (ACPI_PARSE_OBJ_COMMON),
90                ACPI_MAX_PARSE_CACHE_DEPTH, &AcpiGbl_PsNodeCache);
91    if (ACPI_FAILURE (Status))
92    {
93        return (Status);
94    }
95
96    Status = AcpiOsCreateCache ("Acpi-ParseExt", sizeof (ACPI_PARSE_OBJ_NAMED),
97                ACPI_MAX_EXTPARSE_CACHE_DEPTH, &AcpiGbl_PsNodeExtCache);
98    if (ACPI_FAILURE (Status))
99    {
100        return (Status);
101    }
102
103    Status = AcpiOsCreateCache ("Acpi-Operand", sizeof (ACPI_OPERAND_OBJECT),
104                ACPI_MAX_OBJECT_CACHE_DEPTH, &AcpiGbl_OperandCache);
105    if (ACPI_FAILURE (Status))
106    {
107        return (Status);
108    }
109
110
111#ifdef ACPI_DBG_TRACK_ALLOCATIONS
112
113    /* Memory allocation lists */
114
115    Status = AcpiUtCreateList ("Acpi-Global", 0,
116                &AcpiGbl_GlobalList);
117    if (ACPI_FAILURE (Status))
118    {
119        return (Status);
120    }
121
122    Status = AcpiUtCreateList ("Acpi-Namespace", sizeof (ACPI_NAMESPACE_NODE),
123                &AcpiGbl_NsNodeList);
124    if (ACPI_FAILURE (Status))
125    {
126        return (Status);
127    }
128#endif
129
130    return (AE_OK);
131}
132
133
134/*******************************************************************************
135 *
136 * FUNCTION:    AcpiUtDeleteCaches
137 *
138 * PARAMETERS:  None
139 *
140 * RETURN:      Status
141 *
142 * DESCRIPTION: Purge and delete all local caches
143 *
144 ******************************************************************************/
145
146ACPI_STATUS
147AcpiUtDeleteCaches (
148    void)
149{
150#ifdef ACPI_DBG_TRACK_ALLOCATIONS
151    char                    Buffer[7];
152
153    if (AcpiGbl_DisplayFinalMemStats)
154    {
155        ACPI_STRCPY (Buffer, "MEMORY");
156        (void) AcpiDbDisplayStatistics (Buffer);
157    }
158#endif
159
160    (void) AcpiOsDeleteCache (AcpiGbl_NamespaceCache);
161    AcpiGbl_NamespaceCache = NULL;
162
163    (void) AcpiOsDeleteCache (AcpiGbl_StateCache);
164    AcpiGbl_StateCache = NULL;
165
166    (void) AcpiOsDeleteCache (AcpiGbl_OperandCache);
167    AcpiGbl_OperandCache = NULL;
168
169    (void) AcpiOsDeleteCache (AcpiGbl_PsNodeCache);
170    AcpiGbl_PsNodeCache = NULL;
171
172    (void) AcpiOsDeleteCache (AcpiGbl_PsNodeExtCache);
173    AcpiGbl_PsNodeExtCache = NULL;
174
175
176#ifdef ACPI_DBG_TRACK_ALLOCATIONS
177
178    /* Debug only - display leftover memory allocation, if any */
179
180    AcpiUtDumpAllocations (ACPI_UINT32_MAX, NULL);
181
182    /* Free memory lists */
183
184    AcpiOsFree (AcpiGbl_GlobalList);
185    AcpiGbl_GlobalList = NULL;
186
187    AcpiOsFree (AcpiGbl_NsNodeList);
188    AcpiGbl_NsNodeList = NULL;
189#endif
190
191    return (AE_OK);
192}
193
194
195/*******************************************************************************
196 *
197 * FUNCTION:    AcpiUtValidateBuffer
198 *
199 * PARAMETERS:  Buffer              - Buffer descriptor to be validated
200 *
201 * RETURN:      Status
202 *
203 * DESCRIPTION: Perform parameter validation checks on an ACPI_BUFFER
204 *
205 ******************************************************************************/
206
207ACPI_STATUS
208AcpiUtValidateBuffer (
209    ACPI_BUFFER             *Buffer)
210{
211
212    /* Obviously, the structure pointer must be valid */
213
214    if (!Buffer)
215    {
216        return (AE_BAD_PARAMETER);
217    }
218
219    /* Special semantics for the length */
220
221    if ((Buffer->Length == ACPI_NO_BUFFER)              ||
222        (Buffer->Length == ACPI_ALLOCATE_BUFFER)        ||
223        (Buffer->Length == ACPI_ALLOCATE_LOCAL_BUFFER))
224    {
225        return (AE_OK);
226    }
227
228    /* Length is valid, the buffer pointer must be also */
229
230    if (!Buffer->Pointer)
231    {
232        return (AE_BAD_PARAMETER);
233    }
234
235    return (AE_OK);
236}
237
238
239/*******************************************************************************
240 *
241 * FUNCTION:    AcpiUtInitializeBuffer
242 *
243 * PARAMETERS:  Buffer              - Buffer to be validated
244 *              RequiredLength      - Length needed
245 *
246 * RETURN:      Status
247 *
248 * DESCRIPTION: Validate that the buffer is of the required length or
249 *              allocate a new buffer. Returned buffer is always zeroed.
250 *
251 ******************************************************************************/
252
253ACPI_STATUS
254AcpiUtInitializeBuffer (
255    ACPI_BUFFER             *Buffer,
256    ACPI_SIZE               RequiredLength)
257{
258    ACPI_SIZE               InputBufferLength;
259
260
261    /* Parameter validation */
262
263    if (!Buffer || !RequiredLength)
264    {
265        return (AE_BAD_PARAMETER);
266    }
267
268    /*
269     * Buffer->Length is used as both an input and output parameter. Get the
270     * input actual length and set the output required buffer length.
271     */
272    InputBufferLength = Buffer->Length;
273    Buffer->Length = RequiredLength;
274
275    /*
276     * The input buffer length contains the actual buffer length, or the type
277     * of buffer to be allocated by this routine.
278     */
279    switch (InputBufferLength)
280    {
281    case ACPI_NO_BUFFER:
282
283        /* Return the exception (and the required buffer length) */
284
285        return (AE_BUFFER_OVERFLOW);
286
287    case ACPI_ALLOCATE_BUFFER:
288
289        /* Allocate a new buffer */
290
291        Buffer->Pointer = AcpiOsAllocate (RequiredLength);
292        break;
293
294    case ACPI_ALLOCATE_LOCAL_BUFFER:
295
296        /* Allocate a new buffer with local interface to allow tracking */
297
298        Buffer->Pointer = ACPI_ALLOCATE (RequiredLength);
299        break;
300
301    default:
302
303        /* Existing buffer: Validate the size of the buffer */
304
305        if (InputBufferLength < RequiredLength)
306        {
307            return (AE_BUFFER_OVERFLOW);
308        }
309        break;
310    }
311
312    /* Validate allocation from above or input buffer pointer */
313
314    if (!Buffer->Pointer)
315    {
316        return (AE_NO_MEMORY);
317    }
318
319    /* Have a valid buffer, clear it */
320
321    ACPI_MEMSET (Buffer->Pointer, 0, RequiredLength);
322    return (AE_OK);
323}
324
325
326/*******************************************************************************
327 *
328 * FUNCTION:    AcpiUtAllocate
329 *
330 * PARAMETERS:  Size                - Size of the allocation
331 *              Component           - Component type of caller
332 *              Module              - Source file name of caller
333 *              Line                - Line number of caller
334 *
335 * RETURN:      Address of the allocated memory on success, NULL on failure.
336 *
337 * DESCRIPTION: Subsystem equivalent of malloc.
338 *
339 ******************************************************************************/
340
341void *
342AcpiUtAllocate (
343    ACPI_SIZE               Size,
344    UINT32                  Component,
345    const char              *Module,
346    UINT32                  Line)
347{
348    void                    *Allocation;
349
350
351    ACPI_FUNCTION_TRACE_U32 (UtAllocate, Size);
352
353
354    /* Check for an inadvertent size of zero bytes */
355
356    if (!Size)
357    {
358        ACPI_WARNING ((Module, Line,
359            "Attempt to allocate zero bytes, allocating 1 byte"));
360        Size = 1;
361    }
362
363    Allocation = AcpiOsAllocate (Size);
364    if (!Allocation)
365    {
366        /* Report allocation error */
367
368        ACPI_WARNING ((Module, Line,
369            "Could not allocate size %u", (UINT32) Size));
370
371        return_PTR (NULL);
372    }
373
374    return_PTR (Allocation);
375}
376
377
378/*******************************************************************************
379 *
380 * FUNCTION:    AcpiUtAllocateZeroed
381 *
382 * PARAMETERS:  Size                - Size of the allocation
383 *              Component           - Component type of caller
384 *              Module              - Source file name of caller
385 *              Line                - Line number of caller
386 *
387 * RETURN:      Address of the allocated memory on success, NULL on failure.
388 *
389 * DESCRIPTION: Subsystem equivalent of calloc. Allocate and zero memory.
390 *
391 ******************************************************************************/
392
393void *
394AcpiUtAllocateZeroed (
395    ACPI_SIZE               Size,
396    UINT32                  Component,
397    const char              *Module,
398    UINT32                  Line)
399{
400    void                    *Allocation;
401
402
403    ACPI_FUNCTION_ENTRY ();
404
405
406    Allocation = AcpiUtAllocate (Size, Component, Module, Line);
407    if (Allocation)
408    {
409        /* Clear the memory block */
410
411        ACPI_MEMSET (Allocation, 0, Size);
412    }
413
414    return (Allocation);
415}
416
417