exutils.c revision 80062
1104476Ssam
2104476Ssam/******************************************************************************
3104476Ssam *
4104476Ssam * Module Name: exutils - interpreter/scanner utilities
5104476Ssam *              $Revision: 80 $
6104476Ssam *
7104476Ssam *****************************************************************************/
8104476Ssam
9104476Ssam/******************************************************************************
10104476Ssam *
11104476Ssam * 1. Copyright Notice
12104476Ssam *
13104476Ssam * Some or all of this work - Copyright (c) 1999, 2000, 2001, Intel Corp.
14104476Ssam * All rights reserved.
15104476Ssam *
16104476Ssam * 2. License
17104476Ssam *
18104476Ssam * 2.1. This is your license from Intel Corp. under its intellectual property
19104476Ssam * rights.  You may have additional license terms from the party that provided
20104476Ssam * you this software, covering your right to use that party's intellectual
21104476Ssam * property rights.
22104476Ssam *
23104476Ssam * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
24104476Ssam * copy of the source code appearing in this file ("Covered Code") an
25104476Ssam * irrevocable, perpetual, worldwide license under Intel's copyrights in the
26104476Ssam * base code distributed originally by Intel ("Original Intel Code") to copy,
27104476Ssam * make derivatives, distribute, use and display any portion of the Covered
28104476Ssam * Code in any form, with the right to sublicense such rights; and
29104476Ssam *
30104476Ssam * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
31104476Ssam * license (with the right to sublicense), under only those claims of Intel
32104476Ssam * patents that are infringed by the Original Intel Code, to make, use, sell,
33104476Ssam * offer to sell, and import the Covered Code and derivative works thereof
34104476Ssam * solely to the minimum extent necessary to exercise the above copyright
35104476Ssam * license, and in no event shall the patent license extend to any additions
36104476Ssam * to or modifications of the Original Intel Code.  No other license or right
37104476Ssam * is granted directly or by implication, estoppel or otherwise;
38104476Ssam *
39104476Ssam * The above copyright and patent license is granted only if the following
40104476Ssam * conditions are met:
41104476Ssam *
42104476Ssam * 3. Conditions
43104476Ssam *
44104476Ssam * 3.1. Redistribution of Source with Rights to Further Distribute Source.
45104476Ssam * Redistribution of source code of any substantial portion of the Covered
46104476Ssam * Code or modification with rights to further distribute source must include
47104476Ssam * the above Copyright Notice, the above License, this list of Conditions,
48104476Ssam * and the following Disclaimer and Export Compliance provision.  In addition,
49104476Ssam * Licensee must cause all Covered Code to which Licensee contributes to
50104476Ssam * contain a file documenting the changes Licensee made to create that Covered
51104476Ssam * Code and the date of any change.  Licensee must include in that file the
52104476Ssam * documentation of any changes made by any predecessor Licensee.  Licensee
53104476Ssam * must include a prominent statement that the modification is derived,
54104476Ssam * directly or indirectly, from Original Intel Code.
55104476Ssam *
56104476Ssam * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
57104476Ssam * Redistribution of source code of any substantial portion of the Covered
58104476Ssam * Code or modification without rights to further distribute source must
59104476Ssam * include the following Disclaimer and Export Compliance provision in the
60104476Ssam * documentation and/or other materials provided with distribution.  In
61104476Ssam * addition, Licensee may not authorize further sublicense of source of any
62104476Ssam * portion of the Covered Code, and must include terms to the effect that the
63104476Ssam * license from Licensee to its licensee is limited to the intellectual
64104476Ssam * property embodied in the software Licensee provides to its licensee, and
65104476Ssam * not to intellectual property embodied in modifications its licensee may
66104476Ssam * make.
67104476Ssam *
68104476Ssam * 3.3. Redistribution of Executable. Redistribution in executable form of any
69104476Ssam * substantial portion of the Covered Code or modification must reproduce the
70104476Ssam * above Copyright Notice, and the following Disclaimer and Export Compliance
71104476Ssam * provision in the documentation and/or other materials provided with the
72104476Ssam * distribution.
73104476Ssam *
74104476Ssam * 3.4. Intel retains all right, title, and interest in and to the Original
75104476Ssam * Intel Code.
76104476Ssam *
77104476Ssam * 3.5. Neither the name Intel nor any other trademark owned or controlled by
78104476Ssam * Intel shall be used in advertising or otherwise to promote the sale, use or
79104476Ssam * other dealings in products derived from or relating to the Covered Code
80104476Ssam * without prior written authorization from Intel.
81104476Ssam *
82104476Ssam * 4. Disclaimer and Export Compliance
83104476Ssam *
84104476Ssam * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
85104476Ssam * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
86104476Ssam * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
87104476Ssam * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
88104476Ssam * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
89104476Ssam * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
90104476Ssam * PARTICULAR PURPOSE.
91104476Ssam *
92104476Ssam * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
93104476Ssam * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
94104476Ssam * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
95104476Ssam * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
96104476Ssam * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
97104476Ssam * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
98104476Ssam * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
99104476Ssam * LIMITED REMEDY.
100104476Ssam *
101104476Ssam * 4.3. Licensee shall not export, either directly or indirectly, any of this
102104476Ssam * software or system incorporating such software without first obtaining any
103104476Ssam * required license or other approval from the U. S. Department of Commerce or
104104476Ssam * any other agency or department of the United States Government.  In the
105104476Ssam * event Licensee exports any such software from the United States or
106104476Ssam * re-exports any such software from a foreign destination, Licensee shall
107104476Ssam * ensure that the distribution and export/re-export of the software is in
108104476Ssam * compliance with all laws, regulations, orders, or other restrictions of the
109104476Ssam * U.S. Export Administration Regulations. Licensee agrees that neither it nor
110104476Ssam * any of its subsidiaries will export/re-export any technical data, process,
111104476Ssam * software, or service, directly or indirectly, to any country for which the
112104476Ssam * United States government or any agency thereof requires an export license,
113104476Ssam * other governmental approval, or letter of assurance, without first obtaining
114104476Ssam * such license, approval or letter.
115104476Ssam *
116104476Ssam *****************************************************************************/
117104476Ssam
118104476Ssam#define __EXUTILS_C__
119104476Ssam
120104476Ssam#include "acpi.h"
121104476Ssam#include "acparser.h"
122104476Ssam#include "acinterp.h"
123104476Ssam#include "amlcode.h"
124104476Ssam#include "acnamesp.h"
125104476Ssam#include "acevents.h"
126104476Ssam
127104476Ssam#define _COMPONENT          ACPI_EXECUTER
128104476Ssam        MODULE_NAME         ("exutils")
129104476Ssam
130104476Ssam
131104476Ssam/*******************************************************************************
132104476Ssam *
133104476Ssam * FUNCTION:    AcpiExEnterInterpreter
134104476Ssam *
135104476Ssam * PARAMETERS:  None
136104476Ssam *
137109153Sdillon * DESCRIPTION: Enter the interpreter execution region
138104476Ssam *              TBD: should be a macro
139104476Ssam *
140104476Ssam ******************************************************************************/
141104476Ssam
142104476SsamACPI_STATUS
143104476SsamAcpiExEnterInterpreter (void)
144104476Ssam{
145104476Ssam    ACPI_STATUS             Status;
146104476Ssam
147104476Ssam    FUNCTION_TRACE ("ExEnterInterpreter");
148104476Ssam
149104476Ssam
150104476Ssam    Status = AcpiUtAcquireMutex (ACPI_MTX_EXECUTE);
151104476Ssam    return_ACPI_STATUS (Status);
152104476Ssam}
153104476Ssam
154104476Ssam
155104476Ssam/*******************************************************************************
156104476Ssam *
157104476Ssam * FUNCTION:    AcpiExExitInterpreter
158104476Ssam *
159104476Ssam * PARAMETERS:  None
160104476Ssam *
161104476Ssam * DESCRIPTION: Exit the interpreter execution region
162104476Ssam *
163104476Ssam * Cases where the interpreter is unlocked:
164104476Ssam *      1) Completion of the execution of a control method
165104476Ssam *      2) Method blocked on a Sleep() AML opcode
166104476Ssam *      3) Method blocked on an Acquire() AML opcode
167104476Ssam *      4) Method blocked on a Wait() AML opcode
168104476Ssam *      5) Method blocked to acquire the global lock
169104476Ssam *      6) Method blocked to execute a serialized control method that is
170104476Ssam *          already executing
171104476Ssam *      7) About to invoke a user-installed opregion handler
172104476Ssam *
173104476Ssam *              TBD: should be a macro
174104476Ssam *
175104476Ssam ******************************************************************************/
176104476Ssam
177104476Ssamvoid
178104476SsamAcpiExExitInterpreter (void)
179104476Ssam{
180104476Ssam    FUNCTION_TRACE ("ExExitInterpreter");
181104476Ssam
182104476Ssam
183104476Ssam    AcpiUtReleaseMutex (ACPI_MTX_EXECUTE);
184104476Ssam
185104476Ssam    return_VOID;
186104476Ssam}
187104476Ssam
188104476Ssam
189104476Ssam/*******************************************************************************
190104476Ssam *
191104476Ssam * FUNCTION:    AcpiExValidateObjectType
192104476Ssam *
193104476Ssam * PARAMETERS:  Type            Object type to validate
194104476Ssam *
195104476Ssam * DESCRIPTION: Determine if a type is a valid ACPI object type
196104476Ssam *
197104476Ssam ******************************************************************************/
198104476Ssam
199104476SsamBOOLEAN
200104476SsamAcpiExValidateObjectType (
201104476Ssam    ACPI_OBJECT_TYPE        Type)
202104476Ssam{
203104476Ssam
204104476Ssam    if ((Type > ACPI_TYPE_MAX && Type < INTERNAL_TYPE_BEGIN) ||
205104476Ssam        (Type > INTERNAL_TYPE_MAX))
206104476Ssam    {
207104476Ssam        return (FALSE);
208104476Ssam    }
209104476Ssam
210104476Ssam    return (TRUE);
211104476Ssam}
212104476Ssam
213104476Ssam
214104476Ssam/*******************************************************************************
215104476Ssam *
216104476Ssam * FUNCTION:    AcpiExTruncateFor32bitTable
217104476Ssam *
218104476Ssam * PARAMETERS:  ObjDesc         - Object to be truncated
219104476Ssam *              WalkState       - Current walk state
220104476Ssam *                                (A method must be executing)
221104476Ssam *
222104476Ssam * RETURN:      none
223104476Ssam *
224104476Ssam * DESCRIPTION: Truncate a number to 32-bits if the currently executing method
225104476Ssam *              belongs to a 32-bit ACPI table.
226104476Ssam *
227104476Ssam ******************************************************************************/
228104476Ssam
229104476Ssamvoid
230104476SsamAcpiExTruncateFor32bitTable (
231111119Simp    ACPI_OPERAND_OBJECT     *ObjDesc,
232104476Ssam    ACPI_WALK_STATE         *WalkState)
233104476Ssam{
234104476Ssam
235104476Ssam    /*
236104476Ssam     * Object must be a valid number and we must be executing
237104476Ssam     * a control method
238104476Ssam     */
239104476Ssam
240104476Ssam    if ((!ObjDesc) ||
241104476Ssam        (ObjDesc->Common.Type != ACPI_TYPE_INTEGER) ||
242104476Ssam        (!WalkState->MethodNode))
243104476Ssam    {
244104476Ssam        return;
245104476Ssam    }
246104476Ssam
247104476Ssam    if (WalkState->MethodNode->Flags & ANOBJ_DATA_WIDTH_32)
248104476Ssam    {
249111119Simp        /*
250104476Ssam         * We are running a method that exists in a 32-bit ACPI table.
251104476Ssam         * Truncate the value to 32 bits by zeroing out the upper 32-bit field
252104476Ssam         */
253104476Ssam        ObjDesc->Integer.Value &= (ACPI_INTEGER) ACPI_UINT32_MAX;
254104476Ssam    }
255104476Ssam}
256104627Ssam
257104476Ssam
258104476Ssam/*******************************************************************************
259104476Ssam *
260104476Ssam * FUNCTION:    AcpiExAcquireGlobalLock
261104476Ssam *
262104476Ssam * PARAMETERS:  Rule            - Lock rule: AlwaysLock, NeverLock
263104476Ssam *
264104476Ssam * RETURN:      TRUE/FALSE indicating whether the lock was actually acquired
265104476Ssam *
266104476Ssam * DESCRIPTION: Obtain the global lock and keep track of this fact via two
267104476Ssam *              methods.  A global variable keeps the state of the lock, and
268104476Ssam *              the state is returned to the caller.
269104476Ssam *
270104476Ssam ******************************************************************************/
271104476Ssam
272104476SsamBOOLEAN
273104476SsamAcpiExAcquireGlobalLock (
274104476Ssam    UINT32                  Rule)
275104476Ssam{
276104476Ssam    BOOLEAN                 Locked = FALSE;
277104476Ssam    ACPI_STATUS             Status;
278104476Ssam
279104476Ssam
280104476Ssam    FUNCTION_TRACE ("ExAcquireGlobalLock");
281104476Ssam
282104476Ssam
283104476Ssam    /* Only attempt lock if the Rule says so */
284104476Ssam
285104476Ssam    if (Rule == (UINT32) GLOCK_ALWAYS_LOCK)
286104476Ssam    {
287104476Ssam        /* We should attempt to get the lock */
288104476Ssam
289104476Ssam        Status = AcpiEvAcquireGlobalLock ();
290104476Ssam        if (ACPI_SUCCESS (Status))
291104476Ssam        {
292104476Ssam            Locked = TRUE;
293104476Ssam        }
294104476Ssam
295104476Ssam        else
296104476Ssam        {
297104476Ssam            DEBUG_PRINTP (ACPI_ERROR, ("Could not acquire Global Lock, %s\n",
298104476Ssam                AcpiFormatException (Status)));
299104476Ssam        }
300104476Ssam    }
301104476Ssam
302104476Ssam    return_VALUE (Locked);
303104476Ssam}
304104476Ssam
305104476Ssam
306104476Ssam/*******************************************************************************
307104476Ssam *
308104476Ssam * FUNCTION:    AcpiExReleaseGlobalLock
309104476Ssam *
310104476Ssam * PARAMETERS:  LockedByMe      - Return value from corresponding call to
311104476Ssam *                                AcquireGlobalLock.
312104476Ssam *
313104476Ssam * RETURN:      Status
314104476Ssam *
315104476Ssam * DESCRIPTION: Release the global lock if it is locked.
316104476Ssam *
317104476Ssam ******************************************************************************/
318104476Ssam
319104476SsamACPI_STATUS
320104476SsamAcpiExReleaseGlobalLock (
321104476Ssam    BOOLEAN                 LockedByMe)
322104476Ssam{
323104476Ssam
324104476Ssam    FUNCTION_TRACE ("ExReleaseGlobalLock");
325104476Ssam
326104476Ssam
327104476Ssam    /* Only attempt unlock if the caller locked it */
328104476Ssam
329104476Ssam    if (LockedByMe)
330104476Ssam    {
331104476Ssam        /* OK, now release the lock */
332104476Ssam
333104476Ssam        AcpiEvReleaseGlobalLock ();
334104476Ssam    }
335111119Simp
336104476Ssam
337104476Ssam    return_ACPI_STATUS (AE_OK);
338104476Ssam}
339104476Ssam
340104476Ssam
341104476Ssam/*******************************************************************************
342104476Ssam *
343104476Ssam * FUNCTION:    AcpiExDigitsNeeded
344104476Ssam *
345104476Ssam * PARAMETERS:  val             - Value to be represented
346104476Ssam *              base            - Base of representation
347104476Ssam *
348104476Ssam * RETURN:      the number of digits needed to represent val in base
349104476Ssam *
350104476Ssam ******************************************************************************/
351104476Ssam
352104476SsamUINT32
353104476SsamAcpiExDigitsNeeded (
354104476Ssam    ACPI_INTEGER            val,
355104476Ssam    UINT32                  base)
356104476Ssam{
357104476Ssam    UINT32                  NumDigits = 0;
358104476Ssam
359104476Ssam
360104476Ssam    FUNCTION_TRACE ("ExDigitsNeeded");
361104476Ssam
362104476Ssam
363104476Ssam    if (base < 1)
364104476Ssam    {
365104476Ssam        REPORT_ERROR (("ExDigitsNeeded: Internal error - Invalid base\n"));
366104476Ssam    }
367104476Ssam
368104476Ssam    else
369104476Ssam    {
370104476Ssam        /*
371104476Ssam         * ACPI_INTEGER is unsigned, which is why we don't worry about the '-'
372104476Ssam         */
373104476Ssam        for (NumDigits = 1; (val = ACPI_DIVIDE (val,base)); ++NumDigits)
374104476Ssam        { ; }
375104476Ssam    }
376104476Ssam
377104476Ssam    return_VALUE (NumDigits);
378104476Ssam}
379104476Ssam
380104476Ssam
381104476Ssam/*******************************************************************************
382104476Ssam *
383104476Ssam * FUNCTION:    ntohl
384104476Ssam *
385111297Ssam * PARAMETERS:  Value           - Value to be converted
386111297Ssam *
387104476Ssam * DESCRIPTION: Convert a 32-bit value to big-endian (swap the bytes)
388104476Ssam *
389104476Ssam ******************************************************************************/
390104476Ssam
391104476Ssamstatic UINT32
392104476Ssam_ntohl (
393104476Ssam    UINT32                  Value)
394104476Ssam{
395104476Ssam    union
396104476Ssam    {
397104476Ssam        UINT32              Value;
398104476Ssam        UINT8               Bytes[4];
399104476Ssam    } Out;
400104476Ssam
401104476Ssam    union
402104476Ssam    {
403104476Ssam        UINT32              Value;
404104476Ssam        UINT8               Bytes[4];
405104476Ssam    } In;
406104476Ssam
407104476Ssam
408104476Ssam    In.Value = Value;
409104476Ssam
410104476Ssam    Out.Bytes[0] = In.Bytes[3];
411104476Ssam    Out.Bytes[1] = In.Bytes[2];
412104476Ssam    Out.Bytes[2] = In.Bytes[1];
413104476Ssam    Out.Bytes[3] = In.Bytes[0];
414104476Ssam
415104476Ssam    return (Out.Value);
416104476Ssam}
417104476Ssam
418104476Ssam
419104476Ssam/*******************************************************************************
420104476Ssam *
421104476Ssam * FUNCTION:    AcpiExEisaIdToString
422104476Ssam *
423104476Ssam * PARAMETERS:  NumericId       - EISA ID to be converted
424104476Ssam *              OutString       - Where to put the converted string (8 bytes)
425104476Ssam *
426104476Ssam * DESCRIPTION: Convert a numeric EISA ID to string representation
427104476Ssam *
428104476Ssam ******************************************************************************/
429104476Ssam
430104476SsamACPI_STATUS
431104476SsamAcpiExEisaIdToString (
432104476Ssam    UINT32                  NumericId,
433104476Ssam    NATIVE_CHAR             *OutString)
434104476Ssam{
435104476Ssam    UINT32                  id;
436104476Ssam
437104476Ssam    /* swap to big-endian to get contiguous bits */
438104476Ssam
439104476Ssam    id = _ntohl (NumericId);
440104476Ssam
441104476Ssam    OutString[0] = (char) ('@' + ((id >> 26) & 0x1f));
442104476Ssam    OutString[1] = (char) ('@' + ((id >> 21) & 0x1f));
443104476Ssam    OutString[2] = (char) ('@' + ((id >> 16) & 0x1f));
444104476Ssam    OutString[3] = AcpiGbl_HexToAscii[(id >> 12) & 0xf];
445104476Ssam    OutString[4] = AcpiGbl_HexToAscii[(id >> 8) & 0xf];
446104476Ssam    OutString[5] = AcpiGbl_HexToAscii[(id >> 4) & 0xf];
447104476Ssam    OutString[6] = AcpiGbl_HexToAscii[id & 0xf];
448104476Ssam    OutString[7] = 0;
449104476Ssam
450104476Ssam    return (AE_OK);
451104476Ssam}
452104476Ssam
453104476Ssam
454104476Ssam/*******************************************************************************
455104476Ssam *
456104476Ssam * FUNCTION:    AcpiExUnsignedIntegerToString
457104476Ssam *
458104476Ssam * PARAMETERS:  Value           - Value to be converted
459104476Ssam *              OutString       - Where to put the converted string (8 bytes)
460104476Ssam *
461104476Ssam * RETURN:      Convert a number to string representation
462104476Ssam *
463104476Ssam ******************************************************************************/
464104476Ssam
465104476SsamACPI_STATUS
466104476SsamAcpiExUnsignedIntegerToString (
467104476Ssam    ACPI_INTEGER            Value,
468104476Ssam    NATIVE_CHAR             *OutString)
469104476Ssam{
470104476Ssam    UINT32                  Count;
471104476Ssam    UINT32                  DigitsNeeded;
472104476Ssam
473104476Ssam
474104476Ssam    DigitsNeeded = AcpiExDigitsNeeded (Value, 10);
475104476Ssam
476104476Ssam    OutString[DigitsNeeded] = '\0';
477104476Ssam
478104476Ssam    for (Count = DigitsNeeded; Count > 0; Count--)
479104476Ssam    {
480104476Ssam        OutString[Count-1] = (NATIVE_CHAR) ('0' + (ACPI_MODULO (Value, 10)));
481104476Ssam        Value = ACPI_DIVIDE (Value, 10);
482104476Ssam    }
483104476Ssam
484104476Ssam    return (AE_OK);
485104476Ssam}
486104476Ssam
487104476Ssam
488104476Ssam