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