189b8eb6cSchristos /******************************************************************************
289b8eb6cSchristos *
389b8eb6cSchristos * Module Name: dspkginit - Completion of deferred package initialization
489b8eb6cSchristos *
589b8eb6cSchristos *****************************************************************************/
689b8eb6cSchristos
789b8eb6cSchristos /*
8*2c7d7e3cSchristos * Copyright (C) 2000 - 2023, Intel Corp.
989b8eb6cSchristos * All rights reserved.
1089b8eb6cSchristos *
1189b8eb6cSchristos * Redistribution and use in source and binary forms, with or without
1289b8eb6cSchristos * modification, are permitted provided that the following conditions
1389b8eb6cSchristos * are met:
1489b8eb6cSchristos * 1. Redistributions of source code must retain the above copyright
1589b8eb6cSchristos * notice, this list of conditions, and the following disclaimer,
1689b8eb6cSchristos * without modification.
1789b8eb6cSchristos * 2. Redistributions in binary form must reproduce at minimum a disclaimer
1889b8eb6cSchristos * substantially similar to the "NO WARRANTY" disclaimer below
1989b8eb6cSchristos * ("Disclaimer") and any redistribution must be conditioned upon
2089b8eb6cSchristos * including a substantially similar Disclaimer requirement for further
2189b8eb6cSchristos * binary redistribution.
2289b8eb6cSchristos * 3. Neither the names of the above-listed copyright holders nor the names
2389b8eb6cSchristos * of any contributors may be used to endorse or promote products derived
2489b8eb6cSchristos * from this software without specific prior written permission.
2589b8eb6cSchristos *
2689b8eb6cSchristos * Alternatively, this software may be distributed under the terms of the
2789b8eb6cSchristos * GNU General Public License ("GPL") version 2 as published by the Free
2889b8eb6cSchristos * Software Foundation.
2989b8eb6cSchristos *
3089b8eb6cSchristos * NO WARRANTY
3189b8eb6cSchristos * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3289b8eb6cSchristos * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3398244dcfSchristos * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3489b8eb6cSchristos * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3589b8eb6cSchristos * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3689b8eb6cSchristos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3789b8eb6cSchristos * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3889b8eb6cSchristos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
3989b8eb6cSchristos * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
4089b8eb6cSchristos * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
4189b8eb6cSchristos * POSSIBILITY OF SUCH DAMAGES.
4289b8eb6cSchristos */
4389b8eb6cSchristos
4489b8eb6cSchristos #include "acpi.h"
4589b8eb6cSchristos #include "accommon.h"
4689b8eb6cSchristos #include "acnamesp.h"
4789b8eb6cSchristos #include "amlcode.h"
4889b8eb6cSchristos #include "acdispat.h"
4989b8eb6cSchristos #include "acinterp.h"
50062782b3Schristos #include "acparser.h"
5189b8eb6cSchristos
5289b8eb6cSchristos
5389b8eb6cSchristos #define _COMPONENT ACPI_NAMESPACE
5489b8eb6cSchristos ACPI_MODULE_NAME ("dspkginit")
5589b8eb6cSchristos
5689b8eb6cSchristos
5789b8eb6cSchristos /* Local prototypes */
5889b8eb6cSchristos
5989b8eb6cSchristos static void
6089b8eb6cSchristos AcpiDsResolvePackageElement (
6189b8eb6cSchristos ACPI_OPERAND_OBJECT **Element);
6289b8eb6cSchristos
6389b8eb6cSchristos
6489b8eb6cSchristos /*******************************************************************************
6589b8eb6cSchristos *
6689b8eb6cSchristos * FUNCTION: AcpiDsBuildInternalPackageObj
6789b8eb6cSchristos *
6889b8eb6cSchristos * PARAMETERS: WalkState - Current walk state
6989b8eb6cSchristos * Op - Parser object to be translated
7089b8eb6cSchristos * ElementCount - Number of elements in the package - this is
7189b8eb6cSchristos * the NumElements argument to Package()
7289b8eb6cSchristos * ObjDescPtr - Where the ACPI internal object is returned
7389b8eb6cSchristos *
7489b8eb6cSchristos * RETURN: Status
7589b8eb6cSchristos *
7689b8eb6cSchristos * DESCRIPTION: Translate a parser Op package object to the equivalent
7789b8eb6cSchristos * namespace object
7889b8eb6cSchristos *
7989b8eb6cSchristos * NOTE: The number of elements in the package will be always be the NumElements
8089b8eb6cSchristos * count, regardless of the number of elements in the package list. If
8189b8eb6cSchristos * NumElements is smaller, only that many package list elements are used.
8289b8eb6cSchristos * if NumElements is larger, the Package object is padded out with
8389b8eb6cSchristos * objects of type Uninitialized (as per ACPI spec.)
8489b8eb6cSchristos *
8589b8eb6cSchristos * Even though the ASL compilers do not allow NumElements to be smaller
8689b8eb6cSchristos * than the Package list length (for the fixed length package opcode), some
8789b8eb6cSchristos * BIOS code modifies the AML on the fly to adjust the NumElements, and
8889b8eb6cSchristos * this code compensates for that. This also provides compatibility with
8989b8eb6cSchristos * other AML interpreters.
9089b8eb6cSchristos *
9189b8eb6cSchristos ******************************************************************************/
9289b8eb6cSchristos
9389b8eb6cSchristos ACPI_STATUS
AcpiDsBuildInternalPackageObj(ACPI_WALK_STATE * WalkState,ACPI_PARSE_OBJECT * Op,UINT32 ElementCount,ACPI_OPERAND_OBJECT ** ObjDescPtr)9489b8eb6cSchristos AcpiDsBuildInternalPackageObj (
9589b8eb6cSchristos ACPI_WALK_STATE *WalkState,
9689b8eb6cSchristos ACPI_PARSE_OBJECT *Op,
9789b8eb6cSchristos UINT32 ElementCount,
9889b8eb6cSchristos ACPI_OPERAND_OBJECT **ObjDescPtr)
9989b8eb6cSchristos {
10089b8eb6cSchristos ACPI_PARSE_OBJECT *Arg;
10189b8eb6cSchristos ACPI_PARSE_OBJECT *Parent;
10289b8eb6cSchristos ACPI_OPERAND_OBJECT *ObjDesc = NULL;
10389b8eb6cSchristos ACPI_STATUS Status = AE_OK;
104062782b3Schristos BOOLEAN ModuleLevelCode = FALSE;
10589b8eb6cSchristos UINT16 ReferenceCount;
10689b8eb6cSchristos UINT32 Index;
10789b8eb6cSchristos UINT32 i;
10889b8eb6cSchristos
10989b8eb6cSchristos
11089b8eb6cSchristos ACPI_FUNCTION_TRACE (DsBuildInternalPackageObj);
11189b8eb6cSchristos
11289b8eb6cSchristos
113062782b3Schristos /* Check if we are executing module level code */
114062782b3Schristos
115062782b3Schristos if (WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL)
116062782b3Schristos {
117062782b3Schristos ModuleLevelCode = TRUE;
118062782b3Schristos }
119062782b3Schristos
12089b8eb6cSchristos /* Find the parent of a possibly nested package */
12189b8eb6cSchristos
12289b8eb6cSchristos Parent = Op->Common.Parent;
12389b8eb6cSchristos while ((Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
12489b8eb6cSchristos (Parent->Common.AmlOpcode == AML_VARIABLE_PACKAGE_OP))
12589b8eb6cSchristos {
12689b8eb6cSchristos Parent = Parent->Common.Parent;
12789b8eb6cSchristos }
12889b8eb6cSchristos
12989b8eb6cSchristos /*
13089b8eb6cSchristos * If we are evaluating a Named package object of the form:
13189b8eb6cSchristos * Name (xxxx, Package)
13289b8eb6cSchristos * the package object already exists, otherwise it must be created.
13389b8eb6cSchristos */
13489b8eb6cSchristos ObjDesc = *ObjDescPtr;
13589b8eb6cSchristos if (!ObjDesc)
13689b8eb6cSchristos {
13789b8eb6cSchristos ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_PACKAGE);
13889b8eb6cSchristos *ObjDescPtr = ObjDesc;
13989b8eb6cSchristos if (!ObjDesc)
14089b8eb6cSchristos {
14189b8eb6cSchristos return_ACPI_STATUS (AE_NO_MEMORY);
14289b8eb6cSchristos }
14389b8eb6cSchristos
14489b8eb6cSchristos ObjDesc->Package.Node = Parent->Common.Node;
14589b8eb6cSchristos }
14689b8eb6cSchristos
14789b8eb6cSchristos if (ObjDesc->Package.Flags & AOPOBJ_DATA_VALID) /* Just in case */
14889b8eb6cSchristos {
14989b8eb6cSchristos return_ACPI_STATUS (AE_OK);
15089b8eb6cSchristos }
15189b8eb6cSchristos
15289b8eb6cSchristos /*
15389b8eb6cSchristos * Allocate the element array (array of pointers to the individual
154062782b3Schristos * objects) if necessary. the count is based on the NumElements
155062782b3Schristos * parameter. Add an extra pointer slot so that the list is always
156062782b3Schristos * null terminated.
15789b8eb6cSchristos */
158062782b3Schristos if (!ObjDesc->Package.Elements)
159062782b3Schristos {
16089b8eb6cSchristos ObjDesc->Package.Elements = ACPI_ALLOCATE_ZEROED (
16189b8eb6cSchristos ((ACPI_SIZE) ElementCount + 1) * sizeof (void *));
16289b8eb6cSchristos
16389b8eb6cSchristos if (!ObjDesc->Package.Elements)
16489b8eb6cSchristos {
16589b8eb6cSchristos AcpiUtDeleteObjectDesc (ObjDesc);
16689b8eb6cSchristos return_ACPI_STATUS (AE_NO_MEMORY);
16789b8eb6cSchristos }
16889b8eb6cSchristos
16989b8eb6cSchristos ObjDesc->Package.Count = ElementCount;
170062782b3Schristos }
171062782b3Schristos
172062782b3Schristos /* First arg is element count. Second arg begins the initializer list */
173062782b3Schristos
17489b8eb6cSchristos Arg = Op->Common.Value.Arg;
17589b8eb6cSchristos Arg = Arg->Common.Next;
17689b8eb6cSchristos
177062782b3Schristos /*
178062782b3Schristos * If we are executing module-level code, we will defer the
179062782b3Schristos * full resolution of the package elements in order to support
180062782b3Schristos * forward references from the elements. This provides
181062782b3Schristos * compatibility with other ACPI implementations.
182062782b3Schristos */
183062782b3Schristos if (ModuleLevelCode)
18489b8eb6cSchristos {
185062782b3Schristos ObjDesc->Package.AmlStart = WalkState->Aml;
186062782b3Schristos ObjDesc->Package.AmlLength = 0;
187062782b3Schristos
188062782b3Schristos ACPI_DEBUG_PRINT_RAW ((ACPI_DB_PARSE,
189062782b3Schristos "%s: Deferring resolution of Package elements\n",
190062782b3Schristos ACPI_GET_FUNCTION_NAME));
19189b8eb6cSchristos }
19289b8eb6cSchristos
19389b8eb6cSchristos /*
19489b8eb6cSchristos * Initialize the elements of the package, up to the NumElements count.
19589b8eb6cSchristos * Package is automatically padded with uninitialized (NULL) elements
19689b8eb6cSchristos * if NumElements is greater than the package list length. Likewise,
19789b8eb6cSchristos * Package is truncated if NumElements is less than the list length.
19889b8eb6cSchristos */
19989b8eb6cSchristos for (i = 0; Arg && (i < ElementCount); i++)
20089b8eb6cSchristos {
20189b8eb6cSchristos if (Arg->Common.AmlOpcode == AML_INT_RETURN_VALUE_OP)
20289b8eb6cSchristos {
2037efa3256Schristos if (!Arg->Common.Node)
2047efa3256Schristos {
2057efa3256Schristos /*
2067efa3256Schristos * This is the case where an expression has returned a value.
2077efa3256Schristos * The use of expressions (TermArgs) within individual
2087efa3256Schristos * package elements is not supported by the AML interpreter,
2097efa3256Schristos * even though the ASL grammar supports it. Example:
2107efa3256Schristos *
2117efa3256Schristos * Name (INT1, 0x1234)
2127efa3256Schristos *
2137efa3256Schristos * Name (PKG3, Package () {
2147efa3256Schristos * Add (INT1, 0xAAAA0000)
2157efa3256Schristos * })
2167efa3256Schristos *
2177efa3256Schristos * 1) No known AML interpreter supports this type of construct
2187efa3256Schristos * 2) This fixes a fault if the construct is encountered
2197efa3256Schristos */
2207efa3256Schristos ACPI_EXCEPTION ((AE_INFO, AE_SUPPORT,
2217efa3256Schristos "Expressions within package elements are not supported"));
2227efa3256Schristos
2237efa3256Schristos /* Cleanup the return object, it is not needed */
2247efa3256Schristos
2257efa3256Schristos AcpiUtRemoveReference (WalkState->Results->Results.ObjDesc[0]);
2267efa3256Schristos return_ACPI_STATUS (AE_SUPPORT);
2277efa3256Schristos }
2287efa3256Schristos
22989b8eb6cSchristos if (Arg->Common.Node->Type == ACPI_TYPE_METHOD)
23089b8eb6cSchristos {
23189b8eb6cSchristos /*
23289b8eb6cSchristos * A method reference "looks" to the parser to be a method
23389b8eb6cSchristos * invocation, so we special case it here
23489b8eb6cSchristos */
23589b8eb6cSchristos Arg->Common.AmlOpcode = AML_INT_NAMEPATH_OP;
23689b8eb6cSchristos Status = AcpiDsBuildInternalObject (
23789b8eb6cSchristos WalkState, Arg, &ObjDesc->Package.Elements[i]);
23889b8eb6cSchristos }
23989b8eb6cSchristos else
24089b8eb6cSchristos {
24189b8eb6cSchristos /* This package element is already built, just get it */
24289b8eb6cSchristos
24389b8eb6cSchristos ObjDesc->Package.Elements[i] =
24489b8eb6cSchristos ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Arg->Common.Node);
24589b8eb6cSchristos }
24689b8eb6cSchristos }
24789b8eb6cSchristos else
24889b8eb6cSchristos {
24989b8eb6cSchristos Status = AcpiDsBuildInternalObject (
25089b8eb6cSchristos WalkState, Arg, &ObjDesc->Package.Elements[i]);
25189b8eb6cSchristos if (Status == AE_NOT_FOUND)
25289b8eb6cSchristos {
25389b8eb6cSchristos ACPI_ERROR ((AE_INFO, "%-48s", "****DS namepath not found"));
25489b8eb6cSchristos }
25589b8eb6cSchristos
256062782b3Schristos if (!ModuleLevelCode)
257062782b3Schristos {
25889b8eb6cSchristos /*
25989b8eb6cSchristos * Initialize this package element. This function handles the
26089b8eb6cSchristos * resolution of named references within the package.
261062782b3Schristos * Forward references from module-level code are deferred
262062782b3Schristos * until all ACPI tables are loaded.
26389b8eb6cSchristos */
26489b8eb6cSchristos AcpiDsInitPackageElement (0, ObjDesc->Package.Elements[i],
26589b8eb6cSchristos NULL, &ObjDesc->Package.Elements[i]);
26689b8eb6cSchristos }
267062782b3Schristos }
26889b8eb6cSchristos
26989b8eb6cSchristos if (*ObjDescPtr)
27089b8eb6cSchristos {
27189b8eb6cSchristos /* Existing package, get existing reference count */
27289b8eb6cSchristos
27389b8eb6cSchristos ReferenceCount = (*ObjDescPtr)->Common.ReferenceCount;
27489b8eb6cSchristos if (ReferenceCount > 1)
27589b8eb6cSchristos {
27689b8eb6cSchristos /* Make new element ref count match original ref count */
27789b8eb6cSchristos /* TBD: Probably need an AcpiUtAddReferences function */
27889b8eb6cSchristos
27989b8eb6cSchristos for (Index = 0; Index < ((UINT32) ReferenceCount - 1); Index++)
28089b8eb6cSchristos {
28189b8eb6cSchristos AcpiUtAddReference ((ObjDesc->Package.Elements[i]));
28289b8eb6cSchristos }
28389b8eb6cSchristos }
28489b8eb6cSchristos }
28589b8eb6cSchristos
28689b8eb6cSchristos Arg = Arg->Common.Next;
28789b8eb6cSchristos }
28889b8eb6cSchristos
28989b8eb6cSchristos /* Check for match between NumElements and actual length of PackageList */
29089b8eb6cSchristos
29189b8eb6cSchristos if (Arg)
29289b8eb6cSchristos {
29389b8eb6cSchristos /*
29489b8eb6cSchristos * NumElements was exhausted, but there are remaining elements in
29589b8eb6cSchristos * the PackageList. Truncate the package to NumElements.
29689b8eb6cSchristos *
29789b8eb6cSchristos * Note: technically, this is an error, from ACPI spec: "It is an
29889b8eb6cSchristos * error for NumElements to be less than the number of elements in
29989b8eb6cSchristos * the PackageList". However, we just print a message and no
30089b8eb6cSchristos * exception is returned. This provides compatibility with other
30189b8eb6cSchristos * ACPI implementations. Some firmware implementations will alter
30289b8eb6cSchristos * the NumElements on the fly, possibly creating this type of
30389b8eb6cSchristos * ill-formed package object.
30489b8eb6cSchristos */
30589b8eb6cSchristos while (Arg)
30689b8eb6cSchristos {
30789b8eb6cSchristos /*
30889b8eb6cSchristos * We must delete any package elements that were created earlier
30989b8eb6cSchristos * and are not going to be used because of the package truncation.
31089b8eb6cSchristos */
31189b8eb6cSchristos if (Arg->Common.Node)
31289b8eb6cSchristos {
31389b8eb6cSchristos AcpiUtRemoveReference (
31489b8eb6cSchristos ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Arg->Common.Node));
31589b8eb6cSchristos Arg->Common.Node = NULL;
31689b8eb6cSchristos }
31789b8eb6cSchristos
31889b8eb6cSchristos /* Find out how many elements there really are */
31989b8eb6cSchristos
32089b8eb6cSchristos i++;
32189b8eb6cSchristos Arg = Arg->Common.Next;
32289b8eb6cSchristos }
32389b8eb6cSchristos
32489b8eb6cSchristos ACPI_INFO ((
32589b8eb6cSchristos "Actual Package length (%u) is larger than "
32689b8eb6cSchristos "NumElements field (%u), truncated",
32789b8eb6cSchristos i, ElementCount));
32889b8eb6cSchristos }
32989b8eb6cSchristos else if (i < ElementCount)
33089b8eb6cSchristos {
33189b8eb6cSchristos /*
33289b8eb6cSchristos * Arg list (elements) was exhausted, but we did not reach
33389b8eb6cSchristos * NumElements count.
33489b8eb6cSchristos *
33589b8eb6cSchristos * Note: this is not an error, the package is padded out
336062782b3Schristos * with NULLs as per the ACPI specification.
33789b8eb6cSchristos */
338062782b3Schristos ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO,
339062782b3Schristos "%s: Package List length (%u) smaller than NumElements "
34089b8eb6cSchristos "count (%u), padded with null elements\n",
341062782b3Schristos ACPI_GET_FUNCTION_NAME, i, ElementCount));
34289b8eb6cSchristos }
34389b8eb6cSchristos
344062782b3Schristos /* Module-level packages will be resolved later */
345062782b3Schristos
346062782b3Schristos if (!ModuleLevelCode)
347062782b3Schristos {
34889b8eb6cSchristos ObjDesc->Package.Flags |= AOPOBJ_DATA_VALID;
349062782b3Schristos }
350062782b3Schristos
35189b8eb6cSchristos Op->Common.Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjDesc);
35289b8eb6cSchristos return_ACPI_STATUS (Status);
35389b8eb6cSchristos }
35489b8eb6cSchristos
35589b8eb6cSchristos
35689b8eb6cSchristos /*******************************************************************************
35789b8eb6cSchristos *
35889b8eb6cSchristos * FUNCTION: AcpiDsInitPackageElement
35989b8eb6cSchristos *
36089b8eb6cSchristos * PARAMETERS: ACPI_PKG_CALLBACK
36189b8eb6cSchristos *
36289b8eb6cSchristos * RETURN: Status
36389b8eb6cSchristos *
36489b8eb6cSchristos * DESCRIPTION: Resolve a named reference element within a package object
36589b8eb6cSchristos *
36689b8eb6cSchristos ******************************************************************************/
36789b8eb6cSchristos
36889b8eb6cSchristos ACPI_STATUS
AcpiDsInitPackageElement(UINT8 ObjectType,ACPI_OPERAND_OBJECT * SourceObject,ACPI_GENERIC_STATE * State,void * Context)36989b8eb6cSchristos AcpiDsInitPackageElement (
37089b8eb6cSchristos UINT8 ObjectType,
37189b8eb6cSchristos ACPI_OPERAND_OBJECT *SourceObject,
37289b8eb6cSchristos ACPI_GENERIC_STATE *State,
37389b8eb6cSchristos void *Context)
37489b8eb6cSchristos {
37589b8eb6cSchristos ACPI_OPERAND_OBJECT **ElementPtr;
37689b8eb6cSchristos
37789b8eb6cSchristos
378062782b3Schristos ACPI_FUNCTION_TRACE (DsInitPackageElement);
379062782b3Schristos
380062782b3Schristos
38189b8eb6cSchristos if (!SourceObject)
38289b8eb6cSchristos {
383062782b3Schristos return_ACPI_STATUS (AE_OK);
38489b8eb6cSchristos }
38589b8eb6cSchristos
38689b8eb6cSchristos /*
38789b8eb6cSchristos * The following code is a bit of a hack to workaround a (current)
38889b8eb6cSchristos * limitation of the ACPI_PKG_CALLBACK interface. We need a pointer
38989b8eb6cSchristos * to the location within the element array because a new object
39089b8eb6cSchristos * may be created and stored there.
39189b8eb6cSchristos */
39289b8eb6cSchristos if (Context)
39389b8eb6cSchristos {
39489b8eb6cSchristos /* A direct call was made to this function */
39589b8eb6cSchristos
39689b8eb6cSchristos ElementPtr = (ACPI_OPERAND_OBJECT **) Context;
39789b8eb6cSchristos }
39889b8eb6cSchristos else
39989b8eb6cSchristos {
40089b8eb6cSchristos /* Call came from AcpiUtWalkPackageTree */
40189b8eb6cSchristos
40289b8eb6cSchristos ElementPtr = State->Pkg.ThisTargetObj;
40389b8eb6cSchristos }
40489b8eb6cSchristos
40589b8eb6cSchristos /* We are only interested in reference objects/elements */
40689b8eb6cSchristos
40789b8eb6cSchristos if (SourceObject->Common.Type == ACPI_TYPE_LOCAL_REFERENCE)
40889b8eb6cSchristos {
40989b8eb6cSchristos /* Attempt to resolve the (named) reference to a namespace node */
41089b8eb6cSchristos
41189b8eb6cSchristos AcpiDsResolvePackageElement (ElementPtr);
41289b8eb6cSchristos }
41389b8eb6cSchristos else if (SourceObject->Common.Type == ACPI_TYPE_PACKAGE)
41489b8eb6cSchristos {
41589b8eb6cSchristos SourceObject->Package.Flags |= AOPOBJ_DATA_VALID;
41689b8eb6cSchristos }
41789b8eb6cSchristos
418062782b3Schristos return_ACPI_STATUS (AE_OK);
41989b8eb6cSchristos }
42089b8eb6cSchristos
42189b8eb6cSchristos
42289b8eb6cSchristos /*******************************************************************************
42389b8eb6cSchristos *
42489b8eb6cSchristos * FUNCTION: AcpiDsResolvePackageElement
42589b8eb6cSchristos *
42689b8eb6cSchristos * PARAMETERS: ElementPtr - Pointer to a reference object
42789b8eb6cSchristos *
42889b8eb6cSchristos * RETURN: Possible new element is stored to the indirect ElementPtr
42989b8eb6cSchristos *
43089b8eb6cSchristos * DESCRIPTION: Resolve a package element that is a reference to a named
43189b8eb6cSchristos * object.
43289b8eb6cSchristos *
43389b8eb6cSchristos ******************************************************************************/
43489b8eb6cSchristos
43589b8eb6cSchristos static void
AcpiDsResolvePackageElement(ACPI_OPERAND_OBJECT ** ElementPtr)43689b8eb6cSchristos AcpiDsResolvePackageElement (
43789b8eb6cSchristos ACPI_OPERAND_OBJECT **ElementPtr)
43889b8eb6cSchristos {
43989b8eb6cSchristos ACPI_STATUS Status;
440062782b3Schristos ACPI_STATUS Status2;
44189b8eb6cSchristos ACPI_GENERIC_STATE ScopeInfo;
44289b8eb6cSchristos ACPI_OPERAND_OBJECT *Element = *ElementPtr;
44389b8eb6cSchristos ACPI_NAMESPACE_NODE *ResolvedNode;
444062782b3Schristos ACPI_NAMESPACE_NODE *OriginalNode;
445f45f09e8Schristos char *ExternalPath = __UNCONST("");
44689b8eb6cSchristos ACPI_OBJECT_TYPE Type;
44789b8eb6cSchristos
44889b8eb6cSchristos
44989b8eb6cSchristos ACPI_FUNCTION_TRACE (DsResolvePackageElement);
45089b8eb6cSchristos
45189b8eb6cSchristos
45289b8eb6cSchristos /* Check if reference element is already resolved */
45389b8eb6cSchristos
45489b8eb6cSchristos if (Element->Reference.Resolved)
45589b8eb6cSchristos {
456062782b3Schristos ACPI_DEBUG_PRINT_RAW ((ACPI_DB_PARSE,
457062782b3Schristos "%s: Package element is already resolved\n",
458062782b3Schristos ACPI_GET_FUNCTION_NAME));
459062782b3Schristos
46089b8eb6cSchristos return_VOID;
46189b8eb6cSchristos }
46289b8eb6cSchristos
46389b8eb6cSchristos /* Element must be a reference object of correct type */
46489b8eb6cSchristos
46589b8eb6cSchristos ScopeInfo.Scope.Node = Element->Reference.Node; /* Prefix node */
46689b8eb6cSchristos
467062782b3Schristos Status = AcpiNsLookup (&ScopeInfo, (char *) Element->Reference.Aml,
46889b8eb6cSchristos ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
46989b8eb6cSchristos ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
47089b8eb6cSchristos NULL, &ResolvedNode);
47189b8eb6cSchristos if (ACPI_FAILURE (Status))
47289b8eb6cSchristos {
473062782b3Schristos if ((Status == AE_NOT_FOUND) && AcpiGbl_IgnorePackageResolutionErrors)
474062782b3Schristos {
475062782b3Schristos /*
476062782b3Schristos * Optionally be silent about the NOT_FOUND case for the referenced
477062782b3Schristos * name. Although this is potentially a serious problem,
478062782b3Schristos * it can generate a lot of noise/errors on platforms whose
479062782b3Schristos * firmware carries around a bunch of unused Package objects.
480062782b3Schristos * To disable these errors, set this global to TRUE:
481062782b3Schristos * AcpiGbl_IgnorePackageResolutionErrors
482062782b3Schristos *
483062782b3Schristos * If the AML actually tries to use such a package, the unresolved
484062782b3Schristos * element(s) will be replaced with NULL elements.
485062782b3Schristos */
486062782b3Schristos
487062782b3Schristos /* Referenced name not found, set the element to NULL */
488062782b3Schristos
489062782b3Schristos AcpiUtRemoveReference (*ElementPtr);
490062782b3Schristos *ElementPtr = NULL;
491062782b3Schristos return_VOID;
492062782b3Schristos }
493062782b3Schristos
494062782b3Schristos Status2 = AcpiNsExternalizeName (ACPI_UINT32_MAX,
495062782b3Schristos (char *) Element->Reference.Aml, NULL, &ExternalPath);
49689b8eb6cSchristos
49789b8eb6cSchristos ACPI_EXCEPTION ((AE_INFO, Status,
498062782b3Schristos "While resolving a named reference package element - %s",
499062782b3Schristos ExternalPath));
500062782b3Schristos if (ACPI_SUCCESS (Status2))
501062782b3Schristos {
50289b8eb6cSchristos ACPI_FREE (ExternalPath);
503062782b3Schristos }
504062782b3Schristos
505062782b3Schristos /* Could not resolve name, set the element to NULL */
506062782b3Schristos
507062782b3Schristos AcpiUtRemoveReference (*ElementPtr);
50889b8eb6cSchristos *ElementPtr = NULL;
50989b8eb6cSchristos return_VOID;
51089b8eb6cSchristos }
51189b8eb6cSchristos else if (ResolvedNode->Type == ACPI_TYPE_ANY)
51289b8eb6cSchristos {
51389b8eb6cSchristos /* Named reference not resolved, return a NULL package element */
51489b8eb6cSchristos
51589b8eb6cSchristos ACPI_ERROR ((AE_INFO,
51689b8eb6cSchristos "Could not resolve named package element [%4.4s] in [%4.4s]",
51789b8eb6cSchristos ResolvedNode->Name.Ascii, ScopeInfo.Scope.Node->Name.Ascii));
51889b8eb6cSchristos *ElementPtr = NULL;
51989b8eb6cSchristos return_VOID;
52089b8eb6cSchristos }
52189b8eb6cSchristos
52289b8eb6cSchristos /*
52389b8eb6cSchristos * Special handling for Alias objects. We need ResolvedNode to point
52489b8eb6cSchristos * to the Alias target. This effectively "resolves" the alias.
52589b8eb6cSchristos */
52689b8eb6cSchristos if (ResolvedNode->Type == ACPI_TYPE_LOCAL_ALIAS)
52789b8eb6cSchristos {
52889b8eb6cSchristos ResolvedNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE,
52989b8eb6cSchristos ResolvedNode->Object);
53089b8eb6cSchristos }
53189b8eb6cSchristos
53289b8eb6cSchristos /* Update the reference object */
53389b8eb6cSchristos
53489b8eb6cSchristos Element->Reference.Resolved = TRUE;
53589b8eb6cSchristos Element->Reference.Node = ResolvedNode;
53689b8eb6cSchristos Type = Element->Reference.Node->Type;
53789b8eb6cSchristos
53889b8eb6cSchristos /*
53989b8eb6cSchristos * Attempt to resolve the node to a value before we insert it into
54089b8eb6cSchristos * the package. If this is a reference to a common data type,
54189b8eb6cSchristos * resolve it immediately. According to the ACPI spec, package
54289b8eb6cSchristos * elements can only be "data objects" or method references.
54389b8eb6cSchristos * Attempt to resolve to an Integer, Buffer, String or Package.
54489b8eb6cSchristos * If cannot, return the named reference (for things like Devices,
54589b8eb6cSchristos * Methods, etc.) Buffer Fields and Fields will resolve to simple
54689b8eb6cSchristos * objects (int/buf/str/pkg).
54789b8eb6cSchristos *
54889b8eb6cSchristos * NOTE: References to things like Devices, Methods, Mutexes, etc.
54989b8eb6cSchristos * will remain as named references. This behavior is not described
55089b8eb6cSchristos * in the ACPI spec, but it appears to be an oversight.
55189b8eb6cSchristos */
552062782b3Schristos OriginalNode = ResolvedNode;
55389b8eb6cSchristos Status = AcpiExResolveNodeToValue (&ResolvedNode, NULL);
55489b8eb6cSchristos if (ACPI_FAILURE (Status))
55589b8eb6cSchristos {
55689b8eb6cSchristos return_VOID;
55789b8eb6cSchristos }
55889b8eb6cSchristos
55989b8eb6cSchristos switch (Type)
56089b8eb6cSchristos {
56189b8eb6cSchristos /*
56289b8eb6cSchristos * These object types are a result of named references, so we will
56389b8eb6cSchristos * leave them as reference objects. In other words, these types
56489b8eb6cSchristos * have no intrinsic "value".
56589b8eb6cSchristos */
56689b8eb6cSchristos case ACPI_TYPE_DEVICE:
56789b8eb6cSchristos case ACPI_TYPE_THERMAL:
568062782b3Schristos case ACPI_TYPE_METHOD:
56989b8eb6cSchristos break;
57089b8eb6cSchristos
57189b8eb6cSchristos case ACPI_TYPE_MUTEX:
57289b8eb6cSchristos case ACPI_TYPE_POWER:
57389b8eb6cSchristos case ACPI_TYPE_PROCESSOR:
57489b8eb6cSchristos case ACPI_TYPE_EVENT:
57589b8eb6cSchristos case ACPI_TYPE_REGION:
57689b8eb6cSchristos
577062782b3Schristos /* AcpiExResolveNodeToValue gave these an extra reference */
578062782b3Schristos
579062782b3Schristos AcpiUtRemoveReference (OriginalNode->Object);
58089b8eb6cSchristos break;
58189b8eb6cSchristos
58289b8eb6cSchristos default:
58389b8eb6cSchristos /*
58489b8eb6cSchristos * For all other types - the node was resolved to an actual
585062782b3Schristos * operand object with a value, return the object. Remove
586062782b3Schristos * a reference on the existing object.
58789b8eb6cSchristos */
588062782b3Schristos AcpiUtRemoveReference (Element);
58989b8eb6cSchristos *ElementPtr = (ACPI_OPERAND_OBJECT *) ResolvedNode;
59089b8eb6cSchristos break;
59189b8eb6cSchristos }
59289b8eb6cSchristos
59389b8eb6cSchristos return_VOID;
59489b8eb6cSchristos }
595