LCOV - code coverage report
Current view: top level - drivers/acpi/acpica - nsparse.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 47 92 51.1 %
Date: 2022-04-01 14:17:54 Functions: 2 3 66.7 %
Branches: 7 36 19.4 %

           Branch data     Line data    Source code
       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 - 2020, 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                 :         11 : acpi_ns_execute_table(u32 table_index, struct acpi_namespace_node *start_node)
      45                 :            : {
      46                 :         11 :         acpi_status status;
      47                 :         11 :         struct acpi_table_header *table;
      48                 :         11 :         acpi_owner_id owner_id;
      49                 :         11 :         struct acpi_evaluate_info *info = NULL;
      50                 :         11 :         u32 aml_length;
      51                 :         11 :         u8 *aml_start;
      52                 :         11 :         union acpi_operand_object *method_obj = NULL;
      53                 :            : 
      54                 :         11 :         ACPI_FUNCTION_TRACE(ns_execute_table);
      55                 :            : 
      56                 :         11 :         status = acpi_get_table_by_index(table_index, &table);
      57         [ +  - ]:         11 :         if (ACPI_FAILURE(status)) {
      58                 :            :                 return_ACPI_STATUS(status);
      59                 :            :         }
      60                 :            : 
      61                 :            :         /* Table must consist of at least a complete header */
      62                 :            : 
      63         [ +  - ]:         11 :         if (table->length < sizeof(struct acpi_table_header)) {
      64                 :            :                 return_ACPI_STATUS(AE_BAD_HEADER);
      65                 :            :         }
      66                 :            : 
      67                 :         11 :         aml_start = (u8 *)table + sizeof(struct acpi_table_header);
      68                 :         11 :         aml_length = table->length - sizeof(struct acpi_table_header);
      69                 :            : 
      70                 :         11 :         status = acpi_tb_get_owner_id(table_index, &owner_id);
      71         [ +  - ]:         11 :         if (ACPI_FAILURE(status)) {
      72                 :            :                 return_ACPI_STATUS(status);
      73                 :            :         }
      74                 :            : 
      75                 :            :         /* Create, initialize, and link a new temporary method object */
      76                 :            : 
      77                 :         11 :         method_obj = acpi_ut_create_internal_object(ACPI_TYPE_METHOD);
      78         [ +  - ]:         11 :         if (!method_obj) {
      79                 :            :                 return_ACPI_STATUS(AE_NO_MEMORY);
      80                 :            :         }
      81                 :            : 
      82                 :            :         /* Allocate the evaluation information block */
      83                 :            : 
      84                 :         11 :         info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
      85         [ -  + ]:         11 :         if (!info) {
      86                 :          0 :                 status = AE_NO_MEMORY;
      87                 :          0 :                 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                 :         11 :                               method_obj));
      94                 :            : 
      95                 :         11 :         method_obj->method.aml_start = aml_start;
      96                 :         11 :         method_obj->method.aml_length = aml_length;
      97                 :         11 :         method_obj->method.owner_id = owner_id;
      98                 :         11 :         method_obj->method.info_flags |= ACPI_METHOD_MODULE_LEVEL;
      99                 :            : 
     100                 :         11 :         info->pass_number = ACPI_IMODE_EXECUTE;
     101                 :         11 :         info->node = start_node;
     102                 :         11 :         info->obj_desc = method_obj;
     103                 :         11 :         info->node_flags = info->node->flags;
     104                 :         11 :         info->full_pathname = acpi_ns_get_normalized_pathname(info->node, TRUE);
     105         [ -  + ]:         11 :         if (!info->full_pathname) {
     106                 :          0 :                 status = AE_NO_MEMORY;
     107                 :          0 :                 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                 :         11 :                               "Module-level evaluation"));
     115                 :            : 
     116                 :         11 :         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                 :         11 :                               "Module-level complete"));
     123                 :            : 
     124                 :         11 : cleanup:
     125         [ +  - ]:         11 :         if (info) {
     126                 :         11 :                 ACPI_FREE(info->full_pathname);
     127                 :         11 :                 info->full_pathname = NULL;
     128                 :            :         }
     129                 :         11 :         ACPI_FREE(info);
     130                 :         11 :         acpi_ut_remove_reference(method_obj);
     131                 :         11 :         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                 :          0 : acpi_ns_one_complete_parse(u32 pass_number,
     149                 :            :                            u32 table_index,
     150                 :            :                            struct acpi_namespace_node *start_node)
     151                 :            : {
     152                 :          0 :         union acpi_parse_object *parse_root;
     153                 :          0 :         acpi_status status;
     154                 :          0 :         u32 aml_length;
     155                 :          0 :         u8 *aml_start;
     156                 :          0 :         struct acpi_walk_state *walk_state;
     157                 :          0 :         struct acpi_table_header *table;
     158                 :          0 :         acpi_owner_id owner_id;
     159                 :            : 
     160                 :          0 :         ACPI_FUNCTION_TRACE(ns_one_complete_parse);
     161                 :            : 
     162                 :          0 :         status = acpi_get_table_by_index(table_index, &table);
     163         [ #  # ]:          0 :         if (ACPI_FAILURE(status)) {
     164                 :            :                 return_ACPI_STATUS(status);
     165                 :            :         }
     166                 :            : 
     167                 :            :         /* Table must consist of at least a complete header */
     168                 :            : 
     169         [ #  # ]:          0 :         if (table->length < sizeof(struct acpi_table_header)) {
     170                 :            :                 return_ACPI_STATUS(AE_BAD_HEADER);
     171                 :            :         }
     172                 :            : 
     173                 :          0 :         aml_start = (u8 *)table + sizeof(struct acpi_table_header);
     174                 :          0 :         aml_length = table->length - sizeof(struct acpi_table_header);
     175                 :            : 
     176                 :          0 :         status = acpi_tb_get_owner_id(table_index, &owner_id);
     177         [ #  # ]:          0 :         if (ACPI_FAILURE(status)) {
     178                 :            :                 return_ACPI_STATUS(status);
     179                 :            :         }
     180                 :            : 
     181                 :            :         /* Create and init a Root Node */
     182                 :            : 
     183                 :          0 :         parse_root = acpi_ps_create_scope_op(aml_start);
     184         [ #  # ]:          0 :         if (!parse_root) {
     185                 :            :                 return_ACPI_STATUS(AE_NO_MEMORY);
     186                 :            :         }
     187                 :            : 
     188                 :            :         /* Create and initialize a new walk state */
     189                 :            : 
     190                 :          0 :         walk_state = acpi_ds_create_walk_state(owner_id, NULL, NULL, NULL);
     191         [ #  # ]:          0 :         if (!walk_state) {
     192                 :          0 :                 acpi_ps_free_op(parse_root);
     193                 :          0 :                 return_ACPI_STATUS(AE_NO_MEMORY);
     194                 :            :         }
     195                 :            : 
     196                 :          0 :         status = acpi_ds_init_aml_walk(walk_state, parse_root, NULL,
     197                 :            :                                        aml_start, aml_length, NULL,
     198                 :            :                                        (u8)pass_number);
     199         [ #  # ]:          0 :         if (ACPI_FAILURE(status)) {
     200                 :          0 :                 acpi_ds_delete_walk_state(walk_state);
     201                 :          0 :                 goto cleanup;
     202                 :            :         }
     203                 :            : 
     204                 :            :         /* Found OSDT table, enable the namespace override feature */
     205                 :            : 
     206   [ #  #  #  # ]:          0 :         if (ACPI_COMPARE_NAMESEG(table->signature, ACPI_SIG_OSDT) &&
     207                 :            :             pass_number == ACPI_IMODE_LOAD_PASS1) {
     208                 :          0 :                 walk_state->namespace_override = TRUE;
     209                 :            :         }
     210                 :            : 
     211                 :            :         /* start_node is the default location to load the table */
     212                 :            : 
     213   [ #  #  #  # ]:          0 :         if (start_node && start_node != acpi_gbl_root_node) {
     214                 :          0 :                 status =
     215                 :          0 :                     acpi_ds_scope_stack_push(start_node, ACPI_TYPE_METHOD,
     216                 :            :                                              walk_state);
     217         [ #  # ]:          0 :                 if (ACPI_FAILURE(status)) {
     218                 :          0 :                         acpi_ds_delete_walk_state(walk_state);
     219                 :          0 :                         goto cleanup;
     220                 :            :                 }
     221                 :            :         }
     222                 :            : 
     223                 :            :         /* Parse the AML */
     224                 :            : 
     225                 :            :         ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
     226                 :          0 :                           "*PARSE* pass %u parse\n", pass_number));
     227                 :          0 :         acpi_ex_enter_interpreter();
     228                 :          0 :         status = acpi_ps_parse_aml(walk_state);
     229                 :          0 :         acpi_ex_exit_interpreter();
     230                 :            : 
     231                 :          0 : cleanup:
     232                 :          0 :         acpi_ps_delete_parse_tree(parse_root);
     233                 :          0 :         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                 :         11 : acpi_ns_parse_table(u32 table_index, struct acpi_namespace_node *start_node)
     251                 :            : {
     252                 :         11 :         acpi_status status;
     253                 :            : 
     254                 :         11 :         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                 :         11 :                               ACPI_GET_FUNCTION_NAME));
     267                 :            : 
     268                 :         11 :         status = acpi_ns_execute_table(table_index, start_node);
     269                 :            : 
     270                 :         11 :         return_ACPI_STATUS(status);
     271                 :            : }

Generated by: LCOV version 1.14