1 /******************************************************************************
   2  *
   3  * Module Name: psscope - Parser scope stack management routines
   4  *
   5  *****************************************************************************/
   6 
   7 /*
   8  * Copyright (C) 2000 - 2014, Intel Corp.
   9  * All rights reserved.
  10  *
  11  * Redistribution and use in source and binary forms, with or without
  12  * modification, are permitted provided that the following conditions
  13  * are met:
  14  * 1. Redistributions of source code must retain the above copyright
  15  *    notice, this list of conditions, and the following disclaimer,
  16  *    without modification.
  17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  18  *    substantially similar to the "NO WARRANTY" disclaimer below
  19  *    ("Disclaimer") and any redistribution must be conditioned upon
  20  *    including a substantially similar Disclaimer requirement for further
  21  *    binary redistribution.
  22  * 3. Neither the names of the above-listed copyright holders nor the names
  23  *    of any contributors may be used to endorse or promote products derived
  24  *    from this software without specific prior written permission.
  25  *
  26  * Alternatively, this software may be distributed under the terms of the
  27  * GNU General Public License ("GPL") version 2 as published by the Free
  28  * Software Foundation.
  29  *
  30  * NO WARRANTY
  31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
  34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  41  * POSSIBILITY OF SUCH DAMAGES.
  42  */
  43 
  44 
  45 #include "acpi.h"
  46 #include "accommon.h"
  47 #include "acparser.h"
  48 
  49 #define _COMPONENT          ACPI_PARSER
  50         ACPI_MODULE_NAME    ("psscope")
  51 
  52 
  53 /*******************************************************************************
  54  *
  55  * FUNCTION:    AcpiPsGetParentScope
  56  *
  57  * PARAMETERS:  ParserState         - Current parser state object
  58  *
  59  * RETURN:      Pointer to an Op object
  60  *
  61  * DESCRIPTION: Get parent of current op being parsed
  62  *
  63  ******************************************************************************/
  64 
  65 ACPI_PARSE_OBJECT *
  66 AcpiPsGetParentScope (
  67     ACPI_PARSE_STATE        *ParserState)
  68 {
  69 
  70     return (ParserState->Scope->ParseScope.Op);
  71 }
  72 
  73 
  74 /*******************************************************************************
  75  *
  76  * FUNCTION:    AcpiPsHasCompletedScope
  77  *
  78  * PARAMETERS:  ParserState         - Current parser state object
  79  *
  80  * RETURN:      Boolean, TRUE = scope completed.
  81  *
  82  * DESCRIPTION: Is parsing of current argument complete?  Determined by
  83  *              1) AML pointer is at or beyond the end of the scope
  84  *              2) The scope argument count has reached zero.
  85  *
  86  ******************************************************************************/
  87 
  88 BOOLEAN
  89 AcpiPsHasCompletedScope (
  90     ACPI_PARSE_STATE        *ParserState)
  91 {
  92 
  93     return ((BOOLEAN)
  94             ((ParserState->Aml >= ParserState->Scope->ParseScope.ArgEnd ||
  95              !ParserState->Scope->ParseScope.ArgCount)));
  96 }
  97 
  98 
  99 /*******************************************************************************
 100  *
 101  * FUNCTION:    AcpiPsInitScope
 102  *
 103  * PARAMETERS:  ParserState         - Current parser state object
 104  *              Root                - the Root Node of this new scope
 105  *
 106  * RETURN:      Status
 107  *
 108  * DESCRIPTION: Allocate and init a new scope object
 109  *
 110  ******************************************************************************/
 111 
 112 ACPI_STATUS
 113 AcpiPsInitScope (
 114     ACPI_PARSE_STATE        *ParserState,
 115     ACPI_PARSE_OBJECT       *RootOp)
 116 {
 117     ACPI_GENERIC_STATE      *Scope;
 118 
 119 
 120     ACPI_FUNCTION_TRACE_PTR (PsInitScope, RootOp);
 121 
 122 
 123     Scope = AcpiUtCreateGenericState ();
 124     if (!Scope)
 125     {
 126         return_ACPI_STATUS (AE_NO_MEMORY);
 127     }
 128 
 129     Scope->Common.DescriptorType = ACPI_DESC_TYPE_STATE_RPSCOPE;
 130     Scope->ParseScope.Op = RootOp;
 131     Scope->ParseScope.ArgCount = ACPI_VAR_ARGS;
 132     Scope->ParseScope.ArgEnd = ParserState->AmlEnd;
 133     Scope->ParseScope.PkgEnd = ParserState->AmlEnd;
 134 
 135     ParserState->Scope = Scope;
 136     ParserState->StartOp = RootOp;
 137 
 138     return_ACPI_STATUS (AE_OK);
 139 }
 140 
 141 
 142 /*******************************************************************************
 143  *
 144  * FUNCTION:    AcpiPsPushScope
 145  *
 146  * PARAMETERS:  ParserState         - Current parser state object
 147  *              Op                  - Current op to be pushed
 148  *              RemainingArgs       - List of args remaining
 149  *              ArgCount            - Fixed or variable number of args
 150  *
 151  * RETURN:      Status
 152  *
 153  * DESCRIPTION: Push current op to begin parsing its argument
 154  *
 155  ******************************************************************************/
 156 
 157 ACPI_STATUS
 158 AcpiPsPushScope (
 159     ACPI_PARSE_STATE        *ParserState,
 160     ACPI_PARSE_OBJECT       *Op,
 161     UINT32                  RemainingArgs,
 162     UINT32                  ArgCount)
 163 {
 164     ACPI_GENERIC_STATE      *Scope;
 165 
 166 
 167     ACPI_FUNCTION_TRACE_PTR (PsPushScope, Op);
 168 
 169 
 170     Scope = AcpiUtCreateGenericState ();
 171     if (!Scope)
 172     {
 173         return_ACPI_STATUS (AE_NO_MEMORY);
 174     }
 175 
 176     Scope->Common.DescriptorType = ACPI_DESC_TYPE_STATE_PSCOPE;
 177     Scope->ParseScope.Op = Op;
 178     Scope->ParseScope.ArgList = RemainingArgs;
 179     Scope->ParseScope.ArgCount = ArgCount;
 180     Scope->ParseScope.PkgEnd = ParserState->PkgEnd;
 181 
 182     /* Push onto scope stack */
 183 
 184     AcpiUtPushGenericState (&ParserState->Scope, Scope);
 185 
 186     if (ArgCount == ACPI_VAR_ARGS)
 187     {
 188         /* Multiple arguments */
 189 
 190         Scope->ParseScope.ArgEnd = ParserState->PkgEnd;
 191     }
 192     else
 193     {
 194         /* Single argument */
 195 
 196         Scope->ParseScope.ArgEnd = ACPI_TO_POINTER (ACPI_MAX_PTR);
 197     }
 198 
 199     return_ACPI_STATUS (AE_OK);
 200 }
 201 
 202 
 203 /*******************************************************************************
 204  *
 205  * FUNCTION:    AcpiPsPopScope
 206  *
 207  * PARAMETERS:  ParserState         - Current parser state object
 208  *              Op                  - Where the popped op is returned
 209  *              ArgList             - Where the popped "next argument" is
 210  *                                    returned
 211  *              ArgCount            - Count of objects in ArgList
 212  *
 213  * RETURN:      Status
 214  *
 215  * DESCRIPTION: Return to parsing a previous op
 216  *
 217  ******************************************************************************/
 218 
 219 void
 220 AcpiPsPopScope (
 221     ACPI_PARSE_STATE        *ParserState,
 222     ACPI_PARSE_OBJECT       **Op,
 223     UINT32                  *ArgList,
 224     UINT32                  *ArgCount)
 225 {
 226     ACPI_GENERIC_STATE      *Scope = ParserState->Scope;
 227 
 228 
 229     ACPI_FUNCTION_TRACE (PsPopScope);
 230 
 231 
 232     /* Only pop the scope if there is in fact a next scope */
 233 
 234     if (Scope->Common.Next)
 235     {
 236         Scope = AcpiUtPopGenericState (&ParserState->Scope);
 237 
 238         /* Return to parsing previous op */
 239 
 240         *Op                 = Scope->ParseScope.Op;
 241         *ArgList            = Scope->ParseScope.ArgList;
 242         *ArgCount           = Scope->ParseScope.ArgCount;
 243         ParserState->PkgEnd = Scope->ParseScope.PkgEnd;
 244 
 245         /* All done with this scope state structure */
 246 
 247         AcpiUtDeleteGenericState (Scope);
 248     }
 249     else
 250     {
 251         /* Empty parse stack, prepare to fetch next opcode */
 252 
 253         *Op       = NULL;
 254         *ArgList  = 0;
 255         *ArgCount = 0;
 256     }
 257 
 258     ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
 259         "Popped Op %p Args %X\n", *Op, *ArgCount));
 260     return_VOID;
 261 }
 262 
 263 
 264 /*******************************************************************************
 265  *
 266  * FUNCTION:    AcpiPsCleanupScope
 267  *
 268  * PARAMETERS:  ParserState         - Current parser state object
 269  *
 270  * RETURN:      None
 271  *
 272  * DESCRIPTION: Destroy available list, remaining stack levels, and return
 273  *              root scope
 274  *
 275  ******************************************************************************/
 276 
 277 void
 278 AcpiPsCleanupScope (
 279     ACPI_PARSE_STATE        *ParserState)
 280 {
 281     ACPI_GENERIC_STATE      *Scope;
 282 
 283 
 284     ACPI_FUNCTION_TRACE_PTR (PsCleanupScope, ParserState);
 285 
 286 
 287     if (!ParserState)
 288     {
 289         return_VOID;
 290     }
 291 
 292     /* Delete anything on the scope stack */
 293 
 294     while (ParserState->Scope)
 295     {
 296         Scope = AcpiUtPopGenericState (&ParserState->Scope);
 297         AcpiUtDeleteGenericState (Scope);
 298     }
 299 
 300     return_VOID;
 301 }