126f3cdf0SGordon Ross /******************************************************************************
226f3cdf0SGordon Ross *
326f3cdf0SGordon Ross * Module Name: dswload2 - Dispatcher second pass namespace load callbacks
426f3cdf0SGordon Ross *
526f3cdf0SGordon Ross *****************************************************************************/
626f3cdf0SGordon Ross
726f3cdf0SGordon Ross /*
8*385cc6b4SJerry Jelinek * Copyright (C) 2000 - 2016, Intel Corp.
926f3cdf0SGordon Ross * All rights reserved.
1026f3cdf0SGordon Ross *
1126f3cdf0SGordon Ross * Redistribution and use in source and binary forms, with or without
1226f3cdf0SGordon Ross * modification, are permitted provided that the following conditions
1326f3cdf0SGordon Ross * are met:
1426f3cdf0SGordon Ross * 1. Redistributions of source code must retain the above copyright
1526f3cdf0SGordon Ross * notice, this list of conditions, and the following disclaimer,
1626f3cdf0SGordon Ross * without modification.
1726f3cdf0SGordon Ross * 2. Redistributions in binary form must reproduce at minimum a disclaimer
1826f3cdf0SGordon Ross * substantially similar to the "NO WARRANTY" disclaimer below
1926f3cdf0SGordon Ross * ("Disclaimer") and any redistribution must be conditioned upon
2026f3cdf0SGordon Ross * including a substantially similar Disclaimer requirement for further
2126f3cdf0SGordon Ross * binary redistribution.
2226f3cdf0SGordon Ross * 3. Neither the names of the above-listed copyright holders nor the names
2326f3cdf0SGordon Ross * of any contributors may be used to endorse or promote products derived
2426f3cdf0SGordon Ross * from this software without specific prior written permission.
2526f3cdf0SGordon Ross *
2626f3cdf0SGordon Ross * Alternatively, this software may be distributed under the terms of the
2726f3cdf0SGordon Ross * GNU General Public License ("GPL") version 2 as published by the Free
2826f3cdf0SGordon Ross * Software Foundation.
2926f3cdf0SGordon Ross *
3026f3cdf0SGordon Ross * NO WARRANTY
3126f3cdf0SGordon Ross * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3226f3cdf0SGordon Ross * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3326f3cdf0SGordon Ross * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
3426f3cdf0SGordon Ross * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3526f3cdf0SGordon Ross * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3626f3cdf0SGordon Ross * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3726f3cdf0SGordon Ross * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3826f3cdf0SGordon Ross * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
3926f3cdf0SGordon Ross * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
4026f3cdf0SGordon Ross * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
4126f3cdf0SGordon Ross * POSSIBILITY OF SUCH DAMAGES.
4226f3cdf0SGordon Ross */
4326f3cdf0SGordon Ross
4426f3cdf0SGordon Ross #include "acpi.h"
4526f3cdf0SGordon Ross #include "accommon.h"
4626f3cdf0SGordon Ross #include "acparser.h"
4726f3cdf0SGordon Ross #include "amlcode.h"
4826f3cdf0SGordon Ross #include "acdispat.h"
4926f3cdf0SGordon Ross #include "acinterp.h"
5026f3cdf0SGordon Ross #include "acnamesp.h"
5126f3cdf0SGordon Ross #include "acevents.h"
5226f3cdf0SGordon Ross
5326f3cdf0SGordon Ross #define _COMPONENT ACPI_DISPATCHER
5426f3cdf0SGordon Ross ACPI_MODULE_NAME ("dswload2")
5526f3cdf0SGordon Ross
5626f3cdf0SGordon Ross
5726f3cdf0SGordon Ross /*******************************************************************************
5826f3cdf0SGordon Ross *
5926f3cdf0SGordon Ross * FUNCTION: AcpiDsLoad2BeginOp
6026f3cdf0SGordon Ross *
6126f3cdf0SGordon Ross * PARAMETERS: WalkState - Current state of the parse tree walk
6226f3cdf0SGordon Ross * OutOp - Wher to return op if a new one is created
6326f3cdf0SGordon Ross *
6426f3cdf0SGordon Ross * RETURN: Status
6526f3cdf0SGordon Ross *
6626f3cdf0SGordon Ross * DESCRIPTION: Descending callback used during the loading of ACPI tables.
6726f3cdf0SGordon Ross *
6826f3cdf0SGordon Ross ******************************************************************************/
6926f3cdf0SGordon Ross
7026f3cdf0SGordon Ross ACPI_STATUS
AcpiDsLoad2BeginOp(ACPI_WALK_STATE * WalkState,ACPI_PARSE_OBJECT ** OutOp)7126f3cdf0SGordon Ross AcpiDsLoad2BeginOp (
7226f3cdf0SGordon Ross ACPI_WALK_STATE *WalkState,
7326f3cdf0SGordon Ross ACPI_PARSE_OBJECT **OutOp)
7426f3cdf0SGordon Ross {
7526f3cdf0SGordon Ross ACPI_PARSE_OBJECT *Op;
7626f3cdf0SGordon Ross ACPI_NAMESPACE_NODE *Node;
7726f3cdf0SGordon Ross ACPI_STATUS Status;
7826f3cdf0SGordon Ross ACPI_OBJECT_TYPE ObjectType;
7926f3cdf0SGordon Ross char *BufferPtr;
8026f3cdf0SGordon Ross UINT32 Flags;
8126f3cdf0SGordon Ross
8226f3cdf0SGordon Ross
8326f3cdf0SGordon Ross ACPI_FUNCTION_TRACE (DsLoad2BeginOp);
8426f3cdf0SGordon Ross
8526f3cdf0SGordon Ross
8626f3cdf0SGordon Ross Op = WalkState->Op;
8726f3cdf0SGordon Ross ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", Op, WalkState));
8826f3cdf0SGordon Ross
8926f3cdf0SGordon Ross if (Op)
9026f3cdf0SGordon Ross {
9126f3cdf0SGordon Ross if ((WalkState->ControlState) &&
9226f3cdf0SGordon Ross (WalkState->ControlState->Common.State ==
9326f3cdf0SGordon Ross ACPI_CONTROL_CONDITIONAL_EXECUTING))
9426f3cdf0SGordon Ross {
9526f3cdf0SGordon Ross /* We are executing a while loop outside of a method */
9626f3cdf0SGordon Ross
9726f3cdf0SGordon Ross Status = AcpiDsExecBeginOp (WalkState, OutOp);
9826f3cdf0SGordon Ross return_ACPI_STATUS (Status);
9926f3cdf0SGordon Ross }
10026f3cdf0SGordon Ross
10126f3cdf0SGordon Ross /* We only care about Namespace opcodes here */
10226f3cdf0SGordon Ross
10326f3cdf0SGordon Ross if ((!(WalkState->OpInfo->Flags & AML_NSOPCODE) &&
10426f3cdf0SGordon Ross (WalkState->Opcode != AML_INT_NAMEPATH_OP)) ||
10526f3cdf0SGordon Ross (!(WalkState->OpInfo->Flags & AML_NAMED)))
10626f3cdf0SGordon Ross {
10726f3cdf0SGordon Ross return_ACPI_STATUS (AE_OK);
10826f3cdf0SGordon Ross }
10926f3cdf0SGordon Ross
11026f3cdf0SGordon Ross /* Get the name we are going to enter or lookup in the namespace */
11126f3cdf0SGordon Ross
11226f3cdf0SGordon Ross if (WalkState->Opcode == AML_INT_NAMEPATH_OP)
11326f3cdf0SGordon Ross {
11426f3cdf0SGordon Ross /* For Namepath op, get the path string */
11526f3cdf0SGordon Ross
11626f3cdf0SGordon Ross BufferPtr = Op->Common.Value.String;
11726f3cdf0SGordon Ross if (!BufferPtr)
11826f3cdf0SGordon Ross {
11926f3cdf0SGordon Ross /* No name, just exit */
12026f3cdf0SGordon Ross
12126f3cdf0SGordon Ross return_ACPI_STATUS (AE_OK);
12226f3cdf0SGordon Ross }
12326f3cdf0SGordon Ross }
12426f3cdf0SGordon Ross else
12526f3cdf0SGordon Ross {
12626f3cdf0SGordon Ross /* Get name from the op */
12726f3cdf0SGordon Ross
12826f3cdf0SGordon Ross BufferPtr = ACPI_CAST_PTR (char, &Op->Named.Name);
12926f3cdf0SGordon Ross }
13026f3cdf0SGordon Ross }
13126f3cdf0SGordon Ross else
13226f3cdf0SGordon Ross {
13326f3cdf0SGordon Ross /* Get the namestring from the raw AML */
13426f3cdf0SGordon Ross
13526f3cdf0SGordon Ross BufferPtr = AcpiPsGetNextNamestring (&WalkState->ParserState);
13626f3cdf0SGordon Ross }
13726f3cdf0SGordon Ross
13826f3cdf0SGordon Ross /* Map the opcode into an internal object type */
13926f3cdf0SGordon Ross
14026f3cdf0SGordon Ross ObjectType = WalkState->OpInfo->ObjectType;
14126f3cdf0SGordon Ross
14226f3cdf0SGordon Ross ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
14326f3cdf0SGordon Ross "State=%p Op=%p Type=%X\n", WalkState, Op, ObjectType));
14426f3cdf0SGordon Ross
14526f3cdf0SGordon Ross switch (WalkState->Opcode)
14626f3cdf0SGordon Ross {
14726f3cdf0SGordon Ross case AML_FIELD_OP:
14826f3cdf0SGordon Ross case AML_BANK_FIELD_OP:
14926f3cdf0SGordon Ross case AML_INDEX_FIELD_OP:
15026f3cdf0SGordon Ross
15126f3cdf0SGordon Ross Node = NULL;
15226f3cdf0SGordon Ross Status = AE_OK;
15326f3cdf0SGordon Ross break;
15426f3cdf0SGordon Ross
15526f3cdf0SGordon Ross case AML_INT_NAMEPATH_OP:
15626f3cdf0SGordon Ross /*
15726f3cdf0SGordon Ross * The NamePath is an object reference to an existing object.
15826f3cdf0SGordon Ross * Don't enter the name into the namespace, but look it up
15926f3cdf0SGordon Ross * for use later.
16026f3cdf0SGordon Ross */
16126f3cdf0SGordon Ross Status = AcpiNsLookup (WalkState->ScopeInfo, BufferPtr, ObjectType,
16226f3cdf0SGordon Ross ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
16326f3cdf0SGordon Ross WalkState, &(Node));
16426f3cdf0SGordon Ross break;
16526f3cdf0SGordon Ross
16626f3cdf0SGordon Ross case AML_SCOPE_OP:
16726f3cdf0SGordon Ross
16826f3cdf0SGordon Ross /* Special case for Scope(\) -> refers to the Root node */
16926f3cdf0SGordon Ross
17026f3cdf0SGordon Ross if (Op && (Op->Named.Node == AcpiGbl_RootNode))
17126f3cdf0SGordon Ross {
17226f3cdf0SGordon Ross Node = Op->Named.Node;
17326f3cdf0SGordon Ross
17426f3cdf0SGordon Ross Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
17526f3cdf0SGordon Ross if (ACPI_FAILURE (Status))
17626f3cdf0SGordon Ross {
17726f3cdf0SGordon Ross return_ACPI_STATUS (Status);
17826f3cdf0SGordon Ross }
17926f3cdf0SGordon Ross }
18026f3cdf0SGordon Ross else
18126f3cdf0SGordon Ross {
18226f3cdf0SGordon Ross /*
18326f3cdf0SGordon Ross * The Path is an object reference to an existing object.
18426f3cdf0SGordon Ross * Don't enter the name into the namespace, but look it up
18526f3cdf0SGordon Ross * for use later.
18626f3cdf0SGordon Ross */
18726f3cdf0SGordon Ross Status = AcpiNsLookup (WalkState->ScopeInfo, BufferPtr, ObjectType,
18826f3cdf0SGordon Ross ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
18926f3cdf0SGordon Ross WalkState, &(Node));
19026f3cdf0SGordon Ross if (ACPI_FAILURE (Status))
19126f3cdf0SGordon Ross {
19226f3cdf0SGordon Ross #ifdef ACPI_ASL_COMPILER
19326f3cdf0SGordon Ross if (Status == AE_NOT_FOUND)
19426f3cdf0SGordon Ross {
19526f3cdf0SGordon Ross Status = AE_OK;
19626f3cdf0SGordon Ross }
19726f3cdf0SGordon Ross else
19826f3cdf0SGordon Ross {
19926f3cdf0SGordon Ross ACPI_ERROR_NAMESPACE (BufferPtr, Status);
20026f3cdf0SGordon Ross }
20126f3cdf0SGordon Ross #else
20226f3cdf0SGordon Ross ACPI_ERROR_NAMESPACE (BufferPtr, Status);
20326f3cdf0SGordon Ross #endif
20426f3cdf0SGordon Ross return_ACPI_STATUS (Status);
20526f3cdf0SGordon Ross }
20626f3cdf0SGordon Ross }
20726f3cdf0SGordon Ross
20826f3cdf0SGordon Ross /*
20926f3cdf0SGordon Ross * We must check to make sure that the target is
21026f3cdf0SGordon Ross * one of the opcodes that actually opens a scope
21126f3cdf0SGordon Ross */
21226f3cdf0SGordon Ross switch (Node->Type)
21326f3cdf0SGordon Ross {
21426f3cdf0SGordon Ross case ACPI_TYPE_ANY:
21526f3cdf0SGordon Ross case ACPI_TYPE_LOCAL_SCOPE: /* Scope */
21626f3cdf0SGordon Ross case ACPI_TYPE_DEVICE:
21726f3cdf0SGordon Ross case ACPI_TYPE_POWER:
21826f3cdf0SGordon Ross case ACPI_TYPE_PROCESSOR:
21926f3cdf0SGordon Ross case ACPI_TYPE_THERMAL:
22026f3cdf0SGordon Ross
22126f3cdf0SGordon Ross /* These are acceptable types */
22226f3cdf0SGordon Ross break;
22326f3cdf0SGordon Ross
22426f3cdf0SGordon Ross case ACPI_TYPE_INTEGER:
22526f3cdf0SGordon Ross case ACPI_TYPE_STRING:
22626f3cdf0SGordon Ross case ACPI_TYPE_BUFFER:
22726f3cdf0SGordon Ross
22826f3cdf0SGordon Ross /*
22926f3cdf0SGordon Ross * These types we will allow, but we will change the type.
23026f3cdf0SGordon Ross * This enables some existing code of the form:
23126f3cdf0SGordon Ross *
23226f3cdf0SGordon Ross * Name (DEB, 0)
23326f3cdf0SGordon Ross * Scope (DEB) { ... }
23426f3cdf0SGordon Ross */
23526f3cdf0SGordon Ross ACPI_WARNING ((AE_INFO,
23626f3cdf0SGordon Ross "Type override - [%4.4s] had invalid type (%s) "
237*385cc6b4SJerry Jelinek "for Scope operator, changed to type ANY",
23826f3cdf0SGordon Ross AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type)));
23926f3cdf0SGordon Ross
24026f3cdf0SGordon Ross Node->Type = ACPI_TYPE_ANY;
24126f3cdf0SGordon Ross WalkState->ScopeInfo->Common.Value = ACPI_TYPE_ANY;
24226f3cdf0SGordon Ross break;
24326f3cdf0SGordon Ross
244*385cc6b4SJerry Jelinek case ACPI_TYPE_METHOD:
245*385cc6b4SJerry Jelinek
246*385cc6b4SJerry Jelinek /*
247*385cc6b4SJerry Jelinek * Allow scope change to root during execution of module-level
248*385cc6b4SJerry Jelinek * code. Root is typed METHOD during this time.
249*385cc6b4SJerry Jelinek */
250*385cc6b4SJerry Jelinek if ((Node == AcpiGbl_RootNode) &&
251*385cc6b4SJerry Jelinek (WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL))
252*385cc6b4SJerry Jelinek {
253*385cc6b4SJerry Jelinek break;
254*385cc6b4SJerry Jelinek }
255*385cc6b4SJerry Jelinek
256*385cc6b4SJerry Jelinek /*lint -fallthrough */
257*385cc6b4SJerry Jelinek
25826f3cdf0SGordon Ross default:
25926f3cdf0SGordon Ross
26026f3cdf0SGordon Ross /* All other types are an error */
26126f3cdf0SGordon Ross
26226f3cdf0SGordon Ross ACPI_ERROR ((AE_INFO,
26326f3cdf0SGordon Ross "Invalid type (%s) for target of "
26426f3cdf0SGordon Ross "Scope operator [%4.4s] (Cannot override)",
26526f3cdf0SGordon Ross AcpiUtGetTypeName (Node->Type), AcpiUtGetNodeName (Node)));
26626f3cdf0SGordon Ross
267*385cc6b4SJerry Jelinek return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
26826f3cdf0SGordon Ross }
26926f3cdf0SGordon Ross break;
27026f3cdf0SGordon Ross
27126f3cdf0SGordon Ross default:
27226f3cdf0SGordon Ross
27326f3cdf0SGordon Ross /* All other opcodes */
27426f3cdf0SGordon Ross
27526f3cdf0SGordon Ross if (Op && Op->Common.Node)
27626f3cdf0SGordon Ross {
27726f3cdf0SGordon Ross /* This op/node was previously entered into the namespace */
27826f3cdf0SGordon Ross
27926f3cdf0SGordon Ross Node = Op->Common.Node;
28026f3cdf0SGordon Ross
28126f3cdf0SGordon Ross if (AcpiNsOpensScope (ObjectType))
28226f3cdf0SGordon Ross {
28326f3cdf0SGordon Ross Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);
28426f3cdf0SGordon Ross if (ACPI_FAILURE (Status))
28526f3cdf0SGordon Ross {
28626f3cdf0SGordon Ross return_ACPI_STATUS (Status);
28726f3cdf0SGordon Ross }
28826f3cdf0SGordon Ross }
28926f3cdf0SGordon Ross
29026f3cdf0SGordon Ross return_ACPI_STATUS (AE_OK);
29126f3cdf0SGordon Ross }
29226f3cdf0SGordon Ross
29326f3cdf0SGordon Ross /*
29426f3cdf0SGordon Ross * Enter the named type into the internal namespace. We enter the name
29526f3cdf0SGordon Ross * as we go downward in the parse tree. Any necessary subobjects that
29626f3cdf0SGordon Ross * involve arguments to the opcode must be created as we go back up the
29726f3cdf0SGordon Ross * parse tree later.
29826f3cdf0SGordon Ross *
29926f3cdf0SGordon Ross * Note: Name may already exist if we are executing a deferred opcode.
30026f3cdf0SGordon Ross */
30126f3cdf0SGordon Ross if (WalkState->DeferredNode)
30226f3cdf0SGordon Ross {
30326f3cdf0SGordon Ross /* This name is already in the namespace, get the node */
30426f3cdf0SGordon Ross
30526f3cdf0SGordon Ross Node = WalkState->DeferredNode;
30626f3cdf0SGordon Ross Status = AE_OK;
30726f3cdf0SGordon Ross break;
30826f3cdf0SGordon Ross }
30926f3cdf0SGordon Ross
31026f3cdf0SGordon Ross Flags = ACPI_NS_NO_UPSEARCH;
31126f3cdf0SGordon Ross if (WalkState->PassNumber == ACPI_IMODE_EXECUTE)
31226f3cdf0SGordon Ross {
31326f3cdf0SGordon Ross /* Execution mode, node cannot already exist, node is temporary */
31426f3cdf0SGordon Ross
31526f3cdf0SGordon Ross Flags |= ACPI_NS_ERROR_IF_FOUND;
31626f3cdf0SGordon Ross
31726f3cdf0SGordon Ross if (!(WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL))
31826f3cdf0SGordon Ross {
31926f3cdf0SGordon Ross Flags |= ACPI_NS_TEMPORARY;
32026f3cdf0SGordon Ross }
32126f3cdf0SGordon Ross }
32226f3cdf0SGordon Ross
32326f3cdf0SGordon Ross /* Add new entry or lookup existing entry */
32426f3cdf0SGordon Ross
32526f3cdf0SGordon Ross Status = AcpiNsLookup (WalkState->ScopeInfo, BufferPtr, ObjectType,
32626f3cdf0SGordon Ross ACPI_IMODE_LOAD_PASS2, Flags, WalkState, &Node);
32726f3cdf0SGordon Ross
32826f3cdf0SGordon Ross if (ACPI_SUCCESS (Status) && (Flags & ACPI_NS_TEMPORARY))
32926f3cdf0SGordon Ross {
33026f3cdf0SGordon Ross ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
33126f3cdf0SGordon Ross "***New Node [%4.4s] %p is temporary\n",
33226f3cdf0SGordon Ross AcpiUtGetNodeName (Node), Node));
33326f3cdf0SGordon Ross }
33426f3cdf0SGordon Ross break;
33526f3cdf0SGordon Ross }
33626f3cdf0SGordon Ross
33726f3cdf0SGordon Ross if (ACPI_FAILURE (Status))
33826f3cdf0SGordon Ross {
33926f3cdf0SGordon Ross ACPI_ERROR_NAMESPACE (BufferPtr, Status);
34026f3cdf0SGordon Ross return_ACPI_STATUS (Status);
34126f3cdf0SGordon Ross }
34226f3cdf0SGordon Ross
34326f3cdf0SGordon Ross if (!Op)
34426f3cdf0SGordon Ross {
34526f3cdf0SGordon Ross /* Create a new op */
34626f3cdf0SGordon Ross
347*385cc6b4SJerry Jelinek Op = AcpiPsAllocOp (WalkState->Opcode, WalkState->Aml);
34826f3cdf0SGordon Ross if (!Op)
34926f3cdf0SGordon Ross {
35026f3cdf0SGordon Ross return_ACPI_STATUS (AE_NO_MEMORY);
35126f3cdf0SGordon Ross }
35226f3cdf0SGordon Ross
35326f3cdf0SGordon Ross /* Initialize the new op */
35426f3cdf0SGordon Ross
35526f3cdf0SGordon Ross if (Node)
35626f3cdf0SGordon Ross {
35726f3cdf0SGordon Ross Op->Named.Name = Node->Name.Integer;
35826f3cdf0SGordon Ross }
35926f3cdf0SGordon Ross *OutOp = Op;
36026f3cdf0SGordon Ross }
36126f3cdf0SGordon Ross
36226f3cdf0SGordon Ross /*
36326f3cdf0SGordon Ross * Put the Node in the "op" object that the parser uses, so we
36426f3cdf0SGordon Ross * can get it again quickly when this scope is closed
36526f3cdf0SGordon Ross */
36626f3cdf0SGordon Ross Op->Common.Node = Node;
36726f3cdf0SGordon Ross return_ACPI_STATUS (Status);
36826f3cdf0SGordon Ross }
36926f3cdf0SGordon Ross
37026f3cdf0SGordon Ross
37126f3cdf0SGordon Ross /*******************************************************************************
37226f3cdf0SGordon Ross *
37326f3cdf0SGordon Ross * FUNCTION: AcpiDsLoad2EndOp
37426f3cdf0SGordon Ross *
37526f3cdf0SGordon Ross * PARAMETERS: WalkState - Current state of the parse tree walk
37626f3cdf0SGordon Ross *
37726f3cdf0SGordon Ross * RETURN: Status
37826f3cdf0SGordon Ross *
37926f3cdf0SGordon Ross * DESCRIPTION: Ascending callback used during the loading of the namespace,
38026f3cdf0SGordon Ross * both control methods and everything else.
38126f3cdf0SGordon Ross *
38226f3cdf0SGordon Ross ******************************************************************************/
38326f3cdf0SGordon Ross
38426f3cdf0SGordon Ross ACPI_STATUS
AcpiDsLoad2EndOp(ACPI_WALK_STATE * WalkState)38526f3cdf0SGordon Ross AcpiDsLoad2EndOp (
38626f3cdf0SGordon Ross ACPI_WALK_STATE *WalkState)
38726f3cdf0SGordon Ross {
38826f3cdf0SGordon Ross ACPI_PARSE_OBJECT *Op;
38926f3cdf0SGordon Ross ACPI_STATUS Status = AE_OK;
39026f3cdf0SGordon Ross ACPI_OBJECT_TYPE ObjectType;
39126f3cdf0SGordon Ross ACPI_NAMESPACE_NODE *Node;
39226f3cdf0SGordon Ross ACPI_PARSE_OBJECT *Arg;
39326f3cdf0SGordon Ross ACPI_NAMESPACE_NODE *NewNode;
39426f3cdf0SGordon Ross #ifndef ACPI_NO_METHOD_EXECUTION
39526f3cdf0SGordon Ross UINT32 i;
39626f3cdf0SGordon Ross UINT8 RegionSpace;
39726f3cdf0SGordon Ross #endif
39826f3cdf0SGordon Ross
39926f3cdf0SGordon Ross
40026f3cdf0SGordon Ross ACPI_FUNCTION_TRACE (DsLoad2EndOp);
40126f3cdf0SGordon Ross
40226f3cdf0SGordon Ross Op = WalkState->Op;
40326f3cdf0SGordon Ross ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Opcode [%s] Op %p State %p\n",
40426f3cdf0SGordon Ross WalkState->OpInfo->Name, Op, WalkState));
40526f3cdf0SGordon Ross
40626f3cdf0SGordon Ross /* Check if opcode had an associated namespace object */
40726f3cdf0SGordon Ross
40826f3cdf0SGordon Ross if (!(WalkState->OpInfo->Flags & AML_NSOBJECT))
40926f3cdf0SGordon Ross {
41026f3cdf0SGordon Ross return_ACPI_STATUS (AE_OK);
41126f3cdf0SGordon Ross }
41226f3cdf0SGordon Ross
41326f3cdf0SGordon Ross if (Op->Common.AmlOpcode == AML_SCOPE_OP)
41426f3cdf0SGordon Ross {
41526f3cdf0SGordon Ross ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
41626f3cdf0SGordon Ross "Ending scope Op=%p State=%p\n", Op, WalkState));
41726f3cdf0SGordon Ross }
41826f3cdf0SGordon Ross
41926f3cdf0SGordon Ross ObjectType = WalkState->OpInfo->ObjectType;
42026f3cdf0SGordon Ross
42126f3cdf0SGordon Ross /*
42226f3cdf0SGordon Ross * Get the Node/name from the earlier lookup
42326f3cdf0SGordon Ross * (It was saved in the *op structure)
42426f3cdf0SGordon Ross */
42526f3cdf0SGordon Ross Node = Op->Common.Node;
42626f3cdf0SGordon Ross
42726f3cdf0SGordon Ross /*
42826f3cdf0SGordon Ross * Put the Node on the object stack (Contains the ACPI Name of
42926f3cdf0SGordon Ross * this object)
43026f3cdf0SGordon Ross */
43126f3cdf0SGordon Ross WalkState->Operands[0] = (void *) Node;
43226f3cdf0SGordon Ross WalkState->NumOperands = 1;
43326f3cdf0SGordon Ross
43426f3cdf0SGordon Ross /* Pop the scope stack */
43526f3cdf0SGordon Ross
43626f3cdf0SGordon Ross if (AcpiNsOpensScope (ObjectType) &&
43726f3cdf0SGordon Ross (Op->Common.AmlOpcode != AML_INT_METHODCALL_OP))
43826f3cdf0SGordon Ross {
43926f3cdf0SGordon Ross ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "(%s) Popping scope for Op %p\n",
44026f3cdf0SGordon Ross AcpiUtGetTypeName (ObjectType), Op));
44126f3cdf0SGordon Ross
44226f3cdf0SGordon Ross Status = AcpiDsScopeStackPop (WalkState);
44326f3cdf0SGordon Ross if (ACPI_FAILURE (Status))
44426f3cdf0SGordon Ross {
44526f3cdf0SGordon Ross goto Cleanup;
44626f3cdf0SGordon Ross }
44726f3cdf0SGordon Ross }
44826f3cdf0SGordon Ross
44926f3cdf0SGordon Ross /*
45026f3cdf0SGordon Ross * Named operations are as follows:
45126f3cdf0SGordon Ross *
45226f3cdf0SGordon Ross * AML_ALIAS
45326f3cdf0SGordon Ross * AML_BANKFIELD
45426f3cdf0SGordon Ross * AML_CREATEBITFIELD
45526f3cdf0SGordon Ross * AML_CREATEBYTEFIELD
45626f3cdf0SGordon Ross * AML_CREATEDWORDFIELD
45726f3cdf0SGordon Ross * AML_CREATEFIELD
45826f3cdf0SGordon Ross * AML_CREATEQWORDFIELD
45926f3cdf0SGordon Ross * AML_CREATEWORDFIELD
46026f3cdf0SGordon Ross * AML_DATA_REGION
46126f3cdf0SGordon Ross * AML_DEVICE
46226f3cdf0SGordon Ross * AML_EVENT
46326f3cdf0SGordon Ross * AML_FIELD
46426f3cdf0SGordon Ross * AML_INDEXFIELD
46526f3cdf0SGordon Ross * AML_METHOD
46626f3cdf0SGordon Ross * AML_METHODCALL
46726f3cdf0SGordon Ross * AML_MUTEX
46826f3cdf0SGordon Ross * AML_NAME
46926f3cdf0SGordon Ross * AML_NAMEDFIELD
47026f3cdf0SGordon Ross * AML_OPREGION
47126f3cdf0SGordon Ross * AML_POWERRES
47226f3cdf0SGordon Ross * AML_PROCESSOR
47326f3cdf0SGordon Ross * AML_SCOPE
47426f3cdf0SGordon Ross * AML_THERMALZONE
47526f3cdf0SGordon Ross */
47626f3cdf0SGordon Ross
47726f3cdf0SGordon Ross ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
47826f3cdf0SGordon Ross "Create-Load [%s] State=%p Op=%p NamedObj=%p\n",
47926f3cdf0SGordon Ross AcpiPsGetOpcodeName (Op->Common.AmlOpcode), WalkState, Op, Node));
48026f3cdf0SGordon Ross
48126f3cdf0SGordon Ross /* Decode the opcode */
48226f3cdf0SGordon Ross
48326f3cdf0SGordon Ross Arg = Op->Common.Value.Arg;
48426f3cdf0SGordon Ross
48526f3cdf0SGordon Ross switch (WalkState->OpInfo->Type)
48626f3cdf0SGordon Ross {
48726f3cdf0SGordon Ross #ifndef ACPI_NO_METHOD_EXECUTION
48826f3cdf0SGordon Ross
48926f3cdf0SGordon Ross case AML_TYPE_CREATE_FIELD:
49026f3cdf0SGordon Ross /*
49126f3cdf0SGordon Ross * Create the field object, but the field buffer and index must
49226f3cdf0SGordon Ross * be evaluated later during the execution phase
49326f3cdf0SGordon Ross */
49426f3cdf0SGordon Ross Status = AcpiDsCreateBufferField (Op, WalkState);
49526f3cdf0SGordon Ross break;
49626f3cdf0SGordon Ross
49726f3cdf0SGordon Ross case AML_TYPE_NAMED_FIELD:
49826f3cdf0SGordon Ross /*
49926f3cdf0SGordon Ross * If we are executing a method, initialize the field
50026f3cdf0SGordon Ross */
50126f3cdf0SGordon Ross if (WalkState->MethodNode)
50226f3cdf0SGordon Ross {
50326f3cdf0SGordon Ross Status = AcpiDsInitFieldObjects (Op, WalkState);
50426f3cdf0SGordon Ross }
50526f3cdf0SGordon Ross
50626f3cdf0SGordon Ross switch (Op->Common.AmlOpcode)
50726f3cdf0SGordon Ross {
50826f3cdf0SGordon Ross case AML_INDEX_FIELD_OP:
50926f3cdf0SGordon Ross
510*385cc6b4SJerry Jelinek Status = AcpiDsCreateIndexField (
511*385cc6b4SJerry Jelinek Op, (ACPI_HANDLE) Arg->Common.Node, WalkState);
51226f3cdf0SGordon Ross break;
51326f3cdf0SGordon Ross
51426f3cdf0SGordon Ross case AML_BANK_FIELD_OP:
51526f3cdf0SGordon Ross
51626f3cdf0SGordon Ross Status = AcpiDsCreateBankField (Op, Arg->Common.Node, WalkState);
51726f3cdf0SGordon Ross break;
51826f3cdf0SGordon Ross
51926f3cdf0SGordon Ross case AML_FIELD_OP:
52026f3cdf0SGordon Ross
52126f3cdf0SGordon Ross Status = AcpiDsCreateField (Op, Arg->Common.Node, WalkState);
52226f3cdf0SGordon Ross break;
52326f3cdf0SGordon Ross
52426f3cdf0SGordon Ross default:
525*385cc6b4SJerry Jelinek
52626f3cdf0SGordon Ross /* All NAMED_FIELD opcodes must be handled above */
52726f3cdf0SGordon Ross break;
52826f3cdf0SGordon Ross }
52926f3cdf0SGordon Ross break;
53026f3cdf0SGordon Ross
53126f3cdf0SGordon Ross case AML_TYPE_NAMED_SIMPLE:
53226f3cdf0SGordon Ross
53326f3cdf0SGordon Ross Status = AcpiDsCreateOperands (WalkState, Arg);
53426f3cdf0SGordon Ross if (ACPI_FAILURE (Status))
53526f3cdf0SGordon Ross {
53626f3cdf0SGordon Ross goto Cleanup;
53726f3cdf0SGordon Ross }
53826f3cdf0SGordon Ross
53926f3cdf0SGordon Ross switch (Op->Common.AmlOpcode)
54026f3cdf0SGordon Ross {
54126f3cdf0SGordon Ross case AML_PROCESSOR_OP:
54226f3cdf0SGordon Ross
54326f3cdf0SGordon Ross Status = AcpiExCreateProcessor (WalkState);
54426f3cdf0SGordon Ross break;
54526f3cdf0SGordon Ross
54626f3cdf0SGordon Ross case AML_POWER_RES_OP:
54726f3cdf0SGordon Ross
54826f3cdf0SGordon Ross Status = AcpiExCreatePowerResource (WalkState);
54926f3cdf0SGordon Ross break;
55026f3cdf0SGordon Ross
55126f3cdf0SGordon Ross case AML_MUTEX_OP:
55226f3cdf0SGordon Ross
55326f3cdf0SGordon Ross Status = AcpiExCreateMutex (WalkState);
55426f3cdf0SGordon Ross break;
55526f3cdf0SGordon Ross
55626f3cdf0SGordon Ross case AML_EVENT_OP:
55726f3cdf0SGordon Ross
55826f3cdf0SGordon Ross Status = AcpiExCreateEvent (WalkState);
55926f3cdf0SGordon Ross break;
56026f3cdf0SGordon Ross
56126f3cdf0SGordon Ross case AML_ALIAS_OP:
56226f3cdf0SGordon Ross
56326f3cdf0SGordon Ross Status = AcpiExCreateAlias (WalkState);
56426f3cdf0SGordon Ross break;
56526f3cdf0SGordon Ross
56626f3cdf0SGordon Ross default:
567*385cc6b4SJerry Jelinek
56826f3cdf0SGordon Ross /* Unknown opcode */
56926f3cdf0SGordon Ross
57026f3cdf0SGordon Ross Status = AE_OK;
57126f3cdf0SGordon Ross goto Cleanup;
57226f3cdf0SGordon Ross }
57326f3cdf0SGordon Ross
57426f3cdf0SGordon Ross /* Delete operands */
57526f3cdf0SGordon Ross
57626f3cdf0SGordon Ross for (i = 1; i < WalkState->NumOperands; i++)
57726f3cdf0SGordon Ross {
57826f3cdf0SGordon Ross AcpiUtRemoveReference (WalkState->Operands[i]);
57926f3cdf0SGordon Ross WalkState->Operands[i] = NULL;
58026f3cdf0SGordon Ross }
58126f3cdf0SGordon Ross
58226f3cdf0SGordon Ross break;
58326f3cdf0SGordon Ross #endif /* ACPI_NO_METHOD_EXECUTION */
58426f3cdf0SGordon Ross
58526f3cdf0SGordon Ross case AML_TYPE_NAMED_COMPLEX:
58626f3cdf0SGordon Ross
58726f3cdf0SGordon Ross switch (Op->Common.AmlOpcode)
58826f3cdf0SGordon Ross {
58926f3cdf0SGordon Ross #ifndef ACPI_NO_METHOD_EXECUTION
59026f3cdf0SGordon Ross case AML_REGION_OP:
59126f3cdf0SGordon Ross case AML_DATA_REGION_OP:
59226f3cdf0SGordon Ross
59326f3cdf0SGordon Ross if (Op->Common.AmlOpcode == AML_REGION_OP)
59426f3cdf0SGordon Ross {
59526f3cdf0SGordon Ross RegionSpace = (ACPI_ADR_SPACE_TYPE)
59626f3cdf0SGordon Ross ((Op->Common.Value.Arg)->Common.Value.Integer);
59726f3cdf0SGordon Ross }
59826f3cdf0SGordon Ross else
59926f3cdf0SGordon Ross {
60026f3cdf0SGordon Ross RegionSpace = ACPI_ADR_SPACE_DATA_TABLE;
60126f3cdf0SGordon Ross }
60226f3cdf0SGordon Ross
60326f3cdf0SGordon Ross /*
60426f3cdf0SGordon Ross * The OpRegion is not fully parsed at this time. The only valid
60526f3cdf0SGordon Ross * argument is the SpaceId. (We must save the address of the
60626f3cdf0SGordon Ross * AML of the address and length operands)
60726f3cdf0SGordon Ross *
60826f3cdf0SGordon Ross * If we have a valid region, initialize it. The namespace is
60926f3cdf0SGordon Ross * unlocked at this point.
61026f3cdf0SGordon Ross *
61126f3cdf0SGordon Ross * Need to unlock interpreter if it is locked (if we are running
61226f3cdf0SGordon Ross * a control method), in order to allow _REG methods to be run
61326f3cdf0SGordon Ross * during AcpiEvInitializeRegion.
61426f3cdf0SGordon Ross */
61526f3cdf0SGordon Ross if (WalkState->MethodNode)
61626f3cdf0SGordon Ross {
61726f3cdf0SGordon Ross /*
61826f3cdf0SGordon Ross * Executing a method: initialize the region and unlock
61926f3cdf0SGordon Ross * the interpreter
62026f3cdf0SGordon Ross */
621*385cc6b4SJerry Jelinek Status = AcpiExCreateRegion (Op->Named.Data,
622*385cc6b4SJerry Jelinek Op->Named.Length, RegionSpace, WalkState);
62326f3cdf0SGordon Ross if (ACPI_FAILURE (Status))
62426f3cdf0SGordon Ross {
625*385cc6b4SJerry Jelinek return_ACPI_STATUS (Status);
62626f3cdf0SGordon Ross }
62726f3cdf0SGordon Ross
62826f3cdf0SGordon Ross AcpiExExitInterpreter ();
62926f3cdf0SGordon Ross }
63026f3cdf0SGordon Ross
631*385cc6b4SJerry Jelinek Status = AcpiEvInitializeRegion (
632*385cc6b4SJerry Jelinek AcpiNsGetAttachedObject (Node), FALSE);
63326f3cdf0SGordon Ross if (WalkState->MethodNode)
63426f3cdf0SGordon Ross {
63526f3cdf0SGordon Ross AcpiExEnterInterpreter ();
63626f3cdf0SGordon Ross }
63726f3cdf0SGordon Ross
63826f3cdf0SGordon Ross if (ACPI_FAILURE (Status))
63926f3cdf0SGordon Ross {
64026f3cdf0SGordon Ross /*
64126f3cdf0SGordon Ross * If AE_NOT_EXIST is returned, it is not fatal
64226f3cdf0SGordon Ross * because many regions get created before a handler
64326f3cdf0SGordon Ross * is installed for said region.
64426f3cdf0SGordon Ross */
64526f3cdf0SGordon Ross if (AE_NOT_EXIST == Status)
64626f3cdf0SGordon Ross {
64726f3cdf0SGordon Ross Status = AE_OK;
64826f3cdf0SGordon Ross }
64926f3cdf0SGordon Ross }
65026f3cdf0SGordon Ross break;
65126f3cdf0SGordon Ross
65226f3cdf0SGordon Ross case AML_NAME_OP:
65326f3cdf0SGordon Ross
65426f3cdf0SGordon Ross Status = AcpiDsCreateNode (WalkState, Node, Op);
65526f3cdf0SGordon Ross break;
65626f3cdf0SGordon Ross
65726f3cdf0SGordon Ross case AML_METHOD_OP:
65826f3cdf0SGordon Ross /*
65926f3cdf0SGordon Ross * MethodOp PkgLength NameString MethodFlags TermList
66026f3cdf0SGordon Ross *
66126f3cdf0SGordon Ross * Note: We must create the method node/object pair as soon as we
66226f3cdf0SGordon Ross * see the method declaration. This allows later pass1 parsing
66326f3cdf0SGordon Ross * of invocations of the method (need to know the number of
66426f3cdf0SGordon Ross * arguments.)
66526f3cdf0SGordon Ross */
66626f3cdf0SGordon Ross ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
66726f3cdf0SGordon Ross "LOADING-Method: State=%p Op=%p NamedObj=%p\n",
66826f3cdf0SGordon Ross WalkState, Op, Op->Named.Node));
66926f3cdf0SGordon Ross
67026f3cdf0SGordon Ross if (!AcpiNsGetAttachedObject (Op->Named.Node))
67126f3cdf0SGordon Ross {
67226f3cdf0SGordon Ross WalkState->Operands[0] = ACPI_CAST_PTR (void, Op->Named.Node);
67326f3cdf0SGordon Ross WalkState->NumOperands = 1;
67426f3cdf0SGordon Ross
675*385cc6b4SJerry Jelinek Status = AcpiDsCreateOperands (
676*385cc6b4SJerry Jelinek WalkState, Op->Common.Value.Arg);
67726f3cdf0SGordon Ross if (ACPI_SUCCESS (Status))
67826f3cdf0SGordon Ross {
679*385cc6b4SJerry Jelinek Status = AcpiExCreateMethod (
680*385cc6b4SJerry Jelinek Op->Named.Data, Op->Named.Length, WalkState);
68126f3cdf0SGordon Ross }
682*385cc6b4SJerry Jelinek
68326f3cdf0SGordon Ross WalkState->Operands[0] = NULL;
68426f3cdf0SGordon Ross WalkState->NumOperands = 0;
68526f3cdf0SGordon Ross
68626f3cdf0SGordon Ross if (ACPI_FAILURE (Status))
68726f3cdf0SGordon Ross {
68826f3cdf0SGordon Ross return_ACPI_STATUS (Status);
68926f3cdf0SGordon Ross }
69026f3cdf0SGordon Ross }
69126f3cdf0SGordon Ross break;
69226f3cdf0SGordon Ross
69326f3cdf0SGordon Ross #endif /* ACPI_NO_METHOD_EXECUTION */
69426f3cdf0SGordon Ross
69526f3cdf0SGordon Ross default:
696*385cc6b4SJerry Jelinek
69726f3cdf0SGordon Ross /* All NAMED_COMPLEX opcodes must be handled above */
69826f3cdf0SGordon Ross break;
69926f3cdf0SGordon Ross }
70026f3cdf0SGordon Ross break;
70126f3cdf0SGordon Ross
70226f3cdf0SGordon Ross case AML_CLASS_INTERNAL:
70326f3cdf0SGordon Ross
70426f3cdf0SGordon Ross /* case AML_INT_NAMEPATH_OP: */
70526f3cdf0SGordon Ross break;
70626f3cdf0SGordon Ross
70726f3cdf0SGordon Ross case AML_CLASS_METHOD_CALL:
70826f3cdf0SGordon Ross
70926f3cdf0SGordon Ross ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
71026f3cdf0SGordon Ross "RESOLVING-MethodCall: State=%p Op=%p NamedObj=%p\n",
71126f3cdf0SGordon Ross WalkState, Op, Node));
71226f3cdf0SGordon Ross
71326f3cdf0SGordon Ross /*
71426f3cdf0SGordon Ross * Lookup the method name and save the Node
71526f3cdf0SGordon Ross */
71626f3cdf0SGordon Ross Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Common.Value.String,
71726f3cdf0SGordon Ross ACPI_TYPE_ANY, ACPI_IMODE_LOAD_PASS2,
71826f3cdf0SGordon Ross ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
71926f3cdf0SGordon Ross WalkState, &(NewNode));
72026f3cdf0SGordon Ross if (ACPI_SUCCESS (Status))
72126f3cdf0SGordon Ross {
72226f3cdf0SGordon Ross /*
72326f3cdf0SGordon Ross * Make sure that what we found is indeed a method
72426f3cdf0SGordon Ross * We didn't search for a method on purpose, to see if the name
72526f3cdf0SGordon Ross * would resolve
72626f3cdf0SGordon Ross */
72726f3cdf0SGordon Ross if (NewNode->Type != ACPI_TYPE_METHOD)
72826f3cdf0SGordon Ross {
72926f3cdf0SGordon Ross Status = AE_AML_OPERAND_TYPE;
73026f3cdf0SGordon Ross }
73126f3cdf0SGordon Ross
73226f3cdf0SGordon Ross /* We could put the returned object (Node) on the object stack for
73326f3cdf0SGordon Ross * later, but for now, we will put it in the "op" object that the
73426f3cdf0SGordon Ross * parser uses, so we can get it again at the end of this scope
73526f3cdf0SGordon Ross */
73626f3cdf0SGordon Ross Op->Common.Node = NewNode;
73726f3cdf0SGordon Ross }
73826f3cdf0SGordon Ross else
73926f3cdf0SGordon Ross {
74026f3cdf0SGordon Ross ACPI_ERROR_NAMESPACE (Arg->Common.Value.String, Status);
74126f3cdf0SGordon Ross }
74226f3cdf0SGordon Ross break;
74326f3cdf0SGordon Ross
74426f3cdf0SGordon Ross
74526f3cdf0SGordon Ross default:
746*385cc6b4SJerry Jelinek
74726f3cdf0SGordon Ross break;
74826f3cdf0SGordon Ross }
74926f3cdf0SGordon Ross
75026f3cdf0SGordon Ross Cleanup:
75126f3cdf0SGordon Ross
75226f3cdf0SGordon Ross /* Remove the Node pushed at the very beginning */
75326f3cdf0SGordon Ross
75426f3cdf0SGordon Ross WalkState->Operands[0] = NULL;
75526f3cdf0SGordon Ross WalkState->NumOperands = 0;
75626f3cdf0SGordon Ross return_ACPI_STATUS (Status);
75726f3cdf0SGordon Ross }
758