xref: /netbsd-src/sys/external/bsd/acpica/dist/compiler/cvdisasm.c (revision 046a29855e04359424fd074e8313af6b6be8cfb6)
1 /******************************************************************************
2  *
3  * Module Name: cvcompiler - ASL-/ASL+ converter functions
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 "aslcompiler.h"
45 #include "acparser.h"
46 #include "amlcode.h"
47 #include "acdebug.h"
48 #include "acconvert.h"
49 
50 
51 /* Local prototypes */
52 
53 static void
54 CvPrintInclude(
55     ACPI_FILE_NODE          *FNode,
56     UINT32                  Level);
57 
58 static BOOLEAN
59 CvListIsSingleton (
60     ACPI_COMMENT_NODE       *CommentList);
61 
62 
63 /*******************************************************************************
64  *
65  * FUNCTION:    CvPrintOneCommentList
66  *
67  * PARAMETERS:  CommentList
68  *              Level
69  *
70  * RETURN:      None
71  *
72  * DESCRIPTION: Prints all comments within the given list.
73  *              This is referred as ASL_CV_PRINT_ONE_COMMENT_LIST.
74  *
75  ******************************************************************************/
76 
77 void
CvPrintOneCommentList(ACPI_COMMENT_NODE * CommentList,UINT32 Level)78 CvPrintOneCommentList (
79     ACPI_COMMENT_NODE       *CommentList,
80     UINT32                  Level)
81 {
82     ACPI_COMMENT_NODE       *Current = CommentList;
83     ACPI_COMMENT_NODE       *Previous;
84 
85 
86     while (Current)
87     {
88         Previous = Current;
89         if (Current->Comment)
90         {
91             AcpiDmIndent(Level);
92             AcpiOsPrintf("%s\n", Current->Comment);
93             Current->Comment = NULL;
94         }
95 
96         Current = Current->Next;
97         AcpiOsReleaseObject(AcpiGbl_RegCommentCache, Previous);
98     }
99 }
100 
101 
102 /*******************************************************************************
103  *
104  * FUNCTION:    CvListIsSingleton
105  *
106  * PARAMETERS:  CommentList     - check to see if this is a single item list.
107  *
108  * RETURN:      BOOLEAN
109  *
110  * DESCRIPTION: Returns TRUE if CommentList only contains 1 node.
111  *
112  ******************************************************************************/
113 
114 static BOOLEAN
CvListIsSingleton(ACPI_COMMENT_NODE * CommentList)115 CvListIsSingleton (
116     ACPI_COMMENT_NODE       *CommentList)
117 
118 {
119 
120     if (!CommentList)
121     {
122         return (FALSE);
123     }
124     else if (CommentList->Next)
125     {
126         return (FALSE);
127     }
128 
129     return (TRUE);
130 }
131 
132 
133 /*******************************************************************************
134  *
135  * FUNCTION:    CvPrintOneCommentType
136  *
137  * PARAMETERS:  Op
138  *              CommentType
139  *              EndStr - String to print after printing the comment
140  *              Level  - indentation level for comment lists.
141  *
142  * RETURN:      None
143  *
144  * DESCRIPTION: Prints all comments of CommentType within the given Op and
145  *              clears the printed comment from the Op.
146  *              This is referred as ASL_CV_PRINT_ONE_COMMENT.
147  *
148  ******************************************************************************/
149 
150 void
CvPrintOneCommentType(ACPI_PARSE_OBJECT * Op,UINT8 CommentType,char * EndStr,UINT32 Level)151 CvPrintOneCommentType (
152     ACPI_PARSE_OBJECT       *Op,
153     UINT8                   CommentType,
154     char*                   EndStr,
155     UINT32                  Level)
156 {
157     BOOLEAN                 CommentExists = FALSE;
158     char                    **CommentToPrint = NULL;
159 
160 
161     switch (CommentType)
162     {
163     case AML_COMMENT_STANDARD:
164 
165         if (CvListIsSingleton (Op->Common.CommentList))
166         {
167             CvPrintOneCommentList (Op->Common.CommentList, Level);
168             AcpiOsPrintf ("\n");
169         }
170         else
171         {
172             CvPrintOneCommentList (Op->Common.CommentList, Level);
173         }
174 
175         Op->Common.CommentList = NULL;
176         return;
177 
178     case AML_COMMENT_ENDBLK:
179 
180         if (Op->Common.EndBlkComment)
181         {
182             CvPrintOneCommentList (Op->Common.EndBlkComment, Level);
183             Op->Common.EndBlkComment = NULL;
184             AcpiDmIndent(Level);
185         }
186         return;
187 
188     case AMLCOMMENT_INLINE:
189 
190         CommentToPrint = &Op->Common.InlineComment;
191         break;
192 
193     case AML_COMMENT_END_NODE:
194 
195         CommentToPrint = &Op->Common.EndNodeComment;
196         break;
197 
198     case AML_NAMECOMMENT:
199 
200         CommentToPrint = &Op->Common.NameComment;
201         break;
202 
203     case AML_COMMENT_CLOSE_BRACE:
204 
205         CommentToPrint = &Op->Common.CloseBraceComment;
206         break;
207 
208     default:
209         return;
210     }
211 
212     if (*CommentToPrint)
213     {
214         CommentExists = TRUE;
215         AcpiOsPrintf ("%s", *CommentToPrint);
216         *CommentToPrint = NULL;
217     }
218 
219     if (CommentExists && EndStr)
220     {
221         AcpiOsPrintf ("%s", EndStr);
222     }
223 }
224 
225 
226 /*******************************************************************************
227  *
228  * FUNCTION:    CvCloseBraceWriteComment
229  *
230  * PARAMETERS:  Op
231  *              Level
232  *
233  * RETURN:      None
234  *
235  * DESCRIPTION: Print a close brace } and any open brace comments associated
236  *              with this parse object.
237  *              This is referred as ASL_CV_CLOSE_BRACE.
238  *
239  ******************************************************************************/
240 
241 void
CvCloseBraceWriteComment(ACPI_PARSE_OBJECT * Op,UINT32 Level)242 CvCloseBraceWriteComment(
243     ACPI_PARSE_OBJECT       *Op,
244     UINT32                  Level)
245 {
246 
247     if (!AcpiGbl_CaptureComments)
248     {
249         AcpiOsPrintf ("}");
250         return;
251     }
252 
253     CvPrintOneCommentType (Op, AML_COMMENT_ENDBLK, NULL, Level);
254     AcpiOsPrintf ("}");
255     CvPrintOneCommentType (Op, AML_COMMENT_CLOSE_BRACE, NULL, Level);
256 }
257 
258 
259 /*******************************************************************************
260  *
261  * FUNCTION:    CvCloseParenWriteComment
262  *
263  * PARAMETERS:  Op
264  *              Level
265  *
266  * RETURN:      None
267  *
268  * DESCRIPTION: Print a closing paren ) and any end node comments associated
269  *              with this parse object.
270  *              This is referred as ASL_CV_CLOSE_PAREN.
271  *
272  ******************************************************************************/
273 
274 void
CvCloseParenWriteComment(ACPI_PARSE_OBJECT * Op,UINT32 Level)275 CvCloseParenWriteComment(
276     ACPI_PARSE_OBJECT       *Op,
277     UINT32                  Level)
278 {
279 
280     if (!AcpiGbl_CaptureComments)
281     {
282         AcpiOsPrintf (")");
283         return;
284     }
285 
286     /*
287      * If this op has a BLOCK_BRACE, then output the comment when the
288      * disassembler calls CvCloseBraceWriteComment
289      */
290     if (AcpiDmBlockType (Op) == BLOCK_PAREN)
291     {
292         CvPrintOneCommentType (Op, AML_COMMENT_ENDBLK, NULL, Level);
293     }
294 
295     AcpiOsPrintf (")");
296 
297     if (Op->Common.EndNodeComment)
298     {
299         CvPrintOneCommentType (Op, AML_COMMENT_END_NODE, NULL, Level);
300     }
301     else if ((Op->Common.Parent->Common.AmlOpcode == AML_IF_OP) &&
302          Op->Common.Parent->Common.EndNodeComment)
303     {
304         CvPrintOneCommentType (Op->Common.Parent,
305             AML_COMMENT_END_NODE, NULL, Level);
306     }
307 }
308 
309 
310 /*******************************************************************************
311  *
312  * FUNCTION:    CvFileHasSwitched
313  *
314  * PARAMETERS:  Op
315  *
316  * RETURN:      BOOLEAN
317  *
318  * DESCRIPTION: Determine whether if a file has switched.
319  *              TRUE - file has switched.
320  *              FALSE - file has not switched.
321  *              This is referred as ASL_CV_FILE_HAS_SWITCHED.
322  *
323  ******************************************************************************/
324 
325 BOOLEAN
CvFileHasSwitched(ACPI_PARSE_OBJECT * Op)326 CvFileHasSwitched(
327     ACPI_PARSE_OBJECT       *Op)
328 {
329 
330     if (Op->Common.CvFilename   &&
331         AcpiGbl_CurrentFilename &&
332         AcpiUtStricmp(Op->Common.CvFilename, AcpiGbl_CurrentFilename))
333     {
334         return (TRUE);
335     }
336 
337     return (FALSE);
338 }
339 
340 
341 /*******************************************************************************
342  *
343  * FUNCTION:    CvPrintInclude
344  *
345  * PARAMETERS:  FNode - Write an Include statement for the file that is pointed
346  *                      by FNode->File.
347  *              Level - indentation level
348  *
349  * RETURN:      None
350  *
351  * DESCRIPTION: Write the ASL Include statement for FNode->File in the file
352  *              indicated by FNode->Parent->File. Note this function emits
353  *              actual ASL code rather than comments. This switches the output
354  *              file to FNode->Parent->File.
355  *
356  ******************************************************************************/
357 
358 static void
CvPrintInclude(ACPI_FILE_NODE * FNode,UINT32 Level)359 CvPrintInclude(
360     ACPI_FILE_NODE          *FNode,
361     UINT32                  Level)
362 {
363 
364     if (!FNode || FNode->IncludeWritten)
365     {
366         return;
367     }
368 
369     CvDbgPrint ("Writing include for %s within %s\n",
370         FNode->Filename, FNode->Parent->Filename);
371     AcpiOsRedirectOutput (FNode->Parent->File);
372     CvPrintOneCommentList (FNode->IncludeComment, Level);
373 
374     AcpiDmIndent (Level);
375     AcpiOsPrintf ("Include (\"%s\")\n", FNode->Filename);
376     CvDbgPrint ("emitted the following: Include (\"%s\")\n",
377         FNode->Filename);
378     FNode->IncludeWritten = TRUE;
379 }
380 
381 
382 /*******************************************************************************
383  *
384  * FUNCTION:    CvSwitchFiles
385  *
386  * PARAMETERS:  Level                   - indentation level
387  *              Op
388  *
389  * RETURN:      None
390  *
391  * DESCRIPTION: Switch the outputfile and write ASL Include statement. Note,
392  *              this function emits actual ASL code rather than comments.
393  *              This is referred as ASL_CV_SWITCH_FILES.
394  *
395  ******************************************************************************/
396 
397 void
CvSwitchFiles(UINT32 Level,ACPI_PARSE_OBJECT * Op)398 CvSwitchFiles(
399     UINT32                  Level,
400     ACPI_PARSE_OBJECT       *Op)
401 {
402     char                    *Filename = Op->Common.CvFilename;
403     ACPI_FILE_NODE          *FNode;
404     ACPI_FILE_NODE          *Current;
405 
406 
407     CvDbgPrint ("Switching from %s to %s\n", AcpiGbl_CurrentFilename,
408         Filename);
409     FNode = CvFilenameExists (Filename, AcpiGbl_FileTreeRoot);
410     if (!FNode)
411     {
412         /*
413          * At this point, each Filename should exist in AcpiGbl_FileTreeRoot
414          * if it does not exist, then abort.
415          */
416         FlDeleteFile (ASL_FILE_AML_OUTPUT);
417         sprintf (AslGbl_MsgBuffer, "\"Cannot find %s\" - %s",
418             Filename, strerror (errno));
419         AslCommonError (ASL_ERROR, ASL_MSG_OPEN, 0, 0, 0, 0,
420             NULL, AslGbl_MsgBuffer);
421         AslAbort ();
422     }
423 
424     Current = FNode;
425 
426     /*
427      * If the previous file is a descendent of the current file,
428      * make sure that Include statements from the current file
429      * to the previous have been emitted.
430      */
431     while (Current &&
432            Current->Parent &&
433            AcpiUtStricmp (Current->Filename, AcpiGbl_CurrentFilename))
434     {
435         CvPrintInclude (Current, Level);
436         Current = Current->Parent;
437     }
438 
439     if (FNode)
440     {
441         /* Redirect output to Op->Common.CvFilename */
442 
443         AcpiOsRedirectOutput (FNode->File);
444         AcpiGbl_CurrentFilename = FNode->Filename;
445     }
446 }
447