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