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