LCOV - code coverage report
Current view: top level - drivers/acpi/acpica - excreate.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 81 139 58.3 %
Date: 2022-04-01 14:58:12 Functions: 4 7 57.1 %
Branches: 10 30 33.3 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
       2                 :            : /******************************************************************************
       3                 :            :  *
       4                 :            :  * Module Name: excreate - Named object creation
       5                 :            :  *
       6                 :            :  * Copyright (C) 2000 - 2020, Intel Corp.
       7                 :            :  *
       8                 :            :  *****************************************************************************/
       9                 :            : 
      10                 :            : #include <acpi/acpi.h>
      11                 :            : #include "accommon.h"
      12                 :            : #include "acinterp.h"
      13                 :            : #include "amlcode.h"
      14                 :            : #include "acnamesp.h"
      15                 :            : 
      16                 :            : #define _COMPONENT          ACPI_EXECUTER
      17                 :            : ACPI_MODULE_NAME("excreate")
      18                 :            : /*******************************************************************************
      19                 :            :  *
      20                 :            :  * FUNCTION:    acpi_ex_create_alias
      21                 :            :  *
      22                 :            :  * PARAMETERS:  walk_state           - Current state, contains operands
      23                 :            :  *
      24                 :            :  * RETURN:      Status
      25                 :            :  *
      26                 :            :  * DESCRIPTION: Create a new named alias
      27                 :            :  *
      28                 :            :  ******************************************************************************/
      29                 :          0 : acpi_status acpi_ex_create_alias(struct acpi_walk_state *walk_state)
      30                 :            : {
      31                 :          0 :         struct acpi_namespace_node *target_node;
      32                 :          0 :         struct acpi_namespace_node *alias_node;
      33                 :          0 :         acpi_status status = AE_OK;
      34                 :            : 
      35                 :          0 :         ACPI_FUNCTION_TRACE(ex_create_alias);
      36                 :            : 
      37                 :            :         /* Get the source/alias operands (both namespace nodes) */
      38                 :            : 
      39                 :          0 :         alias_node = (struct acpi_namespace_node *)walk_state->operands[0];
      40                 :          0 :         target_node = (struct acpi_namespace_node *)walk_state->operands[1];
      41                 :            : 
      42         [ #  # ]:          0 :         if ((target_node->type == ACPI_TYPE_LOCAL_ALIAS) ||
      43                 :            :             (target_node->type == ACPI_TYPE_LOCAL_METHOD_ALIAS)) {
      44                 :            :                 /*
      45                 :            :                  * Dereference an existing alias so that we don't create a chain
      46                 :            :                  * of aliases. With this code, we guarantee that an alias is
      47                 :            :                  * always exactly one level of indirection away from the
      48                 :            :                  * actual aliased name.
      49                 :            :                  */
      50                 :          0 :                 target_node =
      51                 :            :                     ACPI_CAST_PTR(struct acpi_namespace_node,
      52                 :            :                                   target_node->object);
      53                 :            :         }
      54                 :            : 
      55                 :            :         /* Ensure that the target node is valid */
      56                 :            : 
      57         [ #  # ]:          0 :         if (!target_node) {
      58                 :            :                 return_ACPI_STATUS(AE_NULL_OBJECT);
      59                 :            :         }
      60                 :            : 
      61                 :            :         /* Construct the alias object (a namespace node) */
      62                 :            : 
      63         [ #  # ]:          0 :         switch (target_node->type) {
      64                 :          0 :         case ACPI_TYPE_METHOD:
      65                 :            :                 /*
      66                 :            :                  * Control method aliases need to be differentiated with
      67                 :            :                  * a special type
      68                 :            :                  */
      69                 :          0 :                 alias_node->type = ACPI_TYPE_LOCAL_METHOD_ALIAS;
      70                 :          0 :                 break;
      71                 :            : 
      72                 :          0 :         default:
      73                 :            :                 /*
      74                 :            :                  * All other object types.
      75                 :            :                  *
      76                 :            :                  * The new alias has the type ALIAS and points to the original
      77                 :            :                  * NS node, not the object itself.
      78                 :            :                  */
      79                 :          0 :                 alias_node->type = ACPI_TYPE_LOCAL_ALIAS;
      80                 :          0 :                 alias_node->object =
      81                 :            :                     ACPI_CAST_PTR(union acpi_operand_object, target_node);
      82                 :          0 :                 break;
      83                 :            :         }
      84                 :            : 
      85                 :            :         /* Since both operands are Nodes, we don't need to delete them */
      86                 :            : 
      87                 :          0 :         alias_node->object =
      88                 :            :             ACPI_CAST_PTR(union acpi_operand_object, target_node);
      89                 :          0 :         return_ACPI_STATUS(status);
      90                 :            : }
      91                 :            : 
      92                 :            : /*******************************************************************************
      93                 :            :  *
      94                 :            :  * FUNCTION:    acpi_ex_create_event
      95                 :            :  *
      96                 :            :  * PARAMETERS:  walk_state          - Current state
      97                 :            :  *
      98                 :            :  * RETURN:      Status
      99                 :            :  *
     100                 :            :  * DESCRIPTION: Create a new event object
     101                 :            :  *
     102                 :            :  ******************************************************************************/
     103                 :            : 
     104                 :          0 : acpi_status acpi_ex_create_event(struct acpi_walk_state *walk_state)
     105                 :            : {
     106                 :          0 :         acpi_status status;
     107                 :          0 :         union acpi_operand_object *obj_desc;
     108                 :            : 
     109                 :          0 :         ACPI_FUNCTION_TRACE(ex_create_event);
     110                 :            : 
     111                 :          0 :         obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_EVENT);
     112         [ #  # ]:          0 :         if (!obj_desc) {
     113                 :          0 :                 status = AE_NO_MEMORY;
     114                 :          0 :                 goto cleanup;
     115                 :            :         }
     116                 :            : 
     117                 :            :         /*
     118                 :            :          * Create the actual OS semaphore, with zero initial units -- meaning
     119                 :            :          * that the event is created in an unsignalled state
     120                 :            :          */
     121                 :          0 :         status = acpi_os_create_semaphore(ACPI_NO_UNIT_LIMIT, 0,
     122                 :            :                                           &obj_desc->event.os_semaphore);
     123         [ #  # ]:          0 :         if (ACPI_FAILURE(status)) {
     124                 :          0 :                 goto cleanup;
     125                 :            :         }
     126                 :            : 
     127                 :            :         /* Attach object to the Node */
     128                 :            : 
     129                 :          0 :         status = acpi_ns_attach_object((struct acpi_namespace_node *)
     130                 :          0 :                                        walk_state->operands[0], obj_desc,
     131                 :            :                                        ACPI_TYPE_EVENT);
     132                 :            : 
     133                 :          0 : cleanup:
     134                 :            :         /*
     135                 :            :          * Remove local reference to the object (on error, will cause deletion
     136                 :            :          * of both object and semaphore if present.)
     137                 :            :          */
     138                 :          0 :         acpi_ut_remove_reference(obj_desc);
     139                 :          0 :         return_ACPI_STATUS(status);
     140                 :            : }
     141                 :            : 
     142                 :            : /*******************************************************************************
     143                 :            :  *
     144                 :            :  * FUNCTION:    acpi_ex_create_mutex
     145                 :            :  *
     146                 :            :  * PARAMETERS:  walk_state          - Current state
     147                 :            :  *
     148                 :            :  * RETURN:      Status
     149                 :            :  *
     150                 :            :  * DESCRIPTION: Create a new mutex object
     151                 :            :  *
     152                 :            :  *              Mutex (Name[0], sync_level[1])
     153                 :            :  *
     154                 :            :  ******************************************************************************/
     155                 :            : 
     156                 :          6 : acpi_status acpi_ex_create_mutex(struct acpi_walk_state *walk_state)
     157                 :            : {
     158                 :          6 :         acpi_status status = AE_OK;
     159                 :          6 :         union acpi_operand_object *obj_desc;
     160                 :            : 
     161                 :          6 :         ACPI_FUNCTION_TRACE_PTR(ex_create_mutex, ACPI_WALK_OPERANDS);
     162                 :            : 
     163                 :            :         /* Create the new mutex object */
     164                 :            : 
     165                 :          6 :         obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_MUTEX);
     166         [ -  + ]:          6 :         if (!obj_desc) {
     167                 :          0 :                 status = AE_NO_MEMORY;
     168                 :          0 :                 goto cleanup;
     169                 :            :         }
     170                 :            : 
     171                 :            :         /* Create the actual OS Mutex */
     172                 :            : 
     173                 :          6 :         status = acpi_os_create_mutex(&obj_desc->mutex.os_mutex);
     174         [ -  + ]:          6 :         if (ACPI_FAILURE(status)) {
     175                 :          0 :                 goto cleanup;
     176                 :            :         }
     177                 :            : 
     178                 :            :         /* Init object and attach to NS node */
     179                 :            : 
     180                 :          6 :         obj_desc->mutex.sync_level = (u8)walk_state->operands[1]->integer.value;
     181                 :          6 :         obj_desc->mutex.node =
     182                 :          6 :             (struct acpi_namespace_node *)walk_state->operands[0];
     183                 :            : 
     184                 :          6 :         status =
     185                 :          6 :             acpi_ns_attach_object(obj_desc->mutex.node, obj_desc,
     186                 :            :                                   ACPI_TYPE_MUTEX);
     187                 :            : 
     188                 :          6 : cleanup:
     189                 :            :         /*
     190                 :            :          * Remove local reference to the object (on error, will cause deletion
     191                 :            :          * of both object and semaphore if present.)
     192                 :            :          */
     193                 :          6 :         acpi_ut_remove_reference(obj_desc);
     194                 :          6 :         return_ACPI_STATUS(status);
     195                 :            : }
     196                 :            : 
     197                 :            : /*******************************************************************************
     198                 :            :  *
     199                 :            :  * FUNCTION:    acpi_ex_create_region
     200                 :            :  *
     201                 :            :  * PARAMETERS:  aml_start           - Pointer to the region declaration AML
     202                 :            :  *              aml_length          - Max length of the declaration AML
     203                 :            :  *              space_id            - Address space ID for the region
     204                 :            :  *              walk_state          - Current state
     205                 :            :  *
     206                 :            :  * RETURN:      Status
     207                 :            :  *
     208                 :            :  * DESCRIPTION: Create a new operation region object
     209                 :            :  *
     210                 :            :  ******************************************************************************/
     211                 :            : 
     212                 :            : acpi_status
     213                 :         24 : acpi_ex_create_region(u8 * aml_start,
     214                 :            :                       u32 aml_length,
     215                 :            :                       u8 space_id, struct acpi_walk_state *walk_state)
     216                 :            : {
     217                 :         24 :         acpi_status status;
     218                 :         24 :         union acpi_operand_object *obj_desc;
     219                 :         24 :         struct acpi_namespace_node *node;
     220                 :         24 :         union acpi_operand_object *region_obj2;
     221                 :            : 
     222                 :         24 :         ACPI_FUNCTION_TRACE(ex_create_region);
     223                 :            : 
     224                 :            :         /* Get the Namespace Node */
     225                 :            : 
     226                 :         24 :         node = walk_state->op->common.node;
     227                 :            : 
     228                 :            :         /*
     229                 :            :          * If the region object is already attached to this node,
     230                 :            :          * just return
     231                 :            :          */
     232         [ +  - ]:         24 :         if (acpi_ns_get_attached_object(node)) {
     233                 :            :                 return_ACPI_STATUS(AE_OK);
     234                 :            :         }
     235                 :            : 
     236                 :            :         /*
     237                 :            :          * Space ID must be one of the predefined IDs, or in the user-defined
     238                 :            :          * range
     239                 :            :          */
     240         [ -  + ]:         24 :         if (!acpi_is_valid_space_id(space_id)) {
     241                 :            :                 /*
     242                 :            :                  * Print an error message, but continue. We don't want to abort
     243                 :            :                  * a table load for this exception. Instead, if the region is
     244                 :            :                  * actually used at runtime, abort the executing method.
     245                 :            :                  */
     246                 :          0 :                 ACPI_ERROR((AE_INFO,
     247                 :            :                             "Invalid/unknown Address Space ID: 0x%2.2X",
     248                 :            :                             space_id));
     249                 :            :         }
     250                 :            : 
     251                 :            :         ACPI_DEBUG_PRINT((ACPI_DB_LOAD, "Region Type - %s (0x%X)\n",
     252                 :         24 :                           acpi_ut_get_region_name(space_id), space_id));
     253                 :            : 
     254                 :            :         /* Create the region descriptor */
     255                 :            : 
     256                 :         24 :         obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_REGION);
     257         [ -  + ]:         24 :         if (!obj_desc) {
     258                 :          0 :                 status = AE_NO_MEMORY;
     259                 :          0 :                 goto cleanup;
     260                 :            :         }
     261                 :            : 
     262                 :            :         /*
     263                 :            :          * Remember location in AML stream of address & length
     264                 :            :          * operands since they need to be evaluated at run time.
     265                 :            :          */
     266                 :         24 :         region_obj2 = acpi_ns_get_secondary_object(obj_desc);
     267                 :         24 :         region_obj2->extra.aml_start = aml_start;
     268                 :         24 :         region_obj2->extra.aml_length = aml_length;
     269                 :         24 :         region_obj2->extra.method_REG = NULL;
     270         [ +  - ]:         24 :         if (walk_state->scope_info) {
     271                 :         24 :                 region_obj2->extra.scope_node =
     272                 :         24 :                     walk_state->scope_info->scope.node;
     273                 :            :         } else {
     274                 :          0 :                 region_obj2->extra.scope_node = node;
     275                 :            :         }
     276                 :            : 
     277                 :            :         /* Init the region from the operands */
     278                 :            : 
     279                 :         24 :         obj_desc->region.space_id = space_id;
     280                 :         24 :         obj_desc->region.address = 0;
     281                 :         24 :         obj_desc->region.length = 0;
     282                 :         24 :         obj_desc->region.node = node;
     283                 :         24 :         obj_desc->region.handler = NULL;
     284                 :         24 :         obj_desc->common.flags &=
     285                 :            :             ~(AOPOBJ_SETUP_COMPLETE | AOPOBJ_REG_CONNECTED |
     286                 :            :               AOPOBJ_OBJECT_INITIALIZED);
     287                 :            : 
     288                 :            :         /* Install the new region object in the parent Node */
     289                 :            : 
     290                 :         24 :         status = acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_REGION);
     291                 :            : 
     292                 :         24 : cleanup:
     293                 :            : 
     294                 :            :         /* Remove local reference to the object */
     295                 :            : 
     296                 :         24 :         acpi_ut_remove_reference(obj_desc);
     297                 :         24 :         return_ACPI_STATUS(status);
     298                 :            : }
     299                 :            : 
     300                 :            : /*******************************************************************************
     301                 :            :  *
     302                 :            :  * FUNCTION:    acpi_ex_create_processor
     303                 :            :  *
     304                 :            :  * PARAMETERS:  walk_state          - Current state
     305                 :            :  *
     306                 :            :  * RETURN:      Status
     307                 :            :  *
     308                 :            :  * DESCRIPTION: Create a new processor object and populate the fields
     309                 :            :  *
     310                 :            :  *              Processor (Name[0], cpu_ID[1], pblock_addr[2], pblock_length[3])
     311                 :            :  *
     312                 :            :  ******************************************************************************/
     313                 :            : 
     314                 :          3 : acpi_status acpi_ex_create_processor(struct acpi_walk_state *walk_state)
     315                 :            : {
     316                 :          3 :         union acpi_operand_object **operand = &walk_state->operands[0];
     317                 :          3 :         union acpi_operand_object *obj_desc;
     318                 :          3 :         acpi_status status;
     319                 :            : 
     320                 :          3 :         ACPI_FUNCTION_TRACE_PTR(ex_create_processor, walk_state);
     321                 :            : 
     322                 :            :         /* Create the processor object */
     323                 :            : 
     324                 :          3 :         obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_PROCESSOR);
     325         [ +  - ]:          3 :         if (!obj_desc) {
     326                 :            :                 return_ACPI_STATUS(AE_NO_MEMORY);
     327                 :            :         }
     328                 :            : 
     329                 :            :         /* Initialize the processor object from the operands */
     330                 :            : 
     331                 :          3 :         obj_desc->processor.proc_id = (u8) operand[1]->integer.value;
     332                 :          3 :         obj_desc->processor.length = (u8) operand[3]->integer.value;
     333                 :          3 :         obj_desc->processor.address =
     334                 :          3 :             (acpi_io_address)operand[2]->integer.value;
     335                 :            : 
     336                 :            :         /* Install the processor object in the parent Node */
     337                 :            : 
     338                 :          3 :         status = acpi_ns_attach_object((struct acpi_namespace_node *)operand[0],
     339                 :            :                                        obj_desc, ACPI_TYPE_PROCESSOR);
     340                 :            : 
     341                 :            :         /* Remove local reference to the object */
     342                 :            : 
     343                 :          3 :         acpi_ut_remove_reference(obj_desc);
     344                 :          3 :         return_ACPI_STATUS(status);
     345                 :            : }
     346                 :            : 
     347                 :            : /*******************************************************************************
     348                 :            :  *
     349                 :            :  * FUNCTION:    acpi_ex_create_power_resource
     350                 :            :  *
     351                 :            :  * PARAMETERS:  walk_state          - Current state
     352                 :            :  *
     353                 :            :  * RETURN:      Status
     354                 :            :  *
     355                 :            :  * DESCRIPTION: Create a new power_resource object and populate the fields
     356                 :            :  *
     357                 :            :  *              power_resource (Name[0], system_level[1], resource_order[2])
     358                 :            :  *
     359                 :            :  ******************************************************************************/
     360                 :            : 
     361                 :          0 : acpi_status acpi_ex_create_power_resource(struct acpi_walk_state *walk_state)
     362                 :            : {
     363                 :          0 :         union acpi_operand_object **operand = &walk_state->operands[0];
     364                 :          0 :         acpi_status status;
     365                 :          0 :         union acpi_operand_object *obj_desc;
     366                 :            : 
     367                 :          0 :         ACPI_FUNCTION_TRACE_PTR(ex_create_power_resource, walk_state);
     368                 :            : 
     369                 :            :         /* Create the power resource object */
     370                 :            : 
     371                 :          0 :         obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_POWER);
     372         [ #  # ]:          0 :         if (!obj_desc) {
     373                 :            :                 return_ACPI_STATUS(AE_NO_MEMORY);
     374                 :            :         }
     375                 :            : 
     376                 :            :         /* Initialize the power object from the operands */
     377                 :            : 
     378                 :          0 :         obj_desc->power_resource.system_level = (u8) operand[1]->integer.value;
     379                 :          0 :         obj_desc->power_resource.resource_order =
     380                 :          0 :             (u16) operand[2]->integer.value;
     381                 :            : 
     382                 :            :         /* Install the  power resource object in the parent Node */
     383                 :            : 
     384                 :          0 :         status = acpi_ns_attach_object((struct acpi_namespace_node *)operand[0],
     385                 :            :                                        obj_desc, ACPI_TYPE_POWER);
     386                 :            : 
     387                 :            :         /* Remove local reference to the object */
     388                 :            : 
     389                 :          0 :         acpi_ut_remove_reference(obj_desc);
     390                 :          0 :         return_ACPI_STATUS(status);
     391                 :            : }
     392                 :            : 
     393                 :            : /*******************************************************************************
     394                 :            :  *
     395                 :            :  * FUNCTION:    acpi_ex_create_method
     396                 :            :  *
     397                 :            :  * PARAMETERS:  aml_start       - First byte of the method's AML
     398                 :            :  *              aml_length      - AML byte count for this method
     399                 :            :  *              walk_state      - Current state
     400                 :            :  *
     401                 :            :  * RETURN:      Status
     402                 :            :  *
     403                 :            :  * DESCRIPTION: Create a new method object
     404                 :            :  *
     405                 :            :  ******************************************************************************/
     406                 :            : 
     407                 :            : acpi_status
     408                 :        228 : acpi_ex_create_method(u8 * aml_start,
     409                 :            :                       u32 aml_length, struct acpi_walk_state *walk_state)
     410                 :            : {
     411                 :        228 :         union acpi_operand_object **operand = &walk_state->operands[0];
     412                 :        228 :         union acpi_operand_object *obj_desc;
     413                 :        228 :         acpi_status status;
     414                 :        228 :         u8 method_flags;
     415                 :            : 
     416                 :        228 :         ACPI_FUNCTION_TRACE_PTR(ex_create_method, walk_state);
     417                 :            : 
     418                 :            :         /* Create a new method object */
     419                 :            : 
     420                 :        228 :         obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_METHOD);
     421         [ -  + ]:        228 :         if (!obj_desc) {
     422                 :          0 :                 status = AE_NO_MEMORY;
     423                 :          0 :                 goto exit;
     424                 :            :         }
     425                 :            : 
     426                 :            :         /* Save the method's AML pointer and length  */
     427                 :            : 
     428                 :        228 :         obj_desc->method.aml_start = aml_start;
     429                 :        228 :         obj_desc->method.aml_length = aml_length;
     430                 :        228 :         obj_desc->method.node = operand[0];
     431                 :            : 
     432                 :            :         /*
     433                 :            :          * Disassemble the method flags. Split off the arg_count, Serialized
     434                 :            :          * flag, and sync_level for efficiency.
     435                 :            :          */
     436                 :        228 :         method_flags = (u8)operand[1]->integer.value;
     437                 :        228 :         obj_desc->method.param_count = (u8)
     438                 :            :             (method_flags & AML_METHOD_ARG_COUNT);
     439                 :            : 
     440                 :            :         /*
     441                 :            :          * Get the sync_level. If method is serialized, a mutex will be
     442                 :            :          * created for this method when it is parsed.
     443                 :            :          */
     444         [ +  + ]:        228 :         if (method_flags & AML_METHOD_SERIALIZED) {
     445                 :         24 :                 obj_desc->method.info_flags = ACPI_METHOD_SERIALIZED;
     446                 :            : 
     447                 :            :                 /*
     448                 :            :                  * ACPI 1.0: sync_level = 0
     449                 :            :                  * ACPI 2.0: sync_level = sync_level in method declaration
     450                 :            :                  */
     451                 :         24 :                 obj_desc->method.sync_level = (u8)
     452                 :         24 :                     ((method_flags & AML_METHOD_SYNC_LEVEL) >> 4);
     453                 :            :         }
     454                 :            : 
     455                 :            :         /* Attach the new object to the method Node */
     456                 :            : 
     457                 :        228 :         status = acpi_ns_attach_object((struct acpi_namespace_node *)operand[0],
     458                 :            :                                        obj_desc, ACPI_TYPE_METHOD);
     459                 :            : 
     460                 :            :         /* Remove local reference to the object */
     461                 :            : 
     462                 :        228 :         acpi_ut_remove_reference(obj_desc);
     463                 :            : 
     464                 :        228 : exit:
     465                 :            :         /* Remove a reference to the operand */
     466                 :            : 
     467                 :        228 :         acpi_ut_remove_reference(operand[1]);
     468                 :        228 :         return_ACPI_STATUS(status);
     469                 :            : }

Generated by: LCOV version 1.14