Rev 1498 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1498 | Rev 2216 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | /****************************************************************************** |
1 | /****************************************************************************** |
2 | * |
2 | * |
3 | * Module Name: dsopcode - Dispatcher Op Region support and handling of |
3 | * Module Name: dsopcode - Dispatcher suport for regions and fields |
4 | * "control" opcodes |
- | |
5 | * |
4 | * |
6 | *****************************************************************************/ |
5 | *****************************************************************************/ |
Line 7... | Line 6... | ||
7 | 6 | ||
8 | /****************************************************************************** |
7 | /****************************************************************************** |
9 | * |
8 | * |
10 | * 1. Copyright Notice |
9 | * 1. Copyright Notice |
11 | * |
10 | * |
12 | * Some or all of this work - Copyright (c) 1999 - 2010, Intel Corp. |
11 | * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp. |
13 | * All rights reserved. |
12 | * All rights reserved. |
14 | * |
13 | * |
15 | * 2. License |
14 | * 2. License |
16 | * |
15 | * |
Line 130... | Line 129... | ||
130 | ACPI_MODULE_NAME ("dsopcode") |
129 | ACPI_MODULE_NAME ("dsopcode") |
Line 131... | Line 130... | ||
131 | 130 | ||
Line 132... | Line 131... | ||
132 | /* Local prototypes */ |
131 | /* Local prototypes */ |
133 | - | ||
134 | static ACPI_STATUS |
- | |
135 | AcpiDsExecuteArguments ( |
- | |
136 | ACPI_NAMESPACE_NODE *Node, |
- | |
137 | ACPI_NAMESPACE_NODE *ScopeNode, |
- | |
138 | UINT32 AmlLength, |
- | |
139 | UINT8 *AmlStart); |
- | |
140 | 132 | ||
141 | static ACPI_STATUS |
133 | static ACPI_STATUS |
142 | AcpiDsInitBufferField ( |
134 | AcpiDsInitBufferField ( |
143 | UINT16 AmlOpcode, |
135 | UINT16 AmlOpcode, |
144 | ACPI_OPERAND_OBJECT *ObjDesc, |
136 | ACPI_OPERAND_OBJECT *ObjDesc, |
Line 148... | Line 140... | ||
148 | ACPI_OPERAND_OBJECT *ResultDesc); |
140 | ACPI_OPERAND_OBJECT *ResultDesc); |
Line 149... | Line 141... | ||
149 | 141 | ||
150 | 142 | ||
151 | /******************************************************************************* |
- | |
152 | * |
- | |
153 | * FUNCTION: AcpiDsExecuteArguments |
- | |
154 | * |
- | |
155 | * PARAMETERS: Node - Object NS node |
- | |
156 | * ScopeNode - Parent NS node |
- | |
157 | * AmlLength - Length of executable AML |
- | |
158 | * AmlStart - Pointer to the AML |
- | |
159 | * |
- | |
160 | * RETURN: Status. |
- | |
161 | * |
- | |
162 | * DESCRIPTION: Late (deferred) execution of region or field arguments |
- | |
163 | * |
- | |
164 | ******************************************************************************/ |
- | |
165 | - | ||
166 | static ACPI_STATUS |
- | |
167 | AcpiDsExecuteArguments ( |
- | |
168 | ACPI_NAMESPACE_NODE *Node, |
- | |
169 | ACPI_NAMESPACE_NODE *ScopeNode, |
- | |
170 | UINT32 AmlLength, |
- | |
171 | UINT8 *AmlStart) |
- | |
172 | { |
- | |
173 | ACPI_STATUS Status; |
- | |
174 | ACPI_PARSE_OBJECT *Op; |
- | |
175 | ACPI_WALK_STATE *WalkState; |
- | |
176 | - | ||
177 | - | ||
178 | ACPI_FUNCTION_TRACE (DsExecuteArguments); |
- | |
179 | - | ||
180 | - | ||
181 | /* |
- | |
182 | * Allocate a new parser op to be the root of the parsed tree |
- | |
183 | */ |
- | |
184 | Op = AcpiPsAllocOp (AML_INT_EVAL_SUBTREE_OP); |
- | |
185 | if (!Op) |
- | |
186 | { |
- | |
187 | return_ACPI_STATUS (AE_NO_MEMORY); |
- | |
188 | } |
- | |
189 | - | ||
190 | /* Save the Node for use in AcpiPsParseAml */ |
- | |
191 | - | ||
192 | Op->Common.Node = ScopeNode; |
- | |
193 | - | ||
194 | /* Create and initialize a new parser state */ |
- | |
195 | - | ||
196 | WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL); |
- | |
197 | if (!WalkState) |
- | |
198 | { |
- | |
199 | Status = AE_NO_MEMORY; |
- | |
200 | goto Cleanup; |
- | |
201 | } |
- | |
202 | - | ||
203 | Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, AmlStart, |
- | |
204 | AmlLength, NULL, ACPI_IMODE_LOAD_PASS1); |
- | |
205 | if (ACPI_FAILURE (Status)) |
- | |
206 | { |
- | |
207 | AcpiDsDeleteWalkState (WalkState); |
- | |
208 | goto Cleanup; |
- | |
209 | } |
- | |
210 | - | ||
211 | /* Mark this parse as a deferred opcode */ |
- | |
212 | - | ||
213 | WalkState->ParseFlags = ACPI_PARSE_DEFERRED_OP; |
- | |
214 | WalkState->DeferredNode = Node; |
- | |
215 | - | ||
216 | /* Pass1: Parse the entire declaration */ |
- | |
217 | - | ||
218 | Status = AcpiPsParseAml (WalkState); |
- | |
219 | if (ACPI_FAILURE (Status)) |
- | |
220 | { |
- | |
221 | goto Cleanup; |
- | |
222 | } |
- | |
223 | - | ||
224 | /* Get and init the Op created above */ |
- | |
225 | - | ||
226 | Op->Common.Node = Node; |
- | |
227 | AcpiPsDeleteParseTree (Op); |
- | |
228 | - | ||
229 | /* Evaluate the deferred arguments */ |
- | |
230 | - | ||
231 | Op = AcpiPsAllocOp (AML_INT_EVAL_SUBTREE_OP); |
- | |
232 | if (!Op) |
- | |
233 | { |
- | |
234 | return_ACPI_STATUS (AE_NO_MEMORY); |
- | |
235 | } |
- | |
236 | - | ||
237 | Op->Common.Node = ScopeNode; |
- | |
238 | - | ||
239 | /* Create and initialize a new parser state */ |
- | |
240 | - | ||
241 | WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL); |
- | |
242 | if (!WalkState) |
- | |
243 | { |
- | |
244 | Status = AE_NO_MEMORY; |
- | |
245 | goto Cleanup; |
- | |
246 | } |
- | |
247 | - | ||
248 | /* Execute the opcode and arguments */ |
- | |
249 | - | ||
250 | Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, AmlStart, |
- | |
251 | AmlLength, NULL, ACPI_IMODE_EXECUTE); |
- | |
252 | if (ACPI_FAILURE (Status)) |
- | |
253 | { |
- | |
254 | AcpiDsDeleteWalkState (WalkState); |
- | |
255 | goto Cleanup; |
- | |
256 | } |
- | |
257 | - | ||
258 | /* Mark this execution as a deferred opcode */ |
- | |
259 | - | ||
260 | WalkState->DeferredNode = Node; |
- | |
261 | Status = AcpiPsParseAml (WalkState); |
- | |
262 | - | ||
263 | Cleanup: |
- | |
264 | AcpiPsDeleteParseTree (Op); |
- | |
265 | return_ACPI_STATUS (Status); |
- | |
266 | } |
- | |
267 | - | ||
268 | - | ||
269 | /******************************************************************************* |
- | |
270 | * |
- | |
271 | * FUNCTION: AcpiDsGetBufferFieldArguments |
- | |
272 | * |
- | |
273 | * PARAMETERS: ObjDesc - A valid BufferField object |
- | |
274 | * |
- | |
275 | * RETURN: Status. |
- | |
276 | * |
- | |
277 | * DESCRIPTION: Get BufferField Buffer and Index. This implements the late |
- | |
278 | * evaluation of these field attributes. |
- | |
279 | * |
- | |
280 | ******************************************************************************/ |
- | |
281 | - | ||
282 | ACPI_STATUS |
- | |
283 | AcpiDsGetBufferFieldArguments ( |
- | |
284 | ACPI_OPERAND_OBJECT *ObjDesc) |
- | |
285 | { |
- | |
286 | ACPI_OPERAND_OBJECT *ExtraDesc; |
- | |
287 | ACPI_NAMESPACE_NODE *Node; |
- | |
288 | ACPI_STATUS Status; |
- | |
289 | - | ||
290 | - | ||
291 | ACPI_FUNCTION_TRACE_PTR (DsGetBufferFieldArguments, ObjDesc); |
- | |
292 | - | ||
293 | - | ||
294 | if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID) |
- | |
295 | { |
- | |
296 | return_ACPI_STATUS (AE_OK); |
- | |
297 | } |
- | |
298 | - | ||
299 | /* Get the AML pointer (method object) and BufferField node */ |
- | |
300 | - | ||
301 | ExtraDesc = AcpiNsGetSecondaryObject (ObjDesc); |
- | |
302 | Node = ObjDesc->BufferField.Node; |
- | |
303 | - | ||
304 | ACPI_DEBUG_EXEC(AcpiUtDisplayInitPathname (ACPI_TYPE_BUFFER_FIELD, Node, NULL)); |
- | |
305 | ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] BufferField Arg Init\n", |
- | |
306 | AcpiUtGetNodeName (Node))); |
- | |
307 | - | ||
308 | /* Execute the AML code for the TermArg arguments */ |
- | |
309 | - | ||
310 | Status = AcpiDsExecuteArguments (Node, Node->Parent, |
- | |
311 | ExtraDesc->Extra.AmlLength, ExtraDesc->Extra.AmlStart); |
- | |
312 | return_ACPI_STATUS (Status); |
- | |
313 | } |
- | |
314 | - | ||
315 | - | ||
316 | /******************************************************************************* |
- | |
317 | * |
- | |
318 | * FUNCTION: AcpiDsGetBankFieldArguments |
- | |
319 | * |
- | |
320 | * PARAMETERS: ObjDesc - A valid BankField object |
- | |
321 | * |
- | |
322 | * RETURN: Status. |
- | |
323 | * |
- | |
324 | * DESCRIPTION: Get BankField BankValue. This implements the late |
- | |
325 | * evaluation of these field attributes. |
- | |
326 | * |
- | |
327 | ******************************************************************************/ |
- | |
328 | - | ||
329 | ACPI_STATUS |
- | |
330 | AcpiDsGetBankFieldArguments ( |
- | |
331 | ACPI_OPERAND_OBJECT *ObjDesc) |
- | |
332 | { |
- | |
333 | ACPI_OPERAND_OBJECT *ExtraDesc; |
- | |
334 | ACPI_NAMESPACE_NODE *Node; |
- | |
335 | ACPI_STATUS Status; |
- | |
336 | - | ||
337 | - | ||
338 | ACPI_FUNCTION_TRACE_PTR (DsGetBankFieldArguments, ObjDesc); |
- | |
339 | - | ||
340 | - | ||
341 | if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID) |
- | |
342 | { |
- | |
343 | return_ACPI_STATUS (AE_OK); |
- | |
344 | } |
- | |
345 | - | ||
346 | /* Get the AML pointer (method object) and BankField node */ |
- | |
347 | - | ||
348 | ExtraDesc = AcpiNsGetSecondaryObject (ObjDesc); |
- | |
349 | Node = ObjDesc->BankField.Node; |
- | |
350 | - | ||
351 | ACPI_DEBUG_EXEC(AcpiUtDisplayInitPathname (ACPI_TYPE_LOCAL_BANK_FIELD, Node, NULL)); |
- | |
352 | ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] BankField Arg Init\n", |
- | |
353 | AcpiUtGetNodeName (Node))); |
- | |
354 | - | ||
355 | /* Execute the AML code for the TermArg arguments */ |
- | |
356 | - | ||
357 | Status = AcpiDsExecuteArguments (Node, Node->Parent, |
- | |
358 | ExtraDesc->Extra.AmlLength, ExtraDesc->Extra.AmlStart); |
- | |
359 | return_ACPI_STATUS (Status); |
- | |
360 | } |
- | |
361 | - | ||
362 | - | ||
363 | /******************************************************************************* |
- | |
364 | * |
- | |
365 | * FUNCTION: AcpiDsGetBufferArguments |
- | |
366 | * |
- | |
367 | * PARAMETERS: ObjDesc - A valid Buffer object |
- | |
368 | * |
- | |
369 | * RETURN: Status. |
- | |
370 | * |
- | |
371 | * DESCRIPTION: Get Buffer length and initializer byte list. This implements |
- | |
372 | * the late evaluation of these attributes. |
- | |
373 | * |
- | |
374 | ******************************************************************************/ |
- | |
375 | - | ||
376 | ACPI_STATUS |
- | |
377 | AcpiDsGetBufferArguments ( |
- | |
378 | ACPI_OPERAND_OBJECT *ObjDesc) |
- | |
379 | { |
- | |
380 | ACPI_NAMESPACE_NODE *Node; |
- | |
381 | ACPI_STATUS Status; |
- | |
382 | - | ||
383 | - | ||
384 | ACPI_FUNCTION_TRACE_PTR (DsGetBufferArguments, ObjDesc); |
- | |
385 | - | ||
386 | - | ||
387 | if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID) |
- | |
388 | { |
- | |
389 | return_ACPI_STATUS (AE_OK); |
- | |
390 | } |
- | |
391 | - | ||
392 | /* Get the Buffer node */ |
- | |
393 | - | ||
394 | Node = ObjDesc->Buffer.Node; |
- | |
395 | if (!Node) |
- | |
396 | { |
- | |
397 | ACPI_ERROR ((AE_INFO, |
- | |
398 | "No pointer back to namespace node in buffer object %p", ObjDesc)); |
- | |
399 | return_ACPI_STATUS (AE_AML_INTERNAL); |
- | |
400 | } |
- | |
401 | - | ||
402 | ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Buffer Arg Init\n")); |
- | |
403 | - | ||
404 | /* Execute the AML code for the TermArg arguments */ |
- | |
405 | - | ||
406 | Status = AcpiDsExecuteArguments (Node, Node, |
- | |
407 | ObjDesc->Buffer.AmlLength, ObjDesc->Buffer.AmlStart); |
- | |
408 | return_ACPI_STATUS (Status); |
- | |
409 | } |
- | |
410 | - | ||
411 | - | ||
412 | /******************************************************************************* |
- | |
413 | * |
- | |
414 | * FUNCTION: AcpiDsGetPackageArguments |
- | |
415 | * |
- | |
416 | * PARAMETERS: ObjDesc - A valid Package object |
- | |
417 | * |
- | |
418 | * RETURN: Status. |
- | |
419 | * |
- | |
420 | * DESCRIPTION: Get Package length and initializer byte list. This implements |
- | |
421 | * the late evaluation of these attributes. |
- | |
422 | * |
- | |
423 | ******************************************************************************/ |
- | |
424 | - | ||
425 | ACPI_STATUS |
- | |
426 | AcpiDsGetPackageArguments ( |
- | |
427 | ACPI_OPERAND_OBJECT *ObjDesc) |
- | |
428 | { |
- | |
429 | ACPI_NAMESPACE_NODE *Node; |
- | |
430 | ACPI_STATUS Status; |
- | |
431 | - | ||
432 | - | ||
433 | ACPI_FUNCTION_TRACE_PTR (DsGetPackageArguments, ObjDesc); |
- | |
434 | - | ||
435 | - | ||
436 | if (ObjDesc->Common.Flags & AOPOBJ_DATA_VALID) |
- | |
437 | { |
- | |
438 | return_ACPI_STATUS (AE_OK); |
- | |
439 | } |
- | |
440 | - | ||
441 | /* Get the Package node */ |
- | |
442 | - | ||
443 | Node = ObjDesc->Package.Node; |
- | |
444 | if (!Node) |
- | |
445 | { |
- | |
446 | ACPI_ERROR ((AE_INFO, |
- | |
447 | "No pointer back to namespace node in package %p", ObjDesc)); |
- | |
448 | return_ACPI_STATUS (AE_AML_INTERNAL); |
- | |
449 | } |
- | |
450 | - | ||
451 | ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Package Arg Init\n")); |
- | |
452 | - | ||
453 | /* Execute the AML code for the TermArg arguments */ |
- | |
454 | - | ||
455 | Status = AcpiDsExecuteArguments (Node, Node, |
- | |
456 | ObjDesc->Package.AmlLength, ObjDesc->Package.AmlStart); |
- | |
457 | return_ACPI_STATUS (Status); |
- | |
458 | } |
- | |
459 | - | ||
460 | - | ||
461 | /***************************************************************************** |
- | |
462 | * |
- | |
463 | * FUNCTION: AcpiDsGetRegionArguments |
- | |
464 | * |
- | |
465 | * PARAMETERS: ObjDesc - A valid region object |
- | |
466 | * |
- | |
467 | * RETURN: Status. |
- | |
468 | * |
- | |
469 | * DESCRIPTION: Get region address and length. This implements the late |
- | |
470 | * evaluation of these region attributes. |
- | |
471 | * |
- | |
472 | ****************************************************************************/ |
- | |
473 | - | ||
474 | ACPI_STATUS |
- | |
475 | AcpiDsGetRegionArguments ( |
- | |
476 | ACPI_OPERAND_OBJECT *ObjDesc) |
- | |
477 | { |
- | |
478 | ACPI_NAMESPACE_NODE *Node; |
- | |
479 | ACPI_STATUS Status; |
- | |
480 | ACPI_OPERAND_OBJECT *ExtraDesc; |
- | |
481 | - | ||
482 | - | ||
483 | ACPI_FUNCTION_TRACE_PTR (DsGetRegionArguments, ObjDesc); |
- | |
484 | - | ||
485 | - | ||
486 | if (ObjDesc->Region.Flags & AOPOBJ_DATA_VALID) |
- | |
487 | { |
- | |
488 | return_ACPI_STATUS (AE_OK); |
- | |
489 | } |
- | |
490 | - | ||
491 | ExtraDesc = AcpiNsGetSecondaryObject (ObjDesc); |
- | |
492 | if (!ExtraDesc) |
- | |
493 | { |
- | |
494 | return_ACPI_STATUS (AE_NOT_EXIST); |
- | |
495 | } |
- | |
496 | - | ||
497 | /* Get the Region node */ |
- | |
498 | - | ||
499 | Node = ObjDesc->Region.Node; |
- | |
500 | - | ||
501 | ACPI_DEBUG_EXEC (AcpiUtDisplayInitPathname (ACPI_TYPE_REGION, Node, NULL)); |
- | |
502 | - | ||
503 | ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] OpRegion Arg Init at AML %p\n", |
- | |
504 | AcpiUtGetNodeName (Node), ExtraDesc->Extra.AmlStart)); |
- | |
505 | - | ||
506 | /* Execute the argument AML */ |
- | |
507 | - | ||
508 | Status = AcpiDsExecuteArguments (Node, Node->Parent, |
- | |
509 | ExtraDesc->Extra.AmlLength, ExtraDesc->Extra.AmlStart); |
- | |
510 | return_ACPI_STATUS (Status); |
- | |
511 | } |
- | |
512 | - | ||
513 | - | ||
514 | /******************************************************************************* |
143 | /******************************************************************************* |
515 | * |
144 | * |
516 | * FUNCTION: AcpiDsInitializeRegion |
145 | * FUNCTION: AcpiDsInitializeRegion |
517 | * |
146 | * |
518 | * PARAMETERS: ObjHandle - Region namespace node |
147 | * PARAMETERS: ObjHandle - Region namespace node |
Line 940... | Line 569... | ||
940 | * PARAMETERS: WalkState - Current walk |
569 | * PARAMETERS: WalkState - Current walk |
941 | * Op - A valid region Op object |
570 | * Op - A valid region Op object |
942 | * |
571 | * |
943 | * RETURN: Status |
572 | * RETURN: Status |
944 | * |
573 | * |
945 | * DESCRIPTION: Get region address and length |
574 | * DESCRIPTION: Get region address and length. |
946 | * Called from AcpiDsExecEndOp during DataTableRegion parse tree walk |
575 | * Called from AcpiDsExecEndOp during DataTableRegion parse |
- | 576 | * tree walk. |
|
947 | * |
577 | * |
948 | ******************************************************************************/ |
578 | ******************************************************************************/ |
Line 949... | Line 579... | ||
949 | 579 | ||
950 | ACPI_STATUS |
580 | ACPI_STATUS |
Line 1247... | Line 877... | ||
1247 | 877 | ||
1248 | AcpiUtRemoveReference (OperandDesc); |
878 | AcpiUtRemoveReference (OperandDesc); |
1249 | return_ACPI_STATUS (Status); |
879 | return_ACPI_STATUS (Status); |
Line 1250... | Line -... | ||
1250 | } |
- | |
1251 | - | ||
1252 | - | ||
1253 | /******************************************************************************* |
- | |
1254 | * |
- | |
1255 | * FUNCTION: AcpiDsExecBeginControlOp |
- | |
1256 | * |
- | |
1257 | * PARAMETERS: WalkList - The list that owns the walk stack |
- | |
1258 | * Op - The control Op |
- | |
1259 | * |
- | |
1260 | * RETURN: Status |
- | |
1261 | * |
- | |
1262 | * DESCRIPTION: Handles all control ops encountered during control method |
- | |
1263 | * execution. |
- | |
1264 | * |
- | |
1265 | ******************************************************************************/ |
- | |
1266 | - | ||
1267 | ACPI_STATUS |
- | |
1268 | AcpiDsExecBeginControlOp ( |
- | |
1269 | ACPI_WALK_STATE *WalkState, |
- | |
1270 | ACPI_PARSE_OBJECT *Op) |
- | |
1271 | { |
- | |
1272 | ACPI_STATUS Status = AE_OK; |
- | |
1273 | ACPI_GENERIC_STATE *ControlState; |
- | |
1274 | - | ||
1275 | - | ||
1276 | ACPI_FUNCTION_NAME (DsExecBeginControlOp); |
- | |
1277 | - | ||
1278 | - | ||
1279 | ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p Opcode=%2.2X State=%p\n", Op, |
- | |
1280 | Op->Common.AmlOpcode, WalkState)); |
- | |
1281 | - | ||
1282 | switch (Op->Common.AmlOpcode) |
- | |
1283 | { |
- | |
1284 | case AML_WHILE_OP: |
- | |
1285 | - | ||
1286 | /* |
- | |
1287 | * If this is an additional iteration of a while loop, continue. |
- | |
1288 | * There is no need to allocate a new control state. |
- | |
1289 | */ |
- | |
1290 | if (WalkState->ControlState) |
- | |
1291 | { |
- | |
1292 | if (WalkState->ControlState->Control.AmlPredicateStart == |
- | |
1293 | (WalkState->ParserState.Aml - 1)) |
- | |
1294 | { |
- | |
1295 | /* Reset the state to start-of-loop */ |
- | |
1296 | - | ||
1297 | WalkState->ControlState->Common.State = ACPI_CONTROL_CONDITIONAL_EXECUTING; |
- | |
1298 | break; |
- | |
1299 | } |
- | |
1300 | } |
- | |
1301 | - | ||
1302 | /*lint -fallthrough */ |
- | |
1303 | - | ||
1304 | case AML_IF_OP: |
- | |
1305 | - | ||
1306 | /* |
- | |
1307 | * IF/WHILE: Create a new control state to manage these |
- | |
1308 | * constructs. We need to manage these as a stack, in order |
- | |
1309 | * to handle nesting. |
- | |
1310 | */ |
- | |
1311 | ControlState = AcpiUtCreateControlState (); |
- | |
1312 | if (!ControlState) |
- | |
1313 | { |
- | |
1314 | Status = AE_NO_MEMORY; |
- | |
1315 | break; |
- | |
1316 | } |
- | |
1317 | /* |
- | |
1318 | * Save a pointer to the predicate for multiple executions |
- | |
1319 | * of a loop |
- | |
1320 | */ |
- | |
1321 | ControlState->Control.AmlPredicateStart = WalkState->ParserState.Aml - 1; |
- | |
1322 | ControlState->Control.PackageEnd = WalkState->ParserState.PkgEnd; |
- | |
1323 | ControlState->Control.Opcode = Op->Common.AmlOpcode; |
- | |
1324 | - | ||
1325 | - | ||
1326 | /* Push the control state on this walk's control stack */ |
- | |
1327 | - | ||
1328 | AcpiUtPushGenericState (&WalkState->ControlState, ControlState); |
- | |
1329 | break; |
- | |
1330 | - | ||
1331 | case AML_ELSE_OP: |
- | |
1332 | - | ||
1333 | /* Predicate is in the state object */ |
- | |
1334 | /* If predicate is true, the IF was executed, ignore ELSE part */ |
- | |
1335 | - | ||
1336 | if (WalkState->LastPredicate) |
- | |
1337 | { |
- | |
1338 | Status = AE_CTRL_TRUE; |
- | |
1339 | } |
- | |
1340 | - | ||
1341 | break; |
- | |
1342 | - | ||
1343 | case AML_RETURN_OP: |
- | |
1344 | - | ||
1345 | break; |
- | |
1346 | - | ||
1347 | default: |
- | |
1348 | break; |
- | |
1349 | } |
- | |
1350 | - | ||
1351 | return (Status); |
- | |
1352 | } |
- | |
1353 | - | ||
1354 | - | ||
1355 | /******************************************************************************* |
- | |
1356 | * |
- | |
1357 | * FUNCTION: AcpiDsExecEndControlOp |
- | |
1358 | * |
- | |
1359 | * PARAMETERS: WalkList - The list that owns the walk stack |
- | |
1360 | * Op - The control Op |
- | |
1361 | * |
- | |
1362 | * RETURN: Status |
- | |
1363 | * |
- | |
1364 | * DESCRIPTION: Handles all control ops encountered during control method |
- | |
1365 | * execution. |
- | |
1366 | * |
- | |
1367 | ******************************************************************************/ |
- | |
1368 | - | ||
1369 | ACPI_STATUS |
- | |
1370 | AcpiDsExecEndControlOp ( |
- | |
1371 | ACPI_WALK_STATE *WalkState, |
- | |
1372 | ACPI_PARSE_OBJECT *Op) |
- | |
1373 | { |
- | |
1374 | ACPI_STATUS Status = AE_OK; |
- | |
1375 | ACPI_GENERIC_STATE *ControlState; |
- | |
1376 | - | ||
1377 | - | ||
1378 | ACPI_FUNCTION_NAME (DsExecEndControlOp); |
- | |
1379 | - | ||
1380 | - | ||
1381 | switch (Op->Common.AmlOpcode) |
- | |
1382 | { |
- | |
1383 | case AML_IF_OP: |
- | |
1384 | - | ||
1385 | ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[IF_OP] Op=%p\n", Op)); |
- | |
1386 | - | ||
1387 | /* |
- | |
1388 | * Save the result of the predicate in case there is an |
- | |
1389 | * ELSE to come |
- | |
1390 | */ |
- | |
1391 | WalkState->LastPredicate = |
- | |
1392 | (BOOLEAN) WalkState->ControlState->Common.Value; |
- | |
1393 | - | ||
1394 | /* |
- | |
1395 | * Pop the control state that was created at the start |
- | |
1396 | * of the IF and free it |
- | |
1397 | */ |
- | |
1398 | ControlState = AcpiUtPopGenericState (&WalkState->ControlState); |
- | |
1399 | AcpiUtDeleteGenericState (ControlState); |
- | |
1400 | break; |
- | |
1401 | - | ||
1402 | - | ||
1403 | case AML_ELSE_OP: |
- | |
1404 | - | ||
1405 | break; |
- | |
1406 | - | ||
1407 | - | ||
1408 | case AML_WHILE_OP: |
- | |
1409 | - | ||
1410 | ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[WHILE_OP] Op=%p\n", Op)); |
- | |
1411 | - | ||
1412 | ControlState = WalkState->ControlState; |
- | |
1413 | if (ControlState->Common.Value) |
- | |
1414 | { |
- | |
1415 | /* Predicate was true, the body of the loop was just executed */ |
- | |
1416 | - | ||
1417 | /* |
- | |
1418 | * This loop counter mechanism allows the interpreter to escape |
- | |
1419 | * possibly infinite loops. This can occur in poorly written AML |
- | |
1420 | * when the hardware does not respond within a while loop and the |
- | |
1421 | * loop does not implement a timeout. |
- | |
1422 | */ |
- | |
1423 | ControlState->Control.LoopCount++; |
- | |
1424 | if (ControlState->Control.LoopCount > ACPI_MAX_LOOP_ITERATIONS) |
- | |
1425 | { |
- | |
1426 | Status = AE_AML_INFINITE_LOOP; |
- | |
1427 | break; |
- | |
1428 | } |
- | |
1429 | - | ||
1430 | /* |
- | |
1431 | * Go back and evaluate the predicate and maybe execute the loop |
- | |
1432 | * another time |
- | |
1433 | */ |
- | |
1434 | Status = AE_CTRL_PENDING; |
- | |
1435 | WalkState->AmlLastWhile = ControlState->Control.AmlPredicateStart; |
- | |
1436 | break; |
- | |
1437 | } |
- | |
1438 | - | ||
1439 | /* Predicate was false, terminate this while loop */ |
- | |
1440 | - | ||
1441 | ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, |
- | |
1442 | "[WHILE_OP] termination! Op=%p\n",Op)); |
- | |
1443 | - | ||
1444 | /* Pop this control state and free it */ |
- | |
1445 | - | ||
1446 | ControlState = AcpiUtPopGenericState (&WalkState->ControlState); |
- | |
1447 | AcpiUtDeleteGenericState (ControlState); |
- | |
1448 | break; |
- | |
1449 | - | ||
1450 | - | ||
1451 | case AML_RETURN_OP: |
- | |
1452 | - | ||
1453 | ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, |
- | |
1454 | "[RETURN_OP] Op=%p Arg=%p\n",Op, Op->Common.Value.Arg)); |
- | |
1455 | - | ||
1456 | /* |
- | |
1457 | * One optional operand -- the return value |
- | |
1458 | * It can be either an immediate operand or a result that |
- | |
1459 | * has been bubbled up the tree |
- | |
1460 | */ |
- | |
1461 | if (Op->Common.Value.Arg) |
- | |
1462 | { |
- | |
1463 | /* Since we have a real Return(), delete any implicit return */ |
- | |
1464 | - | ||
1465 | AcpiDsClearImplicitReturn (WalkState); |
- | |
1466 | - | ||
1467 | /* Return statement has an immediate operand */ |
- | |
1468 | - | ||
1469 | Status = AcpiDsCreateOperands (WalkState, Op->Common.Value.Arg); |
- | |
1470 | if (ACPI_FAILURE (Status)) |
- | |
1471 | { |
- | |
1472 | return (Status); |
- | |
1473 | } |
- | |
1474 | - | ||
1475 | /* |
- | |
1476 | * If value being returned is a Reference (such as |
- | |
1477 | * an arg or local), resolve it now because it may |
- | |
1478 | * cease to exist at the end of the method. |
- | |
1479 | */ |
- | |
1480 | Status = AcpiExResolveToValue (&WalkState->Operands [0], WalkState); |
- | |
1481 | if (ACPI_FAILURE (Status)) |
- | |
1482 | { |
- | |
1483 | return (Status); |
- | |
1484 | } |
- | |
1485 | - | ||
1486 | /* |
- | |
1487 | * Get the return value and save as the last result |
- | |
1488 | * value. This is the only place where WalkState->ReturnDesc |
- | |
1489 | * is set to anything other than zero! |
- | |
1490 | */ |
- | |
1491 | WalkState->ReturnDesc = WalkState->Operands[0]; |
- | |
1492 | } |
- | |
1493 | else if (WalkState->ResultCount) |
- | |
1494 | { |
- | |
1495 | /* Since we have a real Return(), delete any implicit return */ |
- | |
1496 | - | ||
1497 | AcpiDsClearImplicitReturn (WalkState); |
- | |
1498 | - | ||
1499 | /* |
- | |
1500 | * The return value has come from a previous calculation. |
- | |
1501 | * |
- | |
1502 | * If value being returned is a Reference (such as |
- | |
1503 | * an arg or local), resolve it now because it may |
- | |
1504 | * cease to exist at the end of the method. |
- | |
1505 | * |
- | |
1506 | * Allow references created by the Index operator to return unchanged. |
- | |
1507 | */ |
- | |
1508 | if ((ACPI_GET_DESCRIPTOR_TYPE (WalkState->Results->Results.ObjDesc[0]) == ACPI_DESC_TYPE_OPERAND) && |
- | |
1509 | ((WalkState->Results->Results.ObjDesc [0])->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) && |
- | |
1510 | ((WalkState->Results->Results.ObjDesc [0])->Reference.Class != ACPI_REFCLASS_INDEX)) |
- | |
1511 | { |
- | |
1512 | Status = AcpiExResolveToValue (&WalkState->Results->Results.ObjDesc [0], WalkState); |
- | |
1513 | if (ACPI_FAILURE (Status)) |
- | |
1514 | { |
- | |
1515 | return (Status); |
- | |
1516 | } |
- | |
1517 | } |
- | |
1518 | - | ||
1519 | WalkState->ReturnDesc = WalkState->Results->Results.ObjDesc [0]; |
- | |
1520 | } |
- | |
1521 | else |
- | |
1522 | { |
- | |
1523 | /* No return operand */ |
- | |
1524 | - | ||
1525 | if (WalkState->NumOperands) |
- | |
1526 | { |
- | |
1527 | AcpiUtRemoveReference (WalkState->Operands [0]); |
- | |
1528 | } |
- | |
1529 | - | ||
1530 | WalkState->Operands [0] = NULL; |
- | |
1531 | WalkState->NumOperands = 0; |
- | |
1532 | WalkState->ReturnDesc = NULL; |
- | |
1533 | } |
- | |
1534 | - | ||
1535 | - | ||
1536 | ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, |
- | |
1537 | "Completed RETURN_OP State=%p, RetVal=%p\n", |
- | |
1538 | WalkState, WalkState->ReturnDesc)); |
- | |
1539 | - | ||
1540 | /* End the control method execution right now */ |
- | |
1541 | - | ||
1542 | Status = AE_CTRL_TERMINATE; |
- | |
1543 | break; |
- | |
1544 | - | ||
1545 | - | ||
1546 | case AML_NOOP_OP: |
- | |
1547 | - | ||
1548 | /* Just do nothing! */ |
- | |
1549 | break; |
- | |
1550 | - | ||
1551 | - | ||
1552 | case AML_BREAK_POINT_OP: |
- | |
1553 | - | ||
1554 | /* |
- | |
1555 | * Set the single-step flag. This will cause the debugger (if present) |
- | |
1556 | * to break to the console within the AML debugger at the start of the |
- | |
1557 | * next AML instruction. |
- | |
1558 | */ |
- | |
1559 | ACPI_DEBUGGER_EXEC ( |
- | |
1560 | AcpiGbl_CmSingleStep = TRUE); |
- | |
1561 | ACPI_DEBUGGER_EXEC ( |
- | |
1562 | AcpiOsPrintf ("**break** Executed AML BreakPoint opcode\n")); |
- | |
1563 | - | ||
1564 | /* Call to the OSL in case OS wants a piece of the action */ |
- | |
1565 | - | ||
1566 | Status = AcpiOsSignal (ACPI_SIGNAL_BREAKPOINT, |
- | |
1567 | "Executed AML Breakpoint opcode"); |
- | |
1568 | break; |
- | |
1569 | - | ||
1570 | - | ||
1571 | case AML_BREAK_OP: |
- | |
1572 | case AML_CONTINUE_OP: /* ACPI 2.0 */ |
- | |
1573 | - | ||
1574 | - | ||
1575 | /* Pop and delete control states until we find a while */ |
- | |
1576 | - | ||
1577 | while (WalkState->ControlState && |
- | |
1578 | (WalkState->ControlState->Control.Opcode != AML_WHILE_OP)) |
- | |
1579 | { |
- | |
1580 | ControlState = AcpiUtPopGenericState (&WalkState->ControlState); |
- | |
1581 | AcpiUtDeleteGenericState (ControlState); |
- | |
1582 | } |
- | |
1583 | - | ||
1584 | /* No while found? */ |
- | |
1585 | - | ||
1586 | if (!WalkState->ControlState) |
- | |
1587 | { |
- | |
1588 | return (AE_AML_NO_WHILE); |
- | |
1589 | } |
- | |
1590 | - | ||
1591 | /* Was: WalkState->AmlLastWhile = WalkState->ControlState->Control.AmlPredicateStart; */ |
- | |
1592 | - | ||
1593 | WalkState->AmlLastWhile = WalkState->ControlState->Control.PackageEnd; |
- | |
1594 | - | ||
1595 | /* Return status depending on opcode */ |
- | |
1596 | - | ||
1597 | if (Op->Common.AmlOpcode == AML_BREAK_OP) |
- | |
1598 | { |
- | |
1599 | Status = AE_CTRL_BREAK; |
- | |
1600 | } |
- | |
1601 | else |
- | |
1602 | { |
- | |
1603 | Status = AE_CTRL_CONTINUE; |
- | |
1604 | } |
- | |
1605 | break; |
- | |
1606 | - | ||
1607 | - | ||
1608 | default: |
- | |
1609 | - | ||
1610 | ACPI_ERROR ((AE_INFO, "Unknown control opcode=0x%X Op=%p", |
- | |
1611 | Op->Common.AmlOpcode, Op)); |
- | |
1612 | - | ||
1613 | Status = AE_AML_BAD_OPCODE; |
- | |
1614 | break; |
- | |
1615 | } |
- | |
1616 | - | ||
1617 | return (Status); |
- |