static void OpcDoUuId ( ACPI_PARSE_OBJECT *Op) { char *InString; UINT8 *Buffer; ACPI_STATUS Status = AE_OK; ACPI_PARSE_OBJECT *NewOp; InString = (char *) Op->Asl.Value.String; Buffer = UtLocalCalloc (16); Status = AuValidateUuid (InString); if (ACPI_FAILURE (Status)) { AslError (ASL_ERROR, ASL_MSG_INVALID_UUID, Op, Op->Asl.Value.String); } else { AcpiUtConvertStringToUuid (InString, Buffer); } /* Change Op to a Buffer */ Op->Asl.ParseOpcode = PARSEOP_BUFFER; Op->Common.AmlOpcode = AML_BUFFER_OP; /* Disable further optimization */ Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST; UtSetParseOpName (Op); /* Child node is the buffer length */ NewOp = TrAllocateNode (PARSEOP_INTEGER); NewOp->Asl.AmlOpcode = AML_BYTE_OP; NewOp->Asl.Value.Integer = 16; NewOp->Asl.Parent = Op; Op->Asl.Child = NewOp; Op = NewOp; /* Peer to the child is the raw buffer data */ NewOp = TrAllocateNode (PARSEOP_RAW_DATA); NewOp->Asl.AmlOpcode = AML_RAW_DATA_BUFFER; NewOp->Asl.AmlLength = 16; NewOp->Asl.Value.String = (char *) Buffer; NewOp->Asl.Parent = Op->Asl.Parent; Op->Asl.Next = NewOp; }
ACPI_PARSE_OBJECT * TrCreateValuedLeafNode ( UINT32 ParseOpcode, UINT64 Value) { ACPI_PARSE_OBJECT *Op; Op = TrAllocateNode (ParseOpcode); DbgPrint (ASL_PARSE_OUTPUT, "\nCreateValuedLeafNode Ln/Col %u/%u NewNode %p " "Op %s Value %8.8X%8.8X ", Op->Asl.LineNumber, Op->Asl.Column, Op, UtGetOpName(ParseOpcode), ACPI_FORMAT_UINT64 (Value)); Op->Asl.Value.Integer = Value; switch (ParseOpcode) { case PARSEOP_STRING_LITERAL: DbgPrint (ASL_PARSE_OUTPUT, "STRING->%s", Value); break; case PARSEOP_NAMESEG: DbgPrint (ASL_PARSE_OUTPUT, "NAMESEG->%s", Value); break; case PARSEOP_NAMESTRING: DbgPrint (ASL_PARSE_OUTPUT, "NAMESTRING->%s", Value); break; case PARSEOP_EISAID: DbgPrint (ASL_PARSE_OUTPUT, "EISAID->%s", Value); break; case PARSEOP_METHOD: DbgPrint (ASL_PARSE_OUTPUT, "METHOD"); break; case PARSEOP_INTEGER: DbgPrint (ASL_PARSE_OUTPUT, "INTEGER->%8.8X%8.8X", ACPI_FORMAT_UINT64 (Value)); break; default: break; } DbgPrint (ASL_PARSE_OUTPUT, "\n\n"); return (Op); }
static void OpcCreateConcatenateNode ( ACPI_PARSE_OBJECT *Op, ACPI_PARSE_OBJECT *Node) { ACPI_PARSE_OBJECT *NewConcatOp; if (!Op->Asl.Child) { Op->Asl.Child = Node; Node->Asl.Parent = Op; return; } NewConcatOp = TrAllocateNode (PARSEOP_CONCATENATE); NewConcatOp->Asl.AmlOpcode = AML_CONCAT_OP; NewConcatOp->Asl.AcpiBtype = 0x7; NewConcatOp->Asl.LogicalLineNumber = Op->Asl.LogicalLineNumber; /* First arg is child of Op*/ NewConcatOp->Asl.Child = Op->Asl.Child; Op->Asl.Child->Asl.Parent = NewConcatOp; /* Second arg is Node */ NewConcatOp->Asl.Child->Asl.Next = Node; Node->Asl.Parent = NewConcatOp; /* Third arg is Zero (not used) */ NewConcatOp->Asl.Child->Asl.Next->Asl.Next = TrAllocateNode (PARSEOP_ZERO); NewConcatOp->Asl.Child->Asl.Next->Asl.Next->Asl.Parent = NewConcatOp; Op->Asl.Child = NewConcatOp; NewConcatOp->Asl.Parent = Op; }
ACPI_PARSE_OBJECT * TrLinkPeerNodes ( UINT32 NumPeers, ...) { ACPI_PARSE_OBJECT *This; ACPI_PARSE_OBJECT *Next; va_list ap; UINT32 i; ACPI_PARSE_OBJECT *Start; DbgPrint (ASL_PARSE_OUTPUT, "\nLinkPeerNodes: (%u) ", NumPeers); va_start (ap, NumPeers); This = va_arg (ap, ACPI_PARSE_OBJECT *); Start = This; /* * Link all peers */ for (i = 0; i < (NumPeers -1); i++) { DbgPrint (ASL_PARSE_OUTPUT, "%u=%p ", (i+1), This); while (This->Asl.Next) { This = This->Asl.Next; } /* Get another peer node */ Next = va_arg (ap, ACPI_PARSE_OBJECT *); if (!Next) { Next = TrAllocateNode (PARSEOP_DEFAULT_ARG); } /* link new node to the current node */ This->Asl.Next = Next; This = Next; } va_end (ap); DbgPrint (ASL_PARSE_OUTPUT,"\n\n"); return (Start); }
ACPI_PARSE_OBJECT * TrCreateLeafNode ( UINT32 ParseOpcode) { ACPI_PARSE_OBJECT *Op; Op = TrAllocateNode (ParseOpcode); DbgPrint (ASL_PARSE_OUTPUT, "\nCreateLeafNode Ln/Col %u/%u NewNode %p Op %s\n\n", Op->Asl.LineNumber, Op->Asl.Column, Op, UtGetOpName(ParseOpcode)); return (Op); }
void OpcDoPrintf ( ACPI_PARSE_OBJECT *Op) { ACPI_PARSE_OBJECT *DestOp; /* Store destination is the Debug op */ DestOp = TrAllocateNode (PARSEOP_DEBUG); DestOp->Asl.AmlOpcode = AML_DEBUG_OP; DestOp->Asl.Parent = Op; OpcParsePrintf (Op, DestOp); }
ACPI_PARSE_OBJECT * TrCreateNullTarget ( void) { ACPI_PARSE_OBJECT *Op; Op = TrAllocateNode (PARSEOP_ZERO); Op->Asl.CompileFlags |= (NODE_IS_TARGET | NODE_COMPILE_TIME_CONST); DbgPrint (ASL_PARSE_OUTPUT, "\nCreateNullTarget Ln/Col %u/%u NewNode %p Op %s\n", Op->Asl.LineNumber, Op->Asl.Column, Op, UtGetOpName (Op->Asl.ParseOpcode)); return (Op); }
void ExDoExternal ( ACPI_PARSE_OBJECT *Op) { ACPI_PARSE_OBJECT *ListOp; ACPI_PARSE_OBJECT *Prev; ACPI_PARSE_OBJECT *Next; ACPI_PARSE_OBJECT *ArgCountOp; ArgCountOp = Op->Asl.Child->Asl.Next->Asl.Next; ArgCountOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE; ArgCountOp->Asl.ParseOpcode = PARSEOP_BYTECONST; ArgCountOp->Asl.Value.Integer = 0; UtSetParseOpName (ArgCountOp); /* Create new list node of arbitrary type */ ListOp = TrAllocateNode (PARSEOP_DEFAULT_ARG); /* Store External node as child */ ListOp->Asl.Child = Op; ListOp->Asl.Next = NULL; if (Gbl_ExternalsListHead) { /* Link new External to end of list */ Prev = Gbl_ExternalsListHead; Next = Prev; while (Next) { Prev = Next; Next = Next->Asl.Next; } Prev->Asl.Next = ListOp; } else { Gbl_ExternalsListHead = ListOp; } }
ACPI_PARSE_OBJECT * TrLinkChildren ( ACPI_PARSE_OBJECT *Op, UINT32 NumChildren, ...) { ACPI_PARSE_OBJECT *Child; ACPI_PARSE_OBJECT *PrevChild; va_list ap; UINT32 i; BOOLEAN FirstChild; va_start (ap, NumChildren); TrSetEndLineNumber (Op); DbgPrint (ASL_PARSE_OUTPUT, "\nLinkChildren Line [%u to %u] NewParent %p Child %u Op %s ", Op->Asl.LineNumber, Op->Asl.EndLine, Op, NumChildren, UtGetOpName(Op->Asl.ParseOpcode)); switch (Op->Asl.ParseOpcode) { case PARSEOP_DEFINITIONBLOCK: RootNode = Op; DbgPrint (ASL_PARSE_OUTPUT, "DEFINITION_BLOCK (Tree Completed)->"); break; case PARSEOP_OPERATIONREGION: DbgPrint (ASL_PARSE_OUTPUT, "OPREGION->"); break; case PARSEOP_OR: DbgPrint (ASL_PARSE_OUTPUT, "OR->"); break; default: /* Nothing to do for other opcodes */ break; } /* Link the new node to it's children */ PrevChild = NULL; FirstChild = TRUE; for (i = 0; i < NumChildren; i++) { Child = va_arg (ap, ACPI_PARSE_OBJECT *); if ((Child == PrevChild) && (Child != NULL)) { AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Child, "Child node list invalid"); va_end(ap); return (Op); } DbgPrint (ASL_PARSE_OUTPUT, "%p, ", Child); /* * If child is NULL, this means that an optional argument * was omitted. We must create a placeholder with a special * opcode (DEFAULT_ARG) so that the code generator will know * that it must emit the correct default for this argument */ if (!Child) { Child = TrAllocateNode (PARSEOP_DEFAULT_ARG); } /* Link first child to parent */ if (FirstChild) { FirstChild = FALSE; Op->Asl.Child = Child; } /* Point all children to parent */ Child->Asl.Parent = Op; /* Link children in a peer list */ if (PrevChild) { PrevChild->Asl.Next = Child; }; /* * This child might be a list, point all nodes in the list * to the same parent */ while (Child->Asl.Next) { Child = Child->Asl.Next; Child->Asl.Parent = Op; } PrevChild = Child; } va_end(ap); DbgPrint (ASL_PARSE_OUTPUT, "\n\n"); return (Op); }
ACPI_PARSE_OBJECT * TrCreateNode ( UINT32 ParseOpcode, UINT32 NumChildren, ...) { ACPI_PARSE_OBJECT *Op; ACPI_PARSE_OBJECT *Child; ACPI_PARSE_OBJECT *PrevChild; va_list ap; UINT32 i; BOOLEAN FirstChild; va_start (ap, NumChildren); /* Allocate one new node */ Op = TrAllocateNode (ParseOpcode); DbgPrint (ASL_PARSE_OUTPUT, "\nCreateNode Ln/Col %u/%u NewParent %p Child %u Op %s ", Op->Asl.LineNumber, Op->Asl.Column, Op, NumChildren, UtGetOpName(ParseOpcode)); /* Some extra debug output based on the parse opcode */ switch (ParseOpcode) { case PARSEOP_DEFINITIONBLOCK: RootNode = Op; DbgPrint (ASL_PARSE_OUTPUT, "DEFINITION_BLOCK (Tree Completed)->"); break; case PARSEOP_OPERATIONREGION: DbgPrint (ASL_PARSE_OUTPUT, "OPREGION->"); break; case PARSEOP_OR: DbgPrint (ASL_PARSE_OUTPUT, "OR->"); break; default: /* Nothing to do for other opcodes */ break; } /* Link the new node to its children */ PrevChild = NULL; FirstChild = TRUE; for (i = 0; i < NumChildren; i++) { /* Get the next child */ Child = va_arg (ap, ACPI_PARSE_OBJECT *); DbgPrint (ASL_PARSE_OUTPUT, "%p, ", Child); /* * If child is NULL, this means that an optional argument * was omitted. We must create a placeholder with a special * opcode (DEFAULT_ARG) so that the code generator will know * that it must emit the correct default for this argument */ if (!Child) { Child = TrAllocateNode (PARSEOP_DEFAULT_ARG); } /* Link first child to parent */ if (FirstChild) { FirstChild = FALSE; Op->Asl.Child = Child; } /* Point all children to parent */ Child->Asl.Parent = Op; /* Link children in a peer list */ if (PrevChild) { PrevChild->Asl.Next = Child; }; /* * This child might be a list, point all nodes in the list * to the same parent */ while (Child->Asl.Next) { Child = Child->Asl.Next; Child->Asl.Parent = Op; } PrevChild = Child; } va_end(ap); DbgPrint (ASL_PARSE_OUTPUT, "\n\n"); return (Op); }
ACPI_PARSE_OBJECT * TrCreateConstantLeafNode ( UINT32 ParseOpcode) { ACPI_PARSE_OBJECT *Op = NULL; time_t CurrentTime; char *StaticTimeString; char *TimeString; char *Path; char *Filename; switch (ParseOpcode) { case PARSEOP___LINE__: Op = TrAllocateNode (PARSEOP_INTEGER); Op->Asl.Value.Integer = Op->Asl.LineNumber; break; case PARSEOP___PATH__: Op = TrAllocateNode (PARSEOP_STRING_LITERAL); /* Op.Asl.Filename contains the full pathname to the file */ Op->Asl.Value.String = Op->Asl.Filename; break; case PARSEOP___FILE__: Op = TrAllocateNode (PARSEOP_STRING_LITERAL); /* Get the simple filename from the full path */ FlSplitInputPathname (Op->Asl.Filename, &Path, &Filename); ACPI_FREE (Path); Op->Asl.Value.String = Filename; break; case PARSEOP___DATE__: Op = TrAllocateNode (PARSEOP_STRING_LITERAL); /* Get a copy of the current time */ CurrentTime = time (NULL); StaticTimeString = ctime (&CurrentTime); TimeString = UtLocalCalloc (strlen (StaticTimeString) + 1); strcpy (TimeString, StaticTimeString); TimeString[strlen(TimeString) -1] = 0; /* Remove trailing newline */ Op->Asl.Value.String = TimeString; break; default: /* This would be an internal error */ return (NULL); } DbgPrint (ASL_PARSE_OUTPUT, "\nCreateConstantLeafNode Ln/Col %u/%u NewNode %p Op %s Value %8.8X%8.8X ", Op->Asl.LineNumber, Op->Asl.Column, Op, UtGetOpName (ParseOpcode), ACPI_FORMAT_UINT64 (Op->Asl.Value.Integer)); return (Op); }
static void ExMoveExternals ( ACPI_PARSE_OBJECT *DefinitionBlockOp) { ACPI_PARSE_OBJECT *ParentOp; ACPI_PARSE_OBJECT *ExternalOp; ACPI_PARSE_OBJECT *PredicateOp; ACPI_PARSE_OBJECT *NextOp; ACPI_PARSE_OBJECT *Prev; ACPI_PARSE_OBJECT *Next; char *ExternalName; ACPI_OBJECT_TYPE ObjType; UINT32 i; if (!Gbl_ExternalsListHead) { return; } /* Remove the External nodes from the tree */ NextOp = Gbl_ExternalsListHead; while (NextOp) { /* * The External is stored in child pointer of each node in the * list */ ExternalOp = NextOp->Asl.Child; /* Get/set the fully qualified name */ ExternalName = AcpiNsGetNormalizedPathname (ExternalOp->Asl.Node, TRUE); ExternalOp->Asl.ExternalName = ExternalName; ExternalOp->Asl.Namepath = ExternalName; /* Set line numbers (for listings, etc.) */ ExternalOp->Asl.LineNumber = 0; ExternalOp->Asl.LogicalLineNumber = 0; Next = ExternalOp->Asl.Child; Next->Asl.LineNumber = 0; Next->Asl.LogicalLineNumber = 0; if (Next->Asl.ParseOpcode == PARSEOP_NAMESEG) { Next->Asl.ParseOpcode = PARSEOP_NAMESTRING; } Next->Asl.ExternalName = ExternalName; UtInternalizeName (ExternalName, &Next->Asl.Value.String); Next->Asl.AmlLength = strlen (Next->Asl.Value.String); Next = Next->Asl.Next; Next->Asl.LineNumber = 0; Next->Asl.LogicalLineNumber = 0; Next = Next->Asl.Next; Next->Asl.LineNumber = 0; Next->Asl.LogicalLineNumber = 0; Next = Next->Asl.Next; Next->Asl.LineNumber = 0; Next->Asl.LogicalLineNumber = 0; ParentOp = ExternalOp->Asl.Parent; Prev = Next = ParentOp->Asl.Child; /* Now find the External node's position in parse tree */ while (Next != ExternalOp) { Prev = Next; Next = Next->Asl.Next; } /* Remove the External from the parse tree */ if (Prev == ExternalOp) { /* External was the first child node */ ParentOp->Asl.Child = ExternalOp->Asl.Next; } Prev->Asl.Next = ExternalOp->Asl.Next; ExternalOp->Asl.Next = NULL; ExternalOp->Asl.Parent = Gbl_ExternalsListHead; /* Point the External to the next in the list */ if (NextOp->Asl.Next) { ExternalOp->Asl.Next = NextOp->Asl.Next->Asl.Child; } NextOp = NextOp->Asl.Next; } /* * Loop again to remove MethodObj Externals for which * a MethodCall was not found (dead external reference) */ Prev = Gbl_ExternalsListHead->Asl.Child; Next = Prev; while (Next) { ObjType = (ACPI_OBJECT_TYPE) Next->Asl.Child->Asl.Next->Asl.Value.Integer; if (ObjType == ACPI_TYPE_METHOD && !(Next->Asl.CompileFlags & NODE_VISITED)) { if (Next == Prev) { Gbl_ExternalsListHead->Asl.Child = Next->Asl.Next; Next->Asl.Next = NULL; Prev = Gbl_ExternalsListHead->Asl.Child; Next = Prev; continue; } else { Prev->Asl.Next = Next->Asl.Next; Next->Asl.Next = NULL; Next = Prev->Asl.Next; continue; } } Prev = Next; Next = Next->Asl.Next; } /* If list is now empty, don't bother to make If (0) block */ if (!Gbl_ExternalsListHead->Asl.Child) { return; } /* Convert Gbl_ExternalsListHead parent to If(). */ Gbl_ExternalsListHead->Asl.ParseOpcode = PARSEOP_IF; Gbl_ExternalsListHead->Asl.AmlOpcode = AML_IF_OP; Gbl_ExternalsListHead->Asl.CompileFlags = NODE_AML_PACKAGE; UtSetParseOpName (Gbl_ExternalsListHead); /* Create a Zero op for the If predicate */ PredicateOp = TrAllocateNode (PARSEOP_ZERO); PredicateOp->Asl.AmlOpcode = AML_ZERO_OP; PredicateOp->Asl.Parent = Gbl_ExternalsListHead; PredicateOp->Asl.Child = NULL; PredicateOp->Asl.Next = Gbl_ExternalsListHead->Asl.Child; Gbl_ExternalsListHead->Asl.Child = PredicateOp; /* Set line numbers (for listings, etc.) */ Gbl_ExternalsListHead->Asl.LineNumber = 0; Gbl_ExternalsListHead->Asl.LogicalLineNumber = 0; PredicateOp->Asl.LineNumber = 0; PredicateOp->Asl.LogicalLineNumber = 0; /* Insert block back in the list */ Prev = DefinitionBlockOp->Asl.Child; Next = Prev; /* Find last default arg */ for (i = 0; i < 6; i++) { Prev = Next; Next = Prev->Asl.Next; } if (Next) { /* Definition Block is not empty */ Gbl_ExternalsListHead->Asl.Next = Next; } else { /* Definition Block is empty. */ Gbl_ExternalsListHead->Asl.Next = NULL; } Prev->Asl.Next = Gbl_ExternalsListHead; Gbl_ExternalsListHead->Asl.Parent = Prev->Asl.Parent; }
ACPI_PARSE_OBJECT * TrCreateAssignmentNode ( ACPI_PARSE_OBJECT *Target, ACPI_PARSE_OBJECT *Source) { ACPI_PARSE_OBJECT *TargetOp; ACPI_PARSE_OBJECT *SourceOp1; ACPI_PARSE_OBJECT *SourceOp2; ACPI_PARSE_OBJECT *Operator; DbgPrint (ASL_PARSE_OUTPUT, "\nTrCreateAssignmentNode Line [%u to %u] Source %s Target %s\n", Source->Asl.LineNumber, Source->Asl.EndLine, UtGetOpName (Source->Asl.ParseOpcode), UtGetOpName (Target->Asl.ParseOpcode)); TrSetNodeFlags (Target, NODE_IS_TARGET); switch (Source->Asl.ParseOpcode) { /* * Only these operators can be optimized because they have * a target operand */ case PARSEOP_ADD: case PARSEOP_AND: case PARSEOP_DIVIDE: case PARSEOP_MOD: case PARSEOP_MULTIPLY: case PARSEOP_NOT: case PARSEOP_OR: case PARSEOP_SHIFTLEFT: case PARSEOP_SHIFTRIGHT: case PARSEOP_SUBTRACT: case PARSEOP_XOR: break; /* Otherwise, just create a normal Store operator */ default: goto CannotOptimize; } /* * Transform the parse tree such that the target is moved to the * last operand of the operator */ SourceOp1 = Source->Asl.Child; SourceOp2 = SourceOp1->Asl.Next; /* NOT only has one operand, but has a target */ if (Source->Asl.ParseOpcode == PARSEOP_NOT) { SourceOp2 = SourceOp1; } /* DIVIDE has an extra target operand (remainder) */ if (Source->Asl.ParseOpcode == PARSEOP_DIVIDE) { SourceOp2 = SourceOp2->Asl.Next; } TargetOp = SourceOp2->Asl.Next; /* * Can't perform this optimization if there already is a target * for the operator (ZERO is a "no target" placeholder). */ if (TargetOp->Asl.ParseOpcode != PARSEOP_ZERO) { goto CannotOptimize; } /* Link in the target as the final operand */ SourceOp2->Asl.Next = Target; Target->Asl.Parent = Source; return (Source); CannotOptimize: Operator = TrAllocateNode (PARSEOP_STORE); TrLinkChildren (Operator, 2, Source, Target); /* Set the appropriate line numbers for the new node */ Operator->Asl.LineNumber = Target->Asl.LineNumber; Operator->Asl.LogicalLineNumber = Target->Asl.LogicalLineNumber; Operator->Asl.LogicalByteOffset = Target->Asl.LogicalByteOffset; Operator->Asl.Column = Target->Asl.Column; return (Operator); }
static ACPI_STATUS TrSimpleConstantReduction ( ACPI_PARSE_OBJECT *Op, ACPI_WALK_STATE *WalkState) { ACPI_PARSE_OBJECT *RootOp; ACPI_PARSE_OBJECT *OriginalParentOp; ACPI_OPERAND_OBJECT *ObjDesc; ACPI_STATUS Status; DbgPrint (ASL_PARSE_OUTPUT, "Simple subtree constant reduction, operator to constant\n"); /* Allocate a new temporary root for this subtree */ RootOp = TrAllocateNode (PARSEOP_INTEGER); if (!RootOp) { return (AE_NO_MEMORY); } RootOp->Common.AmlOpcode = AML_INT_EVAL_SUBTREE_OP; OriginalParentOp = Op->Common.Parent; Op->Common.Parent = RootOp; /* Hand off the subtree to the AML interpreter */ WalkState->CallerReturnDesc = &ObjDesc; Status = TrWalkParseTree (Op, ASL_WALK_VISIT_TWICE, OpcAmlEvaluationWalk1, OpcAmlEvaluationWalk2, WalkState); /* Restore original parse tree */ Op->Common.Parent = OriginalParentOp; if (ACPI_FAILURE (Status)) { DbgPrint (ASL_PARSE_OUTPUT, "Constant Subtree evaluation(1), %s\n", AcpiFormatException (Status)); return (Status); } /* Get the final result */ Status = AcpiDsResultPop (&ObjDesc, WalkState); if (ACPI_FAILURE (Status)) { DbgPrint (ASL_PARSE_OUTPUT, "Constant Subtree evaluation(2), %s\n", AcpiFormatException (Status)); return (Status); } /* Disconnect any existing children, install new constant */ Op->Asl.Child = NULL; TrInstallReducedConstant (Op, ObjDesc); UtSetParseOpName (Op); return (AE_OK); }
static void OpcParsePrintf ( ACPI_PARSE_OBJECT *Op, ACPI_PARSE_OBJECT *DestOp) { char *Format; char *StartPosition = NULL; ACPI_PARSE_OBJECT *ArgNode; ACPI_PARSE_OBJECT *NextNode; UINT32 StringLength = 0; char *NewString; BOOLEAN StringToProcess = FALSE; ACPI_PARSE_OBJECT *NewOp; /* Get format string */ Format = ACPI_CAST_PTR (char, Op->Asl.Child->Asl.Value.String); ArgNode = Op->Asl.Child->Asl.Next; /* * Detach argument list so that we can use a NULL check to distinguish * the first concatenation operation we need to make */ Op->Asl.Child = NULL; for (; *Format; ++Format) { if (*Format != '%') { if (!StringToProcess) { /* Mark the beginning of a string */ StartPosition = Format; StringToProcess = TRUE; } ++StringLength; continue; } /* Save string, if any, to new string object and concat it */ if (StringToProcess) { NewString = UtStringCacheCalloc (StringLength + 1); strncpy (NewString, StartPosition, StringLength); NewOp = TrAllocateNode (PARSEOP_STRING_LITERAL); NewOp->Asl.Value.String = NewString; NewOp->Asl.AmlOpcode = AML_STRING_OP; NewOp->Asl.AcpiBtype = ACPI_BTYPE_STRING; NewOp->Asl.LogicalLineNumber = Op->Asl.LogicalLineNumber; OpcCreateConcatenateNode(Op, NewOp); StringLength = 0; StringToProcess = FALSE; } ++Format; /* * We have a format parameter and will need an argument to go * with it */ if (!ArgNode || ArgNode->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) { AslError(ASL_ERROR, ASL_MSG_ARG_COUNT_LO, Op, NULL); return; } /* * We do not support sub-specifiers of printf (flags, width, * precision, length). For specifiers we only support %x/%X for * hex or %s for strings. Also, %o for generic "acpi object". */ switch (*Format) { case 's': if (ArgNode->Asl.ParseOpcode != PARSEOP_STRING_LITERAL) { AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgNode, "String required"); return; } NextNode = ArgNode->Asl.Next; ArgNode->Asl.Next = NULL; OpcCreateConcatenateNode(Op, ArgNode); ArgNode = NextNode; continue; case 'X': case 'x': case 'o': NextNode = ArgNode->Asl.Next; ArgNode->Asl.Next = NULL; /* * Append an empty string if the first argument is * not a string. This will implicitly conver the 2nd * concat source to a string per the ACPI specification. */ if (!Op->Asl.Child) { NewOp = TrAllocateNode (PARSEOP_STRING_LITERAL); NewOp->Asl.Value.String = ""; NewOp->Asl.AmlOpcode = AML_STRING_OP; NewOp->Asl.AcpiBtype = ACPI_BTYPE_STRING; NewOp->Asl.LogicalLineNumber = Op->Asl.LogicalLineNumber; OpcCreateConcatenateNode(Op, NewOp); } OpcCreateConcatenateNode(Op, ArgNode); ArgNode = NextNode; break; default: AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Op, "Unrecognized format specifier"); continue; } } /* Process any remaining string */ if (StringToProcess) { NewString = UtStringCacheCalloc (StringLength + 1); strncpy (NewString, StartPosition, StringLength); NewOp = TrAllocateNode (PARSEOP_STRING_LITERAL); NewOp->Asl.Value.String = NewString; NewOp->Asl.AcpiBtype = ACPI_BTYPE_STRING; NewOp->Asl.AmlOpcode = AML_STRING_OP; NewOp->Asl.LogicalLineNumber = Op->Asl.LogicalLineNumber; OpcCreateConcatenateNode(Op, NewOp); } /* * If we get here and there's no child node then Format * was an empty string. Just make a no op. */ if (!Op->Asl.Child) { Op->Asl.ParseOpcode = PARSEOP_NOOP; AslError(ASL_WARNING, ASL_MSG_NULL_STRING, Op, "Converted to NOOP"); return; } /* Check for erroneous extra arguments */ if (ArgNode && ArgNode->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) { AslError(ASL_WARNING, ASL_MSG_ARG_COUNT_HI, ArgNode, "Extra arguments ignored"); } /* Change Op to a Store */ Op->Asl.ParseOpcode = PARSEOP_STORE; Op->Common.AmlOpcode = AML_STORE_OP; Op->Asl.CompileFlags = 0; /* Disable further optimization */ Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST; UtSetParseOpName (Op); /* Set Store destination */ Op->Asl.Child->Asl.Next = DestOp; }
static void OpcDoUuId ( ACPI_PARSE_OBJECT *Op) { char *InString; char *Buffer; ACPI_STATUS Status = AE_OK; ACPI_NATIVE_UINT i; ACPI_PARSE_OBJECT *NewOp; InString = (char *) Op->Asl.Value.String; if (ACPI_STRLEN (InString) != 36) { Status = AE_BAD_PARAMETER; } else { /* Check all 36 characters for correct format */ for (i = 0; i < 36; i++) { if ((i == 8) || (i == 13) || (i == 18) || (i == 23)) { if (InString[i] != '-') { Status = AE_BAD_PARAMETER; } } else { if (!isxdigit (InString[i])) { Status = AE_BAD_PARAMETER; } } } } Buffer = UtLocalCalloc (16); if (ACPI_FAILURE (Status)) { AslError (ASL_ERROR, ASL_MSG_INVALID_UUID, Op, Op->Asl.Value.String); } else for (i = 0; i < 16; i++) { Buffer[i] = (char) (UtHexCharToValue (InString[OpcMapToUUID[i]]) << 4); Buffer[i] |= (char) UtHexCharToValue (InString[OpcMapToUUID[i] + 1]); } /* Change Op to a Buffer */ Op->Asl.ParseOpcode = PARSEOP_BUFFER; Op->Common.AmlOpcode = AML_BUFFER_OP; /* Disable further optimization */ Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST; UtSetParseOpName (Op); /* Child node is the buffer length */ NewOp = TrAllocateNode (PARSEOP_INTEGER); NewOp->Asl.AmlOpcode = AML_BYTE_OP; NewOp->Asl.Value.Integer = 16; NewOp->Asl.Parent = Op; Op->Asl.Child = NewOp; Op = NewOp; /* Peer to the child is the raw buffer data */ NewOp = TrAllocateNode (PARSEOP_RAW_DATA); NewOp->Asl.AmlOpcode = AML_RAW_DATA_BUFFER; NewOp->Asl.AmlLength = 16; NewOp->Asl.Value.String = (char *) Buffer; NewOp->Asl.Parent = Op->Asl.Parent; Op->Asl.Next = NewOp; }
static void TrInstallReducedConstant ( ACPI_PARSE_OBJECT *Op, ACPI_OPERAND_OBJECT *ObjDesc) { ACPI_PARSE_OBJECT *LengthOp; ACPI_PARSE_OBJECT *DataOp; TotalFolds++; AslError (ASL_OPTIMIZATION, ASL_MSG_CONSTANT_FOLDED, Op, Op->Asl.ParseOpName); /* * Because we know we executed type 3/4/5 opcodes above, we know that * the result must be either an Integer, String, or Buffer. */ switch (ObjDesc->Common.Type) { case ACPI_TYPE_INTEGER: OpcUpdateIntegerNode (Op, ObjDesc->Integer.Value); DbgPrint (ASL_PARSE_OUTPUT, "Constant expression reduced to (%s) %8.8X%8.8X\n\n", Op->Asl.ParseOpName, ACPI_FORMAT_UINT64 (Op->Common.Value.Integer)); break; case ACPI_TYPE_STRING: Op->Asl.ParseOpcode = PARSEOP_STRING_LITERAL; Op->Common.AmlOpcode = AML_STRING_OP; Op->Asl.AmlLength = strlen (ObjDesc->String.Pointer) + 1; Op->Common.Value.String = ObjDesc->String.Pointer; DbgPrint (ASL_PARSE_OUTPUT, "Constant expression reduced to (STRING) %s\n\n", Op->Common.Value.String); break; case ACPI_TYPE_BUFFER: /* * Create a new parse subtree of the form: * * BUFFER (Buffer AML opcode) * INTEGER (Buffer length in bytes) * RAW_DATA (Buffer byte data) */ Op->Asl.ParseOpcode = PARSEOP_BUFFER; Op->Common.AmlOpcode = AML_BUFFER_OP; Op->Asl.CompileFlags = NODE_AML_PACKAGE; UtSetParseOpName (Op); /* Child node is the buffer length */ LengthOp = TrAllocateNode (PARSEOP_INTEGER); LengthOp->Asl.AmlOpcode = AML_DWORD_OP; LengthOp->Asl.Value.Integer = ObjDesc->Buffer.Length; LengthOp->Asl.Parent = Op; (void) OpcSetOptimalIntegerSize (LengthOp); Op->Asl.Child = LengthOp; /* Next child is the raw buffer data */ DataOp = TrAllocateNode (PARSEOP_RAW_DATA); DataOp->Asl.AmlOpcode = AML_RAW_DATA_BUFFER; DataOp->Asl.AmlLength = ObjDesc->Buffer.Length; DataOp->Asl.Value.String = (char *) ObjDesc->Buffer.Pointer; DataOp->Asl.Parent = Op; LengthOp->Asl.Next = DataOp; DbgPrint (ASL_PARSE_OUTPUT, "Constant expression reduced to (BUFFER) length %X\n\n", ObjDesc->Buffer.Length); break; default: break; } }
static ACPI_STATUS TrTransformToStoreOp ( ACPI_PARSE_OBJECT *Op, ACPI_WALK_STATE *WalkState) { ACPI_PARSE_OBJECT *OriginalTarget; ACPI_PARSE_OBJECT *NewTarget; ACPI_PARSE_OBJECT *Child1; ACPI_PARSE_OBJECT *Child2; ACPI_OPERAND_OBJECT *ObjDesc; ACPI_PARSE_OBJECT *NewParent; ACPI_PARSE_OBJECT *OriginalParent; ACPI_STATUS Status; /* Extract the operands */ Child1 = Op->Asl.Child; Child2 = Child1->Asl.Next; /* * Special case for DIVIDE -- it has two targets. The first * is for the remainder and if present, we will not attempt * to reduce the expression. */ if (Op->Asl.ParseOpcode == PARSEOP_DIVIDE) { Child2 = Child2->Asl.Next; if (Child2->Asl.ParseOpcode != PARSEOP_ZERO) { DbgPrint (ASL_PARSE_OUTPUT, "Cannot reduce DIVIDE - has two targets\n\n"); return (AE_OK); } } DbgPrint (ASL_PARSE_OUTPUT, "Reduction/Transform to StoreOp: Store(%s, %s)\n", Child1->Asl.ParseOpName, Child2->Asl.ParseOpName); /* * Create a NULL (zero) target so that we can use the * interpreter to evaluate the expression. */ NewTarget = TrCreateNullTarget (); NewTarget->Common.AmlOpcode = AML_INT_NAMEPATH_OP; /* Handle one-operand cases (NOT, TOBCD, etc.) */ if (!Child2->Asl.Next) { Child2 = Child1; } /* Link in new NULL target as the last operand */ OriginalTarget = Child2->Asl.Next; Child2->Asl.Next = NewTarget; NewTarget->Asl.Parent = OriginalTarget->Asl.Parent; NewParent = TrAllocateNode (PARSEOP_INTEGER); NewParent->Common.AmlOpcode = AML_INT_EVAL_SUBTREE_OP; OriginalParent = Op->Common.Parent; Op->Common.Parent = NewParent; /* Hand off the subtree to the AML interpreter */ WalkState->CallerReturnDesc = &ObjDesc; Status = TrWalkParseTree (Op, ASL_WALK_VISIT_TWICE, OpcAmlEvaluationWalk1, OpcAmlEvaluationWalk2, WalkState); if (ACPI_FAILURE (Status)) { DbgPrint (ASL_PARSE_OUTPUT, "Constant Subtree evaluation(3), %s\n", AcpiFormatException (Status)); goto EvalError; } /* Get the final result */ Status = AcpiDsResultPop (&ObjDesc, WalkState); if (ACPI_FAILURE (Status)) { DbgPrint (ASL_PARSE_OUTPUT, "Constant Subtree evaluation(4), %s\n", AcpiFormatException (Status)); goto EvalError; } /* Truncate any subtree expressions, they have been evaluated */ Child1->Asl.Child = NULL; /* Folded constant is in ObjDesc, store into Child1 */ TrInstallReducedConstant (Child1, ObjDesc); /* Convert operator to STORE */ Op->Asl.ParseOpcode = PARSEOP_STORE; Op->Asl.AmlOpcode = AML_STORE_OP; UtSetParseOpName (Op); Op->Common.Parent = OriginalParent; /* First child is the folded constant */ /* Second child will be the target */ Child1->Asl.Next = OriginalTarget; return (AE_OK); EvalError: /* Restore original links */ Op->Common.Parent = OriginalParent; Child2->Asl.Next = OriginalTarget; return (Status); }
ACPI_STATUS OpcAmlConstantWalk ( ACPI_PARSE_OBJECT *Op, UINT32 Level, void *Context) { ACPI_WALK_STATE *WalkState; ACPI_STATUS Status = AE_OK; ACPI_OPERAND_OBJECT *ObjDesc; ACPI_PARSE_OBJECT *RootOp; ACPI_PARSE_OBJECT *OriginalParentOp; UINT8 WalkType; /* * Only interested in subtrees that could possibly contain * expressions that can be evaluated at this time */ if ((!(Op->Asl.CompileFlags & NODE_COMPILE_TIME_CONST)) || (Op->Asl.CompileFlags & NODE_IS_TARGET)) { return (AE_OK); } /* Set the walk type based on the reduction used for this op */ if (Op->Asl.CompileFlags & NODE_IS_TERM_ARG) { /* Op is a TermArg, constant folding is merely optional */ if (!Gbl_FoldConstants) { return (AE_CTRL_DEPTH); } WalkType = ACPI_WALK_CONST_OPTIONAL; } else { /* Op is a DataObject, the expression MUST reduced to a constant */ WalkType = ACPI_WALK_CONST_REQUIRED; } /* Create a new walk state */ WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL); if (!WalkState) { return AE_NO_MEMORY; } WalkState->NextOp = NULL; WalkState->Params = NULL; WalkState->WalkType = WalkType; WalkState->CallerReturnDesc = &ObjDesc; /* * Examine the entire subtree -- all nodes must be constants * or type 3/4/5 opcodes */ Status = TrWalkParseTree (Op, ASL_WALK_VISIT_DOWNWARD, OpcAmlCheckForConstant, NULL, WalkState); /* * Did we find an entire subtree that contains all constants and type 3/4/5 * opcodes? (Only AE_OK or AE_TYPE returned from above) */ if (Status == AE_TYPE) { /* Subtree cannot be reduced to a constant */ if (WalkState->WalkType == ACPI_WALK_CONST_OPTIONAL) { AcpiDsDeleteWalkState (WalkState); return (AE_OK); } /* Don't descend any further, and use a default "constant" value */ Status = AE_CTRL_DEPTH; } else { /* Subtree can be reduced */ /* Allocate a new temporary root for this subtree */ RootOp = TrAllocateNode (PARSEOP_INTEGER); if (!RootOp) { return (AE_NO_MEMORY); } RootOp->Common.AmlOpcode = AML_INT_EVAL_SUBTREE_OP; OriginalParentOp = Op->Common.Parent; Op->Common.Parent = RootOp; /* Hand off the subtree to the AML interpreter */ Status = TrWalkParseTree (Op, ASL_WALK_VISIT_TWICE, OpcAmlEvaluationWalk1, OpcAmlEvaluationWalk2, WalkState); Op->Common.Parent = OriginalParentOp; /* TBD: we really *should* release the RootOp node */ if (ACPI_SUCCESS (Status)) { TotalFolds++; /* Get the final result */ Status = AcpiDsResultPop (&ObjDesc, WalkState); } /* Check for error from the ACPICA core */ if (ACPI_FAILURE (Status)) { AslCoreSubsystemError (Op, Status, "Failure during constant evaluation", FALSE); } } if (ACPI_FAILURE (Status)) { /* We could not resolve the subtree for some reason */ AslError (ASL_ERROR, ASL_MSG_CONSTANT_EVALUATION, Op, Op->Asl.ParseOpName); /* Set the subtree value to ZERO anyway. Eliminates further errors */ OpcUpdateIntegerNode (Op, 0); } else { AslError (ASL_OPTIMIZATION, ASL_MSG_CONSTANT_FOLDED, Op, Op->Asl.ParseOpName); /* * Because we know we executed type 3/4/5 opcodes above, we know that * the result must be either an Integer, String, or Buffer. */ switch (ObjDesc->Common.Type) { case ACPI_TYPE_INTEGER: OpcUpdateIntegerNode (Op, ObjDesc->Integer.Value); DbgPrint (ASL_PARSE_OUTPUT, "Constant expression reduced to (%s) %8.8X%8.8X\n", Op->Asl.ParseOpName, ACPI_FORMAT_UINT64 (Op->Common.Value.Integer)); break; case ACPI_TYPE_STRING: Op->Asl.ParseOpcode = PARSEOP_STRING_LITERAL; Op->Common.AmlOpcode = AML_STRING_OP; Op->Asl.AmlLength = ACPI_STRLEN (ObjDesc->String.Pointer) + 1; Op->Common.Value.String = ObjDesc->String.Pointer; DbgPrint (ASL_PARSE_OUTPUT, "Constant expression reduced to (STRING) %s\n", Op->Common.Value.String); break; case ACPI_TYPE_BUFFER: Op->Asl.ParseOpcode = PARSEOP_BUFFER; Op->Common.AmlOpcode = AML_BUFFER_OP; Op->Asl.CompileFlags = NODE_AML_PACKAGE; UtSetParseOpName (Op); /* Child node is the buffer length */ RootOp = TrAllocateNode (PARSEOP_INTEGER); RootOp->Asl.AmlOpcode = AML_DWORD_OP; RootOp->Asl.Value.Integer = ObjDesc->Buffer.Length; RootOp->Asl.Parent = Op; (void) OpcSetOptimalIntegerSize (RootOp); Op->Asl.Child = RootOp; Op = RootOp; UtSetParseOpName (Op); /* Peer to the child is the raw buffer data */ RootOp = TrAllocateNode (PARSEOP_RAW_DATA); RootOp->Asl.AmlOpcode = AML_RAW_DATA_BUFFER; RootOp->Asl.AmlLength = ObjDesc->Buffer.Length; RootOp->Asl.Value.String = (char *) ObjDesc->Buffer.Pointer; RootOp->Asl.Parent = Op->Asl.Parent; Op->Asl.Next = RootOp; Op = RootOp; DbgPrint (ASL_PARSE_OUTPUT, "Constant expression reduced to (BUFFER) length %X\n", ObjDesc->Buffer.Length); break; default: printf ("Unsupported return type: %s\n", AcpiUtGetObjectTypeName (ObjDesc)); break; } } UtSetParseOpName (Op); Op->Asl.Child = NULL; AcpiDsDeleteWalkState (WalkState); return (AE_CTRL_DEPTH); }
static void OpcDoPld ( ACPI_PARSE_OBJECT *Op) { UINT8 *Buffer; ACPI_PARSE_OBJECT *Node; ACPI_PLD_INFO PldInfo; ACPI_PARSE_OBJECT *NewOp; if (!Op) { AslError(ASL_ERROR, ASL_MSG_NOT_EXIST, Op, NULL); return; } if (Op->Asl.ParseOpcode != PARSEOP_TOPLD) { AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Op, NULL); return; } Buffer = UtLocalCalloc (ACPI_PLD_BUFFER_SIZE); if (!Buffer) { AslError(ASL_ERROR, ASL_MSG_BUFFER_ALLOCATION, Op, NULL); return; } ACPI_MEMSET (&PldInfo, 0, sizeof (ACPI_PLD_INFO)); Node = Op->Asl.Child; while (Node) { switch (Node->Asl.ParseOpcode) { case PARSEOP_PLD_REVISION: if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) { AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); break; } if (Node->Asl.Child->Asl.Value.Integer > 127) { AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); break; } PldInfo.Revision = (UINT8) Node->Asl.Child->Asl.Value.Integer; break; case PARSEOP_PLD_IGNORECOLOR: if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) { AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); break; } if (Node->Asl.Child->Asl.Value.Integer > 1) { AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); break; } PldInfo.IgnoreColor = (UINT8) Node->Asl.Child->Asl.Value.Integer; break; case PARSEOP_PLD_RED: case PARSEOP_PLD_GREEN: case PARSEOP_PLD_BLUE: if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) { AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); break; } if (Node->Asl.Child->Asl.Value.Integer > 255) { AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); break; } if (Node->Asl.ParseOpcode == PARSEOP_PLD_RED) { PldInfo.Red = (UINT8) Node->Asl.Child->Asl.Value.Integer; } else if (Node->Asl.ParseOpcode == PARSEOP_PLD_GREEN) { PldInfo.Green = (UINT8) Node->Asl.Child->Asl.Value.Integer; } else /* PARSEOP_PLD_BLUE */ { PldInfo.Blue = (UINT8) Node->Asl.Child->Asl.Value.Integer; } break; case PARSEOP_PLD_WIDTH: case PARSEOP_PLD_HEIGHT: if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) { AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); break; } if (Node->Asl.Child->Asl.Value.Integer > 65535) { AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); break; } if (Node->Asl.ParseOpcode == PARSEOP_PLD_WIDTH) { PldInfo.Width = (UINT16) Node->Asl.Child->Asl.Value.Integer; } else /* PARSEOP_PLD_HEIGHT */ { PldInfo.Height = (UINT16) Node->Asl.Child->Asl.Value.Integer; } break; case PARSEOP_PLD_USERVISIBLE: case PARSEOP_PLD_DOCK: case PARSEOP_PLD_LID: if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) { AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); break; } if (Node->Asl.Child->Asl.Value.Integer > 1) { AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); break; } if (Node->Asl.ParseOpcode == PARSEOP_PLD_USERVISIBLE) { PldInfo.UserVisible = (UINT8) Node->Asl.Child->Asl.Value.Integer; } else if (Node->Asl.ParseOpcode == PARSEOP_PLD_DOCK) { PldInfo.Dock = (UINT8) Node->Asl.Child->Asl.Value.Integer; } else { PldInfo.Lid = (UINT8) Node->Asl.Child->Asl.Value.Integer; } break; case PARSEOP_PLD_PANEL: if (Node->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER) { if (Node->Asl.Child->Asl.Value.Integer > 6) { AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); break; } } else /* PARSEOP_STRING */ { if (!OpcFindName(AslPldPanelList, Node->Asl.Child->Asl.Value.String, &Node->Asl.Child->Asl.Value.Integer)) { AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Node, NULL); break; } } PldInfo.Panel = (UINT8) Node->Asl.Child->Asl.Value.Integer; break; case PARSEOP_PLD_VERTICALPOSITION: if (Node->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER) { if (Node->Asl.Child->Asl.Value.Integer > 2) { AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); break; } } else /* PARSEOP_STRING */ { if (!OpcFindName(AslPldVerticalPositionList, Node->Asl.Child->Asl.Value.String, &Node->Asl.Child->Asl.Value.Integer)) { AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Node, NULL); break; } } PldInfo.VerticalPosition = (UINT8) Node->Asl.Child->Asl.Value.Integer; break; case PARSEOP_PLD_HORIZONTALPOSITION: if (Node->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER) { if (Node->Asl.Child->Asl.Value.Integer > 2) { AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); break; } } else /* PARSEOP_STRING */ { if (!OpcFindName(AslPldHorizontalPositionList, Node->Asl.Child->Asl.Value.String, &Node->Asl.Child->Asl.Value.Integer)) { AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Node, NULL); break; } } PldInfo.HorizontalPosition = (UINT8) Node->Asl.Child->Asl.Value.Integer; break; case PARSEOP_PLD_SHAPE: if (Node->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER) { if (Node->Asl.Child->Asl.Value.Integer > 8) { AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); break; } } else /* PARSEOP_STRING */ { if (!OpcFindName(AslPldShapeList, Node->Asl.Child->Asl.Value.String, &Node->Asl.Child->Asl.Value.Integer)) { AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Node, NULL); break; } } PldInfo.Shape = (UINT8) Node->Asl.Child->Asl.Value.Integer; break; case PARSEOP_PLD_GROUPORIENTATION: if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) { AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); break; } if (Node->Asl.Child->Asl.Value.Integer > 1) { AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); break; } PldInfo.GroupOrientation = (UINT8) Node->Asl.Child->Asl.Value.Integer; break; case PARSEOP_PLD_GROUPTOKEN: case PARSEOP_PLD_GROUPPOSITION: if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) { AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); break; } if (Node->Asl.Child->Asl.Value.Integer > 255) { AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); break; } if (Node->Asl.ParseOpcode == PARSEOP_PLD_GROUPTOKEN) { PldInfo.GroupToken = (UINT8) Node->Asl.Child->Asl.Value.Integer; } else /* PARSEOP_PLD_GROUPPOSITION */ { PldInfo.GroupPosition = (UINT8) Node->Asl.Child->Asl.Value.Integer; } break; case PARSEOP_PLD_BAY: case PARSEOP_PLD_EJECTABLE: case PARSEOP_PLD_EJECTREQUIRED: if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) { AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); break; } if (Node->Asl.Child->Asl.Value.Integer > 1) { AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); break; } if (Node->Asl.ParseOpcode == PARSEOP_PLD_BAY) { PldInfo.Bay = (UINT8) Node->Asl.Child->Asl.Value.Integer; } else if (Node->Asl.ParseOpcode == PARSEOP_PLD_EJECTABLE) { PldInfo.Ejectable = (UINT8) Node->Asl.Child->Asl.Value.Integer; } else /* PARSEOP_PLD_EJECTREQUIRED */ { PldInfo.OspmEjectRequired = (UINT8) Node->Asl.Child->Asl.Value.Integer; } break; case PARSEOP_PLD_CABINETNUMBER: case PARSEOP_PLD_CARDCAGENUMBER: if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) { AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); break; } if (Node->Asl.Child->Asl.Value.Integer > 255) { AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); break; } if (Node->Asl.ParseOpcode == PARSEOP_PLD_CABINETNUMBER) { PldInfo.CabinetNumber = (UINT8) Node->Asl.Child->Asl.Value.Integer; } else /* PARSEOP_PLD_CARDCAGENUMBER */ { PldInfo.CardCageNumber = (UINT8) Node->Asl.Child->Asl.Value.Integer; } break; case PARSEOP_PLD_REFERENCE: if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) { AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); break; } if (Node->Asl.Child->Asl.Value.Integer > 1) { AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); break; } PldInfo.Reference = (UINT8) Node->Asl.Child->Asl.Value.Integer; break; case PARSEOP_PLD_ROTATION: if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) { AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); break; } if (Node->Asl.Child->Asl.Value.Integer > 7) { switch (Node->Asl.Child->Asl.Value.Integer) { case 45: Node->Asl.Child->Asl.Value.Integer = 1; break; case 90: Node->Asl.Child->Asl.Value.Integer = 2; break; case 135: Node->Asl.Child->Asl.Value.Integer = 3; break; case 180: Node->Asl.Child->Asl.Value.Integer = 4; break; case 225: Node->Asl.Child->Asl.Value.Integer = 5; break; case 270: Node->Asl.Child->Asl.Value.Integer = 6; break; case 315: Node->Asl.Child->Asl.Value.Integer = 7; break; default: AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); break; } } PldInfo.Rotation = (UINT8) Node->Asl.Child->Asl.Value.Integer; break; case PARSEOP_PLD_ORDER: if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) { AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); break; } if (Node->Asl.Child->Asl.Value.Integer > 31) { AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); break; } PldInfo.Order = (UINT8) Node->Asl.Child->Asl.Value.Integer; break; case PARSEOP_PLD_VERTICALOFFSET: case PARSEOP_PLD_HORIZONTALOFFSET: if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) { AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); break; } if (Node->Asl.Child->Asl.Value.Integer > 65535) { AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); break; } if (Node->Asl.ParseOpcode == PARSEOP_PLD_VERTICALOFFSET) { PldInfo.VerticalOffset = (UINT16) Node->Asl.Child->Asl.Value.Integer; } else /* PARSEOP_PLD_HORIZONTALOFFSET */ { PldInfo.HorizontalOffset = (UINT16) Node->Asl.Child->Asl.Value.Integer; } break; default: AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); break; } Node = Node->Asl.Next; } Buffer = OpcEncodePldBuffer(&PldInfo); /* Change Op to a Buffer */ Op->Asl.ParseOpcode = PARSEOP_BUFFER; Op->Common.AmlOpcode = AML_BUFFER_OP; /* Disable further optimization */ Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST; UtSetParseOpName (Op); /* Child node is the buffer length */ NewOp = TrAllocateNode (PARSEOP_INTEGER); NewOp->Asl.AmlOpcode = AML_BYTE_OP; NewOp->Asl.Value.Integer = 20; NewOp->Asl.Parent = Op; Op->Asl.Child = NewOp; Op = NewOp; /* Peer to the child is the raw buffer data */ NewOp = TrAllocateNode (PARSEOP_RAW_DATA); NewOp->Asl.AmlOpcode = AML_RAW_DATA_BUFFER; NewOp->Asl.AmlLength = 20; NewOp->Asl.Value.String = ACPI_CAST_PTR (char, Buffer); NewOp->Asl.Parent = Op->Asl.Parent; Op->Asl.Next = NewOp; }