exresop.c revision 1.1.1.2 1
2 /******************************************************************************
3 *
4 * Module Name: exresop - AML Interpreter operand/object resolution
5 *
6 *****************************************************************************/
7
8 /*
9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45 #define __EXRESOP_C__
46
47 #include "acpi.h"
48 #include "accommon.h"
49 #include "amlcode.h"
50 #include "acparser.h"
51 #include "acinterp.h"
52 #include "acnamesp.h"
53
54
55 #define _COMPONENT ACPI_EXECUTER
56 ACPI_MODULE_NAME ("exresop")
57
58 /* Local prototypes */
59
60 static ACPI_STATUS
61 AcpiExCheckObjectType (
62 ACPI_OBJECT_TYPE TypeNeeded,
63 ACPI_OBJECT_TYPE ThisType,
64 void *Object);
65
66
67 /*******************************************************************************
68 *
69 * FUNCTION: AcpiExCheckObjectType
70 *
71 * PARAMETERS: TypeNeeded Object type needed
72 * ThisType Actual object type
73 * Object Object pointer
74 *
75 * RETURN: Status
76 *
77 * DESCRIPTION: Check required type against actual type
78 *
79 ******************************************************************************/
80
81 static ACPI_STATUS
82 AcpiExCheckObjectType (
83 ACPI_OBJECT_TYPE TypeNeeded,
84 ACPI_OBJECT_TYPE ThisType,
85 void *Object)
86 {
87 ACPI_FUNCTION_ENTRY ();
88
89
90 if (TypeNeeded == ACPI_TYPE_ANY)
91 {
92 /* All types OK, so we don't perform any typechecks */
93
94 return (AE_OK);
95 }
96
97 if (TypeNeeded == ACPI_TYPE_LOCAL_REFERENCE)
98 {
99 /*
100 * Allow the AML "Constant" opcodes (Zero, One, etc.) to be reference
101 * objects and thus allow them to be targets. (As per the ACPI
102 * specification, a store to a constant is a noop.)
103 */
104 if ((ThisType == ACPI_TYPE_INTEGER) &&
105 (((ACPI_OPERAND_OBJECT *) Object)->Common.Flags & AOPOBJ_AML_CONSTANT))
106 {
107 return (AE_OK);
108 }
109 }
110
111 if (TypeNeeded != ThisType)
112 {
113 ACPI_ERROR ((AE_INFO,
114 "Needed type [%s], found [%s] %p",
115 AcpiUtGetTypeName (TypeNeeded),
116 AcpiUtGetTypeName (ThisType), Object));
117
118 return (AE_AML_OPERAND_TYPE);
119 }
120
121 return (AE_OK);
122 }
123
124
125 /*******************************************************************************
126 *
127 * FUNCTION: AcpiExResolveOperands
128 *
129 * PARAMETERS: Opcode - Opcode being interpreted
130 * StackPtr - Pointer to the operand stack to be
131 * resolved
132 * WalkState - Current state
133 *
134 * RETURN: Status
135 *
136 * DESCRIPTION: Convert multiple input operands to the types required by the
137 * target operator.
138 *
139 * Each 5-bit group in ArgTypes represents one required
140 * operand and indicates the required Type. The corresponding operand
141 * will be converted to the required type if possible, otherwise we
142 * abort with an exception.
143 *
144 ******************************************************************************/
145
146 ACPI_STATUS
147 AcpiExResolveOperands (
148 UINT16 Opcode,
149 ACPI_OPERAND_OBJECT **StackPtr,
150 ACPI_WALK_STATE *WalkState)
151 {
152 ACPI_OPERAND_OBJECT *ObjDesc;
153 ACPI_STATUS Status = AE_OK;
154 UINT8 ObjectType;
155 UINT32 ArgTypes;
156 const ACPI_OPCODE_INFO *OpInfo;
157 UINT32 ThisArgType;
158 ACPI_OBJECT_TYPE TypeNeeded;
159 UINT16 TargetOp = 0;
160
161
162 ACPI_FUNCTION_TRACE_U32 (ExResolveOperands, Opcode);
163
164
165 OpInfo = AcpiPsGetOpcodeInfo (Opcode);
166 if (OpInfo->Class == AML_CLASS_UNKNOWN)
167 {
168 return_ACPI_STATUS (AE_AML_BAD_OPCODE);
169 }
170
171 ArgTypes = OpInfo->RuntimeArgs;
172 if (ArgTypes == ARGI_INVALID_OPCODE)
173 {
174 ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
175 Opcode));
176
177 return_ACPI_STATUS (AE_AML_INTERNAL);
178 }
179
180 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
181 "Opcode %X [%s] RequiredOperandTypes=%8.8X\n",
182 Opcode, OpInfo->Name, ArgTypes));
183
184 /*
185 * Normal exit is with (ArgTypes == 0) at end of argument list.
186 * Function will return an exception from within the loop upon
187 * finding an entry which is not (or cannot be converted
188 * to) the required type; if stack underflows; or upon
189 * finding a NULL stack entry (which should not happen).
190 */
191 while (GET_CURRENT_ARG_TYPE (ArgTypes))
192 {
193 if (!StackPtr || !*StackPtr)
194 {
195 ACPI_ERROR ((AE_INFO, "Null stack entry at %p",
196 StackPtr));
197
198 return_ACPI_STATUS (AE_AML_INTERNAL);
199 }
200
201 /* Extract useful items */
202
203 ObjDesc = *StackPtr;
204
205 /* Decode the descriptor type */
206
207 switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc))
208 {
209 case ACPI_DESC_TYPE_NAMED:
210
211 /* Namespace Node */
212
213 ObjectType = ((ACPI_NAMESPACE_NODE *) ObjDesc)->Type;
214
215 /*
216 * Resolve an alias object. The construction of these objects
217 * guarantees that there is only one level of alias indirection;
218 * thus, the attached object is always the aliased namespace node
219 */
220 if (ObjectType == ACPI_TYPE_LOCAL_ALIAS)
221 {
222 ObjDesc = AcpiNsGetAttachedObject ((ACPI_NAMESPACE_NODE *) ObjDesc);
223 *StackPtr = ObjDesc;
224 ObjectType = ((ACPI_NAMESPACE_NODE *) ObjDesc)->Type;
225 }
226 break;
227
228
229 case ACPI_DESC_TYPE_OPERAND:
230
231 /* ACPI internal object */
232
233 ObjectType = ObjDesc->Common.Type;
234
235 /* Check for bad ACPI_OBJECT_TYPE */
236
237 if (!AcpiUtValidObjectType (ObjectType))
238 {
239 ACPI_ERROR ((AE_INFO,
240 "Bad operand object type [0x%X]", ObjectType));
241
242 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
243 }
244
245 if (ObjectType == (UINT8) ACPI_TYPE_LOCAL_REFERENCE)
246 {
247 /* Validate the Reference */
248
249 switch (ObjDesc->Reference.Class)
250 {
251 case ACPI_REFCLASS_DEBUG:
252
253 TargetOp = AML_DEBUG_OP;
254
255 /*lint -fallthrough */
256
257 case ACPI_REFCLASS_ARG:
258 case ACPI_REFCLASS_LOCAL:
259 case ACPI_REFCLASS_INDEX:
260 case ACPI_REFCLASS_REFOF:
261 case ACPI_REFCLASS_TABLE: /* DdbHandle from LOAD_OP or LOAD_TABLE_OP */
262 case ACPI_REFCLASS_NAME: /* Reference to a named object */
263
264 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
265 "Operand is a Reference, Class [%s] %2.2X\n",
266 AcpiUtGetReferenceName (ObjDesc),
267 ObjDesc->Reference.Class));
268 break;
269
270 default:
271
272 ACPI_ERROR ((AE_INFO,
273 "Unknown Reference Class 0x%2.2X in %p",
274 ObjDesc->Reference.Class, ObjDesc));
275
276 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
277 }
278 }
279 break;
280
281
282 default:
283
284 /* Invalid descriptor */
285
286 ACPI_ERROR ((AE_INFO, "Invalid descriptor %p [%s]",
287 ObjDesc, AcpiUtGetDescriptorName (ObjDesc)));
288
289 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
290 }
291
292 /* Get one argument type, point to the next */
293
294 ThisArgType = GET_CURRENT_ARG_TYPE (ArgTypes);
295 INCREMENT_ARG_LIST (ArgTypes);
296
297 /*
298 * Handle cases where the object does not need to be
299 * resolved to a value
300 */
301 switch (ThisArgType)
302 {
303 case ARGI_REF_OR_STRING: /* Can be a String or Reference */
304
305 if ((ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) == ACPI_DESC_TYPE_OPERAND) &&
306 (ObjDesc->Common.Type == ACPI_TYPE_STRING))
307 {
308 /*
309 * String found - the string references a named object and
310 * must be resolved to a node
311 */
312 goto NextOperand;
313 }
314
315 /*
316 * Else not a string - fall through to the normal Reference
317 * case below
318 */
319 /*lint -fallthrough */
320
321 case ARGI_REFERENCE: /* References: */
322 case ARGI_INTEGER_REF:
323 case ARGI_OBJECT_REF:
324 case ARGI_DEVICE_REF:
325 case ARGI_TARGETREF: /* Allows implicit conversion rules before store */
326 case ARGI_FIXED_TARGET: /* No implicit conversion before store to target */
327 case ARGI_SIMPLE_TARGET: /* Name, Local, or Arg - no implicit conversion */
328
329 /*
330 * Need an operand of type ACPI_TYPE_LOCAL_REFERENCE
331 * A Namespace Node is OK as-is
332 */
333 if (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) == ACPI_DESC_TYPE_NAMED)
334 {
335 goto NextOperand;
336 }
337
338 Status = AcpiExCheckObjectType (ACPI_TYPE_LOCAL_REFERENCE,
339 ObjectType, ObjDesc);
340 if (ACPI_FAILURE (Status))
341 {
342 return_ACPI_STATUS (Status);
343 }
344 goto NextOperand;
345
346
347 case ARGI_DATAREFOBJ: /* Store operator only */
348
349 /*
350 * We don't want to resolve IndexOp reference objects during
351 * a store because this would be an implicit DeRefOf operation.
352 * Instead, we just want to store the reference object.
353 * -- All others must be resolved below.
354 */
355 if ((Opcode == AML_STORE_OP) &&
356 ((*StackPtr)->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) &&
357 ((*StackPtr)->Reference.Class == ACPI_REFCLASS_INDEX))
358 {
359 goto NextOperand;
360 }
361 break;
362
363 default:
364 /* All cases covered above */
365 break;
366 }
367
368 /*
369 * Resolve this object to a value
370 */
371 Status = AcpiExResolveToValue (StackPtr, WalkState);
372 if (ACPI_FAILURE (Status))
373 {
374 return_ACPI_STATUS (Status);
375 }
376
377 /* Get the resolved object */
378
379 ObjDesc = *StackPtr;
380
381 /*
382 * Check the resulting object (value) type
383 */
384 switch (ThisArgType)
385 {
386 /*
387 * For the simple cases, only one type of resolved object
388 * is allowed
389 */
390 case ARGI_MUTEX:
391
392 /* Need an operand of type ACPI_TYPE_MUTEX */
393
394 TypeNeeded = ACPI_TYPE_MUTEX;
395 break;
396
397 case ARGI_EVENT:
398
399 /* Need an operand of type ACPI_TYPE_EVENT */
400
401 TypeNeeded = ACPI_TYPE_EVENT;
402 break;
403
404 case ARGI_PACKAGE: /* Package */
405
406 /* Need an operand of type ACPI_TYPE_PACKAGE */
407
408 TypeNeeded = ACPI_TYPE_PACKAGE;
409 break;
410
411 case ARGI_ANYTYPE:
412
413 /* Any operand type will do */
414
415 TypeNeeded = ACPI_TYPE_ANY;
416 break;
417
418 case ARGI_DDBHANDLE:
419
420 /* Need an operand of type ACPI_TYPE_DDB_HANDLE */
421
422 TypeNeeded = ACPI_TYPE_LOCAL_REFERENCE;
423 break;
424
425
426 /*
427 * The more complex cases allow multiple resolved object types
428 */
429 case ARGI_INTEGER:
430
431 /*
432 * Need an operand of type ACPI_TYPE_INTEGER,
433 * But we can implicitly convert from a STRING or BUFFER
434 * Aka - "Implicit Source Operand Conversion"
435 */
436 Status = AcpiExConvertToInteger (ObjDesc, StackPtr, 16);
437 if (ACPI_FAILURE (Status))
438 {
439 if (Status == AE_TYPE)
440 {
441 ACPI_ERROR ((AE_INFO,
442 "Needed [Integer/String/Buffer], found [%s] %p",
443 AcpiUtGetObjectTypeName (ObjDesc), ObjDesc));
444
445 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
446 }
447
448 return_ACPI_STATUS (Status);
449 }
450
451 if (ObjDesc != *StackPtr)
452 {
453 AcpiUtRemoveReference (ObjDesc);
454 }
455 goto NextOperand;
456
457
458 case ARGI_BUFFER:
459
460 /*
461 * Need an operand of type ACPI_TYPE_BUFFER,
462 * But we can implicitly convert from a STRING or INTEGER
463 * Aka - "Implicit Source Operand Conversion"
464 */
465 Status = AcpiExConvertToBuffer (ObjDesc, StackPtr);
466 if (ACPI_FAILURE (Status))
467 {
468 if (Status == AE_TYPE)
469 {
470 ACPI_ERROR ((AE_INFO,
471 "Needed [Integer/String/Buffer], found [%s] %p",
472 AcpiUtGetObjectTypeName (ObjDesc), ObjDesc));
473
474 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
475 }
476
477 return_ACPI_STATUS (Status);
478 }
479
480 if (ObjDesc != *StackPtr)
481 {
482 AcpiUtRemoveReference (ObjDesc);
483 }
484 goto NextOperand;
485
486
487 case ARGI_STRING:
488
489 /*
490 * Need an operand of type ACPI_TYPE_STRING,
491 * But we can implicitly convert from a BUFFER or INTEGER
492 * Aka - "Implicit Source Operand Conversion"
493 */
494 Status = AcpiExConvertToString (ObjDesc, StackPtr,
495 ACPI_IMPLICIT_CONVERT_HEX);
496 if (ACPI_FAILURE (Status))
497 {
498 if (Status == AE_TYPE)
499 {
500 ACPI_ERROR ((AE_INFO,
501 "Needed [Integer/String/Buffer], found [%s] %p",
502 AcpiUtGetObjectTypeName (ObjDesc), ObjDesc));
503
504 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
505 }
506
507 return_ACPI_STATUS (Status);
508 }
509
510 if (ObjDesc != *StackPtr)
511 {
512 AcpiUtRemoveReference (ObjDesc);
513 }
514 goto NextOperand;
515
516
517 case ARGI_COMPUTEDATA:
518
519 /* Need an operand of type INTEGER, STRING or BUFFER */
520
521 switch (ObjDesc->Common.Type)
522 {
523 case ACPI_TYPE_INTEGER:
524 case ACPI_TYPE_STRING:
525 case ACPI_TYPE_BUFFER:
526
527 /* Valid operand */
528 break;
529
530 default:
531 ACPI_ERROR ((AE_INFO,
532 "Needed [Integer/String/Buffer], found [%s] %p",
533 AcpiUtGetObjectTypeName (ObjDesc), ObjDesc));
534
535 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
536 }
537 goto NextOperand;
538
539
540 case ARGI_BUFFER_OR_STRING:
541
542 /* Need an operand of type STRING or BUFFER */
543
544 switch (ObjDesc->Common.Type)
545 {
546 case ACPI_TYPE_STRING:
547 case ACPI_TYPE_BUFFER:
548
549 /* Valid operand */
550 break;
551
552 case ACPI_TYPE_INTEGER:
553
554 /* Highest priority conversion is to type Buffer */
555
556 Status = AcpiExConvertToBuffer (ObjDesc, StackPtr);
557 if (ACPI_FAILURE (Status))
558 {
559 return_ACPI_STATUS (Status);
560 }
561
562 if (ObjDesc != *StackPtr)
563 {
564 AcpiUtRemoveReference (ObjDesc);
565 }
566 break;
567
568 default:
569 ACPI_ERROR ((AE_INFO,
570 "Needed [Integer/String/Buffer], found [%s] %p",
571 AcpiUtGetObjectTypeName (ObjDesc), ObjDesc));
572
573 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
574 }
575 goto NextOperand;
576
577
578 case ARGI_DATAOBJECT:
579 /*
580 * ARGI_DATAOBJECT is only used by the SizeOf operator.
581 * Need a buffer, string, package, or RefOf reference.
582 *
583 * The only reference allowed here is a direct reference to
584 * a namespace node.
585 */
586 switch (ObjDesc->Common.Type)
587 {
588 case ACPI_TYPE_PACKAGE:
589 case ACPI_TYPE_STRING:
590 case ACPI_TYPE_BUFFER:
591 case ACPI_TYPE_LOCAL_REFERENCE:
592
593 /* Valid operand */
594 break;
595
596 default:
597 ACPI_ERROR ((AE_INFO,
598 "Needed [Buffer/String/Package/Reference], found [%s] %p",
599 AcpiUtGetObjectTypeName (ObjDesc), ObjDesc));
600
601 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
602 }
603 goto NextOperand;
604
605
606 case ARGI_COMPLEXOBJ:
607
608 /* Need a buffer or package or (ACPI 2.0) String */
609
610 switch (ObjDesc->Common.Type)
611 {
612 case ACPI_TYPE_PACKAGE:
613 case ACPI_TYPE_STRING:
614 case ACPI_TYPE_BUFFER:
615
616 /* Valid operand */
617 break;
618
619 default:
620 ACPI_ERROR ((AE_INFO,
621 "Needed [Buffer/String/Package], found [%s] %p",
622 AcpiUtGetObjectTypeName (ObjDesc), ObjDesc));
623
624 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
625 }
626 goto NextOperand;
627
628
629 case ARGI_REGION_OR_BUFFER: /* Used by Load() only */
630
631 /* Need an operand of type REGION or a BUFFER (which could be a resolved region field) */
632
633 switch (ObjDesc->Common.Type)
634 {
635 case ACPI_TYPE_BUFFER:
636 case ACPI_TYPE_REGION:
637
638 /* Valid operand */
639 break;
640
641 default:
642 ACPI_ERROR ((AE_INFO,
643 "Needed [Region/Buffer], found [%s] %p",
644 AcpiUtGetObjectTypeName (ObjDesc), ObjDesc));
645
646 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
647 }
648 goto NextOperand;
649
650
651 case ARGI_DATAREFOBJ:
652
653 /* Used by the Store() operator only */
654
655 switch (ObjDesc->Common.Type)
656 {
657 case ACPI_TYPE_INTEGER:
658 case ACPI_TYPE_PACKAGE:
659 case ACPI_TYPE_STRING:
660 case ACPI_TYPE_BUFFER:
661 case ACPI_TYPE_BUFFER_FIELD:
662 case ACPI_TYPE_LOCAL_REFERENCE:
663 case ACPI_TYPE_LOCAL_REGION_FIELD:
664 case ACPI_TYPE_LOCAL_BANK_FIELD:
665 case ACPI_TYPE_LOCAL_INDEX_FIELD:
666 case ACPI_TYPE_DDB_HANDLE:
667
668 /* Valid operand */
669 break;
670
671 default:
672
673 if (AcpiGbl_EnableInterpreterSlack)
674 {
675 /*
676 * Enable original behavior of Store(), allowing any and all
677 * objects as the source operand. The ACPI spec does not
678 * allow this, however.
679 */
680 break;
681 }
682
683 if (TargetOp == AML_DEBUG_OP)
684 {
685 /* Allow store of any object to the Debug object */
686
687 break;
688 }
689
690 ACPI_ERROR ((AE_INFO,
691 "Needed Integer/Buffer/String/Package/Ref/Ddb], found [%s] %p",
692 AcpiUtGetObjectTypeName (ObjDesc), ObjDesc));
693
694 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
695 }
696 goto NextOperand;
697
698
699 default:
700
701 /* Unknown type */
702
703 ACPI_ERROR ((AE_INFO,
704 "Internal - Unknown ARGI (required operand) type 0x%X",
705 ThisArgType));
706
707 return_ACPI_STATUS (AE_BAD_PARAMETER);
708 }
709
710 /*
711 * Make sure that the original object was resolved to the
712 * required object type (Simple cases only).
713 */
714 Status = AcpiExCheckObjectType (TypeNeeded,
715 (*StackPtr)->Common.Type, *StackPtr);
716 if (ACPI_FAILURE (Status))
717 {
718 return_ACPI_STATUS (Status);
719 }
720
721 NextOperand:
722 /*
723 * If more operands needed, decrement StackPtr to point
724 * to next operand on stack
725 */
726 if (GET_CURRENT_ARG_TYPE (ArgTypes))
727 {
728 StackPtr--;
729 }
730 }
731
732 ACPI_DUMP_OPERANDS (WalkState->Operands,
733 AcpiPsGetOpcodeName (Opcode), WalkState->NumOperands);
734
735 return_ACPI_STATUS (Status);
736 }
737
738
739