Sync ACPICA with Intel's version 20150619.
[dragonfly.git] / sys / contrib / dev / acpica / source / components / namespace / nsinit.c
1 /******************************************************************************
2  *
3  * Module Name: nsinit - namespace initialization
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 "acpi.h"
45 #include "accommon.h"
46 #include "acnamesp.h"
47 #include "acdispat.h"
48 #include "acinterp.h"
49
50 #define _COMPONENT          ACPI_NAMESPACE
51         ACPI_MODULE_NAME    ("nsinit")
52
53 /* Local prototypes */
54
55 static ACPI_STATUS
56 AcpiNsInitOneObject (
57     ACPI_HANDLE             ObjHandle,
58     UINT32                  Level,
59     void                    *Context,
60     void                    **ReturnValue);
61
62 static ACPI_STATUS
63 AcpiNsInitOneDevice (
64     ACPI_HANDLE             ObjHandle,
65     UINT32                  NestingLevel,
66     void                    *Context,
67     void                    **ReturnValue);
68
69 static ACPI_STATUS
70 AcpiNsFindIniMethods (
71     ACPI_HANDLE             ObjHandle,
72     UINT32                  NestingLevel,
73     void                    *Context,
74     void                    **ReturnValue);
75
76
77 /*******************************************************************************
78  *
79  * FUNCTION:    AcpiNsInitializeObjects
80  *
81  * PARAMETERS:  None
82  *
83  * RETURN:      Status
84  *
85  * DESCRIPTION: Walk the entire namespace and perform any necessary
86  *              initialization on the objects found therein
87  *
88  ******************************************************************************/
89
90 ACPI_STATUS
91 AcpiNsInitializeObjects (
92     void)
93 {
94     ACPI_STATUS             Status;
95     ACPI_INIT_WALK_INFO     Info;
96
97
98     ACPI_FUNCTION_TRACE (NsInitializeObjects);
99
100
101     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
102         "**** Starting initialization of namespace objects ****\n"));
103     ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
104         "Completing Region/Field/Buffer/Package initialization:\n"));
105
106     /* Set all init info to zero */
107
108     memset (&Info, 0, sizeof (ACPI_INIT_WALK_INFO));
109
110     /* Walk entire namespace from the supplied root */
111
112     Status = AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
113                 ACPI_UINT32_MAX, AcpiNsInitOneObject, NULL,
114                 &Info, NULL);
115     if (ACPI_FAILURE (Status))
116     {
117         ACPI_EXCEPTION ((AE_INFO, Status, "During WalkNamespace"));
118     }
119
120     ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
121         "    Initialized %u/%u Regions %u/%u Fields %u/%u "
122         "Buffers %u/%u Packages (%u nodes)\n",
123         Info.OpRegionInit,  Info.OpRegionCount,
124         Info.FieldInit,     Info.FieldCount,
125         Info.BufferInit,    Info.BufferCount,
126         Info.PackageInit,   Info.PackageCount, Info.ObjectCount));
127
128     ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
129         "%u Control Methods found\n%u Op Regions found\n",
130         Info.MethodCount, Info.OpRegionCount));
131
132     return_ACPI_STATUS (AE_OK);
133 }
134
135
136 /*******************************************************************************
137  *
138  * FUNCTION:    AcpiNsInitializeDevices
139  *
140  * PARAMETERS:  None
141  *
142  * RETURN:      ACPI_STATUS
143  *
144  * DESCRIPTION: Walk the entire namespace and initialize all ACPI devices.
145  *              This means running _INI on all present devices.
146  *
147  *              Note: We install PCI config space handler on region access,
148  *              not here.
149  *
150  ******************************************************************************/
151
152 ACPI_STATUS
153 AcpiNsInitializeDevices (
154     void)
155 {
156     ACPI_STATUS             Status;
157     ACPI_DEVICE_WALK_INFO   Info;
158
159
160     ACPI_FUNCTION_TRACE (NsInitializeDevices);
161
162
163     /* Init counters */
164
165     Info.DeviceCount = 0;
166     Info.Num_STA = 0;
167     Info.Num_INI = 0;
168
169     ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
170         "Initializing Device/Processor/Thermal objects "
171         "and executing _INI/_STA methods:\n"));
172
173     /* Tree analysis: find all subtrees that contain _INI methods */
174
175     Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
176                 ACPI_UINT32_MAX, FALSE, AcpiNsFindIniMethods, NULL, &Info, NULL);
177     if (ACPI_FAILURE (Status))
178     {
179         goto ErrorExit;
180     }
181
182     /* Allocate the evaluation information block */
183
184     Info.EvaluateInfo = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
185     if (!Info.EvaluateInfo)
186     {
187         Status = AE_NO_MEMORY;
188         goto ErrorExit;
189     }
190
191     /*
192      * Execute the "global" _INI method that may appear at the root. This
193      * support is provided for Windows compatibility (Vista+) and is not
194      * part of the ACPI specification.
195      */
196     Info.EvaluateInfo->PrefixNode = AcpiGbl_RootNode;
197     Info.EvaluateInfo->RelativePathname = METHOD_NAME__INI;
198     Info.EvaluateInfo->Parameters = NULL;
199     Info.EvaluateInfo->Flags = ACPI_IGNORE_RETURN_VALUE;
200
201     Status = AcpiNsEvaluate (Info.EvaluateInfo);
202     if (ACPI_SUCCESS (Status))
203     {
204         Info.Num_INI++;
205     }
206
207     /* Walk namespace to execute all _INIs on present devices */
208
209     Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
210                 ACPI_UINT32_MAX, FALSE, AcpiNsInitOneDevice, NULL, &Info, NULL);
211
212     /*
213      * Any _OSI requests should be completed by now. If the BIOS has
214      * requested any Windows OSI strings, we will always truncate
215      * I/O addresses to 16 bits -- for Windows compatibility.
216      */
217     if (AcpiGbl_OsiData >= ACPI_OSI_WIN_2000)
218     {
219         AcpiGbl_TruncateIoAddresses = TRUE;
220     }
221
222     ACPI_FREE (Info.EvaluateInfo);
223     if (ACPI_FAILURE (Status))
224     {
225         goto ErrorExit;
226     }
227
228     ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
229         "    Executed %u _INI methods requiring %u _STA executions "
230         "(examined %u objects)\n",
231         Info.Num_INI, Info.Num_STA, Info.DeviceCount));
232
233     return_ACPI_STATUS (Status);
234
235
236 ErrorExit:
237     ACPI_EXCEPTION ((AE_INFO, Status, "During device initialization"));
238     return_ACPI_STATUS (Status);
239 }
240
241
242 /*******************************************************************************
243  *
244  * FUNCTION:    AcpiNsInitOneObject
245  *
246  * PARAMETERS:  ObjHandle       - Node
247  *              Level           - Current nesting level
248  *              Context         - Points to a init info struct
249  *              ReturnValue     - Not used
250  *
251  * RETURN:      Status
252  *
253  * DESCRIPTION: Callback from AcpiWalkNamespace. Invoked for every object
254  *              within the  namespace.
255  *
256  *              Currently, the only objects that require initialization are:
257  *              1) Methods
258  *              2) Op Regions
259  *
260  ******************************************************************************/
261
262 static ACPI_STATUS
263 AcpiNsInitOneObject (
264     ACPI_HANDLE             ObjHandle,
265     UINT32                  Level,
266     void                    *Context,
267     void                    **ReturnValue)
268 {
269     ACPI_OBJECT_TYPE        Type;
270     ACPI_STATUS             Status = AE_OK;
271     ACPI_INIT_WALK_INFO     *Info = (ACPI_INIT_WALK_INFO *) Context;
272     ACPI_NAMESPACE_NODE     *Node = (ACPI_NAMESPACE_NODE *) ObjHandle;
273     ACPI_OPERAND_OBJECT     *ObjDesc;
274
275
276     ACPI_FUNCTION_NAME (NsInitOneObject);
277
278
279     Info->ObjectCount++;
280
281     /* And even then, we are only interested in a few object types */
282
283     Type = AcpiNsGetType (ObjHandle);
284     ObjDesc = AcpiNsGetAttachedObject (Node);
285     if (!ObjDesc)
286     {
287         return (AE_OK);
288     }
289
290     /* Increment counters for object types we are looking for */
291
292     switch (Type)
293     {
294     case ACPI_TYPE_REGION:
295
296         Info->OpRegionCount++;
297         break;
298
299     case ACPI_TYPE_BUFFER_FIELD:
300
301         Info->FieldCount++;
302         break;
303
304     case ACPI_TYPE_LOCAL_BANK_FIELD:
305
306         Info->FieldCount++;
307         break;
308
309     case ACPI_TYPE_BUFFER:
310
311         Info->BufferCount++;
312         break;
313
314     case ACPI_TYPE_PACKAGE:
315
316         Info->PackageCount++;
317         break;
318
319     default:
320
321         /* No init required, just exit now */
322
323         return (AE_OK);
324     }
325
326     /* If the object is already initialized, nothing else to do */
327
328     if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID)
329     {
330         return (AE_OK);
331     }
332
333     /* Must lock the interpreter before executing AML code */
334
335     AcpiExEnterInterpreter ();
336
337     /*
338      * Each of these types can contain executable AML code within the
339      * declaration.
340      */
341     switch (Type)
342     {
343     case ACPI_TYPE_REGION:
344
345         Info->OpRegionInit++;
346         Status = AcpiDsGetRegionArguments (ObjDesc);
347         break;
348
349     case ACPI_TYPE_BUFFER_FIELD:
350
351         Info->FieldInit++;
352         Status = AcpiDsGetBufferFieldArguments (ObjDesc);
353         break;
354
355     case ACPI_TYPE_LOCAL_BANK_FIELD:
356
357         Info->FieldInit++;
358         Status = AcpiDsGetBankFieldArguments (ObjDesc);
359         break;
360
361     case ACPI_TYPE_BUFFER:
362
363         Info->BufferInit++;
364         Status = AcpiDsGetBufferArguments (ObjDesc);
365         break;
366
367     case ACPI_TYPE_PACKAGE:
368
369         Info->PackageInit++;
370         Status = AcpiDsGetPackageArguments (ObjDesc);
371         break;
372
373     default:
374
375         /* No other types can get here */
376
377         break;
378     }
379
380     if (ACPI_FAILURE (Status))
381     {
382         ACPI_EXCEPTION ((AE_INFO, Status,
383             "Could not execute arguments for [%4.4s] (%s)",
384             AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Type)));
385     }
386
387     /*
388      * We ignore errors from above, and always return OK, since we don't want
389      * to abort the walk on any single error.
390      */
391     AcpiExExitInterpreter ();
392     return (AE_OK);
393 }
394
395
396 /*******************************************************************************
397  *
398  * FUNCTION:    AcpiNsFindIniMethods
399  *
400  * PARAMETERS:  ACPI_WALK_CALLBACK
401  *
402  * RETURN:      ACPI_STATUS
403  *
404  * DESCRIPTION: Called during namespace walk. Finds objects named _INI under
405  *              device/processor/thermal objects, and marks the entire subtree
406  *              with a SUBTREE_HAS_INI flag. This flag is used during the
407  *              subsequent device initialization walk to avoid entire subtrees
408  *              that do not contain an _INI.
409  *
410  ******************************************************************************/
411
412 static ACPI_STATUS
413 AcpiNsFindIniMethods (
414     ACPI_HANDLE             ObjHandle,
415     UINT32                  NestingLevel,
416     void                    *Context,
417     void                    **ReturnValue)
418 {
419     ACPI_DEVICE_WALK_INFO   *Info = ACPI_CAST_PTR (ACPI_DEVICE_WALK_INFO, Context);
420     ACPI_NAMESPACE_NODE     *Node;
421     ACPI_NAMESPACE_NODE     *ParentNode;
422
423
424     /* Keep count of device/processor/thermal objects */
425
426     Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
427     if ((Node->Type == ACPI_TYPE_DEVICE)    ||
428         (Node->Type == ACPI_TYPE_PROCESSOR) ||
429         (Node->Type == ACPI_TYPE_THERMAL))
430     {
431         Info->DeviceCount++;
432         return (AE_OK);
433     }
434
435     /* We are only looking for methods named _INI */
436
437     if (!ACPI_COMPARE_NAME (Node->Name.Ascii, METHOD_NAME__INI))
438     {
439         return (AE_OK);
440     }
441
442     /*
443      * The only _INI methods that we care about are those that are
444      * present under Device, Processor, and Thermal objects.
445      */
446     ParentNode = Node->Parent;
447     switch (ParentNode->Type)
448     {
449     case ACPI_TYPE_DEVICE:
450     case ACPI_TYPE_PROCESSOR:
451     case ACPI_TYPE_THERMAL:
452
453         /* Mark parent and bubble up the INI present flag to the root */
454
455         while (ParentNode)
456         {
457             ParentNode->Flags |= ANOBJ_SUBTREE_HAS_INI;
458             ParentNode = ParentNode->Parent;
459         }
460         break;
461
462     default:
463
464         break;
465     }
466
467     return (AE_OK);
468 }
469
470
471 /*******************************************************************************
472  *
473  * FUNCTION:    AcpiNsInitOneDevice
474  *
475  * PARAMETERS:  ACPI_WALK_CALLBACK
476  *
477  * RETURN:      ACPI_STATUS
478  *
479  * DESCRIPTION: This is called once per device soon after ACPI is enabled
480  *              to initialize each device. It determines if the device is
481  *              present, and if so, calls _INI.
482  *
483  ******************************************************************************/
484
485 static ACPI_STATUS
486 AcpiNsInitOneDevice (
487     ACPI_HANDLE             ObjHandle,
488     UINT32                  NestingLevel,
489     void                    *Context,
490     void                    **ReturnValue)
491 {
492     ACPI_DEVICE_WALK_INFO   *WalkInfo = ACPI_CAST_PTR (ACPI_DEVICE_WALK_INFO, Context);
493     ACPI_EVALUATE_INFO      *Info = WalkInfo->EvaluateInfo;
494     UINT32                  Flags;
495     ACPI_STATUS             Status;
496     ACPI_NAMESPACE_NODE     *DeviceNode;
497
498
499     ACPI_FUNCTION_TRACE (NsInitOneDevice);
500
501
502     /* We are interested in Devices, Processors and ThermalZones only */
503
504     DeviceNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
505     if ((DeviceNode->Type != ACPI_TYPE_DEVICE)    &&
506         (DeviceNode->Type != ACPI_TYPE_PROCESSOR) &&
507         (DeviceNode->Type != ACPI_TYPE_THERMAL))
508     {
509         return_ACPI_STATUS (AE_OK);
510     }
511
512     /*
513      * Because of an earlier namespace analysis, all subtrees that contain an
514      * _INI method are tagged.
515      *
516      * If this device subtree does not contain any _INI methods, we
517      * can exit now and stop traversing this entire subtree.
518      */
519     if (!(DeviceNode->Flags & ANOBJ_SUBTREE_HAS_INI))
520     {
521         return_ACPI_STATUS (AE_CTRL_DEPTH);
522     }
523
524     /*
525      * Run _STA to determine if this device is present and functioning. We
526      * must know this information for two important reasons (from ACPI spec):
527      *
528      * 1) We can only run _INI if the device is present.
529      * 2) We must abort the device tree walk on this subtree if the device is
530      *    not present and is not functional (we will not examine the children)
531      *
532      * The _STA method is not required to be present under the device, we
533      * assume the device is present if _STA does not exist.
534      */
535     ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (
536         ACPI_TYPE_METHOD, DeviceNode, METHOD_NAME__STA));
537
538     Status = AcpiUtExecute_STA (DeviceNode, &Flags);
539     if (ACPI_FAILURE (Status))
540     {
541         /* Ignore error and move on to next device */
542
543         return_ACPI_STATUS (AE_OK);
544     }
545
546     /*
547      * Flags == -1 means that _STA was not found. In this case, we assume that
548      * the device is both present and functional.
549      *
550      * From the ACPI spec, description of _STA:
551      *
552      * "If a device object (including the processor object) does not have an
553      * _STA object, then OSPM assumes that all of the above bits are set (in
554      * other words, the device is present, ..., and functioning)"
555      */
556     if (Flags != ACPI_UINT32_MAX)
557     {
558         WalkInfo->Num_STA++;
559     }
560
561     /*
562      * Examine the PRESENT and FUNCTIONING status bits
563      *
564      * Note: ACPI spec does not seem to specify behavior for the present but
565      * not functioning case, so we assume functioning if present.
566      */
567     if (!(Flags & ACPI_STA_DEVICE_PRESENT))
568     {
569         /* Device is not present, we must examine the Functioning bit */
570
571         if (Flags & ACPI_STA_DEVICE_FUNCTIONING)
572         {
573             /*
574              * Device is not present but is "functioning". In this case,
575              * we will not run _INI, but we continue to examine the children
576              * of this device.
577              *
578              * From the ACPI spec, description of _STA: (Note - no mention
579              * of whether to run _INI or not on the device in question)
580              *
581              * "_STA may return bit 0 clear (not present) with bit 3 set
582              * (device is functional). This case is used to indicate a valid
583              * device for which no device driver should be loaded (for example,
584              * a bridge device.) Children of this device may be present and
585              * valid. OSPM should continue enumeration below a device whose
586              * _STA returns this bit combination"
587              */
588             return_ACPI_STATUS (AE_OK);
589         }
590         else
591         {
592             /*
593              * Device is not present and is not functioning. We must abort the
594              * walk of this subtree immediately -- don't look at the children
595              * of such a device.
596              *
597              * From the ACPI spec, description of _INI:
598              *
599              * "If the _STA method indicates that the device is not present,
600              * OSPM will not run the _INI and will not examine the children
601              * of the device for _INI methods"
602              */
603             return_ACPI_STATUS (AE_CTRL_DEPTH);
604         }
605     }
606
607     /*
608      * The device is present or is assumed present if no _STA exists.
609      * Run the _INI if it exists (not required to exist)
610      *
611      * Note: We know there is an _INI within this subtree, but it may not be
612      * under this particular device, it may be lower in the branch.
613      */
614     ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (
615         ACPI_TYPE_METHOD, DeviceNode, METHOD_NAME__INI));
616
617     memset (Info, 0, sizeof (ACPI_EVALUATE_INFO));
618     Info->PrefixNode = DeviceNode;
619     Info->RelativePathname = METHOD_NAME__INI;
620     Info->Parameters = NULL;
621     Info->Flags = ACPI_IGNORE_RETURN_VALUE;
622
623     Status = AcpiNsEvaluate (Info);
624     if (ACPI_SUCCESS (Status))
625     {
626         WalkInfo->Num_INI++;
627     }
628
629 #ifdef ACPI_DEBUG_OUTPUT
630     else if (Status != AE_NOT_FOUND)
631     {
632         /* Ignore error and move on to next device */
633
634         char *ScopeName = AcpiNsGetExternalPathname (Info->Node);
635
636         ACPI_EXCEPTION ((AE_INFO, Status, "during %s._INI execution",
637             ScopeName));
638         ACPI_FREE (ScopeName);
639     }
640 #endif
641
642     /* Ignore errors from above */
643
644     Status = AE_OK;
645
646     /*
647      * The _INI method has been run if present; call the Global Initialization
648      * Handler for this device.
649      */
650     if (AcpiGbl_InitHandler)
651     {
652         Status = AcpiGbl_InitHandler (DeviceNode, ACPI_INIT_DEVICE_INI);
653     }
654
655     return_ACPI_STATUS (Status);
656 }