[ACPICA] Update to version 20180531. CORE-15222
[reactos.git] / drivers / bus / acpi / acpica / dispatcher / dspkginit.c
1 /******************************************************************************
2 *
3 * Module Name: dspkginit - Completion of deferred package initialization
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2018, 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 "amlcode.h"
48 #include "acdispat.h"
49 #include "acinterp.h"
50 #include "acparser.h"
51
52
53 #define _COMPONENT ACPI_NAMESPACE
54 ACPI_MODULE_NAME ("dspkginit")
55
56
57 /* Local prototypes */
58
59 static void
60 AcpiDsResolvePackageElement (
61 ACPI_OPERAND_OBJECT **Element);
62
63
64 /*******************************************************************************
65 *
66 * FUNCTION: AcpiDsBuildInternalPackageObj
67 *
68 * PARAMETERS: WalkState - Current walk state
69 * Op - Parser object to be translated
70 * ElementCount - Number of elements in the package - this is
71 * the NumElements argument to Package()
72 * ObjDescPtr - Where the ACPI internal object is returned
73 *
74 * RETURN: Status
75 *
76 * DESCRIPTION: Translate a parser Op package object to the equivalent
77 * namespace object
78 *
79 * NOTE: The number of elements in the package will be always be the NumElements
80 * count, regardless of the number of elements in the package list. If
81 * NumElements is smaller, only that many package list elements are used.
82 * if NumElements is larger, the Package object is padded out with
83 * objects of type Uninitialized (as per ACPI spec.)
84 *
85 * Even though the ASL compilers do not allow NumElements to be smaller
86 * than the Package list length (for the fixed length package opcode), some
87 * BIOS code modifies the AML on the fly to adjust the NumElements, and
88 * this code compensates for that. This also provides compatibility with
89 * other AML interpreters.
90 *
91 ******************************************************************************/
92
93 ACPI_STATUS
94 AcpiDsBuildInternalPackageObj (
95 ACPI_WALK_STATE *WalkState,
96 ACPI_PARSE_OBJECT *Op,
97 UINT32 ElementCount,
98 ACPI_OPERAND_OBJECT **ObjDescPtr)
99 {
100 ACPI_PARSE_OBJECT *Arg;
101 ACPI_PARSE_OBJECT *Parent;
102 ACPI_OPERAND_OBJECT *ObjDesc = NULL;
103 ACPI_STATUS Status = AE_OK;
104 BOOLEAN ModuleLevelCode = FALSE;
105 UINT16 ReferenceCount;
106 UINT32 Index;
107 UINT32 i;
108
109
110 ACPI_FUNCTION_TRACE (DsBuildInternalPackageObj);
111
112
113 /* Check if we are executing module level code */
114
115 if (WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL)
116 {
117 ModuleLevelCode = TRUE;
118 }
119
120 /* Find the parent of a possibly nested package */
121
122 Parent = Op->Common.Parent;
123 while ((Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
124 (Parent->Common.AmlOpcode == AML_VARIABLE_PACKAGE_OP))
125 {
126 Parent = Parent->Common.Parent;
127 }
128
129 /*
130 * If we are evaluating a Named package object of the form:
131 * Name (xxxx, Package)
132 * the package object already exists, otherwise it must be created.
133 */
134 ObjDesc = *ObjDescPtr;
135 if (!ObjDesc)
136 {
137 ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_PACKAGE);
138 *ObjDescPtr = ObjDesc;
139 if (!ObjDesc)
140 {
141 return_ACPI_STATUS (AE_NO_MEMORY);
142 }
143
144 ObjDesc->Package.Node = Parent->Common.Node;
145 }
146
147 if (ObjDesc->Package.Flags & AOPOBJ_DATA_VALID) /* Just in case */
148 {
149 return_ACPI_STATUS (AE_OK);
150 }
151
152 /*
153 * Allocate the element array (array of pointers to the individual
154 * objects) if necessary. the count is based on the NumElements
155 * parameter. Add an extra pointer slot so that the list is always
156 * null terminated.
157 */
158 if (!ObjDesc->Package.Elements)
159 {
160 ObjDesc->Package.Elements = ACPI_ALLOCATE_ZEROED (
161 ((ACPI_SIZE) ElementCount + 1) * sizeof (void *));
162
163 if (!ObjDesc->Package.Elements)
164 {
165 AcpiUtDeleteObjectDesc (ObjDesc);
166 return_ACPI_STATUS (AE_NO_MEMORY);
167 }
168
169 ObjDesc->Package.Count = ElementCount;
170 }
171
172 /* First arg is element count. Second arg begins the initializer list */
173
174 Arg = Op->Common.Value.Arg;
175 Arg = Arg->Common.Next;
176
177 /*
178 * If we are executing module-level code, we will defer the
179 * full resolution of the package elements in order to support
180 * forward references from the elements. This provides
181 * compatibility with other ACPI implementations.
182 */
183 if (ModuleLevelCode)
184 {
185 ObjDesc->Package.AmlStart = WalkState->Aml;
186 ObjDesc->Package.AmlLength = 0;
187
188 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_PARSE,
189 "%s: Deferring resolution of Package elements\n",
190 ACPI_GET_FUNCTION_NAME));
191 }
192
193 /*
194 * Initialize the elements of the package, up to the NumElements count.
195 * Package is automatically padded with uninitialized (NULL) elements
196 * if NumElements is greater than the package list length. Likewise,
197 * Package is truncated if NumElements is less than the list length.
198 */
199 for (i = 0; Arg && (i < ElementCount); i++)
200 {
201 if (Arg->Common.AmlOpcode == AML_INT_RETURN_VALUE_OP)
202 {
203 if (Arg->Common.Node->Type == ACPI_TYPE_METHOD)
204 {
205 /*
206 * A method reference "looks" to the parser to be a method
207 * invocation, so we special case it here
208 */
209 Arg->Common.AmlOpcode = AML_INT_NAMEPATH_OP;
210 Status = AcpiDsBuildInternalObject (
211 WalkState, Arg, &ObjDesc->Package.Elements[i]);
212 }
213 else
214 {
215 /* This package element is already built, just get it */
216
217 ObjDesc->Package.Elements[i] =
218 ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Arg->Common.Node);
219 }
220 }
221 else
222 {
223 Status = AcpiDsBuildInternalObject (
224 WalkState, Arg, &ObjDesc->Package.Elements[i]);
225 if (Status == AE_NOT_FOUND)
226 {
227 ACPI_ERROR ((AE_INFO, "%-48s", "****DS namepath not found"));
228 }
229
230 if (!ModuleLevelCode)
231 {
232 /*
233 * Initialize this package element. This function handles the
234 * resolution of named references within the package.
235 * Forward references from module-level code are deferred
236 * until all ACPI tables are loaded.
237 */
238 AcpiDsInitPackageElement (0, ObjDesc->Package.Elements[i],
239 NULL, &ObjDesc->Package.Elements[i]);
240 }
241 }
242
243 if (*ObjDescPtr)
244 {
245 /* Existing package, get existing reference count */
246
247 ReferenceCount = (*ObjDescPtr)->Common.ReferenceCount;
248 if (ReferenceCount > 1)
249 {
250 /* Make new element ref count match original ref count */
251 /* TBD: Probably need an AcpiUtAddReferences function */
252
253 for (Index = 0; Index < ((UINT32) ReferenceCount - 1); Index++)
254 {
255 AcpiUtAddReference ((ObjDesc->Package.Elements[i]));
256 }
257 }
258 }
259
260 Arg = Arg->Common.Next;
261 }
262
263 /* Check for match between NumElements and actual length of PackageList */
264
265 if (Arg)
266 {
267 /*
268 * NumElements was exhausted, but there are remaining elements in
269 * the PackageList. Truncate the package to NumElements.
270 *
271 * Note: technically, this is an error, from ACPI spec: "It is an
272 * error for NumElements to be less than the number of elements in
273 * the PackageList". However, we just print a message and no
274 * exception is returned. This provides compatibility with other
275 * ACPI implementations. Some firmware implementations will alter
276 * the NumElements on the fly, possibly creating this type of
277 * ill-formed package object.
278 */
279 while (Arg)
280 {
281 /*
282 * We must delete any package elements that were created earlier
283 * and are not going to be used because of the package truncation.
284 */
285 if (Arg->Common.Node)
286 {
287 AcpiUtRemoveReference (
288 ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Arg->Common.Node));
289 Arg->Common.Node = NULL;
290 }
291
292 /* Find out how many elements there really are */
293
294 i++;
295 Arg = Arg->Common.Next;
296 }
297
298 ACPI_INFO ((
299 "Actual Package length (%u) is larger than "
300 "NumElements field (%u), truncated",
301 i, ElementCount));
302 }
303 else if (i < ElementCount)
304 {
305 /*
306 * Arg list (elements) was exhausted, but we did not reach
307 * NumElements count.
308 *
309 * Note: this is not an error, the package is padded out
310 * with NULLs as per the ACPI specification.
311 */
312 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO,
313 "%s: Package List length (%u) smaller than NumElements "
314 "count (%u), padded with null elements\n",
315 ACPI_GET_FUNCTION_NAME, i, ElementCount));
316 }
317
318 /* Module-level packages will be resolved later */
319
320 if (!ModuleLevelCode)
321 {
322 ObjDesc->Package.Flags |= AOPOBJ_DATA_VALID;
323 }
324
325 Op->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjDesc);
326 return_ACPI_STATUS (Status);
327 }
328
329
330 /*******************************************************************************
331 *
332 * FUNCTION: AcpiDsInitPackageElement
333 *
334 * PARAMETERS: ACPI_PKG_CALLBACK
335 *
336 * RETURN: Status
337 *
338 * DESCRIPTION: Resolve a named reference element within a package object
339 *
340 ******************************************************************************/
341
342 ACPI_STATUS
343 AcpiDsInitPackageElement (
344 UINT8 ObjectType,
345 ACPI_OPERAND_OBJECT *SourceObject,
346 ACPI_GENERIC_STATE *State,
347 void *Context)
348 {
349 ACPI_OPERAND_OBJECT **ElementPtr;
350
351
352 ACPI_FUNCTION_TRACE (DsInitPackageElement);
353
354
355 if (!SourceObject)
356 {
357 return_ACPI_STATUS (AE_OK);
358 }
359
360 /*
361 * The following code is a bit of a hack to workaround a (current)
362 * limitation of the ACPI_PKG_CALLBACK interface. We need a pointer
363 * to the location within the element array because a new object
364 * may be created and stored there.
365 */
366 if (Context)
367 {
368 /* A direct call was made to this function */
369
370 ElementPtr = (ACPI_OPERAND_OBJECT **) Context;
371 }
372 else
373 {
374 /* Call came from AcpiUtWalkPackageTree */
375
376 ElementPtr = State->Pkg.ThisTargetObj;
377 }
378
379 /* We are only interested in reference objects/elements */
380
381 if (SourceObject->Common.Type == ACPI_TYPE_LOCAL_REFERENCE)
382 {
383 /* Attempt to resolve the (named) reference to a namespace node */
384
385 AcpiDsResolvePackageElement (ElementPtr);
386 }
387 else if (SourceObject->Common.Type == ACPI_TYPE_PACKAGE)
388 {
389 SourceObject->Package.Flags |= AOPOBJ_DATA_VALID;
390 }
391
392 return_ACPI_STATUS (AE_OK);
393 }
394
395
396 /*******************************************************************************
397 *
398 * FUNCTION: AcpiDsResolvePackageElement
399 *
400 * PARAMETERS: ElementPtr - Pointer to a reference object
401 *
402 * RETURN: Possible new element is stored to the indirect ElementPtr
403 *
404 * DESCRIPTION: Resolve a package element that is a reference to a named
405 * object.
406 *
407 ******************************************************************************/
408
409 static void
410 AcpiDsResolvePackageElement (
411 ACPI_OPERAND_OBJECT **ElementPtr)
412 {
413 ACPI_STATUS Status;
414 ACPI_STATUS Status2;
415 ACPI_GENERIC_STATE ScopeInfo;
416 ACPI_OPERAND_OBJECT *Element = *ElementPtr;
417 ACPI_NAMESPACE_NODE *ResolvedNode;
418 ACPI_NAMESPACE_NODE *OriginalNode;
419 char *ExternalPath = "";
420 ACPI_OBJECT_TYPE Type;
421
422
423 ACPI_FUNCTION_TRACE (DsResolvePackageElement);
424
425
426 /* Check if reference element is already resolved */
427
428 if (Element->Reference.Resolved)
429 {
430 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_PARSE,
431 "%s: Package element is already resolved\n",
432 ACPI_GET_FUNCTION_NAME));
433
434 return_VOID;
435 }
436
437 /* Element must be a reference object of correct type */
438
439 ScopeInfo.Scope.Node = Element->Reference.Node; /* Prefix node */
440
441 Status = AcpiNsLookup (&ScopeInfo, (char *) Element->Reference.Aml,
442 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
443 ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
444 NULL, &ResolvedNode);
445 if (ACPI_FAILURE (Status))
446 {
447 if ((Status == AE_NOT_FOUND) && AcpiGbl_IgnorePackageResolutionErrors)
448 {
449 /*
450 * Optionally be silent about the NOT_FOUND case for the referenced
451 * name. Although this is potentially a serious problem,
452 * it can generate a lot of noise/errors on platforms whose
453 * firmware carries around a bunch of unused Package objects.
454 * To disable these errors, set this global to TRUE:
455 * AcpiGbl_IgnorePackageResolutionErrors
456 *
457 * If the AML actually tries to use such a package, the unresolved
458 * element(s) will be replaced with NULL elements.
459 */
460
461 /* Referenced name not found, set the element to NULL */
462
463 AcpiUtRemoveReference (*ElementPtr);
464 *ElementPtr = NULL;
465 return_VOID;
466 }
467
468 Status2 = AcpiNsExternalizeName (ACPI_UINT32_MAX,
469 (char *) Element->Reference.Aml, NULL, &ExternalPath);
470
471 ACPI_EXCEPTION ((AE_INFO, Status,
472 "While resolving a named reference package element - %s",
473 ExternalPath));
474 if (ACPI_SUCCESS (Status2))
475 {
476 ACPI_FREE (ExternalPath);
477 }
478
479 /* Could not resolve name, set the element to NULL */
480
481 AcpiUtRemoveReference (*ElementPtr);
482 *ElementPtr = NULL;
483 return_VOID;
484 }
485 else if (ResolvedNode->Type == ACPI_TYPE_ANY)
486 {
487 /* Named reference not resolved, return a NULL package element */
488
489 ACPI_ERROR ((AE_INFO,
490 "Could not resolve named package element [%4.4s] in [%4.4s]",
491 ResolvedNode->Name.Ascii, ScopeInfo.Scope.Node->Name.Ascii));
492 *ElementPtr = NULL;
493 return_VOID;
494 }
495
496 /*
497 * Special handling for Alias objects. We need ResolvedNode to point
498 * to the Alias target. This effectively "resolves" the alias.
499 */
500 if (ResolvedNode->Type == ACPI_TYPE_LOCAL_ALIAS)
501 {
502 ResolvedNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE,
503 ResolvedNode->Object);
504 }
505
506 /* Update the reference object */
507
508 Element->Reference.Resolved = TRUE;
509 Element->Reference.Node = ResolvedNode;
510 Type = Element->Reference.Node->Type;
511
512 /*
513 * Attempt to resolve the node to a value before we insert it into
514 * the package. If this is a reference to a common data type,
515 * resolve it immediately. According to the ACPI spec, package
516 * elements can only be "data objects" or method references.
517 * Attempt to resolve to an Integer, Buffer, String or Package.
518 * If cannot, return the named reference (for things like Devices,
519 * Methods, etc.) Buffer Fields and Fields will resolve to simple
520 * objects (int/buf/str/pkg).
521 *
522 * NOTE: References to things like Devices, Methods, Mutexes, etc.
523 * will remain as named references. This behavior is not described
524 * in the ACPI spec, but it appears to be an oversight.
525 */
526 OriginalNode = ResolvedNode;
527 Status = AcpiExResolveNodeToValue (&ResolvedNode, NULL);
528 if (ACPI_FAILURE (Status))
529 {
530 return_VOID;
531 }
532
533 switch (Type)
534 {
535 /*
536 * These object types are a result of named references, so we will
537 * leave them as reference objects. In other words, these types
538 * have no intrinsic "value".
539 */
540 case ACPI_TYPE_DEVICE:
541 case ACPI_TYPE_THERMAL:
542 case ACPI_TYPE_METHOD:
543 break;
544
545 case ACPI_TYPE_MUTEX:
546 case ACPI_TYPE_POWER:
547 case ACPI_TYPE_PROCESSOR:
548 case ACPI_TYPE_EVENT:
549 case ACPI_TYPE_REGION:
550
551 /* AcpiExResolveNodeToValue gave these an extra reference */
552
553 AcpiUtRemoveReference (OriginalNode->Object);
554 break;
555
556 default:
557 /*
558 * For all other types - the node was resolved to an actual
559 * operand object with a value, return the object. Remove
560 * a reference on the existing object.
561 */
562 AcpiUtRemoveReference (Element);
563 *ElementPtr = (ACPI_OPERAND_OBJECT *) ResolvedNode;
564 break;
565 }
566
567 return_VOID;
568 }