root/drivers/acpi/acpica/nsparse.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ACPI_MODULE_NAME
  2. acpi_ns_one_complete_parse
  3. acpi_ns_parse_table

   1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2 /******************************************************************************
   3  *
   4  * Module Name: nsparse - namespace interface to AML parser
   5  *
   6  * Copyright (C) 2000 - 2019, Intel Corp.
   7  *
   8  *****************************************************************************/
   9 
  10 #include <acpi/acpi.h>
  11 #include "accommon.h"
  12 #include "acnamesp.h"
  13 #include "acparser.h"
  14 #include "acdispat.h"
  15 #include "actables.h"
  16 #include "acinterp.h"
  17 
  18 #define _COMPONENT          ACPI_NAMESPACE
  19 ACPI_MODULE_NAME("nsparse")
  20 
  21 /*******************************************************************************
  22  *
  23  * FUNCTION:    ns_execute_table
  24  *
  25  * PARAMETERS:  table_desc      - An ACPI table descriptor for table to parse
  26  *              start_node      - Where to enter the table into the namespace
  27  *
  28  * RETURN:      Status
  29  *
  30  * DESCRIPTION: Load ACPI/AML table by executing the entire table as a single
  31  *              large control method.
  32  *
  33  * NOTE: The point of this is to execute any module-level code in-place
  34  * as the table is parsed. Some AML code depends on this behavior.
  35  *
  36  * It is a run-time option at this time, but will eventually become
  37  * the default.
  38  *
  39  * Note: This causes the table to only have a single-pass parse.
  40  * However, this is compatible with other ACPI implementations.
  41  *
  42  ******************************************************************************/
  43 acpi_status
  44 acpi_ns_execute_table(u32 table_index, struct acpi_namespace_node *start_node)
  45 {
  46         acpi_status status;
  47         struct acpi_table_header *table;
  48         acpi_owner_id owner_id;
  49         struct acpi_evaluate_info *info = NULL;
  50         u32 aml_length;
  51         u8 *aml_start;
  52         union acpi_operand_object *method_obj = NULL;
  53 
  54         ACPI_FUNCTION_TRACE(ns_execute_table);
  55 
  56         status = acpi_get_table_by_index(table_index, &table);
  57         if (ACPI_FAILURE(status)) {
  58                 return_ACPI_STATUS(status);
  59         }
  60 
  61         /* Table must consist of at least a complete header */
  62 
  63         if (table->length < sizeof(struct acpi_table_header)) {
  64                 return_ACPI_STATUS(AE_BAD_HEADER);
  65         }
  66 
  67         aml_start = (u8 *)table + sizeof(struct acpi_table_header);
  68         aml_length = table->length - sizeof(struct acpi_table_header);
  69 
  70         status = acpi_tb_get_owner_id(table_index, &owner_id);
  71         if (ACPI_FAILURE(status)) {
  72                 return_ACPI_STATUS(status);
  73         }
  74 
  75         /* Create, initialize, and link a new temporary method object */
  76 
  77         method_obj = acpi_ut_create_internal_object(ACPI_TYPE_METHOD);
  78         if (!method_obj) {
  79                 return_ACPI_STATUS(AE_NO_MEMORY);
  80         }
  81 
  82         /* Allocate the evaluation information block */
  83 
  84         info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
  85         if (!info) {
  86                 status = AE_NO_MEMORY;
  87                 goto cleanup;
  88         }
  89 
  90         ACPI_DEBUG_PRINT_RAW((ACPI_DB_PARSE,
  91                               "%s: Create table pseudo-method for [%4.4s] @%p, method %p\n",
  92                               ACPI_GET_FUNCTION_NAME, table->signature, table,
  93                               method_obj));
  94 
  95         method_obj->method.aml_start = aml_start;
  96         method_obj->method.aml_length = aml_length;
  97         method_obj->method.owner_id = owner_id;
  98         method_obj->method.info_flags |= ACPI_METHOD_MODULE_LEVEL;
  99 
 100         info->pass_number = ACPI_IMODE_EXECUTE;
 101         info->node = start_node;
 102         info->obj_desc = method_obj;
 103         info->node_flags = info->node->flags;
 104         info->full_pathname = acpi_ns_get_normalized_pathname(info->node, TRUE);
 105         if (!info->full_pathname) {
 106                 status = AE_NO_MEMORY;
 107                 goto cleanup;
 108         }
 109 
 110         /* Optional object evaluation log */
 111 
 112         ACPI_DEBUG_PRINT_RAW((ACPI_DB_EVALUATION,
 113                               "%-26s:  (Definition Block level)\n",
 114                               "Module-level evaluation"));
 115 
 116         status = acpi_ps_execute_table(info);
 117 
 118         /* Optional object evaluation log */
 119 
 120         ACPI_DEBUG_PRINT_RAW((ACPI_DB_EVALUATION,
 121                               "%-26s:  (Definition Block level)\n",
 122                               "Module-level complete"));
 123 
 124 cleanup:
 125         if (info) {
 126                 ACPI_FREE(info->full_pathname);
 127                 info->full_pathname = NULL;
 128         }
 129         ACPI_FREE(info);
 130         acpi_ut_remove_reference(method_obj);
 131         return_ACPI_STATUS(status);
 132 }
 133 
 134 /*******************************************************************************
 135  *
 136  * FUNCTION:    ns_one_complete_parse
 137  *
 138  * PARAMETERS:  pass_number             - 1 or 2
 139  *              table_desc              - The table to be parsed.
 140  *
 141  * RETURN:      Status
 142  *
 143  * DESCRIPTION: Perform one complete parse of an ACPI/AML table.
 144  *
 145  ******************************************************************************/
 146 
 147 acpi_status
 148 acpi_ns_one_complete_parse(u32 pass_number,
 149                            u32 table_index,
 150                            struct acpi_namespace_node *start_node)
 151 {
 152         union acpi_parse_object *parse_root;
 153         acpi_status status;
 154         u32 aml_length;
 155         u8 *aml_start;
 156         struct acpi_walk_state *walk_state;
 157         struct acpi_table_header *table;
 158         acpi_owner_id owner_id;
 159 
 160         ACPI_FUNCTION_TRACE(ns_one_complete_parse);
 161 
 162         status = acpi_get_table_by_index(table_index, &table);
 163         if (ACPI_FAILURE(status)) {
 164                 return_ACPI_STATUS(status);
 165         }
 166 
 167         /* Table must consist of at least a complete header */
 168 
 169         if (table->length < sizeof(struct acpi_table_header)) {
 170                 return_ACPI_STATUS(AE_BAD_HEADER);
 171         }
 172 
 173         aml_start = (u8 *)table + sizeof(struct acpi_table_header);
 174         aml_length = table->length - sizeof(struct acpi_table_header);
 175 
 176         status = acpi_tb_get_owner_id(table_index, &owner_id);
 177         if (ACPI_FAILURE(status)) {
 178                 return_ACPI_STATUS(status);
 179         }
 180 
 181         /* Create and init a Root Node */
 182 
 183         parse_root = acpi_ps_create_scope_op(aml_start);
 184         if (!parse_root) {
 185                 return_ACPI_STATUS(AE_NO_MEMORY);
 186         }
 187 
 188         /* Create and initialize a new walk state */
 189 
 190         walk_state = acpi_ds_create_walk_state(owner_id, NULL, NULL, NULL);
 191         if (!walk_state) {
 192                 acpi_ps_free_op(parse_root);
 193                 return_ACPI_STATUS(AE_NO_MEMORY);
 194         }
 195 
 196         status = acpi_ds_init_aml_walk(walk_state, parse_root, NULL,
 197                                        aml_start, aml_length, NULL,
 198                                        (u8)pass_number);
 199         if (ACPI_FAILURE(status)) {
 200                 acpi_ds_delete_walk_state(walk_state);
 201                 goto cleanup;
 202         }
 203 
 204         /* Found OSDT table, enable the namespace override feature */
 205 
 206         if (ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_OSDT) &&
 207             pass_number == ACPI_IMODE_LOAD_PASS1) {
 208                 walk_state->namespace_override = TRUE;
 209         }
 210 
 211         /* start_node is the default location to load the table */
 212 
 213         if (start_node && start_node != acpi_gbl_root_node) {
 214                 status =
 215                     acpi_ds_scope_stack_push(start_node, ACPI_TYPE_METHOD,
 216                                              walk_state);
 217                 if (ACPI_FAILURE(status)) {
 218                         acpi_ds_delete_walk_state(walk_state);
 219                         goto cleanup;
 220                 }
 221         }
 222 
 223         /* Parse the AML */
 224 
 225         ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
 226                           "*PARSE* pass %u parse\n", pass_number));
 227         acpi_ex_enter_interpreter();
 228         status = acpi_ps_parse_aml(walk_state);
 229         acpi_ex_exit_interpreter();
 230 
 231 cleanup:
 232         acpi_ps_delete_parse_tree(parse_root);
 233         return_ACPI_STATUS(status);
 234 }
 235 
 236 /*******************************************************************************
 237  *
 238  * FUNCTION:    acpi_ns_parse_table
 239  *
 240  * PARAMETERS:  table_desc      - An ACPI table descriptor for table to parse
 241  *              start_node      - Where to enter the table into the namespace
 242  *
 243  * RETURN:      Status
 244  *
 245  * DESCRIPTION: Parse AML within an ACPI table and return a tree of ops
 246  *
 247  ******************************************************************************/
 248 
 249 acpi_status
 250 acpi_ns_parse_table(u32 table_index, struct acpi_namespace_node *start_node)
 251 {
 252         acpi_status status;
 253 
 254         ACPI_FUNCTION_TRACE(ns_parse_table);
 255 
 256         /*
 257          * Executes the AML table as one large control method.
 258          * The point of this is to execute any module-level code in-place
 259          * as the table is parsed. Some AML code depends on this behavior.
 260          *
 261          * Note: This causes the table to only have a single-pass parse.
 262          * However, this is compatible with other ACPI implementations.
 263          */
 264         ACPI_DEBUG_PRINT_RAW((ACPI_DB_PARSE,
 265                               "%s: **** Start table execution pass\n",
 266                               ACPI_GET_FUNCTION_NAME));
 267 
 268         status = acpi_ns_execute_table(table_index, start_node);
 269 
 270         return_ACPI_STATUS(status);
 271 }

/* [<][>][^][v][top][bottom][index][help] */