xref: /netbsd-src/sys/external/bsd/acpica/dist/tools/acpihelp/ahaml.c (revision 046a29855e04359424fd074e8313af6b6be8cfb6)
1 /******************************************************************************
2  *
3  * Module Name: ahaml - AML opcode decoding for acpihelp utility
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2023, 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 MERCHANTABILITY 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 
47 /* Local prototypes */
48 
49 static void
50 AhDisplayAmlOpcode (
51     const AH_AML_OPCODE     *Op);
52 
53 static void
54 AhDisplayAmlType (
55     const AH_AML_TYPE       *Op);
56 
57 
58 /*******************************************************************************
59  *
60  * FUNCTION:    AhFindAmlOpcode (entry point for AML opcode name search)
61  *
62  * PARAMETERS:  Name                - Name or prefix for an AML opcode.
63  *                                    NULL means "find all"
64  *
65  * RETURN:      None
66  *
67  * DESCRIPTION: Find all AML opcodes that match the input Name or name
68  *              prefix.
69  *
70  ******************************************************************************/
71 
72 void
AhFindAmlOpcode(char * Name)73 AhFindAmlOpcode (
74     char                    *Name)
75 {
76     const AH_AML_OPCODE     *Op;
77     BOOLEAN                 Found = FALSE;
78 
79 
80     AcpiUtStrupr (Name);
81 
82     /* Find/display all opcode names that match the input name prefix */
83 
84     for (Op = Gbl_AmlOpcodeInfo; Op->OpcodeString; Op++)
85     {
86         if (!Op->OpcodeName) /* Unused opcodes */
87         {
88             continue;
89         }
90 
91         if (!Name || (Name[0] == '*'))
92         {
93             AhDisplayAmlOpcode (Op);
94             Found = TRUE;
95             continue;
96         }
97 
98         /* Upper case the opcode name before substring compare */
99 
100         strcpy (Gbl_Buffer, Op->OpcodeName);
101         AcpiUtStrupr (Gbl_Buffer);
102 
103         if (strstr (Gbl_Buffer, Name) == Gbl_Buffer)
104         {
105             AhDisplayAmlOpcode (Op);
106             Found = TRUE;
107         }
108     }
109 
110     if (!Found && Name)
111     {
112         printf ("%s, no matching AML opcodes\n", Name);
113     }
114 }
115 
116 
117 /*******************************************************************************
118  *
119  * FUNCTION:    AhDecodeAmlOpcode (entry point for AML opcode search)
120  *
121  * PARAMETERS:  OpcodeString        - String version of AML opcode
122  *
123  * RETURN:      None
124  *
125  * DESCRIPTION: Display information about the input AML opcode
126  *
127  ******************************************************************************/
128 
129 void
AhDecodeAmlOpcode(char * OpcodeString)130 AhDecodeAmlOpcode (
131     char                    *OpcodeString)
132 {
133     const AH_AML_OPCODE     *Op;
134     UINT32                  Opcode;
135     UINT8                   Prefix;
136 
137 
138     if (!OpcodeString)
139     {
140         AhFindAmlOpcode (NULL);
141         return;
142     }
143 
144     Opcode = strtoul (OpcodeString, NULL, 16);
145     if (Opcode > ACPI_UINT16_MAX)
146     {
147         printf ("Invalid opcode (more than 16 bits)\n");
148         return;
149     }
150 
151     /* Only valid opcode extension is 0x5B */
152 
153     Prefix = (Opcode & 0x0000FF00) >> 8;
154     if (Prefix && (Prefix != 0x5B))
155     {
156         printf ("Invalid opcode (invalid extension prefix 0x%X)\n",
157             Prefix);
158         return;
159     }
160 
161     /* Find/Display the opcode. May fall within an opcode range */
162 
163     for (Op = Gbl_AmlOpcodeInfo; Op->OpcodeString; Op++)
164     {
165         if ((Opcode >= Op->OpcodeRangeStart) &&
166             (Opcode <= Op->OpcodeRangeEnd))
167         {
168             AhDisplayAmlOpcode (Op);
169         }
170     }
171 }
172 
173 
174 /*******************************************************************************
175  *
176  * FUNCTION:    AhDisplayAmlOpcode
177  *
178  * PARAMETERS:  Op                  - An opcode info struct
179  *
180  * RETURN:      None
181  *
182  * DESCRIPTION: Display the contents of an AML opcode information struct
183  *
184  ******************************************************************************/
185 
186 static void
AhDisplayAmlOpcode(const AH_AML_OPCODE * Op)187 AhDisplayAmlOpcode (
188     const AH_AML_OPCODE     *Op)
189 {
190 
191     if (!Op->OpcodeName)
192     {
193         printf ("%18s: Opcode=%-9s\n", "Reserved opcode", Op->OpcodeString);
194         return;
195     }
196 
197     /* Opcode name and value(s) */
198 
199     printf ("%18s: Opcode=%-9s Type (%s)",
200         Op->OpcodeName, Op->OpcodeString, Op->Type);
201 
202     /* Optional fixed/static arguments */
203 
204     if (Op->FixedArguments)
205     {
206         printf (" FixedArgs (");
207         AhPrintOneField (37, 36 + 7 + strlen (Op->Type) + 12,
208             AH_MAX_AML_LINE_LENGTH, Op->FixedArguments);
209         printf (")");
210     }
211 
212     /* Optional variable-length argument list */
213 
214     if (Op->VariableArguments)
215     {
216         if (Op->FixedArguments)
217         {
218             printf ("\n%*s", 36, " ");
219         }
220         printf (" VariableArgs (");
221         AhPrintOneField (37, 15, AH_MAX_AML_LINE_LENGTH, Op->VariableArguments);
222         printf (")");
223     }
224     printf ("\n");
225 
226     /* Grammar specification */
227 
228     if (Op->Grammar)
229     {
230         AhPrintOneField (37, 0, AH_MAX_AML_LINE_LENGTH, Op->Grammar);
231         printf ("\n");
232     }
233 }
234 
235 
236 /*******************************************************************************
237  *
238  * FUNCTION:    AhFindAmlTypes (entry point for AML grammar keyword search)
239  *
240  * PARAMETERS:  Name                - Name or prefix for an AML grammar element.
241  *                                    NULL means "find all"
242  *
243  * RETURN:      None
244  *
245  * DESCRIPTION: Find all AML grammar keywords that match the input Name or name
246  *              prefix.
247  *
248  ******************************************************************************/
249 
250 void
AhFindAmlTypes(char * Name)251 AhFindAmlTypes (
252     char                    *Name)
253 {
254     const AH_AML_TYPE       *Keyword;
255     BOOLEAN                 Found = FALSE;
256 
257 
258     AcpiUtStrupr (Name);
259 
260     for (Keyword = Gbl_AmlTypesInfo; Keyword->Name; Keyword++)
261     {
262         if (!Name)
263         {
264             printf ("    %s\n", Keyword->Name);
265             Found = TRUE;
266             continue;
267         }
268 
269         if (*Name == '*')
270         {
271             AhDisplayAmlType (Keyword);
272             Found = TRUE;
273             continue;
274         }
275 
276         /* Upper case the operator name before substring compare */
277 
278         strcpy (Gbl_Buffer, Keyword->Name);
279         AcpiUtStrupr (Gbl_Buffer);
280 
281         if (strstr (Gbl_Buffer, Name) == Gbl_Buffer)
282         {
283             AhDisplayAmlType (Keyword);
284             Found = TRUE;
285         }
286     }
287 
288     if (!Found)
289     {
290         printf ("%s, no matching AML grammar type\n", Name);
291     }
292 }
293 
294 
295 /*******************************************************************************
296  *
297  * FUNCTION:    AhDisplayAmlType
298  *
299  * PARAMETERS:  Op                  - Pointer to AML grammar info
300  *
301  * RETURN:      None
302  *
303  * DESCRIPTION: Format and display info for an AML grammar element.
304  *
305  ******************************************************************************/
306 
307 static void
AhDisplayAmlType(const AH_AML_TYPE * Op)308 AhDisplayAmlType (
309     const AH_AML_TYPE       *Op)
310 {
311     char                    *Description;
312 
313 
314     Description = Op->Description;
315     printf ("%4s", " ");    /* Primary indent */
316 
317     /* Emit the entire description string */
318 
319     while (*Description)
320     {
321         /* Description can be multiple lines, must indent each */
322 
323         while (*Description != '\n')
324         {
325             printf ("%c", *Description);
326             Description++;
327         }
328 
329         printf ("\n");
330         Description++;
331 
332         /* Do indent */
333 
334         if (*Description)
335         {
336             printf ("%8s", " ");    /* Secondary indent */
337 
338             /* Index extra for a comment */
339 
340             if ((Description[0] == '/') &&
341                 (Description[1] == '/'))
342             {
343                 printf ("%4s", " ");
344             }
345         }
346     }
347 
348     printf ("\n");
349 }
350