ahdecode.c revision 1.1 1 /******************************************************************************
2 *
3 * Module Name: ahdecode - Operator/Opcode decoding for acpihelp utility
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 "acpihelp.h"
45
46 #define ACPI_CREATE_PREDEFINED_TABLE
47 #include "acpredef.h"
48
49 static char Gbl_Buffer[64];
50 static const char *AcpiRtypeNames[] =
51 {
52 "/Integer",
53 "/String",
54 "/Buffer",
55 "/Package",
56 "/Reference",
57 };
58
59
60 /* Local prototypes */
61
62 static BOOLEAN
63 AhDisplayPredefinedName (
64 char *Name,
65 UINT32 Length);
66
67 static void
68 AhDisplayPredefinedInfo (
69 char *Name);
70
71 static void
72 AhGetExpectedTypes (
73 char *Buffer,
74 UINT32 ExpectedBtypes);
75
76 static void
77 AhDisplayAmlOpcode (
78 const AH_AML_OPCODE *Op);
79
80 static void
81 AhDisplayAslOperator (
82 const AH_ASL_OPERATOR *Op);
83
84 static void
85 AhDisplayAslKeyword (
86 const AH_ASL_KEYWORD *Op);
87
88 static void
89 AhPrintOneField (
90 UINT32 Indent,
91 UINT32 CurrentPosition,
92 UINT32 MaxPosition,
93 const char *Field);
94
95
96 /*******************************************************************************
97 *
98 * FUNCTION: AhFindPredefinedNames (entry point for predefined name search)
99 *
100 * PARAMETERS: NamePrefix - Name or prefix to find. Must start with
101 * an underscore. NULL means "find all"
102 *
103 * RETURN: None
104 *
105 * DESCRIPTION: Find and display all ACPI predefined names that match the
106 * input name or prefix. Includes the required number of arguments
107 * and the expected return type, if any.
108 *
109 ******************************************************************************/
110
111 void
112 AhFindPredefinedNames (
113 char *NamePrefix)
114 {
115 UINT32 Length;
116 BOOLEAN Found;
117 char Name[9];
118
119
120 if (!NamePrefix)
121 {
122 Found = AhDisplayPredefinedName (Name, 0);
123 return;
124 }
125
126 /* Contruct a local name or name prefix */
127
128 AhStrupr (NamePrefix);
129 if (*NamePrefix == '_')
130 {
131 NamePrefix++;
132 }
133
134 Name[0] = '_';
135 strncpy (&Name[1], NamePrefix, 7);
136
137 Length = strlen (Name);
138 if (Length > 4)
139 {
140 printf ("%.8s: Predefined name must be 4 characters maximum\n", Name);
141 return;
142 }
143
144 Found = AhDisplayPredefinedName (Name, Length);
145 if (!Found)
146 {
147 printf ("%s, no matching predefined names\n", Name);
148 }
149 }
150
151
152 /*******************************************************************************
153 *
154 * FUNCTION: AhDisplayPredefinedName
155 *
156 * PARAMETERS: Name - Name or name prefix
157 *
158 * RETURN: TRUE if any names matched, FALSE otherwise
159 *
160 * DESCRIPTION: Display information about ACPI predefined names that match
161 * the input name or name prefix.
162 *
163 ******************************************************************************/
164
165 static BOOLEAN
166 AhDisplayPredefinedName (
167 char *Name,
168 UINT32 Length)
169 {
170 const AH_PREDEFINED_NAME *Info;
171 BOOLEAN Found = FALSE;
172 BOOLEAN Matched;
173 UINT32 i;
174
175
176 /* Find/display all names that match the input name prefix */
177
178 for (Info = AslPredefinedInfo; Info->Name; Info++)
179 {
180 if (!Name)
181 {
182 Found = TRUE;
183 printf ("%s: <%s>\n", Info->Name, Info->Description);
184 printf ("%*s%s\n", 6, " ", Info->Action);
185
186 AhDisplayPredefinedInfo (Info->Name);
187 continue;
188 }
189
190 Matched = TRUE;
191 for (i = 0; i < Length; i++)
192 {
193 if (Info->Name[i] != Name[i])
194 {
195 Matched = FALSE;
196 break;
197 }
198 }
199
200 if (Matched)
201 {
202 Found = TRUE;
203 printf ("%s: <%s>\n", Info->Name, Info->Description);
204 printf ("%*s%s\n", 6, " ", Info->Action);
205
206 AhDisplayPredefinedInfo (Info->Name);
207 }
208 }
209
210 return (Found);
211 }
212
213
214 /*******************************************************************************
215 *
216 * FUNCTION: AhDisplayPredefinedInfo
217 *
218 * PARAMETERS: Name - Exact 4-character ACPI name.
219 *
220 * RETURN: None
221 *
222 * DESCRIPTION: Find the name in the main ACPICA predefined info table and
223 * display the # of arguments and the return value type.
224 *
225 * Note: Resource Descriptor field names do not appear in this
226 * table -- thus, nothing will be displayed for them.
227 *
228 ******************************************************************************/
229
230 static void
231 AhDisplayPredefinedInfo (
232 char *Name)
233 {
234 const ACPI_PREDEFINED_INFO *ThisName;
235 BOOLEAN Matched;
236 UINT32 i;
237
238
239 /* Find/display only the exact input name */
240
241 for (ThisName = PredefinedNames; ThisName->Info.Name[0]; ThisName++)
242 {
243 Matched = TRUE;
244 for (i = 0; i < ACPI_NAME_SIZE; i++)
245 {
246 if (ThisName->Info.Name[i] != Name[i])
247 {
248 Matched = FALSE;
249 break;
250 }
251 }
252
253 if (Matched)
254 {
255 AhGetExpectedTypes (Gbl_Buffer, ThisName->Info.ExpectedBtypes);
256
257 printf ("%*s%4.4s has %u arguments, returns: %s\n",
258 6, " ", ThisName->Info.Name, ThisName->Info.ParamCount,
259 ThisName->Info.ExpectedBtypes ? Gbl_Buffer : "-Nothing-");
260 return;
261 }
262
263 if (ThisName->Info.ExpectedBtypes & ACPI_RTYPE_PACKAGE)
264 {
265 ThisName++;
266 }
267 }
268 }
269
270
271 /*******************************************************************************
272 *
273 * FUNCTION: AhGetExpectedTypes
274 *
275 * PARAMETERS: Buffer - Where the formatted string is returned
276 * ExpectedBTypes - Bitfield of expected data types
277 *
278 * RETURN: Formatted string in Buffer.
279 *
280 * DESCRIPTION: Format the expected object types into a printable string.
281 *
282 ******************************************************************************/
283
284 static void
285 AhGetExpectedTypes (
286 char *Buffer,
287 UINT32 ExpectedBtypes)
288 {
289 UINT32 ThisRtype;
290 UINT32 i;
291 UINT32 j;
292
293
294 j = 1;
295 Buffer[0] = 0;
296 ThisRtype = ACPI_RTYPE_INTEGER;
297
298 for (i = 0; i < ACPI_NUM_RTYPES; i++)
299 {
300 /* If one of the expected types, concatenate the name of this type */
301
302 if (ExpectedBtypes & ThisRtype)
303 {
304 strcat (Buffer, &AcpiRtypeNames[i][j]);
305 j = 0; /* Use name separator from now on */
306 }
307 ThisRtype <<= 1; /* Next Rtype */
308 }
309 }
310
311
312 /*******************************************************************************
313 *
314 * FUNCTION: AhFindAmlOpcode (entry point for AML opcode name search)
315 *
316 * PARAMETERS: Name - Name or prefix for an AML opcode.
317 * NULL means "find all"
318 *
319 * RETURN: None
320 *
321 * DESCRIPTION: Find all AML opcodes that match the input Name or name
322 * prefix.
323 *
324 ******************************************************************************/
325
326 void
327 AhFindAmlOpcode (
328 char *Name)
329 {
330 const AH_AML_OPCODE *Op;
331 BOOLEAN Found = FALSE;
332
333
334 AhStrupr (Name);
335
336 /* Find/display all opcode names that match the input name prefix */
337
338 for (Op = AmlOpcodeInfo; Op->OpcodeString; Op++)
339 {
340 if (!Op->OpcodeName) /* Unused opcodes */
341 {
342 continue;
343 }
344
345 if (!Name)
346 {
347 AhDisplayAmlOpcode (Op);
348 Found = TRUE;
349 continue;
350 }
351
352 /* Upper case the opcode name before substring compare */
353
354 strcpy (Gbl_Buffer, Op->OpcodeName);
355 AhStrupr (Gbl_Buffer);
356
357 if (strstr (Gbl_Buffer, Name) == Gbl_Buffer)
358 {
359 AhDisplayAmlOpcode (Op);
360 Found = TRUE;
361 }
362 }
363
364 if (!Found)
365 {
366 printf ("%s, no matching AML operators\n", Name);
367 }
368 }
369
370
371 /*******************************************************************************
372 *
373 * FUNCTION: AhDecodeAmlOpcode (entry point for AML opcode search)
374 *
375 * PARAMETERS: OpcodeString - String version of AML opcode
376 *
377 * RETURN: None
378 *
379 * DESCRIPTION: Display information about the input AML opcode
380 *
381 ******************************************************************************/
382
383 void
384 AhDecodeAmlOpcode (
385 char *OpcodeString)
386 {
387 const AH_AML_OPCODE *Op;
388 UINT32 Opcode;
389 BOOLEAN Found = FALSE;
390 UINT8 Prefix;
391
392
393 if (!OpcodeString)
394 {
395 AhFindAmlOpcode (NULL);
396 return;
397 }
398
399 Opcode = ACPI_STRTOUL (OpcodeString, NULL, 16);
400 if (Opcode > ACPI_UINT16_MAX)
401 {
402 printf ("Invalid opcode (more than 16 bits)\n");
403 return;
404 }
405
406 /* Only valid opcode extension is 0x5B */
407
408 Prefix = (Opcode & 0x0000FF00) >> 8;
409 if (Prefix && (Prefix != 0x5B))
410 {
411 printf ("Invalid opcode (invalid extension prefix 0x%X)\n",
412 Prefix);
413 return;
414 }
415
416 /* Find/Display the opcode. May fall within an opcode range */
417
418 for (Op = AmlOpcodeInfo; Op->OpcodeString; Op++)
419 {
420 if ((Opcode >= Op->OpcodeRangeStart) &&
421 (Opcode <= Op->OpcodeRangeEnd))
422 {
423 AhDisplayAmlOpcode (Op);
424 Found = TRUE;
425 }
426 }
427 }
428
429
430 /*******************************************************************************
431 *
432 * FUNCTION: AhDisplayAmlOpcode
433 *
434 * PARAMETERS: Op - An opcode info struct
435 *
436 * RETURN: None
437 *
438 * DESCRIPTION: Display the contents of an AML opcode information struct
439 *
440 ******************************************************************************/
441
442 static void
443 AhDisplayAmlOpcode (
444 const AH_AML_OPCODE *Op)
445 {
446
447 if (!Op->OpcodeName)
448 {
449 printf ("%18s: Opcode=%-9s\n", "Reserved opcode", Op->OpcodeString);
450 return;
451 }
452
453 /* Opcode name and value(s) */
454
455 printf ("%18s: Opcode=%-9s Type (%s)",
456 Op->OpcodeName, Op->OpcodeString, Op->Type);
457
458 /* Optional fixed/static arguments */
459
460 if (Op->FixedArguments)
461 {
462 printf (" FixedArgs (");
463 AhPrintOneField (37, 36 + 7 + strlen (Op->Type) + 12,
464 AH_MAX_AML_LINE_LENGTH, Op->FixedArguments);
465 printf (")");
466 }
467
468 /* Optional variable-length argument list */
469
470 if (Op->VariableArguments)
471 {
472 if (Op->FixedArguments)
473 {
474 printf ("\n%*s", 36, " ");
475 }
476 printf (" VariableArgs (");
477 AhPrintOneField (37, 15, AH_MAX_AML_LINE_LENGTH, Op->VariableArguments);
478 printf (")");
479 }
480 printf ("\n");
481
482 /* Grammar specification */
483
484 if (Op->Grammar)
485 {
486 AhPrintOneField (37, 0, AH_MAX_AML_LINE_LENGTH, Op->Grammar);
487 printf ("\n");
488 }
489 }
490
491
492 /*******************************************************************************
493 *
494 * FUNCTION: AhFindAslKeywords (entry point for ASL keyword search)
495 *
496 * PARAMETERS: Name - Name or prefix for an ASL keyword.
497 * NULL means "find all"
498 *
499 * RETURN: None
500 *
501 * DESCRIPTION: Find all ASL keywords that match the input Name or name
502 * prefix.
503 *
504 ******************************************************************************/
505
506 void
507 AhFindAslKeywords (
508 char *Name)
509 {
510 const AH_ASL_KEYWORD *Keyword;
511 BOOLEAN Found = FALSE;
512
513
514 AhStrupr (Name);
515
516 for (Keyword = AslKeywordInfo; Keyword->Name; Keyword++)
517 {
518 if (!Name)
519 {
520 AhDisplayAslKeyword (Keyword);
521 Found = TRUE;
522 continue;
523 }
524
525 /* Upper case the operator name before substring compare */
526
527 strcpy (Gbl_Buffer, Keyword->Name);
528 AhStrupr (Gbl_Buffer);
529
530 if (strstr (Gbl_Buffer, Name) == Gbl_Buffer)
531 {
532 AhDisplayAslKeyword (Keyword);
533 Found = TRUE;
534 }
535 }
536
537 if (!Found)
538 {
539 printf ("%s, no matching ASL keywords\n", Name);
540 }
541 }
542
543
544 /*******************************************************************************
545 *
546 * FUNCTION: AhDisplayAslKeyword
547 *
548 * PARAMETERS: Op - Pointer to ASL keyword with syntax info
549 *
550 * RETURN: None
551 *
552 * DESCRIPTION: Format and display syntax info for an ASL keyword. Splits
553 * long lines appropriately for reading.
554 *
555 ******************************************************************************/
556
557 static void
558 AhDisplayAslKeyword (
559 const AH_ASL_KEYWORD *Op)
560 {
561
562 /* ASL keyword name and description */
563
564 printf ("%20s: %s\n", Op->Name, Op->Description);
565 if (!Op->KeywordList)
566 {
567 return;
568 }
569
570 /* List of actual keywords */
571
572 AhPrintOneField (22, 0, AH_MAX_ASL_LINE_LENGTH, Op->KeywordList);
573 printf ("\n");
574 }
575
576
577 /*******************************************************************************
578 *
579 * FUNCTION: AhFindAslOperators (entry point for ASL operator search)
580 *
581 * PARAMETERS: Name - Name or prefix for an ASL operator.
582 * NULL means "find all"
583 *
584 * RETURN: None
585 *
586 * DESCRIPTION: Find all ASL operators that match the input Name or name
587 * prefix.
588 *
589 ******************************************************************************/
590
591 void
592 AhFindAslOperators (
593 char *Name)
594 {
595 const AH_ASL_OPERATOR *Operator;
596 BOOLEAN Found = FALSE;
597
598
599 AhStrupr (Name);
600
601 /* Find/display all names that match the input name prefix */
602
603 for (Operator = AslOperatorInfo; Operator->Name; Operator++)
604 {
605 if (!Name)
606 {
607 AhDisplayAslOperator (Operator);
608 Found = TRUE;
609 continue;
610 }
611
612 /* Upper case the operator name before substring compare */
613
614 strcpy (Gbl_Buffer, Operator->Name);
615 AhStrupr (Gbl_Buffer);
616
617 if (strstr (Gbl_Buffer, Name) == Gbl_Buffer)
618 {
619 AhDisplayAslOperator (Operator);
620 Found = TRUE;
621 }
622 }
623
624 if (!Found)
625 {
626 printf ("%s, no matching ASL operators\n", Name);
627 }
628 }
629
630
631 /*******************************************************************************
632 *
633 * FUNCTION: AhDisplayAslOperator
634 *
635 * PARAMETERS: Op - Pointer to ASL operator with syntax info
636 *
637 * RETURN: None
638 *
639 * DESCRIPTION: Format and display syntax info for an ASL operator. Splits
640 * long lines appropriately for reading.
641 *
642 ******************************************************************************/
643
644 static void
645 AhDisplayAslOperator (
646 const AH_ASL_OPERATOR *Op)
647 {
648
649 /* ASL operator name and description */
650
651 printf ("%16s: %s\n", Op->Name, Op->Description);
652 if (!Op->Syntax)
653 {
654 return;
655 }
656
657 /* Syntax for the operator */
658
659 AhPrintOneField (18, 0, AH_MAX_ASL_LINE_LENGTH, Op->Syntax);
660 printf ("\n");
661 }
662
663
664 /*******************************************************************************
665 *
666 * FUNCTION: AhPrintOneField
667 *
668 * PARAMETERS: Indent - Indent length for new line(s)
669 * CurrentPosition - Position on current line
670 * MaxPosition - Max allowed line length
671 * Field - Data to output
672 *
673 * RETURN: Line position after field is written
674 *
675 * DESCRIPTION: Split long lines appropriately for ease of reading.
676 *
677 ******************************************************************************/
678
679 static void
680 AhPrintOneField (
681 UINT32 Indent,
682 UINT32 CurrentPosition,
683 UINT32 MaxPosition,
684 const char *Field)
685 {
686 UINT32 Position;
687 UINT32 TokenLength;
688 const char *This;
689 const char *Next;
690 const char *Last;
691
692
693 This = Field;
694 Position = CurrentPosition;
695
696 if (Position == 0)
697 {
698 printf ("%*s", (int) Indent, " ");
699 Position = Indent;
700 }
701
702 Last = This + strlen (This);
703 while ((Next = strpbrk (This, " ")))
704 {
705 TokenLength = Next - This;
706 Position += TokenLength;
707
708 /* Split long lines */
709
710 if (Position > MaxPosition)
711 {
712 printf ("\n%*s", (int) Indent, " ");
713 Position = TokenLength;
714 }
715
716 printf ("%.*s ", (int) TokenLength, This);
717 This = Next + 1;
718 }
719
720 /* Handle last token on the input line */
721
722 TokenLength = Last - This;
723 if (TokenLength > 0)
724 {
725 Position += TokenLength;
726 if (Position > MaxPosition)
727 {
728 printf ("\n%*s", (int) Indent, " ");
729 }
730 printf ("%s", This);
731 }
732 }
733