dmopcode.c revision 1.1.1.2 1 /*******************************************************************************
2 *
3 * Module Name: dmopcode - AML disassembler, specific AML opcodes
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.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44 #include "acpi.h"
45 #include "accommon.h"
46 #include "acparser.h"
47 #include "amlcode.h"
48 #include "acdisasm.h"
49
50 #ifdef ACPI_DISASSEMBLER
51
52 #define _COMPONENT ACPI_CA_DEBUGGER
53 ACPI_MODULE_NAME ("dmopcode")
54
55 /* Local prototypes */
56
57 static void
58 AcpiDmMatchKeyword (
59 ACPI_PARSE_OBJECT *Op);
60
61
62 /*******************************************************************************
63 *
64 * FUNCTION: AcpiDmMethodFlags
65 *
66 * PARAMETERS: Op - Method Object to be examined
67 *
68 * RETURN: None
69 *
70 * DESCRIPTION: Decode control method flags
71 *
72 ******************************************************************************/
73
74 void
75 AcpiDmMethodFlags (
76 ACPI_PARSE_OBJECT *Op)
77 {
78 UINT32 Flags;
79 UINT32 Args;
80
81
82 /* The next Op contains the flags */
83
84 Op = AcpiPsGetDepthNext (NULL, Op);
85 Flags = (UINT8) Op->Common.Value.Integer;
86 Args = Flags & 0x07;
87
88 /* Mark the Op as completed */
89
90 Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
91
92 /* 1) Method argument count */
93
94 AcpiOsPrintf (", %u, ", Args);
95
96 /* 2) Serialize rule */
97
98 if (!(Flags & 0x08))
99 {
100 AcpiOsPrintf ("Not");
101 }
102
103 AcpiOsPrintf ("Serialized");
104
105 /* 3) SyncLevel */
106
107 if (Flags & 0xF0)
108 {
109 AcpiOsPrintf (", %u", Flags >> 4);
110 }
111 }
112
113
114 /*******************************************************************************
115 *
116 * FUNCTION: AcpiDmFieldFlags
117 *
118 * PARAMETERS: Op - Field Object to be examined
119 *
120 * RETURN: None
121 *
122 * DESCRIPTION: Decode Field definition flags
123 *
124 ******************************************************************************/
125
126 void
127 AcpiDmFieldFlags (
128 ACPI_PARSE_OBJECT *Op)
129 {
130 UINT32 Flags;
131
132
133 Op = Op->Common.Next;
134 Flags = (UINT8) Op->Common.Value.Integer;
135
136 /* Mark the Op as completed */
137
138 Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
139
140 AcpiOsPrintf ("%s, ", AcpiGbl_AccessTypes [Flags & 0x07]);
141 AcpiOsPrintf ("%s, ", AcpiGbl_LockRule [(Flags & 0x10) >> 4]);
142 AcpiOsPrintf ("%s)", AcpiGbl_UpdateRules [(Flags & 0x60) >> 5]);
143 }
144
145
146 /*******************************************************************************
147 *
148 * FUNCTION: AcpiDmAddressSpace
149 *
150 * PARAMETERS: SpaceId - ID to be translated
151 *
152 * RETURN: None
153 *
154 * DESCRIPTION: Decode a SpaceId to an AddressSpaceKeyword
155 *
156 ******************************************************************************/
157
158 void
159 AcpiDmAddressSpace (
160 UINT8 SpaceId)
161 {
162
163 if (SpaceId >= ACPI_NUM_PREDEFINED_REGIONS)
164 {
165 if (SpaceId == 0x7F)
166 {
167 AcpiOsPrintf ("FFixedHW, ");
168 }
169 else
170 {
171 AcpiOsPrintf ("0x%.2X, ", SpaceId);
172 }
173 }
174 else
175 {
176 AcpiOsPrintf ("%s, ", AcpiGbl_RegionTypes [SpaceId]);
177 }
178 }
179
180
181 /*******************************************************************************
182 *
183 * FUNCTION: AcpiDmRegionFlags
184 *
185 * PARAMETERS: Op - Object to be examined
186 *
187 * RETURN: None
188 *
189 * DESCRIPTION: Decode OperationRegion flags
190 *
191 ******************************************************************************/
192
193 void
194 AcpiDmRegionFlags (
195 ACPI_PARSE_OBJECT *Op)
196 {
197
198
199 /* The next Op contains the SpaceId */
200
201 Op = AcpiPsGetDepthNext (NULL, Op);
202
203 /* Mark the Op as completed */
204
205 Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
206
207 AcpiOsPrintf (", ");
208 AcpiDmAddressSpace ((UINT8) Op->Common.Value.Integer);
209 }
210
211
212 /*******************************************************************************
213 *
214 * FUNCTION: AcpiDmMatchOp
215 *
216 * PARAMETERS: Op - Match Object to be examined
217 *
218 * RETURN: None
219 *
220 * DESCRIPTION: Decode Match opcode operands
221 *
222 ******************************************************************************/
223
224 void
225 AcpiDmMatchOp (
226 ACPI_PARSE_OBJECT *Op)
227 {
228 ACPI_PARSE_OBJECT *NextOp;
229
230
231 NextOp = AcpiPsGetDepthNext (NULL, Op);
232 NextOp = NextOp->Common.Next;
233
234 if (!NextOp)
235 {
236 /* Handle partial tree during single-step */
237
238 return;
239 }
240
241 /* Mark the two nodes that contain the encoding for the match keywords */
242
243 NextOp->Common.DisasmOpcode = ACPI_DASM_MATCHOP;
244
245 NextOp = NextOp->Common.Next;
246 NextOp = NextOp->Common.Next;
247 NextOp->Common.DisasmOpcode = ACPI_DASM_MATCHOP;
248 }
249
250
251 /*******************************************************************************
252 *
253 * FUNCTION: AcpiDmMatchKeyword
254 *
255 * PARAMETERS: Op - Match Object to be examined
256 *
257 * RETURN: None
258 *
259 * DESCRIPTION: Decode Match opcode operands
260 *
261 ******************************************************************************/
262
263 static void
264 AcpiDmMatchKeyword (
265 ACPI_PARSE_OBJECT *Op)
266 {
267
268
269 if (((UINT32) Op->Common.Value.Integer) > ACPI_MAX_MATCH_OPCODE)
270 {
271 AcpiOsPrintf ("/* Unknown Match Keyword encoding */");
272 }
273 else
274 {
275 AcpiOsPrintf ("%s", ACPI_CAST_PTR (char,
276 AcpiGbl_MatchOps[(ACPI_SIZE) Op->Common.Value.Integer]));
277 }
278 }
279
280
281 /*******************************************************************************
282 *
283 * FUNCTION: AcpiDmDisassembleOneOp
284 *
285 * PARAMETERS: WalkState - Current walk info
286 * Info - Parse tree walk info
287 * Op - Op that is to be printed
288 *
289 * RETURN: None
290 *
291 * DESCRIPTION: Disassemble a single AML opcode
292 *
293 ******************************************************************************/
294
295 void
296 AcpiDmDisassembleOneOp (
297 ACPI_WALK_STATE *WalkState,
298 ACPI_OP_WALK_INFO *Info,
299 ACPI_PARSE_OBJECT *Op)
300 {
301 const ACPI_OPCODE_INFO *OpInfo = NULL;
302 UINT32 Offset;
303 UINT32 Length;
304 ACPI_PARSE_OBJECT *Child;
305 ACPI_STATUS Status;
306
307
308 if (!Op)
309 {
310 AcpiOsPrintf ("<NULL OP PTR>");
311 return;
312 }
313
314 switch (Op->Common.DisasmOpcode)
315 {
316 case ACPI_DASM_MATCHOP:
317
318 AcpiDmMatchKeyword (Op);
319 return;
320
321 case ACPI_DASM_LNOT_SUFFIX:
322 switch (Op->Common.AmlOpcode)
323 {
324 case AML_LEQUAL_OP:
325 AcpiOsPrintf ("LNotEqual");
326 break;
327
328 case AML_LGREATER_OP:
329 AcpiOsPrintf ("LLessEqual");
330 break;
331
332 case AML_LLESS_OP:
333 AcpiOsPrintf ("LGreaterEqual");
334 break;
335
336 default:
337 break;
338 }
339 Op->Common.DisasmOpcode = 0;
340 Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
341 return;
342
343 default:
344 break;
345 }
346
347
348 OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
349
350 /* The op and arguments */
351
352 switch (Op->Common.AmlOpcode)
353 {
354 case AML_LNOT_OP:
355
356 Child = Op->Common.Value.Arg;
357 if ((Child->Common.AmlOpcode == AML_LEQUAL_OP) ||
358 (Child->Common.AmlOpcode == AML_LGREATER_OP) ||
359 (Child->Common.AmlOpcode == AML_LLESS_OP))
360 {
361 Child->Common.DisasmOpcode = ACPI_DASM_LNOT_SUFFIX;
362 Op->Common.DisasmOpcode = ACPI_DASM_LNOT_PREFIX;
363 }
364 else
365 {
366 AcpiOsPrintf ("%s", OpInfo->Name);
367 }
368 break;
369
370 case AML_BYTE_OP:
371
372 AcpiOsPrintf ("0x%2.2X", (UINT32) Op->Common.Value.Integer);
373 break;
374
375
376 case AML_WORD_OP:
377
378 if (Op->Common.DisasmOpcode == ACPI_DASM_EISAID)
379 {
380 AcpiDmEisaId ((UINT32) Op->Common.Value.Integer);
381 }
382 else
383 {
384 AcpiOsPrintf ("0x%4.4X", (UINT32) Op->Common.Value.Integer);
385 }
386 break;
387
388
389 case AML_DWORD_OP:
390
391 if (Op->Common.DisasmOpcode == ACPI_DASM_EISAID)
392 {
393 AcpiDmEisaId ((UINT32) Op->Common.Value.Integer);
394 }
395 else
396 {
397 AcpiOsPrintf ("0x%8.8X", (UINT32) Op->Common.Value.Integer);
398 }
399 break;
400
401
402 case AML_QWORD_OP:
403
404 AcpiOsPrintf ("0x%8.8X%8.8X",
405 ACPI_FORMAT_UINT64 (Op->Common.Value.Integer));
406 break;
407
408
409 case AML_STRING_OP:
410
411 AcpiUtPrintString (Op->Common.Value.String, ACPI_UINT8_MAX);
412 break;
413
414
415 case AML_BUFFER_OP:
416
417 /*
418 * Determine the type of buffer. We can have one of the following:
419 *
420 * 1) ResourceTemplate containing Resource Descriptors.
421 * 2) Unicode String buffer
422 * 3) ASCII String buffer
423 * 4) Raw data buffer (if none of the above)
424 *
425 * Since there are no special AML opcodes to differentiate these
426 * types of buffers, we have to closely look at the data in the
427 * buffer to determine the type.
428 */
429 Status = AcpiDmIsResourceTemplate (Op);
430 if (ACPI_SUCCESS (Status))
431 {
432 Op->Common.DisasmOpcode = ACPI_DASM_RESOURCE;
433 AcpiOsPrintf ("ResourceTemplate");
434 break;
435 }
436 else if (Status == AE_AML_NO_RESOURCE_END_TAG)
437 {
438 AcpiOsPrintf ("/**** Is ResourceTemplate, but EndTag not at buffer end ****/ ");
439 }
440
441 if (AcpiDmIsUnicodeBuffer (Op))
442 {
443 Op->Common.DisasmOpcode = ACPI_DASM_UNICODE;
444 AcpiOsPrintf ("Unicode (");
445 }
446 else if (AcpiDmIsStringBuffer (Op))
447 {
448 Op->Common.DisasmOpcode = ACPI_DASM_STRING;
449 AcpiOsPrintf ("Buffer");
450 }
451 else
452 {
453 Op->Common.DisasmOpcode = ACPI_DASM_BUFFER;
454 AcpiOsPrintf ("Buffer");
455 }
456 break;
457
458
459 case AML_INT_STATICSTRING_OP:
460
461 if (Op->Common.Value.String)
462 {
463 AcpiOsPrintf ("%s", Op->Common.Value.String);
464 }
465 else
466 {
467 AcpiOsPrintf ("\"<NULL STATIC STRING PTR>\"");
468 }
469 break;
470
471
472 case AML_INT_NAMEPATH_OP:
473
474 AcpiDmNamestring (Op->Common.Value.Name);
475 break;
476
477
478 case AML_INT_NAMEDFIELD_OP:
479
480 Length = AcpiDmDumpName (Op->Named.Name);
481 AcpiOsPrintf (",%*.s %u", (unsigned) (5 - Length), " ",
482 (UINT32) Op->Common.Value.Integer);
483 AcpiDmCommaIfFieldMember (Op);
484
485 Info->BitOffset += (UINT32) Op->Common.Value.Integer;
486 break;
487
488
489 case AML_INT_RESERVEDFIELD_OP:
490
491 /* Offset() -- Must account for previous offsets */
492
493 Offset = (UINT32) Op->Common.Value.Integer;
494 Info->BitOffset += Offset;
495
496 if (Info->BitOffset % 8 == 0)
497 {
498 AcpiOsPrintf (" Offset (0x%.2X)", ACPI_DIV_8 (Info->BitOffset));
499 }
500 else
501 {
502 AcpiOsPrintf (" , %u", Offset);
503 }
504
505 AcpiDmCommaIfFieldMember (Op);
506 break;
507
508
509 case AML_INT_ACCESSFIELD_OP:
510
511 AcpiOsPrintf (" AccessAs (%s, ",
512 AcpiGbl_AccessTypes [(UINT32) (Op->Common.Value.Integer >> 8) & 0x7]);
513
514 AcpiDmDecodeAttribute ((UINT8) Op->Common.Value.Integer);
515 AcpiOsPrintf (")");
516 AcpiDmCommaIfFieldMember (Op);
517 break;
518
519
520 case AML_INT_BYTELIST_OP:
521
522 AcpiDmByteList (Info, Op);
523 break;
524
525
526 case AML_INT_METHODCALL_OP:
527
528 Op = AcpiPsGetDepthNext (NULL, Op);
529 Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
530
531 AcpiDmNamestring (Op->Common.Value.Name);
532 break;
533
534
535 default:
536
537 /* Just get the opcode name and print it */
538
539 AcpiOsPrintf ("%s", OpInfo->Name);
540
541
542 #ifdef ACPI_DEBUGGER
543
544 if ((Op->Common.AmlOpcode == AML_INT_RETURN_VALUE_OP) &&
545 (WalkState) &&
546 (WalkState->Results) &&
547 (WalkState->ResultCount))
548 {
549 AcpiDmDecodeInternalObject (
550 WalkState->Results->Results.ObjDesc [
551 (WalkState->ResultCount - 1) %
552 ACPI_RESULTS_FRAME_OBJ_NUM]);
553 }
554 #endif
555
556 break;
557 }
558 }
559
560 #endif /* ACPI_DISASSEMBLER */
561