static ACPI_STATUS LdNamespace1Begin ( ACPI_PARSE_OBJECT *Op, UINT32 Level, void *Context) { ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; ACPI_NAMESPACE_NODE *Node; ACPI_PARSE_OBJECT *MethodOp; ACPI_STATUS Status; ACPI_OBJECT_TYPE ObjectType; ACPI_OBJECT_TYPE ActualObjectType = ACPI_TYPE_ANY; char *Path; UINT32 Flags = ACPI_NS_NO_UPSEARCH; ACPI_PARSE_OBJECT *Arg; UINT32 i; BOOLEAN ForceNewScope = FALSE; const ACPI_OPCODE_INFO *OpInfo; ACPI_PARSE_OBJECT *ParentOp; ACPI_FUNCTION_NAME (LdNamespace1Begin); ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n", Op, Op->Asl.ParseOpName)); /* * We are only interested in opcodes that have an associated name * (or multiple names) */ switch (Op->Asl.AmlOpcode) { case AML_BANK_FIELD_OP: case AML_INDEX_FIELD_OP: case AML_FIELD_OP: Status = LdLoadFieldElements (Op, WalkState); return (Status); case AML_INT_CONNECTION_OP: if (Op->Asl.Child->Asl.AmlOpcode != AML_INT_NAMEPATH_OP) { break; } Arg = Op->Asl.Child; Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Asl.ExternalName, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, WalkState, &Node); if (ACPI_FAILURE (Status)) { break; } if (Node->Type == ACPI_TYPE_BUFFER) { Arg->Asl.Node = Node; Arg = Node->Op->Asl.Child; /* Get namepath */ Arg = Arg->Asl.Next; /* Get actual buffer */ Arg = Arg->Asl.Child; /* Buffer length */ Arg = Arg->Asl.Next; /* RAW_DATA buffer */ } break; default: /* All other opcodes go below */ break; } /* Check if this object has already been installed in the namespace */ if (Op->Asl.Node) { return (AE_OK); } /* Check for a possible illegal forward reference */ if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) || (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING)) { /* * Op->Asl.Namepath will be NULL for these opcodes. * These opcodes are guaranteed to have a parent. * Examine the parent opcode. */ Status = AE_OK; ParentOp = Op->Asl.Parent; OpInfo = AcpiPsGetOpcodeInfo (ParentOp->Asl.AmlOpcode); /* * Exclude all operators that actually declare a new name: * Name (ABCD, 1) -> Ignore (AML_CLASS_NAMED_OBJECT) * We only want references to named objects: * Store (2, WXYZ) -> Attempt to resolve the name */ if (OpInfo->Class == AML_CLASS_NAMED_OBJECT) { return (AE_OK); } /* * Check if the referenced object exists at this point during * the load: * 1) If it exists, then this cannot be a forward reference. * 2) If it does not exist, it could be a forward reference or * it truly does not exist (and no external declaration). */ Status = AcpiNsLookup (WalkState->ScopeInfo, Op->Asl.Value.Name, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, WalkState, &Node); if (Status == AE_NOT_FOUND) { /* * This is either a foward reference or the object truly * does not exist. The two cases can only be differentiated * during the cross-reference stage later. Mark the Op/Name * as not-found for now to indicate the need for further * processing. * * Special case: Allow forward references from elements of * Package objects. This provides compatibility with other * ACPI implementations. To correctly implement this, the * ACPICA table load defers package resolution until the entire * namespace has been loaded. */ if ((ParentOp->Asl.ParseOpcode != PARSEOP_PACKAGE) && (ParentOp->Asl.ParseOpcode != PARSEOP_VAR_PACKAGE)) { Op->Asl.CompileFlags |= OP_NOT_FOUND_DURING_LOAD; } return (AE_OK); } return (Status); } Path = Op->Asl.Namepath; if (!Path) { return (AE_OK); } /* Map the raw opcode into an internal object type */ switch (Op->Asl.ParseOpcode) { case PARSEOP_NAME: Arg = Op->Asl.Child; /* Get the NameSeg/NameString node */ Arg = Arg->Asl.Next; /* First peer is the object to be associated with the name */ /* * If this name refers to a ResourceTemplate, we will need to open * a new scope so that the resource subfield names can be entered into * the namespace underneath this name */ if (Op->Asl.CompileFlags & OP_IS_RESOURCE_DESC) { ForceNewScope = TRUE; } /* Get the data type associated with the named object, not the name itself */ /* Log2 loop to convert from Btype (binary) to Etype (encoded) */ ObjectType = 1; for (i = 1; i < Arg->Asl.AcpiBtype; i *= 2) { ObjectType++; } break; case PARSEOP_EXTERNAL: /* * "External" simply enters a name and type into the namespace. * We must be careful to not open a new scope, however, no matter * what type the external name refers to (e.g., a method) * * first child is name, next child is ObjectType */ ActualObjectType = (UINT8) Op->Asl.Child->Asl.Next->Asl.Value.Integer; ObjectType = ACPI_TYPE_ANY; /* * We will mark every new node along the path as "External". This * allows some or all of the nodes to be created later in the ASL * code. Handles cases like this: * * External (\_SB_.PCI0.ABCD, IntObj) * Scope (_SB_) * { * Device (PCI0) * { * } * } * Method (X) * { * Store (\_SB_.PCI0.ABCD, Local0) * } */ Flags |= ACPI_NS_EXTERNAL; break; case PARSEOP_DEFAULT_ARG: if (Op->Asl.CompileFlags == OP_IS_RESOURCE_DESC) { Status = LdLoadResourceElements (Op, WalkState); return_ACPI_STATUS (Status); } ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); break; case PARSEOP_SCOPE: /* * The name referenced by Scope(Name) must already exist at this point. * In other words, forward references for Scope() are not supported. * The only real reason for this is that the MS interpreter cannot * handle this case. Perhaps someday this case can go away. */ Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, WalkState, &(Node)); if (ACPI_FAILURE (Status)) { if (Status == AE_NOT_FOUND) { /* The name was not found, go ahead and create it */ Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_LOCAL_SCOPE, ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &(Node)); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } /* * However, this is an error -- primarily because the MS * interpreter can't handle a forward reference from the * Scope() operator. */ AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op, Op->Asl.ExternalName); AslError (ASL_ERROR, ASL_MSG_SCOPE_FWD_REF, Op, Op->Asl.ExternalName); goto FinishNode; } AslCoreSubsystemError (Op, Status, "Failure from namespace lookup", FALSE); return_ACPI_STATUS (Status); } else /* Status AE_OK */ { /* * Do not allow references to external scopes from the DSDT. * This is because the DSDT is always loaded first, and the * external reference cannot be resolved -- causing a runtime * error because Scope() must be resolved immediately. * 10/2015. */ if ((Node->Flags & ANOBJ_IS_EXTERNAL) && (ACPI_COMPARE_NAME (Gbl_TableSignature, "DSDT"))) { /* However, allowed if the reference is within a method */ MethodOp = Op->Asl.Parent; while (MethodOp && (MethodOp->Asl.ParseOpcode != PARSEOP_METHOD)) { MethodOp = MethodOp->Asl.Parent; } if (!MethodOp) { /* Not in a control method, error */ AslError (ASL_ERROR, ASL_MSG_CROSS_TABLE_SCOPE, Op, NULL); } } } /* We found a node with this name, now check the type */ switch (Node->Type) { case ACPI_TYPE_LOCAL_SCOPE: case ACPI_TYPE_DEVICE: case ACPI_TYPE_POWER: case ACPI_TYPE_PROCESSOR: case ACPI_TYPE_THERMAL: /* These are acceptable types - they all open a new scope */ break; case ACPI_TYPE_INTEGER: case ACPI_TYPE_STRING: case ACPI_TYPE_BUFFER: /* * These types we will allow, but we will change the type. * This enables some existing code of the form: * * Name (DEB, 0) * Scope (DEB) { ... } * * Which is used to workaround the fact that the MS interpreter * does not allow Scope() forward references. */ sprintf (MsgBuffer, "%s [%s], changing type to [Scope]", Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type)); AslError (ASL_REMARK, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer); /* Switch the type to scope, open the new scope */ Node->Type = ACPI_TYPE_LOCAL_SCOPE; Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE, WalkState); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } break; default: /* All other types are an error */ sprintf (MsgBuffer, "%s [%s]", Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type)); AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer); /* * However, switch the type to be an actual scope so * that compilation can continue without generating a whole * cascade of additional errors. Open the new scope. */ Node->Type = ACPI_TYPE_LOCAL_SCOPE; Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE, WalkState); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } break; } Status = AE_OK; goto FinishNode; default: ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); break; } ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Loading name: %s, (%s)\n", Op->Asl.ExternalName, AcpiUtGetTypeName (ObjectType))); /* The name must not already exist */ Flags |= ACPI_NS_ERROR_IF_FOUND; /* * Enter the named type into the internal namespace. We enter the name * as we go downward in the parse tree. Any necessary subobjects that * involve arguments to the opcode must be created as we go back up the * parse tree later. */ Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType, ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node); if (ACPI_FAILURE (Status)) { if (Status == AE_ALREADY_EXISTS) { /* The name already exists in this scope */ if (Node->Type == ACPI_TYPE_LOCAL_SCOPE) { /* Allow multiple references to the same scope */ Node->Type = (UINT8) ObjectType; Status = AE_OK; } else if ((Node->Flags & ANOBJ_IS_EXTERNAL) && (Op->Asl.ParseOpcode != PARSEOP_EXTERNAL)) { /* * Allow one create on an object or segment that was * previously declared External */ Node->Flags &= ~ANOBJ_IS_EXTERNAL; Node->Type = (UINT8) ObjectType; /* Just retyped a node, probably will need to open a scope */ if (AcpiNsOpensScope (ObjectType)) { Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } } Status = AE_OK; } else if (!(Node->Flags & ANOBJ_IS_EXTERNAL) && (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL)) { /* * Allow externals in same scope as the definition of the * actual object. Similar to C. Allows multiple definition * blocks that refer to each other in the same file. */ Status = AE_OK; } else if ((Node->Flags & ANOBJ_IS_EXTERNAL) && (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL) && (ObjectType == ACPI_TYPE_ANY)) { /* Allow update of externals of unknown type. */ if (AcpiNsOpensScope (ActualObjectType)) { Node->Type = (UINT8) ActualObjectType; Status = AE_OK; } else { sprintf (MsgBuffer, "%s [%s]", Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type)); AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer); return_ACPI_STATUS (AE_OK); } } else { /* Valid error, object already exists */ AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op, Op->Asl.ExternalName, ASL_MSG_FOUND_HERE, Node->Op, Node->Op->Asl.ExternalName); return_ACPI_STATUS (AE_OK); } } else { AslCoreSubsystemError (Op, Status, "Failure from namespace lookup", FALSE); return_ACPI_STATUS (Status); } } if (ForceNewScope) { Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } } FinishNode: /* * Point the parse node to the new namespace node, and point * the Node back to the original Parse node */ Op->Asl.Node = Node; Node->Op = Op; /* Set the actual data type if appropriate (EXTERNAL term only) */ if (ActualObjectType != ACPI_TYPE_ANY) { Node->Type = (UINT8) ActualObjectType; Node->Value = ASL_EXTERNAL_METHOD; } if (Op->Asl.ParseOpcode == PARSEOP_METHOD) { /* * Get the method argument count from "Extra" and save * it in the namespace node */ Node->Value = (UINT32) Op->Asl.Extra; } return_ACPI_STATUS (Status); }
static ACPI_STATUS LdNamespace1Begin ( ACPI_PARSE_OBJECT *Op, UINT32 Level, void *Context) { ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; ACPI_NAMESPACE_NODE *Node; ACPI_STATUS Status; ACPI_OBJECT_TYPE ObjectType; ACPI_OBJECT_TYPE ActualObjectType = ACPI_TYPE_ANY; char *Path; UINT32 Flags = ACPI_NS_NO_UPSEARCH; ACPI_PARSE_OBJECT *Arg; UINT32 i; BOOLEAN ForceNewScope = FALSE; ACPI_FUNCTION_NAME (LdNamespace1Begin); ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n", Op, Op->Asl.ParseOpName)); /* * We are only interested in opcodes that have an associated name * (or multiple names) */ switch (Op->Asl.AmlOpcode) { case AML_BANK_FIELD_OP: case AML_INDEX_FIELD_OP: case AML_FIELD_OP: Status = LdLoadFieldElements (Op, WalkState); return (Status); default: /* All other opcodes go below */ break; } /* Check if this object has already been installed in the namespace */ if (Op->Asl.Node) { return (AE_OK); } Path = Op->Asl.Namepath; if (!Path) { return (AE_OK); } /* Map the raw opcode into an internal object type */ switch (Op->Asl.ParseOpcode) { case PARSEOP_NAME: Arg = Op->Asl.Child; /* Get the NameSeg/NameString node */ Arg = Arg->Asl.Next; /* First peer is the object to be associated with the name */ /* * If this name refers to a ResourceTemplate, we will need to open * a new scope so that the resource subfield names can be entered into * the namespace underneath this name */ if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC) { ForceNewScope = TRUE; } /* Get the data type associated with the named object, not the name itself */ /* Log2 loop to convert from Btype (binary) to Etype (encoded) */ ObjectType = 1; for (i = 1; i < Arg->Asl.AcpiBtype; i *= 2) { ObjectType++; } break; case PARSEOP_EXTERNAL: /* * "External" simply enters a name and type into the namespace. * We must be careful to not open a new scope, however, no matter * what type the external name refers to (e.g., a method) * * first child is name, next child is ObjectType */ ActualObjectType = (UINT8) Op->Asl.Child->Asl.Next->Asl.Value.Integer; ObjectType = ACPI_TYPE_ANY; /* * We will mark every new node along the path as "External". This * allows some or all of the nodes to be created later in the ASL * code. Handles cases like this: * * External (\_SB_.PCI0.ABCD, IntObj) * Scope (_SB_) * { * Device (PCI0) * { * } * } * Method (X) * { * Store (\_SB_.PCI0.ABCD, Local0) * } */ Flags |= ACPI_NS_EXTERNAL; break; case PARSEOP_DEFAULT_ARG: if (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC) { Status = LdLoadResourceElements (Op, WalkState); return_ACPI_STATUS (Status); } ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); break; case PARSEOP_SCOPE: /* * The name referenced by Scope(Name) must already exist at this point. * In other words, forward references for Scope() are not supported. * The only real reason for this is that the MS interpreter cannot * handle this case. Perhaps someday this case can go away. */ Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, WalkState, &(Node)); if (ACPI_FAILURE (Status)) { if (Status == AE_NOT_FOUND) { /* The name was not found, go ahead and create it */ Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_LOCAL_SCOPE, ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &(Node)); /* * However, this is an error -- primarily because the MS * interpreter can't handle a forward reference from the * Scope() operator. */ AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op, Op->Asl.ExternalName); AslError (ASL_ERROR, ASL_MSG_SCOPE_FWD_REF, Op, Op->Asl.ExternalName); goto FinishNode; } AslCoreSubsystemError (Op, Status, "Failure from namespace lookup", FALSE); return_ACPI_STATUS (Status); } /* We found a node with this name, now check the type */ switch (Node->Type) { case ACPI_TYPE_LOCAL_SCOPE: case ACPI_TYPE_DEVICE: case ACPI_TYPE_POWER: case ACPI_TYPE_PROCESSOR: case ACPI_TYPE_THERMAL: /* These are acceptable types - they all open a new scope */ break; case ACPI_TYPE_INTEGER: case ACPI_TYPE_STRING: case ACPI_TYPE_BUFFER: /* * These types we will allow, but we will change the type. * This enables some existing code of the form: * * Name (DEB, 0) * Scope (DEB) { ... } * * Which is used to workaround the fact that the MS interpreter * does not allow Scope() forward references. */ sprintf (MsgBuffer, "%s [%s], changing type to [Scope]", Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type)); AslError (ASL_REMARK, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer); /* Switch the type to scope, open the new scope */ Node->Type = ACPI_TYPE_LOCAL_SCOPE; Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE, WalkState); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } break; default: /* All other types are an error */ sprintf (MsgBuffer, "%s [%s]", Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type)); AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer); /* * However, switch the type to be an actual scope so * that compilation can continue without generating a whole * cascade of additional errors. Open the new scope. */ Node->Type = ACPI_TYPE_LOCAL_SCOPE; Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE, WalkState); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } break; } Status = AE_OK; goto FinishNode; default: ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); break; } ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Loading name: %s, (%s)\n", Op->Asl.ExternalName, AcpiUtGetTypeName (ObjectType))); /* The name must not already exist */ Flags |= ACPI_NS_ERROR_IF_FOUND; /* * Enter the named type into the internal namespace. We enter the name * as we go downward in the parse tree. Any necessary subobjects that * involve arguments to the opcode must be created as we go back up the * parse tree later. */ Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType, ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node); if (ACPI_FAILURE (Status)) { if (Status == AE_ALREADY_EXISTS) { /* The name already exists in this scope */ if (Node->Type == ACPI_TYPE_LOCAL_SCOPE) { /* Allow multiple references to the same scope */ Node->Type = (UINT8) ObjectType; Status = AE_OK; } else if ((Node->Flags & ANOBJ_IS_EXTERNAL) && (Op->Asl.ParseOpcode != PARSEOP_EXTERNAL)) { /* * Allow one create on an object or segment that was * previously declared External */ Node->Flags &= ~ANOBJ_IS_EXTERNAL; Node->Type = (UINT8) ObjectType; /* Just retyped a node, probably will need to open a scope */ if (AcpiNsOpensScope (ObjectType)) { Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } } Status = AE_OK; } else { /* Valid error, object already exists */ AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op, Op->Asl.ExternalName); return_ACPI_STATUS (AE_OK); } } else { AslCoreSubsystemError (Op, Status, "Failure from namespace lookup", FALSE); return_ACPI_STATUS (Status); } } if (ForceNewScope) { Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } } FinishNode: /* * Point the parse node to the new namespace node, and point * the Node back to the original Parse node */ Op->Asl.Node = Node; Node->Op = Op; /* Set the actual data type if appropriate (EXTERNAL term only) */ if (ActualObjectType != ACPI_TYPE_ANY) { Node->Type = (UINT8) ActualObjectType; Node->Value = ASL_EXTERNAL_METHOD; } if (Op->Asl.ParseOpcode == PARSEOP_METHOD) { /* * Get the method argument count from "Extra" and save * it in the namespace node */ Node->Value = (UINT32) Op->Asl.Extra; } return_ACPI_STATUS (Status); }
static ACPI_STATUS LdNamespace1Begin ( ACPI_PARSE_OBJECT *Op, UINT32 Level, void *Context) { ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; ACPI_NAMESPACE_NODE *Node; ACPI_PARSE_OBJECT *MethodOp; ACPI_STATUS Status; ACPI_OBJECT_TYPE ObjectType; ACPI_OBJECT_TYPE ActualObjectType = ACPI_TYPE_ANY; char *Path; UINT32 Flags = ACPI_NS_NO_UPSEARCH; ACPI_PARSE_OBJECT *Arg; UINT32 i; BOOLEAN ForceNewScope = FALSE; ACPI_OWNER_ID OwnerId = 0; ACPI_FUNCTION_NAME (LdNamespace1Begin); ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n", Op, Op->Asl.ParseOpName)); if (Op->Asl.ParseOpcode == PARSEOP_DEFINITION_BLOCK) { /* * Allocate an OwnerId for this block. This helps identify the owners * of each namespace node. This is used in determining whether if * certain external declarations cause redefinition errors. */ Status = AcpiUtAllocateOwnerId (&OwnerId); WalkState->OwnerId = OwnerId; if (ACPI_FAILURE (Status)) { AslCoreSubsystemError (Op, Status, "Failure to allocate owner ID to this definition block.", FALSE); return_ACPI_STATUS (Status); } } /* * We are only interested in opcodes that have an associated name * (or multiple names) */ switch (Op->Asl.AmlOpcode) { case AML_BANK_FIELD_OP: case AML_INDEX_FIELD_OP: case AML_FIELD_OP: Status = LdLoadFieldElements (Op, WalkState); return (Status); case AML_INT_CONNECTION_OP: if (Op->Asl.Child->Asl.AmlOpcode != AML_INT_NAMEPATH_OP) { break; } Arg = Op->Asl.Child; Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Asl.ExternalName, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, WalkState, &Node); if (ACPI_FAILURE (Status)) { break; } if (Node->Type == ACPI_TYPE_BUFFER) { Arg->Asl.Node = Node; Arg = Node->Op->Asl.Child; /* Get namepath */ Arg = Arg->Asl.Next; /* Get actual buffer */ Arg = Arg->Asl.Child; /* Buffer length */ Arg = Arg->Asl.Next; /* RAW_DATA buffer */ } break; default: /* All other opcodes go below */ break; } /* Check if this object has already been installed in the namespace */ if (Op->Asl.Node) { return (AE_OK); } Path = Op->Asl.Namepath; if (!Path) { return (AE_OK); } /* Map the raw opcode into an internal object type */ switch (Op->Asl.ParseOpcode) { case PARSEOP_NAME: Arg = Op->Asl.Child; /* Get the NameSeg/NameString node */ Arg = Arg->Asl.Next; /* First peer is the object to be associated with the name */ /* * If this name refers to a ResourceTemplate, we will need to open * a new scope so that the resource subfield names can be entered into * the namespace underneath this name */ if (Op->Asl.CompileFlags & OP_IS_RESOURCE_DESC) { ForceNewScope = TRUE; } /* Get the data type associated with the named object, not the name itself */ /* Log2 loop to convert from Btype (binary) to Etype (encoded) */ ObjectType = 1; for (i = 1; i < Arg->Asl.AcpiBtype; i *= 2) { ObjectType++; } break; case PARSEOP_EXTERNAL: /* * "External" simply enters a name and type into the namespace. * We must be careful to not open a new scope, however, no matter * what type the external name refers to (e.g., a method) * * first child is name, next child is ObjectType */ ActualObjectType = (UINT8) Op->Asl.Child->Asl.Next->Asl.Value.Integer; ObjectType = ACPI_TYPE_ANY; /* * We will mark every new node along the path as "External". This * allows some or all of the nodes to be created later in the ASL * code. Handles cases like this: * * External (\_SB_.PCI0.ABCD, IntObj) * Scope (_SB_) * { * Device (PCI0) * { * } * } * Method (X) * { * Store (\_SB_.PCI0.ABCD, Local0) * } */ Flags |= ACPI_NS_EXTERNAL; break; case PARSEOP_DEFAULT_ARG: if (Op->Asl.CompileFlags == OP_IS_RESOURCE_DESC) { Status = LdLoadResourceElements (Op, WalkState); return_ACPI_STATUS (Status); } ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); break; case PARSEOP_SCOPE: /* * The name referenced by Scope(Name) must already exist at this point. * In other words, forward references for Scope() are not supported. * The only real reason for this is that the MS interpreter cannot * handle this case. Perhaps someday this case can go away. */ Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, WalkState, &(Node)); if (ACPI_FAILURE (Status)) { if (Status == AE_NOT_FOUND) { /* The name was not found, go ahead and create it */ Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_LOCAL_SCOPE, ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &(Node)); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } /* * However, this is an error -- primarily because the MS * interpreter can't handle a forward reference from the * Scope() operator. */ AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op, Op->Asl.ExternalName); AslError (ASL_ERROR, ASL_MSG_SCOPE_FWD_REF, Op, Op->Asl.ExternalName); goto FinishNode; } AslCoreSubsystemError (Op, Status, "Failure from namespace lookup", FALSE); return_ACPI_STATUS (Status); } else /* Status AE_OK */ { /* * Do not allow references to external scopes from the DSDT. * This is because the DSDT is always loaded first, and the * external reference cannot be resolved -- causing a runtime * error because Scope() must be resolved immediately. * 10/2015. */ if ((Node->Flags & ANOBJ_IS_EXTERNAL) && (ACPI_COMPARE_NAME (Gbl_TableSignature, "DSDT"))) { /* However, allowed if the reference is within a method */ MethodOp = Op->Asl.Parent; while (MethodOp && (MethodOp->Asl.ParseOpcode != PARSEOP_METHOD)) { MethodOp = MethodOp->Asl.Parent; } if (!MethodOp) { /* Not in a control method, error */ AslError (ASL_ERROR, ASL_MSG_CROSS_TABLE_SCOPE, Op, NULL); } } } /* We found a node with this name, now check the type */ switch (Node->Type) { case ACPI_TYPE_LOCAL_SCOPE: case ACPI_TYPE_DEVICE: case ACPI_TYPE_POWER: case ACPI_TYPE_PROCESSOR: case ACPI_TYPE_THERMAL: /* These are acceptable types - they all open a new scope */ break; case ACPI_TYPE_INTEGER: case ACPI_TYPE_STRING: case ACPI_TYPE_BUFFER: /* * These types we will allow, but we will change the type. * This enables some existing code of the form: * * Name (DEB, 0) * Scope (DEB) { ... } * * Which is used to workaround the fact that the MS interpreter * does not allow Scope() forward references. */ sprintf (MsgBuffer, "%s [%s], changing type to [Scope]", Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type)); AslError (ASL_REMARK, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer); /* Switch the type to scope, open the new scope */ Node->Type = ACPI_TYPE_LOCAL_SCOPE; Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE, WalkState); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } break; default: /* All other types are an error */ sprintf (MsgBuffer, "%s [%s]", Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type)); AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer); /* * However, switch the type to be an actual scope so * that compilation can continue without generating a whole * cascade of additional errors. Open the new scope. */ Node->Type = ACPI_TYPE_LOCAL_SCOPE; Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE, WalkState); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } break; } Status = AE_OK; goto FinishNode; default: ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); break; } ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Loading name: %s, (%s)\n", Op->Asl.ExternalName, AcpiUtGetTypeName (ObjectType))); /* The name must not already exist */ Flags |= ACPI_NS_ERROR_IF_FOUND; /* * Enter the named type into the internal namespace. We enter the name * as we go downward in the parse tree. Any necessary subobjects that * involve arguments to the opcode must be created as we go back up the * parse tree later. */ Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType, ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node); if (ACPI_FAILURE (Status)) { if (Status == AE_ALREADY_EXISTS) { /* The name already exists in this scope */ if (Node->Type == ACPI_TYPE_LOCAL_SCOPE) { /* Allow multiple references to the same scope */ Node->Type = (UINT8) ObjectType; Status = AE_OK; } else if ((Node->Flags & ANOBJ_IS_EXTERNAL) && (Op->Asl.ParseOpcode != PARSEOP_EXTERNAL)) { /* * Allow one create on an object or segment that was * previously declared External only if WalkState->OwnerId and * Node->OwnerId are different (meaning that the current WalkState * and the Node are in different tables). */ Node->Flags &= ~ANOBJ_IS_EXTERNAL; Node->Type = (UINT8) ObjectType; /* Just retyped a node, probably will need to open a scope */ if (AcpiNsOpensScope (ObjectType)) { Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } } Status = AE_OK; if (Node->OwnerId == WalkState->OwnerId && !(Node->Flags & IMPLICIT_EXTERNAL)) { AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op, Op->Asl.ExternalName, ASL_MSG_FOUND_HERE, Node->Op, Node->Op->Asl.ExternalName); } if (Node->Flags & IMPLICIT_EXTERNAL) { Node->Flags &= ~IMPLICIT_EXTERNAL; } } else if (!(Node->Flags & ANOBJ_IS_EXTERNAL) && (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL)) { /* * Allow externals in same scope as the definition of the * actual object. Similar to C. Allows multiple definition * blocks that refer to each other in the same file. However, * do not allow name declaration and an external declaration * within the same table. This is considered a re-declaration. */ Status = AE_OK; if (Node->OwnerId == WalkState->OwnerId) { AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op, Op->Asl.ExternalName, ASL_MSG_FOUND_HERE, Node->Op, Node->Op->Asl.ExternalName); } } else if ((Node->Flags & ANOBJ_IS_EXTERNAL) && (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL) && (ObjectType == ACPI_TYPE_ANY)) { /* * Allow update of externals of unknown type. * In the case that multiple definition blocks are being * parsed, updating the OwnerId allows enables subsequent calls * of this method to understand which table the most recent * external declaration was seen. Without this OwnerId update, * code like the following is allowed to compile: * * DefinitionBlock("externtest.aml", "DSDT", 0x02, "Intel", "Many", 0x00000001) * { * External(ERRS,methodobj) * Method (MAIN) * { * Name(NUM2, 0) * ERRS(1,2,3) * } * } * * DefinitionBlock("externtest.aml", "SSDT", 0x02, "Intel", "Many", 0x00000001) * { * if (0) * { * External(ERRS,methodobj) * } * Method (ERRS,3) * {} * * } */ Node->OwnerId = WalkState->OwnerId; if (AcpiNsOpensScope (ActualObjectType)) { Node->Type = (UINT8) ActualObjectType; Status = AE_OK; } else { sprintf (MsgBuffer, "%s [%s]", Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type)); AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer); return_ACPI_STATUS (AE_OK); } } else { /* Valid error, object already exists */ AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op, Op->Asl.ExternalName, ASL_MSG_FOUND_HERE, Node->Op, Node->Op->Asl.ExternalName); return_ACPI_STATUS (AE_OK); } } else { AslCoreSubsystemError (Op, Status, "Failure from namespace lookup", FALSE); return_ACPI_STATUS (Status); } } if (ForceNewScope) { Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } } FinishNode: /* * Point the parse node to the new namespace node, and point * the Node back to the original Parse node */ Op->Asl.Node = Node; Node->Op = Op; /* Set the actual data type if appropriate (EXTERNAL term only) */ if (ActualObjectType != ACPI_TYPE_ANY) { Node->Type = (UINT8) ActualObjectType; Node->Value = ASL_EXTERNAL_METHOD; } if (Op->Asl.ParseOpcode == PARSEOP_METHOD) { /* * Get the method argument count from "Extra" and save * it in the namespace node */ Node->Value = (UINT32) Op->Asl.Extra; } return_ACPI_STATUS (Status); }