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