utmisc.c revision 73561
1189251Ssam/*******************************************************************************
2189251Ssam *
3189251Ssam * Module Name: cmutils - common utility procedures
4189251Ssam *              $Revision: 27 $
5189251Ssam *
6189251Ssam ******************************************************************************/
7189251Ssam
8189251Ssam/******************************************************************************
9189251Ssam *
10189251Ssam * 1. Copyright Notice
11189251Ssam *
12189251Ssam * Some or all of this work - Copyright (c) 1999, 2000, 2001, Intel Corp.
13189251Ssam * All rights reserved.
14189251Ssam *
15189251Ssam * 2. License
16189251Ssam *
17189251Ssam * 2.1. This is your license from Intel Corp. under its intellectual property
18189251Ssam * rights.  You may have additional license terms from the party that provided
19189251Ssam * you this software, covering your right to use that party's intellectual
20189251Ssam * property rights.
21189251Ssam *
22189251Ssam * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
23189251Ssam * copy of the source code appearing in this file ("Covered Code") an
24189251Ssam * irrevocable, perpetual, worldwide license under Intel's copyrights in the
25189251Ssam * base code distributed originally by Intel ("Original Intel Code") to copy,
26189251Ssam * make derivatives, distribute, use and display any portion of the Covered
27189251Ssam * Code in any form, with the right to sublicense such rights; and
28189251Ssam *
29189251Ssam * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
30189251Ssam * license (with the right to sublicense), under only those claims of Intel
31189251Ssam * patents that are infringed by the Original Intel Code, to make, use, sell,
32189251Ssam * offer to sell, and import the Covered Code and derivative works thereof
33189251Ssam * solely to the minimum extent necessary to exercise the above copyright
34189251Ssam * license, and in no event shall the patent license extend to any additions
35189251Ssam * to or modifications of the Original Intel Code.  No other license or right
36189251Ssam * is granted directly or by implication, estoppel or otherwise;
37189251Ssam *
38189251Ssam * The above copyright and patent license is granted only if the following
39189251Ssam * conditions are met:
40189251Ssam *
41189251Ssam * 3. Conditions
42189251Ssam *
43189251Ssam * 3.1. Redistribution of Source with Rights to Further Distribute Source.
44189251Ssam * Redistribution of source code of any substantial portion of the Covered
45189251Ssam * Code or modification with rights to further distribute source must include
46189251Ssam * the above Copyright Notice, the above License, this list of Conditions,
47189251Ssam * and the following Disclaimer and Export Compliance provision.  In addition,
48189251Ssam * Licensee must cause all Covered Code to which Licensee contributes to
49189251Ssam * contain a file documenting the changes Licensee made to create that Covered
50189251Ssam * Code and the date of any change.  Licensee must include in that file the
51189251Ssam * documentation of any changes made by any predecessor Licensee.  Licensee
52189251Ssam * must include a prominent statement that the modification is derived,
53189251Ssam * directly or indirectly, from Original Intel Code.
54189251Ssam *
55189251Ssam * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
56189251Ssam * Redistribution of source code of any substantial portion of the Covered
57189251Ssam * Code or modification without rights to further distribute source must
58189251Ssam * include the following Disclaimer and Export Compliance provision in the
59189251Ssam * documentation and/or other materials provided with distribution.  In
60189251Ssam * addition, Licensee may not authorize further sublicense of source of any
61189251Ssam * portion of the Covered Code, and must include terms to the effect that the
62189251Ssam * license from Licensee to its licensee is limited to the intellectual
63189251Ssam * property embodied in the software Licensee provides to its licensee, and
64189251Ssam * not to intellectual property embodied in modifications its licensee may
65189251Ssam * make.
66189251Ssam *
67189251Ssam * 3.3. Redistribution of Executable. Redistribution in executable form of any
68189251Ssam * substantial portion of the Covered Code or modification must reproduce the
69189251Ssam * above Copyright Notice, and the following Disclaimer and Export Compliance
70189251Ssam * provision in the documentation and/or other materials provided with the
71189251Ssam * distribution.
72189251Ssam *
73189251Ssam * 3.4. Intel retains all right, title, and interest in and to the Original
74189251Ssam * Intel Code.
75189251Ssam *
76189251Ssam * 3.5. Neither the name Intel nor any other trademark owned or controlled by
77189251Ssam * Intel shall be used in advertising or otherwise to promote the sale, use or
78189251Ssam * other dealings in products derived from or relating to the Covered Code
79189251Ssam * without prior written authorization from Intel.
80189251Ssam *
81189251Ssam * 4. Disclaimer and Export Compliance
82189251Ssam *
83189251Ssam * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
84189251Ssam * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
85189251Ssam * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
86189251Ssam * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
87189251Ssam * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
88189251Ssam * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
89189251Ssam * PARTICULAR PURPOSE.
90189251Ssam *
91189251Ssam * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
92189251Ssam * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
93189251Ssam * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
94189251Ssam * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
95189251Ssam * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
96189251Ssam * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
97189251Ssam * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
98189251Ssam * LIMITED REMEDY.
99189251Ssam *
100189251Ssam * 4.3. Licensee shall not export, either directly or indirectly, any of this
101189251Ssam * software or system incorporating such software without first obtaining any
102189251Ssam * required license or other approval from the U. S. Department of Commerce or
103189251Ssam * any other agency or department of the United States Government.  In the
104189251Ssam * event Licensee exports any such software from the United States or
105189251Ssam * re-exports any such software from a foreign destination, Licensee shall
106189251Ssam * ensure that the distribution and export/re-export of the software is in
107189251Ssam * compliance with all laws, regulations, orders, or other restrictions of the
108189251Ssam * U.S. Export Administration Regulations. Licensee agrees that neither it nor
109189251Ssam * any of its subsidiaries will export/re-export any technical data, process,
110189251Ssam * software, or service, directly or indirectly, to any country for which the
111189251Ssam * United States government or any agency thereof requires an export license,
112189251Ssam * other governmental approval, or letter of assurance, without first obtaining
113189251Ssam * such license, approval or letter.
114189251Ssam *
115189251Ssam *****************************************************************************/
116189251Ssam
117189251Ssam
118189251Ssam#define __CMUTILS_C__
119189251Ssam
120189251Ssam#include "acpi.h"
121189251Ssam#include "acevents.h"
122189251Ssam#include "achware.h"
123189251Ssam#include "acnamesp.h"
124189251Ssam#include "acinterp.h"
125189251Ssam#include "amlcode.h"
126189251Ssam#include "acdebug.h"
127189251Ssam
128189251Ssam
129189251Ssam#define _COMPONENT          MISCELLANEOUS
130189251Ssam        MODULE_NAME         ("cmutils")
131189251Ssam
132189251Ssam
133189251Ssam/*******************************************************************************
134189251Ssam *
135189251Ssam * FUNCTION:    AcpiCmValidAcpiName
136189251Ssam *
137189251Ssam * PARAMETERS:  Character           - The character to be examined
138189251Ssam *
139189251Ssam * RETURN:      1 if Character may appear in a name, else 0
140189251Ssam *
141189251Ssam * DESCRIPTION: Check for a valid ACPI name.  Each character must be one of:
142189251Ssam *              1) Upper case alpha
143189251Ssam *              2) numeric
144189251Ssam *              3) underscore
145189251Ssam *
146189251Ssam ******************************************************************************/
147189251Ssam
148189251SsamBOOLEAN
149189251SsamAcpiCmValidAcpiName (
150189251Ssam    UINT32                  Name)
151189251Ssam{
152189251Ssam    NATIVE_CHAR             *NamePtr = (NATIVE_CHAR *) &Name;
153189251Ssam    UINT32                  i;
154189251Ssam
155189251Ssam
156189251Ssam    for (i = 0; i < ACPI_NAME_SIZE; i++)
157189251Ssam    {
158189251Ssam        if (!((NamePtr[i] == '_') ||
159189251Ssam              (NamePtr[i] >= 'A' && NamePtr[i] <= 'Z') ||
160189251Ssam              (NamePtr[i] >= '0' && NamePtr[i] <= '9')))
161189251Ssam        {
162189251Ssam            return (FALSE);
163189251Ssam        }
164189251Ssam    }
165189251Ssam
166189251Ssam
167189251Ssam    return (TRUE);
168189251Ssam}
169189251Ssam
170189251Ssam
171189251Ssam/*******************************************************************************
172189251Ssam *
173189251Ssam * FUNCTION:    AcpiCmValidAcpiCharacter
174189251Ssam *
175189251Ssam * PARAMETERS:  Character           - The character to be examined
176189251Ssam *
177189251Ssam * RETURN:      1 if Character may appear in a name, else 0
178189251Ssam *
179189251Ssam * DESCRIPTION: Check for a printable character
180189251Ssam *
181189251Ssam ******************************************************************************/
182189251Ssam
183189251SsamBOOLEAN
184189251SsamAcpiCmValidAcpiCharacter (
185189251Ssam    NATIVE_CHAR             Character)
186189251Ssam{
187189251Ssam
188189251Ssam    return ((BOOLEAN)   ((Character == '_') ||
189189251Ssam                        (Character >= 'A' && Character <= 'Z') ||
190189251Ssam                        (Character >= '0' && Character <= '9')));
191189251Ssam}
192189251Ssam
193189251Ssam
194189251Ssam/*******************************************************************************
195189251Ssam *
196189251Ssam * FUNCTION:    AcpiCmMutexInitialize
197189251Ssam *
198189251Ssam * PARAMETERS:  None.
199189251Ssam *
200189251Ssam * RETURN:      Status
201189251Ssam *
202189251Ssam * DESCRIPTION: Create the system mutex objects.
203189251Ssam *
204189251Ssam ******************************************************************************/
205189251Ssam
206189251SsamACPI_STATUS
207189251SsamAcpiCmMutexInitialize (
208189251Ssam    void)
209189251Ssam{
210189251Ssam    UINT32                  i;
211189251Ssam    ACPI_STATUS             Status;
212189251Ssam
213189251Ssam
214189251Ssam    FUNCTION_TRACE ("CmMutexInitialize");
215189251Ssam
216189251Ssam
217189251Ssam    /*
218189251Ssam     * Create each of the predefined mutex objects
219189251Ssam     */
220189251Ssam    for (i = 0; i < NUM_MTX; i++)
221189251Ssam    {
222189251Ssam        Status = AcpiCmCreateMutex (i);
223189251Ssam        if (ACPI_FAILURE (Status))
224189251Ssam        {
225189251Ssam            return_ACPI_STATUS (Status);
226189251Ssam        }
227189251Ssam    }
228189251Ssam
229189251Ssam    return_ACPI_STATUS (AE_OK);
230189251Ssam}
231189251Ssam
232189251Ssam
233189251Ssam/*******************************************************************************
234189251Ssam *
235189251Ssam * FUNCTION:    AcpiCmMutexTerminate
236189251Ssam *
237189251Ssam * PARAMETERS:  None.
238189251Ssam *
239189251Ssam * RETURN:      None.
240189251Ssam *
241189251Ssam * DESCRIPTION: Delete all of the system mutex objects.
242189251Ssam *
243189251Ssam ******************************************************************************/
244189251Ssam
245189251Ssamvoid
246189251SsamAcpiCmMutexTerminate (
247189251Ssam    void)
248189251Ssam{
249189251Ssam    UINT32                  i;
250189251Ssam
251189251Ssam
252189251Ssam    FUNCTION_TRACE ("CmMutexTerminate");
253189251Ssam
254189251Ssam
255189251Ssam    /*
256189251Ssam     * Delete each predefined mutex object
257189251Ssam     */
258189251Ssam    for (i = 0; i < NUM_MTX; i++)
259189251Ssam    {
260189251Ssam        AcpiCmDeleteMutex (i);
261189251Ssam    }
262189251Ssam
263189251Ssam    return_VOID;
264189251Ssam}
265189251Ssam
266189251Ssam
267189251Ssam/*******************************************************************************
268189251Ssam *
269189251Ssam * FUNCTION:    AcpiCmCreateMutex
270189251Ssam *
271189251Ssam * PARAMETERS:  MutexID         - ID of the mutex to be created
272189251Ssam *
273189251Ssam * RETURN:      Status
274189251Ssam *
275189251Ssam * DESCRIPTION: Create a mutex object.
276189251Ssam *
277189251Ssam ******************************************************************************/
278189251Ssam
279189251SsamACPI_STATUS
280189251SsamAcpiCmCreateMutex (
281189251Ssam    ACPI_MUTEX_HANDLE       MutexId)
282189251Ssam{
283189251Ssam    ACPI_STATUS             Status = AE_OK;
284189251Ssam
285189251Ssam
286189251Ssam    FUNCTION_TRACE_U32 ("CmCreateMutex", MutexId);
287189251Ssam
288189251Ssam
289189251Ssam    if (MutexId > MAX_MTX)
290189251Ssam    {
291189251Ssam        return_ACPI_STATUS (AE_BAD_PARAMETER);
292189251Ssam    }
293189251Ssam
294189251Ssam
295189251Ssam    if (!AcpiGbl_AcpiMutexInfo[MutexId].Mutex)
296189251Ssam    {
297189251Ssam        Status = AcpiOsCreateSemaphore (1, 1,
298189251Ssam                                        &AcpiGbl_AcpiMutexInfo[MutexId].Mutex);
299189251Ssam        AcpiGbl_AcpiMutexInfo[MutexId].Locked = FALSE;
300189251Ssam        AcpiGbl_AcpiMutexInfo[MutexId].UseCount = 0;
301189251Ssam    }
302189251Ssam
303189251Ssam    return_ACPI_STATUS (Status);
304189251Ssam}
305189251Ssam
306189251Ssam
307189251Ssam/*******************************************************************************
308189251Ssam *
309189251Ssam * FUNCTION:    AcpiCmDeleteMutex
310189251Ssam *
311189251Ssam * PARAMETERS:  MutexID         - ID of the mutex to be deleted
312189251Ssam *
313189251Ssam * RETURN:      Status
314189251Ssam *
315189251Ssam * DESCRIPTION: Delete a mutex object.
316189251Ssam *
317189251Ssam ******************************************************************************/
318189251Ssam
319189251SsamACPI_STATUS
320189251SsamAcpiCmDeleteMutex (
321189251Ssam    ACPI_MUTEX_HANDLE       MutexId)
322189251Ssam{
323189251Ssam    ACPI_STATUS             Status;
324189251Ssam
325189251Ssam
326189251Ssam    FUNCTION_TRACE_U32 ("CmDeleteMutex", MutexId);
327189251Ssam
328189251Ssam
329189251Ssam    if (MutexId > MAX_MTX)
330189251Ssam    {
331189251Ssam        return_ACPI_STATUS (AE_BAD_PARAMETER);
332189251Ssam    }
333189251Ssam
334189251Ssam
335189251Ssam    Status = AcpiOsDeleteSemaphore (AcpiGbl_AcpiMutexInfo[MutexId].Mutex);
336189251Ssam
337189251Ssam    AcpiGbl_AcpiMutexInfo[MutexId].Mutex = NULL;
338189251Ssam    AcpiGbl_AcpiMutexInfo[MutexId].Locked = FALSE;
339189251Ssam
340189251Ssam    return_ACPI_STATUS (Status);
341189251Ssam}
342189251Ssam
343189251Ssam
344189251Ssam/*******************************************************************************
345189251Ssam *
346189251Ssam * FUNCTION:    AcpiCmAcquireMutex
347189251Ssam *
348189251Ssam * PARAMETERS:  MutexID         - ID of the mutex to be acquired
349189251Ssam *
350189251Ssam * RETURN:      Status
351189251Ssam *
352189251Ssam * DESCRIPTION: Acquire a mutex object.
353189251Ssam *
354189251Ssam ******************************************************************************/
355189251Ssam
356189251SsamACPI_STATUS
357189251SsamAcpiCmAcquireMutex (
358189251Ssam    ACPI_MUTEX_HANDLE       MutexId)
359189251Ssam{
360189251Ssam    ACPI_STATUS             Status;
361189251Ssam
362189251Ssam
363189251Ssam    DEBUG_PRINT (TRACE_MUTEX,
364189251Ssam                ("Acquiring Mutex [%s]\n", AcpiCmGetMutexName (MutexId)));
365189251Ssam
366189251Ssam    if (MutexId > MAX_MTX)
367189251Ssam    {
368189251Ssam        return (AE_BAD_PARAMETER);
369189251Ssam    }
370189251Ssam
371189251Ssam
372189251Ssam    Status = AcpiOsWaitSemaphore (AcpiGbl_AcpiMutexInfo[MutexId].Mutex,
373189251Ssam                                    1, WAIT_FOREVER);
374189251Ssam
375189251Ssam    DEBUG_PRINT (TRACE_MUTEX, ("Acquired Mutex  [%s] Status %s\n",
376189251Ssam                AcpiCmGetMutexName (MutexId), AcpiCmFormatException (Status)));
377189251Ssam
378189251Ssam    if (ACPI_SUCCESS (Status))
379189251Ssam    {
380189251Ssam        AcpiGbl_AcpiMutexInfo[MutexId].Locked = TRUE;
381189251Ssam        AcpiGbl_AcpiMutexInfo[MutexId].UseCount++;
382189251Ssam    }
383189251Ssam
384189251Ssam    return (Status);
385189251Ssam}
386189251Ssam
387189251Ssam
388189251Ssam/*******************************************************************************
389189251Ssam *
390189251Ssam * FUNCTION:    AcpiCmReleaseMutex
391189251Ssam *
392189251Ssam * PARAMETERS:  MutexID         - ID of the mutex to be released
393189251Ssam *
394189251Ssam * RETURN:      Status
395189251Ssam *
396189251Ssam * DESCRIPTION: Release a mutex object.
397189251Ssam *
398189251Ssam ******************************************************************************/
399189251Ssam
400189251SsamACPI_STATUS
401189251SsamAcpiCmReleaseMutex (
402189251Ssam    ACPI_MUTEX_HANDLE       MutexId)
403189251Ssam{
404189251Ssam    ACPI_STATUS             Status;
405189251Ssam
406189251Ssam
407189251Ssam    DEBUG_PRINT (TRACE_MUTEX,
408189251Ssam        ("Releasing Mutex [%s]\n", AcpiCmGetMutexName (MutexId)));
409189251Ssam
410189251Ssam    if (MutexId > MAX_MTX)
411189251Ssam    {
412189251Ssam        return (AE_BAD_PARAMETER);
413189251Ssam    }
414189251Ssam
415189251Ssam
416189251Ssam    AcpiGbl_AcpiMutexInfo[MutexId].Locked = FALSE;  /* Mark before unlocking */
417189251Ssam
418189251Ssam    Status = AcpiOsSignalSemaphore (AcpiGbl_AcpiMutexInfo[MutexId].Mutex, 1);
419189251Ssam
420189251Ssam    if (ACPI_FAILURE (Status))
421189251Ssam    {
422189251Ssam        DEBUG_PRINT (ACPI_ERROR, ("Error Releasing Mutex [%s], %s\n",
423189251Ssam                    AcpiCmGetMutexName (MutexId), AcpiCmFormatException (Status)));
424189251Ssam    }
425189251Ssam    else
426189251Ssam    {
427189251Ssam        DEBUG_PRINT (TRACE_MUTEX, ("Released Mutex [%s], %s\n",
428189251Ssam                    AcpiCmGetMutexName (MutexId), AcpiCmFormatException (Status)));
429189251Ssam    }
430189251Ssam
431189251Ssam    return (Status);
432189251Ssam}
433189251Ssam
434189251Ssam
435189251Ssam/*******************************************************************************
436189251Ssam *
437189251Ssam * FUNCTION:    AcpiCmCreateUpdateStateAndPush
438189251Ssam *
439189251Ssam * PARAMETERS:  *Object         - Object to be added to the new state
440189251Ssam *              Action          - Increment/Decrement
441189251Ssam *              StateList       - List the state will be added to
442189251Ssam *
443189251Ssam * RETURN:      None
444189251Ssam *
445189251Ssam * DESCRIPTION: Create a new state and push it
446189251Ssam *
447189251Ssam ******************************************************************************/
448189251Ssam
449189251SsamACPI_STATUS
450189251SsamAcpiCmCreateUpdateStateAndPush (
451189251Ssam    ACPI_OPERAND_OBJECT     *Object,
452189251Ssam    UINT16                  Action,
453189251Ssam    ACPI_GENERIC_STATE      **StateList)
454189251Ssam{
455189251Ssam    ACPI_GENERIC_STATE       *State;
456189251Ssam
457189251Ssam
458189251Ssam    /* Ignore null objects; these are expected */
459189251Ssam
460189251Ssam    if (!Object)
461189251Ssam    {
462189251Ssam        return (AE_OK);
463189251Ssam    }
464189251Ssam
465189251Ssam    State = AcpiCmCreateUpdateState (Object, Action);
466189251Ssam    if (!State)
467189251Ssam    {
468189251Ssam        return (AE_NO_MEMORY);
469189251Ssam    }
470189251Ssam
471189251Ssam
472189251Ssam    AcpiCmPushGenericState (StateList, State);
473189251Ssam    return (AE_OK);
474189251Ssam}
475189251Ssam
476189251Ssam
477189251Ssam/*******************************************************************************
478189251Ssam *
479189251Ssam * FUNCTION:    AcpiCmCreatePkgStateAndPush
480189251Ssam *
481189251Ssam * PARAMETERS:  *Object         - Object to be added to the new state
482189251Ssam *              Action          - Increment/Decrement
483189251Ssam *              StateList       - List the state will be added to
484189251Ssam *
485189251Ssam * RETURN:      None
486189251Ssam *
487189251Ssam * DESCRIPTION: Create a new state and push it
488189251Ssam *
489189251Ssam ******************************************************************************/
490189251Ssam
491189251SsamACPI_STATUS
492189251SsamAcpiCmCreatePkgStateAndPush (
493189251Ssam    void                    *InternalObject,
494189251Ssam    void                    *ExternalObject,
495189251Ssam    UINT16                  Index,
496189251Ssam    ACPI_GENERIC_STATE      **StateList)
497189251Ssam{
498189251Ssam    ACPI_GENERIC_STATE       *State;
499189251Ssam
500189251Ssam
501189251Ssam
502189251Ssam    State = AcpiCmCreatePkgState (InternalObject, ExternalObject, Index);
503189251Ssam    if (!State)
504189251Ssam    {
505189251Ssam        return (AE_NO_MEMORY);
506189251Ssam    }
507189251Ssam
508189251Ssam
509189251Ssam    AcpiCmPushGenericState (StateList, State);
510189251Ssam    return (AE_OK);
511189251Ssam}
512189251Ssam
513189251Ssam
514189251Ssam
515189251Ssam/*******************************************************************************
516189251Ssam *
517189251Ssam * FUNCTION:    AcpiCmPushGenericState
518189251Ssam *
519189251Ssam * PARAMETERS:  ListHead            - Head of the state stack
520189251Ssam *              State               - State object to push
521189251Ssam *
522189251Ssam * RETURN:      Status
523189251Ssam *
524189251Ssam * DESCRIPTION: Push a state object onto a state stack
525189251Ssam *
526189251Ssam ******************************************************************************/
527189251Ssam
528189251Ssamvoid
529189251SsamAcpiCmPushGenericState (
530189251Ssam    ACPI_GENERIC_STATE      **ListHead,
531189251Ssam    ACPI_GENERIC_STATE      *State)
532189251Ssam{
533    FUNCTION_TRACE ("CmPushGenericState");
534
535    /* Push the state object onto the front of the list (stack) */
536
537    State->Common.Next = *ListHead;
538    *ListHead = State;
539
540    return_VOID;
541}
542
543
544/*******************************************************************************
545 *
546 * FUNCTION:    AcpiCmPopGenericState
547 *
548 * PARAMETERS:  ListHead            - Head of the state stack
549 *
550 * RETURN:      Status
551 *
552 * DESCRIPTION: Pop a state object from a state stack
553 *
554 ******************************************************************************/
555
556ACPI_GENERIC_STATE *
557AcpiCmPopGenericState (
558    ACPI_GENERIC_STATE      **ListHead)
559{
560    ACPI_GENERIC_STATE      *State;
561
562
563    FUNCTION_TRACE ("DsPopGenericState");
564
565
566    /* Remove the state object at the head of the list (stack) */
567
568    State = *ListHead;
569    if (State)
570    {
571        /* Update the list head */
572
573        *ListHead = State->Common.Next;
574    }
575
576    return_PTR (State);
577}
578
579
580/*******************************************************************************
581 *
582 * FUNCTION:    AcpiCmCreateGenericState
583 *
584 * PARAMETERS:  None
585 *
586 * RETURN:      Status
587 *
588 * DESCRIPTION: Create a generic state object.  Attempt to obtain one from
589 *              the global state cache;  If none available, create a new one.
590 *
591 ******************************************************************************/
592
593ACPI_GENERIC_STATE *
594AcpiCmCreateGenericState (void)
595{
596    ACPI_GENERIC_STATE      *State;
597
598
599    AcpiCmAcquireMutex (ACPI_MTX_CACHES);
600
601    AcpiGbl_StateCacheRequests++;
602
603    /* Check the cache first */
604
605    if (AcpiGbl_GenericStateCache)
606    {
607        /* There is an object available, use it */
608
609        State = AcpiGbl_GenericStateCache;
610        AcpiGbl_GenericStateCache = State->Common.Next;
611        State->Common.Next = NULL;
612
613        AcpiGbl_StateCacheHits++;
614        AcpiGbl_GenericStateCacheDepth--;
615
616        AcpiCmReleaseMutex (ACPI_MTX_CACHES);
617
618        DEBUG_PRINT (TRACE_EXEC, ("CreateGenState: State %p from cache\n", State));
619    }
620
621    else
622    {
623        /* The cache is empty, create a new object */
624
625        AcpiCmReleaseMutex (ACPI_MTX_CACHES);
626
627        State = AcpiCmCallocate (sizeof (ACPI_GENERIC_STATE));
628    }
629
630    /* Initialize */
631
632    if (State)
633    {
634        /* Always zero out the object before init */
635
636        MEMSET (State, 0, sizeof (ACPI_GENERIC_STATE));
637
638        State->Common.DataType = ACPI_DESC_TYPE_STATE;
639    }
640
641    return (State);
642}
643
644
645/*******************************************************************************
646 *
647 * FUNCTION:    AcpiCmCreateUpdateState
648 *
649 * PARAMETERS:  Object              - Initial Object to be installed in the
650 *                                    state
651 *              Action              - Update action to be performed
652 *
653 * RETURN:      Status
654 *
655 * DESCRIPTION: Create an "Update State" - a flavor of the generic state used
656 *              to update reference counts and delete complex objects such
657 *              as packages.
658 *
659 ******************************************************************************/
660
661ACPI_GENERIC_STATE *
662AcpiCmCreateUpdateState (
663    ACPI_OPERAND_OBJECT     *Object,
664    UINT16                  Action)
665{
666    ACPI_GENERIC_STATE      *State;
667
668
669    FUNCTION_TRACE_PTR ("CmCreateUpdateState", Object);
670
671
672    /* Create the generic state object */
673
674    State = AcpiCmCreateGenericState ();
675    if (!State)
676    {
677        return (NULL);
678    }
679
680    /* Init fields specific to the update struct */
681
682    State->Update.Object = Object;
683    State->Update.Value  = Action;
684
685    return_PTR (State);
686}
687
688
689/*******************************************************************************
690 *
691 * FUNCTION:    AcpiCmCreatePkgState
692 *
693 * PARAMETERS:  Object              - Initial Object to be installed in the
694 *                                    state
695 *              Action              - Update action to be performed
696 *
697 * RETURN:      Status
698 *
699 * DESCRIPTION: Create an "Update State" - a flavor of the generic state used
700 *              to update reference counts and delete complex objects such
701 *              as packages.
702 *
703 ******************************************************************************/
704
705ACPI_GENERIC_STATE *
706AcpiCmCreatePkgState (
707    void                    *InternalObject,
708    void                    *ExternalObject,
709    UINT16                  Index)
710{
711    ACPI_GENERIC_STATE      *State;
712
713
714    FUNCTION_TRACE_PTR ("CmCreatePkgState", InternalObject);
715
716
717    /* Create the generic state object */
718
719    State = AcpiCmCreateGenericState ();
720    if (!State)
721    {
722        return (NULL);
723    }
724
725    /* Init fields specific to the update struct */
726
727    State->Pkg.SourceObject = (ACPI_OPERAND_OBJECT *) InternalObject;
728    State->Pkg.DestObject   = ExternalObject;
729    State->Pkg.Index        = Index;
730    State->Pkg.NumPackages  = 1;
731
732    return_PTR (State);
733}
734
735
736
737/*******************************************************************************
738 *
739 * FUNCTION:    AcpiCmCreateControlState
740 *
741 * PARAMETERS:  None
742 *
743 * RETURN:      Status
744 *
745 * DESCRIPTION: Create a "Control State" - a flavor of the generic state used
746 *              to support nested IF/WHILE constructs in the AML.
747 *
748 ******************************************************************************/
749
750ACPI_GENERIC_STATE *
751AcpiCmCreateControlState (
752    void)
753{
754    ACPI_GENERIC_STATE      *State;
755
756
757    FUNCTION_TRACE ("CmCreateControlState");
758
759    /* Create the generic state object */
760
761    State = AcpiCmCreateGenericState ();
762    if (!State)
763    {
764        return (NULL);
765    }
766
767
768    /* Init fields specific to the control struct */
769
770    State->Common.State = CONTROL_CONDITIONAL_EXECUTING;
771
772    return_PTR (State);
773}
774
775
776/*******************************************************************************
777 *
778 * FUNCTION:    AcpiCmDeleteGenericState
779 *
780 * PARAMETERS:  State               - The state object to be deleted
781 *
782 * RETURN:      Status
783 *
784 * DESCRIPTION: Put a state object back into the global state cache.  The object
785 *              is not actually freed at this time.
786 *
787 ******************************************************************************/
788
789void
790AcpiCmDeleteGenericState (
791    ACPI_GENERIC_STATE      *State)
792{
793    FUNCTION_TRACE ("CmDeleteGenericState");
794
795
796    /* If cache is full, just free this state object */
797
798    if (AcpiGbl_GenericStateCacheDepth >= MAX_STATE_CACHE_DEPTH)
799    {
800        AcpiCmFree (State);
801    }
802
803    /* Otherwise put this object back into the cache */
804
805    else
806    {
807        AcpiCmAcquireMutex (ACPI_MTX_CACHES);
808
809        /* Clear the state */
810
811        MEMSET (State, 0, sizeof (ACPI_GENERIC_STATE));
812        State->Common.DataType = ACPI_DESC_TYPE_STATE;
813
814        /* Put the object at the head of the global cache list */
815
816        State->Common.Next = AcpiGbl_GenericStateCache;
817        AcpiGbl_GenericStateCache = State;
818        AcpiGbl_GenericStateCacheDepth++;
819
820
821        AcpiCmReleaseMutex (ACPI_MTX_CACHES);
822    }
823    return_VOID;
824}
825
826
827/*******************************************************************************
828 *
829 * FUNCTION:    AcpiCmDeleteGenericStateCache
830 *
831 * PARAMETERS:  None
832 *
833 * RETURN:      Status
834 *
835 * DESCRIPTION: Purge the global state object cache.  Used during subsystem
836 *              termination.
837 *
838 ******************************************************************************/
839
840void
841AcpiCmDeleteGenericStateCache (
842    void)
843{
844    ACPI_GENERIC_STATE      *Next;
845
846
847    FUNCTION_TRACE ("CmDeleteGenericStateCache");
848
849
850    /* Traverse the global cache list */
851
852    while (AcpiGbl_GenericStateCache)
853    {
854        /* Delete one cached state object */
855
856        Next = AcpiGbl_GenericStateCache->Common.Next;
857        AcpiCmFree (AcpiGbl_GenericStateCache);
858        AcpiGbl_GenericStateCache = Next;
859        AcpiGbl_GenericStateCacheDepth--;
860    }
861
862    return_VOID;
863}
864
865
866/*******************************************************************************
867 *
868 * FUNCTION:    AcpiCmResolvePackageReferences
869 *
870 * PARAMETERS:  ObjDesc         - The Package object on which to resolve refs
871 *
872 * RETURN:      Status
873 *
874 * DESCRIPTION: Walk through a package and turn internal references into values
875 *
876 ******************************************************************************/
877
878ACPI_STATUS
879AcpiCmResolvePackageReferences (
880    ACPI_OPERAND_OBJECT     *ObjDesc)
881{
882    UINT32                  Count;
883    ACPI_OPERAND_OBJECT     *SubObject;
884
885
886    FUNCTION_TRACE ("AcpiCmResolvePackageReferences");
887
888
889    if (ObjDesc->Common.Type != ACPI_TYPE_PACKAGE)
890    {
891        /* The object must be a package */
892
893        REPORT_ERROR (("Must resolve Package Refs on a Package\n"));
894        return_ACPI_STATUS(AE_ERROR);
895    }
896
897    /*
898     * TBD: what about nested packages? */
899
900    for (Count = 0; Count < ObjDesc->Package.Count; Count++)
901    {
902        SubObject = ObjDesc->Package.Elements[Count];
903
904        if (SubObject->Common.Type == INTERNAL_TYPE_REFERENCE)
905        {
906            if (SubObject->Reference.OpCode == AML_ZERO_OP)
907            {
908                SubObject->Common.Type  = ACPI_TYPE_INTEGER;
909                SubObject->Integer.Value = 0;
910            }
911            else if (SubObject->Reference.OpCode == AML_ONE_OP)
912            {
913                SubObject->Common.Type  = ACPI_TYPE_INTEGER;
914                SubObject->Integer.Value = 1;
915            }
916            else if (SubObject->Reference.OpCode == AML_ONES_OP)
917            {
918                SubObject->Common.Type  = ACPI_TYPE_INTEGER;
919                SubObject->Integer.Value = ACPI_INTEGER_MAX;
920            }
921        }
922    }
923
924    return_ACPI_STATUS(AE_OK);
925}
926
927#ifdef ACPI_DEBUG
928
929/******************************************************************************
930 *
931 * FUNCTION:    AcpiCmDisplayInitPathname
932 *
933 * PARAMETERS:  ObjHandle           - Handle whose pathname will be displayed
934 *              Path                - Additional path string to be appended
935 *
936 * RETURN:      ACPI_STATUS
937 *
938 * DESCRIPTION: Display full pathnbame of an object, DEBUG ONLY
939 *
940 *****************************************************************************/
941
942void
943AcpiCmDisplayInitPathname (
944    ACPI_HANDLE             ObjHandle,
945    char                    *Path)
946{
947    ACPI_STATUS             Status;
948    UINT32                  Length = 128;
949    char                    Buffer[128];
950
951
952    Status = AcpiNsHandleToPathname (ObjHandle, &Length, Buffer);
953    if (ACPI_SUCCESS (Status))
954    {
955        if (Path)
956        {
957            DEBUG_PRINT (TRACE_INIT, ("%s.%s\n", Buffer, Path))
958        }
959        else
960        {
961            DEBUG_PRINT (TRACE_INIT, ("%s\n", Buffer))
962        }
963    }
964}
965#endif
966
967/*******************************************************************************
968 *
969 * FUNCTION:    AcpiCmWalkPackageTree
970 *
971 * PARAMETERS:  ObjDesc         - The Package object on which to resolve refs
972 *
973 * RETURN:      Status
974 *
975 * DESCRIPTION: Walk through a package
976 *
977 ******************************************************************************/
978
979ACPI_STATUS
980AcpiCmWalkPackageTree (
981    ACPI_OPERAND_OBJECT     *SourceObject,
982    void                    *TargetObject,
983    ACPI_PKG_CALLBACK       WalkCallback,
984    void                    *Context)
985{
986    ACPI_STATUS             Status = AE_OK;
987    ACPI_GENERIC_STATE      *StateList = NULL;
988    ACPI_GENERIC_STATE      *State;
989    UINT32                  ThisIndex;
990    ACPI_OPERAND_OBJECT     *ThisSourceObj;
991
992
993    FUNCTION_TRACE ("AcpiCmWalkPackageTree");
994
995
996    State = AcpiCmCreatePkgState (SourceObject, TargetObject, 0);
997    if (!State)
998    {
999        return_ACPI_STATUS (AE_NO_MEMORY);
1000    }
1001
1002    while (State)
1003    {
1004        ThisIndex        = State->Pkg.Index;
1005        ThisSourceObj    = (ACPI_OPERAND_OBJECT *)
1006                            State->Pkg.SourceObject->Package.Elements[ThisIndex];
1007
1008        /*
1009         * Check for
1010         * 1) An uninitialized package element.  It is completely
1011         *      legal to declare a package and leave it uninitialized
1012         * 2) Not an internal object - can be a namespace node instead
1013         * 3) Any type other than a package.  Packages are handled in else case below.
1014         */
1015        if ((!ThisSourceObj) ||
1016            (!VALID_DESCRIPTOR_TYPE (
1017                    ThisSourceObj, ACPI_DESC_TYPE_INTERNAL)) ||
1018            (!IS_THIS_OBJECT_TYPE (
1019                    ThisSourceObj, ACPI_TYPE_PACKAGE)))
1020        {
1021
1022            Status = WalkCallback (0, ThisSourceObj, State, Context);
1023            if (ACPI_FAILURE (Status))
1024            {
1025                /* TBD: must delete package created up to this point */
1026
1027                return_ACPI_STATUS (Status);
1028            }
1029
1030            State->Pkg.Index++;
1031            while (State->Pkg.Index >= State->Pkg.SourceObject->Package.Count)
1032            {
1033                /*
1034                 * We've handled all of the objects at this level,  This means
1035                 * that we have just completed a package.  That package may
1036                 * have contained one or more packages itself.
1037                 *
1038                 * Delete this state and pop the previous state (package).
1039                 */
1040                AcpiCmDeleteGenericState (State);
1041                State = AcpiCmPopGenericState (&StateList);
1042
1043
1044                /* Finished when there are no more states */
1045
1046                if (!State)
1047                {
1048                    /*
1049                     * We have handled all of the objects in the top level
1050                     * package just add the length of the package objects
1051                     * and exit
1052                     */
1053                    return_ACPI_STATUS (AE_OK);
1054                }
1055
1056                /*
1057                 * Go back up a level and move the index past the just
1058                 * completed package object.
1059                 */
1060                State->Pkg.Index++;
1061            }
1062        }
1063
1064        else
1065        {
1066            /* This is a sub-object of type package */
1067
1068            Status = WalkCallback (1, ThisSourceObj, State, Context);
1069            if (ACPI_FAILURE (Status))
1070            {
1071                /* TBD: must delete package created up to this point */
1072
1073                return_ACPI_STATUS (Status);
1074            }
1075
1076
1077            /*
1078             * The callback above returned a new target package object.
1079             */
1080
1081            /*
1082             * Push the current state and create a new one
1083             */
1084            AcpiCmPushGenericState (&StateList, State);
1085            State = AcpiCmCreatePkgState (ThisSourceObj, State->Pkg.ThisTargetObj, 0);
1086            if (!State)
1087            {
1088                /* TBD: must delete package created up to this point */
1089
1090                return_ACPI_STATUS (AE_NO_MEMORY);
1091            }
1092        }
1093    }
1094
1095    /* We should never get here */
1096
1097    return (AE_AML_INTERNAL);
1098
1099}
1100
1101
1102
1103/*******************************************************************************
1104 *
1105 * FUNCTION:    _ReportError
1106 *
1107 * PARAMETERS:  ModuleName          - Caller's module name (for error output)
1108 *              LineNumber          - Caller's line number (for error output)
1109 *              ComponentId         - Caller's component ID (for error output)
1110 *              Message             - Error message to use on failure
1111 *
1112 * RETURN:      None
1113 *
1114 * DESCRIPTION: Print error message
1115 *
1116 ******************************************************************************/
1117
1118void
1119_ReportError (
1120    NATIVE_CHAR             *ModuleName,
1121    UINT32                  LineNumber,
1122    UINT32                  ComponentId)
1123{
1124
1125
1126    AcpiOsPrintf ("%8s-%04d: *** Error: ", ModuleName, LineNumber);
1127}
1128
1129
1130/*******************************************************************************
1131 *
1132 * FUNCTION:    _ReportWarning
1133 *
1134 * PARAMETERS:  ModuleName          - Caller's module name (for error output)
1135 *              LineNumber          - Caller's line number (for error output)
1136 *              ComponentId         - Caller's component ID (for error output)
1137 *              Message             - Error message to use on failure
1138 *
1139 * RETURN:      None
1140 *
1141 * DESCRIPTION: Print warning message
1142 *
1143 ******************************************************************************/
1144
1145void
1146_ReportWarning (
1147    NATIVE_CHAR             *ModuleName,
1148    UINT32                  LineNumber,
1149    UINT32                  ComponentId)
1150{
1151
1152    AcpiOsPrintf ("%8s-%04d: *** Warning: ", ModuleName, LineNumber);
1153}
1154
1155
1156/*******************************************************************************
1157 *
1158 * FUNCTION:    _ReportInfo
1159 *
1160 * PARAMETERS:  ModuleName          - Caller's module name (for error output)
1161 *              LineNumber          - Caller's line number (for error output)
1162 *              ComponentId         - Caller's component ID (for error output)
1163 *              Message             - Error message to use on failure
1164 *
1165 * RETURN:      None
1166 *
1167 * DESCRIPTION: Print information message
1168 *
1169 ******************************************************************************/
1170
1171void
1172_ReportInfo (
1173    NATIVE_CHAR             *ModuleName,
1174    UINT32                  LineNumber,
1175    UINT32                  ComponentId)
1176{
1177
1178    AcpiOsPrintf ("%8s-%04d: *** Info: ", ModuleName, LineNumber);
1179}
1180
1181
1182