⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 asltransform.c

📁 acpi tools for linux include acpiexec and acpixtract
💻 C
📖 第 1 页 / 共 2 页
字号:
 * RETURN:      None * * DESCRIPTION: Find the end of the definition block and set a global to this *              node.  It is used by the compiler to insert compiler-generated *              names at the root level of the namespace. * ******************************************************************************/static voidTrDoDefinitionBlock (    ACPI_PARSE_OBJECT       *Op){    ACPI_PARSE_OBJECT       *Next;    UINT32                  i;    Next = Op->Asl.Child;    for (i = 0; i < 5; i++)    {        Next = Next->Asl.Next;        if (i == 0)        {            /*             * This is the table signature. Only the DSDT can be assumed             * to be at the root of the namespace;  Therefore, namepath             * optimization can only be performed on the DSDT.             */            if (!ACPI_COMPARE_NAME (Next->Asl.Value.String, ACPI_SIG_DSDT))            {                Gbl_ReferenceOptimizationFlag = FALSE;            }        }    }    Gbl_FirstLevelInsertionNode = Next;}/******************************************************************************* * * FUNCTION:    TrDoSwitch * * PARAMETERS:  StartNode        - Parse node for SWITCH * * RETURN:      None * * * DESCRIPTION: Translate ASL SWITCH statement to if/else pairs.  There is *              no actual AML opcode for SWITCH -- it must be simulated. * ******************************************************************************/static voidTrDoSwitch (    ACPI_PARSE_OBJECT       *StartNode){    ACPI_PARSE_OBJECT       *Next;    ACPI_PARSE_OBJECT       *CaseOp = NULL;    ACPI_PARSE_OBJECT       *CaseBlock = NULL;    ACPI_PARSE_OBJECT       *DefaultOp = NULL;    ACPI_PARSE_OBJECT       *CurrentParentNode;    ACPI_PARSE_OBJECT       *Conditional = NULL;    ACPI_PARSE_OBJECT       *Predicate;    ACPI_PARSE_OBJECT       *Peer;    ACPI_PARSE_OBJECT       *NewOp;    ACPI_PARSE_OBJECT       *NewOp2;    char                    *PredicateValueName;    UINT16                  Index;    UINT32                  Btype;    /* Start node is the Switch() node */    CurrentParentNode  = StartNode;    /* Create a new temp name of the form _T_x */    PredicateValueName = TrAmlGetNextTempName (StartNode, &Gbl_TempCount);    if (!PredicateValueName)    {        return;    }    /* First child is the Switch() predicate */    Next = StartNode->Asl.Child;    /*     * Examine the return type of the Switch Value -     * must be Integer/Buffer/String     */    Index = (UINT16) (Next->Asl.ParseOpcode - ASL_PARSE_OPCODE_BASE);    Btype = AslKeywordMapping[Index].AcpiBtype;    if ((Btype != ACPI_BTYPE_INTEGER) &&        (Btype != ACPI_BTYPE_STRING)  &&        (Btype != ACPI_BTYPE_BUFFER))    {        AslError (ASL_WARNING, ASL_MSG_SWITCH_TYPE, Next, NULL);        Btype = ACPI_BTYPE_INTEGER;    }    /* CASE statements start at next child */    Peer = Next->Asl.Next;    while (Peer)    {        Next = Peer;        Peer = Next->Asl.Next;        if (Next->Asl.ParseOpcode == PARSEOP_CASE)        {            if (CaseOp)            {                /* Add an ELSE to complete the previous CASE */                if (!Conditional)                {                    return;                }                NewOp             = TrCreateLeafNode (PARSEOP_ELSE);                NewOp->Asl.Parent = Conditional->Asl.Parent;                TrAmlInitLineNumbers (NewOp, NewOp->Asl.Parent);                /* Link ELSE node as a peer to the previous IF */                TrAmlInsertPeer (Conditional, NewOp);                CurrentParentNode = NewOp;            }            CaseOp      = Next;            Conditional = CaseOp;            CaseBlock   = CaseOp->Asl.Child->Asl.Next;            Conditional->Asl.Child->Asl.Next = NULL;            Predicate = CaseOp->Asl.Child;            if ((Predicate->Asl.ParseOpcode == PARSEOP_PACKAGE) ||                (Predicate->Asl.ParseOpcode == PARSEOP_VAR_PACKAGE))            {                /*                 * Convert the package declaration to this form:                 *                 * If (LNotEqual (Match (Package(<size>){<data>},                 *                       MEQ, _T_x, MTR, Zero, Zero), Ones))                 */                NewOp2              = TrCreateLeafNode (PARSEOP_MATCHTYPE_MEQ);                Predicate->Asl.Next = NewOp2;                TrAmlInitLineNumbers (NewOp2, Conditional);                NewOp               = NewOp2;                NewOp2              = TrCreateValuedLeafNode (PARSEOP_NAMESTRING,                                        (ACPI_INTEGER) ACPI_TO_INTEGER (PredicateValueName));                NewOp->Asl.Next     = NewOp2;                TrAmlInitLineNumbers (NewOp2, Predicate);                NewOp               = NewOp2;                NewOp2              = TrCreateLeafNode (PARSEOP_MATCHTYPE_MTR);                NewOp->Asl.Next     = NewOp2;                TrAmlInitLineNumbers (NewOp2, Predicate);                NewOp               = NewOp2;                NewOp2              = TrCreateLeafNode (PARSEOP_ZERO);                NewOp->Asl.Next     = NewOp2;                TrAmlInitLineNumbers (NewOp2, Predicate);                NewOp               = NewOp2;                NewOp2              = TrCreateLeafNode (PARSEOP_ZERO);                NewOp->Asl.Next     = NewOp2;                TrAmlInitLineNumbers (NewOp2, Predicate);                NewOp2              = TrCreateLeafNode (PARSEOP_MATCH);                NewOp2->Asl.Child   = Predicate;  /* PARSEOP_PACKAGE */                TrAmlInitLineNumbers (NewOp2, Conditional);                TrAmlSetSubtreeParent (Predicate, NewOp2);                NewOp               = NewOp2;                NewOp2              = TrCreateLeafNode (PARSEOP_ONES);                NewOp->Asl.Next     = NewOp2;                TrAmlInitLineNumbers (NewOp2, Conditional);                NewOp2              = TrCreateLeafNode (PARSEOP_LEQUAL);                NewOp2->Asl.Child   = NewOp;                NewOp->Asl.Parent   = NewOp2;                TrAmlInitLineNumbers (NewOp2, Conditional);                TrAmlSetSubtreeParent (NewOp, NewOp2);                NewOp               = NewOp2;                NewOp2              = TrCreateLeafNode (PARSEOP_LNOT);                NewOp2->Asl.Child   = NewOp;                NewOp2->Asl.Parent  = Conditional;                NewOp->Asl.Parent   = NewOp2;                TrAmlInitLineNumbers (NewOp2, Conditional);                Conditional->Asl.Child = NewOp2;                NewOp2->Asl.Next = CaseBlock;            }            else            {                /*                 * Integer and Buffer case.                 *                 * Change CaseOp() to:  If (LEqual (SwitchValue, CaseValue)) {...}                 * Note: SwitchValue is first to allow the CaseValue to be implicitly                 * converted to the type of SwitchValue if necessary.                 *                 * CaseOp->Child is the case value                 * CaseOp->Child->Peer is the beginning of the case block                 */                NewOp = TrCreateValuedLeafNode (PARSEOP_NAMESTRING,                            (ACPI_INTEGER) ACPI_TO_INTEGER (PredicateValueName));                NewOp->Asl.Next = Predicate;                TrAmlInitLineNumbers (NewOp, Predicate);                NewOp2              = TrCreateLeafNode (PARSEOP_LEQUAL);                NewOp2->Asl.Parent  = Conditional;                NewOp2->Asl.Child   = NewOp;                TrAmlInitLineNumbers (NewOp2, Conditional);                TrAmlSetSubtreeParent (NewOp, NewOp2);                Predicate           = NewOp2;                Predicate->Asl.Next = CaseBlock;                TrAmlSetSubtreeParent (Predicate, Conditional);                Conditional->Asl.Child = Predicate;            }            /* Reinitialize the CASE node to an IF node */            TrAmlInitNode (Conditional, PARSEOP_IF);            /*             * The first CASE(IF) is not nested under an ELSE.             * All other CASEs are children of a parent ELSE.             */            if (CurrentParentNode == StartNode)            {                Conditional->Asl.Parent = CurrentParentNode->Asl.Parent;                /* Link IF into the peer list */                TrAmlInsertPeer (CurrentParentNode, Conditional);            }            else            {                /*                 * The IF is a child of previous IF/ELSE.  It                 * is therefore without peer.                 */                CurrentParentNode->Asl.Child = Conditional;                Conditional->Asl.Parent      = CurrentParentNode;                Conditional->Asl.Next        = NULL;            }        }        else if (Next->Asl.ParseOpcode == PARSEOP_DEFAULT)        {            if (DefaultOp)            {                /*                 * More than one Default                 * (Parser does not catch this, must check here)                 */                AslError (ASL_ERROR, ASL_MSG_MULTIPLE_DEFAULT, Next, NULL);            }            else            {                /* Save the DEFAULT node for later, after CASEs */                DefaultOp = Next;            }        }        else        {            /* Unknown peer opcode */            AcpiOsPrintf ("Unknown parse opcode for switch statement: %s (%d)\n",                        Next->Asl.ParseOpName, Next->Asl.ParseOpcode);        }    }    /* Add the default case at the end of the if/else construct */    if (DefaultOp)    {        /* If no CASE statements, this is an error - see below */        if (CaseOp)        {            /* Convert the DEFAULT node to an ELSE */            if (!Conditional)            {                return;            }            TrAmlInitNode (DefaultOp, PARSEOP_ELSE);            DefaultOp->Asl.Parent = Conditional->Asl.Parent;            /* Link ELSE node as a peer to the previous IF */            TrAmlInsertPeer (Conditional, DefaultOp);        }    }    if (!CaseOp)    {        AslError (ASL_ERROR, ASL_MSG_NO_CASES, StartNode, NULL);    }    /*     * Create a Name(_T_x, ...) statement. This statement must appear at the     * method level, in case a loop surrounds the switch statement and could     * cause the name to be created twice (error).     */    /* Create the Name node */    Predicate = StartNode->Asl.Child;    NewOp = TrCreateLeafNode (PARSEOP_NAME);    /* Find the parent method */    Next = StartNode;    while ((Next->Asl.ParseOpcode != PARSEOP_METHOD) &&           (Next->Asl.ParseOpcode != PARSEOP_DEFINITIONBLOCK))    {        Next = Next->Asl.Parent;    }    NewOp->Asl.CompileFlags |= NODE_COMPILER_EMITTED;    NewOp->Asl.Parent = Next;    /* Insert name after the method name and arguments */    Next = Next->Asl.Child;    Next = Next->Asl.Next;    Next = Next->Asl.Next;    Next = Next->Asl.Next;    Next = Next->Asl.Next;    Next = Next->Asl.Next;    TrAmlInsertPeer (Next, NewOp);    TrAmlInitLineNumbers (NewOp, Next);    /* Create the NameSeg child for the Name node */    NewOp2 = TrCreateValuedLeafNode (PARSEOP_NAMESEG,                (ACPI_INTEGER) ACPI_TO_INTEGER (PredicateValueName));    NewOp2->Asl.CompileFlags |= NODE_IS_NAME_DECLARATION;    NewOp->Asl.Child  = NewOp2;    /* Create the initial value for the Name. Btype was already validated above */    switch (Btype)    {    case ACPI_BTYPE_INTEGER:        NewOp2->Asl.Next = TrCreateValuedLeafNode (PARSEOP_ZERO,                                (ACPI_INTEGER) 0);        break;    case ACPI_BTYPE_STRING:        NewOp2->Asl.Next = TrCreateValuedLeafNode (PARSEOP_STRING_LITERAL,                                (ACPI_INTEGER) "");        break;    case ACPI_BTYPE_BUFFER:        (void) TrLinkPeerNode (NewOp2, TrCreateValuedLeafNode (PARSEOP_BUFFER,                                    (ACPI_INTEGER) 0));        Next = NewOp2->Asl.Next;        (void) TrLinkChildren (Next, 1, TrCreateValuedLeafNode (PARSEOP_ZERO,                                    (ACPI_INTEGER) 1));        (void) TrLinkPeerNode (Next->Asl.Child,            TrCreateValuedLeafNode (PARSEOP_DEFAULT_ARG, (ACPI_INTEGER) 0));        TrAmlSetSubtreeParent (Next->Asl.Child, Next);        break;    default:        break;    }    TrAmlSetSubtreeParent (NewOp2, NewOp);    /*     * Transform the Switch() into a Store() node which will be used to save the     * Switch() value.  The store is of the form: Store (Value, _T_x)     * where _T_x is the temp variable.     */    TrAmlInitNode (StartNode, PARSEOP_STORE);    StartNode->Asl.Child = NULL;    /* Complete the Store subtree */    StartNode->Asl.Child = Predicate;    Predicate->Asl.Parent = StartNode;    NewOp = TrCreateValuedLeafNode (PARSEOP_NAMESEG,                (ACPI_INTEGER) ACPI_TO_INTEGER (PredicateValueName));    NewOp->Asl.Parent    = StartNode;    Predicate->Asl.Next  = NewOp;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -