Print this page
update to acpica-unix2-20140114
acpica-unix2-20130823
PANKOVs restructure
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/intel/io/acpica/executer/exoparg1.c
+++ new/usr/src/common/acpica/components/executer/exoparg1.c
1 -
2 1 /******************************************************************************
3 2 *
4 3 * Module Name: exoparg1 - AML execution - opcodes with 1 argument
5 4 *
6 5 *****************************************************************************/
7 6
8 7 /*
9 - * Copyright (C) 2000 - 2011, Intel Corp.
8 + * Copyright (C) 2000 - 2014, Intel Corp.
10 9 * All rights reserved.
11 10 *
12 11 * Redistribution and use in source and binary forms, with or without
13 12 * modification, are permitted provided that the following conditions
14 13 * are met:
15 14 * 1. Redistributions of source code must retain the above copyright
16 15 * notice, this list of conditions, and the following disclaimer,
17 16 * without modification.
18 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 18 * substantially similar to the "NO WARRANTY" disclaimer below
20 19 * ("Disclaimer") and any redistribution must be conditioned upon
21 20 * including a substantially similar Disclaimer requirement for further
22 21 * binary redistribution.
23 22 * 3. Neither the names of the above-listed copyright holders nor the names
24 23 * of any contributors may be used to endorse or promote products derived
25 24 * from this software without specific prior written permission.
26 25 *
27 26 * Alternatively, this software may be distributed under the terms of the
28 27 * GNU General Public License ("GPL") version 2 as published by the Free
29 28 * Software Foundation.
30 29 *
31 30 * NO WARRANTY
32 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 41 * POSSIBILITY OF SUCH DAMAGES.
43 42 */
44 43
45 44 #define __EXOPARG1_C__
46 45
47 46 #include "acpi.h"
48 47 #include "accommon.h"
49 48 #include "acparser.h"
50 49 #include "acdispat.h"
51 50 #include "acinterp.h"
52 51 #include "amlcode.h"
53 52 #include "acnamesp.h"
54 53
55 54
56 55 #define _COMPONENT ACPI_EXECUTER
57 56 ACPI_MODULE_NAME ("exoparg1")
58 57
59 58
60 59 /*!
61 60 * Naming convention for AML interpreter execution routines.
62 61 *
63 62 * The routines that begin execution of AML opcodes are named with a common
64 63 * convention based upon the number of arguments, the number of target operands,
65 64 * and whether or not a value is returned:
66 65 *
67 66 * AcpiExOpcode_xA_yT_zR
68 67 *
69 68 * Where:
70 69 *
71 70 * xA - ARGUMENTS: The number of arguments (input operands) that are
72 71 * required for this opcode type (0 through 6 args).
73 72 * yT - TARGETS: The number of targets (output operands) that are required
74 73 * for this opcode type (0, 1, or 2 targets).
75 74 * zR - RETURN VALUE: Indicates whether this opcode type returns a value
76 75 * as the function return (0 or 1).
77 76 *
78 77 * The AcpiExOpcode* functions are called via the Dispatcher component with
79 78 * fully resolved operands.
80 79 !*/
81 80
82 81 /*******************************************************************************
83 82 *
84 83 * FUNCTION: AcpiExOpcode_0A_0T_1R
85 84 *
86 85 * PARAMETERS: WalkState - Current state (contains AML opcode)
87 86 *
88 87 * RETURN: Status
89 88 *
90 89 * DESCRIPTION: Execute operator with no operands, one return value
91 90 *
92 91 ******************************************************************************/
93 92
94 93 ACPI_STATUS
95 94 AcpiExOpcode_0A_0T_1R (
96 95 ACPI_WALK_STATE *WalkState)
97 96 {
98 97 ACPI_STATUS Status = AE_OK;
99 98 ACPI_OPERAND_OBJECT *ReturnDesc = NULL;
100 99
101 100
102 101 ACPI_FUNCTION_TRACE_STR (ExOpcode_0A_0T_1R,
103 102 AcpiPsGetOpcodeName (WalkState->Opcode));
104 103
105 104
106 105 /* Examine the AML opcode */
107 106
108 107 switch (WalkState->Opcode)
109 108 {
110 109 case AML_TIMER_OP: /* Timer () */
111 110
112 111 /* Create a return object of type Integer */
113 112
114 113 ReturnDesc = AcpiUtCreateIntegerObject (AcpiOsGetTimer ());
115 114 if (!ReturnDesc)
116 115 {
117 116 Status = AE_NO_MEMORY;
118 117 goto Cleanup;
119 118 }
120 119 break;
121 120
122 121 default: /* Unknown opcode */
123 122
124 123 ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
125 124 WalkState->Opcode));
126 125 Status = AE_AML_BAD_OPCODE;
127 126 break;
128 127 }
129 128
130 129 Cleanup:
131 130
132 131 /* Delete return object on error */
133 132
134 133 if ((ACPI_FAILURE (Status)) || WalkState->ResultObj)
135 134 {
136 135 AcpiUtRemoveReference (ReturnDesc);
137 136 WalkState->ResultObj = NULL;
138 137 }
139 138 else
140 139 {
141 140 /* Save the return value */
142 141
143 142 WalkState->ResultObj = ReturnDesc;
144 143 }
145 144
146 145 return_ACPI_STATUS (Status);
147 146 }
148 147
149 148
150 149 /*******************************************************************************
151 150 *
152 151 * FUNCTION: AcpiExOpcode_1A_0T_0R
153 152 *
154 153 * PARAMETERS: WalkState - Current state (contains AML opcode)
155 154 *
156 155 * RETURN: Status
157 156 *
158 157 * DESCRIPTION: Execute Type 1 monadic operator with numeric operand on
159 158 * object stack
160 159 *
161 160 ******************************************************************************/
162 161
163 162 ACPI_STATUS
164 163 AcpiExOpcode_1A_0T_0R (
165 164 ACPI_WALK_STATE *WalkState)
166 165 {
167 166 ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0];
168 167 ACPI_STATUS Status = AE_OK;
169 168
170 169
171 170 ACPI_FUNCTION_TRACE_STR (ExOpcode_1A_0T_0R,
172 171 AcpiPsGetOpcodeName (WalkState->Opcode));
173 172
↓ open down ↓ |
154 lines elided |
↑ open up ↑ |
174 173
175 174 /* Examine the AML opcode */
176 175
177 176 switch (WalkState->Opcode)
178 177 {
179 178 case AML_RELEASE_OP: /* Release (MutexObject) */
180 179
181 180 Status = AcpiExReleaseMutex (Operand[0], WalkState);
182 181 break;
183 182
184 -
185 183 case AML_RESET_OP: /* Reset (EventObject) */
186 184
187 185 Status = AcpiExSystemResetEvent (Operand[0]);
188 186 break;
189 187
190 -
191 188 case AML_SIGNAL_OP: /* Signal (EventObject) */
192 189
193 190 Status = AcpiExSystemSignalEvent (Operand[0]);
194 191 break;
195 192
196 -
197 193 case AML_SLEEP_OP: /* Sleep (MsecTime) */
198 194
199 195 Status = AcpiExSystemDoSleep (Operand[0]->Integer.Value);
200 196 break;
201 197
202 -
203 198 case AML_STALL_OP: /* Stall (UsecTime) */
204 199
205 200 Status = AcpiExSystemDoStall ((UINT32) Operand[0]->Integer.Value);
206 201 break;
207 202
208 -
209 203 case AML_UNLOAD_OP: /* Unload (Handle) */
210 204
211 205 Status = AcpiExUnloadTable (Operand[0]);
212 206 break;
213 207
214 -
215 208 default: /* Unknown opcode */
216 209
217 210 ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
218 211 WalkState->Opcode));
219 212 Status = AE_AML_BAD_OPCODE;
220 213 break;
221 214 }
222 215
223 216 return_ACPI_STATUS (Status);
224 217 }
225 218
226 219
227 220 /*******************************************************************************
228 221 *
229 222 * FUNCTION: AcpiExOpcode_1A_1T_0R
230 223 *
231 224 * PARAMETERS: WalkState - Current state (contains AML opcode)
232 225 *
233 226 * RETURN: Status
234 227 *
235 228 * DESCRIPTION: Execute opcode with one argument, one target, and no
236 229 * return value.
237 230 *
238 231 ******************************************************************************/
239 232
240 233 ACPI_STATUS
241 234 AcpiExOpcode_1A_1T_0R (
242 235 ACPI_WALK_STATE *WalkState)
243 236 {
244 237 ACPI_STATUS Status = AE_OK;
245 238 ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0];
246 239
247 240
248 241 ACPI_FUNCTION_TRACE_STR (ExOpcode_1A_1T_0R,
249 242 AcpiPsGetOpcodeName (WalkState->Opcode));
250 243
251 244
252 245 /* Examine the AML opcode */
253 246
254 247 switch (WalkState->Opcode)
255 248 {
256 249 case AML_LOAD_OP:
257 250
258 251 Status = AcpiExLoadOp (Operand[0], Operand[1], WalkState);
259 252 break;
260 253
261 254 default: /* Unknown opcode */
262 255
263 256 ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
264 257 WalkState->Opcode));
265 258 Status = AE_AML_BAD_OPCODE;
266 259 goto Cleanup;
267 260 }
268 261
269 262
270 263 Cleanup:
271 264
272 265 return_ACPI_STATUS (Status);
273 266 }
274 267
275 268
276 269 /*******************************************************************************
277 270 *
278 271 * FUNCTION: AcpiExOpcode_1A_1T_1R
279 272 *
280 273 * PARAMETERS: WalkState - Current state (contains AML opcode)
281 274 *
282 275 * RETURN: Status
283 276 *
284 277 * DESCRIPTION: Execute opcode with one argument, one target, and a
285 278 * return value.
286 279 *
287 280 ******************************************************************************/
288 281
289 282 ACPI_STATUS
290 283 AcpiExOpcode_1A_1T_1R (
291 284 ACPI_WALK_STATE *WalkState)
292 285 {
293 286 ACPI_STATUS Status = AE_OK;
294 287 ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0];
295 288 ACPI_OPERAND_OBJECT *ReturnDesc = NULL;
296 289 ACPI_OPERAND_OBJECT *ReturnDesc2 = NULL;
297 290 UINT32 Temp32;
298 291 UINT32 i;
299 292 UINT64 PowerOfTen;
300 293 UINT64 Digit;
301 294
302 295
303 296 ACPI_FUNCTION_TRACE_STR (ExOpcode_1A_1T_1R,
304 297 AcpiPsGetOpcodeName (WalkState->Opcode));
305 298
306 299
307 300 /* Examine the AML opcode */
308 301
309 302 switch (WalkState->Opcode)
310 303 {
311 304 case AML_BIT_NOT_OP:
312 305 case AML_FIND_SET_LEFT_BIT_OP:
313 306 case AML_FIND_SET_RIGHT_BIT_OP:
314 307 case AML_FROM_BCD_OP:
315 308 case AML_TO_BCD_OP:
316 309 case AML_COND_REF_OF_OP:
317 310
318 311 /* Create a return object of type Integer for these opcodes */
319 312
320 313 ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
321 314 if (!ReturnDesc)
322 315 {
323 316 Status = AE_NO_MEMORY;
↓ open down ↓ |
99 lines elided |
↑ open up ↑ |
324 317 goto Cleanup;
325 318 }
326 319
327 320 switch (WalkState->Opcode)
328 321 {
329 322 case AML_BIT_NOT_OP: /* Not (Operand, Result) */
330 323
331 324 ReturnDesc->Integer.Value = ~Operand[0]->Integer.Value;
332 325 break;
333 326
334 -
335 327 case AML_FIND_SET_LEFT_BIT_OP: /* FindSetLeftBit (Operand, Result) */
336 328
337 329 ReturnDesc->Integer.Value = Operand[0]->Integer.Value;
338 330
339 331 /*
340 332 * Acpi specification describes Integer type as a little
341 333 * endian unsigned value, so this boundary condition is valid.
342 334 */
343 335 for (Temp32 = 0; ReturnDesc->Integer.Value &&
344 336 Temp32 < ACPI_INTEGER_BIT_SIZE; ++Temp32)
345 337 {
346 338 ReturnDesc->Integer.Value >>= 1;
347 339 }
348 340
349 341 ReturnDesc->Integer.Value = Temp32;
350 342 break;
351 343
352 -
353 344 case AML_FIND_SET_RIGHT_BIT_OP: /* FindSetRightBit (Operand, Result) */
354 345
355 346 ReturnDesc->Integer.Value = Operand[0]->Integer.Value;
356 347
357 348 /*
358 349 * The Acpi specification describes Integer type as a little
359 350 * endian unsigned value, so this boundary condition is valid.
360 351 */
361 352 for (Temp32 = 0; ReturnDesc->Integer.Value &&
362 353 Temp32 < ACPI_INTEGER_BIT_SIZE; ++Temp32)
363 354 {
364 355 ReturnDesc->Integer.Value <<= 1;
365 356 }
366 357
367 358 /* Since the bit position is one-based, subtract from 33 (65) */
368 359
369 360 ReturnDesc->Integer.Value =
370 361 Temp32 == 0 ? 0 : (ACPI_INTEGER_BIT_SIZE + 1) - Temp32;
371 362 break;
372 363
373 -
374 364 case AML_FROM_BCD_OP: /* FromBcd (BCDValue, Result) */
375 -
376 365 /*
377 366 * The 64-bit ACPI integer can hold 16 4-bit BCD characters
378 367 * (if table is 32-bit, integer can hold 8 BCD characters)
379 368 * Convert each 4-bit BCD value
380 369 */
381 370 PowerOfTen = 1;
382 371 ReturnDesc->Integer.Value = 0;
383 372 Digit = Operand[0]->Integer.Value;
384 373
385 374 /* Convert each BCD digit (each is one nybble wide) */
386 375
387 376 for (i = 0; (i < AcpiGbl_IntegerNybbleWidth) && (Digit > 0); i++)
388 377 {
389 378 /* Get the least significant 4-bit BCD digit */
390 379
391 380 Temp32 = ((UINT32) Digit) & 0xF;
392 381
393 382 /* Check the range of the digit */
394 383
395 384 if (Temp32 > 9)
396 385 {
397 386 ACPI_ERROR ((AE_INFO,
398 387 "BCD digit too large (not decimal): 0x%X",
399 388 Temp32));
400 389
401 390 Status = AE_AML_NUMERIC_OVERFLOW;
402 391 goto Cleanup;
403 392 }
404 393
405 394 /* Sum the digit into the result with the current power of 10 */
406 395
407 396 ReturnDesc->Integer.Value +=
408 397 (((UINT64) Temp32) * PowerOfTen);
409 398
↓ open down ↓ |
24 lines elided |
↑ open up ↑ |
410 399 /* Shift to next BCD digit */
411 400
412 401 Digit >>= 4;
413 402
414 403 /* Next power of 10 */
415 404
416 405 PowerOfTen *= 10;
417 406 }
418 407 break;
419 408
420 -
421 409 case AML_TO_BCD_OP: /* ToBcd (Operand, Result) */
422 410
423 411 ReturnDesc->Integer.Value = 0;
424 412 Digit = Operand[0]->Integer.Value;
425 413
426 414 /* Each BCD digit is one nybble wide */
427 415
428 416 for (i = 0; (i < AcpiGbl_IntegerNybbleWidth) && (Digit > 0); i++)
429 417 {
430 418 (void) AcpiUtShortDivide (Digit, 10, &Digit, &Temp32);
431 419
432 420 /*
433 421 * Insert the BCD digit that resides in the
434 422 * remainder from above
435 423 */
436 424 ReturnDesc->Integer.Value |=
437 425 (((UINT64) Temp32) << ACPI_MUL_4 (i));
438 426 }
439 427
440 428 /* Overflow if there is any data left in Digit */
441 429
↓ open down ↓ |
11 lines elided |
↑ open up ↑ |
442 430 if (Digit > 0)
443 431 {
444 432 ACPI_ERROR ((AE_INFO,
445 433 "Integer too large to convert to BCD: 0x%8.8X%8.8X",
446 434 ACPI_FORMAT_UINT64 (Operand[0]->Integer.Value)));
447 435 Status = AE_AML_NUMERIC_OVERFLOW;
448 436 goto Cleanup;
449 437 }
450 438 break;
451 439
452 -
453 440 case AML_COND_REF_OF_OP: /* CondRefOf (SourceObject, Result) */
454 -
455 441 /*
456 442 * This op is a little strange because the internal return value is
457 443 * different than the return value stored in the result descriptor
458 444 * (There are really two return values)
459 445 */
460 446 if ((ACPI_NAMESPACE_NODE *) Operand[0] == AcpiGbl_RootNode)
461 447 {
462 448 /*
463 449 * This means that the object does not exist in the namespace,
464 450 * return FALSE
465 451 */
466 452 ReturnDesc->Integer.Value = 0;
467 453 goto Cleanup;
468 454 }
469 455
470 456 /* Get the object reference, store it, and remove our reference */
471 457
472 458 Status = AcpiExGetObjectReference (Operand[0],
473 459 &ReturnDesc2, WalkState);
474 460 if (ACPI_FAILURE (Status))
475 461 {
476 462 goto Cleanup;
477 463 }
478 464
↓ open down ↓ |
14 lines elided |
↑ open up ↑ |
479 465 Status = AcpiExStore (ReturnDesc2, Operand[1], WalkState);
480 466 AcpiUtRemoveReference (ReturnDesc2);
481 467
482 468 /* The object exists in the namespace, return TRUE */
483 469
484 470 ReturnDesc->Integer.Value = ACPI_UINT64_MAX;
485 471 goto Cleanup;
486 472
487 473
488 474 default:
475 +
489 476 /* No other opcodes get here */
477 +
490 478 break;
491 479 }
492 480 break;
493 481
494 -
495 482 case AML_STORE_OP: /* Store (Source, Target) */
496 -
497 483 /*
498 484 * A store operand is typically a number, string, buffer or lvalue
499 485 * Be careful about deleting the source object,
500 486 * since the object itself may have been stored.
501 487 */
502 488 Status = AcpiExStore (Operand[0], Operand[1], WalkState);
503 489 if (ACPI_FAILURE (Status))
504 490 {
505 491 return_ACPI_STATUS (Status);
506 492 }
507 493
508 494 /* It is possible that the Store already produced a return object */
509 495
510 496 if (!WalkState->ResultObj)
511 497 {
512 498 /*
↓ open down ↓ |
6 lines elided |
↑ open up ↑ |
513 499 * Normally, we would remove a reference on the Operand[0]
514 500 * parameter; But since it is being used as the internal return
515 501 * object (meaning we would normally increment it), the two
516 502 * cancel out, and we simply don't do anything.
517 503 */
518 504 WalkState->ResultObj = Operand[0];
519 505 WalkState->Operands[0] = NULL; /* Prevent deletion */
520 506 }
521 507 return_ACPI_STATUS (Status);
522 508
523 -
524 509 /*
525 510 * ACPI 2.0 Opcodes
526 511 */
527 512 case AML_COPY_OP: /* Copy (Source, Target) */
528 513
529 514 Status = AcpiUtCopyIobjectToIobject (Operand[0], &ReturnDesc,
530 515 WalkState);
531 516 break;
532 517
533 -
534 518 case AML_TO_DECSTRING_OP: /* ToDecimalString (Data, Result) */
535 519
536 520 Status = AcpiExConvertToString (Operand[0], &ReturnDesc,
537 521 ACPI_EXPLICIT_CONVERT_DECIMAL);
538 522 if (ReturnDesc == Operand[0])
539 523 {
540 524 /* No conversion performed, add ref to handle return value */
541 525 AcpiUtAddReference (ReturnDesc);
542 526 }
543 527 break;
544 528
545 -
546 529 case AML_TO_HEXSTRING_OP: /* ToHexString (Data, Result) */
547 530
548 531 Status = AcpiExConvertToString (Operand[0], &ReturnDesc,
549 532 ACPI_EXPLICIT_CONVERT_HEX);
550 533 if (ReturnDesc == Operand[0])
551 534 {
552 535 /* No conversion performed, add ref to handle return value */
553 536 AcpiUtAddReference (ReturnDesc);
554 537 }
555 538 break;
556 539
557 -
558 540 case AML_TO_BUFFER_OP: /* ToBuffer (Data, Result) */
559 541
560 542 Status = AcpiExConvertToBuffer (Operand[0], &ReturnDesc);
561 543 if (ReturnDesc == Operand[0])
562 544 {
563 545 /* No conversion performed, add ref to handle return value */
564 546 AcpiUtAddReference (ReturnDesc);
565 547 }
566 548 break;
567 549
568 -
569 550 case AML_TO_INTEGER_OP: /* ToInteger (Data, Result) */
570 551
571 552 Status = AcpiExConvertToInteger (Operand[0], &ReturnDesc,
572 553 ACPI_ANY_BASE);
573 554 if (ReturnDesc == Operand[0])
574 555 {
575 556 /* No conversion performed, add ref to handle return value */
576 557 AcpiUtAddReference (ReturnDesc);
577 558 }
578 559 break;
579 560
580 -
581 561 case AML_SHIFT_LEFT_BIT_OP: /* ShiftLeftBit (Source, BitNum) */
582 562 case AML_SHIFT_RIGHT_BIT_OP: /* ShiftRightBit (Source, BitNum) */
583 563
584 564 /* These are two obsolete opcodes */
585 565
586 566 ACPI_ERROR ((AE_INFO,
587 567 "%s is obsolete and not implemented",
588 568 AcpiPsGetOpcodeName (WalkState->Opcode)));
589 569 Status = AE_SUPPORT;
590 570 goto Cleanup;
591 571
592 -
593 572 default: /* Unknown opcode */
594 573
595 574 ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
596 575 WalkState->Opcode));
597 576 Status = AE_AML_BAD_OPCODE;
598 577 goto Cleanup;
599 578 }
600 579
601 580 if (ACPI_SUCCESS (Status))
602 581 {
603 582 /* Store the return value computed above into the target object */
604 583
605 584 Status = AcpiExStore (ReturnDesc, Operand[1], WalkState);
606 585 }
607 586
608 587
609 588 Cleanup:
610 589
611 590 /* Delete return object on error */
612 591
613 592 if (ACPI_FAILURE (Status))
614 593 {
615 594 AcpiUtRemoveReference (ReturnDesc);
616 595 }
617 596
618 597 /* Save return object on success */
619 598
620 599 else if (!WalkState->ResultObj)
621 600 {
622 601 WalkState->ResultObj = ReturnDesc;
623 602 }
624 603
625 604 return_ACPI_STATUS (Status);
626 605 }
627 606
628 607
629 608 /*******************************************************************************
630 609 *
631 610 * FUNCTION: AcpiExOpcode_1A_0T_1R
632 611 *
633 612 * PARAMETERS: WalkState - Current state (contains AML opcode)
634 613 *
635 614 * RETURN: Status
636 615 *
637 616 * DESCRIPTION: Execute opcode with one argument, no target, and a return value
638 617 *
639 618 ******************************************************************************/
640 619
641 620 ACPI_STATUS
642 621 AcpiExOpcode_1A_0T_1R (
643 622 ACPI_WALK_STATE *WalkState)
644 623 {
645 624 ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0];
646 625 ACPI_OPERAND_OBJECT *TempDesc;
647 626 ACPI_OPERAND_OBJECT *ReturnDesc = NULL;
648 627 ACPI_STATUS Status = AE_OK;
649 628 UINT32 Type;
650 629 UINT64 Value;
651 630
652 631
653 632 ACPI_FUNCTION_TRACE_STR (ExOpcode_1A_0T_1R,
654 633 AcpiPsGetOpcodeName (WalkState->Opcode));
655 634
656 635
657 636 /* Examine the AML opcode */
658 637
659 638 switch (WalkState->Opcode)
660 639 {
↓ open down ↓ |
58 lines elided |
↑ open up ↑ |
661 640 case AML_LNOT_OP: /* LNot (Operand) */
662 641
663 642 ReturnDesc = AcpiUtCreateIntegerObject ((UINT64) 0);
664 643 if (!ReturnDesc)
665 644 {
666 645 Status = AE_NO_MEMORY;
667 646 goto Cleanup;
668 647 }
669 648
670 649 /*
671 - * Set result to ONES (TRUE) if Value == 0. Note:
650 + * Set result to ONES (TRUE) if Value == 0. Note:
672 651 * ReturnDesc->Integer.Value is initially == 0 (FALSE) from above.
673 652 */
674 653 if (!Operand[0]->Integer.Value)
675 654 {
676 655 ReturnDesc->Integer.Value = ACPI_UINT64_MAX;
677 656 }
678 657 break;
679 658
680 -
681 659 case AML_DECREMENT_OP: /* Decrement (Operand) */
682 660 case AML_INCREMENT_OP: /* Increment (Operand) */
683 -
684 661 /*
685 - * Create a new integer. Can't just get the base integer and
662 + * Create a new integer. Can't just get the base integer and
686 663 * increment it because it may be an Arg or Field.
687 664 */
688 665 ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
689 666 if (!ReturnDesc)
690 667 {
691 668 Status = AE_NO_MEMORY;
692 669 goto Cleanup;
693 670 }
694 671
695 672 /*
696 673 * Since we are expecting a Reference operand, it can be either a
697 674 * NS Node or an internal object.
698 675 */
699 676 TempDesc = Operand[0];
700 677 if (ACPI_GET_DESCRIPTOR_TYPE (TempDesc) == ACPI_DESC_TYPE_OPERAND)
701 678 {
702 679 /* Internal reference object - prevent deletion */
703 680
704 681 AcpiUtAddReference (TempDesc);
705 682 }
706 683
707 684 /*
708 685 * Convert the Reference operand to an Integer (This removes a
709 686 * reference on the Operand[0] object)
710 687 *
711 688 * NOTE: We use LNOT_OP here in order to force resolution of the
712 689 * reference operand to an actual integer.
713 690 */
714 691 Status = AcpiExResolveOperands (AML_LNOT_OP, &TempDesc, WalkState);
715 692 if (ACPI_FAILURE (Status))
716 693 {
717 694 ACPI_EXCEPTION ((AE_INFO, Status,
718 695 "While resolving operands for [%s]",
719 696 AcpiPsGetOpcodeName (WalkState->Opcode)));
720 697
721 698 goto Cleanup;
722 699 }
723 700
724 701 /*
725 702 * TempDesc is now guaranteed to be an Integer object --
726 703 * Perform the actual increment or decrement
727 704 */
728 705 if (WalkState->Opcode == AML_INCREMENT_OP)
729 706 {
730 707 ReturnDesc->Integer.Value = TempDesc->Integer.Value +1;
731 708 }
732 709 else
733 710 {
734 711 ReturnDesc->Integer.Value = TempDesc->Integer.Value -1;
735 712 }
736 713
737 714 /* Finished with this Integer object */
↓ open down ↓ |
42 lines elided |
↑ open up ↑ |
738 715
739 716 AcpiUtRemoveReference (TempDesc);
740 717
741 718 /*
742 719 * Store the result back (indirectly) through the original
743 720 * Reference object
744 721 */
745 722 Status = AcpiExStore (ReturnDesc, Operand[0], WalkState);
746 723 break;
747 724
748 -
749 725 case AML_TYPE_OP: /* ObjectType (SourceObject) */
750 -
751 726 /*
752 727 * Note: The operand is not resolved at this point because we want to
753 - * get the associated object, not its value. For example, we don't
728 + * get the associated object, not its value. For example, we don't
754 729 * want to resolve a FieldUnit to its value, we want the actual
755 730 * FieldUnit object.
756 731 */
757 732
758 733 /* Get the type of the base object */
759 734
760 735 Status = AcpiExResolveMultiple (WalkState, Operand[0], &Type, NULL);
761 736 if (ACPI_FAILURE (Status))
762 737 {
763 738 goto Cleanup;
764 739 }
765 740
↓ open down ↓ |
2 lines elided |
↑ open up ↑ |
766 741 /* Allocate a descriptor to hold the type. */
767 742
768 743 ReturnDesc = AcpiUtCreateIntegerObject ((UINT64) Type);
769 744 if (!ReturnDesc)
770 745 {
771 746 Status = AE_NO_MEMORY;
772 747 goto Cleanup;
773 748 }
774 749 break;
775 750
776 -
777 751 case AML_SIZE_OF_OP: /* SizeOf (SourceObject) */
778 -
779 752 /*
780 753 * Note: The operand is not resolved at this point because we want to
781 754 * get the associated object, not its value.
782 755 */
783 756
784 757 /* Get the base object */
785 758
786 759 Status = AcpiExResolveMultiple (WalkState,
787 760 Operand[0], &Type, &TempDesc);
788 761 if (ACPI_FAILURE (Status))
789 762 {
790 763 goto Cleanup;
791 764 }
792 765
793 766 /*
794 767 * The type of the base object must be integer, buffer, string, or
795 - * package. All others are not supported.
768 + * package. All others are not supported.
796 769 *
797 770 * NOTE: Integer is not specifically supported by the ACPI spec,
798 771 * but is supported implicitly via implicit operand conversion.
799 772 * rather than bother with conversion, we just use the byte width
800 773 * global (4 or 8 bytes).
801 774 */
802 775 switch (Type)
803 776 {
804 777 case ACPI_TYPE_INTEGER:
778 +
805 779 Value = AcpiGbl_IntegerByteWidth;
806 780 break;
807 781
808 782 case ACPI_TYPE_STRING:
783 +
809 784 Value = TempDesc->String.Length;
810 785 break;
811 786
812 787 case ACPI_TYPE_BUFFER:
813 788
814 789 /* Buffer arguments may not be evaluated at this point */
815 790
816 791 Status = AcpiDsGetBufferArguments (TempDesc);
817 792 Value = TempDesc->Buffer.Length;
818 793 break;
819 794
820 795 case ACPI_TYPE_PACKAGE:
821 796
822 797 /* Package arguments may not be evaluated at this point */
823 798
824 799 Status = AcpiDsGetPackageArguments (TempDesc);
825 800 Value = TempDesc->Package.Count;
826 801 break;
827 802
828 803 default:
804 +
829 805 ACPI_ERROR ((AE_INFO,
830 806 "Operand must be Buffer/Integer/String/Package - found type %s",
831 807 AcpiUtGetTypeName (Type)));
832 808 Status = AE_AML_OPERAND_TYPE;
833 809 goto Cleanup;
834 810 }
835 811
836 812 if (ACPI_FAILURE (Status))
837 813 {
838 814 goto Cleanup;
839 815 }
840 816
841 817 /*
842 818 * Now that we have the size of the object, create a result
843 819 * object to hold the value
844 820 */
845 821 ReturnDesc = AcpiUtCreateIntegerObject (Value);
846 822 if (!ReturnDesc)
847 823 {
848 824 Status = AE_NO_MEMORY;
849 825 goto Cleanup;
850 826 }
851 827 break;
852 828
853 829
854 830 case AML_REF_OF_OP: /* RefOf (SourceObject) */
855 831
856 832 Status = AcpiExGetObjectReference (Operand[0], &ReturnDesc, WalkState);
857 833 if (ACPI_FAILURE (Status))
858 834 {
859 835 goto Cleanup;
860 836 }
861 837 break;
862 838
863 839
864 840 case AML_DEREF_OF_OP: /* DerefOf (ObjReference | String) */
865 841
866 842 /* Check for a method local or argument, or standalone String */
867 843
868 844 if (ACPI_GET_DESCRIPTOR_TYPE (Operand[0]) == ACPI_DESC_TYPE_NAMED)
869 845 {
870 846 TempDesc = AcpiNsGetAttachedObject (
871 847 (ACPI_NAMESPACE_NODE *) Operand[0]);
872 848 if (TempDesc &&
873 849 ((TempDesc->Common.Type == ACPI_TYPE_STRING) ||
874 850 (TempDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE)))
875 851 {
876 852 Operand[0] = TempDesc;
877 853 AcpiUtAddReference (TempDesc);
878 854 }
879 855 else
880 856 {
881 857 Status = AE_AML_OPERAND_TYPE;
882 858 goto Cleanup;
883 859 }
884 860 }
885 861 else
886 862 {
887 863 switch ((Operand[0])->Common.Type)
888 864 {
889 865 case ACPI_TYPE_LOCAL_REFERENCE:
890 866 /*
891 867 * This is a DerefOf (LocalX | ArgX)
892 868 *
893 869 * Must resolve/dereference the local/arg reference first
894 870 */
895 871 switch (Operand[0]->Reference.Class)
896 872 {
897 873 case ACPI_REFCLASS_LOCAL:
898 874 case ACPI_REFCLASS_ARG:
899 875
900 876 /* Set Operand[0] to the value of the local/arg */
901 877
902 878 Status = AcpiDsMethodDataGetValue (
903 879 Operand[0]->Reference.Class,
904 880 Operand[0]->Reference.Value,
905 881 WalkState, &TempDesc);
906 882 if (ACPI_FAILURE (Status))
907 883 {
908 884 goto Cleanup;
909 885 }
910 886
911 887 /*
912 888 * Delete our reference to the input object and
913 889 * point to the object just retrieved
914 890 */
915 891 AcpiUtRemoveReference (Operand[0]);
916 892 Operand[0] = TempDesc;
917 893 break;
918 894
919 895 case ACPI_REFCLASS_REFOF:
920 896
921 897 /* Get the object to which the reference refers */
922 898
923 899 TempDesc = Operand[0]->Reference.Object;
924 900 AcpiUtRemoveReference (Operand[0]);
925 901 Operand[0] = TempDesc;
↓ open down ↓ |
87 lines elided |
↑ open up ↑ |
926 902 break;
927 903
928 904 default:
929 905
930 906 /* Must be an Index op - handled below */
931 907 break;
932 908 }
933 909 break;
934 910
935 911 case ACPI_TYPE_STRING:
912 +
936 913 break;
937 914
938 915 default:
916 +
939 917 Status = AE_AML_OPERAND_TYPE;
940 918 goto Cleanup;
941 919 }
942 920 }
943 921
944 922 if (ACPI_GET_DESCRIPTOR_TYPE (Operand[0]) != ACPI_DESC_TYPE_NAMED)
945 923 {
946 924 if ((Operand[0])->Common.Type == ACPI_TYPE_STRING)
947 925 {
948 926 /*
949 927 * This is a DerefOf (String). The string is a reference
950 928 * to a named ACPI object.
951 929 *
952 930 * 1) Find the owning Node
953 931 * 2) Dereference the node to an actual object. Could be a
954 932 * Field, so we need to resolve the node to a value.
955 933 */
956 934 Status = AcpiNsGetNode (WalkState->ScopeInfo->Scope.Node,
957 935 Operand[0]->String.Pointer,
958 936 ACPI_NS_SEARCH_PARENT,
959 937 ACPI_CAST_INDIRECT_PTR (
960 938 ACPI_NAMESPACE_NODE, &ReturnDesc));
961 939 if (ACPI_FAILURE (Status))
962 940 {
963 941 goto Cleanup;
964 942 }
965 943
966 944 Status = AcpiExResolveNodeToValue (
967 945 ACPI_CAST_INDIRECT_PTR (
968 946 ACPI_NAMESPACE_NODE, &ReturnDesc),
969 947 WalkState);
970 948 goto Cleanup;
971 949 }
972 950 }
973 951
974 952 /* Operand[0] may have changed from the code above */
975 953
976 954 if (ACPI_GET_DESCRIPTOR_TYPE (Operand[0]) == ACPI_DESC_TYPE_NAMED)
977 955 {
978 956 /*
979 957 * This is a DerefOf (ObjectReference)
980 958 * Get the actual object from the Node (This is the dereference).
981 959 * This case may only happen when a LocalX or ArgX is
982 960 * dereferenced above.
983 961 */
984 962 ReturnDesc = AcpiNsGetAttachedObject (
985 963 (ACPI_NAMESPACE_NODE *) Operand[0]);
986 964 AcpiUtAddReference (ReturnDesc);
↓ open down ↓ |
38 lines elided |
↑ open up ↑ |
987 965 }
988 966 else
989 967 {
990 968 /*
991 969 * This must be a reference object produced by either the
992 970 * Index() or RefOf() operator
993 971 */
994 972 switch (Operand[0]->Reference.Class)
995 973 {
996 974 case ACPI_REFCLASS_INDEX:
997 -
998 975 /*
999 976 * The target type for the Index operator must be
1000 977 * either a Buffer or a Package
1001 978 */
1002 979 switch (Operand[0]->Reference.TargetType)
1003 980 {
1004 981 case ACPI_TYPE_BUFFER_FIELD:
1005 982
1006 983 TempDesc = Operand[0]->Reference.Object;
1007 984
1008 985 /*
1009 986 * Create a new object that contains one element of the
1010 987 * buffer -- the element pointed to by the index.
1011 988 *
1012 989 * NOTE: index into a buffer is NOT a pointer to a
1013 990 * sub-buffer of the main buffer, it is only a pointer to a
1014 991 * single element (byte) of the buffer!
1015 992 *
1016 993 * Since we are returning the value of the buffer at the
1017 994 * indexed location, we don't need to add an additional
1018 995 * reference to the buffer itself.
↓ open down ↓ |
11 lines elided |
↑ open up ↑ |
1019 996 */
1020 997 ReturnDesc = AcpiUtCreateIntegerObject ((UINT64)
1021 998 TempDesc->Buffer.Pointer[Operand[0]->Reference.Value]);
1022 999 if (!ReturnDesc)
1023 1000 {
1024 1001 Status = AE_NO_MEMORY;
1025 1002 goto Cleanup;
1026 1003 }
1027 1004 break;
1028 1005
1029 -
1030 1006 case ACPI_TYPE_PACKAGE:
1031 -
1032 1007 /*
1033 - * Return the referenced element of the package. We must
1008 + * Return the referenced element of the package. We must
1034 1009 * add another reference to the referenced object, however.
1035 1010 */
1036 1011 ReturnDesc = *(Operand[0]->Reference.Where);
1037 - if (ReturnDesc)
1012 + if (!ReturnDesc)
1038 1013 {
1039 - AcpiUtAddReference (ReturnDesc);
1014 + /*
1015 + * Element is NULL, do not allow the dereference.
1016 + * This provides compatibility with other ACPI
1017 + * implementations.
1018 + */
1019 + return_ACPI_STATUS (AE_AML_UNINITIALIZED_ELEMENT);
1040 1020 }
1021 +
1022 + AcpiUtAddReference (ReturnDesc);
1041 1023 break;
1042 1024
1043 -
1044 1025 default:
1045 1026
1046 1027 ACPI_ERROR ((AE_INFO,
1047 1028 "Unknown Index TargetType 0x%X in reference object %p",
1048 1029 Operand[0]->Reference.TargetType, Operand[0]));
1049 1030 Status = AE_AML_OPERAND_TYPE;
1050 1031 goto Cleanup;
1051 1032 }
1052 1033 break;
1053 1034
1054 -
1055 1035 case ACPI_REFCLASS_REFOF:
1056 1036
1057 1037 ReturnDesc = Operand[0]->Reference.Object;
1058 1038
1059 1039 if (ACPI_GET_DESCRIPTOR_TYPE (ReturnDesc) ==
1060 - ACPI_DESC_TYPE_NAMED)
1040 + ACPI_DESC_TYPE_NAMED)
1061 1041 {
1062 1042 ReturnDesc = AcpiNsGetAttachedObject (
1063 - (ACPI_NAMESPACE_NODE *) ReturnDesc);
1064 - }
1043 + (ACPI_NAMESPACE_NODE *) ReturnDesc);
1044 + if (!ReturnDesc)
1045 + {
1046 + break;
1047 + }
1065 1048
1066 - /* Add another reference to the object! */
1049 + /*
1050 + * June 2013:
1051 + * BufferFields/FieldUnits require additional resolution
1052 + */
1053 + switch (ReturnDesc->Common.Type)
1054 + {
1055 + case ACPI_TYPE_BUFFER_FIELD:
1056 + case ACPI_TYPE_LOCAL_REGION_FIELD:
1057 + case ACPI_TYPE_LOCAL_BANK_FIELD:
1058 + case ACPI_TYPE_LOCAL_INDEX_FIELD:
1067 1059
1068 - AcpiUtAddReference (ReturnDesc);
1069 - break;
1060 + Status = AcpiExReadDataFromField (WalkState,
1061 + ReturnDesc, &TempDesc);
1062 + if (ACPI_FAILURE (Status))
1063 + {
1064 + goto Cleanup;
1065 + }
1070 1066
1067 + ReturnDesc = TempDesc;
1068 + break;
1071 1069
1070 + default:
1071 +
1072 + /* Add another reference to the object */
1073 +
1074 + AcpiUtAddReference (ReturnDesc);
1075 + break;
1076 + }
1077 + }
1078 + break;
1079 +
1072 1080 default:
1081 +
1073 1082 ACPI_ERROR ((AE_INFO,
1074 1083 "Unknown class in reference(%p) - 0x%2.2X",
1075 1084 Operand[0], Operand[0]->Reference.Class));
1076 1085
1077 1086 Status = AE_TYPE;
1078 1087 goto Cleanup;
1079 1088 }
1080 1089 }
1081 1090 break;
1082 1091
1083 -
1084 1092 default:
1085 1093
1086 1094 ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X",
1087 1095 WalkState->Opcode));
1088 1096 Status = AE_AML_BAD_OPCODE;
1089 1097 goto Cleanup;
1090 1098 }
1091 1099
1092 1100
1093 1101 Cleanup:
1094 1102
1095 1103 /* Delete return object on error */
1096 1104
1097 1105 if (ACPI_FAILURE (Status))
1098 1106 {
1099 1107 AcpiUtRemoveReference (ReturnDesc);
1100 1108 }
↓ open down ↓ |
7 lines elided |
↑ open up ↑ |
1101 1109
1102 1110 /* Save return object on success */
1103 1111
1104 1112 else
1105 1113 {
1106 1114 WalkState->ResultObj = ReturnDesc;
1107 1115 }
1108 1116
1109 1117 return_ACPI_STATUS (Status);
1110 1118 }
1111 -
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX