Sync ACPICA with Intel's version 20140828.
[dragonfly.git] / sys / contrib / dev / acpica / source / components / utilities / utmisc.c
1 /*******************************************************************************
2  *
3  * Module Name: utmisc - common utility procedures
4  *
5  ******************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2014, 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 #define __UTMISC_C__
45
46 #include "acpi.h"
47 #include "accommon.h"
48 #include "acnamesp.h"
49
50
51 #define _COMPONENT          ACPI_UTILITIES
52         ACPI_MODULE_NAME    ("utmisc")
53
54
55 /*******************************************************************************
56  *
57  * FUNCTION:    AcpiUtIsPciRootBridge
58  *
59  * PARAMETERS:  Id              - The HID/CID in string format
60  *
61  * RETURN:      TRUE if the Id is a match for a PCI/PCI-Express Root Bridge
62  *
63  * DESCRIPTION: Determine if the input ID is a PCI Root Bridge ID.
64  *
65  ******************************************************************************/
66
67 BOOLEAN
68 AcpiUtIsPciRootBridge (
69     char                    *Id)
70 {
71
72     /*
73      * Check if this is a PCI root bridge.
74      * ACPI 3.0+: check for a PCI Express root also.
75      */
76     if (!(ACPI_STRCMP (Id,
77             PCI_ROOT_HID_STRING)) ||
78
79         !(ACPI_STRCMP (Id,
80             PCI_EXPRESS_ROOT_HID_STRING)))
81     {
82         return (TRUE);
83     }
84
85     return (FALSE);
86 }
87
88
89 /*******************************************************************************
90  *
91  * FUNCTION:    AcpiUtIsAmlTable
92  *
93  * PARAMETERS:  Table               - An ACPI table
94  *
95  * RETURN:      TRUE if table contains executable AML; FALSE otherwise
96  *
97  * DESCRIPTION: Check ACPI Signature for a table that contains AML code.
98  *              Currently, these are DSDT,SSDT,PSDT. All other table types are
99  *              data tables that do not contain AML code.
100  *
101  ******************************************************************************/
102
103 BOOLEAN
104 AcpiUtIsAmlTable (
105     ACPI_TABLE_HEADER       *Table)
106 {
107
108     /* These are the only tables that contain executable AML */
109
110     if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT) ||
111         ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_PSDT) ||
112         ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_SSDT))
113     {
114         return (TRUE);
115     }
116
117     return (FALSE);
118 }
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
133 UINT32
134 AcpiUtDwordByteSwap (
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
178 void
179 AcpiUtSetIntegerWidth (
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
216 ACPI_STATUS
217 AcpiUtCreateUpdateStateAndPush (
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
261 ACPI_STATUS
262 AcpiUtWalkPackageTree (
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
397 void
398 AcpiUtDisplayInitPathname (
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