Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
0002 /******************************************************************************
0003  *
0004  * Module Name: exstoren - AML Interpreter object store support,
0005  *                        Store to Node (namespace object)
0006  *
0007  * Copyright (C) 2000 - 2022, Intel Corp.
0008  *
0009  *****************************************************************************/
0010 
0011 #include <acpi/acpi.h>
0012 #include "accommon.h"
0013 #include "acinterp.h"
0014 #include "amlcode.h"
0015 
0016 #define _COMPONENT          ACPI_EXECUTER
0017 ACPI_MODULE_NAME("exstoren")
0018 
0019 /*******************************************************************************
0020  *
0021  * FUNCTION:    acpi_ex_resolve_object
0022  *
0023  * PARAMETERS:  source_desc_ptr     - Pointer to the source object
0024  *              target_type         - Current type of the target
0025  *              walk_state          - Current walk state
0026  *
0027  * RETURN:      Status, resolved object in source_desc_ptr.
0028  *
0029  * DESCRIPTION: Resolve an object. If the object is a reference, dereference
0030  *              it and return the actual object in the source_desc_ptr.
0031  *
0032  ******************************************************************************/
0033 acpi_status
0034 acpi_ex_resolve_object(union acpi_operand_object **source_desc_ptr,
0035                acpi_object_type target_type,
0036                struct acpi_walk_state *walk_state)
0037 {
0038     union acpi_operand_object *source_desc = *source_desc_ptr;
0039     acpi_status status = AE_OK;
0040 
0041     ACPI_FUNCTION_TRACE(ex_resolve_object);
0042 
0043     /* Ensure we have a Target that can be stored to */
0044 
0045     switch (target_type) {
0046     case ACPI_TYPE_BUFFER_FIELD:
0047     case ACPI_TYPE_LOCAL_REGION_FIELD:
0048     case ACPI_TYPE_LOCAL_BANK_FIELD:
0049     case ACPI_TYPE_LOCAL_INDEX_FIELD:
0050         /*
0051          * These cases all require only Integers or values that
0052          * can be converted to Integers (Strings or Buffers)
0053          */
0054     case ACPI_TYPE_INTEGER:
0055     case ACPI_TYPE_STRING:
0056     case ACPI_TYPE_BUFFER:
0057         /*
0058          * Stores into a Field/Region or into a Integer/Buffer/String
0059          * are all essentially the same. This case handles the
0060          * "interchangeable" types Integer, String, and Buffer.
0061          */
0062         if (source_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) {
0063 
0064             /* Resolve a reference object first */
0065 
0066             status =
0067                 acpi_ex_resolve_to_value(source_desc_ptr,
0068                              walk_state);
0069             if (ACPI_FAILURE(status)) {
0070                 break;
0071             }
0072         }
0073 
0074         /* For copy_object, no further validation necessary */
0075 
0076         if (walk_state->opcode == AML_COPY_OBJECT_OP) {
0077             break;
0078         }
0079 
0080         /* Must have a Integer, Buffer, or String */
0081 
0082         if ((source_desc->common.type != ACPI_TYPE_INTEGER) &&
0083             (source_desc->common.type != ACPI_TYPE_BUFFER) &&
0084             (source_desc->common.type != ACPI_TYPE_STRING) &&
0085             !((source_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) &&
0086               (source_desc->reference.class == ACPI_REFCLASS_TABLE))) {
0087 
0088             /* Conversion successful but still not a valid type */
0089 
0090             ACPI_ERROR((AE_INFO,
0091                     "Cannot assign type [%s] to [%s] (must be type Int/Str/Buf)",
0092                     acpi_ut_get_object_type_name(source_desc),
0093                     acpi_ut_get_type_name(target_type)));
0094 
0095             status = AE_AML_OPERAND_TYPE;
0096         }
0097         break;
0098 
0099     case ACPI_TYPE_LOCAL_ALIAS:
0100     case ACPI_TYPE_LOCAL_METHOD_ALIAS:
0101         /*
0102          * All aliases should have been resolved earlier, during the
0103          * operand resolution phase.
0104          */
0105         ACPI_ERROR((AE_INFO, "Store into an unresolved Alias object"));
0106         status = AE_AML_INTERNAL;
0107         break;
0108 
0109     case ACPI_TYPE_PACKAGE:
0110     default:
0111         /*
0112          * All other types than Alias and the various Fields come here,
0113          * including the untyped case - ACPI_TYPE_ANY.
0114          */
0115         break;
0116     }
0117 
0118     return_ACPI_STATUS(status);
0119 }
0120 
0121 /*******************************************************************************
0122  *
0123  * FUNCTION:    acpi_ex_store_object_to_object
0124  *
0125  * PARAMETERS:  source_desc         - Object to store
0126  *              dest_desc           - Object to receive a copy of the source
0127  *              new_desc            - New object if dest_desc is obsoleted
0128  *              walk_state          - Current walk state
0129  *
0130  * RETURN:      Status
0131  *
0132  * DESCRIPTION: "Store" an object to another object. This may include
0133  *              converting the source type to the target type (implicit
0134  *              conversion), and a copy of the value of the source to
0135  *              the target.
0136  *
0137  *              The Assignment of an object to another (not named) object
0138  *              is handled here.
0139  *              The Source passed in will replace the current value (if any)
0140  *              with the input value.
0141  *
0142  *              When storing into an object the data is converted to the
0143  *              target object type then stored in the object. This means
0144  *              that the target object type (for an initialized target) will
0145  *              not be changed by a store operation.
0146  *
0147  *              This module allows destination types of Number, String,
0148  *              Buffer, and Package.
0149  *
0150  *              Assumes parameters are already validated. NOTE: source_desc
0151  *              resolution (from a reference object) must be performed by
0152  *              the caller if necessary.
0153  *
0154  ******************************************************************************/
0155 
0156 acpi_status
0157 acpi_ex_store_object_to_object(union acpi_operand_object *source_desc,
0158                    union acpi_operand_object *dest_desc,
0159                    union acpi_operand_object **new_desc,
0160                    struct acpi_walk_state *walk_state)
0161 {
0162     union acpi_operand_object *actual_src_desc;
0163     acpi_status status = AE_OK;
0164 
0165     ACPI_FUNCTION_TRACE_PTR(ex_store_object_to_object, source_desc);
0166 
0167     actual_src_desc = source_desc;
0168     if (!dest_desc) {
0169         /*
0170          * There is no destination object (An uninitialized node or
0171          * package element), so we can simply copy the source object
0172          * creating a new destination object
0173          */
0174         status =
0175             acpi_ut_copy_iobject_to_iobject(actual_src_desc, new_desc,
0176                             walk_state);
0177         return_ACPI_STATUS(status);
0178     }
0179 
0180     if (source_desc->common.type != dest_desc->common.type) {
0181         /*
0182          * The source type does not match the type of the destination.
0183          * Perform the "implicit conversion" of the source to the current type
0184          * of the target as per the ACPI specification.
0185          *
0186          * If no conversion performed, actual_src_desc = source_desc.
0187          * Otherwise, actual_src_desc is a temporary object to hold the
0188          * converted object.
0189          */
0190         status = acpi_ex_convert_to_target_type(dest_desc->common.type,
0191                             source_desc,
0192                             &actual_src_desc,
0193                             walk_state);
0194         if (ACPI_FAILURE(status)) {
0195             return_ACPI_STATUS(status);
0196         }
0197 
0198         if (source_desc == actual_src_desc) {
0199             /*
0200              * No conversion was performed. Return the source_desc as the
0201              * new object.
0202              */
0203             *new_desc = source_desc;
0204             return_ACPI_STATUS(AE_OK);
0205         }
0206     }
0207 
0208     /*
0209      * We now have two objects of identical types, and we can perform a
0210      * copy of the *value* of the source object.
0211      */
0212     switch (dest_desc->common.type) {
0213     case ACPI_TYPE_INTEGER:
0214 
0215         dest_desc->integer.value = actual_src_desc->integer.value;
0216 
0217         /* Truncate value if we are executing from a 32-bit ACPI table */
0218 
0219         (void)acpi_ex_truncate_for32bit_table(dest_desc);
0220         break;
0221 
0222     case ACPI_TYPE_STRING:
0223 
0224         status =
0225             acpi_ex_store_string_to_string(actual_src_desc, dest_desc);
0226         break;
0227 
0228     case ACPI_TYPE_BUFFER:
0229 
0230         status =
0231             acpi_ex_store_buffer_to_buffer(actual_src_desc, dest_desc);
0232         break;
0233 
0234     case ACPI_TYPE_PACKAGE:
0235 
0236         status =
0237             acpi_ut_copy_iobject_to_iobject(actual_src_desc, &dest_desc,
0238                             walk_state);
0239         break;
0240 
0241     default:
0242         /*
0243          * All other types come here.
0244          */
0245         ACPI_WARNING((AE_INFO, "Store into type [%s] not implemented",
0246                   acpi_ut_get_object_type_name(dest_desc)));
0247 
0248         status = AE_NOT_IMPLEMENTED;
0249         break;
0250     }
0251 
0252     if (actual_src_desc != source_desc) {
0253 
0254         /* Delete the intermediate (temporary) source object */
0255 
0256         acpi_ut_remove_reference(actual_src_desc);
0257     }
0258 
0259     *new_desc = dest_desc;
0260     return_ACPI_STATUS(status);
0261 }