1 /******************************************************************************
2 *
3 * Module Name: psparse - Parser top level AML parse routines
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2011, 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.
174
175 if (Op->Common.Parent)
176 {
177 Prev = Op->Common.Parent->Common.Value.Arg;
178 if (!Prev)
179 {
180 /* Nothing more to do */
181
182 goto Cleanup;
183 }
184
185 /*
186 * Check if we need to replace the operator and its subtree
187 * with a return value op (placeholder op)
188 */
189 ParentInfo = AcpiPsGetOpcodeInfo (Op->Common.Parent->Common.AmlOpcode);
190
191 switch (ParentInfo->Class)
192 {
193 case AML_CLASS_CONTROL:
194 break;
195
196 case AML_CLASS_CREATE:
197
198 /*
199 * These opcodes contain TermArg operands. The current
200 * op must be replaced by a placeholder return op
201 */
202 ReplacementOp = AcpiPsAllocOp (AML_INT_RETURN_VALUE_OP);
203 if (!ReplacementOp)
204 {
205 Status = AE_NO_MEMORY;
206 }
207 break;
208
209 case AML_CLASS_NAMED_OBJECT:
210
211 /*
212 * These opcodes contain TermArg operands. The current
213 * op must be replaced by a placeholder return op
214 */
215 if ((Op->Common.Parent->Common.AmlOpcode == AML_REGION_OP) ||
216 (Op->Common.Parent->Common.AmlOpcode == AML_DATA_REGION_OP) ||
217 (Op->Common.Parent->Common.AmlOpcode == AML_BUFFER_OP) ||
218 (Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
219 (Op->Common.Parent->Common.AmlOpcode == AML_BANK_FIELD_OP) ||
220 (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP))
221 {
222 ReplacementOp = AcpiPsAllocOp (AML_INT_RETURN_VALUE_OP);
223 if (!ReplacementOp)
224 {
225 Status = AE_NO_MEMORY;
226 }
227 }
228 else if ((Op->Common.Parent->Common.AmlOpcode == AML_NAME_OP) &&
229 (WalkState->PassNumber <= ACPI_IMODE_LOAD_PASS2))
230 {
335 ACPI_STATUS CallbackStatus)
336 {
337 ACPI_PARSE_STATE *ParserState = &WalkState->ParserState;
338 ACPI_STATUS Status = AE_CTRL_PENDING;
339
340
341 ACPI_FUNCTION_TRACE_PTR (PsNextParseState, Op);
342
343
344 switch (CallbackStatus)
345 {
346 case AE_CTRL_TERMINATE:
347 /*
348 * A control method was terminated via a RETURN statement.
349 * The walk of this method is complete.
350 */
351 ParserState->Aml = ParserState->AmlEnd;
352 Status = AE_CTRL_TERMINATE;
353 break;
354
355
356 case AE_CTRL_BREAK:
357
358 ParserState->Aml = WalkState->AmlLastWhile;
359 WalkState->ControlState->Common.Value = FALSE;
360 Status = AE_CTRL_BREAK;
361 break;
362
363
364 case AE_CTRL_CONTINUE:
365
366 ParserState->Aml = WalkState->AmlLastWhile;
367 Status = AE_CTRL_CONTINUE;
368 break;
369
370
371 case AE_CTRL_PENDING:
372
373 ParserState->Aml = WalkState->AmlLastWhile;
374 break;
375
376 #if 0
377 case AE_CTRL_SKIP:
378
379 ParserState->Aml = ParserState->Scope->ParseScope.PkgEnd;
380 Status = AE_OK;
381 break;
382 #endif
383
384 case AE_CTRL_TRUE:
385 /*
386 * Predicate of an IF was true, and we are at the matching ELSE.
387 * Just close out this package
388 */
389 ParserState->Aml = AcpiPsGetNextPackageEnd (ParserState);
390 Status = AE_CTRL_PENDING;
391 break;
392
393
394 case AE_CTRL_FALSE:
395 /*
396 * Either an IF/WHILE Predicate was false or we encountered a BREAK
397 * opcode. In both cases, we do not execute the rest of the
398 * package; We simply close out the parent (finishing the walk of
399 * this branch of the tree) and continue execution at the parent
400 * level.
401 */
402 ParserState->Aml = ParserState->Scope->ParseScope.PkgEnd;
403
404 /* In the case of a BREAK, just force a predicate (if any) to FALSE */
405
406 WalkState->ControlState->Common.Value = FALSE;
407 Status = AE_CTRL_END;
408 break;
409
410
411 case AE_CTRL_TRANSFER:
412
413 /* A method call (invocation) -- transfer control */
414
415 Status = AE_CTRL_TRANSFER;
416 WalkState->PrevOp = Op;
417 WalkState->MethodCallOp = Op;
418 WalkState->MethodCallNode = (Op->Common.Value.Arg)->Common.Node;
419
420 /* Will return value (if any) be used by the caller? */
421
422 WalkState->ReturnUsed = AcpiDsIsResultUsed (Op, WalkState);
423 break;
424
425
426 default:
427
428 Status = CallbackStatus;
429 if ((CallbackStatus & AE_CODE_MASK) == AE_CODE_CONTROL)
430 {
431 Status = AE_OK;
432 }
433 break;
434 }
435
436 return_ACPI_STATUS (Status);
437 }
438
439
440 /*******************************************************************************
441 *
442 * FUNCTION: AcpiPsParseAml
443 *
444 * PARAMETERS: WalkState - Current state
445 *
690 AcpiUtRemoveReference (PreviousWalkState->ReturnDesc);
691 }
692 if (PreviousWalkState->ImplicitReturnObj)
693 {
694 /* Caller doesn't want it, must delete it */
695
696 AcpiUtRemoveReference (PreviousWalkState->ImplicitReturnObj);
697 }
698 }
699
700 AcpiDsDeleteWalkState (PreviousWalkState);
701 }
702
703 /* Normal exit */
704
705 AcpiExReleaseAllMutexes (Thread);
706 AcpiUtDeleteGenericState (ACPI_CAST_PTR (ACPI_GENERIC_STATE, Thread));
707 AcpiGbl_CurrentWalkList = PrevWalkList;
708 return_ACPI_STATUS (Status);
709 }
710
711
|
1 /******************************************************************************
2 *
3 * Module Name: psparse - Parser top level AML parse routines
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2014, 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.
174
175 if (Op->Common.Parent)
176 {
177 Prev = Op->Common.Parent->Common.Value.Arg;
178 if (!Prev)
179 {
180 /* Nothing more to do */
181
182 goto Cleanup;
183 }
184
185 /*
186 * Check if we need to replace the operator and its subtree
187 * with a return value op (placeholder op)
188 */
189 ParentInfo = AcpiPsGetOpcodeInfo (Op->Common.Parent->Common.AmlOpcode);
190
191 switch (ParentInfo->Class)
192 {
193 case AML_CLASS_CONTROL:
194
195 break;
196
197 case AML_CLASS_CREATE:
198 /*
199 * These opcodes contain TermArg operands. The current
200 * op must be replaced by a placeholder return op
201 */
202 ReplacementOp = AcpiPsAllocOp (AML_INT_RETURN_VALUE_OP);
203 if (!ReplacementOp)
204 {
205 Status = AE_NO_MEMORY;
206 }
207 break;
208
209 case AML_CLASS_NAMED_OBJECT:
210 /*
211 * These opcodes contain TermArg operands. The current
212 * op must be replaced by a placeholder return op
213 */
214 if ((Op->Common.Parent->Common.AmlOpcode == AML_REGION_OP) ||
215 (Op->Common.Parent->Common.AmlOpcode == AML_DATA_REGION_OP) ||
216 (Op->Common.Parent->Common.AmlOpcode == AML_BUFFER_OP) ||
217 (Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
218 (Op->Common.Parent->Common.AmlOpcode == AML_BANK_FIELD_OP) ||
219 (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP))
220 {
221 ReplacementOp = AcpiPsAllocOp (AML_INT_RETURN_VALUE_OP);
222 if (!ReplacementOp)
223 {
224 Status = AE_NO_MEMORY;
225 }
226 }
227 else if ((Op->Common.Parent->Common.AmlOpcode == AML_NAME_OP) &&
228 (WalkState->PassNumber <= ACPI_IMODE_LOAD_PASS2))
229 {
334 ACPI_STATUS CallbackStatus)
335 {
336 ACPI_PARSE_STATE *ParserState = &WalkState->ParserState;
337 ACPI_STATUS Status = AE_CTRL_PENDING;
338
339
340 ACPI_FUNCTION_TRACE_PTR (PsNextParseState, Op);
341
342
343 switch (CallbackStatus)
344 {
345 case AE_CTRL_TERMINATE:
346 /*
347 * A control method was terminated via a RETURN statement.
348 * The walk of this method is complete.
349 */
350 ParserState->Aml = ParserState->AmlEnd;
351 Status = AE_CTRL_TERMINATE;
352 break;
353
354 case AE_CTRL_BREAK:
355
356 ParserState->Aml = WalkState->AmlLastWhile;
357 WalkState->ControlState->Common.Value = FALSE;
358 Status = AE_CTRL_BREAK;
359 break;
360
361 case AE_CTRL_CONTINUE:
362
363 ParserState->Aml = WalkState->AmlLastWhile;
364 Status = AE_CTRL_CONTINUE;
365 break;
366
367 case AE_CTRL_PENDING:
368
369 ParserState->Aml = WalkState->AmlLastWhile;
370 break;
371
372 #if 0
373 case AE_CTRL_SKIP:
374
375 ParserState->Aml = ParserState->Scope->ParseScope.PkgEnd;
376 Status = AE_OK;
377 break;
378 #endif
379
380 case AE_CTRL_TRUE:
381 /*
382 * Predicate of an IF was true, and we are at the matching ELSE.
383 * Just close out this package
384 */
385 ParserState->Aml = AcpiPsGetNextPackageEnd (ParserState);
386 Status = AE_CTRL_PENDING;
387 break;
388
389 case AE_CTRL_FALSE:
390 /*
391 * Either an IF/WHILE Predicate was false or we encountered a BREAK
392 * opcode. In both cases, we do not execute the rest of the
393 * package; We simply close out the parent (finishing the walk of
394 * this branch of the tree) and continue execution at the parent
395 * level.
396 */
397 ParserState->Aml = ParserState->Scope->ParseScope.PkgEnd;
398
399 /* In the case of a BREAK, just force a predicate (if any) to FALSE */
400
401 WalkState->ControlState->Common.Value = FALSE;
402 Status = AE_CTRL_END;
403 break;
404
405 case AE_CTRL_TRANSFER:
406
407 /* A method call (invocation) -- transfer control */
408
409 Status = AE_CTRL_TRANSFER;
410 WalkState->PrevOp = Op;
411 WalkState->MethodCallOp = Op;
412 WalkState->MethodCallNode = (Op->Common.Value.Arg)->Common.Node;
413
414 /* Will return value (if any) be used by the caller? */
415
416 WalkState->ReturnUsed = AcpiDsIsResultUsed (Op, WalkState);
417 break;
418
419 default:
420
421 Status = CallbackStatus;
422 if ((CallbackStatus & AE_CODE_MASK) == AE_CODE_CONTROL)
423 {
424 Status = AE_OK;
425 }
426 break;
427 }
428
429 return_ACPI_STATUS (Status);
430 }
431
432
433 /*******************************************************************************
434 *
435 * FUNCTION: AcpiPsParseAml
436 *
437 * PARAMETERS: WalkState - Current state
438 *
683 AcpiUtRemoveReference (PreviousWalkState->ReturnDesc);
684 }
685 if (PreviousWalkState->ImplicitReturnObj)
686 {
687 /* Caller doesn't want it, must delete it */
688
689 AcpiUtRemoveReference (PreviousWalkState->ImplicitReturnObj);
690 }
691 }
692
693 AcpiDsDeleteWalkState (PreviousWalkState);
694 }
695
696 /* Normal exit */
697
698 AcpiExReleaseAllMutexes (Thread);
699 AcpiUtDeleteGenericState (ACPI_CAST_PTR (ACPI_GENERIC_STATE, Thread));
700 AcpiGbl_CurrentWalkList = PrevWalkList;
701 return_ACPI_STATUS (Status);
702 }
|