utmisc.c revision 281687
1/*******************************************************************************
2 *
3 * Module Name: utmisc - common utility procedures
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2015, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions, and the following disclaimer,
16 *    without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 *    substantially similar to the "NO WARRANTY" disclaimer below
19 *    ("Disclaimer") and any redistribution must be conditioned upon
20 *    including a substantially similar Disclaimer requirement for further
21 *    binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 *    of any contributors may be used to endorse or promote products derived
24 *    from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#include <contrib/dev/acpica/include/acpi.h>
45#include <contrib/dev/acpica/include/accommon.h>
46#include <contrib/dev/acpica/include/acnamesp.h>
47
48
49#define _COMPONENT          ACPI_UTILITIES
50        ACPI_MODULE_NAME    ("utmisc")
51
52
53/*******************************************************************************
54 *
55 * FUNCTION:    AcpiUtIsPciRootBridge
56 *
57 * PARAMETERS:  Id              - The HID/CID in string format
58 *
59 * RETURN:      TRUE if the Id is a match for a PCI/PCI-Express Root Bridge
60 *
61 * DESCRIPTION: Determine if the input ID is a PCI Root Bridge ID.
62 *
63 ******************************************************************************/
64
65BOOLEAN
66AcpiUtIsPciRootBridge (
67    char                    *Id)
68{
69
70    /*
71     * Check if this is a PCI root bridge.
72     * ACPI 3.0+: check for a PCI Express root also.
73     */
74    if (!(ACPI_STRCMP (Id,
75            PCI_ROOT_HID_STRING)) ||
76
77        !(ACPI_STRCMP (Id,
78            PCI_EXPRESS_ROOT_HID_STRING)))
79    {
80        return (TRUE);
81    }
82
83    return (FALSE);
84}
85
86
87#if (defined ACPI_ASL_COMPILER || defined ACPI_EXEC_APP)
88/*******************************************************************************
89 *
90 * FUNCTION:    AcpiUtIsAmlTable
91 *
92 * PARAMETERS:  Table               - An ACPI table
93 *
94 * RETURN:      TRUE if table contains executable AML; FALSE otherwise
95 *
96 * DESCRIPTION: Check ACPI Signature for a table that contains AML code.
97 *              Currently, these are DSDT,SSDT,PSDT. All other table types are
98 *              data tables that do not contain AML code.
99 *
100 ******************************************************************************/
101
102BOOLEAN
103AcpiUtIsAmlTable (
104    ACPI_TABLE_HEADER       *Table)
105{
106
107    /* These are the only tables that contain executable AML */
108
109    if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT) ||
110        ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_PSDT) ||
111        ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_SSDT))
112    {
113        return (TRUE);
114    }
115
116    return (FALSE);
117}
118#endif
119
120
121/*******************************************************************************
122 *
123 * FUNCTION:    AcpiUtDwordByteSwap
124 *
125 * PARAMETERS:  Value           - Value to be converted
126 *
127 * RETURN:      UINT32 integer with bytes swapped
128 *
129 * DESCRIPTION: Convert a 32-bit value to big-endian (swap the bytes)
130 *
131 ******************************************************************************/
132
133UINT32
134AcpiUtDwordByteSwap (
135    UINT32                  Value)
136{
137    union
138    {
139        UINT32              Value;
140        UINT8               Bytes[4];
141    } Out;
142    union
143    {
144        UINT32              Value;
145        UINT8               Bytes[4];
146    } In;
147
148
149    ACPI_FUNCTION_ENTRY ();
150
151
152    In.Value = Value;
153
154    Out.Bytes[0] = In.Bytes[3];
155    Out.Bytes[1] = In.Bytes[2];
156    Out.Bytes[2] = In.Bytes[1];
157    Out.Bytes[3] = In.Bytes[0];
158
159    return (Out.Value);
160}
161
162
163/*******************************************************************************
164 *
165 * FUNCTION:    AcpiUtSetIntegerWidth
166 *
167 * PARAMETERS:  Revision            From DSDT header
168 *
169 * RETURN:      None
170 *
171 * DESCRIPTION: Set the global integer bit width based upon the revision
172 *              of the DSDT. For Revision 1 and 0, Integers are 32 bits.
173 *              For Revision 2 and above, Integers are 64 bits. Yes, this
174 *              makes a difference.
175 *
176 ******************************************************************************/
177
178void
179AcpiUtSetIntegerWidth (
180    UINT8                   Revision)
181{
182
183    if (Revision < 2)
184    {
185        /* 32-bit case */
186
187        AcpiGbl_IntegerBitWidth    = 32;
188        AcpiGbl_IntegerNybbleWidth = 8;
189        AcpiGbl_IntegerByteWidth   = 4;
190    }
191    else
192    {
193        /* 64-bit case (ACPI 2.0+) */
194
195        AcpiGbl_IntegerBitWidth    = 64;
196        AcpiGbl_IntegerNybbleWidth = 16;
197        AcpiGbl_IntegerByteWidth   = 8;
198    }
199}
200
201
202/*******************************************************************************
203 *
204 * FUNCTION:    AcpiUtCreateUpdateStateAndPush
205 *
206 * PARAMETERS:  Object          - Object to be added to the new state
207 *              Action          - Increment/Decrement
208 *              StateList       - List the state will be added to
209 *
210 * RETURN:      Status
211 *
212 * DESCRIPTION: Create a new state and push it
213 *
214 ******************************************************************************/
215
216ACPI_STATUS
217AcpiUtCreateUpdateStateAndPush (
218    ACPI_OPERAND_OBJECT     *Object,
219    UINT16                  Action,
220    ACPI_GENERIC_STATE      **StateList)
221{
222    ACPI_GENERIC_STATE       *State;
223
224
225    ACPI_FUNCTION_ENTRY ();
226
227
228    /* Ignore null objects; these are expected */
229
230    if (!Object)
231    {
232        return (AE_OK);
233    }
234
235    State = AcpiUtCreateUpdateState (Object, Action);
236    if (!State)
237    {
238        return (AE_NO_MEMORY);
239    }
240
241    AcpiUtPushGenericState (StateList, State);
242    return (AE_OK);
243}
244
245
246/*******************************************************************************
247 *
248 * FUNCTION:    AcpiUtWalkPackageTree
249 *
250 * PARAMETERS:  SourceObject        - The package to walk
251 *              TargetObject        - Target object (if package is being copied)
252 *              WalkCallback        - Called once for each package element
253 *              Context             - Passed to the callback function
254 *
255 * RETURN:      Status
256 *
257 * DESCRIPTION: Walk through a package
258 *
259 ******************************************************************************/
260
261ACPI_STATUS
262AcpiUtWalkPackageTree (
263    ACPI_OPERAND_OBJECT     *SourceObject,
264    void                    *TargetObject,
265    ACPI_PKG_CALLBACK       WalkCallback,
266    void                    *Context)
267{
268    ACPI_STATUS             Status = AE_OK;
269    ACPI_GENERIC_STATE      *StateList = NULL;
270    ACPI_GENERIC_STATE      *State;
271    UINT32                  ThisIndex;
272    ACPI_OPERAND_OBJECT     *ThisSourceObj;
273
274
275    ACPI_FUNCTION_TRACE (UtWalkPackageTree);
276
277
278    State = AcpiUtCreatePkgState (SourceObject, TargetObject, 0);
279    if (!State)
280    {
281        return_ACPI_STATUS (AE_NO_MEMORY);
282    }
283
284    while (State)
285    {
286        /* Get one element of the package */
287
288        ThisIndex     = State->Pkg.Index;
289        ThisSourceObj = (ACPI_OPERAND_OBJECT *)
290                        State->Pkg.SourceObject->Package.Elements[ThisIndex];
291
292        /*
293         * Check for:
294         * 1) An uninitialized package element. It is completely
295         *    legal to declare a package and leave it uninitialized
296         * 2) Not an internal object - can be a namespace node instead
297         * 3) Any type other than a package. Packages are handled in else
298         *    case below.
299         */
300        if ((!ThisSourceObj) ||
301            (ACPI_GET_DESCRIPTOR_TYPE (ThisSourceObj) != ACPI_DESC_TYPE_OPERAND) ||
302            (ThisSourceObj->Common.Type != ACPI_TYPE_PACKAGE))
303        {
304            Status = WalkCallback (ACPI_COPY_TYPE_SIMPLE, ThisSourceObj,
305                                    State, Context);
306            if (ACPI_FAILURE (Status))
307            {
308                return_ACPI_STATUS (Status);
309            }
310
311            State->Pkg.Index++;
312            while (State->Pkg.Index >= State->Pkg.SourceObject->Package.Count)
313            {
314                /*
315                 * We've handled all of the objects at this level,  This means
316                 * that we have just completed a package. That package may
317                 * have contained one or more packages itself.
318                 *
319                 * Delete this state and pop the previous state (package).
320                 */
321                AcpiUtDeleteGenericState (State);
322                State = AcpiUtPopGenericState (&StateList);
323
324                /* Finished when there are no more states */
325
326                if (!State)
327                {
328                    /*
329                     * We have handled all of the objects in the top level
330                     * package just add the length of the package objects
331                     * and exit
332                     */
333                    return_ACPI_STATUS (AE_OK);
334                }
335
336                /*
337                 * Go back up a level and move the index past the just
338                 * completed package object.
339                 */
340                State->Pkg.Index++;
341            }
342        }
343        else
344        {
345            /* This is a subobject of type package */
346
347            Status = WalkCallback (ACPI_COPY_TYPE_PACKAGE, ThisSourceObj,
348                                        State, Context);
349            if (ACPI_FAILURE (Status))
350            {
351                return_ACPI_STATUS (Status);
352            }
353
354            /*
355             * Push the current state and create a new one
356             * The callback above returned a new target package object.
357             */
358            AcpiUtPushGenericState (&StateList, State);
359            State = AcpiUtCreatePkgState (ThisSourceObj,
360                                            State->Pkg.ThisTargetObj, 0);
361            if (!State)
362            {
363                /* Free any stacked Update State objects */
364
365                while (StateList)
366                {
367                    State = AcpiUtPopGenericState (&StateList);
368                    AcpiUtDeleteGenericState (State);
369                }
370                return_ACPI_STATUS (AE_NO_MEMORY);
371            }
372        }
373    }
374
375    /* We should never get here */
376
377    return_ACPI_STATUS (AE_AML_INTERNAL);
378}
379
380
381#ifdef ACPI_DEBUG_OUTPUT
382/*******************************************************************************
383 *
384 * FUNCTION:    AcpiUtDisplayInitPathname
385 *
386 * PARAMETERS:  Type                - Object type of the node
387 *              ObjHandle           - Handle whose pathname will be displayed
388 *              Path                - Additional path string to be appended.
389 *                                      (NULL if no extra path)
390 *
391 * RETURN:      ACPI_STATUS
392 *
393 * DESCRIPTION: Display full pathname of an object, DEBUG ONLY
394 *
395 ******************************************************************************/
396
397void
398AcpiUtDisplayInitPathname (
399    UINT8                   Type,
400    ACPI_NAMESPACE_NODE     *ObjHandle,
401    char                    *Path)
402{
403    ACPI_STATUS             Status;
404    ACPI_BUFFER             Buffer;
405
406
407    ACPI_FUNCTION_ENTRY ();
408
409
410    /* Only print the path if the appropriate debug level is enabled */
411
412    if (!(AcpiDbgLevel & ACPI_LV_INIT_NAMES))
413    {
414        return;
415    }
416
417    /* Get the full pathname to the node */
418
419    Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
420    Status = AcpiNsHandleToPathname (ObjHandle, &Buffer);
421    if (ACPI_FAILURE (Status))
422    {
423        return;
424    }
425
426    /* Print what we're doing */
427
428    switch (Type)
429    {
430    case ACPI_TYPE_METHOD:
431
432        AcpiOsPrintf ("Executing    ");
433        break;
434
435    default:
436
437        AcpiOsPrintf ("Initializing ");
438        break;
439    }
440
441    /* Print the object type and pathname */
442
443    AcpiOsPrintf ("%-12s  %s",
444        AcpiUtGetTypeName (Type), (char *) Buffer.Pointer);
445
446    /* Extra path is used to append names like _STA, _INI, etc. */
447
448    if (Path)
449    {
450        AcpiOsPrintf (".%s", Path);
451    }
452    AcpiOsPrintf ("\n");
453
454    ACPI_FREE (Buffer.Pointer);
455}
456#endif
457