ACPI_PARSE_OBJECT * TrLinkChildNode ( ACPI_PARSE_OBJECT *Op1, ACPI_PARSE_OBJECT *Op2) { ACPI_PARSE_OBJECT *Next; DbgPrint (ASL_PARSE_OUTPUT, "\nLinkChildNode: Parent=%p (%s), Child=%p (%s)\n\n", Op1, Op1 ? UtGetOpName(Op1->Asl.ParseOpcode): NULL, Op2, Op2 ? UtGetOpName(Op2->Asl.ParseOpcode): NULL); if (!Op1 || !Op2) { return (Op1); } Op1->Asl.Child = Op2; /* Set the child and all peers of the child to point to the parent */ Next = Op2; while (Next) { Next->Asl.Parent = Op1; Next = Next->Asl.Next; } return (Op1); }
ACPI_PARSE_OBJECT * TrLinkPeerNode ( ACPI_PARSE_OBJECT *Op1, ACPI_PARSE_OBJECT *Op2) { ACPI_PARSE_OBJECT *Next; DbgPrint (ASL_PARSE_OUTPUT, "\nLinkPeerNode: 1=%p (%s), 2=%p (%s)\n\n", Op1, Op1 ? UtGetOpName(Op1->Asl.ParseOpcode) : NULL, Op2, Op2 ? UtGetOpName(Op2->Asl.ParseOpcode) : NULL); if ((!Op1) && (!Op2)) { DbgPrint (ASL_PARSE_OUTPUT, "\nTwo Null nodes!\n"); return (Op1); } /* If one of the nodes is null, just return the non-null node */ if (!Op2) { return (Op1); } if (!Op1) { return (Op2); } if (Op1 == Op2) { DbgPrint (ASL_DEBUG_OUTPUT, "\n\n************* Internal error, linking node to itself %p\n\n\n", Op1); AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Op1, "Linking node to itself"); return (Op1); } Op1->Asl.Parent = Op2->Asl.Parent; /* * Op 1 may already have a peer list (such as an IF/ELSE pair), * so we must walk to the end of the list and attach the new * peer at the end */ Next = Op1; while (Next->Asl.Next) { Next = Next->Asl.Next; } Next->Asl.Next = Op2; return (Op1); }
void UtSetParseOpName ( ACPI_PARSE_OBJECT *Op) { strncpy (Op->Asl.ParseOpName, UtGetOpName (Op->Asl.ParseOpcode), ACPI_MAX_PARSEOP_NAME); }
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); }
ACPI_PARSE_OBJECT * TrLinkChildOp ( ACPI_PARSE_OBJECT *Op1, ACPI_PARSE_OBJECT *Op2) { ACPI_PARSE_OBJECT *Next; DbgPrint (ASL_PARSE_OUTPUT, "\nLinkChildOp: Parent=%p (%s), Child=%p (%s)\n", Op1, Op1 ? UtGetOpName(Op1->Asl.ParseOpcode): NULL, Op2, Op2 ? UtGetOpName(Op2->Asl.ParseOpcode): NULL); /* * Converter: if TrLinkChildOp is called to link a method call, * turn on capture comments as it signifies that we are done parsing * a method call. */ if (AcpiGbl_CaptureComments && Op1) { if (Op1->Asl.ParseOpcode == PARSEOP_METHODCALL) { Gbl_CommentState.CaptureComments = TRUE; } Gbl_CommentState.LatestParseOp = Op1; } if (!Op1 || !Op2) { return (Op1); } Op1->Asl.Child = Op2; /* Set the child and all peers of the child to point to the parent */ Next = Op2; while (Next) { Next->Asl.Parent = Op1; Next = Next->Asl.Next; } return (Op1); }
static void ApCheckObjectType ( const char *PredefinedName, ACPI_PARSE_OBJECT *Op, UINT32 ExpectedBtypes) { UINT32 ReturnBtype; switch (Op->Asl.ParseOpcode) { case PARSEOP_ZERO: case PARSEOP_ONE: case PARSEOP_ONES: case PARSEOP_INTEGER: ReturnBtype = ACPI_RTYPE_INTEGER; break; case PARSEOP_BUFFER: ReturnBtype = ACPI_RTYPE_BUFFER; break; case PARSEOP_STRING_LITERAL: ReturnBtype = ACPI_RTYPE_STRING; break; case PARSEOP_PACKAGE: case PARSEOP_VAR_PACKAGE: ReturnBtype = ACPI_RTYPE_PACKAGE; break; default: /* Not one of the supported object types */ goto TypeErrorExit; } /* Exit if the object is one of the expected types */ if (ReturnBtype & ExpectedBtypes) { return; } TypeErrorExit: /* Format the expected types and emit an error message */ ApGetExpectedTypes (StringBuffer, ExpectedBtypes); sprintf (MsgBuffer, "%s: found %s, requires %s", PredefinedName, UtGetOpName (Op->Asl.ParseOpcode), StringBuffer); AslError (ASL_ERROR, ASL_MSG_RESERVED_OPERAND_TYPE, Op, MsgBuffer); }
static void UtDumpParseOpName ( ACPI_PARSE_OBJECT *Op, UINT32 Level, UINT32 DataLength) { char *ParseOpName; UINT32 IndentLength; UINT32 NameLength; UINT32 LineLength; UINT32 PaddingLength; /* Emit the LineNumber/IndentLevel prefix on each output line */ DbgPrint (ASL_TREE_OUTPUT, "%5.5d [%2d]", Op->Asl.LogicalLineNumber, Level); ParseOpName = UtGetOpName (Op->Asl.ParseOpcode); /* Calculate various lengths for output alignment */ IndentLength = Level * DEBUG_SPACES_PER_INDENT; NameLength = strlen (ParseOpName); LineLength = IndentLength + 1 + NameLength + 1 + DataLength; PaddingLength = (DEBUG_MAX_LINE_LENGTH + 1) - LineLength; /* Parse tree indentation is based upon the nesting/indent level */ if (Level) { DbgPrint (ASL_TREE_OUTPUT, "%*s", IndentLength, " "); } /* Emit the actual name here */ DbgPrint (ASL_TREE_OUTPUT, " %s", ParseOpName); /* Emit extra padding blanks for alignment of later data items */ if (LineLength > DEBUG_MAX_LINE_LENGTH) { /* Split a long line immediately after the ParseOpName string */ DbgPrint (ASL_TREE_OUTPUT, "\n%*s", (DEBUG_FULL_LINE_LENGTH - DataLength), " "); } else { DbgPrint (ASL_TREE_OUTPUT, "%*s", PaddingLength, " "); } }
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); }
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 UtPrintFormattedName ( UINT16 ParseOpcode, UINT32 Level) { if (Level) { DbgPrint (ASL_TREE_OUTPUT, "%*s", (3 * Level), " "); } DbgPrint (ASL_TREE_OUTPUT, " %-20.20s", UtGetOpName (ParseOpcode)); if (Level < TEXT_OFFSET) { DbgPrint (ASL_TREE_OUTPUT, "%*s", (TEXT_OFFSET - Level) * 3, " "); } }
static void OpnDoBuffer ( ACPI_PARSE_OBJECT *Op) { ACPI_PARSE_OBJECT *InitializerOp; ACPI_PARSE_OBJECT *BufferLengthOp; /* Optional arguments for this opcode with defaults */ UINT32 BufferLength = 0; /* Opcode and package length first */ /* Buffer Length is next, followed by the initializer list */ BufferLengthOp = Op->Asl.Child; InitializerOp = BufferLengthOp->Asl.Next; /* * If the BufferLength is not an INTEGER or was not specified in the ASL * (DEFAULT_ARG), it is a TermArg that is * evaluated at run-time, and we are therefore finished. */ if ((BufferLengthOp->Asl.ParseOpcode != PARSEOP_INTEGER) && (BufferLengthOp->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)) { return; } /* * We want to count the number of items in the initializer list, because if * it is larger than the buffer length, we will define the buffer size * to be the size of the initializer list (as per the ACPI Specification) */ switch (InitializerOp->Asl.ParseOpcode) { case PARSEOP_INTEGER: case PARSEOP_BYTECONST: case PARSEOP_WORDCONST: case PARSEOP_DWORDCONST: /* The peer list contains the byte list (if any...) */ while (InitializerOp) { /* For buffers, this is a list of raw bytes */ InitializerOp->Asl.AmlOpcode = AML_RAW_DATA_BYTE; InitializerOp->Asl.AmlLength = 1; InitializerOp->Asl.ParseOpcode = PARSEOP_RAW_DATA; BufferLength++; InitializerOp = ASL_GET_PEER_NODE (InitializerOp); } break; case PARSEOP_STRING_LITERAL: /* * Only one initializer, the string. Buffer must be big enough to hold * the string plus the null termination byte */ BufferLength = strlen (InitializerOp->Asl.Value.String) + 1; InitializerOp->Asl.AmlOpcode = AML_RAW_DATA_BUFFER; InitializerOp->Asl.AmlLength = BufferLength; InitializerOp->Asl.ParseOpcode = PARSEOP_RAW_DATA; break; case PARSEOP_RAW_DATA: /* Buffer nodes are already initialized (e.g. Unicode operator) */ return; case PARSEOP_DEFAULT_ARG: break; default: AslError (ASL_ERROR, ASL_MSG_INVALID_OPERAND, InitializerOp, "Unknown buffer initializer opcode"); printf ("Unknown buffer initializer opcode [%s]\n", UtGetOpName (InitializerOp->Asl.ParseOpcode)); return; } /* Check if initializer list is longer than the buffer length */ if (BufferLengthOp->Asl.Value.Integer > BufferLength) { BufferLength = (UINT32) BufferLengthOp->Asl.Value.Integer; } if (!BufferLength) { /* No length AND no items -- issue notice */ AslError (ASL_REMARK, ASL_MSG_BUFFER_LENGTH, BufferLengthOp, NULL); /* But go ahead and put the buffer length of zero into the AML */ } /* * Just set the buffer size node to be the buffer length, regardless * of whether it was previously an integer or a default_arg placeholder */ BufferLengthOp->Asl.ParseOpcode = PARSEOP_INTEGER; BufferLengthOp->Asl.AmlOpcode = AML_DWORD_OP; BufferLengthOp->Asl.Value.Integer = BufferLength; (void) OpcSetOptimalIntegerSize (BufferLengthOp); /* Remaining nodes are handled via the tree walk */ }
ACPI_STATUS ApCheckObjectType ( const char *PredefinedName, ACPI_PARSE_OBJECT *Op, UINT32 ExpectedBtypes, UINT32 PackageIndex) { UINT32 ReturnBtype; char *TypeName; if (!Op) { return (AE_TYPE); } /* Map the parse opcode to a bitmapped return type (RTYPE) */ switch (Op->Asl.ParseOpcode) { case PARSEOP_ZERO: case PARSEOP_ONE: case PARSEOP_ONES: case PARSEOP_INTEGER: ReturnBtype = ACPI_RTYPE_INTEGER; TypeName = "Integer"; break; case PARSEOP_STRING_LITERAL: ReturnBtype = ACPI_RTYPE_STRING; TypeName = "String"; break; case PARSEOP_BUFFER: ReturnBtype = ACPI_RTYPE_BUFFER; TypeName = "Buffer"; break; case PARSEOP_PACKAGE: case PARSEOP_VAR_PACKAGE: ReturnBtype = ACPI_RTYPE_PACKAGE; TypeName = "Package"; break; case PARSEOP_NAMESEG: case PARSEOP_NAMESTRING: /* * Ignore any named references within a package object. * * For Package objects, references are allowed instead of any of the * standard data types (Integer/String/Buffer/Package). These * references are resolved at runtime. NAMESEG and NAMESTRING are * impossible to typecheck at compile time because the type of * any named object can be changed at runtime (for example, * CopyObject will change the type of the target object). */ if (PackageIndex != ACPI_NOT_PACKAGE_ELEMENT) { return (AE_OK); } ReturnBtype = ACPI_RTYPE_REFERENCE; TypeName = "Reference"; break; default: /* Not one of the supported object types */ TypeName = UtGetOpName (Op->Asl.ParseOpcode); goto TypeErrorExit; } /* Exit if the object is one of the expected types */ if (ReturnBtype & ExpectedBtypes) { return (AE_OK); } TypeErrorExit: /* Format the expected types and emit an error message */ AcpiUtGetExpectedReturnTypes (StringBuffer, ExpectedBtypes); if (PackageIndex == ACPI_NOT_PACKAGE_ELEMENT) { sprintf (MsgBuffer, "%4.4s: found %s, %s required", PredefinedName, TypeName, StringBuffer); } else { sprintf (MsgBuffer, "%4.4s: found %s at index %u, %s required", PredefinedName, TypeName, PackageIndex, StringBuffer); } AslError (ASL_ERROR, ASL_MSG_RESERVED_OPERAND_TYPE, Op, MsgBuffer); return (AE_TYPE); }
ACPI_PARSE_OBJECT * TrLinkOpChildren ( 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); TrSetOpEndLineNumber (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_ASL_CODE: Gbl_ParseTreeRoot = Op; Op->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; DbgPrint (ASL_PARSE_OUTPUT, "ASLCODE (Tree Completed)->"); break; case PARSEOP_DEFINITION_BLOCK: 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; } /* The following is for capturing comments */ if (AcpiGbl_CaptureComments) { /* * If there are "regular comments" detected at this point, * then is an endBlk comment. Categorize it as so and distribute * all regular comments to this parse op. */ if (Gbl_CommentListHead) { Op->Asl.EndBlkComment = Gbl_CommentListHead; CvDbgPrint ("EndBlk Comment for %s: %s", Op->Asl.ParseOpName, Gbl_CommentListHead->Comment); Gbl_CommentListHead = NULL; Gbl_CommentListTail = NULL; } } /* Link the new op 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 op 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 = TrAllocateOp (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 ops 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"); if (AcpiGbl_CaptureComments) { Gbl_CommentState.LatestParseOp = Op; CvDbgPrint ("TrLinkOpChildren=====Set latest parse op to this op.\n"); } return (Op); }
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); }
ACPI_PARSE_OBJECT * TrUpdateNode ( UINT32 ParseOpcode, ACPI_PARSE_OBJECT *Op) { if (!Op) { return (NULL); } DbgPrint (ASL_PARSE_OUTPUT, "\nUpdateNode: Old - %s, New - %s\n\n", UtGetOpName (Op->Asl.ParseOpcode), UtGetOpName (ParseOpcode)); /* Assign new opcode and name */ if (Op->Asl.ParseOpcode == PARSEOP_ONES) { switch (ParseOpcode) { case PARSEOP_BYTECONST: Op->Asl.Value.Integer = ACPI_UINT8_MAX; break; case PARSEOP_WORDCONST: Op->Asl.Value.Integer = ACPI_UINT16_MAX; break; case PARSEOP_DWORDCONST: Op->Asl.Value.Integer = ACPI_UINT32_MAX; break; /* Don't need to do the QWORD case */ default: /* Don't care about others */ break; } } Op->Asl.ParseOpcode = (UINT16) ParseOpcode; UtSetParseOpName (Op); /* * For the BYTE, WORD, and DWORD constants, make sure that the integer * that was passed in will actually fit into the data type */ switch (ParseOpcode) { case PARSEOP_BYTECONST: UtCheckIntegerRange (Op, 0x00, ACPI_UINT8_MAX); Op->Asl.Value.Integer &= ACPI_UINT8_MAX; break; case PARSEOP_WORDCONST: UtCheckIntegerRange (Op, 0x00, ACPI_UINT16_MAX); Op->Asl.Value.Integer &= ACPI_UINT16_MAX; break; case PARSEOP_DWORDCONST: UtCheckIntegerRange (Op, 0x00, ACPI_UINT32_MAX); Op->Asl.Value.Integer &= ACPI_UINT32_MAX; break; default: /* Don't care about others, don't need to check QWORD */ break; } return (Op); }
ACPI_PARSE_OBJECT * TrSetOpIntegerValue ( UINT32 ParseOpcode, ACPI_PARSE_OBJECT *Op) { if (!Op) { return (NULL); } DbgPrint (ASL_PARSE_OUTPUT, "\nUpdateOp: Old - %s, New - %s\n", UtGetOpName (Op->Asl.ParseOpcode), UtGetOpName (ParseOpcode)); /* Assign new opcode and name */ if (Op->Asl.ParseOpcode == PARSEOP_ONES) { switch (ParseOpcode) { case PARSEOP_BYTECONST: Op->Asl.Value.Integer = ACPI_UINT8_MAX; break; case PARSEOP_WORDCONST: Op->Asl.Value.Integer = ACPI_UINT16_MAX; break; case PARSEOP_DWORDCONST: Op->Asl.Value.Integer = ACPI_UINT32_MAX; break; /* Don't need to do the QWORD case */ default: /* Don't care about others */ break; } } Op->Asl.ParseOpcode = (UINT16) ParseOpcode; UtSetParseOpName (Op); /* * For the BYTE, WORD, and DWORD constants, make sure that the integer * that was passed in will actually fit into the data type */ switch (ParseOpcode) { case PARSEOP_BYTECONST: UtCheckIntegerRange (Op, 0x00, ACPI_UINT8_MAX); Op->Asl.Value.Integer &= ACPI_UINT8_MAX; break; case PARSEOP_WORDCONST: UtCheckIntegerRange (Op, 0x00, ACPI_UINT16_MAX); Op->Asl.Value.Integer &= ACPI_UINT16_MAX; break; case PARSEOP_DWORDCONST: UtCheckIntegerRange (Op, 0x00, ACPI_UINT32_MAX); Op->Asl.Value.Integer &= ACPI_UINT32_MAX; break; default: /* Don't care about others, don't need to check QWORD */ break; } /* Converter: if this is a method invocation, turn off capture comments */ if (AcpiGbl_CaptureComments && (ParseOpcode == PARSEOP_METHODCALL)) { Gbl_CommentState.CaptureComments = FALSE; } return (Op); }
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); }
ACPI_STATUS ApCheckObjectType ( const char *PredefinedName, ACPI_PARSE_OBJECT *Op, UINT32 ExpectedBtypes, UINT32 PackageIndex) { UINT32 ReturnBtype; char *TypeName; if (!Op) { return (AE_TYPE); } /* Map the parse opcode to a bitmapped return type (RTYPE) */ switch (Op->Asl.ParseOpcode) { case PARSEOP_ZERO: case PARSEOP_ONE: case PARSEOP_ONES: case PARSEOP_INTEGER: ReturnBtype = ACPI_RTYPE_INTEGER; TypeName = "Integer"; break; case PARSEOP_STRING_LITERAL: ReturnBtype = ACPI_RTYPE_STRING; TypeName = "String"; break; case PARSEOP_BUFFER: ReturnBtype = ACPI_RTYPE_BUFFER; TypeName = "Buffer"; break; case PARSEOP_PACKAGE: case PARSEOP_VAR_PACKAGE: ReturnBtype = ACPI_RTYPE_PACKAGE; TypeName = "Package"; break; case PARSEOP_NAMESEG: case PARSEOP_NAMESTRING: ReturnBtype = ACPI_RTYPE_REFERENCE; TypeName = "Reference"; break; default: /* Not one of the supported object types */ TypeName = UtGetOpName (Op->Asl.ParseOpcode); goto TypeErrorExit; } /* Exit if the object is one of the expected types */ if (ReturnBtype & ExpectedBtypes) { return (AE_OK); } TypeErrorExit: /* Format the expected types and emit an error message */ AcpiUtGetExpectedReturnTypes (StringBuffer, ExpectedBtypes); if (PackageIndex == ACPI_NOT_PACKAGE_ELEMENT) { sprintf (MsgBuffer, "%s: found %s, %s required", PredefinedName, TypeName, StringBuffer); } else { sprintf (MsgBuffer, "%s: found %s at index %u, %s required", PredefinedName, TypeName, PackageIndex, StringBuffer); } AslError (ASL_ERROR, ASL_MSG_RESERVED_OPERAND_TYPE, Op, MsgBuffer); return (AE_TYPE); }