xref: /netbsd-src/sys/external/bsd/acpica/dist/compiler/cvdisasm.c (revision 046a29855e04359424fd074e8313af6b6be8cfb6)
1835858a6Schristos /******************************************************************************
2835858a6Schristos  *
3835858a6Schristos  * Module Name: cvcompiler - ASL-/ASL+ converter functions
4835858a6Schristos  *
5835858a6Schristos  *****************************************************************************/
6835858a6Schristos 
7835858a6Schristos /*
8*046a2985Schristos  * Copyright (C) 2000 - 2023, Intel Corp.
9835858a6Schristos  * All rights reserved.
10835858a6Schristos  *
11835858a6Schristos  * Redistribution and use in source and binary forms, with or without
12835858a6Schristos  * modification, are permitted provided that the following conditions
13835858a6Schristos  * are met:
14835858a6Schristos  * 1. Redistributions of source code must retain the above copyright
15835858a6Schristos  *    notice, this list of conditions, and the following disclaimer,
16835858a6Schristos  *    without modification.
17835858a6Schristos  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18835858a6Schristos  *    substantially similar to the "NO WARRANTY" disclaimer below
19835858a6Schristos  *    ("Disclaimer") and any redistribution must be conditioned upon
20835858a6Schristos  *    including a substantially similar Disclaimer requirement for further
21835858a6Schristos  *    binary redistribution.
22835858a6Schristos  * 3. Neither the names of the above-listed copyright holders nor the names
23835858a6Schristos  *    of any contributors may be used to endorse or promote products derived
24835858a6Schristos  *    from this software without specific prior written permission.
25835858a6Schristos  *
26835858a6Schristos  * Alternatively, this software may be distributed under the terms of the
27835858a6Schristos  * GNU General Public License ("GPL") version 2 as published by the Free
28835858a6Schristos  * Software Foundation.
29835858a6Schristos  *
30835858a6Schristos  * NO WARRANTY
31835858a6Schristos  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32835858a6Schristos  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3346a330b4Schristos  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34835858a6Schristos  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35835858a6Schristos  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36835858a6Schristos  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37835858a6Schristos  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38835858a6Schristos  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39835858a6Schristos  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40835858a6Schristos  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41835858a6Schristos  * POSSIBILITY OF SUCH DAMAGES.
42835858a6Schristos  */
43835858a6Schristos 
44835858a6Schristos #include "aslcompiler.h"
45835858a6Schristos #include "acparser.h"
46835858a6Schristos #include "amlcode.h"
47835858a6Schristos #include "acdebug.h"
48835858a6Schristos #include "acconvert.h"
49835858a6Schristos 
50835858a6Schristos 
5189b8eb6cSchristos /* Local prototypes */
5289b8eb6cSchristos 
53835858a6Schristos static void
54835858a6Schristos CvPrintInclude(
55835858a6Schristos     ACPI_FILE_NODE          *FNode,
56835858a6Schristos     UINT32                  Level);
57835858a6Schristos 
58835858a6Schristos static BOOLEAN
59835858a6Schristos CvListIsSingleton (
60835858a6Schristos     ACPI_COMMENT_NODE       *CommentList);
61835858a6Schristos 
62835858a6Schristos 
63835858a6Schristos /*******************************************************************************
64835858a6Schristos  *
65835858a6Schristos  * FUNCTION:    CvPrintOneCommentList
66835858a6Schristos  *
67835858a6Schristos  * PARAMETERS:  CommentList
68835858a6Schristos  *              Level
69835858a6Schristos  *
70835858a6Schristos  * RETURN:      None
71835858a6Schristos  *
72835858a6Schristos  * DESCRIPTION: Prints all comments within the given list.
73835858a6Schristos  *              This is referred as ASL_CV_PRINT_ONE_COMMENT_LIST.
74835858a6Schristos  *
75835858a6Schristos  ******************************************************************************/
76835858a6Schristos 
77835858a6Schristos void
CvPrintOneCommentList(ACPI_COMMENT_NODE * CommentList,UINT32 Level)78835858a6Schristos CvPrintOneCommentList (
79835858a6Schristos     ACPI_COMMENT_NODE       *CommentList,
80835858a6Schristos     UINT32                  Level)
81835858a6Schristos {
82835858a6Schristos     ACPI_COMMENT_NODE       *Current = CommentList;
83835858a6Schristos     ACPI_COMMENT_NODE       *Previous;
84835858a6Schristos 
85835858a6Schristos 
86835858a6Schristos     while (Current)
87835858a6Schristos     {
88835858a6Schristos         Previous = Current;
89835858a6Schristos         if (Current->Comment)
90835858a6Schristos         {
91835858a6Schristos             AcpiDmIndent(Level);
92835858a6Schristos             AcpiOsPrintf("%s\n", Current->Comment);
93835858a6Schristos             Current->Comment = NULL;
94835858a6Schristos         }
9589b8eb6cSchristos 
96835858a6Schristos         Current = Current->Next;
97835858a6Schristos         AcpiOsReleaseObject(AcpiGbl_RegCommentCache, Previous);
98835858a6Schristos     }
99835858a6Schristos }
100835858a6Schristos 
101835858a6Schristos 
102835858a6Schristos /*******************************************************************************
103835858a6Schristos  *
104835858a6Schristos  * FUNCTION:    CvListIsSingleton
105835858a6Schristos  *
10689b8eb6cSchristos  * PARAMETERS:  CommentList     - check to see if this is a single item list.
107835858a6Schristos  *
108835858a6Schristos  * RETURN:      BOOLEAN
109835858a6Schristos  *
110835858a6Schristos  * DESCRIPTION: Returns TRUE if CommentList only contains 1 node.
111835858a6Schristos  *
112835858a6Schristos  ******************************************************************************/
113835858a6Schristos 
114835858a6Schristos static BOOLEAN
CvListIsSingleton(ACPI_COMMENT_NODE * CommentList)115835858a6Schristos CvListIsSingleton (
116835858a6Schristos     ACPI_COMMENT_NODE       *CommentList)
117835858a6Schristos 
118835858a6Schristos {
11989b8eb6cSchristos 
120835858a6Schristos     if (!CommentList)
121835858a6Schristos     {
12289b8eb6cSchristos         return (FALSE);
123835858a6Schristos     }
124835858a6Schristos     else if (CommentList->Next)
125835858a6Schristos     {
12689b8eb6cSchristos         return (FALSE);
127835858a6Schristos     }
128835858a6Schristos 
12989b8eb6cSchristos     return (TRUE);
130835858a6Schristos }
131835858a6Schristos 
132835858a6Schristos 
133835858a6Schristos /*******************************************************************************
134835858a6Schristos  *
135835858a6Schristos  * FUNCTION:    CvPrintOneCommentType
136835858a6Schristos  *
137835858a6Schristos  * PARAMETERS:  Op
138835858a6Schristos  *              CommentType
139835858a6Schristos  *              EndStr - String to print after printing the comment
140835858a6Schristos  *              Level  - indentation level for comment lists.
141835858a6Schristos  *
142835858a6Schristos  * RETURN:      None
143835858a6Schristos  *
144835858a6Schristos  * DESCRIPTION: Prints all comments of CommentType within the given Op and
145835858a6Schristos  *              clears the printed comment from the Op.
146835858a6Schristos  *              This is referred as ASL_CV_PRINT_ONE_COMMENT.
147835858a6Schristos  *
148835858a6Schristos  ******************************************************************************/
149835858a6Schristos 
150835858a6Schristos void
CvPrintOneCommentType(ACPI_PARSE_OBJECT * Op,UINT8 CommentType,char * EndStr,UINT32 Level)151835858a6Schristos CvPrintOneCommentType (
152835858a6Schristos     ACPI_PARSE_OBJECT       *Op,
153835858a6Schristos     UINT8                   CommentType,
154835858a6Schristos     char*                   EndStr,
155835858a6Schristos     UINT32                  Level)
156835858a6Schristos {
157835858a6Schristos     BOOLEAN                 CommentExists = FALSE;
158835858a6Schristos     char                    **CommentToPrint = NULL;
159835858a6Schristos 
160835858a6Schristos 
161835858a6Schristos     switch (CommentType)
162835858a6Schristos     {
163835858a6Schristos     case AML_COMMENT_STANDARD:
164835858a6Schristos 
165835858a6Schristos         if (CvListIsSingleton (Op->Common.CommentList))
166835858a6Schristos         {
167835858a6Schristos             CvPrintOneCommentList (Op->Common.CommentList, Level);
168835858a6Schristos             AcpiOsPrintf ("\n");
169835858a6Schristos         }
170835858a6Schristos         else
171835858a6Schristos         {
172835858a6Schristos             CvPrintOneCommentList (Op->Common.CommentList, Level);
173835858a6Schristos         }
17489b8eb6cSchristos 
175835858a6Schristos         Op->Common.CommentList = NULL;
176835858a6Schristos         return;
177835858a6Schristos 
178835858a6Schristos     case AML_COMMENT_ENDBLK:
179835858a6Schristos 
180835858a6Schristos         if (Op->Common.EndBlkComment)
181835858a6Schristos         {
182835858a6Schristos             CvPrintOneCommentList (Op->Common.EndBlkComment, Level);
183835858a6Schristos             Op->Common.EndBlkComment = NULL;
184835858a6Schristos             AcpiDmIndent(Level);
185835858a6Schristos         }
186835858a6Schristos         return;
187835858a6Schristos 
188835858a6Schristos     case AMLCOMMENT_INLINE:
189835858a6Schristos 
190835858a6Schristos         CommentToPrint = &Op->Common.InlineComment;
191835858a6Schristos         break;
192835858a6Schristos 
193835858a6Schristos     case AML_COMMENT_END_NODE:
194835858a6Schristos 
195835858a6Schristos         CommentToPrint = &Op->Common.EndNodeComment;
196835858a6Schristos         break;
197835858a6Schristos 
198835858a6Schristos     case AML_NAMECOMMENT:
199835858a6Schristos 
200835858a6Schristos         CommentToPrint = &Op->Common.NameComment;
201835858a6Schristos         break;
202835858a6Schristos 
203835858a6Schristos     case AML_COMMENT_CLOSE_BRACE:
204835858a6Schristos 
205835858a6Schristos         CommentToPrint = &Op->Common.CloseBraceComment;
206835858a6Schristos         break;
207835858a6Schristos 
208835858a6Schristos     default:
209835858a6Schristos         return;
210835858a6Schristos     }
211835858a6Schristos 
212835858a6Schristos     if (*CommentToPrint)
213835858a6Schristos     {
21489b8eb6cSchristos         CommentExists = TRUE;
215835858a6Schristos         AcpiOsPrintf ("%s", *CommentToPrint);
216835858a6Schristos         *CommentToPrint = NULL;
217835858a6Schristos     }
218835858a6Schristos 
219835858a6Schristos     if (CommentExists && EndStr)
220835858a6Schristos     {
221835858a6Schristos         AcpiOsPrintf ("%s", EndStr);
222835858a6Schristos     }
223835858a6Schristos }
224835858a6Schristos 
225835858a6Schristos 
226835858a6Schristos /*******************************************************************************
227835858a6Schristos  *
228835858a6Schristos  * FUNCTION:    CvCloseBraceWriteComment
229835858a6Schristos  *
230835858a6Schristos  * PARAMETERS:  Op
231835858a6Schristos  *              Level
232835858a6Schristos  *
23389b8eb6cSchristos  * RETURN:      None
234835858a6Schristos  *
235835858a6Schristos  * DESCRIPTION: Print a close brace } and any open brace comments associated
236835858a6Schristos  *              with this parse object.
237835858a6Schristos  *              This is referred as ASL_CV_CLOSE_BRACE.
238835858a6Schristos  *
239835858a6Schristos  ******************************************************************************/
240835858a6Schristos 
241835858a6Schristos void
CvCloseBraceWriteComment(ACPI_PARSE_OBJECT * Op,UINT32 Level)242835858a6Schristos CvCloseBraceWriteComment(
243835858a6Schristos     ACPI_PARSE_OBJECT       *Op,
244835858a6Schristos     UINT32                  Level)
245835858a6Schristos {
24689b8eb6cSchristos 
247062782b3Schristos     if (!AcpiGbl_CaptureComments)
248835858a6Schristos     {
249835858a6Schristos         AcpiOsPrintf ("}");
250835858a6Schristos         return;
251835858a6Schristos     }
252835858a6Schristos 
253835858a6Schristos     CvPrintOneCommentType (Op, AML_COMMENT_ENDBLK, NULL, Level);
254835858a6Schristos     AcpiOsPrintf ("}");
255835858a6Schristos     CvPrintOneCommentType (Op, AML_COMMENT_CLOSE_BRACE, NULL, Level);
256835858a6Schristos }
257835858a6Schristos 
258835858a6Schristos 
259835858a6Schristos /*******************************************************************************
260835858a6Schristos  *
261835858a6Schristos  * FUNCTION:    CvCloseParenWriteComment
262835858a6Schristos  *
263835858a6Schristos  * PARAMETERS:  Op
264835858a6Schristos  *              Level
265835858a6Schristos  *
26689b8eb6cSchristos  * RETURN:      None
267835858a6Schristos  *
268835858a6Schristos  * DESCRIPTION: Print a closing paren ) and any end node comments associated
269835858a6Schristos  *              with this parse object.
270835858a6Schristos  *              This is referred as ASL_CV_CLOSE_PAREN.
271835858a6Schristos  *
272835858a6Schristos  ******************************************************************************/
273835858a6Schristos 
274835858a6Schristos void
CvCloseParenWriteComment(ACPI_PARSE_OBJECT * Op,UINT32 Level)275835858a6Schristos CvCloseParenWriteComment(
276835858a6Schristos     ACPI_PARSE_OBJECT       *Op,
277835858a6Schristos     UINT32                  Level)
278835858a6Schristos {
27989b8eb6cSchristos 
280062782b3Schristos     if (!AcpiGbl_CaptureComments)
281835858a6Schristos     {
282835858a6Schristos         AcpiOsPrintf (")");
283835858a6Schristos         return;
284835858a6Schristos     }
285835858a6Schristos 
286835858a6Schristos     /*
287835858a6Schristos      * If this op has a BLOCK_BRACE, then output the comment when the
288835858a6Schristos      * disassembler calls CvCloseBraceWriteComment
289835858a6Schristos      */
290835858a6Schristos     if (AcpiDmBlockType (Op) == BLOCK_PAREN)
291835858a6Schristos     {
292835858a6Schristos         CvPrintOneCommentType (Op, AML_COMMENT_ENDBLK, NULL, Level);
293835858a6Schristos     }
294835858a6Schristos 
295835858a6Schristos     AcpiOsPrintf (")");
296835858a6Schristos 
297835858a6Schristos     if (Op->Common.EndNodeComment)
298835858a6Schristos     {
299835858a6Schristos         CvPrintOneCommentType (Op, AML_COMMENT_END_NODE, NULL, Level);
300835858a6Schristos     }
301835858a6Schristos     else if ((Op->Common.Parent->Common.AmlOpcode == AML_IF_OP) &&
302835858a6Schristos          Op->Common.Parent->Common.EndNodeComment)
303835858a6Schristos     {
304835858a6Schristos         CvPrintOneCommentType (Op->Common.Parent,
305835858a6Schristos             AML_COMMENT_END_NODE, NULL, Level);
306835858a6Schristos     }
307835858a6Schristos }
308835858a6Schristos 
309835858a6Schristos 
310835858a6Schristos /*******************************************************************************
311835858a6Schristos  *
312835858a6Schristos  * FUNCTION:    CvFileHasSwitched
313835858a6Schristos  *
314835858a6Schristos  * PARAMETERS:  Op
315835858a6Schristos  *
316835858a6Schristos  * RETURN:      BOOLEAN
317835858a6Schristos  *
318835858a6Schristos  * DESCRIPTION: Determine whether if a file has switched.
319835858a6Schristos  *              TRUE - file has switched.
320835858a6Schristos  *              FALSE - file has not switched.
321835858a6Schristos  *              This is referred as ASL_CV_FILE_HAS_SWITCHED.
322835858a6Schristos  *
323835858a6Schristos  ******************************************************************************/
324835858a6Schristos 
325835858a6Schristos BOOLEAN
CvFileHasSwitched(ACPI_PARSE_OBJECT * Op)326835858a6Schristos CvFileHasSwitched(
327835858a6Schristos     ACPI_PARSE_OBJECT       *Op)
328835858a6Schristos {
32989b8eb6cSchristos 
330835858a6Schristos     if (Op->Common.CvFilename   &&
331835858a6Schristos         AcpiGbl_CurrentFilename &&
332835858a6Schristos         AcpiUtStricmp(Op->Common.CvFilename, AcpiGbl_CurrentFilename))
333835858a6Schristos     {
33489b8eb6cSchristos         return (TRUE);
335835858a6Schristos     }
33689b8eb6cSchristos 
33789b8eb6cSchristos     return (FALSE);
338835858a6Schristos }
339835858a6Schristos 
340835858a6Schristos 
341835858a6Schristos /*******************************************************************************
342835858a6Schristos  *
343835858a6Schristos  * FUNCTION:    CvPrintInclude
344835858a6Schristos  *
345835858a6Schristos  * PARAMETERS:  FNode - Write an Include statement for the file that is pointed
346835858a6Schristos  *                      by FNode->File.
347835858a6Schristos  *              Level - indentation level
348835858a6Schristos  *
349835858a6Schristos  * RETURN:      None
350835858a6Schristos  *
351835858a6Schristos  * DESCRIPTION: Write the ASL Include statement for FNode->File in the file
352835858a6Schristos  *              indicated by FNode->Parent->File. Note this function emits
353835858a6Schristos  *              actual ASL code rather than comments. This switches the output
354835858a6Schristos  *              file to FNode->Parent->File.
355835858a6Schristos  *
356835858a6Schristos  ******************************************************************************/
357835858a6Schristos 
358835858a6Schristos static void
CvPrintInclude(ACPI_FILE_NODE * FNode,UINT32 Level)359835858a6Schristos CvPrintInclude(
360835858a6Schristos     ACPI_FILE_NODE          *FNode,
361835858a6Schristos     UINT32                  Level)
362835858a6Schristos {
36389b8eb6cSchristos 
364835858a6Schristos     if (!FNode || FNode->IncludeWritten)
365835858a6Schristos     {
366835858a6Schristos         return;
367835858a6Schristos     }
368835858a6Schristos 
36989b8eb6cSchristos     CvDbgPrint ("Writing include for %s within %s\n",
37089b8eb6cSchristos         FNode->Filename, FNode->Parent->Filename);
371835858a6Schristos     AcpiOsRedirectOutput (FNode->Parent->File);
372835858a6Schristos     CvPrintOneCommentList (FNode->IncludeComment, Level);
37389b8eb6cSchristos 
374835858a6Schristos     AcpiDmIndent (Level);
375835858a6Schristos     AcpiOsPrintf ("Include (\"%s\")\n", FNode->Filename);
37689b8eb6cSchristos     CvDbgPrint ("emitted the following: Include (\"%s\")\n",
37789b8eb6cSchristos         FNode->Filename);
378835858a6Schristos     FNode->IncludeWritten = TRUE;
379835858a6Schristos }
380835858a6Schristos 
381835858a6Schristos 
382835858a6Schristos /*******************************************************************************
383835858a6Schristos  *
384835858a6Schristos  * FUNCTION:    CvSwitchFiles
385835858a6Schristos  *
386835858a6Schristos  * PARAMETERS:  Level                   - indentation level
387835858a6Schristos  *              Op
388835858a6Schristos  *
389835858a6Schristos  * RETURN:      None
390835858a6Schristos  *
391835858a6Schristos  * DESCRIPTION: Switch the outputfile and write ASL Include statement. Note,
392835858a6Schristos  *              this function emits actual ASL code rather than comments.
393835858a6Schristos  *              This is referred as ASL_CV_SWITCH_FILES.
394835858a6Schristos  *
395835858a6Schristos  ******************************************************************************/
396835858a6Schristos 
397835858a6Schristos void
CvSwitchFiles(UINT32 Level,ACPI_PARSE_OBJECT * Op)398835858a6Schristos CvSwitchFiles(
399835858a6Schristos     UINT32                  Level,
400835858a6Schristos     ACPI_PARSE_OBJECT       *Op)
401835858a6Schristos {
402835858a6Schristos     char                    *Filename = Op->Common.CvFilename;
403835858a6Schristos     ACPI_FILE_NODE          *FNode;
40489b8eb6cSchristos     ACPI_FILE_NODE          *Current;
405835858a6Schristos 
40689b8eb6cSchristos 
40789b8eb6cSchristos     CvDbgPrint ("Switching from %s to %s\n", AcpiGbl_CurrentFilename,
40889b8eb6cSchristos         Filename);
409835858a6Schristos     FNode = CvFilenameExists (Filename, AcpiGbl_FileTreeRoot);
410835858a6Schristos     if (!FNode)
411835858a6Schristos     {
412835858a6Schristos         /*
413835858a6Schristos          * At this point, each Filename should exist in AcpiGbl_FileTreeRoot
414835858a6Schristos          * if it does not exist, then abort.
415835858a6Schristos          */
416835858a6Schristos         FlDeleteFile (ASL_FILE_AML_OUTPUT);
4174c4e8184Schristos         sprintf (AslGbl_MsgBuffer, "\"Cannot find %s\" - %s",
41889b8eb6cSchristos             Filename, strerror (errno));
41989b8eb6cSchristos         AslCommonError (ASL_ERROR, ASL_MSG_OPEN, 0, 0, 0, 0,
4204c4e8184Schristos             NULL, AslGbl_MsgBuffer);
421835858a6Schristos         AslAbort ();
422835858a6Schristos     }
423835858a6Schristos 
42489b8eb6cSchristos     Current = FNode;
42589b8eb6cSchristos 
426835858a6Schristos     /*
427835858a6Schristos      * If the previous file is a descendent of the current file,
428835858a6Schristos      * make sure that Include statements from the current file
429835858a6Schristos      * to the previous have been emitted.
430835858a6Schristos      */
43189b8eb6cSchristos     while (Current &&
43289b8eb6cSchristos            Current->Parent &&
43389b8eb6cSchristos            AcpiUtStricmp (Current->Filename, AcpiGbl_CurrentFilename))
434835858a6Schristos     {
43589b8eb6cSchristos         CvPrintInclude (Current, Level);
43689b8eb6cSchristos         Current = Current->Parent;
437835858a6Schristos     }
438835858a6Schristos 
43932aedd46Schristos     if (FNode)
44032aedd46Schristos     {
44189b8eb6cSchristos         /* Redirect output to Op->Common.CvFilename */
442835858a6Schristos 
443835858a6Schristos         AcpiOsRedirectOutput (FNode->File);
444835858a6Schristos         AcpiGbl_CurrentFilename = FNode->Filename;
445835858a6Schristos     }
44632aedd46Schristos }
447