linux/drivers/acpi/acpica/psscope.c
<<
>>
Prefs
   1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2/******************************************************************************
   3 *
   4 * Module Name: psscope - Parser scope stack management routines
   5 *
   6 * Copyright (C) 2000 - 2021, Intel Corp.
   7 *
   8 *****************************************************************************/
   9
  10#include <acpi/acpi.h>
  11#include "accommon.h"
  12#include "acparser.h"
  13
  14#define _COMPONENT          ACPI_PARSER
  15ACPI_MODULE_NAME("psscope")
  16
  17/*******************************************************************************
  18 *
  19 * FUNCTION:    acpi_ps_get_parent_scope
  20 *
  21 * PARAMETERS:  parser_state        - Current parser state object
  22 *
  23 * RETURN:      Pointer to an Op object
  24 *
  25 * DESCRIPTION: Get parent of current op being parsed
  26 *
  27 ******************************************************************************/
  28union acpi_parse_object *acpi_ps_get_parent_scope(struct acpi_parse_state
  29                                                  *parser_state)
  30{
  31
  32        return (parser_state->scope->parse_scope.op);
  33}
  34
  35/*******************************************************************************
  36 *
  37 * FUNCTION:    acpi_ps_has_completed_scope
  38 *
  39 * PARAMETERS:  parser_state        - Current parser state object
  40 *
  41 * RETURN:      Boolean, TRUE = scope completed.
  42 *
  43 * DESCRIPTION: Is parsing of current argument complete?  Determined by
  44 *              1) AML pointer is at or beyond the end of the scope
  45 *              2) The scope argument count has reached zero.
  46 *
  47 ******************************************************************************/
  48
  49u8 acpi_ps_has_completed_scope(struct acpi_parse_state * parser_state)
  50{
  51
  52        return ((u8)
  53                ((parser_state->aml >= parser_state->scope->parse_scope.arg_end
  54                  || !parser_state->scope->parse_scope.arg_count)));
  55}
  56
  57/*******************************************************************************
  58 *
  59 * FUNCTION:    acpi_ps_init_scope
  60 *
  61 * PARAMETERS:  parser_state        - Current parser state object
  62 *              root                - the Root Node of this new scope
  63 *
  64 * RETURN:      Status
  65 *
  66 * DESCRIPTION: Allocate and init a new scope object
  67 *
  68 ******************************************************************************/
  69
  70acpi_status
  71acpi_ps_init_scope(struct acpi_parse_state * parser_state,
  72                   union acpi_parse_object * root_op)
  73{
  74        union acpi_generic_state *scope;
  75
  76        ACPI_FUNCTION_TRACE_PTR(ps_init_scope, root_op);
  77
  78        scope = acpi_ut_create_generic_state();
  79        if (!scope) {
  80                return_ACPI_STATUS(AE_NO_MEMORY);
  81        }
  82
  83        scope->common.descriptor_type = ACPI_DESC_TYPE_STATE_RPSCOPE;
  84        scope->parse_scope.op = root_op;
  85        scope->parse_scope.arg_count = ACPI_VAR_ARGS;
  86        scope->parse_scope.arg_end = parser_state->aml_end;
  87        scope->parse_scope.pkg_end = parser_state->aml_end;
  88
  89        parser_state->scope = scope;
  90        parser_state->start_op = root_op;
  91
  92        return_ACPI_STATUS(AE_OK);
  93}
  94
  95/*******************************************************************************
  96 *
  97 * FUNCTION:    acpi_ps_push_scope
  98 *
  99 * PARAMETERS:  parser_state        - Current parser state object
 100 *              op                  - Current op to be pushed
 101 *              remaining_args      - List of args remaining
 102 *              arg_count           - Fixed or variable number of args
 103 *
 104 * RETURN:      Status
 105 *
 106 * DESCRIPTION: Push current op to begin parsing its argument
 107 *
 108 ******************************************************************************/
 109
 110acpi_status
 111acpi_ps_push_scope(struct acpi_parse_state *parser_state,
 112                   union acpi_parse_object *op,
 113                   u32 remaining_args, u32 arg_count)
 114{
 115        union acpi_generic_state *scope;
 116
 117        ACPI_FUNCTION_TRACE_PTR(ps_push_scope, op);
 118
 119        scope = acpi_ut_create_generic_state();
 120        if (!scope) {
 121                return_ACPI_STATUS(AE_NO_MEMORY);
 122        }
 123
 124        scope->common.descriptor_type = ACPI_DESC_TYPE_STATE_PSCOPE;
 125        scope->parse_scope.op = op;
 126        scope->parse_scope.arg_list = remaining_args;
 127        scope->parse_scope.arg_count = arg_count;
 128        scope->parse_scope.pkg_end = parser_state->pkg_end;
 129
 130        /* Push onto scope stack */
 131
 132        acpi_ut_push_generic_state(&parser_state->scope, scope);
 133
 134        if (arg_count == ACPI_VAR_ARGS) {
 135
 136                /* Multiple arguments */
 137
 138                scope->parse_scope.arg_end = parser_state->pkg_end;
 139        } else {
 140                /* Single argument */
 141
 142                scope->parse_scope.arg_end = ACPI_TO_POINTER(ACPI_MAX_PTR);
 143        }
 144
 145        return_ACPI_STATUS(AE_OK);
 146}
 147
 148/*******************************************************************************
 149 *
 150 * FUNCTION:    acpi_ps_pop_scope
 151 *
 152 * PARAMETERS:  parser_state        - Current parser state object
 153 *              op                  - Where the popped op is returned
 154 *              arg_list            - Where the popped "next argument" is
 155 *                                    returned
 156 *              arg_count           - Count of objects in arg_list
 157 *
 158 * RETURN:      Status
 159 *
 160 * DESCRIPTION: Return to parsing a previous op
 161 *
 162 ******************************************************************************/
 163
 164void
 165acpi_ps_pop_scope(struct acpi_parse_state *parser_state,
 166                  union acpi_parse_object **op, u32 * arg_list, u32 * arg_count)
 167{
 168        union acpi_generic_state *scope = parser_state->scope;
 169
 170        ACPI_FUNCTION_TRACE(ps_pop_scope);
 171
 172        /* Only pop the scope if there is in fact a next scope */
 173
 174        if (scope->common.next) {
 175                scope = acpi_ut_pop_generic_state(&parser_state->scope);
 176
 177                /* Return to parsing previous op */
 178
 179                *op = scope->parse_scope.op;
 180                *arg_list = scope->parse_scope.arg_list;
 181                *arg_count = scope->parse_scope.arg_count;
 182                parser_state->pkg_end = scope->parse_scope.pkg_end;
 183
 184                /* All done with this scope state structure */
 185
 186                acpi_ut_delete_generic_state(scope);
 187        } else {
 188                /* Empty parse stack, prepare to fetch next opcode */
 189
 190                *op = NULL;
 191                *arg_list = 0;
 192                *arg_count = 0;
 193        }
 194
 195        ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
 196                          "Popped Op %p Args %X\n", *op, *arg_count));
 197        return_VOID;
 198}
 199
 200/*******************************************************************************
 201 *
 202 * FUNCTION:    acpi_ps_cleanup_scope
 203 *
 204 * PARAMETERS:  parser_state        - Current parser state object
 205 *
 206 * RETURN:      None
 207 *
 208 * DESCRIPTION: Destroy available list, remaining stack levels, and return
 209 *              root scope
 210 *
 211 ******************************************************************************/
 212
 213void acpi_ps_cleanup_scope(struct acpi_parse_state *parser_state)
 214{
 215        union acpi_generic_state *scope;
 216
 217        ACPI_FUNCTION_TRACE_PTR(ps_cleanup_scope, parser_state);
 218
 219        if (!parser_state) {
 220                return_VOID;
 221        }
 222
 223        /* Delete anything on the scope stack */
 224
 225        while (parser_state->scope) {
 226                scope = acpi_ut_pop_generic_state(&parser_state->scope);
 227                acpi_ut_delete_generic_state(scope);
 228        }
 229
 230        return_VOID;
 231}
 232