xref: /titanic_51/usr/src/uts/intel/io/acpica/utilities/utalloc.c (revision 385cc6b4ad1792caef3f84eb61eed3f27085801f)
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