root/drivers/acpi/acpica/excreate.c

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

DEFINITIONS

This source file includes following definitions.
  1. ACPI_MODULE_NAME
  2. acpi_ex_create_event
  3. acpi_ex_create_mutex
  4. acpi_ex_create_region
  5. acpi_ex_create_processor
  6. acpi_ex_create_power_resource
  7. acpi_ex_create_method

   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 - 2019, 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 acpi_status acpi_ex_create_alias(struct acpi_walk_state *walk_state)
  30 {
  31         struct acpi_namespace_node *target_node;
  32         struct acpi_namespace_node *alias_node;
  33         acpi_status status = AE_OK;
  34 
  35         ACPI_FUNCTION_TRACE(ex_create_alias);
  36 
  37         /* Get the source/alias operands (both namespace nodes) */
  38 
  39         alias_node = (struct acpi_namespace_node *)walk_state->operands[0];
  40         target_node = (struct acpi_namespace_node *)walk_state->operands[1];
  41 
  42         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                 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         if (!target_node) {
  58                 return_ACPI_STATUS(AE_NULL_OBJECT);
  59         }
  60 
  61         /* Construct the alias object (a namespace node) */
  62 
  63         switch (target_node->type) {
  64         case ACPI_TYPE_METHOD:
  65                 /*
  66                  * Control method aliases need to be differentiated with
  67                  * a special type
  68                  */
  69                 alias_node->type = ACPI_TYPE_LOCAL_METHOD_ALIAS;
  70                 break;
  71 
  72         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                 alias_node->type = ACPI_TYPE_LOCAL_ALIAS;
  80                 alias_node->object =
  81                     ACPI_CAST_PTR(union acpi_operand_object, target_node);
  82                 break;
  83         }
  84 
  85         /* Since both operands are Nodes, we don't need to delete them */
  86 
  87         alias_node->object =
  88             ACPI_CAST_PTR(union acpi_operand_object, target_node);
  89         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 acpi_status acpi_ex_create_event(struct acpi_walk_state *walk_state)
 105 {
 106         acpi_status status;
 107         union acpi_operand_object *obj_desc;
 108 
 109         ACPI_FUNCTION_TRACE(ex_create_event);
 110 
 111         obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_EVENT);
 112         if (!obj_desc) {
 113                 status = AE_NO_MEMORY;
 114                 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         status = acpi_os_create_semaphore(ACPI_NO_UNIT_LIMIT, 0,
 122                                           &obj_desc->event.os_semaphore);
 123         if (ACPI_FAILURE(status)) {
 124                 goto cleanup;
 125         }
 126 
 127         /* Attach object to the Node */
 128 
 129         status = acpi_ns_attach_object((struct acpi_namespace_node *)
 130                                        walk_state->operands[0], obj_desc,
 131                                        ACPI_TYPE_EVENT);
 132 
 133 cleanup:
 134         /*
 135          * Remove local reference to the object (on error, will cause deletion
 136          * of both object and semaphore if present.)
 137          */
 138         acpi_ut_remove_reference(obj_desc);
 139         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 acpi_status acpi_ex_create_mutex(struct acpi_walk_state *walk_state)
 157 {
 158         acpi_status status = AE_OK;
 159         union acpi_operand_object *obj_desc;
 160 
 161         ACPI_FUNCTION_TRACE_PTR(ex_create_mutex, ACPI_WALK_OPERANDS);
 162 
 163         /* Create the new mutex object */
 164 
 165         obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_MUTEX);
 166         if (!obj_desc) {
 167                 status = AE_NO_MEMORY;
 168                 goto cleanup;
 169         }
 170 
 171         /* Create the actual OS Mutex */
 172 
 173         status = acpi_os_create_mutex(&obj_desc->mutex.os_mutex);
 174         if (ACPI_FAILURE(status)) {
 175                 goto cleanup;
 176         }
 177 
 178         /* Init object and attach to NS node */
 179 
 180         obj_desc->mutex.sync_level = (u8)walk_state->operands[1]->integer.value;
 181         obj_desc->mutex.node =
 182             (struct acpi_namespace_node *)walk_state->operands[0];
 183 
 184         status =
 185             acpi_ns_attach_object(obj_desc->mutex.node, obj_desc,
 186                                   ACPI_TYPE_MUTEX);
 187 
 188 cleanup:
 189         /*
 190          * Remove local reference to the object (on error, will cause deletion
 191          * of both object and semaphore if present.)
 192          */
 193         acpi_ut_remove_reference(obj_desc);
 194         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 acpi_ex_create_region(u8 * aml_start,
 214                       u32 aml_length,
 215                       u8 space_id, struct acpi_walk_state *walk_state)
 216 {
 217         acpi_status status;
 218         union acpi_operand_object *obj_desc;
 219         struct acpi_namespace_node *node;
 220         union acpi_operand_object *region_obj2;
 221 
 222         ACPI_FUNCTION_TRACE(ex_create_region);
 223 
 224         /* Get the Namespace Node */
 225 
 226         node = walk_state->op->common.node;
 227 
 228         /*
 229          * If the region object is already attached to this node,
 230          * just return
 231          */
 232         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         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                 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                           acpi_ut_get_region_name(space_id), space_id));
 253 
 254         /* Create the region descriptor */
 255 
 256         obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_REGION);
 257         if (!obj_desc) {
 258                 status = AE_NO_MEMORY;
 259                 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         region_obj2 = acpi_ns_get_secondary_object(obj_desc);
 267         region_obj2->extra.aml_start = aml_start;
 268         region_obj2->extra.aml_length = aml_length;
 269         region_obj2->extra.method_REG = NULL;
 270         if (walk_state->scope_info) {
 271                 region_obj2->extra.scope_node =
 272                     walk_state->scope_info->scope.node;
 273         } else {
 274                 region_obj2->extra.scope_node = node;
 275         }
 276 
 277         /* Init the region from the operands */
 278 
 279         obj_desc->region.space_id = space_id;
 280         obj_desc->region.address = 0;
 281         obj_desc->region.length = 0;
 282         obj_desc->region.node = node;
 283         obj_desc->region.handler = NULL;
 284         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         status = acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_REGION);
 291 
 292 cleanup:
 293 
 294         /* Remove local reference to the object */
 295 
 296         acpi_ut_remove_reference(obj_desc);
 297         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 acpi_status acpi_ex_create_processor(struct acpi_walk_state *walk_state)
 315 {
 316         union acpi_operand_object **operand = &walk_state->operands[0];
 317         union acpi_operand_object *obj_desc;
 318         acpi_status status;
 319 
 320         ACPI_FUNCTION_TRACE_PTR(ex_create_processor, walk_state);
 321 
 322         /* Create the processor object */
 323 
 324         obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_PROCESSOR);
 325         if (!obj_desc) {
 326                 return_ACPI_STATUS(AE_NO_MEMORY);
 327         }
 328 
 329         /* Initialize the processor object from the operands */
 330 
 331         obj_desc->processor.proc_id = (u8) operand[1]->integer.value;
 332         obj_desc->processor.length = (u8) operand[3]->integer.value;
 333         obj_desc->processor.address =
 334             (acpi_io_address)operand[2]->integer.value;
 335 
 336         /* Install the processor object in the parent Node */
 337 
 338         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         acpi_ut_remove_reference(obj_desc);
 344         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 acpi_status acpi_ex_create_power_resource(struct acpi_walk_state *walk_state)
 362 {
 363         union acpi_operand_object **operand = &walk_state->operands[0];
 364         acpi_status status;
 365         union acpi_operand_object *obj_desc;
 366 
 367         ACPI_FUNCTION_TRACE_PTR(ex_create_power_resource, walk_state);
 368 
 369         /* Create the power resource object */
 370 
 371         obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_POWER);
 372         if (!obj_desc) {
 373                 return_ACPI_STATUS(AE_NO_MEMORY);
 374         }
 375 
 376         /* Initialize the power object from the operands */
 377 
 378         obj_desc->power_resource.system_level = (u8) operand[1]->integer.value;
 379         obj_desc->power_resource.resource_order =
 380             (u16) operand[2]->integer.value;
 381 
 382         /* Install the  power resource object in the parent Node */
 383 
 384         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         acpi_ut_remove_reference(obj_desc);
 390         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 acpi_ex_create_method(u8 * aml_start,
 409                       u32 aml_length, struct acpi_walk_state *walk_state)
 410 {
 411         union acpi_operand_object **operand = &walk_state->operands[0];
 412         union acpi_operand_object *obj_desc;
 413         acpi_status status;
 414         u8 method_flags;
 415 
 416         ACPI_FUNCTION_TRACE_PTR(ex_create_method, walk_state);
 417 
 418         /* Create a new method object */
 419 
 420         obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_METHOD);
 421         if (!obj_desc) {
 422                 status = AE_NO_MEMORY;
 423                 goto exit;
 424         }
 425 
 426         /* Save the method's AML pointer and length  */
 427 
 428         obj_desc->method.aml_start = aml_start;
 429         obj_desc->method.aml_length = aml_length;
 430         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         method_flags = (u8)operand[1]->integer.value;
 437         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         if (method_flags & AML_METHOD_SERIALIZED) {
 445                 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                 obj_desc->method.sync_level = (u8)
 452                     ((method_flags & AML_METHOD_SYNC_LEVEL) >> 4);
 453         }
 454 
 455         /* Attach the new object to the method Node */
 456 
 457         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         acpi_ut_remove_reference(obj_desc);
 463 
 464 exit:
 465         /* Remove a reference to the operand */
 466 
 467         acpi_ut_remove_reference(operand[1]);
 468         return_ACPI_STATUS(status);
 469 }

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