diff options
Diffstat (limited to 'source/compiler/asltree.c')
-rw-r--r-- | source/compiler/asltree.c | 70 |
1 files changed, 62 insertions, 8 deletions
diff --git a/source/compiler/asltree.c b/source/compiler/asltree.c index 6bb40888ed5d..62efc5fa907c 100644 --- a/source/compiler/asltree.c +++ b/source/compiler/asltree.c @@ -462,6 +462,7 @@ TrLinkOpChildren ( { ACPI_PARSE_OBJECT *Child; ACPI_PARSE_OBJECT *PrevChild; + ACPI_PARSE_OBJECT *LastSibling; va_list ap; UINT32 i; BOOLEAN FirstChild; @@ -480,8 +481,18 @@ TrLinkOpChildren ( { case PARSEOP_ASL_CODE: - AslGbl_ParseTreeRoot = Op; - Op->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; + if (!AslGbl_ParseTreeRoot) + { + DbgPrint (ASL_PARSE_OUTPUT, "Creating first Definition Block\n"); + AslGbl_ParseTreeRoot = Op; + Op->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; + } + else + { + DbgPrint (ASL_PARSE_OUTPUT, "Creating subsequent Definition Block\n"); + Op = AslGbl_ParseTreeRoot; + } + DbgPrint (ASL_PARSE_OUTPUT, "ASLCODE (Tree Completed)->"); break; @@ -560,7 +571,27 @@ TrLinkOpChildren ( if (FirstChild) { FirstChild = FALSE; - Op->Asl.Child = Child; + + /* + * In the case that multiple definition blocks are being compiled, + * append the definition block to the end of the child list as the + * last sibling. This is done to facilitate namespace cross- + * reference between multiple definition blocks. + */ + if (Op->Asl.Child && + (Op->Asl.Child->Asl.ParseOpcode == PARSEOP_DEFINITION_BLOCK)) + { + LastSibling = Op->Asl.Child; + while (LastSibling->Asl.Next) + { + LastSibling = LastSibling->Asl.Next; + } + LastSibling->Asl.Next = Child; + } + else + { + Op->Asl.Child = Child; + } } /* Point all children to parent */ @@ -825,6 +856,8 @@ TrWalkParseTree ( BOOLEAN OpPreviouslyVisited; ACPI_PARSE_OBJECT *StartOp = Op; ACPI_STATUS Status; + ACPI_PARSE_OBJECT *Restore = NULL; + BOOLEAN WalkOneDefinitionBlock = Visitation & ASL_WALK_VISIT_DB_SEPARATELY; if (!AslGbl_ParseTreeRoot) @@ -835,7 +868,13 @@ TrWalkParseTree ( Level = 0; OpPreviouslyVisited = FALSE; - switch (Visitation) + if (Op->Asl.ParseOpcode == PARSEOP_DEFINITION_BLOCK && + WalkOneDefinitionBlock) + { + Restore = Op->Asl.Next; + Op->Asl.Next = NULL; + } + switch (Visitation & ~ASL_WALK_VISIT_DB_SEPARATELY) { case ASL_WALK_VISIT_DOWNWARD: @@ -861,7 +900,7 @@ TrWalkParseTree ( { /* Exit immediately on any error */ - return (Status); + goto ErrorExit; } } @@ -907,7 +946,7 @@ TrWalkParseTree ( Status = AscendingCallback (Op, Level, Context); if (ACPI_FAILURE (Status)) { - return (Status); + goto ErrorExit; } } else @@ -956,7 +995,7 @@ TrWalkParseTree ( Status = AscendingCallback (Op, Level, Context); if (ACPI_FAILURE (Status)) { - return (Status); + goto ErrorExit; } } else @@ -979,7 +1018,7 @@ TrWalkParseTree ( { /* Exit immediately on any error */ - return (Status); + goto ErrorExit; } } @@ -1018,5 +1057,20 @@ TrWalkParseTree ( /* If we get here, the walk completed with no errors */ + if (Op->Asl.ParseOpcode == PARSEOP_DEFINITION_BLOCK && + WalkOneDefinitionBlock) + { + Op->Asl.Next = Restore; + } + return (AE_OK); + +ErrorExit: + + if (Op->Asl.ParseOpcode == PARSEOP_DEFINITION_BLOCK && + WalkOneDefinitionBlock) + { + Op->Asl.Next = Restore; + } + return (Status); } |