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 *
AcpiOsAllocateZeroed(ACPI_SIZE Size)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
AcpiUtCreateCaches(void)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
AcpiUtDeleteCaches(void)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
AcpiUtValidateBuffer(ACPI_BUFFER * Buffer)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
AcpiUtInitializeBuffer(ACPI_BUFFER * Buffer,ACPI_SIZE RequiredLength)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