ACPICA: All acpica: Update copyrights to 2020 Including tool signons.
[linux-2.6-microblaze.git] / drivers / acpi / acpica / dsobject.c
1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /******************************************************************************
3  *
4  * Module Name: dsobject - Dispatcher object management routines
5  *
6  * Copyright (C) 2000 - 2020, Intel Corp.
7  *
8  *****************************************************************************/
9
10 #include <acpi/acpi.h>
11 #include "accommon.h"
12 #include "acparser.h"
13 #include "amlcode.h"
14 #include "acdispat.h"
15 #include "acnamesp.h"
16 #include "acinterp.h"
17
18 #define _COMPONENT          ACPI_DISPATCHER
19 ACPI_MODULE_NAME("dsobject")
20
21 /*******************************************************************************
22  *
23  * FUNCTION:    acpi_ds_build_internal_object
24  *
25  * PARAMETERS:  walk_state      - Current walk state
26  *              op              - Parser object to be translated
27  *              obj_desc_ptr    - Where the ACPI internal object is returned
28  *
29  * RETURN:      Status
30  *
31  * DESCRIPTION: Translate a parser Op object to the equivalent namespace object
32  *              Simple objects are any objects other than a package object!
33  *
34  ******************************************************************************/
35 acpi_status
36 acpi_ds_build_internal_object(struct acpi_walk_state *walk_state,
37                               union acpi_parse_object *op,
38                               union acpi_operand_object **obj_desc_ptr)
39 {
40         union acpi_operand_object *obj_desc;
41         acpi_status status;
42
43         ACPI_FUNCTION_TRACE(ds_build_internal_object);
44
45         *obj_desc_ptr = NULL;
46         if (op->common.aml_opcode == AML_INT_NAMEPATH_OP) {
47                 /*
48                  * This is a named object reference. If this name was
49                  * previously looked up in the namespace, it was stored in
50                  * this op. Otherwise, go ahead and look it up now
51                  */
52                 if (!op->common.node) {
53
54                         /* Check if we are resolving a named reference within a package */
55
56                         if ((op->common.parent->common.aml_opcode ==
57                              AML_PACKAGE_OP)
58                             || (op->common.parent->common.aml_opcode ==
59                                 AML_VARIABLE_PACKAGE_OP)) {
60                                 /*
61                                  * We won't resolve package elements here, we will do this
62                                  * after all ACPI tables are loaded into the namespace. This
63                                  * behavior supports both forward references to named objects
64                                  * and external references to objects in other tables.
65                                  */
66                                 goto create_new_object;
67                         } else {
68                                 status = acpi_ns_lookup(walk_state->scope_info,
69                                                         op->common.value.string,
70                                                         ACPI_TYPE_ANY,
71                                                         ACPI_IMODE_EXECUTE,
72                                                         ACPI_NS_SEARCH_PARENT |
73                                                         ACPI_NS_DONT_OPEN_SCOPE,
74                                                         NULL,
75                                                         ACPI_CAST_INDIRECT_PTR
76                                                         (struct
77                                                          acpi_namespace_node,
78                                                          &(op->common.node)));
79                                 if (ACPI_FAILURE(status)) {
80                                         ACPI_ERROR_NAMESPACE(walk_state->
81                                                              scope_info,
82                                                              op->common.value.
83                                                              string, status);
84                                         return_ACPI_STATUS(status);
85                                 }
86                         }
87                 }
88         }
89
90 create_new_object:
91
92         /* Create and init a new internal ACPI object */
93
94         obj_desc = acpi_ut_create_internal_object((acpi_ps_get_opcode_info
95                                                    (op->common.aml_opcode))->
96                                                   object_type);
97         if (!obj_desc) {
98                 return_ACPI_STATUS(AE_NO_MEMORY);
99         }
100
101         status =
102             acpi_ds_init_object_from_op(walk_state, op, op->common.aml_opcode,
103                                         &obj_desc);
104         if (ACPI_FAILURE(status)) {
105                 acpi_ut_remove_reference(obj_desc);
106                 return_ACPI_STATUS(status);
107         }
108
109         /*
110          * Handling for unresolved package reference elements.
111          * These are elements that are namepaths.
112          */
113         if ((op->common.parent->common.aml_opcode == AML_PACKAGE_OP) ||
114             (op->common.parent->common.aml_opcode == AML_VARIABLE_PACKAGE_OP)) {
115                 obj_desc->reference.resolved = TRUE;
116
117                 if ((op->common.aml_opcode == AML_INT_NAMEPATH_OP) &&
118                     !obj_desc->reference.node) {
119                         /*
120                          * Name was unresolved above.
121                          * Get the prefix node for later lookup
122                          */
123                         obj_desc->reference.node =
124                             walk_state->scope_info->scope.node;
125                         obj_desc->reference.aml = op->common.aml;
126                         obj_desc->reference.resolved = FALSE;
127                 }
128         }
129
130         *obj_desc_ptr = obj_desc;
131         return_ACPI_STATUS(status);
132 }
133
134 /*******************************************************************************
135  *
136  * FUNCTION:    acpi_ds_build_internal_buffer_obj
137  *
138  * PARAMETERS:  walk_state      - Current walk state
139  *              op              - Parser object to be translated
140  *              buffer_length   - Length of the buffer
141  *              obj_desc_ptr    - Where the ACPI internal object is returned
142  *
143  * RETURN:      Status
144  *
145  * DESCRIPTION: Translate a parser Op package object to the equivalent
146  *              namespace object
147  *
148  ******************************************************************************/
149
150 acpi_status
151 acpi_ds_build_internal_buffer_obj(struct acpi_walk_state *walk_state,
152                                   union acpi_parse_object *op,
153                                   u32 buffer_length,
154                                   union acpi_operand_object **obj_desc_ptr)
155 {
156         union acpi_parse_object *arg;
157         union acpi_operand_object *obj_desc;
158         union acpi_parse_object *byte_list;
159         u32 byte_list_length = 0;
160
161         ACPI_FUNCTION_TRACE(ds_build_internal_buffer_obj);
162
163         /*
164          * If we are evaluating a Named buffer object "Name (xxxx, Buffer)".
165          * The buffer object already exists (from the NS node), otherwise it must
166          * be created.
167          */
168         obj_desc = *obj_desc_ptr;
169         if (!obj_desc) {
170
171                 /* Create a new buffer object */
172
173                 obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER);
174                 *obj_desc_ptr = obj_desc;
175                 if (!obj_desc) {
176                         return_ACPI_STATUS(AE_NO_MEMORY);
177                 }
178         }
179
180         /*
181          * Second arg is the buffer data (optional) byte_list can be either
182          * individual bytes or a string initializer. In either case, a
183          * byte_list appears in the AML.
184          */
185         arg = op->common.value.arg;     /* skip first arg */
186
187         byte_list = arg->named.next;
188         if (byte_list) {
189                 if (byte_list->common.aml_opcode != AML_INT_BYTELIST_OP) {
190                         ACPI_ERROR((AE_INFO,
191                                     "Expecting bytelist, found AML opcode 0x%X in op %p",
192                                     byte_list->common.aml_opcode, byte_list));
193
194                         acpi_ut_remove_reference(obj_desc);
195                         return (AE_TYPE);
196                 }
197
198                 byte_list_length = (u32) byte_list->common.value.integer;
199         }
200
201         /*
202          * The buffer length (number of bytes) will be the larger of:
203          * 1) The specified buffer length and
204          * 2) The length of the initializer byte list
205          */
206         obj_desc->buffer.length = buffer_length;
207         if (byte_list_length > buffer_length) {
208                 obj_desc->buffer.length = byte_list_length;
209         }
210
211         /* Allocate the buffer */
212
213         if (obj_desc->buffer.length == 0) {
214                 obj_desc->buffer.pointer = NULL;
215                 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
216                                   "Buffer defined with zero length in AML, creating\n"));
217         } else {
218                 obj_desc->buffer.pointer =
219                     ACPI_ALLOCATE_ZEROED(obj_desc->buffer.length);
220                 if (!obj_desc->buffer.pointer) {
221                         acpi_ut_delete_object_desc(obj_desc);
222                         return_ACPI_STATUS(AE_NO_MEMORY);
223                 }
224
225                 /* Initialize buffer from the byte_list (if present) */
226
227                 if (byte_list) {
228                         memcpy(obj_desc->buffer.pointer, byte_list->named.data,
229                                byte_list_length);
230                 }
231         }
232
233         obj_desc->buffer.flags |= AOPOBJ_DATA_VALID;
234         op->common.node = ACPI_CAST_PTR(struct acpi_namespace_node, obj_desc);
235         return_ACPI_STATUS(AE_OK);
236 }
237
238 /*******************************************************************************
239  *
240  * FUNCTION:    acpi_ds_create_node
241  *
242  * PARAMETERS:  walk_state      - Current walk state
243  *              node            - NS Node to be initialized
244  *              op              - Parser object to be translated
245  *
246  * RETURN:      Status
247  *
248  * DESCRIPTION: Create the object to be associated with a namespace node
249  *
250  ******************************************************************************/
251
252 acpi_status
253 acpi_ds_create_node(struct acpi_walk_state *walk_state,
254                     struct acpi_namespace_node *node,
255                     union acpi_parse_object *op)
256 {
257         acpi_status status;
258         union acpi_operand_object *obj_desc;
259
260         ACPI_FUNCTION_TRACE_PTR(ds_create_node, op);
261
262         /*
263          * Because of the execution pass through the non-control-method
264          * parts of the table, we can arrive here twice. Only init
265          * the named object node the first time through
266          */
267         if (acpi_ns_get_attached_object(node)) {
268                 return_ACPI_STATUS(AE_OK);
269         }
270
271         if (!op->common.value.arg) {
272
273                 /* No arguments, there is nothing to do */
274
275                 return_ACPI_STATUS(AE_OK);
276         }
277
278         /* Build an internal object for the argument(s) */
279
280         status =
281             acpi_ds_build_internal_object(walk_state, op->common.value.arg,
282                                           &obj_desc);
283         if (ACPI_FAILURE(status)) {
284                 return_ACPI_STATUS(status);
285         }
286
287         /* Re-type the object according to its argument */
288
289         node->type = obj_desc->common.type;
290
291         /* Attach obj to node */
292
293         status = acpi_ns_attach_object(node, obj_desc, node->type);
294
295         /* Remove local reference to the object */
296
297         acpi_ut_remove_reference(obj_desc);
298         return_ACPI_STATUS(status);
299 }
300
301 /*******************************************************************************
302  *
303  * FUNCTION:    acpi_ds_init_object_from_op
304  *
305  * PARAMETERS:  walk_state      - Current walk state
306  *              op              - Parser op used to init the internal object
307  *              opcode          - AML opcode associated with the object
308  *              ret_obj_desc    - Namespace object to be initialized
309  *
310  * RETURN:      Status
311  *
312  * DESCRIPTION: Initialize a namespace object from a parser Op and its
313  *              associated arguments. The namespace object is a more compact
314  *              representation of the Op and its arguments.
315  *
316  ******************************************************************************/
317
318 acpi_status
319 acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state,
320                             union acpi_parse_object *op,
321                             u16 opcode,
322                             union acpi_operand_object **ret_obj_desc)
323 {
324         const struct acpi_opcode_info *op_info;
325         union acpi_operand_object *obj_desc;
326         acpi_status status = AE_OK;
327
328         ACPI_FUNCTION_TRACE(ds_init_object_from_op);
329
330         obj_desc = *ret_obj_desc;
331         op_info = acpi_ps_get_opcode_info(opcode);
332         if (op_info->class == AML_CLASS_UNKNOWN) {
333
334                 /* Unknown opcode */
335
336                 return_ACPI_STATUS(AE_TYPE);
337         }
338
339         /* Perform per-object initialization */
340
341         switch (obj_desc->common.type) {
342         case ACPI_TYPE_BUFFER:
343                 /*
344                  * Defer evaluation of Buffer term_arg operand
345                  */
346                 obj_desc->buffer.node =
347                     ACPI_CAST_PTR(struct acpi_namespace_node,
348                                   walk_state->operands[0]);
349                 obj_desc->buffer.aml_start = op->named.data;
350                 obj_desc->buffer.aml_length = op->named.length;
351                 break;
352
353         case ACPI_TYPE_PACKAGE:
354                 /*
355                  * Defer evaluation of Package term_arg operand and all
356                  * package elements. (01/2017): We defer the element
357                  * resolution to allow forward references from the package
358                  * in order to provide compatibility with other ACPI
359                  * implementations.
360                  */
361                 obj_desc->package.node =
362                     ACPI_CAST_PTR(struct acpi_namespace_node,
363                                   walk_state->operands[0]);
364
365                 if (!op->named.data) {
366                         return_ACPI_STATUS(AE_OK);
367                 }
368
369                 obj_desc->package.aml_start = op->named.data;
370                 obj_desc->package.aml_length = op->named.length;
371                 break;
372
373         case ACPI_TYPE_INTEGER:
374
375                 switch (op_info->type) {
376                 case AML_TYPE_CONSTANT:
377                         /*
378                          * Resolve AML Constants here - AND ONLY HERE!
379                          * All constants are integers.
380                          * We mark the integer with a flag that indicates that it started
381                          * life as a constant -- so that stores to constants will perform
382                          * as expected (noop). zero_op is used as a placeholder for optional
383                          * target operands.
384                          */
385                         obj_desc->common.flags = AOPOBJ_AML_CONSTANT;
386
387                         switch (opcode) {
388                         case AML_ZERO_OP:
389
390                                 obj_desc->integer.value = 0;
391                                 break;
392
393                         case AML_ONE_OP:
394
395                                 obj_desc->integer.value = 1;
396                                 break;
397
398                         case AML_ONES_OP:
399
400                                 obj_desc->integer.value = ACPI_UINT64_MAX;
401
402                                 /* Truncate value if we are executing from a 32-bit ACPI table */
403
404                                 (void)acpi_ex_truncate_for32bit_table(obj_desc);
405                                 break;
406
407                         case AML_REVISION_OP:
408
409                                 obj_desc->integer.value = ACPI_CA_VERSION;
410                                 break;
411
412                         default:
413
414                                 ACPI_ERROR((AE_INFO,
415                                             "Unknown constant opcode 0x%X",
416                                             opcode));
417                                 status = AE_AML_OPERAND_TYPE;
418                                 break;
419                         }
420                         break;
421
422                 case AML_TYPE_LITERAL:
423
424                         obj_desc->integer.value = op->common.value.integer;
425
426                         if (acpi_ex_truncate_for32bit_table(obj_desc)) {
427
428                                 /* Warn if we found a 64-bit constant in a 32-bit table */
429
430                                 ACPI_WARNING((AE_INFO,
431                                               "Truncated 64-bit constant found in 32-bit table: %8.8X%8.8X => %8.8X",
432                                               ACPI_FORMAT_UINT64(op->common.
433                                                                  value.integer),
434                                               (u32)obj_desc->integer.value));
435                         }
436                         break;
437
438                 default:
439
440                         ACPI_ERROR((AE_INFO, "Unknown Integer type 0x%X",
441                                     op_info->type));
442                         status = AE_AML_OPERAND_TYPE;
443                         break;
444                 }
445                 break;
446
447         case ACPI_TYPE_STRING:
448
449                 obj_desc->string.pointer = op->common.value.string;
450                 obj_desc->string.length = (u32)strlen(op->common.value.string);
451
452                 /*
453                  * The string is contained in the ACPI table, don't ever try
454                  * to delete it
455                  */
456                 obj_desc->common.flags |= AOPOBJ_STATIC_POINTER;
457                 break;
458
459         case ACPI_TYPE_METHOD:
460                 break;
461
462         case ACPI_TYPE_LOCAL_REFERENCE:
463
464                 switch (op_info->type) {
465                 case AML_TYPE_LOCAL_VARIABLE:
466
467                         /* Local ID (0-7) is (AML opcode - base AML_FIRST_LOCAL_OP) */
468
469                         obj_desc->reference.value =
470                             ((u32)opcode) - AML_FIRST_LOCAL_OP;
471                         obj_desc->reference.class = ACPI_REFCLASS_LOCAL;
472
473                         status =
474                             acpi_ds_method_data_get_node(ACPI_REFCLASS_LOCAL,
475                                                          obj_desc->reference.
476                                                          value, walk_state,
477                                                          ACPI_CAST_INDIRECT_PTR
478                                                          (struct
479                                                           acpi_namespace_node,
480                                                           &obj_desc->reference.
481                                                           object));
482                         break;
483
484                 case AML_TYPE_METHOD_ARGUMENT:
485
486                         /* Arg ID (0-6) is (AML opcode - base AML_FIRST_ARG_OP) */
487
488                         obj_desc->reference.value =
489                             ((u32)opcode) - AML_FIRST_ARG_OP;
490                         obj_desc->reference.class = ACPI_REFCLASS_ARG;
491
492                         status = acpi_ds_method_data_get_node(ACPI_REFCLASS_ARG,
493                                                               obj_desc->
494                                                               reference.value,
495                                                               walk_state,
496                                                               ACPI_CAST_INDIRECT_PTR
497                                                               (struct
498                                                                acpi_namespace_node,
499                                                                &obj_desc->
500                                                                reference.
501                                                                object));
502                         break;
503
504                 default:        /* Object name or Debug object */
505
506                         switch (op->common.aml_opcode) {
507                         case AML_INT_NAMEPATH_OP:
508
509                                 /* Node was saved in Op */
510
511                                 obj_desc->reference.node = op->common.node;
512                                 obj_desc->reference.class = ACPI_REFCLASS_NAME;
513                                 if (op->common.node) {
514                                         obj_desc->reference.object =
515                                             op->common.node->object;
516                                 }
517                                 break;
518
519                         case AML_DEBUG_OP:
520
521                                 obj_desc->reference.class = ACPI_REFCLASS_DEBUG;
522                                 break;
523
524                         default:
525
526                                 ACPI_ERROR((AE_INFO,
527                                             "Unimplemented reference type for AML opcode: 0x%4.4X",
528                                             opcode));
529                                 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
530                         }
531                         break;
532                 }
533                 break;
534
535         default:
536
537                 ACPI_ERROR((AE_INFO, "Unimplemented data type: 0x%X",
538                             obj_desc->common.type));
539
540                 status = AE_AML_OPERAND_TYPE;
541                 break;
542         }
543
544         return_ACPI_STATUS(status);
545 }