linux/drivers/acpi/acpica/exresnte.c
<<
>>
Prefs
   1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2/******************************************************************************
   3 *
   4 * Module Name: exresnte - AML Interpreter object resolution
   5 *
   6 * Copyright (C) 2000 - 2020, Intel Corp.
   7 *
   8 *****************************************************************************/
   9
  10#include <acpi/acpi.h>
  11#include "accommon.h"
  12#include "acdispat.h"
  13#include "acinterp.h"
  14#include "acnamesp.h"
  15
  16#define _COMPONENT          ACPI_EXECUTER
  17ACPI_MODULE_NAME("exresnte")
  18
  19/*******************************************************************************
  20 *
  21 * FUNCTION:    acpi_ex_resolve_node_to_value
  22 *
  23 * PARAMETERS:  object_ptr      - Pointer to a location that contains
  24 *                                a pointer to a NS node, and will receive a
  25 *                                pointer to the resolved object.
  26 *              walk_state      - Current state. Valid only if executing AML
  27 *                                code. NULL if simply resolving an object
  28 *
  29 * RETURN:      Status
  30 *
  31 * DESCRIPTION: Resolve a Namespace node to a valued object
  32 *
  33 * Note: for some of the data types, the pointer attached to the Node
  34 * can be either a pointer to an actual internal object or a pointer into the
  35 * AML stream itself. These types are currently:
  36 *
  37 *      ACPI_TYPE_INTEGER
  38 *      ACPI_TYPE_STRING
  39 *      ACPI_TYPE_BUFFER
  40 *      ACPI_TYPE_MUTEX
  41 *      ACPI_TYPE_PACKAGE
  42 *
  43 ******************************************************************************/
  44acpi_status
  45acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr,
  46                              struct acpi_walk_state *walk_state)
  47{
  48        acpi_status status = AE_OK;
  49        union acpi_operand_object *source_desc;
  50        union acpi_operand_object *obj_desc = NULL;
  51        struct acpi_namespace_node *node;
  52        acpi_object_type entry_type;
  53
  54        ACPI_FUNCTION_TRACE(ex_resolve_node_to_value);
  55
  56        /*
  57         * The stack pointer points to a struct acpi_namespace_node (Node). Get the
  58         * object that is attached to the Node.
  59         */
  60        node = *object_ptr;
  61        source_desc = acpi_ns_get_attached_object(node);
  62        entry_type = acpi_ns_get_type((acpi_handle)node);
  63
  64        ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Entry=%p SourceDesc=%p [%s]\n",
  65                          node, source_desc,
  66                          acpi_ut_get_type_name(entry_type)));
  67
  68        if ((entry_type == ACPI_TYPE_LOCAL_ALIAS) ||
  69            (entry_type == ACPI_TYPE_LOCAL_METHOD_ALIAS)) {
  70
  71                /* There is always exactly one level of indirection */
  72
  73                node = ACPI_CAST_PTR(struct acpi_namespace_node, node->object);
  74                source_desc = acpi_ns_get_attached_object(node);
  75                entry_type = acpi_ns_get_type((acpi_handle)node);
  76                *object_ptr = node;
  77        }
  78
  79        /*
  80         * Several object types require no further processing:
  81         * 1) Device/Thermal objects don't have a "real" subobject, return Node
  82         * 2) Method locals and arguments have a pseudo-Node
  83         * 3) 10/2007: Added method type to assist with Package construction.
  84         */
  85        if ((entry_type == ACPI_TYPE_DEVICE) ||
  86            (entry_type == ACPI_TYPE_THERMAL) ||
  87            (entry_type == ACPI_TYPE_METHOD) ||
  88            (node->flags & (ANOBJ_METHOD_ARG | ANOBJ_METHOD_LOCAL))) {
  89                return_ACPI_STATUS(AE_OK);
  90        }
  91
  92        if (!source_desc) {
  93                ACPI_ERROR((AE_INFO, "No object attached to node [%4.4s] %p",
  94                            node->name.ascii, node));
  95                return_ACPI_STATUS(AE_AML_UNINITIALIZED_NODE);
  96        }
  97
  98        /*
  99         * Action is based on the type of the Node, which indicates the type
 100         * of the attached object or pointer
 101         */
 102        switch (entry_type) {
 103        case ACPI_TYPE_PACKAGE:
 104
 105                if (source_desc->common.type != ACPI_TYPE_PACKAGE) {
 106                        ACPI_ERROR((AE_INFO, "Object not a Package, type %s",
 107                                    acpi_ut_get_object_type_name(source_desc)));
 108                        return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 109                }
 110
 111                status = acpi_ds_get_package_arguments(source_desc);
 112                if (ACPI_SUCCESS(status)) {
 113
 114                        /* Return an additional reference to the object */
 115
 116                        obj_desc = source_desc;
 117                        acpi_ut_add_reference(obj_desc);
 118                }
 119                break;
 120
 121        case ACPI_TYPE_BUFFER:
 122
 123                if (source_desc->common.type != ACPI_TYPE_BUFFER) {
 124                        ACPI_ERROR((AE_INFO, "Object not a Buffer, type %s",
 125                                    acpi_ut_get_object_type_name(source_desc)));
 126                        return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 127                }
 128
 129                status = acpi_ds_get_buffer_arguments(source_desc);
 130                if (ACPI_SUCCESS(status)) {
 131
 132                        /* Return an additional reference to the object */
 133
 134                        obj_desc = source_desc;
 135                        acpi_ut_add_reference(obj_desc);
 136                }
 137                break;
 138
 139        case ACPI_TYPE_STRING:
 140
 141                if (source_desc->common.type != ACPI_TYPE_STRING) {
 142                        ACPI_ERROR((AE_INFO, "Object not a String, type %s",
 143                                    acpi_ut_get_object_type_name(source_desc)));
 144                        return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 145                }
 146
 147                /* Return an additional reference to the object */
 148
 149                obj_desc = source_desc;
 150                acpi_ut_add_reference(obj_desc);
 151                break;
 152
 153        case ACPI_TYPE_INTEGER:
 154
 155                if (source_desc->common.type != ACPI_TYPE_INTEGER) {
 156                        ACPI_ERROR((AE_INFO, "Object not a Integer, type %s",
 157                                    acpi_ut_get_object_type_name(source_desc)));
 158                        return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 159                }
 160
 161                /* Return an additional reference to the object */
 162
 163                obj_desc = source_desc;
 164                acpi_ut_add_reference(obj_desc);
 165                break;
 166
 167        case ACPI_TYPE_BUFFER_FIELD:
 168        case ACPI_TYPE_LOCAL_REGION_FIELD:
 169        case ACPI_TYPE_LOCAL_BANK_FIELD:
 170        case ACPI_TYPE_LOCAL_INDEX_FIELD:
 171
 172                ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
 173                                  "FieldRead Node=%p SourceDesc=%p Type=%X\n",
 174                                  node, source_desc, entry_type));
 175
 176                status =
 177                    acpi_ex_read_data_from_field(walk_state, source_desc,
 178                                                 &obj_desc);
 179                break;
 180
 181                /* For these objects, just return the object attached to the Node */
 182
 183        case ACPI_TYPE_MUTEX:
 184        case ACPI_TYPE_POWER:
 185        case ACPI_TYPE_PROCESSOR:
 186        case ACPI_TYPE_EVENT:
 187        case ACPI_TYPE_REGION:
 188
 189                /* Return an additional reference to the object */
 190
 191                obj_desc = source_desc;
 192                acpi_ut_add_reference(obj_desc);
 193                break;
 194
 195                /* TYPE_ANY is untyped, and thus there is no object associated with it */
 196
 197        case ACPI_TYPE_ANY:
 198
 199                ACPI_ERROR((AE_INFO,
 200                            "Untyped entry %p, no attached object!", node));
 201
 202                return_ACPI_STATUS(AE_AML_OPERAND_TYPE);        /* Cannot be AE_TYPE */
 203
 204        case ACPI_TYPE_LOCAL_REFERENCE:
 205
 206                switch (source_desc->reference.class) {
 207                case ACPI_REFCLASS_TABLE:       /* This is a ddb_handle */
 208                case ACPI_REFCLASS_REFOF:
 209                case ACPI_REFCLASS_INDEX:
 210
 211                        /* Return an additional reference to the object */
 212
 213                        obj_desc = source_desc;
 214                        acpi_ut_add_reference(obj_desc);
 215                        break;
 216
 217                default:
 218
 219                        /* No named references are allowed here */
 220
 221                        ACPI_ERROR((AE_INFO,
 222                                    "Unsupported Reference type 0x%X",
 223                                    source_desc->reference.class));
 224
 225                        return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 226                }
 227                break;
 228
 229        default:
 230
 231                /* Default case is for unknown types */
 232
 233                ACPI_ERROR((AE_INFO,
 234                            "Node %p - Unknown object type 0x%X",
 235                            node, entry_type));
 236
 237                return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 238
 239        }                       /* switch (entry_type) */
 240
 241        /* Return the object descriptor */
 242
 243        *object_ptr = (void *)obj_desc;
 244        return_ACPI_STATUS(status);
 245}
 246