Warning, cross-references for /kernel/drivers/acpica/psparse.c need to be fixed.
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126 #include "acpi.h"
0127 #include "accommon.h"
0128 #include "acparser.h"
0129 #include "acdispat.h"
0130 #include "amlcode.h"
0131 #include "acnamesp.h"
0132 #include "acinterp.h"
0133
0134 #define _COMPONENT ACPI_PARSER
0135 ACPI_MODULE_NAME ("psparse")
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150 UINT32
0151 AcpiPsGetOpcodeSize (
0152 UINT32 Opcode)
0153 {
0154
0155
0156
0157 if (Opcode > 0x00FF)
0158 {
0159 return (2);
0160 }
0161
0162
0163
0164 return (1);
0165 }
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180 UINT16
0181 AcpiPsPeekOpcode (
0182 ACPI_PARSE_STATE *ParserState)
0183 {
0184 UINT8 *Aml;
0185 UINT16 Opcode;
0186
0187
0188 Aml = ParserState->Aml;
0189 Opcode = (UINT16) ACPI_GET8 (Aml);
0190
0191 if (Opcode == AML_EXTENDED_OP_PREFIX)
0192 {
0193
0194
0195 Aml++;
0196 Opcode = (UINT16) ((Opcode << 8) | ACPI_GET8 (Aml));
0197 }
0198
0199 return (Opcode);
0200 }
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216 ACPI_STATUS
0217 AcpiPsCompleteThisOp (
0218 ACPI_WALK_STATE *WalkState,
0219 ACPI_PARSE_OBJECT *Op)
0220 {
0221 ACPI_PARSE_OBJECT *Prev;
0222 ACPI_PARSE_OBJECT *Next;
0223 const ACPI_OPCODE_INFO *ParentInfo;
0224 ACPI_PARSE_OBJECT *ReplacementOp = NULL;
0225 ACPI_STATUS Status = AE_OK;
0226
0227
0228 ACPI_FUNCTION_TRACE_PTR (PsCompleteThisOp, Op);
0229
0230
0231
0232
0233 if (!Op)
0234 {
0235 return_ACPI_STATUS (AE_OK);
0236 }
0237
0238
0239
0240 if (((WalkState->ParseFlags & ACPI_PARSE_TREE_MASK) != ACPI_PARSE_DELETE_TREE) ||
0241 (WalkState->OpInfo->Class == AML_CLASS_ARGUMENT))
0242 {
0243 return_ACPI_STATUS (AE_OK);
0244 }
0245
0246
0247
0248 if (Op->Common.Parent)
0249 {
0250 Prev = Op->Common.Parent->Common.Value.Arg;
0251 if (!Prev)
0252 {
0253
0254
0255 goto Cleanup;
0256 }
0257
0258
0259
0260
0261
0262 ParentInfo = AcpiPsGetOpcodeInfo (Op->Common.Parent->Common.AmlOpcode);
0263
0264 switch (ParentInfo->Class)
0265 {
0266 case AML_CLASS_CONTROL:
0267 break;
0268
0269 case AML_CLASS_CREATE:
0270
0271
0272
0273
0274
0275 ReplacementOp = AcpiPsAllocOp (AML_INT_RETURN_VALUE_OP);
0276 if (!ReplacementOp)
0277 {
0278 Status = AE_NO_MEMORY;
0279 }
0280 break;
0281
0282 case AML_CLASS_NAMED_OBJECT:
0283
0284
0285
0286
0287
0288 if ((Op->Common.Parent->Common.AmlOpcode == AML_REGION_OP) ||
0289 (Op->Common.Parent->Common.AmlOpcode == AML_DATA_REGION_OP) ||
0290 (Op->Common.Parent->Common.AmlOpcode == AML_BUFFER_OP) ||
0291 (Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||
0292 (Op->Common.Parent->Common.AmlOpcode == AML_BANK_FIELD_OP) ||
0293 (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP))
0294 {
0295 ReplacementOp = AcpiPsAllocOp (AML_INT_RETURN_VALUE_OP);
0296 if (!ReplacementOp)
0297 {
0298 Status = AE_NO_MEMORY;
0299 }
0300 }
0301 else if ((Op->Common.Parent->Common.AmlOpcode == AML_NAME_OP) &&
0302 (WalkState->PassNumber <= ACPI_IMODE_LOAD_PASS2))
0303 {
0304 if ((Op->Common.AmlOpcode == AML_BUFFER_OP) ||
0305 (Op->Common.AmlOpcode == AML_PACKAGE_OP) ||
0306 (Op->Common.AmlOpcode == AML_VAR_PACKAGE_OP))
0307 {
0308 ReplacementOp = AcpiPsAllocOp (Op->Common.AmlOpcode);
0309 if (!ReplacementOp)
0310 {
0311 Status = AE_NO_MEMORY;
0312 }
0313 else
0314 {
0315 ReplacementOp->Named.Data = Op->Named.Data;
0316 ReplacementOp->Named.Length = Op->Named.Length;
0317 }
0318 }
0319 }
0320 break;
0321
0322 default:
0323
0324 ReplacementOp = AcpiPsAllocOp (AML_INT_RETURN_VALUE_OP);
0325 if (!ReplacementOp)
0326 {
0327 Status = AE_NO_MEMORY;
0328 }
0329 }
0330
0331
0332
0333 if (Prev == Op)
0334 {
0335
0336
0337 if (ReplacementOp)
0338 {
0339 ReplacementOp->Common.Parent = Op->Common.Parent;
0340 ReplacementOp->Common.Value.Arg = NULL;
0341 ReplacementOp->Common.Node = Op->Common.Node;
0342 Op->Common.Parent->Common.Value.Arg = ReplacementOp;
0343 ReplacementOp->Common.Next = Op->Common.Next;
0344 }
0345 else
0346 {
0347 Op->Common.Parent->Common.Value.Arg = Op->Common.Next;
0348 }
0349 }
0350
0351
0352
0353 else while (Prev)
0354 {
0355
0356
0357 Next = Prev->Common.Next;
0358 if (Next == Op)
0359 {
0360 if (ReplacementOp)
0361 {
0362 ReplacementOp->Common.Parent = Op->Common.Parent;
0363 ReplacementOp->Common.Value.Arg = NULL;
0364 ReplacementOp->Common.Node = Op->Common.Node;
0365 Prev->Common.Next = ReplacementOp;
0366 ReplacementOp->Common.Next = Op->Common.Next;
0367 Next = NULL;
0368 }
0369 else
0370 {
0371 Prev->Common.Next = Op->Common.Next;
0372 Next = NULL;
0373 }
0374 }
0375 Prev = Next;
0376 }
0377 }
0378
0379
0380 Cleanup:
0381
0382
0383
0384 AcpiPsDeleteParseTree (Op);
0385 return_ACPI_STATUS (Status);
0386 }
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404 ACPI_STATUS
0405 AcpiPsNextParseState (
0406 ACPI_WALK_STATE *WalkState,
0407 ACPI_PARSE_OBJECT *Op,
0408 ACPI_STATUS CallbackStatus)
0409 {
0410 ACPI_PARSE_STATE *ParserState = &WalkState->ParserState;
0411 ACPI_STATUS Status = AE_CTRL_PENDING;
0412
0413
0414 ACPI_FUNCTION_TRACE_PTR (PsNextParseState, Op);
0415
0416
0417 switch (CallbackStatus)
0418 {
0419 case AE_CTRL_TERMINATE:
0420
0421
0422
0423
0424 ParserState->Aml = ParserState->AmlEnd;
0425 Status = AE_CTRL_TERMINATE;
0426 break;
0427
0428
0429 case AE_CTRL_BREAK:
0430
0431 ParserState->Aml = WalkState->AmlLastWhile;
0432 WalkState->ControlState->Common.Value = FALSE;
0433 Status = AE_CTRL_BREAK;
0434 break;
0435
0436
0437 case AE_CTRL_CONTINUE:
0438
0439 ParserState->Aml = WalkState->AmlLastWhile;
0440 Status = AE_CTRL_CONTINUE;
0441 break;
0442
0443
0444 case AE_CTRL_PENDING:
0445
0446 ParserState->Aml = WalkState->AmlLastWhile;
0447 break;
0448
0449 #if 0
0450 case AE_CTRL_SKIP:
0451
0452 ParserState->Aml = ParserState->Scope->ParseScope.PkgEnd;
0453 Status = AE_OK;
0454 break;
0455 #endif
0456
0457 case AE_CTRL_TRUE:
0458
0459
0460
0461
0462 ParserState->Aml = AcpiPsGetNextPackageEnd (ParserState);
0463 Status = AE_CTRL_PENDING;
0464 break;
0465
0466
0467 case AE_CTRL_FALSE:
0468
0469
0470
0471
0472
0473
0474
0475 ParserState->Aml = ParserState->Scope->ParseScope.PkgEnd;
0476
0477
0478
0479 WalkState->ControlState->Common.Value = FALSE;
0480 Status = AE_CTRL_END;
0481 break;
0482
0483
0484 case AE_CTRL_TRANSFER:
0485
0486
0487
0488 Status = AE_CTRL_TRANSFER;
0489 WalkState->PrevOp = Op;
0490 WalkState->MethodCallOp = Op;
0491 WalkState->MethodCallNode = (Op->Common.Value.Arg)->Common.Node;
0492
0493
0494
0495 WalkState->ReturnUsed = AcpiDsIsResultUsed (Op, WalkState);
0496 break;
0497
0498
0499 default:
0500
0501 Status = CallbackStatus;
0502 if ((CallbackStatus & AE_CODE_MASK) == AE_CODE_CONTROL)
0503 {
0504 Status = AE_OK;
0505 }
0506 break;
0507 }
0508
0509 return_ACPI_STATUS (Status);
0510 }
0511
0512
0513
0514
0515
0516
0517
0518
0519
0520
0521
0522
0523
0524
0525
0526 ACPI_STATUS
0527 AcpiPsParseAml (
0528 ACPI_WALK_STATE *WalkState)
0529 {
0530 ACPI_STATUS Status;
0531 ACPI_THREAD_STATE *Thread;
0532 ACPI_THREAD_STATE *PrevWalkList = AcpiGbl_CurrentWalkList;
0533 ACPI_WALK_STATE *PreviousWalkState;
0534
0535
0536 ACPI_FUNCTION_TRACE (PsParseAml);
0537
0538 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
0539 "Entered with WalkState=%p Aml=%p size=%X\n",
0540 WalkState, WalkState->ParserState.Aml,
0541 WalkState->ParserState.AmlSize));
0542
0543 if (!WalkState->ParserState.Aml)
0544 {
0545 return_ACPI_STATUS (AE_NULL_OBJECT);
0546 }
0547
0548
0549
0550 Thread = AcpiUtCreateThreadState ();
0551 if (!Thread)
0552 {
0553 if (WalkState->MethodDesc)
0554 {
0555
0556
0557 AcpiDsTerminateControlMethod (WalkState->MethodDesc, WalkState);
0558 }
0559
0560 AcpiDsDeleteWalkState (WalkState);
0561 return_ACPI_STATUS (AE_NO_MEMORY);
0562 }
0563
0564 WalkState->Thread = Thread;
0565
0566
0567
0568
0569
0570 if (WalkState->MethodDesc)
0571 {
0572 WalkState->Thread->CurrentSyncLevel = WalkState->MethodDesc->Method.SyncLevel;
0573 }
0574
0575 AcpiDsPushWalkState (WalkState, Thread);
0576
0577
0578
0579
0580
0581 AcpiGbl_CurrentWalkList = Thread;
0582
0583
0584
0585
0586
0587 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "State=%p\n", WalkState));
0588
0589 Status = AE_OK;
0590 while (WalkState)
0591 {
0592 if (ACPI_SUCCESS (Status))
0593 {
0594
0595
0596
0597
0598 Status = AcpiPsParseLoop (WalkState);
0599 }
0600
0601 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
0602 "Completed one call to walk loop, %s State=%p\n",
0603 AcpiFormatException (Status), WalkState));
0604
0605 if (Status == AE_CTRL_TRANSFER)
0606 {
0607
0608
0609
0610
0611 Status = AcpiDsCallControlMethod (Thread, WalkState, NULL);
0612 if (ACPI_FAILURE (Status))
0613 {
0614 Status = AcpiDsMethodError (Status, WalkState);
0615 }
0616
0617
0618
0619
0620
0621 WalkState = AcpiDsGetCurrentWalkState (Thread);
0622 continue;
0623 }
0624 else if (Status == AE_CTRL_TERMINATE)
0625 {
0626 Status = AE_OK;
0627 }
0628 else if ((Status != AE_OK) && (WalkState->MethodDesc))
0629 {
0630
0631
0632 ACPI_ERROR_METHOD ("Method parse/execution failed",
0633 WalkState->MethodNode, NULL, Status);
0634
0635
0636
0637 if ((Status == AE_ALREADY_EXISTS) &&
0638 (!WalkState->MethodDesc->Method.Mutex))
0639 {
0640 ACPI_INFO ((AE_INFO,
0641 "Marking method %4.4s as Serialized because of AE_ALREADY_EXISTS error",
0642 WalkState->MethodNode->Name.Ascii));
0643
0644
0645
0646
0647
0648
0649
0650
0651
0652
0653 WalkState->MethodDesc->Method.MethodFlags |= AML_METHOD_SERIALIZED;
0654 WalkState->MethodDesc->Method.SyncLevel = 0;
0655 }
0656 }
0657
0658
0659
0660 WalkState = AcpiDsPopWalkState (Thread);
0661
0662
0663
0664 AcpiDsScopeStackClear (WalkState);
0665
0666
0667
0668
0669
0670
0671 if (((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) == ACPI_PARSE_EXECUTE) ||
0672 (ACPI_FAILURE (Status)))
0673 {
0674 AcpiDsTerminateControlMethod (WalkState->MethodDesc, WalkState);
0675 }
0676
0677
0678
0679 AcpiPsCleanupScope (&WalkState->ParserState);
0680 PreviousWalkState = WalkState;
0681
0682 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
0683 "ReturnValue=%p, ImplicitValue=%p State=%p\n",
0684 WalkState->ReturnDesc, WalkState->ImplicitReturnObj, WalkState));
0685
0686
0687
0688 WalkState = AcpiDsGetCurrentWalkState (Thread);
0689 if (WalkState)
0690 {
0691 if (ACPI_SUCCESS (Status))
0692 {
0693
0694
0695
0696
0697
0698 if (!PreviousWalkState->ReturnDesc)
0699 {
0700
0701
0702
0703
0704 if (AcpiGbl_EnableInterpreterSlack &&
0705 !PreviousWalkState->ImplicitReturnObj)
0706 {
0707 PreviousWalkState->ImplicitReturnObj =
0708 AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER);
0709 if (!PreviousWalkState->ImplicitReturnObj)
0710 {
0711 return_ACPI_STATUS (AE_NO_MEMORY);
0712 }
0713
0714 PreviousWalkState->ImplicitReturnObj->Integer.Value = 0;
0715 }
0716
0717
0718
0719 Status = AcpiDsRestartControlMethod (WalkState,
0720 PreviousWalkState->ImplicitReturnObj);
0721 }
0722 else
0723 {
0724
0725
0726
0727
0728 AcpiDsClearImplicitReturn (PreviousWalkState);
0729
0730 Status = AcpiDsRestartControlMethod (WalkState,
0731 PreviousWalkState->ReturnDesc);
0732 }
0733 if (ACPI_SUCCESS (Status))
0734 {
0735 WalkState->WalkType |= ACPI_WALK_METHOD_RESTART;
0736 }
0737 }
0738 else
0739 {
0740
0741
0742 AcpiUtRemoveReference (PreviousWalkState->ReturnDesc);
0743 AcpiDsClearImplicitReturn (PreviousWalkState);
0744 }
0745 }
0746
0747
0748
0749
0750
0751 else if (PreviousWalkState->CallerReturnDesc)
0752 {
0753 if (PreviousWalkState->ImplicitReturnObj)
0754 {
0755 *(PreviousWalkState->CallerReturnDesc) =
0756 PreviousWalkState->ImplicitReturnObj;
0757 }
0758 else
0759 {
0760
0761
0762 *(PreviousWalkState->CallerReturnDesc) =
0763 PreviousWalkState->ReturnDesc;
0764 }
0765 }
0766 else
0767 {
0768 if (PreviousWalkState->ReturnDesc)
0769 {
0770
0771
0772 AcpiUtRemoveReference (PreviousWalkState->ReturnDesc);
0773 }
0774 if (PreviousWalkState->ImplicitReturnObj)
0775 {
0776
0777
0778 AcpiUtRemoveReference (PreviousWalkState->ImplicitReturnObj);
0779 }
0780 }
0781
0782 AcpiDsDeleteWalkState (PreviousWalkState);
0783 }
0784
0785
0786
0787 AcpiExReleaseAllMutexes (Thread);
0788 AcpiUtDeleteGenericState (ACPI_CAST_PTR (ACPI_GENERIC_STATE, Thread));
0789 AcpiGbl_CurrentWalkList = PrevWalkList;
0790 return_ACPI_STATUS (Status);
0791 }
0792
0793