LCOV - code coverage report
Current view: top level - drivers/acpi/acpica - dsfield.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 105 225 46.7 %
Date: 2022-04-01 14:17:54 Functions: 4 6 66.7 %
Branches: 31 79 39.2 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
       2                 :            : /******************************************************************************
       3                 :            :  *
       4                 :            :  * Module Name: dsfield - Dispatcher field routines
       5                 :            :  *
       6                 :            :  * Copyright (C) 2000 - 2020, Intel Corp.
       7                 :            :  *
       8                 :            :  *****************************************************************************/
       9                 :            : 
      10                 :            : #include <acpi/acpi.h>
      11                 :            : #include "accommon.h"
      12                 :            : #include "amlcode.h"
      13                 :            : #include "acdispat.h"
      14                 :            : #include "acinterp.h"
      15                 :            : #include "acnamesp.h"
      16                 :            : #include "acparser.h"
      17                 :            : 
      18                 :            : #ifdef ACPI_EXEC_APP
      19                 :            : #include "aecommon.h"
      20                 :            : #endif
      21                 :            : 
      22                 :            : #define _COMPONENT          ACPI_DISPATCHER
      23                 :            : ACPI_MODULE_NAME("dsfield")
      24                 :            : 
      25                 :            : /* Local prototypes */
      26                 :            : #ifdef ACPI_ASL_COMPILER
      27                 :            : #include "acdisasm.h"
      28                 :            : static acpi_status
      29                 :            : acpi_ds_create_external_region(acpi_status lookup_status,
      30                 :            :                                union acpi_parse_object *op,
      31                 :            :                                char *path,
      32                 :            :                                struct acpi_walk_state *walk_state,
      33                 :            :                                struct acpi_namespace_node **node);
      34                 :            : #endif
      35                 :            : 
      36                 :            : static acpi_status
      37                 :            : acpi_ds_get_field_names(struct acpi_create_field_info *info,
      38                 :            :                         struct acpi_walk_state *walk_state,
      39                 :            :                         union acpi_parse_object *arg);
      40                 :            : 
      41                 :            : #ifdef ACPI_ASL_COMPILER
      42                 :            : /*******************************************************************************
      43                 :            :  *
      44                 :            :  * FUNCTION:    acpi_ds_create_external_region (iASL Disassembler only)
      45                 :            :  *
      46                 :            :  * PARAMETERS:  lookup_status   - Status from ns_lookup operation
      47                 :            :  *              op              - Op containing the Field definition and args
      48                 :            :  *              path            - Pathname of the region
      49                 :            :  *  `           walk_state      - Current method state
      50                 :            :  *              node            - Where the new region node is returned
      51                 :            :  *
      52                 :            :  * RETURN:      Status
      53                 :            :  *
      54                 :            :  * DESCRIPTION: Add region to the external list if NOT_FOUND. Create a new
      55                 :            :  *              region node/object.
      56                 :            :  *
      57                 :            :  ******************************************************************************/
      58                 :            : 
      59                 :            : static acpi_status
      60                 :            : acpi_ds_create_external_region(acpi_status lookup_status,
      61                 :            :                                union acpi_parse_object *op,
      62                 :            :                                char *path,
      63                 :            :                                struct acpi_walk_state *walk_state,
      64                 :            :                                struct acpi_namespace_node **node)
      65                 :            : {
      66                 :            :         acpi_status status;
      67                 :            :         union acpi_operand_object *obj_desc;
      68                 :            : 
      69                 :            :         if (lookup_status != AE_NOT_FOUND) {
      70                 :            :                 return (lookup_status);
      71                 :            :         }
      72                 :            : 
      73                 :            :         /*
      74                 :            :          * Table disassembly:
      75                 :            :          * operation_region not found. Generate an External for it, and
      76                 :            :          * insert the name into the namespace.
      77                 :            :          */
      78                 :            :         acpi_dm_add_op_to_external_list(op, path, ACPI_TYPE_REGION, 0, 0);
      79                 :            : 
      80                 :            :         status = acpi_ns_lookup(walk_state->scope_info, path, ACPI_TYPE_REGION,
      81                 :            :                                 ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT,
      82                 :            :                                 walk_state, node);
      83                 :            :         if (ACPI_FAILURE(status)) {
      84                 :            :                 return (status);
      85                 :            :         }
      86                 :            : 
      87                 :            :         /* Must create and install a region object for the new node */
      88                 :            : 
      89                 :            :         obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_REGION);
      90                 :            :         if (!obj_desc) {
      91                 :            :                 return (AE_NO_MEMORY);
      92                 :            :         }
      93                 :            : 
      94                 :            :         obj_desc->region.node = *node;
      95                 :            :         status = acpi_ns_attach_object(*node, obj_desc, ACPI_TYPE_REGION);
      96                 :            :         return (status);
      97                 :            : }
      98                 :            : #endif
      99                 :            : 
     100                 :            : /*******************************************************************************
     101                 :            :  *
     102                 :            :  * FUNCTION:    acpi_ds_create_buffer_field
     103                 :            :  *
     104                 :            :  * PARAMETERS:  op                  - Current parse op (create_XXField)
     105                 :            :  *              walk_state          - Current state
     106                 :            :  *
     107                 :            :  * RETURN:      Status
     108                 :            :  *
     109                 :            :  * DESCRIPTION: Execute the create_field operators:
     110                 :            :  *              create_bit_field_op,
     111                 :            :  *              create_byte_field_op,
     112                 :            :  *              create_word_field_op,
     113                 :            :  *              create_dword_field_op,
     114                 :            :  *              create_qword_field_op,
     115                 :            :  *              create_field_op     (all of which define a field in a buffer)
     116                 :            :  *
     117                 :            :  ******************************************************************************/
     118                 :            : 
     119                 :            : acpi_status
     120                 :        110 : acpi_ds_create_buffer_field(union acpi_parse_object *op,
     121                 :            :                             struct acpi_walk_state *walk_state)
     122                 :            : {
     123                 :        110 :         union acpi_parse_object *arg;
     124                 :        110 :         struct acpi_namespace_node *node;
     125                 :        110 :         acpi_status status;
     126                 :        110 :         union acpi_operand_object *obj_desc;
     127                 :        110 :         union acpi_operand_object *second_desc = NULL;
     128                 :        110 :         u32 flags;
     129                 :            : 
     130                 :        110 :         ACPI_FUNCTION_TRACE(ds_create_buffer_field);
     131                 :            : 
     132                 :            :         /*
     133                 :            :          * Get the name_string argument (name of the new buffer_field)
     134                 :            :          */
     135         [ -  + ]:        110 :         if (op->common.aml_opcode == AML_CREATE_FIELD_OP) {
     136                 :            : 
     137                 :            :                 /* For create_field, name is the 4th argument */
     138                 :            : 
     139                 :          0 :                 arg = acpi_ps_get_arg(op, 3);
     140                 :            :         } else {
     141                 :            :                 /* For all other create_XXXField operators, name is the 3rd argument */
     142                 :            : 
     143                 :        110 :                 arg = acpi_ps_get_arg(op, 2);
     144                 :            :         }
     145                 :            : 
     146         [ +  - ]:        110 :         if (!arg) {
     147                 :            :                 return_ACPI_STATUS(AE_AML_NO_OPERAND);
     148                 :            :         }
     149                 :            : 
     150         [ -  + ]:        110 :         if (walk_state->deferred_node) {
     151                 :          0 :                 node = walk_state->deferred_node;
     152                 :            :         } else {
     153                 :            :                 /* Execute flag should always be set when this function is entered */
     154                 :            : 
     155         [ -  + ]:        110 :                 if (!(walk_state->parse_flags & ACPI_PARSE_EXECUTE)) {
     156                 :          0 :                         ACPI_ERROR((AE_INFO, "Parse execute mode is not set"));
     157                 :          0 :                         return_ACPI_STATUS(AE_AML_INTERNAL);
     158                 :            :                 }
     159                 :            : 
     160                 :            :                 /* Creating new namespace node, should not already exist */
     161                 :            : 
     162                 :        110 :                 flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
     163                 :            :                     ACPI_NS_ERROR_IF_FOUND;
     164                 :            : 
     165                 :            :                 /*
     166                 :            :                  * Mark node temporary if we are executing a normal control
     167                 :            :                  * method. (Don't mark if this is a module-level code method)
     168                 :            :                  */
     169         [ +  - ]:        110 :                 if (walk_state->method_node &&
     170         [ +  - ]:        110 :                     !(walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
     171                 :        110 :                         flags |= ACPI_NS_TEMPORARY;
     172                 :            :                 }
     173                 :            : 
     174                 :            :                 /* Enter the name_string into the namespace */
     175                 :            : 
     176                 :        110 :                 status = acpi_ns_lookup(walk_state->scope_info,
     177                 :            :                                         arg->common.value.string, ACPI_TYPE_ANY,
     178                 :            :                                         ACPI_IMODE_LOAD_PASS1, flags,
     179                 :            :                                         walk_state, &node);
     180         [ -  + ]:        110 :                 if (ACPI_FAILURE(status)) {
     181                 :          0 :                         ACPI_ERROR_NAMESPACE(walk_state->scope_info,
     182                 :          0 :                                              arg->common.value.string, status);
     183                 :          0 :                         return_ACPI_STATUS(status);
     184                 :            :                 }
     185                 :            :         }
     186                 :            : 
     187                 :            :         /*
     188                 :            :          * We could put the returned object (Node) on the object stack for later,
     189                 :            :          * but for now, we will put it in the "op" object that the parser uses,
     190                 :            :          * so we can get it again at the end of this scope.
     191                 :            :          */
     192                 :        110 :         op->common.node = node;
     193                 :            : 
     194                 :            :         /*
     195                 :            :          * If there is no object attached to the node, this node was just created
     196                 :            :          * and we need to create the field object. Otherwise, this was a lookup
     197                 :            :          * of an existing node and we don't want to create the field object again.
     198                 :            :          */
     199                 :        110 :         obj_desc = acpi_ns_get_attached_object(node);
     200         [ +  - ]:        110 :         if (obj_desc) {
     201                 :            :                 return_ACPI_STATUS(AE_OK);
     202                 :            :         }
     203                 :            : 
     204                 :            :         /*
     205                 :            :          * The Field definition is not fully parsed at this time.
     206                 :            :          * (We must save the address of the AML for the buffer and index operands)
     207                 :            :          */
     208                 :            : 
     209                 :            :         /* Create the buffer field object */
     210                 :            : 
     211                 :        110 :         obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER_FIELD);
     212         [ -  + ]:        110 :         if (!obj_desc) {
     213                 :          0 :                 status = AE_NO_MEMORY;
     214                 :          0 :                 goto cleanup;
     215                 :            :         }
     216                 :            : 
     217                 :            :         /*
     218                 :            :          * Remember location in AML stream of the field unit opcode and operands
     219                 :            :          * -- since the buffer and index operands must be evaluated.
     220                 :            :          */
     221                 :        110 :         second_desc = obj_desc->common.next_object;
     222                 :        110 :         second_desc->extra.aml_start = op->named.data;
     223                 :        110 :         second_desc->extra.aml_length = op->named.length;
     224                 :        110 :         obj_desc->buffer_field.node = node;
     225                 :            : 
     226                 :            :         /* Attach constructed field descriptors to parent node */
     227                 :            : 
     228                 :        110 :         status = acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_BUFFER_FIELD);
     229         [ +  - ]:        110 :         if (ACPI_FAILURE(status)) {
     230                 :          0 :                 goto cleanup;
     231                 :            :         }
     232                 :            : 
     233                 :        110 : cleanup:
     234                 :            : 
     235                 :            :         /* Remove local reference to the object */
     236                 :            : 
     237                 :        110 :         acpi_ut_remove_reference(obj_desc);
     238                 :        110 :         return_ACPI_STATUS(status);
     239                 :            : }
     240                 :            : 
     241                 :            : /*******************************************************************************
     242                 :            :  *
     243                 :            :  * FUNCTION:    acpi_ds_get_field_names
     244                 :            :  *
     245                 :            :  * PARAMETERS:  info            - create_field info structure
     246                 :            :  *              walk_state      - Current method state
     247                 :            :  *              arg             - First parser arg for the field name list
     248                 :            :  *
     249                 :            :  * RETURN:      Status
     250                 :            :  *
     251                 :            :  * DESCRIPTION: Process all named fields in a field declaration. Names are
     252                 :            :  *              entered into the namespace.
     253                 :            :  *
     254                 :            :  ******************************************************************************/
     255                 :            : 
     256                 :            : static acpi_status
     257                 :         99 : acpi_ds_get_field_names(struct acpi_create_field_info *info,
     258                 :            :                         struct acpi_walk_state *walk_state,
     259                 :            :                         union acpi_parse_object *arg)
     260                 :            : {
     261                 :         99 :         acpi_status status;
     262                 :         99 :         u64 position;
     263                 :         99 :         union acpi_parse_object *child;
     264                 :            : 
     265                 :            : #ifdef ACPI_EXEC_APP
     266                 :            :         union acpi_operand_object *result_desc;
     267                 :            :         union acpi_operand_object *obj_desc;
     268                 :            :         char *name_path;
     269                 :            : #endif
     270                 :            : 
     271                 :         99 :         ACPI_FUNCTION_TRACE_PTR(ds_get_field_names, info);
     272                 :            : 
     273                 :            :         /* First field starts at bit zero */
     274                 :            : 
     275                 :         99 :         info->field_bit_position = 0;
     276                 :            : 
     277                 :            :         /* Process all elements in the field list (of parse nodes) */
     278                 :            : 
     279         [ +  + ]:        418 :         while (arg) {
     280                 :            :                 /*
     281                 :            :                  * Four types of field elements are handled:
     282                 :            :                  * 1) name - Enters a new named field into the namespace
     283                 :            :                  * 2) offset - specifies a bit offset
     284                 :            :                  * 3) access_as - changes the access mode/attributes
     285                 :            :                  * 4) connection - Associate a resource template with the field
     286                 :            :                  */
     287   [ +  -  -  +  :        319 :                 switch (arg->common.aml_opcode) {
                      - ]
     288                 :         88 :                 case AML_INT_RESERVEDFIELD_OP:
     289                 :            : 
     290                 :         88 :                         position = (u64)info->field_bit_position +
     291                 :         88 :                             (u64)arg->common.value.size;
     292                 :            : 
     293         [ -  + ]:         88 :                         if (position > ACPI_UINT32_MAX) {
     294                 :          0 :                                 ACPI_ERROR((AE_INFO,
     295                 :            :                                             "Bit offset within field too large (> 0xFFFFFFFF)"));
     296                 :          0 :                                 return_ACPI_STATUS(AE_SUPPORT);
     297                 :            :                         }
     298                 :            : 
     299                 :         88 :                         info->field_bit_position = (u32) position;
     300                 :         88 :                         break;
     301                 :            : 
     302                 :          0 :                 case AML_INT_ACCESSFIELD_OP:
     303                 :            :                 case AML_INT_EXTACCESSFIELD_OP:
     304                 :            :                         /*
     305                 :            :                          * Get new access_type, access_attribute, and access_length fields
     306                 :            :                          * -- to be used for all field units that follow, until the
     307                 :            :                          * end-of-field or another access_as keyword is encountered.
     308                 :            :                          * NOTE. These three bytes are encoded in the integer value
     309                 :            :                          * of the parseop for convenience.
     310                 :            :                          *
     311                 :            :                          * In field_flags, preserve the flag bits other than the
     312                 :            :                          * ACCESS_TYPE bits.
     313                 :            :                          */
     314                 :            : 
     315                 :            :                         /* access_type (byte_acc, word_acc, etc.) */
     316                 :            : 
     317                 :          0 :                         info->field_flags = (u8)
     318                 :          0 :                             ((info->
     319                 :          0 :                               field_flags & ~(AML_FIELD_ACCESS_TYPE_MASK)) |
     320                 :          0 :                              ((u8)((u32)(arg->common.value.integer & 0x07))));
     321                 :            : 
     322                 :            :                         /* access_attribute (attrib_quick, attrib_byte, etc.) */
     323                 :            : 
     324                 :          0 :                         info->attribute = (u8)
     325                 :          0 :                             ((arg->common.value.integer >> 8) & 0xFF);
     326                 :            : 
     327                 :            :                         /* access_length (for serial/buffer protocols) */
     328                 :            : 
     329                 :          0 :                         info->access_length = (u8)
     330                 :          0 :                             ((arg->common.value.integer >> 16) & 0xFF);
     331                 :          0 :                         break;
     332                 :            : 
     333                 :          0 :                 case AML_INT_CONNECTION_OP:
     334                 :            :                         /*
     335                 :            :                          * Clear any previous connection. New connection is used for all
     336                 :            :                          * fields that follow, similar to access_as
     337                 :            :                          */
     338                 :          0 :                         info->resource_buffer = NULL;
     339                 :          0 :                         info->connection_node = NULL;
     340                 :          0 :                         info->pin_number_index = 0;
     341                 :            : 
     342                 :            :                         /*
     343                 :            :                          * A Connection() is either an actual resource descriptor (buffer)
     344                 :            :                          * or a named reference to a resource template
     345                 :            :                          */
     346                 :          0 :                         child = arg->common.value.arg;
     347         [ #  # ]:          0 :                         if (child->common.aml_opcode == AML_INT_BYTELIST_OP) {
     348                 :          0 :                                 info->resource_buffer = child->named.data;
     349                 :          0 :                                 info->resource_length =
     350                 :          0 :                                     (u16)child->named.value.integer;
     351                 :            :                         } else {
     352                 :            :                                 /* Lookup the Connection() namepath, it should already exist */
     353                 :            : 
     354                 :          0 :                                 status = acpi_ns_lookup(walk_state->scope_info,
     355                 :            :                                                         child->common.value.
     356                 :            :                                                         name, ACPI_TYPE_ANY,
     357                 :            :                                                         ACPI_IMODE_EXECUTE,
     358                 :            :                                                         ACPI_NS_DONT_OPEN_SCOPE,
     359                 :            :                                                         walk_state,
     360                 :            :                                                         &info->connection_node);
     361         [ #  # ]:          0 :                                 if (ACPI_FAILURE(status)) {
     362                 :          0 :                                         ACPI_ERROR_NAMESPACE(walk_state->
     363                 :            :                                                              scope_info,
     364                 :            :                                                              child->common.
     365                 :            :                                                              value.name,
     366                 :          0 :                                                              status);
     367                 :          0 :                                         return_ACPI_STATUS(status);
     368                 :            :                                 }
     369                 :            :                         }
     370                 :            :                         break;
     371                 :            : 
     372                 :        231 :                 case AML_INT_NAMEDFIELD_OP:
     373                 :            : 
     374                 :            :                         /* Lookup the name, it should already exist */
     375                 :            : 
     376                 :        231 :                         status = acpi_ns_lookup(walk_state->scope_info,
     377                 :        231 :                                                 (char *)&arg->named.name,
     378                 :        231 :                                                 info->field_type,
     379                 :            :                                                 ACPI_IMODE_EXECUTE,
     380                 :            :                                                 ACPI_NS_DONT_OPEN_SCOPE,
     381                 :            :                                                 walk_state, &info->field_node);
     382         [ -  + ]:        231 :                         if (ACPI_FAILURE(status)) {
     383                 :          0 :                                 ACPI_ERROR_NAMESPACE(walk_state->scope_info,
     384                 :            :                                                      (char *)&arg->named.name,
     385                 :          0 :                                                      status);
     386                 :          0 :                                 return_ACPI_STATUS(status);
     387                 :            :                         } else {
     388                 :        231 :                                 arg->common.node = info->field_node;
     389                 :        231 :                                 info->field_bit_length = arg->common.value.size;
     390                 :            : 
     391                 :            :                                 /*
     392                 :            :                                  * If there is no object attached to the node, this node was
     393                 :            :                                  * just created and we need to create the field object.
     394                 :            :                                  * Otherwise, this was a lookup of an existing node and we
     395                 :            :                                  * don't want to create the field object again.
     396                 :            :                                  */
     397         [ +  - ]:        231 :                                 if (!acpi_ns_get_attached_object
     398                 :            :                                     (info->field_node)) {
     399                 :        231 :                                         status = acpi_ex_prep_field_value(info);
     400         [ -  + ]:        231 :                                         if (ACPI_FAILURE(status)) {
     401                 :          0 :                                                 return_ACPI_STATUS(status);
     402                 :            :                                         }
     403                 :            : #ifdef ACPI_EXEC_APP
     404                 :            :                                         name_path =
     405                 :            :                                             acpi_ns_get_external_pathname(info->
     406                 :            :                                                                           field_node);
     407                 :            :                                         if (ACPI_SUCCESS
     408                 :            :                                             (ae_lookup_init_file_entry
     409                 :            :                                              (name_path, &obj_desc))) {
     410                 :            :                                                 acpi_ex_write_data_to_field
     411                 :            :                                                     (obj_desc,
     412                 :            :                                                      acpi_ns_get_attached_object
     413                 :            :                                                      (info->field_node),
     414                 :            :                                                      &result_desc);
     415                 :            :                                                 acpi_ut_remove_reference
     416                 :            :                                                     (obj_desc);
     417                 :            :                                         }
     418                 :            :                                         ACPI_FREE(name_path);
     419                 :            : #endif
     420                 :            :                                 }
     421                 :            :                         }
     422                 :            : 
     423                 :            :                         /* Keep track of bit position for the next field */
     424                 :            : 
     425                 :        231 :                         position = (u64)info->field_bit_position +
     426                 :        231 :                             (u64)arg->common.value.size;
     427                 :            : 
     428         [ -  + ]:        231 :                         if (position > ACPI_UINT32_MAX) {
     429                 :          0 :                                 ACPI_ERROR((AE_INFO,
     430                 :            :                                             "Field [%4.4s] bit offset too large (> 0xFFFFFFFF)",
     431                 :            :                                             ACPI_CAST_PTR(char,
     432                 :            :                                                           &info->field_node->
     433                 :            :                                                           name)));
     434                 :          0 :                                 return_ACPI_STATUS(AE_SUPPORT);
     435                 :            :                         }
     436                 :            : 
     437                 :        231 :                         info->field_bit_position += info->field_bit_length;
     438                 :        231 :                         info->pin_number_index++;    /* Index relative to previous Connection() */
     439                 :        231 :                         break;
     440                 :            : 
     441                 :          0 :                 default:
     442                 :            : 
     443                 :          0 :                         ACPI_ERROR((AE_INFO,
     444                 :            :                                     "Invalid opcode in field list: 0x%X",
     445                 :            :                                     arg->common.aml_opcode));
     446                 :          0 :                         return_ACPI_STATUS(AE_AML_BAD_OPCODE);
     447                 :            :                 }
     448                 :            : 
     449                 :        319 :                 arg = arg->common.next;
     450                 :            :         }
     451                 :            : 
     452                 :            :         return_ACPI_STATUS(AE_OK);
     453                 :            : }
     454                 :            : 
     455                 :            : /*******************************************************************************
     456                 :            :  *
     457                 :            :  * FUNCTION:    acpi_ds_create_field
     458                 :            :  *
     459                 :            :  * PARAMETERS:  op              - Op containing the Field definition and args
     460                 :            :  *              region_node     - Object for the containing Operation Region
     461                 :            :  *  `           walk_state      - Current method state
     462                 :            :  *
     463                 :            :  * RETURN:      Status
     464                 :            :  *
     465                 :            :  * DESCRIPTION: Create a new field in the specified operation region
     466                 :            :  *
     467                 :            :  ******************************************************************************/
     468                 :            : 
     469                 :            : acpi_status
     470                 :         99 : acpi_ds_create_field(union acpi_parse_object *op,
     471                 :            :                      struct acpi_namespace_node *region_node,
     472                 :            :                      struct acpi_walk_state *walk_state)
     473                 :            : {
     474                 :         99 :         acpi_status status;
     475                 :         99 :         union acpi_parse_object *arg;
     476                 :         99 :         struct acpi_create_field_info info;
     477                 :            : 
     478                 :         99 :         ACPI_FUNCTION_TRACE_PTR(ds_create_field, op);
     479                 :            : 
     480                 :            :         /* First arg is the name of the parent op_region (must already exist) */
     481                 :            : 
     482                 :         99 :         arg = op->common.value.arg;
     483                 :            : 
     484         [ +  - ]:         99 :         if (!region_node) {
     485                 :         99 :                 status =
     486                 :         99 :                     acpi_ns_lookup(walk_state->scope_info,
     487                 :            :                                    arg->common.value.name, ACPI_TYPE_REGION,
     488                 :            :                                    ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
     489                 :            :                                    walk_state, &region_node);
     490                 :            : #ifdef ACPI_ASL_COMPILER
     491                 :            :                 status = acpi_ds_create_external_region(status, arg,
     492                 :            :                                                         arg->common.value.name,
     493                 :            :                                                         walk_state,
     494                 :            :                                                         &region_node);
     495                 :            : #endif
     496         [ -  + ]:         99 :                 if (ACPI_FAILURE(status)) {
     497                 :          0 :                         ACPI_ERROR_NAMESPACE(walk_state->scope_info,
     498                 :          0 :                                              arg->common.value.name, status);
     499                 :          0 :                         return_ACPI_STATUS(status);
     500                 :            :                 }
     501                 :            :         }
     502                 :            : 
     503                 :         99 :         memset(&info, 0, sizeof(struct acpi_create_field_info));
     504                 :            : 
     505                 :            :         /* Second arg is the field flags */
     506                 :            : 
     507                 :         99 :         arg = arg->common.next;
     508                 :         99 :         info.field_flags = (u8) arg->common.value.integer;
     509                 :         99 :         info.attribute = 0;
     510                 :            : 
     511                 :            :         /* Each remaining arg is a Named Field */
     512                 :            : 
     513                 :         99 :         info.field_type = ACPI_TYPE_LOCAL_REGION_FIELD;
     514                 :         99 :         info.region_node = region_node;
     515                 :            : 
     516                 :         99 :         status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
     517         [ -  + ]:         99 :         if (info.region_node->object->region.space_id ==
     518                 :            :             ACPI_ADR_SPACE_PLATFORM_COMM
     519         [ #  # ]:          0 :             && !(region_node->object->field.internal_pcc_buffer =
     520                 :          0 :                  ACPI_ALLOCATE_ZEROED(info.region_node->object->region.
     521                 :            :                                       length))) {
     522                 :          0 :                 return_ACPI_STATUS(AE_NO_MEMORY);
     523                 :            :         }
     524                 :            :         return_ACPI_STATUS(status);
     525                 :            : }
     526                 :            : 
     527                 :            : /*******************************************************************************
     528                 :            :  *
     529                 :            :  * FUNCTION:    acpi_ds_init_field_objects
     530                 :            :  *
     531                 :            :  * PARAMETERS:  op              - Op containing the Field definition and args
     532                 :            :  *  `           walk_state      - Current method state
     533                 :            :  *
     534                 :            :  * RETURN:      Status
     535                 :            :  *
     536                 :            :  * DESCRIPTION: For each "Field Unit" name in the argument list that is
     537                 :            :  *              part of the field declaration, enter the name into the
     538                 :            :  *              namespace.
     539                 :            :  *
     540                 :            :  ******************************************************************************/
     541                 :            : 
     542                 :            : acpi_status
     543                 :         99 : acpi_ds_init_field_objects(union acpi_parse_object *op,
     544                 :            :                            struct acpi_walk_state *walk_state)
     545                 :            : {
     546                 :         99 :         acpi_status status;
     547                 :         99 :         union acpi_parse_object *arg = NULL;
     548                 :         99 :         struct acpi_namespace_node *node;
     549                 :         99 :         u8 type = 0;
     550                 :         99 :         u32 flags;
     551                 :            : 
     552                 :         99 :         ACPI_FUNCTION_TRACE_PTR(ds_init_field_objects, op);
     553                 :            : 
     554                 :            :         /* Execute flag should always be set when this function is entered */
     555                 :            : 
     556         [ -  + ]:         99 :         if (!(walk_state->parse_flags & ACPI_PARSE_EXECUTE)) {
     557         [ #  # ]:          0 :                 if (walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP) {
     558                 :            : 
     559                 :            :                         /* bank_field Op is deferred, just return OK */
     560                 :            : 
     561                 :            :                         return_ACPI_STATUS(AE_OK);
     562                 :            :                 }
     563                 :            : 
     564                 :          0 :                 ACPI_ERROR((AE_INFO, "Parse deferred mode is not set"));
     565                 :          0 :                 return_ACPI_STATUS(AE_AML_INTERNAL);
     566                 :            :         }
     567                 :            : 
     568                 :            :         /*
     569                 :            :          * Get the field_list argument for this opcode. This is the start of the
     570                 :            :          * list of field elements.
     571                 :            :          */
     572   [ +  -  -  - ]:         99 :         switch (walk_state->opcode) {
     573                 :         99 :         case AML_FIELD_OP:
     574                 :            : 
     575                 :         99 :                 arg = acpi_ps_get_arg(op, 2);
     576                 :         99 :                 type = ACPI_TYPE_LOCAL_REGION_FIELD;
     577                 :         99 :                 break;
     578                 :            : 
     579                 :          0 :         case AML_BANK_FIELD_OP:
     580                 :            : 
     581                 :          0 :                 arg = acpi_ps_get_arg(op, 4);
     582                 :          0 :                 type = ACPI_TYPE_LOCAL_BANK_FIELD;
     583                 :          0 :                 break;
     584                 :            : 
     585                 :          0 :         case AML_INDEX_FIELD_OP:
     586                 :            : 
     587                 :          0 :                 arg = acpi_ps_get_arg(op, 3);
     588                 :          0 :                 type = ACPI_TYPE_LOCAL_INDEX_FIELD;
     589                 :          0 :                 break;
     590                 :            : 
     591                 :            :         default:
     592                 :            : 
     593                 :            :                 return_ACPI_STATUS(AE_BAD_PARAMETER);
     594                 :            :         }
     595                 :            : 
     596                 :            :         /* Creating new namespace node(s), should not already exist */
     597                 :            : 
     598                 :         99 :         flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
     599                 :            :             ACPI_NS_ERROR_IF_FOUND;
     600                 :            : 
     601                 :            :         /*
     602                 :            :          * Mark node(s) temporary if we are executing a normal control
     603                 :            :          * method. (Don't mark if this is a module-level code method)
     604                 :            :          */
     605         [ +  - ]:         99 :         if (walk_state->method_node &&
     606         [ -  + ]:         99 :             !(walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
     607                 :          0 :                 flags |= ACPI_NS_TEMPORARY;
     608                 :            :         }
     609                 :            : #ifdef ACPI_EXEC_APP
     610                 :            :         flags |= ACPI_NS_OVERRIDE_IF_FOUND;
     611                 :            : #endif
     612                 :            :         /*
     613                 :            :          * Walk the list of entries in the field_list
     614                 :            :          * Note: field_list can be of zero length. In this case, Arg will be NULL.
     615                 :            :          */
     616         [ +  + ]:        418 :         while (arg) {
     617                 :            :                 /*
     618                 :            :                  * Ignore OFFSET/ACCESSAS/CONNECTION terms here; we are only interested
     619                 :            :                  * in the field names in order to enter them into the namespace.
     620                 :            :                  */
     621         [ +  + ]:        319 :                 if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) {
     622                 :        231 :                         status = acpi_ns_lookup(walk_state->scope_info,
     623                 :        231 :                                                 (char *)&arg->named.name, type,
     624                 :            :                                                 ACPI_IMODE_LOAD_PASS1, flags,
     625                 :            :                                                 walk_state, &node);
     626         [ -  + ]:        231 :                         if (ACPI_FAILURE(status)) {
     627                 :          0 :                                 ACPI_ERROR_NAMESPACE(walk_state->scope_info,
     628                 :            :                                                      (char *)&arg->named.name,
     629                 :          0 :                                                      status);
     630         [ #  # ]:          0 :                                 if (status != AE_ALREADY_EXISTS) {
     631                 :          0 :                                         return_ACPI_STATUS(status);
     632                 :            :                                 }
     633                 :            : 
     634                 :            :                                 /* Name already exists, just ignore this error */
     635                 :            :                         }
     636                 :            : 
     637                 :        231 :                         arg->common.node = node;
     638                 :            :                 }
     639                 :            : 
     640                 :            :                 /* Get the next field element in the list */
     641                 :            : 
     642                 :        319 :                 arg = arg->common.next;
     643                 :            :         }
     644                 :            : 
     645                 :            :         return_ACPI_STATUS(AE_OK);
     646                 :            : }
     647                 :            : 
     648                 :            : /*******************************************************************************
     649                 :            :  *
     650                 :            :  * FUNCTION:    acpi_ds_create_bank_field
     651                 :            :  *
     652                 :            :  * PARAMETERS:  op              - Op containing the Field definition and args
     653                 :            :  *              region_node     - Object for the containing Operation Region
     654                 :            :  *              walk_state      - Current method state
     655                 :            :  *
     656                 :            :  * RETURN:      Status
     657                 :            :  *
     658                 :            :  * DESCRIPTION: Create a new bank field in the specified operation region
     659                 :            :  *
     660                 :            :  ******************************************************************************/
     661                 :            : 
     662                 :            : acpi_status
     663                 :          0 : acpi_ds_create_bank_field(union acpi_parse_object *op,
     664                 :            :                           struct acpi_namespace_node *region_node,
     665                 :            :                           struct acpi_walk_state *walk_state)
     666                 :            : {
     667                 :          0 :         acpi_status status;
     668                 :          0 :         union acpi_parse_object *arg;
     669                 :          0 :         struct acpi_create_field_info info;
     670                 :            : 
     671                 :          0 :         ACPI_FUNCTION_TRACE_PTR(ds_create_bank_field, op);
     672                 :            : 
     673                 :            :         /* First arg is the name of the parent op_region (must already exist) */
     674                 :            : 
     675                 :          0 :         arg = op->common.value.arg;
     676         [ #  # ]:          0 :         if (!region_node) {
     677                 :          0 :                 status =
     678                 :          0 :                     acpi_ns_lookup(walk_state->scope_info,
     679                 :            :                                    arg->common.value.name, ACPI_TYPE_REGION,
     680                 :            :                                    ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
     681                 :            :                                    walk_state, &region_node);
     682                 :            : #ifdef ACPI_ASL_COMPILER
     683                 :            :                 status = acpi_ds_create_external_region(status, arg,
     684                 :            :                                                         arg->common.value.name,
     685                 :            :                                                         walk_state,
     686                 :            :                                                         &region_node);
     687                 :            : #endif
     688         [ #  # ]:          0 :                 if (ACPI_FAILURE(status)) {
     689                 :          0 :                         ACPI_ERROR_NAMESPACE(walk_state->scope_info,
     690                 :          0 :                                              arg->common.value.name, status);
     691                 :          0 :                         return_ACPI_STATUS(status);
     692                 :            :                 }
     693                 :            :         }
     694                 :            : 
     695                 :            :         /* Second arg is the Bank Register (Field) (must already exist) */
     696                 :            : 
     697                 :          0 :         arg = arg->common.next;
     698                 :          0 :         status =
     699                 :          0 :             acpi_ns_lookup(walk_state->scope_info, arg->common.value.string,
     700                 :            :                            ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
     701                 :            :                            ACPI_NS_SEARCH_PARENT, walk_state,
     702                 :            :                            &info.register_node);
     703         [ #  # ]:          0 :         if (ACPI_FAILURE(status)) {
     704                 :          0 :                 ACPI_ERROR_NAMESPACE(walk_state->scope_info,
     705                 :          0 :                                      arg->common.value.string, status);
     706                 :          0 :                 return_ACPI_STATUS(status);
     707                 :            :         }
     708                 :            : 
     709                 :            :         /*
     710                 :            :          * Third arg is the bank_value
     711                 :            :          * This arg is a term_arg, not a constant
     712                 :            :          * It will be evaluated later, by acpi_ds_eval_bank_field_operands
     713                 :            :          */
     714                 :          0 :         arg = arg->common.next;
     715                 :            : 
     716                 :            :         /* Fourth arg is the field flags */
     717                 :            : 
     718                 :          0 :         arg = arg->common.next;
     719                 :          0 :         info.field_flags = (u8) arg->common.value.integer;
     720                 :            : 
     721                 :            :         /* Each remaining arg is a Named Field */
     722                 :            : 
     723                 :          0 :         info.field_type = ACPI_TYPE_LOCAL_BANK_FIELD;
     724                 :          0 :         info.region_node = region_node;
     725                 :            : 
     726                 :            :         /*
     727                 :            :          * Use Info.data_register_node to store bank_field Op
     728                 :            :          * It's safe because data_register_node will never be used when create
     729                 :            :          * bank field \we store aml_start and aml_length in the bank_field Op for
     730                 :            :          * late evaluation. Used in acpi_ex_prep_field_value(Info)
     731                 :            :          *
     732                 :            :          * TBD: Or, should we add a field in struct acpi_create_field_info, like
     733                 :            :          * "void *ParentOp"?
     734                 :            :          */
     735                 :          0 :         info.data_register_node = (struct acpi_namespace_node *)op;
     736                 :            : 
     737                 :          0 :         status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
     738                 :          0 :         return_ACPI_STATUS(status);
     739                 :            : }
     740                 :            : 
     741                 :            : /*******************************************************************************
     742                 :            :  *
     743                 :            :  * FUNCTION:    acpi_ds_create_index_field
     744                 :            :  *
     745                 :            :  * PARAMETERS:  op              - Op containing the Field definition and args
     746                 :            :  *              region_node     - Object for the containing Operation Region
     747                 :            :  *  `           walk_state      - Current method state
     748                 :            :  *
     749                 :            :  * RETURN:      Status
     750                 :            :  *
     751                 :            :  * DESCRIPTION: Create a new index field in the specified operation region
     752                 :            :  *
     753                 :            :  ******************************************************************************/
     754                 :            : 
     755                 :            : acpi_status
     756                 :          0 : acpi_ds_create_index_field(union acpi_parse_object *op,
     757                 :            :                            struct acpi_namespace_node *region_node,
     758                 :            :                            struct acpi_walk_state *walk_state)
     759                 :            : {
     760                 :          0 :         acpi_status status;
     761                 :          0 :         union acpi_parse_object *arg;
     762                 :          0 :         struct acpi_create_field_info info;
     763                 :            : 
     764                 :          0 :         ACPI_FUNCTION_TRACE_PTR(ds_create_index_field, op);
     765                 :            : 
     766                 :            :         /* First arg is the name of the Index register (must already exist) */
     767                 :            : 
     768                 :          0 :         arg = op->common.value.arg;
     769                 :          0 :         status =
     770                 :          0 :             acpi_ns_lookup(walk_state->scope_info, arg->common.value.string,
     771                 :            :                            ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
     772                 :            :                            ACPI_NS_SEARCH_PARENT, walk_state,
     773                 :            :                            &info.register_node);
     774         [ #  # ]:          0 :         if (ACPI_FAILURE(status)) {
     775                 :          0 :                 ACPI_ERROR_NAMESPACE(walk_state->scope_info,
     776                 :          0 :                                      arg->common.value.string, status);
     777                 :          0 :                 return_ACPI_STATUS(status);
     778                 :            :         }
     779                 :            : 
     780                 :            :         /* Second arg is the data register (must already exist) */
     781                 :            : 
     782                 :          0 :         arg = arg->common.next;
     783                 :          0 :         status =
     784                 :          0 :             acpi_ns_lookup(walk_state->scope_info, arg->common.value.string,
     785                 :            :                            ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
     786                 :            :                            ACPI_NS_SEARCH_PARENT, walk_state,
     787                 :            :                            &info.data_register_node);
     788         [ #  # ]:          0 :         if (ACPI_FAILURE(status)) {
     789                 :          0 :                 ACPI_ERROR_NAMESPACE(walk_state->scope_info,
     790                 :          0 :                                      arg->common.value.string, status);
     791                 :          0 :                 return_ACPI_STATUS(status);
     792                 :            :         }
     793                 :            : 
     794                 :            :         /* Next arg is the field flags */
     795                 :            : 
     796                 :          0 :         arg = arg->common.next;
     797                 :          0 :         info.field_flags = (u8) arg->common.value.integer;
     798                 :            : 
     799                 :            :         /* Each remaining arg is a Named Field */
     800                 :            : 
     801                 :          0 :         info.field_type = ACPI_TYPE_LOCAL_INDEX_FIELD;
     802                 :          0 :         info.region_node = region_node;
     803                 :            : 
     804                 :          0 :         status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
     805                 :          0 :         return_ACPI_STATUS(status);
     806                 :            : }

Generated by: LCOV version 1.14