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