VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/acpi/acpi-ast.cpp@ 108221

Last change on this file since 108221 was 108221, checked in by vboxsync, 3 months ago

Runtime/RTAcpi*: Support generating AML for more statements found in vbox.dsl, bugref:10733

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 34.3 KB
Line 
1/* $Id: acpi-ast.cpp 108221 2025-02-14 12:16:40Z vboxsync $ */
2/** @file
3 * IPRT - Advanced Configuration and Power Interface (ACPI) AST handling.
4 */
5
6/*
7 * Copyright (C) 2025 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * The contents of this file may alternatively be used under the terms
26 * of the Common Development and Distribution License Version 1.0
27 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
28 * in the VirtualBox distribution, in which case the provisions of the
29 * CDDL are applicable instead of those of the GPL.
30 *
31 * You may elect to license modified versions of this file under the
32 * terms and conditions of either the GPL or the CDDL or both.
33 *
34 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
35 */
36
37
38/*********************************************************************************************************************************
39* Header Files *
40*********************************************************************************************************************************/
41#define LOG_GROUP RTLOGGROUP_ACPI
42#include <iprt/assert.h>
43#include <iprt/errcore.h>
44#include <iprt/list.h>
45#include <iprt/mem.h>
46
47#include <iprt/formats/acpi-aml.h>
48
49#include "internal/acpi.h"
50
51
52/*********************************************************************************************************************************
53* Defined Constants And Macros *
54*********************************************************************************************************************************/
55
56
57/*********************************************************************************************************************************
58* Structures and Typedefs *
59*********************************************************************************************************************************/
60
61
62/*********************************************************************************************************************************
63* Global Variables *
64*********************************************************************************************************************************/
65
66
67/*********************************************************************************************************************************
68* Internal Functions *
69*********************************************************************************************************************************/
70
71DECLHIDDEN(PRTACPIASTNODE) rtAcpiAstNodeAlloc(RTACPIASTNODEOP enmOp, uint32_t fFlags, uint8_t cArgs)
72{
73 PRTACPIASTNODE pAstNd = (PRTACPIASTNODE)RTMemAllocZ(RT_UOFFSETOF_DYN(RTACPIASTNODE, aArgs[cArgs]));
74 if (pAstNd)
75 {
76 pAstNd->enmOp = enmOp;
77 pAstNd->fFlags = fFlags;
78 pAstNd->cArgs = cArgs;
79 RTListInit(&pAstNd->LstScopeNodes);
80 }
81
82 return pAstNd;
83}
84
85
86DECLHIDDEN(void) rtAcpiAstNodeFree(PRTACPIASTNODE pAstNd)
87{
88 /** @todo */
89 RTMemFree(pAstNd);
90}
91
92
93DECLHIDDEN(int) rtAcpiAstNodeTransform(PRTACPIASTNODE pAstNd, PRTERRINFO pErrInfo)
94{
95#if 0
96 /* Walk all arguments containing AST nodes first. */
97 for (uint8_t i = 0; i < pAstNd->cArgs; i++)
98 {
99 if ( pAstNd->aArgs[i].enmType == kAcpiAstArgType_AstNode
100 && pAstNd->aArgs[i].u.pAstNd)
101 {
102 int rc = rtAcpiAstNodeTransform(pAstNd->aArgs[i].u.pAstNd, pErrInfo);
103 if (RT_FAILURE(rc))
104 return rc;
105 }
106 }
107
108 if (pAstNd->fFlags & RTACPI_AST_NODE_F_NEW_SCOPE)
109 {
110 PRTACPIASTNODE pIt/*, pItPrev*/;
111 /* Do transformations on the nodes first. */
112 RTListForEach(&pAstNd->LstScopeNodes, pIt, RTACPIASTNODE, NdAst)
113 {
114 int rc = rtAcpiAstNodeTransform(pIt, pErrInfo);
115 if (RT_FAILURE(rc))
116 return rc;
117 }
118
119 /* Now do transformations on our level. */
120 RTListForEachReverseSafe(&pAstNd->LstScopeNodes, pIt, pItPrev, RTACPIASTNODE, NdAst)
121 {
122 /*
123 * If there is an If AST node followed by Else we move the Else branch as the last
124 * statement in the If because when emitting to AML the Else is enclosed in the If
125 * package.
126 */
127 if ( pIt->enmOp == kAcpiAstNodeOp_Else
128 && pItPrev
129 && pItPrev->enmOp == kAcpiAstNodeOp_If)
130 {
131 RTListNodeRemove(&pIt->NdAst);
132 RTListAppend(&pItPrev->LstScopeNodes, &pIt->NdAst);
133 }
134 }
135 }
136#else
137 RT_NOREF(pAstNd, pErrInfo);
138#endif
139
140 return VINF_SUCCESS;
141}
142
143
144/**
145 * Evaluates the given AST node to an integer if possible.
146 *
147 * @returns IPRT status code.
148 * @param pAstNd The AST node to evaluate.
149 * @param pNsRoot The namespace root this AST belongs to.
150 * @param pu64 Where to store the integer on success.
151 */
152static int rtAcpiAstNodeEvaluateToInteger(PCRTACPIASTNODE pAstNd, PRTACPINSROOT pNsRoot, uint64_t *pu64)
153{
154 /* Easy way out?. */
155 if (pAstNd->enmOp == kAcpiAstNodeOp_Number)
156 {
157 *pu64 = pAstNd->u64;
158 return VINF_SUCCESS;
159 }
160
161 if (pAstNd->enmOp == kAcpiAstNodeOp_One)
162 {
163 *pu64 = 1;
164 return VINF_SUCCESS;
165 }
166
167 if (pAstNd->enmOp == kAcpiAstNodeOp_Zero)
168 {
169 *pu64 = 0;
170 return VINF_SUCCESS;
171 }
172
173 if (pAstNd->enmOp == kAcpiAstNodeOp_Identifier)
174 {
175 /* Look it up in the namespace and use the result. */
176 PCRTACPINSENTRY pNsEntry = rtAcpiNsLookup(pNsRoot, pAstNd->pszIde);
177 if (!pNsEntry)
178 return VERR_NOT_FOUND;
179
180 *pu64 = pNsEntry->offBits;
181 }
182
183 /** @todo */
184 return VERR_NOT_IMPLEMENTED;
185}
186
187
188static int rtAcpiAstDumpAstList(PCRTLISTANCHOR pLst, PRTACPINSROOT pNsRoot, RTACPITBL hAcpiTbl)
189{
190 PCRTACPIASTNODE pIt;
191 RTListForEach(pLst, pIt, RTACPIASTNODE, NdAst)
192 {
193 int rc = rtAcpiAstDumpToTbl(pIt, pNsRoot, hAcpiTbl);
194 if (RT_FAILURE(rc))
195 return rc;
196 }
197
198 return VINF_SUCCESS;
199}
200
201
202DECLHIDDEN(int) rtAcpiAstDumpToTbl(PCRTACPIASTNODE pAstNd, PRTACPINSROOT pNsRoot, RTACPITBL hAcpiTbl)
203{
204 int rc = VINF_SUCCESS;
205
206 switch (pAstNd->enmOp)
207 {
208 case kAcpiAstNodeOp_Identifier:
209 {
210 rc = RTAcpiTblNameStringAppend(hAcpiTbl, pAstNd->pszIde);
211 if (RT_SUCCESS(rc))
212 {
213 for (uint8_t i = 0; i < pAstNd->cArgs; i++)
214 {
215 Assert(pAstNd->aArgs[i].enmType == kAcpiAstArgType_AstNode);
216 rc = rtAcpiAstDumpToTbl(pAstNd->aArgs[i].u.pAstNd, pNsRoot, hAcpiTbl);
217 if (RT_FAILURE(rc))
218 break;
219 }
220 }
221 break;
222 }
223 case kAcpiAstNodeOp_StringLiteral:
224 rc = RTAcpiTblStringAppend(hAcpiTbl, pAstNd->pszStrLit);
225 break;
226 case kAcpiAstNodeOp_Number:
227 rc = RTAcpiTblIntegerAppend(hAcpiTbl, pAstNd->u64);
228 break;
229 case kAcpiAstNodeOp_Scope:
230 {
231 AssertBreakStmt( pAstNd->cArgs == 1
232 && pAstNd->aArgs[0].enmType == kAcpiAstArgType_NameString,
233 rc = VERR_INTERNAL_ERROR);
234 rc = RTAcpiTblScopeStart(hAcpiTbl, pAstNd->aArgs[0].u.pszNameString);
235 if (RT_SUCCESS(rc))
236 {
237 /* Walk all the other AST nodes. */
238 rc = rtAcpiAstDumpAstList(&pAstNd->LstScopeNodes, pNsRoot, hAcpiTbl);
239 if (RT_SUCCESS(rc))
240 rc = RTAcpiTblScopeFinalize(hAcpiTbl);
241 }
242 break;
243 }
244 case kAcpiAstNodeOp_Processor:
245 {
246 AssertBreakStmt( pAstNd->cArgs == 4
247 && pAstNd->aArgs[0].enmType == kAcpiAstArgType_NameString
248 && pAstNd->aArgs[1].enmType == kAcpiAstArgType_U8
249 && pAstNd->aArgs[2].enmType == kAcpiAstArgType_U32
250 && pAstNd->aArgs[3].enmType == kAcpiAstArgType_U8,
251 rc = VERR_INTERNAL_ERROR);
252 rc = RTAcpiTblProcessorStart(hAcpiTbl,
253 pAstNd->aArgs[0].u.pszNameString,
254 pAstNd->aArgs[1].u.u8,
255 pAstNd->aArgs[2].u.u32,
256 pAstNd->aArgs[3].u.u8);
257 if (RT_SUCCESS(rc))
258 {
259 /* Walk all the other AST nodes. */
260 rc = rtAcpiAstDumpAstList(&pAstNd->LstScopeNodes, pNsRoot, hAcpiTbl);
261 if (RT_SUCCESS(rc))
262 rc = RTAcpiTblProcessorFinalize(hAcpiTbl);
263 }
264 break;
265 }
266 case kAcpiAstNodeOp_Method:
267 {
268 AssertBreakStmt( pAstNd->cArgs == 4
269 && pAstNd->aArgs[0].enmType == kAcpiAstArgType_NameString
270 && pAstNd->aArgs[1].enmType == kAcpiAstArgType_U8
271 && pAstNd->aArgs[2].enmType == kAcpiAstArgType_Bool
272 && pAstNd->aArgs[3].enmType == kAcpiAstArgType_U8,
273 rc = VERR_INTERNAL_ERROR);
274 rc = RTAcpiTblMethodStart(hAcpiTbl, pAstNd->aArgs[0].u.pszNameString,
275 pAstNd->aArgs[1].u.u8,
276 pAstNd->aArgs[2].u.f ? RTACPI_METHOD_F_SERIALIZED : RTACPI_METHOD_F_NOT_SERIALIZED,
277 pAstNd->aArgs[3].u.u8);
278 if (RT_SUCCESS(rc))
279 {
280 /* Walk all the other AST nodes. */
281 rc = rtAcpiAstDumpAstList(&pAstNd->LstScopeNodes, pNsRoot, hAcpiTbl);
282 if (RT_SUCCESS(rc))
283 rc = RTAcpiTblMethodFinalize(hAcpiTbl);
284 }
285 break;
286 }
287 case kAcpiAstNodeOp_Device:
288 {
289 AssertBreakStmt( pAstNd->cArgs == 1
290 && pAstNd->aArgs[0].enmType == kAcpiAstArgType_NameString,
291 rc = VERR_INTERNAL_ERROR);
292 rc = RTAcpiTblDeviceStart(hAcpiTbl, pAstNd->aArgs[0].u.pszNameString);
293 if (RT_SUCCESS(rc))
294 {
295 /* Walk all the other AST nodes. */
296 rc = rtAcpiAstDumpAstList(&pAstNd->LstScopeNodes, pNsRoot, hAcpiTbl);
297 if (RT_SUCCESS(rc))
298 rc = RTAcpiTblDeviceFinalize(hAcpiTbl);
299 }
300 break;
301 }
302 case kAcpiAstNodeOp_If:
303 {
304 AssertBreakStmt( pAstNd->cArgs == 1
305 && pAstNd->aArgs[0].enmType == kAcpiAstArgType_AstNode,
306 rc = VERR_INTERNAL_ERROR);
307 rc = RTAcpiTblIfStart(hAcpiTbl);
308 if (RT_SUCCESS(rc))
309 {
310 /* Predicate. */
311 rc = rtAcpiAstDumpToTbl(pAstNd->aArgs[0].u.pAstNd, pNsRoot, hAcpiTbl);
312 if (RT_SUCCESS(rc))
313 {
314 /* Walk all the other AST nodes. */
315 rc = rtAcpiAstDumpAstList(&pAstNd->LstScopeNodes, pNsRoot, hAcpiTbl);
316 if (RT_SUCCESS(rc))
317 rc = RTAcpiTblIfFinalize(hAcpiTbl);
318 }
319 }
320 break;
321 }
322 case kAcpiAstNodeOp_Else:
323 {
324 AssertBreakStmt(pAstNd->cArgs == 0, rc = VERR_INTERNAL_ERROR);
325 rc = RTAcpiTblElseStart(hAcpiTbl);
326 if (RT_SUCCESS(rc))
327 {
328 /* Walk all the other AST nodes. */
329 rc = rtAcpiAstDumpAstList(&pAstNd->LstScopeNodes, pNsRoot, hAcpiTbl);
330 if (RT_SUCCESS(rc))
331 rc = RTAcpiTblElseFinalize(hAcpiTbl);
332 }
333 break;
334 }
335 case kAcpiAstNodeOp_While:
336 {
337 AssertBreakStmt( pAstNd->cArgs == 1
338 && pAstNd->aArgs[0].enmType == kAcpiAstArgType_AstNode,
339 rc = VERR_INTERNAL_ERROR);
340 rc = RTAcpiTblWhileStart(hAcpiTbl);
341 if (RT_SUCCESS(rc))
342 {
343 /* Predicate. */
344 rc = rtAcpiAstDumpToTbl(pAstNd->aArgs[0].u.pAstNd, pNsRoot, hAcpiTbl);
345 if (RT_SUCCESS(rc))
346 {
347 /* Walk all the other AST nodes. */
348 rc = rtAcpiAstDumpAstList(&pAstNd->LstScopeNodes, pNsRoot, hAcpiTbl);
349 if (RT_SUCCESS(rc))
350 rc = RTAcpiTblWhileFinalize(hAcpiTbl);
351 }
352 }
353 break;
354 }
355 case kAcpiAstNodeOp_LAnd:
356 case kAcpiAstNodeOp_LOr:
357 case kAcpiAstNodeOp_LEqual:
358 case kAcpiAstNodeOp_LGreater:
359 case kAcpiAstNodeOp_LGreaterEqual:
360 case kAcpiAstNodeOp_LLess:
361 case kAcpiAstNodeOp_LLessEqual:
362 case kAcpiAstNodeOp_LNotEqual:
363 {
364 AssertBreakStmt( pAstNd->cArgs == 2
365 && pAstNd->aArgs[0].enmType == kAcpiAstArgType_AstNode
366 && pAstNd->aArgs[1].enmType == kAcpiAstArgType_AstNode,
367 rc = VERR_INTERNAL_ERROR);
368 RTACPIBINARYOP enmOp;
369 switch (pAstNd->enmOp)
370 {
371 case kAcpiAstNodeOp_LAnd: enmOp = kAcpiBinaryOp_LAnd; break;
372 case kAcpiAstNodeOp_LOr: enmOp = kAcpiBinaryOp_LOr; break;
373 case kAcpiAstNodeOp_LEqual: enmOp = kAcpiBinaryOp_LEqual; break;
374 case kAcpiAstNodeOp_LGreater: enmOp = kAcpiBinaryOp_LGreater; break;
375 case kAcpiAstNodeOp_LGreaterEqual: enmOp = kAcpiBinaryOp_LGreaterEqual; break;
376 case kAcpiAstNodeOp_LLess: enmOp = kAcpiBinaryOp_LLess; break;
377 case kAcpiAstNodeOp_LLessEqual: enmOp = kAcpiBinaryOp_LLessEqual; break;
378 case kAcpiAstNodeOp_LNotEqual: enmOp = kAcpiBinaryOp_LNotEqual; break;
379 default:
380 AssertReleaseFailed(); /* Impossible */
381 return VERR_INTERNAL_ERROR;
382 }
383
384 rc = RTAcpiTblBinaryOpAppend(hAcpiTbl, enmOp);
385 if (RT_SUCCESS(rc))
386 {
387 rc = rtAcpiAstDumpToTbl(pAstNd->aArgs[0].u.pAstNd, pNsRoot, hAcpiTbl);
388 if (RT_SUCCESS(rc))
389 rc = rtAcpiAstDumpToTbl(pAstNd->aArgs[1].u.pAstNd, pNsRoot, hAcpiTbl);
390 }
391 break;
392 }
393 case kAcpiAstNodeOp_LNot:
394 AssertBreakStmt( pAstNd->cArgs == 1
395 && pAstNd->aArgs[0].enmType == kAcpiAstArgType_AstNode,
396 rc = VERR_INTERNAL_ERROR);
397 rc = RTAcpiTblStmtSimpleAppend(hAcpiTbl, kAcpiStmt_LNot);
398 if (RT_SUCCESS(rc))
399 rc = rtAcpiAstDumpToTbl(pAstNd->aArgs[0].u.pAstNd, pNsRoot, hAcpiTbl);
400 break;
401 case kAcpiAstNodeOp_Zero:
402 {
403 AssertBreakStmt(pAstNd->cArgs == 0, rc = VERR_INTERNAL_ERROR);
404 rc = RTAcpiTblIntegerAppend(hAcpiTbl, 0);
405 break;
406 }
407 case kAcpiAstNodeOp_One:
408 {
409 AssertBreakStmt(pAstNd->cArgs == 0, rc = VERR_INTERNAL_ERROR);
410 rc = RTAcpiTblIntegerAppend(hAcpiTbl, 1);
411 break;
412 }
413 case kAcpiAstNodeOp_Ones:
414 {
415 AssertBreakStmt(pAstNd->cArgs == 0, rc = VERR_INTERNAL_ERROR);
416 rc = RTAcpiTblStmtSimpleAppend(hAcpiTbl, kAcpiStmt_Ones);
417 break;
418 }
419 case kAcpiAstNodeOp_Return:
420 {
421 AssertBreakStmt( pAstNd->cArgs == 1
422 && pAstNd->aArgs[0].enmType == kAcpiAstArgType_AstNode,
423 rc = VERR_INTERNAL_ERROR);
424 rc = RTAcpiTblStmtSimpleAppend(hAcpiTbl, kAcpiStmt_Return);
425 if (RT_SUCCESS(rc))
426 {
427 if (pAstNd->aArgs[0].u.pAstNd)
428 rc = rtAcpiAstDumpToTbl(pAstNd->aArgs[0].u.pAstNd, pNsRoot, hAcpiTbl);
429 else
430 rc = RTAcpiTblNullNameAppend(hAcpiTbl);
431 }
432 break;
433 }
434 case kAcpiAstNodeOp_Unicode:
435 {
436 AssertBreakStmt( pAstNd->cArgs == 1
437 && pAstNd->aArgs[0].enmType == kAcpiAstArgType_AstNode
438 && pAstNd->aArgs[0].u.pAstNd->enmOp == kAcpiAstNodeOp_StringLiteral,
439 rc = VERR_INTERNAL_ERROR);
440
441 rc = RTAcpiTblStringAppendAsUtf16(hAcpiTbl, pAstNd->aArgs[0].u.pAstNd->pszStrLit);
442 break;
443 }
444 case kAcpiAstNodeOp_OperationRegion:
445 {
446 AssertBreakStmt( pAstNd->cArgs == 4
447 && pAstNd->aArgs[0].enmType == kAcpiAstArgType_NameString
448 && pAstNd->aArgs[1].enmType == kAcpiAstArgType_RegionSpace
449 && pAstNd->aArgs[2].enmType == kAcpiAstArgType_AstNode
450 && pAstNd->aArgs[3].enmType == kAcpiAstArgType_AstNode,
451 rc = VERR_INTERNAL_ERROR);
452
453 rc = RTAcpiTblOpRegionAppendEx(hAcpiTbl, pAstNd->aArgs[0].u.pszNameString, pAstNd->aArgs[1].u.enmRegionSpace);
454 if (RT_SUCCESS(rc))
455 rc = rtAcpiAstDumpToTbl(pAstNd->aArgs[2].u.pAstNd, pNsRoot, hAcpiTbl);
456 if (RT_SUCCESS(rc))
457 rc = rtAcpiAstDumpToTbl(pAstNd->aArgs[3].u.pAstNd, pNsRoot, hAcpiTbl);
458 break;
459 }
460 case kAcpiAstNodeOp_Field:
461 {
462 AssertBreakStmt( pAstNd->cArgs == 4
463 && pAstNd->aArgs[0].enmType == kAcpiAstArgType_NameString
464 && pAstNd->aArgs[1].enmType == kAcpiAstArgType_FieldAcc
465 && pAstNd->aArgs[2].enmType == kAcpiAstArgType_Bool
466 && pAstNd->aArgs[3].enmType == kAcpiAstArgType_FieldUpdate,
467 rc = VERR_INTERNAL_ERROR);
468
469 rc = RTAcpiTblFieldAppend(hAcpiTbl, pAstNd->aArgs[0].u.pszNameString, pAstNd->aArgs[1].u.enmFieldAcc,
470 pAstNd->aArgs[2].u.f, pAstNd->aArgs[3].u.enmFieldUpdate, pAstNd->Fields.paFields,
471 pAstNd->Fields.cFields);
472 break;
473 }
474 case kAcpiAstNodeOp_IndexField:
475 {
476 AssertBreakStmt( pAstNd->cArgs == 5
477 && pAstNd->aArgs[0].enmType == kAcpiAstArgType_NameString
478 && pAstNd->aArgs[1].enmType == kAcpiAstArgType_NameString
479 && pAstNd->aArgs[2].enmType == kAcpiAstArgType_FieldAcc
480 && pAstNd->aArgs[3].enmType == kAcpiAstArgType_Bool
481 && pAstNd->aArgs[4].enmType == kAcpiAstArgType_FieldUpdate,
482 rc = VERR_INTERNAL_ERROR);
483
484 rc = RTAcpiTblIndexFieldAppend(hAcpiTbl, pAstNd->aArgs[0].u.pszNameString, pAstNd->aArgs[1].u.pszNameString,
485 pAstNd->aArgs[2].u.enmFieldAcc, pAstNd->aArgs[3].u.f, pAstNd->aArgs[4].u.enmFieldUpdate,
486 pAstNd->Fields.paFields, pAstNd->Fields.cFields);
487 break;
488 }
489 case kAcpiAstNodeOp_Name:
490 {
491 AssertBreakStmt( pAstNd->cArgs == 2
492 && pAstNd->aArgs[0].enmType == kAcpiAstArgType_NameString
493 && pAstNd->aArgs[1].enmType == kAcpiAstArgType_AstNode,
494 rc = VERR_INTERNAL_ERROR);
495
496 rc = RTAcpiTblNameAppend(hAcpiTbl, pAstNd->aArgs[0].u.pszNameString);
497 if (RT_SUCCESS(rc))
498 rc = rtAcpiAstDumpToTbl(pAstNd->aArgs[1].u.pAstNd, pNsRoot, hAcpiTbl);
499 break;
500 }
501 case kAcpiAstNodeOp_ResourceTemplate:
502 rc = RTAcpiTblResourceAppend(hAcpiTbl, pAstNd->hAcpiRes);
503 break;
504 case kAcpiAstNodeOp_Arg0:
505 case kAcpiAstNodeOp_Arg1:
506 case kAcpiAstNodeOp_Arg2:
507 case kAcpiAstNodeOp_Arg3:
508 case kAcpiAstNodeOp_Arg4:
509 case kAcpiAstNodeOp_Arg5:
510 case kAcpiAstNodeOp_Arg6:
511 rc = RTAcpiTblArgOpAppend(hAcpiTbl, pAstNd->enmOp - kAcpiAstNodeOp_Arg0);
512 break;
513 case kAcpiAstNodeOp_Local0:
514 case kAcpiAstNodeOp_Local1:
515 case kAcpiAstNodeOp_Local2:
516 case kAcpiAstNodeOp_Local3:
517 case kAcpiAstNodeOp_Local4:
518 case kAcpiAstNodeOp_Local5:
519 case kAcpiAstNodeOp_Local6:
520 case kAcpiAstNodeOp_Local7:
521 rc = RTAcpiTblLocalOpAppend(hAcpiTbl, pAstNd->enmOp - kAcpiAstNodeOp_Local0);
522 break;
523 case kAcpiAstNodeOp_Package:
524 {
525 AssertBreakStmt( pAstNd->cArgs == 1
526 && pAstNd->aArgs[0].enmType == kAcpiAstArgType_AstNode,
527 rc = VERR_INTERNAL_ERROR);
528
529 /* Try to gather the number of elements. */
530 uint64_t cElems = 0;
531 if (pAstNd->aArgs[0].u.pAstNd)
532 {
533 /* Try resolving to a constant expression. */
534 rc = rtAcpiAstNodeEvaluateToInteger(pAstNd->aArgs[0].u.pAstNd, pNsRoot, &cElems);
535 if (RT_FAILURE(rc))
536 break;
537 }
538 else
539 {
540 /* Count elements. */
541 PRTACPIASTNODE pIt;
542 RTListForEach(&pAstNd->LstScopeNodes, pIt, RTACPIASTNODE, NdAst)
543 {
544 cElems++;
545 }
546 }
547 if (RT_SUCCESS(rc))
548 {
549 if (cElems > 255)
550 {
551 rc = VERR_BUFFER_OVERFLOW;
552 break;
553 }
554
555 rc = RTAcpiTblPackageStart(hAcpiTbl, (uint8_t)cElems);
556 if (RT_SUCCESS(rc))
557 rc = rtAcpiAstDumpAstList(&pAstNd->LstScopeNodes, pNsRoot, hAcpiTbl);
558 if (RT_SUCCESS(rc))
559 rc = RTAcpiTblPackageFinalize(hAcpiTbl);
560 }
561 break;
562 }
563 case kAcpiAstNodeOp_Buffer:
564 {
565 AssertBreakStmt( pAstNd->cArgs == 1
566 && pAstNd->aArgs[0].enmType == kAcpiAstArgType_AstNode,
567 rc = VERR_INTERNAL_ERROR);
568
569 rc = RTAcpiTblBufferStart(hAcpiTbl);
570
571 /* Try to gather the number of elements. */
572 uint64_t cElems = 0;
573 /* Count elements. */
574 PRTACPIASTNODE pIt;
575 RTListForEach(&pAstNd->LstScopeNodes, pIt, RTACPIASTNODE, NdAst)
576 {
577 cElems++;
578 }
579
580 /*
581 * If the buffer size is empty (no AST node) the number of elements
582 * in the initializer serve as tehe buffer size.
583 */
584 /** @todo Strings. */
585 if (pAstNd->aArgs[0].u.pAstNd)
586 rc = rtAcpiAstDumpToTbl(pAstNd->aArgs[0].u.pAstNd, pNsRoot, hAcpiTbl);
587 else
588 rc = RTAcpiTblIntegerAppend(hAcpiTbl, cElems);
589
590 if ( RT_SUCCESS(rc)
591 && cElems)
592 {
593 uint8_t *pb = (uint8_t *)RTMemAlloc(cElems);
594 if (pb)
595 {
596 uint64_t i = 0;
597 RTListForEach(&pAstNd->LstScopeNodes, pIt, RTACPIASTNODE, NdAst)
598 {
599 /* Try resolving to a constant expression. */
600 uint64_t u64 = 0;
601 rc = rtAcpiAstNodeEvaluateToInteger(pIt, pNsRoot, &u64);
602 if (RT_FAILURE(rc))
603 break;
604 if (u64 > UINT8_MAX)
605 {
606 rc = VERR_BUFFER_OVERFLOW;
607 break;
608 }
609
610 pb[i++] = (uint8_t)u64;
611 }
612
613 if (RT_SUCCESS(rc))
614 rc = RTAcpiTblBufferAppendRawData(hAcpiTbl, pb, cElems);
615 RTMemFree(pb);
616 }
617 else
618 rc = VERR_NO_MEMORY;
619 }
620
621 rc = RTAcpiTblBufferFinalize(hAcpiTbl);
622 break;
623 }
624 case kAcpiAstNodeOp_ToUuid:
625 {
626 AssertBreakStmt( pAstNd->cArgs == 1
627 && pAstNd->aArgs[0].enmType == kAcpiAstArgType_AstNode
628 && pAstNd->aArgs[0].u.pAstNd->enmOp == kAcpiAstNodeOp_StringLiteral,
629 rc = VERR_INTERNAL_ERROR);
630 rc = RTAcpiTblUuidAppendFromStr(hAcpiTbl, pAstNd->aArgs[0].u.pAstNd->pszStrLit);
631 break;
632 }
633 case kAcpiAstNodeOp_Break:
634 {
635 AssertBreakStmt(pAstNd->cArgs == 0, rc = VERR_INTERNAL_ERROR);
636 rc = RTAcpiTblStmtSimpleAppend(hAcpiTbl, kAcpiStmt_Break);
637 break;
638 }
639 case kAcpiAstNodeOp_Continue:
640 {
641 AssertBreakStmt(pAstNd->cArgs == 0, rc = VERR_INTERNAL_ERROR);
642 rc = RTAcpiTblStmtSimpleAppend(hAcpiTbl, kAcpiStmt_Continue);
643 break;
644 }
645 case kAcpiAstNodeOp_DerefOf:
646 case kAcpiAstNodeOp_SizeOf:
647 case kAcpiAstNodeOp_Increment:
648 case kAcpiAstNodeOp_Decrement:
649 {
650 AssertBreakStmt( pAstNd->cArgs == 1
651 && pAstNd->aArgs[0].enmType == kAcpiAstArgType_AstNode,
652 rc = VERR_INTERNAL_ERROR);
653
654 RTACPISTMT enmStmt;
655 switch (pAstNd->enmOp)
656 {
657 case kAcpiAstNodeOp_DerefOf: enmStmt = kAcpiStmt_DerefOf; break;
658 case kAcpiAstNodeOp_SizeOf: enmStmt = kAcpiStmt_SizeOf; break;
659 case kAcpiAstNodeOp_Increment: enmStmt = kAcpiStmt_Increment; break;
660 case kAcpiAstNodeOp_Decrement: enmStmt = kAcpiStmt_Decrement; break;
661 default:
662 AssertReleaseFailed(); /* Impossible */
663 return VERR_INTERNAL_ERROR;
664 }
665
666
667 rc = RTAcpiTblStmtSimpleAppend(hAcpiTbl, enmStmt);
668 if (RT_SUCCESS(rc))
669 rc = rtAcpiAstDumpToTbl(pAstNd->aArgs[0].u.pAstNd, pNsRoot, hAcpiTbl);
670 break;
671 }
672 case kAcpiAstNodeOp_Store:
673 case kAcpiAstNodeOp_Notify:
674 {
675 AssertBreakStmt( pAstNd->cArgs == 2
676 && pAstNd->aArgs[0].enmType == kAcpiAstArgType_AstNode
677 && pAstNd->aArgs[1].enmType == kAcpiAstArgType_AstNode,
678 rc = VERR_INTERNAL_ERROR);
679 rc = RTAcpiTblStmtSimpleAppend(hAcpiTbl,
680 pAstNd->enmOp == kAcpiAstNodeOp_Store
681 ? kAcpiStmt_Store
682 : kAcpiStmt_Notify);
683 if (RT_SUCCESS(rc))
684 rc = rtAcpiAstDumpToTbl(pAstNd->aArgs[0].u.pAstNd, pNsRoot, hAcpiTbl);
685 if (RT_SUCCESS(rc))
686 rc = rtAcpiAstDumpToTbl(pAstNd->aArgs[1].u.pAstNd, pNsRoot, hAcpiTbl);
687 break;
688 }
689 case kAcpiAstNodeOp_Not:
690 case kAcpiAstNodeOp_CondRefOf:
691 case kAcpiAstNodeOp_FindSetLeftBit:
692 case kAcpiAstNodeOp_FindSetRightBit:
693 {
694 AssertBreakStmt( pAstNd->cArgs == 2
695 && pAstNd->aArgs[0].enmType == kAcpiAstArgType_AstNode
696 && pAstNd->aArgs[1].enmType == kAcpiAstArgType_AstNode,
697 rc = VERR_INTERNAL_ERROR);
698
699 RTACPISTMT enmStmt;
700 switch (pAstNd->enmOp)
701 {
702 case kAcpiAstNodeOp_Not: enmStmt = kAcpiStmt_Not; break;
703 case kAcpiAstNodeOp_CondRefOf: enmStmt = kAcpiStmt_CondRefOf; break;
704 case kAcpiAstNodeOp_FindSetLeftBit: enmStmt = kAcpiStmt_FindSetLeftBit; break;
705 case kAcpiAstNodeOp_FindSetRightBit: enmStmt = kAcpiStmt_FindSetRightBit; break;
706 default:
707 AssertReleaseFailed(); /* Impossible */
708 return VERR_INTERNAL_ERROR;
709 }
710
711 rc = RTAcpiTblStmtSimpleAppend(hAcpiTbl, enmStmt);
712 if (RT_SUCCESS(rc))
713 rc = rtAcpiAstDumpToTbl(pAstNd->aArgs[0].u.pAstNd, pNsRoot, hAcpiTbl);
714 if (RT_SUCCESS(rc))
715 {
716 if (pAstNd->aArgs[1].u.pAstNd)
717 rc = rtAcpiAstDumpToTbl(pAstNd->aArgs[1].u.pAstNd, pNsRoot, hAcpiTbl);
718 else
719 rc = RTAcpiTblNullNameAppend(hAcpiTbl);
720 }
721 break;
722 }
723 case kAcpiAstNodeOp_Index:
724 case kAcpiAstNodeOp_Add:
725 case kAcpiAstNodeOp_Subtract:
726 case kAcpiAstNodeOp_Multiply:
727 case kAcpiAstNodeOp_And:
728 case kAcpiAstNodeOp_Nand:
729 case kAcpiAstNodeOp_Or:
730 case kAcpiAstNodeOp_Xor:
731 case kAcpiAstNodeOp_ShiftLeft:
732 case kAcpiAstNodeOp_ShiftRight:
733 case kAcpiAstNodeOp_ConcatenateResTemplate:
734 {
735 AssertBreakStmt( pAstNd->cArgs == 3
736 && pAstNd->aArgs[0].enmType == kAcpiAstArgType_AstNode
737 && pAstNd->aArgs[1].enmType == kAcpiAstArgType_AstNode
738 && pAstNd->aArgs[2].enmType == kAcpiAstArgType_AstNode,
739 rc = VERR_INTERNAL_ERROR);
740
741 RTACPISTMT enmStmt;
742 switch (pAstNd->enmOp)
743 {
744 case kAcpiAstNodeOp_Index: enmStmt = kAcpiStmt_Index; break;
745 case kAcpiAstNodeOp_Add: enmStmt = kAcpiStmt_Add; break;
746 case kAcpiAstNodeOp_Subtract: enmStmt = kAcpiStmt_Subtract; break;
747 case kAcpiAstNodeOp_Multiply: enmStmt = kAcpiStmt_Multiply; break;
748 case kAcpiAstNodeOp_And: enmStmt = kAcpiStmt_And; break;
749 case kAcpiAstNodeOp_Nand: enmStmt = kAcpiStmt_Nand; break;
750 case kAcpiAstNodeOp_Or: enmStmt = kAcpiStmt_Or; break;
751 case kAcpiAstNodeOp_Xor: enmStmt = kAcpiStmt_Xor; break;
752 case kAcpiAstNodeOp_ShiftLeft: enmStmt = kAcpiStmt_ShiftLeft; break;
753 case kAcpiAstNodeOp_ShiftRight: enmStmt = kAcpiStmt_ShiftRight; break;
754 case kAcpiAstNodeOp_ConcatenateResTemplate: enmStmt = kAcpiStmt_ConcatenateResTemplate; break;
755 default:
756 AssertReleaseFailed(); /* Impossible */
757 return VERR_INTERNAL_ERROR;
758 }
759
760 rc = RTAcpiTblStmtSimpleAppend(hAcpiTbl, enmStmt);
761 if (RT_SUCCESS(rc))
762 rc = rtAcpiAstDumpToTbl(pAstNd->aArgs[0].u.pAstNd, pNsRoot, hAcpiTbl);
763 if (RT_SUCCESS(rc))
764 rc = rtAcpiAstDumpToTbl(pAstNd->aArgs[1].u.pAstNd, pNsRoot, hAcpiTbl);
765 if (RT_SUCCESS(rc))
766 {
767 if (pAstNd->aArgs[2].u.pAstNd)
768 rc = rtAcpiAstDumpToTbl(pAstNd->aArgs[2].u.pAstNd, pNsRoot, hAcpiTbl);
769 else
770 rc = RTAcpiTblNullNameAppend(hAcpiTbl);
771 }
772 break;
773 }
774 case kAcpiAstNodeOp_EisaId:
775 {
776 AssertBreakStmt( pAstNd->cArgs == 1
777 && pAstNd->aArgs[0].enmType == kAcpiAstArgType_StringLiteral,
778 rc = VERR_INTERNAL_ERROR);
779 rc = RTAcpiTblEisaIdAppend(hAcpiTbl, pAstNd->aArgs[0].u.pszStrLit);
780 break;
781 }
782 case kAcpiAstNodeOp_CreateBitField:
783 case kAcpiAstNodeOp_CreateByteField:
784 case kAcpiAstNodeOp_CreateWordField:
785 case kAcpiAstNodeOp_CreateDWordField:
786 case kAcpiAstNodeOp_CreateQWordField:
787 {
788 AssertBreakStmt( pAstNd->cArgs == 3
789 && pAstNd->aArgs[0].enmType == kAcpiAstArgType_AstNode
790 && pAstNd->aArgs[1].enmType == kAcpiAstArgType_AstNode
791 && pAstNd->aArgs[2].enmType == kAcpiAstArgType_NameString,
792 rc = VERR_INTERNAL_ERROR);
793
794 RTACPISTMT enmStmt;
795 switch (pAstNd->enmOp)
796 {
797 case kAcpiAstNodeOp_CreateBitField: enmStmt = kAcpiStmt_CreateBitField; break;
798 case kAcpiAstNodeOp_CreateByteField: enmStmt = kAcpiStmt_CreateByteField; break;
799 case kAcpiAstNodeOp_CreateWordField: enmStmt = kAcpiStmt_CreateWordField; break;
800 case kAcpiAstNodeOp_CreateDWordField: enmStmt = kAcpiStmt_CreateDWordField; break;
801 case kAcpiAstNodeOp_CreateQWordField: enmStmt = kAcpiStmt_CreateQWordField; break;
802 default:
803 AssertReleaseFailed(); /* Impossible */
804 return VERR_INTERNAL_ERROR;
805 }
806
807 rc = RTAcpiTblStmtSimpleAppend(hAcpiTbl, enmStmt);
808 if (RT_SUCCESS(rc))
809 rc = rtAcpiAstDumpToTbl(pAstNd->aArgs[0].u.pAstNd, pNsRoot, hAcpiTbl);
810 if (RT_SUCCESS(rc))
811 {
812 /* Try to resolve to an integer. */
813 uint64_t offBits = 0;
814 rc = rtAcpiAstNodeEvaluateToInteger(pAstNd->aArgs[1].u.pAstNd, pNsRoot, &offBits);
815 if (RT_SUCCESS(rc))
816 rc = RTAcpiTblIntegerAppend(hAcpiTbl, pAstNd->enmOp == kAcpiAstNodeOp_CreateBitField ? offBits : offBits / 8);
817 else
818 rc = rtAcpiAstDumpToTbl(pAstNd->aArgs[1].u.pAstNd, pNsRoot, hAcpiTbl);
819 }
820 if (RT_SUCCESS(rc))
821 rc = RTAcpiTblNameStringAppend(hAcpiTbl, pAstNd->aArgs[2].u.pszNameString);
822 break;
823 }
824 case kAcpiAstNodeOp_External:
825 default:
826 AssertFailedStmt(rc = VERR_NOT_IMPLEMENTED);
827 }
828
829 AssertRC(rc);
830 return rc;
831}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette