Print this page
update to acpica-unix2-20140114
update to acpica-unix2-20131218
acpica-unix2-20130823
PANKOVs restructure
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/intel/io/acpica/dispatcher/dsutils.c
+++ new/usr/src/common/acpica/components/dispatcher/dsutils.c
1 1 /*******************************************************************************
2 2 *
3 3 * Module Name: dsutils - Dispatcher utilities
4 4 *
5 5 ******************************************************************************/
6 6
7 7 /*
8 - * Copyright (C) 2000 - 2011, Intel Corp.
8 + * Copyright (C) 2000 - 2014, Intel Corp.
9 9 * All rights reserved.
10 10 *
11 11 * Redistribution and use in source and binary forms, with or without
12 12 * modification, are permitted provided that the following conditions
13 13 * are met:
14 14 * 1. Redistributions of source code must retain the above copyright
15 15 * notice, this list of conditions, and the following disclaimer,
16 16 * without modification.
17 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 18 * substantially similar to the "NO WARRANTY" disclaimer below
19 19 * ("Disclaimer") and any redistribution must be conditioned upon
20 20 * including a substantially similar Disclaimer requirement for further
21 21 * binary redistribution.
22 22 * 3. Neither the names of the above-listed copyright holders nor the names
23 23 * of any contributors may be used to endorse or promote products derived
24 24 * from this software without specific prior written permission.
25 25 *
26 26 * Alternatively, this software may be distributed under the terms of the
27 27 * GNU General Public License ("GPL") version 2 as published by the Free
28 28 * Software Foundation.
29 29 *
30 30 * NO WARRANTY
31 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 41 * POSSIBILITY OF SUCH DAMAGES.
42 42 */
43 43
44 44 #define __DSUTILS_C__
45 45
46 46 #include "acpi.h"
47 47 #include "accommon.h"
48 48 #include "acparser.h"
49 49 #include "amlcode.h"
50 50 #include "acdispat.h"
51 51 #include "acinterp.h"
52 52 #include "acnamesp.h"
53 53 #include "acdebug.h"
54 54
55 55 #define _COMPONENT ACPI_DISPATCHER
56 56 ACPI_MODULE_NAME ("dsutils")
↓ open down ↓ |
38 lines elided |
↑ open up ↑ |
57 57
58 58
59 59 /*******************************************************************************
60 60 *
61 61 * FUNCTION: AcpiDsClearImplicitReturn
62 62 *
63 63 * PARAMETERS: WalkState - Current State
64 64 *
65 65 * RETURN: None.
66 66 *
67 - * DESCRIPTION: Clear and remove a reference on an implicit return value. Used
67 + * DESCRIPTION: Clear and remove a reference on an implicit return value. Used
68 68 * to delete "stale" return values (if enabled, the return value
69 69 * from every operator is saved at least momentarily, in case the
70 70 * parent method exits.)
71 71 *
72 72 ******************************************************************************/
73 73
74 74 void
75 75 AcpiDsClearImplicitReturn (
76 76 ACPI_WALK_STATE *WalkState)
77 77 {
78 78 ACPI_FUNCTION_NAME (DsClearImplicitReturn);
79 79
80 80
81 81 /*
82 82 * Slack must be enabled for this feature
83 83 */
84 84 if (!AcpiGbl_EnableInterpreterSlack)
85 85 {
86 86 return;
87 87 }
88 88
89 89 if (WalkState->ImplicitReturnObj)
90 90 {
91 91 /*
92 92 * Delete any "stale" implicit return. However, in
93 93 * complex statements, the implicit return value can be
94 94 * bubbled up several levels.
95 95 */
96 96 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
97 97 "Removing reference on stale implicit return obj %p\n",
98 98 WalkState->ImplicitReturnObj));
99 99
100 100 AcpiUtRemoveReference (WalkState->ImplicitReturnObj);
101 101 WalkState->ImplicitReturnObj = NULL;
102 102 }
103 103 }
104 104
105 105
106 106 #ifndef ACPI_NO_METHOD_EXECUTION
107 107 /*******************************************************************************
108 108 *
109 109 * FUNCTION: AcpiDsDoImplicitReturn
↓ open down ↓ |
32 lines elided |
↑ open up ↑ |
110 110 *
111 111 * PARAMETERS: ReturnDesc - The return value
112 112 * WalkState - Current State
113 113 * AddReference - True if a reference should be added to the
114 114 * return object
115 115 *
116 116 * RETURN: TRUE if implicit return enabled, FALSE otherwise
117 117 *
118 118 * DESCRIPTION: Implements the optional "implicit return". We save the result
119 119 * of every ASL operator and control method invocation in case the
120 - * parent method exit. Before storing a new return value, we
120 + * parent method exit. Before storing a new return value, we
121 121 * delete the previous return value.
122 122 *
123 123 ******************************************************************************/
124 124
125 125 BOOLEAN
126 126 AcpiDsDoImplicitReturn (
127 127 ACPI_OPERAND_OBJECT *ReturnDesc,
128 128 ACPI_WALK_STATE *WalkState,
129 129 BOOLEAN AddReference)
130 130 {
131 131 ACPI_FUNCTION_NAME (DsDoImplicitReturn);
132 132
133 133
134 134 /*
135 135 * Slack must be enabled for this feature, and we must
136 136 * have a valid return object
137 137 */
138 138 if ((!AcpiGbl_EnableInterpreterSlack) ||
139 139 (!ReturnDesc))
140 140 {
141 141 return (FALSE);
142 142 }
143 143
144 144 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
145 145 "Result %p will be implicitly returned; Prev=%p\n",
146 146 ReturnDesc,
147 147 WalkState->ImplicitReturnObj));
148 148
149 149 /*
150 150 * Delete any "stale" implicit return value first. However, in
151 151 * complex statements, the implicit return value can be
152 152 * bubbled up several levels, so we don't clear the value if it
153 153 * is the same as the ReturnDesc.
154 154 */
155 155 if (WalkState->ImplicitReturnObj)
156 156 {
157 157 if (WalkState->ImplicitReturnObj == ReturnDesc)
158 158 {
159 159 return (TRUE);
160 160 }
161 161 AcpiDsClearImplicitReturn (WalkState);
162 162 }
163 163
164 164 /* Save the implicit return value, add a reference if requested */
165 165
166 166 WalkState->ImplicitReturnObj = ReturnDesc;
167 167 if (AddReference)
168 168 {
169 169 AcpiUtAddReference (ReturnDesc);
170 170 }
171 171
172 172 return (TRUE);
173 173 }
174 174
175 175
176 176 /*******************************************************************************
177 177 *
178 178 * FUNCTION: AcpiDsIsResultUsed
179 179 *
180 180 * PARAMETERS: Op - Current Op
181 181 * WalkState - Current State
182 182 *
183 183 * RETURN: TRUE if result is used, FALSE otherwise
184 184 *
185 185 * DESCRIPTION: Check if a result object will be used by the parent
186 186 *
187 187 ******************************************************************************/
188 188
189 189 BOOLEAN
190 190 AcpiDsIsResultUsed (
191 191 ACPI_PARSE_OBJECT *Op,
192 192 ACPI_WALK_STATE *WalkState)
193 193 {
194 194 const ACPI_OPCODE_INFO *ParentInfo;
195 195
196 196 ACPI_FUNCTION_TRACE_PTR (DsIsResultUsed, Op);
197 197
198 198
199 199 /* Must have both an Op and a Result Object */
200 200
201 201 if (!Op)
202 202 {
203 203 ACPI_ERROR ((AE_INFO, "Null Op"));
204 204 return_UINT8 (TRUE);
205 205 }
206 206
207 207 /*
208 208 * We know that this operator is not a
209 209 * Return() operator (would not come here.) The following code is the
210 210 * optional support for a so-called "implicit return". Some AML code
211 211 * assumes that the last value of the method is "implicitly" returned
212 212 * to the caller. Just save the last result as the return value.
↓ open down ↓ |
82 lines elided |
↑ open up ↑ |
213 213 * NOTE: this is optional because the ASL language does not actually
214 214 * support this behavior.
215 215 */
216 216 (void) AcpiDsDoImplicitReturn (WalkState->ResultObj, WalkState, TRUE);
217 217
218 218 /*
219 219 * Now determine if the parent will use the result
220 220 *
221 221 * If there is no parent, or the parent is a ScopeOp, we are executing
222 222 * at the method level. An executing method typically has no parent,
223 - * since each method is parsed separately. A method invoked externally
223 + * since each method is parsed separately. A method invoked externally
224 224 * via ExecuteControlMethod has a ScopeOp as the parent.
225 225 */
226 226 if ((!Op->Common.Parent) ||
227 227 (Op->Common.Parent->Common.AmlOpcode == AML_SCOPE_OP))
228 228 {
229 229 /* No parent, the return value cannot possibly be used */
230 230
231 231 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
232 232 "At Method level, result of [%s] not used\n",
233 233 AcpiPsGetOpcodeName (Op->Common.AmlOpcode)));
234 234 return_UINT8 (FALSE);
235 235 }
236 236
237 237 /* Get info on the parent. The RootOp is AML_SCOPE */
↓ open down ↓ |
4 lines elided |
↑ open up ↑ |
238 238
239 239 ParentInfo = AcpiPsGetOpcodeInfo (Op->Common.Parent->Common.AmlOpcode);
240 240 if (ParentInfo->Class == AML_CLASS_UNKNOWN)
241 241 {
242 242 ACPI_ERROR ((AE_INFO,
243 243 "Unknown parent opcode Op=%p", Op));
244 244 return_UINT8 (FALSE);
245 245 }
246 246
247 247 /*
248 - * Decide what to do with the result based on the parent. If
248 + * Decide what to do with the result based on the parent. If
249 249 * the parent opcode will not use the result, delete the object.
250 250 * Otherwise leave it as is, it will be deleted when it is used
251 251 * as an operand later.
252 252 */
253 253 switch (ParentInfo->Class)
254 254 {
255 255 case AML_CLASS_CONTROL:
256 256
257 257 switch (Op->Common.Parent->Common.AmlOpcode)
258 258 {
259 259 case AML_RETURN_OP:
260 260
261 261 /* Never delete the return value associated with a return opcode */
262 262
263 263 goto ResultUsed;
264 264
265 265 case AML_IF_OP:
266 266 case AML_WHILE_OP:
267 -
268 267 /*
269 268 * If we are executing the predicate AND this is the predicate op,
270 269 * we will use the return value
271 270 */
272 271 if ((WalkState->ControlState->Common.State == ACPI_CONTROL_PREDICATE_EXECUTING) &&
273 272 (WalkState->ControlState->Control.PredicateOp == Op))
274 273 {
275 274 goto ResultUsed;
276 275 }
277 276 break;
278 277
279 278 default:
279 +
280 280 /* Ignore other control opcodes */
281 +
281 282 break;
282 283 }
283 284
284 285 /* The general control opcode returns no result */
285 286
286 287 goto ResultNotUsed;
287 288
288 -
289 289 case AML_CLASS_CREATE:
290 -
291 290 /*
292 291 * These opcodes allow TermArg(s) as operands and therefore
293 - * the operands can be method calls. The result is used.
292 + * the operands can be method calls. The result is used.
294 293 */
295 294 goto ResultUsed;
296 295
297 -
298 296 case AML_CLASS_NAMED_OBJECT:
299 297
300 298 if ((Op->Common.Parent->Common.AmlOpcode == AML_REGION_OP) ||
301 299 (Op->Common.Parent->Common.AmlOpcode == AML_DATA_REGION_OP) ||
302 300 (Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
303 301 (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP) ||
304 302 (Op->Common.Parent->Common.AmlOpcode == AML_BUFFER_OP) ||
305 303 (Op->Common.Parent->Common.AmlOpcode == AML_INT_EVAL_SUBTREE_OP) ||
306 304 (Op->Common.Parent->Common.AmlOpcode == AML_BANK_FIELD_OP))
307 305 {
308 306 /*
309 307 * These opcodes allow TermArg(s) as operands and therefore
310 - * the operands can be method calls. The result is used.
308 + * the operands can be method calls. The result is used.
311 309 */
312 310 goto ResultUsed;
313 311 }
314 312
315 313 goto ResultNotUsed;
316 314
317 -
318 315 default:
319 -
320 316 /*
321 317 * In all other cases. the parent will actually use the return
322 318 * object, so keep it.
323 319 */
324 320 goto ResultUsed;
325 321 }
326 322
327 323
328 324 ResultUsed:
329 325 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
330 326 "Result of [%s] used by Parent [%s] Op=%p\n",
331 327 AcpiPsGetOpcodeName (Op->Common.AmlOpcode),
332 328 AcpiPsGetOpcodeName (Op->Common.Parent->Common.AmlOpcode), Op));
333 329
334 330 return_UINT8 (TRUE);
335 331
336 332
337 333 ResultNotUsed:
338 334 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
339 335 "Result of [%s] not used by Parent [%s] Op=%p\n",
340 336 AcpiPsGetOpcodeName (Op->Common.AmlOpcode),
341 337 AcpiPsGetOpcodeName (Op->Common.Parent->Common.AmlOpcode), Op));
342 338
343 339 return_UINT8 (FALSE);
344 340 }
345 341
346 342
↓ open down ↓ |
17 lines elided |
↑ open up ↑ |
347 343 /*******************************************************************************
348 344 *
349 345 * FUNCTION: AcpiDsDeleteResultIfNotUsed
350 346 *
351 347 * PARAMETERS: Op - Current parse Op
352 348 * ResultObj - Result of the operation
353 349 * WalkState - Current state
354 350 *
355 351 * RETURN: Status
356 352 *
357 - * DESCRIPTION: Used after interpretation of an opcode. If there is an internal
353 + * DESCRIPTION: Used after interpretation of an opcode. If there is an internal
358 354 * result descriptor, check if the parent opcode will actually use
359 - * this result. If not, delete the result now so that it will
355 + * this result. If not, delete the result now so that it will
360 356 * not become orphaned.
361 357 *
362 358 ******************************************************************************/
363 359
364 360 void
365 361 AcpiDsDeleteResultIfNotUsed (
366 362 ACPI_PARSE_OBJECT *Op,
367 363 ACPI_OPERAND_OBJECT *ResultObj,
368 364 ACPI_WALK_STATE *WalkState)
369 365 {
370 366 ACPI_OPERAND_OBJECT *ObjDesc;
371 367 ACPI_STATUS Status;
372 368
373 369
374 370 ACPI_FUNCTION_TRACE_PTR (DsDeleteResultIfNotUsed, ResultObj);
375 371
376 372
377 373 if (!Op)
378 374 {
379 375 ACPI_ERROR ((AE_INFO, "Null Op"));
380 376 return_VOID;
381 377 }
382 378
383 379 if (!ResultObj)
384 380 {
385 381 return_VOID;
386 382 }
387 383
388 384 if (!AcpiDsIsResultUsed (Op, WalkState))
389 385 {
390 386 /* Must pop the result stack (ObjDesc should be equal to ResultObj) */
391 387
392 388 Status = AcpiDsResultPop (&ObjDesc, WalkState);
393 389 if (ACPI_SUCCESS (Status))
394 390 {
395 391 AcpiUtRemoveReference (ResultObj);
396 392 }
397 393 }
398 394
399 395 return_VOID;
400 396 }
↓ open down ↓ |
31 lines elided |
↑ open up ↑ |
401 397
402 398
403 399 /*******************************************************************************
404 400 *
405 401 * FUNCTION: AcpiDsResolveOperands
406 402 *
407 403 * PARAMETERS: WalkState - Current walk state with operands on stack
408 404 *
409 405 * RETURN: Status
410 406 *
411 - * DESCRIPTION: Resolve all operands to their values. Used to prepare
407 + * DESCRIPTION: Resolve all operands to their values. Used to prepare
412 408 * arguments to a control method invocation (a call from one
413 409 * method to another.)
414 410 *
415 411 ******************************************************************************/
416 412
417 413 ACPI_STATUS
418 414 AcpiDsResolveOperands (
419 415 ACPI_WALK_STATE *WalkState)
420 416 {
421 417 UINT32 i;
422 418 ACPI_STATUS Status = AE_OK;
423 419
424 420
425 421 ACPI_FUNCTION_TRACE_PTR (DsResolveOperands, WalkState);
426 422
427 423
428 424 /*
429 425 * Attempt to resolve each of the valid operands
430 - * Method arguments are passed by reference, not by value. This means
426 + * Method arguments are passed by reference, not by value. This means
431 427 * that the actual objects are passed, not copies of the objects.
432 428 */
433 429 for (i = 0; i < WalkState->NumOperands; i++)
434 430 {
435 431 Status = AcpiExResolveToValue (&WalkState->Operands[i], WalkState);
436 432 if (ACPI_FAILURE (Status))
437 433 {
438 434 break;
439 435 }
440 436 }
441 437
442 438 return_ACPI_STATUS (Status);
443 439 }
444 440
445 441
446 442 /*******************************************************************************
447 443 *
448 444 * FUNCTION: AcpiDsClearOperands
449 445 *
450 446 * PARAMETERS: WalkState - Current walk state with operands on stack
451 447 *
452 448 * RETURN: None
453 449 *
454 450 * DESCRIPTION: Clear all operands on the current walk state operand stack.
455 451 *
456 452 ******************************************************************************/
457 453
458 454 void
459 455 AcpiDsClearOperands (
460 456 ACPI_WALK_STATE *WalkState)
461 457 {
462 458 UINT32 i;
463 459
464 460
465 461 ACPI_FUNCTION_TRACE_PTR (DsClearOperands, WalkState);
466 462
467 463
468 464 /* Remove a reference on each operand on the stack */
469 465
470 466 for (i = 0; i < WalkState->NumOperands; i++)
471 467 {
472 468 /*
473 469 * Remove a reference to all operands, including both
474 470 * "Arguments" and "Targets".
475 471 */
476 472 AcpiUtRemoveReference (WalkState->Operands[i]);
477 473 WalkState->Operands[i] = NULL;
478 474 }
479 475
480 476 WalkState->NumOperands = 0;
481 477 return_VOID;
482 478 }
483 479 #endif
484 480
485 481
486 482 /*******************************************************************************
↓ open down ↓ |
46 lines elided |
↑ open up ↑ |
487 483 *
488 484 * FUNCTION: AcpiDsCreateOperand
489 485 *
490 486 * PARAMETERS: WalkState - Current walk state
491 487 * Arg - Parse object for the argument
492 488 * ArgIndex - Which argument (zero based)
493 489 *
494 490 * RETURN: Status
495 491 *
496 492 * DESCRIPTION: Translate a parse tree object that is an argument to an AML
497 - * opcode to the equivalent interpreter object. This may include
493 + * opcode to the equivalent interpreter object. This may include
498 494 * looking up a name or entering a new name into the internal
499 495 * namespace.
500 496 *
501 497 ******************************************************************************/
502 498
503 499 ACPI_STATUS
504 500 AcpiDsCreateOperand (
505 501 ACPI_WALK_STATE *WalkState,
506 502 ACPI_PARSE_OBJECT *Arg,
507 503 UINT32 ArgIndex)
508 504 {
509 505 ACPI_STATUS Status = AE_OK;
510 506 char *NameString;
511 507 UINT32 NameLength;
512 508 ACPI_OPERAND_OBJECT *ObjDesc;
513 509 ACPI_PARSE_OBJECT *ParentOp;
514 510 UINT16 Opcode;
515 511 ACPI_INTERPRETER_MODE InterpreterMode;
516 512 const ACPI_OPCODE_INFO *OpInfo;
517 513
518 514
519 515 ACPI_FUNCTION_TRACE_PTR (DsCreateOperand, Arg);
520 516
521 517
522 518 /* A valid name must be looked up in the namespace */
523 519
524 520 if ((Arg->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
525 521 (Arg->Common.Value.String) &&
526 522 !(Arg->Common.Flags & ACPI_PARSEOP_IN_STACK))
527 523 {
528 524 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Getting a name: Arg=%p\n", Arg));
529 525
530 526 /* Get the entire name string from the AML stream */
531 527
532 528 Status = AcpiExGetNameString (ACPI_TYPE_ANY, Arg->Common.Value.Buffer,
↓ open down ↓ |
25 lines elided |
↑ open up ↑ |
533 529 &NameString, &NameLength);
534 530
535 531 if (ACPI_FAILURE (Status))
536 532 {
537 533 return_ACPI_STATUS (Status);
538 534 }
539 535
540 536 /* All prefixes have been handled, and the name is in NameString */
541 537
542 538 /*
543 - * Special handling for BufferField declarations. This is a deferred
539 + * Special handling for BufferField declarations. This is a deferred
544 540 * opcode that unfortunately defines the field name as the last
545 - * parameter instead of the first. We get here when we are performing
541 + * parameter instead of the first. We get here when we are performing
546 542 * the deferred execution, so the actual name of the field is already
547 - * in the namespace. We don't want to attempt to look it up again
543 + * in the namespace. We don't want to attempt to look it up again
548 544 * because we may be executing in a different scope than where the
549 545 * actual opcode exists.
550 546 */
551 547 if ((WalkState->DeferredNode) &&
552 548 (WalkState->DeferredNode->Type == ACPI_TYPE_BUFFER_FIELD) &&
553 549 (ArgIndex == (UINT32) ((WalkState->Opcode == AML_CREATE_FIELD_OP) ? 3 : 2)))
554 550 {
555 551 ObjDesc = ACPI_CAST_PTR (
556 552 ACPI_OPERAND_OBJECT, WalkState->DeferredNode);
557 553 Status = AE_OK;
558 554 }
559 555 else /* All other opcodes */
560 556 {
561 557 /*
562 558 * Differentiate between a namespace "create" operation
563 559 * versus a "lookup" operation (IMODE_LOAD_PASS2 vs.
564 560 * IMODE_EXECUTE) in order to support the creation of
565 561 * namespace objects during the execution of control methods.
566 562 */
567 563 ParentOp = Arg->Common.Parent;
568 564 OpInfo = AcpiPsGetOpcodeInfo (ParentOp->Common.AmlOpcode);
569 565 if ((OpInfo->Flags & AML_NSNODE) &&
570 566 (ParentOp->Common.AmlOpcode != AML_INT_METHODCALL_OP) &&
571 567 (ParentOp->Common.AmlOpcode != AML_REGION_OP) &&
572 568 (ParentOp->Common.AmlOpcode != AML_INT_NAMEPATH_OP))
573 569 {
574 570 /* Enter name into namespace if not found */
575 571
576 572 InterpreterMode = ACPI_IMODE_LOAD_PASS2;
577 573 }
578 574 else
579 575 {
580 576 /* Return a failure if name not found */
581 577
582 578 InterpreterMode = ACPI_IMODE_EXECUTE;
583 579 }
584 580
585 581 Status = AcpiNsLookup (WalkState->ScopeInfo, NameString,
586 582 ACPI_TYPE_ANY, InterpreterMode,
587 583 ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
588 584 WalkState,
589 585 ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &ObjDesc));
590 586 /*
591 587 * The only case where we pass through (ignore) a NOT_FOUND
592 588 * error is for the CondRefOf opcode.
593 589 */
594 590 if (Status == AE_NOT_FOUND)
595 591 {
596 592 if (ParentOp->Common.AmlOpcode == AML_COND_REF_OF_OP)
597 593 {
598 594 /*
599 595 * For the Conditional Reference op, it's OK if
600 596 * the name is not found; We just need a way to
601 597 * indicate this to the interpreter, set the
602 598 * object to the root
603 599 */
604 600 ObjDesc = ACPI_CAST_PTR (
605 601 ACPI_OPERAND_OBJECT, AcpiGbl_RootNode);
606 602 Status = AE_OK;
607 603 }
608 604 else
609 605 {
610 606 /*
611 607 * We just plain didn't find it -- which is a
612 608 * very serious error at this point
613 609 */
614 610 Status = AE_AML_NAME_NOT_FOUND;
615 611 }
616 612 }
617 613
618 614 if (ACPI_FAILURE (Status))
619 615 {
620 616 ACPI_ERROR_NAMESPACE (NameString, Status);
621 617 }
622 618 }
623 619
624 620 /* Free the namestring created above */
625 621
626 622 ACPI_FREE (NameString);
627 623
628 624 /* Check status from the lookup */
629 625
630 626 if (ACPI_FAILURE (Status))
631 627 {
632 628 return_ACPI_STATUS (Status);
633 629 }
634 630
635 631 /* Put the resulting object onto the current object stack */
636 632
637 633 Status = AcpiDsObjStackPush (ObjDesc, WalkState);
638 634 if (ACPI_FAILURE (Status))
639 635 {
640 636 return_ACPI_STATUS (Status);
641 637 }
642 638 ACPI_DEBUGGER_EXEC (AcpiDbDisplayArgumentObject (ObjDesc, WalkState));
643 639 }
↓ open down ↓ |
86 lines elided |
↑ open up ↑ |
644 640 else
645 641 {
646 642 /* Check for null name case */
647 643
648 644 if ((Arg->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
649 645 !(Arg->Common.Flags & ACPI_PARSEOP_IN_STACK))
650 646 {
651 647 /*
652 648 * If the name is null, this means that this is an
653 649 * optional result parameter that was not specified
654 - * in the original ASL. Create a Zero Constant for a
655 - * placeholder. (Store to a constant is a Noop.)
650 + * in the original ASL. Create a Zero Constant for a
651 + * placeholder. (Store to a constant is a Noop.)
656 652 */
657 653 Opcode = AML_ZERO_OP; /* Has no arguments! */
658 654
659 655 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
660 656 "Null namepath: Arg=%p\n", Arg));
661 657 }
662 658 else
663 659 {
664 660 Opcode = Arg->Common.AmlOpcode;
665 661 }
666 662
667 663 /* Get the object type of the argument */
668 664
669 665 OpInfo = AcpiPsGetOpcodeInfo (Opcode);
670 666 if (OpInfo->ObjectType == ACPI_TYPE_INVALID)
671 667 {
672 668 return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
673 669 }
674 670
675 671 if ((OpInfo->Flags & AML_HAS_RETVAL) || (Arg->Common.Flags & ACPI_PARSEOP_IN_STACK))
676 672 {
677 673 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
678 674 "Argument previously created, already stacked\n"));
679 675
680 676 ACPI_DEBUGGER_EXEC (AcpiDbDisplayArgumentObject (
681 677 WalkState->Operands [WalkState->NumOperands - 1], WalkState));
682 678
683 679 /*
684 680 * Use value that was already previously returned
685 681 * by the evaluation of this argument
686 682 */
687 683 Status = AcpiDsResultPop (&ObjDesc, WalkState);
688 684 if (ACPI_FAILURE (Status))
689 685 {
690 686 /*
691 687 * Only error is underflow, and this indicates
692 688 * a missing or null operand!
693 689 */
694 690 ACPI_EXCEPTION ((AE_INFO, Status,
695 691 "Missing or null operand"));
696 692 return_ACPI_STATUS (Status);
697 693 }
698 694 }
699 695 else
700 696 {
701 697 /* Create an ACPI_INTERNAL_OBJECT for the argument */
702 698
703 699 ObjDesc = AcpiUtCreateInternalObject (OpInfo->ObjectType);
704 700 if (!ObjDesc)
705 701 {
706 702 return_ACPI_STATUS (AE_NO_MEMORY);
707 703 }
708 704
709 705 /* Initialize the new object */
710 706
711 707 Status = AcpiDsInitObjectFromOp (
712 708 WalkState, Arg, Opcode, &ObjDesc);
713 709 if (ACPI_FAILURE (Status))
714 710 {
715 711 AcpiUtDeleteObjectDesc (ObjDesc);
716 712 return_ACPI_STATUS (Status);
717 713 }
718 714 }
719 715
720 716 /* Put the operand object on the object stack */
721 717
722 718 Status = AcpiDsObjStackPush (ObjDesc, WalkState);
723 719 if (ACPI_FAILURE (Status))
724 720 {
725 721 return_ACPI_STATUS (Status);
726 722 }
727 723
728 724 ACPI_DEBUGGER_EXEC (AcpiDbDisplayArgumentObject (ObjDesc, WalkState));
729 725 }
730 726
731 727 return_ACPI_STATUS (AE_OK);
732 728 }
733 729
734 730
735 731 /*******************************************************************************
736 732 *
737 733 * FUNCTION: AcpiDsCreateOperands
738 734 *
739 735 * PARAMETERS: WalkState - Current state
740 736 * FirstArg - First argument of a parser argument tree
741 737 *
742 738 * RETURN: Status
743 739 *
744 740 * DESCRIPTION: Convert an operator's arguments from a parse tree format to
745 741 * namespace objects and place those argument object on the object
746 742 * stack in preparation for evaluation by the interpreter.
747 743 *
748 744 ******************************************************************************/
749 745
750 746 ACPI_STATUS
751 747 AcpiDsCreateOperands (
752 748 ACPI_WALK_STATE *WalkState,
753 749 ACPI_PARSE_OBJECT *FirstArg)
754 750 {
755 751 ACPI_STATUS Status = AE_OK;
756 752 ACPI_PARSE_OBJECT *Arg;
757 753 ACPI_PARSE_OBJECT *Arguments[ACPI_OBJ_NUM_OPERANDS];
758 754 UINT32 ArgCount = 0;
759 755 UINT32 Index = WalkState->NumOperands;
760 756 UINT32 i;
761 757
762 758
763 759 ACPI_FUNCTION_TRACE_PTR (DsCreateOperands, FirstArg);
764 760
765 761
766 762 /* Get all arguments in the list */
767 763
768 764 Arg = FirstArg;
769 765 while (Arg)
770 766 {
771 767 if (Index >= ACPI_OBJ_NUM_OPERANDS)
772 768 {
773 769 return_ACPI_STATUS (AE_BAD_DATA);
774 770 }
775 771
↓ open down ↓ |
110 lines elided |
↑ open up ↑ |
776 772 Arguments[Index] = Arg;
777 773 WalkState->Operands [Index] = NULL;
778 774
779 775 /* Move on to next argument, if any */
780 776
781 777 Arg = Arg->Common.Next;
782 778 ArgCount++;
783 779 Index++;
784 780 }
785 781
786 - Index--;
782 + ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
783 + "NumOperands %d, ArgCount %d, Index %d\n",
784 + WalkState->NumOperands, ArgCount, Index));
787 785
788 - /* It is the appropriate order to get objects from the Result stack */
786 + /* Create the interpreter arguments, in reverse order */
789 787
788 + Index--;
790 789 for (i = 0; i < ArgCount; i++)
791 790 {
792 791 Arg = Arguments[Index];
793 -
794 - /* Force the filling of the operand stack in inverse order */
795 -
796 792 WalkState->OperandIndex = (UINT8) Index;
797 793
798 794 Status = AcpiDsCreateOperand (WalkState, Arg, Index);
799 795 if (ACPI_FAILURE (Status))
800 796 {
801 797 goto Cleanup;
802 798 }
803 799
800 + ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
801 + "Created Arg #%u (%p) %u args total\n",
802 + Index, Arg, ArgCount));
804 803 Index--;
805 -
806 - ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Arg #%u (%p) done, Arg1=%p\n",
807 - Index, Arg, FirstArg));
808 804 }
809 805
810 806 return_ACPI_STATUS (Status);
811 807
812 808
813 809 Cleanup:
814 810 /*
815 811 * We must undo everything done above; meaning that we must
816 812 * pop everything off of the operand stack and delete those
817 813 * objects
818 814 */
819 815 AcpiDsObjStackPopAndDelete (ArgCount, WalkState);
820 816
821 817 ACPI_EXCEPTION ((AE_INFO, Status, "While creating Arg %u", Index));
822 818 return_ACPI_STATUS (Status);
823 819 }
824 820
825 821
826 822 /*****************************************************************************
827 823 *
828 824 * FUNCTION: AcpiDsEvaluateNamePath
829 825 *
830 826 * PARAMETERS: WalkState - Current state of the parse tree walk,
831 827 * the opcode of current operation should be
832 828 * AML_INT_NAMEPATH_OP
833 829 *
834 830 * RETURN: Status
835 831 *
836 832 * DESCRIPTION: Translate the -NamePath- parse tree object to the equivalent
837 833 * interpreter object, convert it to value, if needed, duplicate
838 834 * it, if needed, and push it onto the current result stack.
839 835 *
840 836 ****************************************************************************/
841 837
842 838 ACPI_STATUS
843 839 AcpiDsEvaluateNamePath (
844 840 ACPI_WALK_STATE *WalkState)
845 841 {
846 842 ACPI_STATUS Status = AE_OK;
847 843 ACPI_PARSE_OBJECT *Op = WalkState->Op;
848 844 ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0];
849 845 ACPI_OPERAND_OBJECT *NewObjDesc;
850 846 UINT8 Type;
851 847
852 848
853 849 ACPI_FUNCTION_TRACE_PTR (DsEvaluateNamePath, WalkState);
854 850
855 851
856 852 if (!Op->Common.Parent)
857 853 {
858 854 /* This happens after certain exception processing */
859 855
860 856 goto Exit;
861 857 }
862 858
863 859 if ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
864 860 (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP) ||
865 861 (Op->Common.Parent->Common.AmlOpcode == AML_REF_OF_OP))
866 862 {
867 863 /* TBD: Should we specify this feature as a bit of OpInfo->Flags of these opcodes? */
868 864
869 865 goto Exit;
870 866 }
871 867
872 868 Status = AcpiDsCreateOperand (WalkState, Op, 0);
873 869 if (ACPI_FAILURE (Status))
874 870 {
875 871 goto Exit;
876 872 }
877 873
878 874 if (Op->Common.Flags & ACPI_PARSEOP_TARGET)
879 875 {
880 876 NewObjDesc = *Operand;
881 877 goto PushResult;
882 878 }
883 879
884 880 Type = (*Operand)->Common.Type;
885 881
886 882 Status = AcpiExResolveToValue (Operand, WalkState);
887 883 if (ACPI_FAILURE (Status))
888 884 {
889 885 goto Exit;
890 886 }
891 887
892 888 if (Type == ACPI_TYPE_INTEGER)
893 889 {
894 890 /* It was incremented by AcpiExResolveToValue */
895 891
896 892 AcpiUtRemoveReference (*Operand);
897 893
898 894 Status = AcpiUtCopyIobjectToIobject (*Operand, &NewObjDesc, WalkState);
899 895 if (ACPI_FAILURE (Status))
900 896 {
901 897 goto Exit;
902 898 }
903 899 }
904 900 else
905 901 {
906 902 /*
907 903 * The object either was anew created or is
908 904 * a Namespace node - don't decrement it.
909 905 */
910 906 NewObjDesc = *Operand;
911 907 }
912 908
913 909 /* Cleanup for name-path operand */
914 910
915 911 Status = AcpiDsObjStackPop (1, WalkState);
916 912 if (ACPI_FAILURE (Status))
917 913 {
918 914 WalkState->ResultObj = NewObjDesc;
919 915 goto Exit;
920 916 }
921 917
922 918 PushResult:
923 919
924 920 WalkState->ResultObj = NewObjDesc;
925 921
926 922 Status = AcpiDsResultPush (WalkState->ResultObj, WalkState);
927 923 if (ACPI_SUCCESS (Status))
928 924 {
929 925 /* Force to take it from stack */
930 926
931 927 Op->Common.Flags |= ACPI_PARSEOP_IN_STACK;
932 928 }
933 929
934 930 Exit:
935 931
936 932 return_ACPI_STATUS (Status);
937 933 }
↓ open down ↓ |
120 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX