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