195857638SErik Schmauss // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
295b482a8SLen Brown /******************************************************************************
395b482a8SLen Brown *
495b482a8SLen Brown * Module Name: exstore - AML Interpreter object store support
595b482a8SLen Brown *
6*487ea80aSBob Moore * Copyright (C) 2000 - 2023, Intel Corp.
795b482a8SLen Brown *
895857638SErik Schmauss *****************************************************************************/
995b482a8SLen Brown
1095b482a8SLen Brown #include <acpi/acpi.h>
11e2f7a777SLen Brown #include "accommon.h"
12e2f7a777SLen Brown #include "acdispat.h"
13e2f7a777SLen Brown #include "acinterp.h"
14e2f7a777SLen Brown #include "amlcode.h"
15e2f7a777SLen Brown #include "acnamesp.h"
1695b482a8SLen Brown
1795b482a8SLen Brown #define _COMPONENT ACPI_EXECUTER
1895b482a8SLen Brown ACPI_MODULE_NAME("exstore")
1995b482a8SLen Brown
2095b482a8SLen Brown /* Local prototypes */
2195b482a8SLen Brown static acpi_status
2295b482a8SLen Brown acpi_ex_store_object_to_index(union acpi_operand_object *val_desc,
2395b482a8SLen Brown union acpi_operand_object *dest_desc,
2495b482a8SLen Brown struct acpi_walk_state *walk_state);
2595b482a8SLen Brown
264be4be8fSBob Moore static acpi_status
274be4be8fSBob Moore acpi_ex_store_direct_to_node(union acpi_operand_object *source_desc,
284be4be8fSBob Moore struct acpi_namespace_node *node,
294be4be8fSBob Moore struct acpi_walk_state *walk_state);
304be4be8fSBob Moore
3195b482a8SLen Brown /*******************************************************************************
3295b482a8SLen Brown *
3395b482a8SLen Brown * FUNCTION: acpi_ex_store
3495b482a8SLen Brown *
3595b482a8SLen Brown * PARAMETERS: *source_desc - Value to be stored
3695b482a8SLen Brown * *dest_desc - Where to store it. Must be an NS node
37cf48958eSBob Moore * or union acpi_operand_object of type
3895b482a8SLen Brown * Reference;
3995b482a8SLen Brown * walk_state - Current walk state
4095b482a8SLen Brown *
4195b482a8SLen Brown * RETURN: Status
4295b482a8SLen Brown *
4395b482a8SLen Brown * DESCRIPTION: Store the value described by source_desc into the location
4495b482a8SLen Brown * described by dest_desc. Called by various interpreter
4595b482a8SLen Brown * functions to store the result of an operation into
4695b482a8SLen Brown * the destination operand -- not just simply the actual "Store"
4795b482a8SLen Brown * ASL operator.
4895b482a8SLen Brown *
4995b482a8SLen Brown ******************************************************************************/
5095b482a8SLen Brown
5195b482a8SLen Brown acpi_status
acpi_ex_store(union acpi_operand_object * source_desc,union acpi_operand_object * dest_desc,struct acpi_walk_state * walk_state)5295b482a8SLen Brown acpi_ex_store(union acpi_operand_object *source_desc,
5395b482a8SLen Brown union acpi_operand_object *dest_desc,
5495b482a8SLen Brown struct acpi_walk_state *walk_state)
5595b482a8SLen Brown {
5695b482a8SLen Brown acpi_status status = AE_OK;
5795b482a8SLen Brown union acpi_operand_object *ref_desc = dest_desc;
5895b482a8SLen Brown
5995b482a8SLen Brown ACPI_FUNCTION_TRACE_PTR(ex_store, dest_desc);
6095b482a8SLen Brown
6195b482a8SLen Brown /* Validate parameters */
6295b482a8SLen Brown
6395b482a8SLen Brown if (!source_desc || !dest_desc) {
6495b482a8SLen Brown ACPI_ERROR((AE_INFO, "Null parameter"));
6595b482a8SLen Brown return_ACPI_STATUS(AE_AML_NO_OPERAND);
6695b482a8SLen Brown }
6795b482a8SLen Brown
6895b482a8SLen Brown /* dest_desc can be either a namespace node or an ACPI object */
6995b482a8SLen Brown
7095b482a8SLen Brown if (ACPI_GET_DESCRIPTOR_TYPE(dest_desc) == ACPI_DESC_TYPE_NAMED) {
7195b482a8SLen Brown /*
7295b482a8SLen Brown * Dest is a namespace node,
7395b482a8SLen Brown * Storing an object into a Named node.
7495b482a8SLen Brown */
7595b482a8SLen Brown status = acpi_ex_store_object_to_node(source_desc,
7695b482a8SLen Brown (struct
7795b482a8SLen Brown acpi_namespace_node *)
7895b482a8SLen Brown dest_desc, walk_state,
7995b482a8SLen Brown ACPI_IMPLICIT_CONVERSION);
8095b482a8SLen Brown
8195b482a8SLen Brown return_ACPI_STATUS(status);
8295b482a8SLen Brown }
8395b482a8SLen Brown
8495b482a8SLen Brown /* Destination object must be a Reference or a Constant object */
8595b482a8SLen Brown
863371c19cSBob Moore switch (dest_desc->common.type) {
8795b482a8SLen Brown case ACPI_TYPE_LOCAL_REFERENCE:
881d1ea1b7SChao Guan
8995b482a8SLen Brown break;
9095b482a8SLen Brown
9195b482a8SLen Brown case ACPI_TYPE_INTEGER:
9295b482a8SLen Brown
9395b482a8SLen Brown /* Allow stores to Constants -- a Noop as per ACPI spec */
9495b482a8SLen Brown
9595b482a8SLen Brown if (dest_desc->common.flags & AOPOBJ_AML_CONSTANT) {
9695b482a8SLen Brown return_ACPI_STATUS(AE_OK);
9795b482a8SLen Brown }
9895b482a8SLen Brown
99c1a7c2ceSNick Desaulniers ACPI_FALLTHROUGH;
10095b482a8SLen Brown
10195b482a8SLen Brown default:
10295b482a8SLen Brown
10395b482a8SLen Brown /* Destination is not a Reference object */
10495b482a8SLen Brown
10595b482a8SLen Brown ACPI_ERROR((AE_INFO,
106a5922a1fSBob Moore "Target is not a Reference or Constant object - [%s] %p",
10795b482a8SLen Brown acpi_ut_get_object_type_name(dest_desc),
10895b482a8SLen Brown dest_desc));
10995b482a8SLen Brown
11095b482a8SLen Brown return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
11195b482a8SLen Brown }
11295b482a8SLen Brown
11395b482a8SLen Brown /*
11495b482a8SLen Brown * Examine the Reference class. These cases are handled:
11595b482a8SLen Brown *
11695b482a8SLen Brown * 1) Store to Name (Change the object associated with a name)
11795b482a8SLen Brown * 2) Store to an indexed area of a Buffer or Package
11895b482a8SLen Brown * 3) Store to a Method Local or Arg
11995b482a8SLen Brown * 4) Store to the debug object
12095b482a8SLen Brown */
12195b482a8SLen Brown switch (ref_desc->reference.class) {
12295b482a8SLen Brown case ACPI_REFCLASS_REFOF:
12395b482a8SLen Brown
12495b482a8SLen Brown /* Storing an object into a Name "container" */
12595b482a8SLen Brown
12695b482a8SLen Brown status = acpi_ex_store_object_to_node(source_desc,
12795b482a8SLen Brown ref_desc->reference.
12895b482a8SLen Brown object, walk_state,
12995b482a8SLen Brown ACPI_IMPLICIT_CONVERSION);
13095b482a8SLen Brown break;
13195b482a8SLen Brown
13295b482a8SLen Brown case ACPI_REFCLASS_INDEX:
13395b482a8SLen Brown
13495b482a8SLen Brown /* Storing to an Index (pointer into a packager or buffer) */
13595b482a8SLen Brown
13695b482a8SLen Brown status =
13795b482a8SLen Brown acpi_ex_store_object_to_index(source_desc, ref_desc,
13895b482a8SLen Brown walk_state);
13995b482a8SLen Brown break;
14095b482a8SLen Brown
14195b482a8SLen Brown case ACPI_REFCLASS_LOCAL:
14295b482a8SLen Brown case ACPI_REFCLASS_ARG:
14395b482a8SLen Brown
14495b482a8SLen Brown /* Store to a method local/arg */
14595b482a8SLen Brown
14695b482a8SLen Brown status =
14795b482a8SLen Brown acpi_ds_store_object_to_local(ref_desc->reference.class,
14895b482a8SLen Brown ref_desc->reference.value,
14995b482a8SLen Brown source_desc, walk_state);
15095b482a8SLen Brown break;
15195b482a8SLen Brown
15295b482a8SLen Brown case ACPI_REFCLASS_DEBUG:
15395b482a8SLen Brown /*
15495b482a8SLen Brown * Storing to the Debug object causes the value stored to be
15595b482a8SLen Brown * displayed and otherwise has no effect -- see ACPI Specification
15695b482a8SLen Brown */
15795b482a8SLen Brown ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
158a5922a1fSBob Moore "**** Write to Debug Object: Object %p [%s] ****:\n\n",
15995b482a8SLen Brown source_desc,
16095b482a8SLen Brown acpi_ut_get_object_type_name(source_desc)));
16195b482a8SLen Brown
1624cdf1a56SLin Ming ACPI_DEBUG_OBJECT(source_desc, 0, 0);
16395b482a8SLen Brown break;
16495b482a8SLen Brown
16595b482a8SLen Brown default:
16695b482a8SLen Brown
167f6a22b0bSBob Moore ACPI_ERROR((AE_INFO, "Unknown Reference Class 0x%2.2X",
16895b482a8SLen Brown ref_desc->reference.class));
16995b482a8SLen Brown ACPI_DUMP_ENTRY(ref_desc, ACPI_LV_INFO);
17095b482a8SLen Brown
17195b482a8SLen Brown status = AE_AML_INTERNAL;
17295b482a8SLen Brown break;
17395b482a8SLen Brown }
17495b482a8SLen Brown
17595b482a8SLen Brown return_ACPI_STATUS(status);
17695b482a8SLen Brown }
17795b482a8SLen Brown
17895b482a8SLen Brown /*******************************************************************************
17995b482a8SLen Brown *
18095b482a8SLen Brown * FUNCTION: acpi_ex_store_object_to_index
18195b482a8SLen Brown *
18295b482a8SLen Brown * PARAMETERS: *source_desc - Value to be stored
18395b482a8SLen Brown * *dest_desc - Named object to receive the value
18495b482a8SLen Brown * walk_state - Current walk state
18595b482a8SLen Brown *
18695b482a8SLen Brown * RETURN: Status
18795b482a8SLen Brown *
18895b482a8SLen Brown * DESCRIPTION: Store the object to indexed Buffer or Package element
18995b482a8SLen Brown *
19095b482a8SLen Brown ******************************************************************************/
19195b482a8SLen Brown
19295b482a8SLen Brown static acpi_status
acpi_ex_store_object_to_index(union acpi_operand_object * source_desc,union acpi_operand_object * index_desc,struct acpi_walk_state * walk_state)19395b482a8SLen Brown acpi_ex_store_object_to_index(union acpi_operand_object *source_desc,
19495b482a8SLen Brown union acpi_operand_object *index_desc,
19595b482a8SLen Brown struct acpi_walk_state *walk_state)
19695b482a8SLen Brown {
19795b482a8SLen Brown acpi_status status = AE_OK;
19895b482a8SLen Brown union acpi_operand_object *obj_desc;
19995b482a8SLen Brown union acpi_operand_object *new_desc;
20095b482a8SLen Brown u8 value = 0;
20195b482a8SLen Brown u32 i;
20295b482a8SLen Brown
20395b482a8SLen Brown ACPI_FUNCTION_TRACE(ex_store_object_to_index);
20495b482a8SLen Brown
20595b482a8SLen Brown /*
20695b482a8SLen Brown * Destination must be a reference pointer, and
20795b482a8SLen Brown * must point to either a buffer or a package
20895b482a8SLen Brown */
20995b482a8SLen Brown switch (index_desc->reference.target_type) {
21095b482a8SLen Brown case ACPI_TYPE_PACKAGE:
21195b482a8SLen Brown /*
21295b482a8SLen Brown * Storing to a package element. Copy the object and replace
21395b482a8SLen Brown * any existing object with the new object. No implicit
21495b482a8SLen Brown * conversion is performed.
21595b482a8SLen Brown *
21695b482a8SLen Brown * The object at *(index_desc->Reference.Where) is the
21795b482a8SLen Brown * element within the package that is to be modified.
21895b482a8SLen Brown * The parent package object is at index_desc->Reference.Object
21995b482a8SLen Brown */
22095b482a8SLen Brown obj_desc = *(index_desc->reference.where);
22195b482a8SLen Brown
2223371c19cSBob Moore if (source_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE &&
2233371c19cSBob Moore source_desc->reference.class == ACPI_REFCLASS_TABLE) {
22495b482a8SLen Brown
22595b482a8SLen Brown /* This is a DDBHandle, just add a reference to it */
22695b482a8SLen Brown
22795b482a8SLen Brown acpi_ut_add_reference(source_desc);
22895b482a8SLen Brown new_desc = source_desc;
22995b482a8SLen Brown } else {
23095b482a8SLen Brown /* Normal object, copy it */
23195b482a8SLen Brown
23295b482a8SLen Brown status =
23395b482a8SLen Brown acpi_ut_copy_iobject_to_iobject(source_desc,
23495b482a8SLen Brown &new_desc,
23595b482a8SLen Brown walk_state);
23695b482a8SLen Brown if (ACPI_FAILURE(status)) {
23795b482a8SLen Brown return_ACPI_STATUS(status);
23895b482a8SLen Brown }
23995b482a8SLen Brown }
24095b482a8SLen Brown
24195b482a8SLen Brown if (obj_desc) {
24295b482a8SLen Brown
24395b482a8SLen Brown /* Decrement reference count by the ref count of the parent package */
24495b482a8SLen Brown
24595b482a8SLen Brown for (i = 0; i < ((union acpi_operand_object *)
24695b482a8SLen Brown index_desc->reference.object)->common.
24795b482a8SLen Brown reference_count; i++) {
24895b482a8SLen Brown acpi_ut_remove_reference(obj_desc);
24995b482a8SLen Brown }
25095b482a8SLen Brown }
25195b482a8SLen Brown
25295b482a8SLen Brown *(index_desc->reference.where) = new_desc;
25395b482a8SLen Brown
25495b482a8SLen Brown /* Increment ref count by the ref count of the parent package-1 */
25595b482a8SLen Brown
25695b482a8SLen Brown for (i = 1; i < ((union acpi_operand_object *)
25795b482a8SLen Brown index_desc->reference.object)->common.
25895b482a8SLen Brown reference_count; i++) {
25995b482a8SLen Brown acpi_ut_add_reference(new_desc);
26095b482a8SLen Brown }
26195b482a8SLen Brown
26295b482a8SLen Brown break;
26395b482a8SLen Brown
26495b482a8SLen Brown case ACPI_TYPE_BUFFER_FIELD:
26595b482a8SLen Brown /*
26695b482a8SLen Brown * Store into a Buffer or String (not actually a real buffer_field)
26795b482a8SLen Brown * at a location defined by an Index.
26895b482a8SLen Brown *
26995b482a8SLen Brown * The first 8-bit element of the source object is written to the
27095b482a8SLen Brown * 8-bit Buffer location defined by the Index destination object,
27195b482a8SLen Brown * according to the ACPI 2.0 specification.
27295b482a8SLen Brown */
27395b482a8SLen Brown
27495b482a8SLen Brown /*
27595b482a8SLen Brown * Make sure the target is a Buffer or String. An error should
27695b482a8SLen Brown * not happen here, since the reference_object was constructed
27795b482a8SLen Brown * by the INDEX_OP code.
27895b482a8SLen Brown */
27995b482a8SLen Brown obj_desc = index_desc->reference.object;
2803371c19cSBob Moore if ((obj_desc->common.type != ACPI_TYPE_BUFFER) &&
2813371c19cSBob Moore (obj_desc->common.type != ACPI_TYPE_STRING)) {
28295b482a8SLen Brown return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
28395b482a8SLen Brown }
28495b482a8SLen Brown
28595b482a8SLen Brown /*
28695b482a8SLen Brown * The assignment of the individual elements will be slightly
28795b482a8SLen Brown * different for each source type.
28895b482a8SLen Brown */
2893371c19cSBob Moore switch (source_desc->common.type) {
29095b482a8SLen Brown case ACPI_TYPE_INTEGER:
29195b482a8SLen Brown
29295b482a8SLen Brown /* Use the least-significant byte of the integer */
29395b482a8SLen Brown
29495b482a8SLen Brown value = (u8) (source_desc->integer.value);
29595b482a8SLen Brown break;
29695b482a8SLen Brown
29795b482a8SLen Brown case ACPI_TYPE_BUFFER:
29895b482a8SLen Brown case ACPI_TYPE_STRING:
29995b482a8SLen Brown
30095b482a8SLen Brown /* Note: Takes advantage of common string/buffer fields */
30195b482a8SLen Brown
30295b482a8SLen Brown value = source_desc->buffer.pointer[0];
30395b482a8SLen Brown break;
30495b482a8SLen Brown
30595b482a8SLen Brown default:
30695b482a8SLen Brown
30795b482a8SLen Brown /* All other types are invalid */
30895b482a8SLen Brown
30995b482a8SLen Brown ACPI_ERROR((AE_INFO,
310a5922a1fSBob Moore "Source must be type [Integer/Buffer/String], found [%s]",
31195b482a8SLen Brown acpi_ut_get_object_type_name(source_desc)));
31295b482a8SLen Brown return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
31395b482a8SLen Brown }
31495b482a8SLen Brown
31595b482a8SLen Brown /* Store the source value into the target buffer byte */
31695b482a8SLen Brown
31795b482a8SLen Brown obj_desc->buffer.pointer[index_desc->reference.value] = value;
31895b482a8SLen Brown break;
31995b482a8SLen Brown
32095b482a8SLen Brown default:
321a5922a1fSBob Moore ACPI_ERROR((AE_INFO,
322a5922a1fSBob Moore "Target is not of type [Package/BufferField]"));
323a5922a1fSBob Moore status = AE_AML_TARGET_TYPE;
32495b482a8SLen Brown break;
32595b482a8SLen Brown }
32695b482a8SLen Brown
32795b482a8SLen Brown return_ACPI_STATUS(status);
32895b482a8SLen Brown }
32995b482a8SLen Brown
33095b482a8SLen Brown /*******************************************************************************
33195b482a8SLen Brown *
33295b482a8SLen Brown * FUNCTION: acpi_ex_store_object_to_node
33395b482a8SLen Brown *
33495b482a8SLen Brown * PARAMETERS: source_desc - Value to be stored
335ba494beeSBob Moore * node - Named object to receive the value
33695b482a8SLen Brown * walk_state - Current walk state
33795b482a8SLen Brown * implicit_conversion - Perform implicit conversion (yes/no)
33895b482a8SLen Brown *
33995b482a8SLen Brown * RETURN: Status
34095b482a8SLen Brown *
34195b482a8SLen Brown * DESCRIPTION: Store the object to the named object.
34295b482a8SLen Brown *
343a5922a1fSBob Moore * The assignment of an object to a named object is handled here.
34495b482a8SLen Brown * The value passed in will replace the current value (if any)
34595b482a8SLen Brown * with the input value.
34695b482a8SLen Brown *
34795b482a8SLen Brown * When storing into an object the data is converted to the
34895b482a8SLen Brown * target object type then stored in the object. This means
34995b482a8SLen Brown * that the target object type (for an initialized target) will
3504be4be8fSBob Moore * not be changed by a store operation. A copy_object can change
3514be4be8fSBob Moore * the target type, however.
3524be4be8fSBob Moore *
3534be4be8fSBob Moore * The implicit_conversion flag is set to NO/FALSE only when
3544be4be8fSBob Moore * storing to an arg_x -- as per the rules of the ACPI spec.
35595b482a8SLen Brown *
35695b482a8SLen Brown * Assumes parameters are already validated.
35795b482a8SLen Brown *
35895b482a8SLen Brown ******************************************************************************/
35995b482a8SLen Brown
36095b482a8SLen Brown acpi_status
acpi_ex_store_object_to_node(union acpi_operand_object * source_desc,struct acpi_namespace_node * node,struct acpi_walk_state * walk_state,u8 implicit_conversion)36195b482a8SLen Brown acpi_ex_store_object_to_node(union acpi_operand_object *source_desc,
36295b482a8SLen Brown struct acpi_namespace_node *node,
36395b482a8SLen Brown struct acpi_walk_state *walk_state,
36495b482a8SLen Brown u8 implicit_conversion)
36595b482a8SLen Brown {
36695b482a8SLen Brown acpi_status status = AE_OK;
36795b482a8SLen Brown union acpi_operand_object *target_desc;
36895b482a8SLen Brown union acpi_operand_object *new_desc;
36995b482a8SLen Brown acpi_object_type target_type;
37095b482a8SLen Brown
37195b482a8SLen Brown ACPI_FUNCTION_TRACE_PTR(ex_store_object_to_node, source_desc);
37295b482a8SLen Brown
37395b482a8SLen Brown /* Get current type of the node, and object attached to Node */
37495b482a8SLen Brown
37595b482a8SLen Brown target_type = acpi_ns_get_type(node);
37695b482a8SLen Brown target_desc = acpi_ns_get_attached_object(node);
37795b482a8SLen Brown
378a5922a1fSBob Moore ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Storing %p [%s] to node %p [%s]\n",
37995b482a8SLen Brown source_desc,
38095b482a8SLen Brown acpi_ut_get_object_type_name(source_desc), node,
38195b482a8SLen Brown acpi_ut_get_type_name(target_type)));
38295b482a8SLen Brown
383a5922a1fSBob Moore /* Only limited target types possible for everything except copy_object */
384a5922a1fSBob Moore
3859ff5a21aSBob Moore if (walk_state->opcode != AML_COPY_OBJECT_OP) {
386a5922a1fSBob Moore /*
387a5922a1fSBob Moore * Only copy_object allows all object types to be overwritten. For
388a5922a1fSBob Moore * target_ref(s), there are restrictions on the object types that
389a5922a1fSBob Moore * are allowed.
390a5922a1fSBob Moore *
391a5922a1fSBob Moore * Allowable operations/typing for Store:
392a5922a1fSBob Moore *
393a5922a1fSBob Moore * 1) Simple Store
394a5922a1fSBob Moore * Integer --> Integer (Named/Local/Arg)
395a5922a1fSBob Moore * String --> String (Named/Local/Arg)
396a5922a1fSBob Moore * Buffer --> Buffer (Named/Local/Arg)
397a5922a1fSBob Moore * Package --> Package (Named/Local/Arg)
398a5922a1fSBob Moore *
399a5922a1fSBob Moore * 2) Store with implicit conversion
400a5922a1fSBob Moore * Integer --> String or Buffer (Named)
401a5922a1fSBob Moore * String --> Integer or Buffer (Named)
402a5922a1fSBob Moore * Buffer --> Integer or String (Named)
403a5922a1fSBob Moore */
404a5922a1fSBob Moore switch (target_type) {
405a5922a1fSBob Moore case ACPI_TYPE_PACKAGE:
406a5922a1fSBob Moore /*
407a5922a1fSBob Moore * Here, can only store a package to an existing package.
408a5922a1fSBob Moore * Storing a package to a Local/Arg is OK, and handled
409a5922a1fSBob Moore * elsewhere.
410a5922a1fSBob Moore */
411a5922a1fSBob Moore if (walk_state->opcode == AML_STORE_OP) {
412a5922a1fSBob Moore if (source_desc->common.type !=
413a5922a1fSBob Moore ACPI_TYPE_PACKAGE) {
414a5922a1fSBob Moore ACPI_ERROR((AE_INFO,
415a5922a1fSBob Moore "Cannot assign type [%s] to [Package] "
416a5922a1fSBob Moore "(source must be type Pkg)",
417a5922a1fSBob Moore acpi_ut_get_object_type_name
418a5922a1fSBob Moore (source_desc)));
419a5922a1fSBob Moore
420a5922a1fSBob Moore return_ACPI_STATUS(AE_AML_TARGET_TYPE);
421a5922a1fSBob Moore }
422a5922a1fSBob Moore break;
423a5922a1fSBob Moore }
424a5922a1fSBob Moore
425c1a7c2ceSNick Desaulniers ACPI_FALLTHROUGH;
426a5922a1fSBob Moore
427a5922a1fSBob Moore case ACPI_TYPE_DEVICE:
428a5922a1fSBob Moore case ACPI_TYPE_EVENT:
429a5922a1fSBob Moore case ACPI_TYPE_MUTEX:
430a5922a1fSBob Moore case ACPI_TYPE_REGION:
431a5922a1fSBob Moore case ACPI_TYPE_POWER:
432a5922a1fSBob Moore case ACPI_TYPE_PROCESSOR:
433a5922a1fSBob Moore case ACPI_TYPE_THERMAL:
434a5922a1fSBob Moore
435a5922a1fSBob Moore ACPI_ERROR((AE_INFO,
4361fad8738SBob Moore "Target must be [Buffer/Integer/String/Reference]"
4371fad8738SBob Moore ", found [%s] (%4.4s)",
438a5922a1fSBob Moore acpi_ut_get_type_name(node->type),
439a5922a1fSBob Moore node->name.ascii));
440a5922a1fSBob Moore
441a5922a1fSBob Moore return_ACPI_STATUS(AE_AML_TARGET_TYPE);
442a5922a1fSBob Moore
443a5922a1fSBob Moore default:
444a5922a1fSBob Moore break;
445a5922a1fSBob Moore }
446a5922a1fSBob Moore }
447a5922a1fSBob Moore
44895b482a8SLen Brown /*
44995b482a8SLen Brown * Resolve the source object to an actual value
45095b482a8SLen Brown * (If it is a reference object)
45195b482a8SLen Brown */
45295b482a8SLen Brown status = acpi_ex_resolve_object(&source_desc, target_type, walk_state);
45395b482a8SLen Brown if (ACPI_FAILURE(status)) {
45495b482a8SLen Brown return_ACPI_STATUS(status);
45595b482a8SLen Brown }
45695b482a8SLen Brown
45795b482a8SLen Brown /* Do the actual store operation */
45895b482a8SLen Brown
45995b482a8SLen Brown switch (target_type) {
46095b482a8SLen Brown /*
4614be4be8fSBob Moore * The simple data types all support implicit source operand
4624be4be8fSBob Moore * conversion before the store.
46395b482a8SLen Brown */
464a5922a1fSBob Moore case ACPI_TYPE_INTEGER:
465a5922a1fSBob Moore case ACPI_TYPE_STRING:
466a5922a1fSBob Moore case ACPI_TYPE_BUFFER:
4674be4be8fSBob Moore
4689ff5a21aSBob Moore if ((walk_state->opcode == AML_COPY_OBJECT_OP) ||
4699ff5a21aSBob Moore !implicit_conversion) {
4704be4be8fSBob Moore /*
4714be4be8fSBob Moore * However, copy_object and Stores to arg_x do not perform
4724be4be8fSBob Moore * an implicit conversion, as per the ACPI specification.
4734be4be8fSBob Moore * A direct store is performed instead.
4744be4be8fSBob Moore */
4751fad8738SBob Moore status =
4761fad8738SBob Moore acpi_ex_store_direct_to_node(source_desc, node,
4774be4be8fSBob Moore walk_state);
4784be4be8fSBob Moore break;
4794be4be8fSBob Moore }
4804be4be8fSBob Moore
4814be4be8fSBob Moore /* Store with implicit source operand conversion support */
4824be4be8fSBob Moore
48395b482a8SLen Brown status =
48495b482a8SLen Brown acpi_ex_store_object_to_object(source_desc, target_desc,
48595b482a8SLen Brown &new_desc, walk_state);
48695b482a8SLen Brown if (ACPI_FAILURE(status)) {
48795b482a8SLen Brown return_ACPI_STATUS(status);
48895b482a8SLen Brown }
48995b482a8SLen Brown
49095b482a8SLen Brown if (new_desc != target_desc) {
49195b482a8SLen Brown /*
49295b482a8SLen Brown * Store the new new_desc as the new value of the Name, and set
49395b482a8SLen Brown * the Name's type to that of the value being stored in it.
49495b482a8SLen Brown * source_desc reference count is incremented by attach_object.
49595b482a8SLen Brown *
4964be4be8fSBob Moore * Note: This may change the type of the node if an explicit
4974be4be8fSBob Moore * store has been performed such that the node/object type
4984be4be8fSBob Moore * has been changed.
49995b482a8SLen Brown */
5001fad8738SBob Moore status =
5011fad8738SBob Moore acpi_ns_attach_object(node, new_desc,
50295b482a8SLen Brown new_desc->common.type);
50395b482a8SLen Brown
50495b482a8SLen Brown ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
505a5922a1fSBob Moore "Store type [%s] into [%s] via Convert/Attach\n",
50695b482a8SLen Brown acpi_ut_get_object_type_name
50795b482a8SLen Brown (source_desc),
50895b482a8SLen Brown acpi_ut_get_object_type_name
50995b482a8SLen Brown (new_desc)));
51095b482a8SLen Brown }
51195b482a8SLen Brown break;
51295b482a8SLen Brown
5134be4be8fSBob Moore case ACPI_TYPE_BUFFER_FIELD:
5144be4be8fSBob Moore case ACPI_TYPE_LOCAL_REGION_FIELD:
5154be4be8fSBob Moore case ACPI_TYPE_LOCAL_BANK_FIELD:
5164be4be8fSBob Moore case ACPI_TYPE_LOCAL_INDEX_FIELD:
5174be4be8fSBob Moore /*
5184be4be8fSBob Moore * For all fields, always write the source data to the target
5194be4be8fSBob Moore * field. Any required implicit source operand conversion is
5204be4be8fSBob Moore * performed in the function below as necessary. Note, field
5214be4be8fSBob Moore * objects must retain their original type permanently.
5224be4be8fSBob Moore */
5234be4be8fSBob Moore status = acpi_ex_write_data_to_field(source_desc, target_desc,
5244be4be8fSBob Moore &walk_state->result_obj);
5254be4be8fSBob Moore break;
5264be4be8fSBob Moore
52795b482a8SLen Brown default:
5284be4be8fSBob Moore /*
529a5922a1fSBob Moore * copy_object operator: No conversions for all other types.
530a5922a1fSBob Moore * Instead, directly store a copy of the source object.
5314be4be8fSBob Moore *
532a5922a1fSBob Moore * This is the ACPI spec-defined behavior for the copy_object
533a5922a1fSBob Moore * operator. (Note, for this default case, all normal
534a5922a1fSBob Moore * Store/Target operations exited above with an error).
5354be4be8fSBob Moore */
5361fad8738SBob Moore status =
5371fad8738SBob Moore acpi_ex_store_direct_to_node(source_desc, node, walk_state);
5384be4be8fSBob Moore break;
5394be4be8fSBob Moore }
5404be4be8fSBob Moore
5414be4be8fSBob Moore return_ACPI_STATUS(status);
5424be4be8fSBob Moore }
5434be4be8fSBob Moore
5444be4be8fSBob Moore /*******************************************************************************
5454be4be8fSBob Moore *
5464be4be8fSBob Moore * FUNCTION: acpi_ex_store_direct_to_node
5474be4be8fSBob Moore *
5484be4be8fSBob Moore * PARAMETERS: source_desc - Value to be stored
5494be4be8fSBob Moore * node - Named object to receive the value
5504be4be8fSBob Moore * walk_state - Current walk state
5514be4be8fSBob Moore *
5524be4be8fSBob Moore * RETURN: Status
5534be4be8fSBob Moore *
5544be4be8fSBob Moore * DESCRIPTION: "Store" an object directly to a node. This involves a copy
5554be4be8fSBob Moore * and an attach.
5564be4be8fSBob Moore *
5574be4be8fSBob Moore ******************************************************************************/
5584be4be8fSBob Moore
5594be4be8fSBob Moore static acpi_status
acpi_ex_store_direct_to_node(union acpi_operand_object * source_desc,struct acpi_namespace_node * node,struct acpi_walk_state * walk_state)5604be4be8fSBob Moore acpi_ex_store_direct_to_node(union acpi_operand_object *source_desc,
5614be4be8fSBob Moore struct acpi_namespace_node *node,
5624be4be8fSBob Moore struct acpi_walk_state *walk_state)
5634be4be8fSBob Moore {
5644be4be8fSBob Moore acpi_status status;
5654be4be8fSBob Moore union acpi_operand_object *new_desc;
5664be4be8fSBob Moore
5674be4be8fSBob Moore ACPI_FUNCTION_TRACE(ex_store_direct_to_node);
56895b482a8SLen Brown
56995b482a8SLen Brown ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
5703f654badSBob Moore "Storing [%s] (%p) directly into node [%s] (%p)"
5713f654badSBob Moore " with no implicit conversion\n",
57295b482a8SLen Brown acpi_ut_get_object_type_name(source_desc),
5734be4be8fSBob Moore source_desc, acpi_ut_get_type_name(node->type),
5743f654badSBob Moore node));
57595b482a8SLen Brown
5764be4be8fSBob Moore /* Copy the source object to a new object */
5774be4be8fSBob Moore
5783f654badSBob Moore status =
5794be4be8fSBob Moore acpi_ut_copy_iobject_to_iobject(source_desc, &new_desc, walk_state);
5803f654badSBob Moore if (ACPI_FAILURE(status)) {
5813f654badSBob Moore return_ACPI_STATUS(status);
5823f654badSBob Moore }
58395b482a8SLen Brown
5844be4be8fSBob Moore /* Attach the new object to the node */
58595b482a8SLen Brown
5864be4be8fSBob Moore status = acpi_ns_attach_object(node, new_desc, new_desc->common.type);
5874be4be8fSBob Moore acpi_ut_remove_reference(new_desc);
58895b482a8SLen Brown return_ACPI_STATUS(status);
58995b482a8SLen Brown }
590