VirtualBox

source: vbox/trunk/src/VBox/Runtime/include/internal/acpi.h@ 108215

Last change on this file since 108215 was 108215, checked in by vboxsync, 2 months ago

Runtime/RTAcpi*: Treat External delcarations differently so that they can be properly dumped to the AML code. With this RTIasl is capable of producing AML code for vbox-tpm.dsl matching that generated by iasl, bugref:10733

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 15.5 KB
Line 
1/* $Id: acpi.h 108215 2025-02-13 18:24:31Z vboxsync $ */
2/** @file
3 * IPRT - Internal RTAcpi header.
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#ifndef IPRT_INCLUDED_INTERNAL_acpi_h
38#define IPRT_INCLUDED_INTERNAL_acpi_h
39#ifndef RT_WITHOUT_PRAGMA_ONCE
40# pragma once
41#endif
42
43#include <iprt/acpi.h>
44#include <iprt/list.h>
45
46RT_C_DECLS_BEGIN
47
48/** Pointer to an ACPI AST node. */
49typedef struct RTACPIASTNODE *PRTACPIASTNODE;
50/** Pointer to a const ACPI AST node. */
51typedef const struct RTACPIASTNODE *PCRTACPIASTNODE;
52
53/**
54 * AST node argument type.
55 */
56typedef enum RTACPIASTARGTYPE
57{
58 kAcpiAstArgType_Invalid = 0,
59 kAcpiAstArgType_AstNode,
60 kAcpiAstArgType_NameString,
61 kAcpiAstArgType_Bool,
62 kAcpiAstArgType_U8,
63 kAcpiAstArgType_U16,
64 kAcpiAstArgType_U32,
65 kAcpiAstArgType_U64,
66 kAcpiAstArgType_ObjType,
67 kAcpiAstArgType_RegionSpace,
68 kAcpiAstArgType_FieldAcc,
69 kAcpiAstArgType_FieldUpdate,
70 kAcpiAstArgType_StringLiteral,
71 kAcpiAstArgType_32Bit_Hack = 0x7fffffff
72} RTACPIASTARGTYPE;
73
74
75/**
76 * An AST node argument
77 */
78typedef struct RTACPIASTARG
79{
80 /** Argument type. */
81 RTACPIASTARGTYPE enmType;
82 /** Type dependent data. */
83 union
84 {
85 uintptr_t uPtrInternal;
86 PRTACPIASTNODE pAstNd;
87 const char *pszNameString;
88 const char *pszStrLit;
89 bool f;
90 uint8_t u8;
91 uint16_t u16;
92 uint32_t u32;
93 uint64_t u64;
94 RTACPIOBJTYPE enmObjType;
95 RTACPIOPREGIONSPACE enmRegionSpace;
96 RTACPIFIELDACC enmFieldAcc;
97 RTACPIFIELDUPDATE enmFieldUpdate;
98 } u;
99} RTACPIASTARG;
100/** Pointer to an AST node argument. */
101typedef RTACPIASTARG *PRTACPIASTARG;
102/** Pointer to a const AST node argument. */
103typedef const RTACPIASTARG *PCRTACPIASTARG;
104
105
106/**
107 * The ACPI AST node op.
108 */
109typedef enum RTACPIASTNODEOP
110{
111 kAcpiAstNodeOp_Invalid = 0,
112 kAcpiAstNodeOp_Identifier,
113 kAcpiAstNodeOp_StringLiteral,
114 kAcpiAstNodeOp_Number,
115 kAcpiAstNodeOp_Scope,
116 kAcpiAstNodeOp_Processor,
117 kAcpiAstNodeOp_External,
118 kAcpiAstNodeOp_Method,
119 kAcpiAstNodeOp_Device,
120 kAcpiAstNodeOp_If,
121 kAcpiAstNodeOp_Else,
122 kAcpiAstNodeOp_LAnd,
123 kAcpiAstNodeOp_LEqual,
124 kAcpiAstNodeOp_LGreater,
125 kAcpiAstNodeOp_LGreaterEqual,
126 kAcpiAstNodeOp_LLess,
127 kAcpiAstNodeOp_LLessEqual,
128 kAcpiAstNodeOp_LNot,
129 kAcpiAstNodeOp_LNotEqual,
130 kAcpiAstNodeOp_Zero,
131 kAcpiAstNodeOp_One,
132 kAcpiAstNodeOp_Ones,
133 kAcpiAstNodeOp_Return,
134 kAcpiAstNodeOp_Unicode,
135 kAcpiAstNodeOp_OperationRegion,
136 kAcpiAstNodeOp_Field,
137 kAcpiAstNodeOp_Name,
138 kAcpiAstNodeOp_ResourceTemplate,
139 kAcpiAstNodeOp_Arg0,
140 kAcpiAstNodeOp_Arg1,
141 kAcpiAstNodeOp_Arg2,
142 kAcpiAstNodeOp_Arg3,
143 kAcpiAstNodeOp_Arg4,
144 kAcpiAstNodeOp_Arg5,
145 kAcpiAstNodeOp_Arg6,
146 kAcpiAstNodeOp_Local0,
147 kAcpiAstNodeOp_Local1,
148 kAcpiAstNodeOp_Local2,
149 kAcpiAstNodeOp_Local3,
150 kAcpiAstNodeOp_Local4,
151 kAcpiAstNodeOp_Local5,
152 kAcpiAstNodeOp_Local6,
153 kAcpiAstNodeOp_Local7,
154 kAcpiAstNodeOp_Package,
155 kAcpiAstNodeOp_Buffer,
156 kAcpiAstNodeOp_ToUuid,
157 kAcpiAstNodeOp_DerefOf,
158 kAcpiAstNodeOp_Index,
159 kAcpiAstNodeOp_Store,
160 kAcpiAstNodeOp_Break,
161 kAcpiAstNodeOp_Continue,
162 kAcpiAstNodeOp_Add,
163 kAcpiAstNodeOp_Subtract,
164 kAcpiAstNodeOp_Multiply,
165 kAcpiAstNodeOp_And,
166 kAcpiAstNodeOp_Nand,
167 kAcpiAstNodeOp_Or,
168 kAcpiAstNodeOp_Xor,
169 kAcpiAstNodeOp_ShiftLeft,
170 kAcpiAstNodeOp_ShiftRight,
171 kAcpiAstNodeOp_Not,
172 kAcpiAstNodeOp_Notify,
173 kAcpiAstNodeOp_SizeOf,
174 kAcpiAstNodeOp_While,
175 kAcpiAstNodeOp_Increment,
176 kAcpiAstNodeOp_Decrement,
177 kAcpiAstNodeOp_CondRefOf,
178 kAcpiAstNodeOp_IndexField,
179 kAcpiAstNodeOp_EisaId,
180 kAcpiAstNodeOp_CreateField,
181 kAcpiAstNodeOp_CreateBitField,
182 kAcpiAstNodeOp_CreateByteField,
183 kAcpiAstNodeOp_CreateWordField,
184 kAcpiAstNodeOp_CreateDWordField,
185 kAcpiAstNodeOp_CreateQWordField,
186 kAcpiAstNodeOp_ConcatenateResTemplate,
187 kAcpiAstNodeOp_32Bit_Hack = 0x7fffffff
188} RTACPIASTNODEOP;
189
190
191/**
192 * The core ACPI AST node.
193 */
194typedef struct RTACPIASTNODE
195{
196 /** List node. */
197 RTLISTNODE NdAst;
198 /** The AML op defining the node. */
199 RTACPIASTNODEOP enmOp;
200 /** Some additional flags. */
201 uint32_t fFlags;
202 /** Operation dependent data. */
203 union
204 {
205 /** List of other AST nodes for the opened scope if indicated by the AST flags (RTACPIASTNODE). */
206 RTLISTANCHOR LstScopeNodes;
207 /** Pointer to the identifier if an identifier node. */
208 const char *pszIde;
209 /** Pointer to the string literal if a string literal node. */
210 const char *pszStrLit;
211 /** A number */
212 uint64_t u64;
213 struct
214 {
215 /** Pointer to the field unit list - freed with RTMemFree() when the node is freed. */
216 PRTACPIFIELDENTRY paFields;
217 /** Number of field entries. */
218 uint32_t cFields;
219 } Fields;
220 /** The resource template. */
221 RTACPIRES hAcpiRes;
222 };
223 /** Number of "arguments" for the opcode following (for example Scope(), Method(), If(), etc., i.e. anything requiring () after the keyword ). */
224 uint8_t cArgs;
225 /** Padding */
226 uint8_t abRsvd[2];
227 /** The AST node arguments - variable in size. */
228 RTACPIASTARG aArgs[1];
229} RTACPIASTNODE;
230
231/** Default flags. */
232#define RTACPI_AST_NODE_F_DEFAULT 0
233/** The AST node opens a new scope. */
234#define RTACPI_AST_NODE_F_NEW_SCOPE RT_BIT_32(0)
235/** The AST node has an associated namespace entry. */
236#define RTACPI_AST_NODE_F_NS_ENTRY RT_BIT_32(1)
237
238
239/**
240 * External declaration.
241 */
242typedef struct RTACPIASLEXTERNAL
243{
244 /** List node for the list of externals. */
245 RTLISTNODE NdExternal;
246 /** The object type. */
247 RTACPIOBJTYPE enmObjType;
248 /** For methods this will hold the argument count. */
249 uint32_t cArgs;
250 /** The name as parsed from the source file. */
251 const char *pszName;
252 /** Size of the full name path in characters excluding the terminating zero. */
253 size_t cchNamePath;
254 /** The name path - variable in size. */
255 char szNamePath[1];
256} RTACPIASLEXTERNAL;
257/** Pointer to an external declaration. */
258typedef RTACPIASLEXTERNAL *PRTACPIASLEXTERNAL;
259/** Pointer to a const external declaration. */
260typedef const RTACPIASLEXTERNAL *PCRTACPIASLEXTERNAL;
261
262
263
264/** Pointer to an ACPI namespace entry. */
265typedef struct RTACPINSENTRY *PRTACPINSENTRY;
266
267
268/**
269 * An ACPI namespace entry.
270 */
271typedef struct RTACPINSENTRY
272{
273 /** Node for the namespace list. */
274 RTLISTNODE NdNs;
275 /** Pointer to the parent in the namespace, NULL if this is the root. */
276 PRTACPINSENTRY pParent;
277 /** The name segment identifying the entry. */
278 char achNameSeg[4];
279 /** Flag whether this points to an AST node or an external. */
280 bool fAstNd;
281 /** Type dependent data. */
282 union
283 {
284 /** The AST node associated with this namespace entry. */
285 PCRTACPIASTNODE pAstNd;
286 /** Pointer to the external declaration. */
287 PCRTACPIASLEXTERNAL pExternal;
288 };
289 /** Bit offset for resource fields. */
290 uint32_t offBits;
291 /** Bit count for resource fields. */
292 uint32_t cBits;
293 /** List of namespace entries below this entry. */
294 RTLISTANCHOR LstNsEntries;
295} RTACPINSENTRY;
296/** Pointer to a const ACPI namespace entry. */
297typedef const RTACPINSENTRY *PCRTACPINSENTRY;
298
299
300/**
301 * An ACPI namespace root
302 */
303typedef struct RTACPINSROOT
304{
305 /** Root namespace entry. */
306 RTACPINSENTRY RootEntry;
307 /** Current top of the stack. */
308 uint8_t idxNsStack;
309 /** Stack of name space entries for navigation - 255 entries
310 * is enough because a path name can only be encoded with 255 entries. */
311 PRTACPINSENTRY aNsStack[255];
312} RTACPINSROOT;
313/** Pointer to an ACPI namespace root. */
314typedef RTACPINSROOT *PRTACPINSROOT;
315/** Pointer to a const ACPI namespace root. */
316typedef const RTACPINSROOT *PCRTACPINSROOT;
317
318
319/**
320 * Allocates a new ACPI AST node initialized with the given properties.
321 *
322 * @returns Pointer to the new ACPI AST node or NULL if out of memory.
323 * @param enmOp The operation of the AST node.
324 * @param fFlags Flags for this node.
325 * @param cArgs Number of arguments to allocate.
326 */
327DECLHIDDEN(PRTACPIASTNODE) rtAcpiAstNodeAlloc(RTACPIASTNODEOP enmOp, uint32_t fFlags, uint8_t cArgs);
328
329
330/**
331 * Frees the given AST node and all children nodes linked to this one.
332 *
333 * @param pAstNd The AST node to free.
334 */
335DECLHIDDEN(void) rtAcpiAstNodeFree(PRTACPIASTNODE pAstNd);
336
337
338/**
339 * Does a few transformations on the given AST node and its children where required.
340 *
341 * @returns IPRT status.
342 * @param pAstNd The AST node to transform.
343 * @param pErrInfo Some additional error information on failure.
344 *
345 * @note This currently only implements merging if ... else ... nodes but can be extended to
346 * also do some optimizations and proper checking.
347 */
348DECLHIDDEN(int) rtAcpiAstNodeTransform(PRTACPIASTNODE pAstNd, PRTERRINFO pErrInfo);
349
350
351/**
352 * Creates a new namespace and returns the root.
353 *
354 * @returns Pointer to the namespace root or NULL if out of memory.
355 */
356DECLHIDDEN(PRTACPINSROOT) rtAcpiNsCreate(void);
357
358
359/**
360 * Destroys the given namespace, freeing all allocated resources,
361 * including all namespace entries int it.
362 *
363 * @param pNsRoot The namespace root to destroy.
364 */
365DECLHIDDEN(void) rtAcpiNsDestroy(PRTACPINSROOT pNsRoot);
366
367
368/**
369 * Adds a new namespace entry to the given name space - AST node variant.
370 *
371 * @returns IPRT status code.
372 * @param pNsRoot The namespace root to add the entry to.
373 * @param pszNameString An ACPI NameString (either segment or path).
374 * @param pAstNd The AST node to associate with the entry.
375 * @param fSwitchTo Flag whether to switch the current point for the namespace to this entry.
376 */
377DECLHIDDEN(int) rtAcpiNsAddEntryAstNode(PRTACPINSROOT pNsRoot, const char *pszNameString, PCRTACPIASTNODE pAstNd, bool fSwitchTo);
378
379
380/**
381 * Adds a new namespace entry to the given name space - resource field.
382 *
383 * @returns IPRT status code.
384 * @param pNsRoot The namespace root to add the entry to.
385 * @param pszNameString An ACPI NameString (either segment or path).
386 * @param offBits Bit offset from the beginning of the resource.
387 * @param cBits NUmber of bits this resource field has.
388 */
389DECLHIDDEN(int) rtAcpiNsAddEntryRsrcField(PRTACPINSROOT pNsRoot, const char *pszNameString, uint32_t offBits, uint32_t cBits);
390
391
392/**
393 * Adds a new namespace entry to the given name space - resource field.
394 *
395 * @returns IPRT status code.
396 * @param pNsRoot The namespace root to add the entry to.
397 * @param pszNameString An ACPI NameString (either segment or path).
398 * @param offBits Bit offset from the beginning of the resource.
399 * @param cBits NUmber of bits this resource field has.
400 */
401DECLHIDDEN(int) rtAcpiNsAddEntryExternal(PRTACPINSROOT pNsRoot, const char *pszNameString, PCRTACPIASLEXTERNAL pExternal);
402
403
404/**
405 * Queries the name path for the given name string based on the current scope.
406 *
407 * @returns IPRT status code.
408 * @retval VERR_NOT_FOUND if the name string can't be resolved to a name path with the given namespace.
409 * @retval VERR_BUFFER_OVERFLOW if the buffer for holding the name path is too small. pcchNamePath will
410 * hold the required number of characters, excluding the zero temrinator.
411 * @param pNsRoot The namespace root.
412 * @param pszNameString The name string to query the name path for.
413 * @param pachNamePath Where to store the name path (including zero terminator), or NULL if the size is queried.
414 * @param pcchNamePath Holds the size of the name path buffer on input, on successful return
415 * holds the actual length of the name path excluding the zero terminator.
416 */
417DECLHIDDEN(int) rtAcpiNsQueryNamePathForNameString(PRTACPINSROOT pNsRoot, const char *pszNameString, char *pachNamePath, size_t *pcchNamePath);
418
419
420/**
421 * Pops the current name space entry from the stack and returns to the previous one.
422 *
423 * @returns IPRT status code.
424 * @param pNsRoot The namespace root.
425 */
426DECLHIDDEN(int) rtAcpiNsPop(PRTACPINSROOT pNsRoot);
427
428
429/**
430 * Looks up the given name string and returns the namespace entry if found.
431 *
432 * @returns Pointer to the namespace entry or NULL if not found.
433 * @param pNsRoot The namespace root.
434 * @param pszNameString The ACPI NameString (either segment or path) to lookup.
435 */
436DECLHIDDEN(PCRTACPINSENTRY) rtAcpiNsLookup(PRTACPINSROOT pNsRoot, const char *pszNameString);
437
438
439/**
440 * Dumps the given AST node and everything it references to the given ACPI table.
441 *
442 * @returns IPRT status code.
443 * @param pAstNd The AST node to dump.
444 * @param hAcpiTbl The ACPI table to dump to.
445 */
446DECLHIDDEN(int) rtAcpiAstDumpToTbl(PCRTACPIASTNODE pAstNd, RTACPITBL hAcpiTbl);
447
448
449/**
450 * Worker for decompiling AML bytecode to the ASL source language.
451 *
452 * @returns IPRT status code.
453 * @param hVfsIosOut The VFS I/O stream handle to output the result to.
454 * @param hVfsIosIn The VFS I/O stream handle to read the ACPI table from.
455 * @param pErrInfo Where to return additional error information.
456 */
457DECLHIDDEN(int) rtAcpiTblConvertFromAmlToAsl(RTVFSIOSTREAM hVfsIosOut, RTVFSIOSTREAM hVfsIosIn, PRTERRINFO pErrInfo);
458
459
460/**
461 * Worker for compiling ASL to the AML bytecode.
462 *
463 * @returns IPRT status code.
464 * @param hVfsIosOut The VFS I/O stream handle to output the result to.
465 * @param hVfsIosIn The VFS I/O stream handle to read the ACPI table from.
466 * @param pErrInfo Where to return additional error information.
467 */
468DECLHIDDEN(int) rtAcpiTblConvertFromAslToAml(RTVFSIOSTREAM hVfsIosOut, RTVFSIOSTREAM hVfsIosIn, PRTERRINFO pErrInfo);
469
470
471RT_C_DECLS_END
472
473#endif /* !IPRT_INCLUDED_INTERNAL_acpi_h */
474
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