VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/acpi/acpi-compiler.cpp@ 108280

Last change on this file since 108280 was 108280, checked in by vboxsync, 3 weeks ago

Runtime/RTScriptLex*: Implement support for optionally returning parsed comments (single and multi line) as tokens when enabled in the lexer config, bugref:10321

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 155.6 KB
Line 
1/* $Id: acpi-compiler.cpp 108280 2025-02-19 09:28:41Z vboxsync $ */
2/** @file
3 * IPRT - Advanced Configuration and Power Interface (ACPI) Table generation API.
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/acpi.h>
43#include <iprt/asm.h>
44#include <iprt/buildconfig.h>
45#include <iprt/ctype.h>
46#include <iprt/err.h>
47#include <iprt/file.h>
48#include <iprt/list.h>
49#include <iprt/mem.h>
50#include <iprt/script.h>
51#include <iprt/string.h>
52#include <iprt/uuid.h>
53
54#include <iprt/formats/acpi-aml.h>
55#include <iprt/formats/acpi-resources.h>
56
57#include "internal/acpi.h"
58
59
60/*********************************************************************************************************************************
61* Defined Constants And Macros *
62*********************************************************************************************************************************/
63
64
65/*********************************************************************************************************************************
66* Structures and Typedefs *
67*********************************************************************************************************************************/
68
69/**
70 * Terminals in the ACPI ASL lnaguage like keywords, operators and punctuators.
71 */
72typedef enum RTACPIASLTERMINAL
73{
74 RTACPIASLTERMINAL_INVALID = 2047,
75
76 /** Miscelleanous keywords not appearing in the parser table. */
77 RTACPIASLTERMINAL_KEYWORD_DEFINITION_BLOCK,
78 RTACPIASLTERMINAL_KEYWORD_UNKNOWN_OBJ,
79 RTACPIASLTERMINAL_KEYWORD_INT_OBJ,
80 RTACPIASLTERMINAL_KEYWORD_STR_OBJ,
81 RTACPIASLTERMINAL_KEYWORD_BUFF_OBJ,
82 RTACPIASLTERMINAL_KEYWORD_PKG_OBJ,
83 RTACPIASLTERMINAL_KEYWORD_FIELD_UNIT_OBJ,
84 RTACPIASLTERMINAL_KEYWORD_DEVICE_OBJ,
85 RTACPIASLTERMINAL_KEYWORD_EVENT_OBJ,
86 RTACPIASLTERMINAL_KEYWORD_METHOD_OBJ,
87 RTACPIASLTERMINAL_KEYWORD_MUTEX_OBJ,
88 RTACPIASLTERMINAL_KEYWORD_OP_REGION_OBJ,
89 RTACPIASLTERMINAL_KEYWORD_POWER_RES_OBJ,
90 RTACPIASLTERMINAL_KEYWORD_THERMAL_ZONE_OBJ,
91 RTACPIASLTERMINAL_KEYWORD_BUFF_FIELD_OBJ,
92 RTACPIASLTERMINAL_KEYWORD_PROCESSOR_OBJ,
93 RTACPIASLTERMINAL_KEYWORD_SERIALIZED,
94 RTACPIASLTERMINAL_KEYWORD_NOT_SERIALIZED,
95 RTACPIASLTERMINAL_KEYWORD_SYSTEM_IO,
96 RTACPIASLTERMINAL_KEYWORD_SYSTEM_MEMORY,
97 RTACPIASLTERMINAL_KEYWORD_PCI_CONFIG,
98 RTACPIASLTERMINAL_KEYWORD_EMBEDDED_CONTROL,
99 RTACPIASLTERMINAL_KEYWORD_SMBUS,
100 RTACPIASLTERMINAL_KEYWORD_SYSTEM_CMOS,
101 RTACPIASLTERMINAL_KEYWORD_PCI_BAR_TARGET,
102 RTACPIASLTERMINAL_KEYWORD_IPMI,
103 RTACPIASLTERMINAL_KEYWORD_GENERAL_PURPOSE_IO,
104 RTACPIASLTERMINAL_KEYWORD_GENERIC_SERIAL_BUS,
105 RTACPIASLTERMINAL_KEYWORD_PCC,
106 RTACPIASLTERMINAL_KEYWORD_PRM,
107 RTACPIASLTERMINAL_KEYWORD_FFIXED_HW,
108
109 RTACPIASLTERMINAL_KEYWORD_ANY_ACC,
110 RTACPIASLTERMINAL_KEYWORD_BYTE_ACC,
111 RTACPIASLTERMINAL_KEYWORD_WORD_ACC,
112 RTACPIASLTERMINAL_KEYWORD_DWORD_ACC,
113 RTACPIASLTERMINAL_KEYWORD_QWORD_ACC,
114 RTACPIASLTERMINAL_KEYWORD_BUFFER_ACC,
115
116 RTACPIASLTERMINAL_KEYWORD_LOCK,
117 RTACPIASLTERMINAL_KEYWORD_NO_LOCK,
118
119 RTACPIASLTERMINAL_KEYWORD_PRESERVE,
120 RTACPIASLTERMINAL_KEYWORD_WRITE_AS_ONES,
121 RTACPIASLTERMINAL_KEYWORD_WRITE_AS_ZEROES,
122
123 RTACPIASLTERMINAL_KEYWORD_OFFSET,
124
125 RTACPIASLTERMINAL_KEYWORD_MEMORY32_FIXED,
126 RTACPIASLTERMINAL_KEYWORD_READONLY,
127 RTACPIASLTERMINAL_KEYWORD_READWRITE,
128
129 RTACPIASLTERMINAL_KEYWORD_IRQ,
130 RTACPIASLTERMINAL_KEYWORD_IRQ_NO_FLAGS,
131 RTACPIASLTERMINAL_KEYWORD_EDGE,
132 RTACPIASLTERMINAL_KEYWORD_LEVEL,
133 RTACPIASLTERMINAL_KEYWORD_ACTIVE_HIGH,
134 RTACPIASLTERMINAL_KEYWORD_ACTIVE_LOW,
135 RTACPIASLTERMINAL_KEYWORD_SHARED,
136 RTACPIASLTERMINAL_KEYWORD_EXCLUSIVE,
137 RTACPIASLTERMINAL_KEYWORD_SHARED_AND_WAKE,
138 RTACPIASLTERMINAL_KEYWORD_EXCLUSIVE_AND_WAKE,
139
140 RTACPIASLTERMINAL_KEYWORD_IO,
141 RTACPIASLTERMINAL_KEYWORD_DECODE_10,
142 RTACPIASLTERMINAL_KEYWORD_DECODE_16,
143
144 RTACPIASLTERMINAL_KEYWORD_DMA,
145 RTACPIASLTERMINAL_KEYWORD_COMPATIBILITY,
146 RTACPIASLTERMINAL_KEYWORD_TYPE_A,
147 RTACPIASLTERMINAL_KEYWORD_TYPE_B,
148 RTACPIASLTERMINAL_KEYWORD_TYPE_F,
149 RTACPIASLTERMINAL_KEYWORD_BUS_MASTER,
150 RTACPIASLTERMINAL_KEYWORD_NOT_BUS_MASTER,
151 RTACPIASLTERMINAL_KEYWORD_TRANSFER_8,
152 RTACPIASLTERMINAL_KEYWORD_TRANSFER_16,
153 RTACPIASLTERMINAL_KEYWORD_TRANSFER_8_16,
154
155 RTACPIASLTERMINAL_KEYWORD_WORD_BUS_NUMBER,
156 RTACPIASLTERMINAL_KEYWORD_MIN_FIXED,
157 RTACPIASLTERMINAL_KEYWORD_MIN_NOT_FIXED,
158 RTACPIASLTERMINAL_KEYWORD_MAX_FIXED,
159 RTACPIASLTERMINAL_KEYWORD_MAX_NOT_FIXED,
160 RTACPIASLTERMINAL_KEYWORD_RESOURCE_CONSUMER,
161 RTACPIASLTERMINAL_KEYWORD_RESOURCE_PRODUCER,
162 RTACPIASLTERMINAL_KEYWORD_POS_DECODE,
163 RTACPIASLTERMINAL_KEYWORD_SUB_DECODE,
164
165 RTACPIASLTERMINAL_KEYWORD_WORD_IO,
166 RTACPIASLTERMINAL_KEYWORD_ISA_ONLY,
167 RTACPIASLTERMINAL_KEYWORD_NON_ISA_ONLY,
168 RTACPIASLTERMINAL_KEYWORD_ENTIRE_RANGE,
169 RTACPIASLTERMINAL_KEYWORD_TYPE_TRANSLATION,
170 RTACPIASLTERMINAL_KEYWORD_TYPE_STATIC,
171 RTACPIASLTERMINAL_KEYWORD_SPARSE_TRANSLATION,
172 RTACPIASLTERMINAL_KEYWORD_DENSE_TRANSLATION,
173
174 RTACPIASLTERMINAL_KEYWORD_DWORD_MEMORY,
175 RTACPIASLTERMINAL_KEYWORD_QWORD_MEMORY,
176 RTACPIASLTERMINAL_KEYWORD_CACHEABLE,
177 RTACPIASLTERMINAL_KEYWORD_WRITE_COMBINING,
178 RTACPIASLTERMINAL_KEYWORD_PREFETCHABLE,
179 RTACPIASLTERMINAL_KEYWORD_NON_CACHEABLE,
180 RTACPIASLTERMINAL_KEYWORD_ADDRESS_RANGE_MEMORY,
181 RTACPIASLTERMINAL_KEYWORD_ADDRESS_RANGE_NVS,
182 RTACPIASLTERMINAL_KEYWORD_ADDRESS_RANGE_ACPI,
183 RTACPIASLTERMINAL_KEYWORD_ADDRESS_RANGE_RESERVED,
184
185 RTACPIASLTERMINAL_PUNCTUATOR_COMMA,
186 RTACPIASLTERMINAL_PUNCTUATOR_OPEN_BRACKET,
187 RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_BRACKET,
188 RTACPIASLTERMINAL_PUNCTUATOR_OPEN_CURLY_BRACKET,
189 RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_CURLY_BRACKET
190
191} RTACPIASLTERMINAL;
192/** Pointer to a terminal enum. */
193typedef RTACPIASLTERMINAL *PRTACPIASLTERMINAL;
194/** Pointer to a const terminal enum. */
195typedef const RTACPIASLTERMINAL *PCRTACPIASLTERMINAL;
196
197
198/**
199 * The ACPI ASL compilation unit state.
200 */
201typedef struct RTACPIASLCU
202{
203 /** The lexer handle. */
204 RTSCRIPTLEX hLexSource;
205 /** The VFS I/O input stream. */
206 RTVFSIOSTREAM hVfsIosIn;
207 /** The ACPI table handle. */
208 RTACPITBL hAcpiTbl;
209 /** Error information. */
210 PRTERRINFO pErrInfo;
211 /** List of external declarations. */
212 RTLISTANCHOR LstExternals;
213 /** List of AST nodes for the DefinitionBlock() scope. */
214 RTLISTANCHOR LstStmts;
215 /** The ACPI namespace. */
216 PRTACPINSROOT pNs;
217} RTACPIASLCU;
218/** Pointer to an ACPI ASL compilation unit state. */
219typedef RTACPIASLCU *PRTACPIASLCU;
220/** Pointer to a constant ACPI ASL compilation unit state. */
221typedef const RTACPIASLCU *PCRTACPIASLCU;
222
223
224/** Pointer to a const ASL keyword encoding entry. */
225typedef const struct RTACPIASLKEYWORD *PCRTACPIASLKEYWORD;
226
227/**
228 * ACPI ASL -> AST parse callback.
229 *
230 * @returns IPRT status code.
231 * @param pThis ACPI ASL compiler state.
232 * @param pKeyword The keyword entry being processed.
233 * @param pAstNd The AST node to initialize.
234 */
235typedef DECLCALLBACKTYPE(int, FNRTACPITBLASLPARSE,(PRTACPIASLCU pThis, PCRTACPIASLKEYWORD pKeyword, PRTACPIASTNODE pAstNd));
236/** Pointer to a ACPI AML -> ASL decode callback. */
237typedef FNRTACPITBLASLPARSE *PFNRTACPITBLASLPARSE;
238
239
240/**
241 * ASL keyword encoding entry.
242 */
243typedef struct RTACPIASLKEYWORD
244{
245 /** Name of the opcode. */
246 const char *pszOpc;
247 /** The parsing callback to call, optional.
248 * If not NULL this will have priority over the default parsing. */
249 PFNRTACPITBLASLPARSE pfnParse;
250 /** Number of arguments required. */
251 uint8_t cArgsReq;
252 /** Number of optional arguments. */
253 uint8_t cArgsOpt;
254 /** Flags for the opcode. */
255 uint32_t fFlags;
256 /** Argument type for the required arguments. */
257 RTACPIASTARGTYPE aenmTypes[5];
258 /** Arguments for optional arguments, including the default value if absent. */
259 RTACPIASTARG aArgsOpt[3];
260} RTACPIASLKEYWORD;
261/** Pointer to a ASL keyword encoding entry. */
262typedef RTACPIASLKEYWORD *PRTACPIASLKEYWORD;
263
264
265/*********************************************************************************************************************************
266* Global Variables *
267*********************************************************************************************************************************/
268
269static DECLCALLBACK(int) rtAcpiAslLexerParseNumber(RTSCRIPTLEX hScriptLex, char ch, PRTSCRIPTLEXTOKEN pToken, void *pvUser);
270static DECLCALLBACK(int) rtAcpiAslLexerParseNameString(RTSCRIPTLEX hScriptLex, char ch, PRTSCRIPTLEXTOKEN pToken, void *pvUser);
271
272
273static const char *s_aszSingleStart[] =
274{
275 "//",
276 NULL
277};
278
279
280static const char *s_aszMultiStart[] =
281{
282 "/*",
283 NULL
284};
285
286
287static const char *s_aszMultiEnd[] =
288{
289 "*/",
290 NULL
291};
292
293
294static const RTSCRIPTLEXTOKMATCH s_aMatches[] =
295{
296 /* Keywords */
297 { RT_STR_TUPLE("SCOPE"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_Scope },
298 { RT_STR_TUPLE("PROCESSOR"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_Processor },
299 { RT_STR_TUPLE("EXTERNAL"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_External },
300 { RT_STR_TUPLE("METHOD"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_Method },
301 { RT_STR_TUPLE("DEVICE"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_Device },
302 { RT_STR_TUPLE("IF"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_If },
303 { RT_STR_TUPLE("ELSE"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_Else },
304 { RT_STR_TUPLE("LAND"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_LAnd },
305 { RT_STR_TUPLE("LOR"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_LOr },
306 { RT_STR_TUPLE("LEQUAL"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_LEqual },
307 { RT_STR_TUPLE("LGREATER"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_LGreater },
308 { RT_STR_TUPLE("LGREATEREQUAL"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_LGreaterEqual },
309 { RT_STR_TUPLE("LLESS"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_LLess },
310 { RT_STR_TUPLE("LLESSEQUAL"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_LLessEqual },
311 { RT_STR_TUPLE("LNOT"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_LNot },
312 { RT_STR_TUPLE("LNOTEQUAL"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_LNotEqual },
313 { RT_STR_TUPLE("ZERO"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_Zero },
314 { RT_STR_TUPLE("ONE"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_One },
315 { RT_STR_TUPLE("ONES"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_Ones },
316 { RT_STR_TUPLE("RETURN"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_Return },
317 { RT_STR_TUPLE("UNICODE"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_Unicode },
318 { RT_STR_TUPLE("OPERATIONREGION"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_OperationRegion },
319 { RT_STR_TUPLE("FIELD"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_Field },
320 { RT_STR_TUPLE("NAME"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_Name },
321 { RT_STR_TUPLE("RESOURCETEMPLATE"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_ResourceTemplate },
322 { RT_STR_TUPLE("ARG0"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_Arg0 },
323 { RT_STR_TUPLE("ARG1"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_Arg1 },
324 { RT_STR_TUPLE("ARG2"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_Arg2 },
325 { RT_STR_TUPLE("ARG3"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_Arg3 },
326 { RT_STR_TUPLE("ARG4"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_Arg4 },
327 { RT_STR_TUPLE("ARG5"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_Arg5 },
328 { RT_STR_TUPLE("ARG6"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_Arg6 },
329 { RT_STR_TUPLE("LOCAL0"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_Local0 },
330 { RT_STR_TUPLE("LOCAL1"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_Local1 },
331 { RT_STR_TUPLE("LOCAL2"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_Local2 },
332 { RT_STR_TUPLE("LOCAL3"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_Local3 },
333 { RT_STR_TUPLE("LOCAL4"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_Local4 },
334 { RT_STR_TUPLE("LOCAL5"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_Local5 },
335 { RT_STR_TUPLE("LOCAL6"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_Local6 },
336 { RT_STR_TUPLE("LOCAL7"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_Local7 },
337 { RT_STR_TUPLE("PACKAGE"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_Package },
338 { RT_STR_TUPLE("BUFFER"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_Buffer },
339 { RT_STR_TUPLE("TOUUID"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_ToUuid },
340 { RT_STR_TUPLE("DEREFOF"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_DerefOf },
341 { RT_STR_TUPLE("INDEX"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_Index },
342 { RT_STR_TUPLE("STORE"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_Store },
343 { RT_STR_TUPLE("BREAK"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_Break },
344 { RT_STR_TUPLE("CONTINUE"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_Continue },
345 { RT_STR_TUPLE("ADD"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_Add },
346 { RT_STR_TUPLE("SUBTRACT"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_Subtract },
347 { RT_STR_TUPLE("MULTIPLY"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_Multiply },
348 { RT_STR_TUPLE("AND"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_And },
349 { RT_STR_TUPLE("NAND"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_Nand },
350 { RT_STR_TUPLE("OR"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_Or },
351 { RT_STR_TUPLE("XOR"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_Xor },
352 { RT_STR_TUPLE("NOT"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_Not },
353 { RT_STR_TUPLE("SHIFTLEFT"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_ShiftLeft },
354 { RT_STR_TUPLE("SHIFTRIGHT"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_ShiftRight },
355 { RT_STR_TUPLE("NOTIFY"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_Notify },
356 { RT_STR_TUPLE("SIZEOF"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_SizeOf },
357 { RT_STR_TUPLE("WHILE"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_While },
358 { RT_STR_TUPLE("INCREMENT"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_Increment },
359 { RT_STR_TUPLE("DECREMENT"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_Decrement },
360 { RT_STR_TUPLE("CONDREFOF"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_CondRefOf },
361 { RT_STR_TUPLE("INDEXFIELD"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_IndexField },
362 { RT_STR_TUPLE("EISAID"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_EisaId },
363 { RT_STR_TUPLE("CREATEFIELD"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_CreateField },
364 { RT_STR_TUPLE("CREATEBITFIELD"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_CreateBitField },
365 { RT_STR_TUPLE("CREATEBYTEFIELD"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_CreateByteField },
366 { RT_STR_TUPLE("CREATEWORDFIELD"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_CreateWordField },
367 { RT_STR_TUPLE("CREATEDWORDFIELD"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_CreateDWordField },
368 { RT_STR_TUPLE("CREATEQWORDFIELD"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_CreateQWordField },
369 { RT_STR_TUPLE("CONCATENATERESTEMPLATE"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_ConcatenateResTemplate },
370 { RT_STR_TUPLE("FINDSETLEFTBIT"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_FindSetLeftBit },
371 { RT_STR_TUPLE("FINDSETRIGHTBIT"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, kAcpiAstNodeOp_FindSetRightBit },
372
373 /* Keywords not in the operation parser table. */
374 { RT_STR_TUPLE("DEFINITIONBLOCK"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_DEFINITION_BLOCK },
375 { RT_STR_TUPLE("UNKNOWNOBJ"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_UNKNOWN_OBJ },
376 { RT_STR_TUPLE("INTOBJ"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_INT_OBJ },
377 { RT_STR_TUPLE("STROBJ"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_STR_OBJ },
378 { RT_STR_TUPLE("BUFFOBJ"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_BUFF_OBJ },
379 { RT_STR_TUPLE("PKGOBJ"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_PKG_OBJ },
380 { RT_STR_TUPLE("FIELDUNITOBJ"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_FIELD_UNIT_OBJ },
381 { RT_STR_TUPLE("DEVICEOBJ"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_DEVICE_OBJ },
382 { RT_STR_TUPLE("EVENTOBJ"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_EVENT_OBJ },
383 { RT_STR_TUPLE("METHODOBJ"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_METHOD_OBJ },
384 { RT_STR_TUPLE("MUTEXOBJ"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_MUTEX_OBJ },
385 { RT_STR_TUPLE("OPREGIONOBJ"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_OP_REGION_OBJ },
386 { RT_STR_TUPLE("POWERRESOBJ"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_POWER_RES_OBJ },
387 { RT_STR_TUPLE("THERMALZONEOBJ"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_THERMAL_ZONE_OBJ },
388 { RT_STR_TUPLE("BUFFFIELDOBJ"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_BUFF_FIELD_OBJ },
389 { RT_STR_TUPLE("PROCESSOROBJ"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_PROCESSOR_OBJ },
390
391 { RT_STR_TUPLE("SERIALIZED"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_SERIALIZED },
392 { RT_STR_TUPLE("NOTSERIALIZED"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_NOT_SERIALIZED },
393
394 { RT_STR_TUPLE("SYSTEMIO"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_SYSTEM_IO },
395 { RT_STR_TUPLE("SYSTEMMEMORY"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_SYSTEM_MEMORY },
396 { RT_STR_TUPLE("PCI_CONFIG"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_PCI_CONFIG },
397 { RT_STR_TUPLE("EMBEDDEDCONTROL"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_EMBEDDED_CONTROL },
398 { RT_STR_TUPLE("SMBUS"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_SMBUS },
399 { RT_STR_TUPLE("SYSTEMCMOS"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_SYSTEM_CMOS },
400 { RT_STR_TUPLE("PCIBARTARGET"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_PCI_BAR_TARGET },
401 { RT_STR_TUPLE("IPMI"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_IPMI },
402 { RT_STR_TUPLE("GENERALPURPOSEIO"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_GENERAL_PURPOSE_IO },
403 { RT_STR_TUPLE("GENERICSERIALBUS"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_GENERIC_SERIAL_BUS },
404 { RT_STR_TUPLE("PCC"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_PCC },
405 { RT_STR_TUPLE("PRM"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_PRM },
406 { RT_STR_TUPLE("FFIXEDHW"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_FFIXED_HW },
407
408 { RT_STR_TUPLE("ANYACC"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_ANY_ACC },
409 { RT_STR_TUPLE("BYTEACC"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_BYTE_ACC },
410 { RT_STR_TUPLE("WORDACC"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_WORD_ACC },
411 { RT_STR_TUPLE("DWORDACC"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_DWORD_ACC },
412 { RT_STR_TUPLE("QWORDACC"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_QWORD_ACC },
413 { RT_STR_TUPLE("BUFFERACC"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_BUFFER_ACC },
414
415 { RT_STR_TUPLE("LOCK"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_LOCK },
416 { RT_STR_TUPLE("NOLOCK"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_NO_LOCK },
417
418 { RT_STR_TUPLE("PRESERVE"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_PRESERVE },
419 { RT_STR_TUPLE("WRITEASONES"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_WRITE_AS_ONES },
420 { RT_STR_TUPLE("WRITEASZEROS"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_WRITE_AS_ZEROES },
421
422 { RT_STR_TUPLE("OFFSET"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_OFFSET },
423 { RT_STR_TUPLE("MEMORY32FIXED"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_MEMORY32_FIXED },
424 { RT_STR_TUPLE("READONLY"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_READONLY },
425 { RT_STR_TUPLE("READWRITE"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_READWRITE },
426
427 { RT_STR_TUPLE("IRQ"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_IRQ },
428 { RT_STR_TUPLE("IRQNOFLAGS"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_IRQ_NO_FLAGS },
429 { RT_STR_TUPLE("EDGE"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_EDGE },
430 { RT_STR_TUPLE("LEVEL"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_LEVEL },
431 { RT_STR_TUPLE("ACTIVEHIGH"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_ACTIVE_HIGH },
432 { RT_STR_TUPLE("ACTIVELOW"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_ACTIVE_LOW },
433 { RT_STR_TUPLE("SHARED"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_SHARED },
434 { RT_STR_TUPLE("EXCLUSIVE"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_EXCLUSIVE },
435 { RT_STR_TUPLE("SHAREDANDWAKE"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_SHARED_AND_WAKE },
436 { RT_STR_TUPLE("EXCLUSIVEANDWAKE"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_EXCLUSIVE_AND_WAKE },
437
438 { RT_STR_TUPLE("IO"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_IO },
439 { RT_STR_TUPLE("DECODE10"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_DECODE_10 },
440 { RT_STR_TUPLE("DECODE16"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_DECODE_16 },
441
442 { RT_STR_TUPLE("DMA"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_DMA },
443 { RT_STR_TUPLE("COMPATIBILITY"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_COMPATIBILITY },
444 { RT_STR_TUPLE("TYPEA"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_TYPE_A },
445 { RT_STR_TUPLE("TYPEB"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_TYPE_B },
446 { RT_STR_TUPLE("TYPEF"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_TYPE_F },
447 { RT_STR_TUPLE("BUSMASTER"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_BUS_MASTER },
448 { RT_STR_TUPLE("NOTBUSMASTER"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_NOT_BUS_MASTER },
449 { RT_STR_TUPLE("TRANSFER8"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_TRANSFER_8 },
450 { RT_STR_TUPLE("TRANSFER16"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_TRANSFER_16 },
451 { RT_STR_TUPLE("TRANSFER8_16"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_TRANSFER_8_16 },
452
453 { RT_STR_TUPLE("WORDBUSNUMBER"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_WORD_BUS_NUMBER },
454 { RT_STR_TUPLE("MINFIXED"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_MIN_FIXED },
455 { RT_STR_TUPLE("MINNOTFIXED"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_MIN_NOT_FIXED },
456 { RT_STR_TUPLE("MAXFIXED"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_MAX_FIXED },
457 { RT_STR_TUPLE("MAXNOTFIXED"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_MAX_NOT_FIXED },
458 { RT_STR_TUPLE("RESOURCECONSUMER"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_RESOURCE_CONSUMER },
459 { RT_STR_TUPLE("RESOURCEPRODUCER"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_RESOURCE_PRODUCER },
460 { RT_STR_TUPLE("POSDECODE"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_POS_DECODE },
461 { RT_STR_TUPLE("SUBDECODE"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_SUB_DECODE },
462
463 { RT_STR_TUPLE("WORDIO"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_WORD_IO },
464 { RT_STR_TUPLE("ISAONLY"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_ISA_ONLY },
465 { RT_STR_TUPLE("NONISAONLY"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_NON_ISA_ONLY },
466 { RT_STR_TUPLE("ENTIRERANGE"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_ENTIRE_RANGE },
467 { RT_STR_TUPLE("TYPETRANSLATION"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_TYPE_TRANSLATION },
468 { RT_STR_TUPLE("TYPESTATIC"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_TYPE_STATIC },
469 { RT_STR_TUPLE("SPARSETRANSLATION"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_SPARSE_TRANSLATION },
470 { RT_STR_TUPLE("DENSETRANSLATION"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_DENSE_TRANSLATION },
471
472 { RT_STR_TUPLE("DWORDMEMORY"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_DWORD_MEMORY },
473 { RT_STR_TUPLE("QWORDMEMORY"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_QWORD_MEMORY },
474 { RT_STR_TUPLE("CACHEABLE"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_CACHEABLE },
475 { RT_STR_TUPLE("WRITECOMBINING"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_WRITE_COMBINING },
476 { RT_STR_TUPLE("PREFETCHABLE"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_PREFETCHABLE },
477 { RT_STR_TUPLE("NONCACHEABLE"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_NON_CACHEABLE },
478 { RT_STR_TUPLE("ADDRESSRANGEMEMORY"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_ADDRESS_RANGE_MEMORY },
479 { RT_STR_TUPLE("ADDRESSRANGENVS"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_ADDRESS_RANGE_NVS },
480 { RT_STR_TUPLE("ADDRESSRANGEACPI"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_ADDRESS_RANGE_ACPI },
481 { RT_STR_TUPLE("ADDRESSRANGERESERVED"), RTSCRIPTLEXTOKTYPE_KEYWORD, true, RTACPIASLTERMINAL_KEYWORD_ADDRESS_RANGE_RESERVED },
482
483 /* Punctuators */
484 { RT_STR_TUPLE(","), RTSCRIPTLEXTOKTYPE_PUNCTUATOR, false, RTACPIASLTERMINAL_PUNCTUATOR_COMMA },
485 { RT_STR_TUPLE("("), RTSCRIPTLEXTOKTYPE_PUNCTUATOR, false, RTACPIASLTERMINAL_PUNCTUATOR_OPEN_BRACKET },
486 { RT_STR_TUPLE(")"), RTSCRIPTLEXTOKTYPE_PUNCTUATOR, false, RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_BRACKET },
487 { RT_STR_TUPLE("{"), RTSCRIPTLEXTOKTYPE_PUNCTUATOR, false, RTACPIASLTERMINAL_PUNCTUATOR_OPEN_CURLY_BRACKET },
488 { RT_STR_TUPLE("}"), RTSCRIPTLEXTOKTYPE_PUNCTUATOR, false, RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_CURLY_BRACKET },
489 { NULL, 0, RTSCRIPTLEXTOKTYPE_INVALID, false, 0 }
490};
491
492
493static const RTSCRIPTLEXRULE s_aRules[] =
494{
495 { '\"', '\"', RTSCRIPT_LEX_RULE_CONSUME, RTScriptLexScanStringLiteralC, NULL},
496 { '0', '9', RTSCRIPT_LEX_RULE_DEFAULT, rtAcpiAslLexerParseNumber, NULL},
497 { 'A', 'Z', RTSCRIPT_LEX_RULE_DEFAULT, rtAcpiAslLexerParseNameString, NULL},
498 { '_', '_', RTSCRIPT_LEX_RULE_DEFAULT, rtAcpiAslLexerParseNameString, NULL},
499 { '^', '^', RTSCRIPT_LEX_RULE_DEFAULT, rtAcpiAslLexerParseNameString, NULL},
500 { '\\', '\\', RTSCRIPT_LEX_RULE_DEFAULT, rtAcpiAslLexerParseNameString, NULL},
501
502 { '\0', '\0', RTSCRIPT_LEX_RULE_DEFAULT, NULL, NULL}
503};
504
505
506static const RTSCRIPTLEXCFG s_AslLexCfg =
507{
508 /** pszName */
509 "AcpiAsl",
510 /** pszDesc */
511 "ACPI ASL lexer",
512 /** fFlags */
513 RTSCRIPT_LEX_CFG_F_CASE_INSENSITIVE_UPPER,
514 /** pszWhitespace */
515 NULL,
516 /** pszNewline */
517 NULL,
518 /** papszCommentMultiStart */
519 s_aszMultiStart,
520 /** papszCommentMultiEnd */
521 s_aszMultiEnd,
522 /** papszCommentSingleStart */
523 s_aszSingleStart,
524 /** paTokMatches */
525 s_aMatches,
526 /** paRules */
527 s_aRules,
528 /** pfnProdDef */
529 NULL,
530 /** pfnProdDefUser */
531 NULL
532};
533
534
535/*********************************************************************************************************************************
536* Internal Functions *
537*********************************************************************************************************************************/
538
539static DECLCALLBACK(int) rtAcpiAslLexerParseNumber(RTSCRIPTLEX hScriptLex, char ch, PRTSCRIPTLEXTOKEN pToken, void *pvUser)
540{
541 RT_NOREF(ch, pvUser);
542 return RTScriptLexScanNumber(hScriptLex, 0 /*uBase*/, false /*fAllowReal*/, pToken);
543}
544
545
546static int rtAcpiAslLexerParseNameSeg(RTSCRIPTLEX hScriptLex, PRTSCRIPTLEXTOKEN pTok, char *pachNameSeg)
547{
548 /*
549 * A Nameseg consist of a lead character and up to 3 following characters A-Z, 0-9 or _.
550 * If the name segment is not 4 characters long the remainder is filled with _.
551 */
552 char ch = RTScriptLexGetCh(hScriptLex);
553 if ( ch != '_'
554 && ( ch < 'A'
555 || ch > 'Z'))
556 return RTScriptLexProduceTokError(hScriptLex, pTok, VERR_INVALID_PARAMETER, "Lexer: Name segment starts with invalid character '%c'", ch);
557 RTScriptLexConsumeCh(hScriptLex);
558
559 /* Initialize the default name segment. */
560 pachNameSeg[0] = ch;
561 pachNameSeg[1] = '_';
562 pachNameSeg[2] = '_';
563 pachNameSeg[3] = '_';
564
565 for (uint8_t i = 1; i < 4; i++)
566 {
567 ch = RTScriptLexGetCh(hScriptLex);
568
569 /* Anything not belonging to the allowed characters terminates the parsing. */
570 if ( ch != '_'
571 && ( ch < 'A'
572 || ch > 'Z')
573 && ( ch < '0'
574 || ch > '9'))
575 return VINF_SUCCESS;
576 RTScriptLexConsumeCh(hScriptLex);
577 pachNameSeg[i] = ch;
578 }
579
580 return VINF_SUCCESS;
581}
582
583static DECLCALLBACK(int) rtAcpiAslLexerParseNameString(RTSCRIPTLEX hScriptLex, char ch,
584 PRTSCRIPTLEXTOKEN pTok, void *pvUser)
585{
586 RT_NOREF(pvUser);
587
588 char aszIde[513]; RT_ZERO(aszIde);
589 unsigned idx = 0;
590
591 if (ch == '^') /* PrefixPath */
592 {
593 aszIde[idx++] = '^';
594 RTScriptLexConsumeCh(hScriptLex);
595
596 ch = RTScriptLexGetCh(hScriptLex);
597 while ( idx < sizeof(aszIde) - 1
598 && ch == '^')
599 {
600 RTScriptLexConsumeCh(hScriptLex);
601 aszIde[idx++] = ch;
602 ch = RTScriptLexGetCh(hScriptLex);
603 }
604
605 if (idx == sizeof(aszIde) - 1)
606 return RTScriptLexProduceTokError(hScriptLex, pTok, VERR_BUFFER_OVERFLOW, "Lexer: PrefixPath exceeds the allowed length");
607 }
608 else if (ch == '\\')
609 {
610 aszIde[idx++] = '\\';
611 RTScriptLexConsumeCh(hScriptLex);
612 }
613
614 /* Now there is only a sequence of NameSeg allowed (separated by the . separator). */
615 while (idx < sizeof(aszIde) - 1 - 4)
616 {
617 char achNameSeg[4];
618 int rc = rtAcpiAslLexerParseNameSeg(hScriptLex, pTok, &achNameSeg[0]);
619 if (RT_FAILURE(rc))
620 return rc;
621
622 aszIde[idx++] = achNameSeg[0];
623 aszIde[idx++] = achNameSeg[1];
624 aszIde[idx++] = achNameSeg[2];
625 aszIde[idx++] = achNameSeg[3];
626
627 ch = RTScriptLexGetCh(hScriptLex);
628 if (ch != '.')
629 break;
630 aszIde[idx++] = '.';
631 RTScriptLexConsumeCh(hScriptLex);
632 }
633
634 if (idx == sizeof(aszIde) - 1)
635 return RTScriptLexProduceTokError(hScriptLex, pTok, VERR_BUFFER_OVERFLOW, "Lexer: Identifier exceeds the allowed length");
636
637 return RTScriptLexProduceTokIde(hScriptLex, pTok, &aszIde[0], idx);
638}
639
640
641static DECLCALLBACK(int) rtAcpiAslLexerRead(RTSCRIPTLEX hScriptLex, size_t offBuf, char *pchCur,
642 size_t cchBuf, size_t *pcchRead, void *pvUser)
643{
644 PCRTACPIASLCU pThis = (PCRTACPIASLCU)pvUser;
645 RT_NOREF(hScriptLex, offBuf);
646
647 size_t cbRead = 0;
648 int rc = RTVfsIoStrmRead(pThis->hVfsIosIn, pchCur, cchBuf, true /*fBlocking*/, &cbRead);
649 if (RT_FAILURE(rc))
650 return rc;
651
652 *pcchRead = cbRead * sizeof(char);
653 if (!cbRead)
654 return VINF_EOF;
655
656 return VINF_SUCCESS;
657}
658
659
660DECLINLINE(bool) rtAcpiAslLexerIsPunctuator(PCRTACPIASLCU pThis, RTACPIASLTERMINAL enmTerm)
661{
662 PCRTSCRIPTLEXTOKEN pTok;
663 int rc = RTScriptLexQueryToken(pThis->hLexSource, &pTok);
664 if (RT_FAILURE(rc))
665 return false;
666
667 if ( pTok->enmType == RTSCRIPTLEXTOKTYPE_PUNCTUATOR
668 && pTok->Type.Keyword.pKeyword->u64Val == (uint64_t)enmTerm)
669 return true;
670
671 return false;
672}
673
674
675static int rtAcpiAslLexerConsumeIfKeywordInList(PCRTACPIASLCU pThis, PCRTACPIASLTERMINAL paenmTerms, PRTACPIASLTERMINAL penmTerm)
676{
677 PCRTSCRIPTLEXTOKEN pTok;
678 int rc = RTScriptLexQueryToken(pThis->hLexSource, &pTok);
679 if (RT_FAILURE(rc))
680 return RTErrInfoSetF(pThis->pErrInfo, rc, "Lexer: Failed to query keyword token with %Rrc", rc);
681
682 if (pTok->enmType == RTSCRIPTLEXTOKTYPE_KEYWORD)
683 {
684 unsigned i = 0;
685 do
686 {
687 if (pTok->Type.Keyword.pKeyword->u64Val == (uint64_t)paenmTerms[i])
688 {
689 RTScriptLexConsumeToken(pThis->hLexSource);
690 *penmTerm = paenmTerms[i];
691 return VINF_SUCCESS;
692 }
693
694 i++;
695 } while (paenmTerms[i] != RTACPIASLTERMINAL_INVALID);
696 }
697
698 *penmTerm = RTACPIASLTERMINAL_INVALID;
699 return VINF_SUCCESS;
700}
701
702
703static int rtAcpiAslLexerConsumeIfKeyword(PCRTACPIASLCU pThis, RTACPIASLTERMINAL enmTerm, bool *pfConsumed)
704{
705 PCRTSCRIPTLEXTOKEN pTok;
706 int rc = RTScriptLexQueryToken(pThis->hLexSource, &pTok);
707 if (RT_FAILURE(rc))
708 return RTErrInfoSetF(pThis->pErrInfo, rc, "Lexer: Failed to query keyword token with %Rrc", rc);
709
710 if ( pTok->enmType == RTSCRIPTLEXTOKTYPE_KEYWORD
711 && pTok->Type.Keyword.pKeyword->u64Val == (uint64_t)enmTerm)
712 {
713 RTScriptLexConsumeToken(pThis->hLexSource);
714 *pfConsumed = true;
715 return VINF_SUCCESS;
716 }
717
718 *pfConsumed = false;
719 return VINF_SUCCESS;
720}
721
722
723static int rtAcpiAslLexerConsumeIfPunctuator(PCRTACPIASLCU pThis, RTACPIASLTERMINAL enmTerm, bool *pfConsumed)
724{
725 PCRTSCRIPTLEXTOKEN pTok;
726 int rc = RTScriptLexQueryToken(pThis->hLexSource, &pTok);
727 if (RT_FAILURE(rc))
728 return RTErrInfoSetF(pThis->pErrInfo, rc, "Lexer: Failed to query punctuator token with %Rrc", rc);
729
730 if ( pTok->enmType == RTSCRIPTLEXTOKTYPE_PUNCTUATOR
731 && pTok->Type.Keyword.pKeyword->u64Val == (uint64_t)enmTerm)
732 {
733 RTScriptLexConsumeToken(pThis->hLexSource);
734 *pfConsumed = true;
735 return VINF_SUCCESS;
736 }
737
738 *pfConsumed = false;
739 return VINF_SUCCESS;
740}
741
742
743static int rtAcpiAslLexerConsumeIfStringLit(PCRTACPIASLCU pThis, const char **ppszStrLit)
744{
745 PCRTSCRIPTLEXTOKEN pTok;
746 int rc = RTScriptLexQueryToken(pThis->hLexSource, &pTok);
747 if (RT_FAILURE(rc))
748 return RTErrInfoSetF(pThis->pErrInfo, rc, "Lexer: Failed to query string literal token with %Rrc", rc);
749
750 if (pTok->enmType == RTSCRIPTLEXTOKTYPE_STRINGLIT)
751 {
752 *ppszStrLit = pTok->Type.StringLit.pszString;
753 RTScriptLexConsumeToken(pThis->hLexSource);
754 return VINF_SUCCESS;
755 }
756
757 return VINF_SUCCESS;
758}
759
760
761static int rtAcpiAslLexerConsumeIfIdentifier(PCRTACPIASLCU pThis, const char **ppszIde)
762{
763 PCRTSCRIPTLEXTOKEN pTok;
764 int rc = RTScriptLexQueryToken(pThis->hLexSource, &pTok);
765 if (RT_FAILURE(rc))
766 return RTErrInfoSetF(pThis->pErrInfo, rc, "Lexer: Failed to query string literal token with %Rrc", rc);
767
768 if (pTok->enmType == RTSCRIPTLEXTOKTYPE_IDENTIFIER)
769 {
770 *ppszIde = pTok->Type.Id.pszIde;
771 RTScriptLexConsumeToken(pThis->hLexSource);
772 return VINF_SUCCESS;
773 }
774
775 return VINF_SUCCESS;
776}
777
778
779static int rtAcpiAslLexerConsumeIfNatural(PCRTACPIASLCU pThis, uint64_t *pu64, bool *pfConsumed)
780{
781 PCRTSCRIPTLEXTOKEN pTok;
782 int rc = RTScriptLexQueryToken(pThis->hLexSource, &pTok);
783 if (RT_FAILURE(rc))
784 return RTErrInfoSetF(pThis->pErrInfo, rc, "Lexer: Failed to query punctuator token with %Rrc", rc);
785
786 if ( pTok->enmType == RTSCRIPTLEXTOKTYPE_NUMBER
787 && pTok->Type.Number.enmType == RTSCRIPTLEXTOKNUMTYPE_NATURAL)
788 {
789 *pfConsumed = true;
790 *pu64 = pTok->Type.Number.Type.u64;
791 RTScriptLexConsumeToken(pThis->hLexSource);
792 return VINF_SUCCESS;
793 }
794
795 *pfConsumed = false;
796 return VINF_SUCCESS;
797}
798
799
800static int rtAcpiAslParserConsumeEos(PCRTACPIASLCU pThis)
801{
802 PCRTSCRIPTLEXTOKEN pTok;
803 int rc = RTScriptLexQueryToken(pThis->hLexSource, &pTok);
804 if (RT_FAILURE(rc))
805 return RTErrInfoSetF(pThis->pErrInfo, rc, "Lexer: Failed to query punctuator token with %Rrc", rc);
806
807 if (pTok->enmType == RTSCRIPTLEXTOKTYPE_EOS)
808 {
809 RTScriptLexConsumeToken(pThis->hLexSource);
810 return VINF_SUCCESS;
811 }
812
813 return RTErrInfoSetF(pThis->pErrInfo, VERR_INVALID_PARAMETER,
814 "Parser: Found unexpected token after final closing }, expected end of stream");
815}
816
817
818/* Some parser helper macros. */
819#define RTACPIASL_PARSE_KEYWORD(a_enmKeyword, a_pszKeyword) \
820 do { \
821 bool fConsumed2 = false; \
822 int rc2 = rtAcpiAslLexerConsumeIfKeyword(pThis, a_enmKeyword, &fConsumed2); \
823 if (RT_FAILURE(rc2)) \
824 return rc2; \
825 if (!fConsumed2) \
826 return RTErrInfoSetF(pThis->pErrInfo, VERR_INVALID_PARAMETER, "Parser: Expected keyword '%s'", a_pszKeyword); \
827 } while(0)
828
829#define RTACPIASL_PARSE_KEYWORD_LIST(a_enmKeyword, a_aenmKeywordList) \
830 RTACPIASLTERMINAL a_enmKeyword = RTACPIASLTERMINAL_INVALID; \
831 do { \
832 int rc2 = rtAcpiAslLexerConsumeIfKeywordInList(pThis, a_aenmKeywordList, &a_enmKeyword); \
833 if (RT_FAILURE(rc2)) \
834 return rc2; \
835 if (a_enmKeyword == RTACPIASLTERMINAL_INVALID) \
836 return RTErrInfoSetF(pThis->pErrInfo, VERR_INVALID_PARAMETER, "Parser: Unexpected keyword found"); \
837 } while(0)
838
839#define RTACPIASL_PARSE_OPTIONAL_KEYWORD_LIST(a_enmKeyword, a_aenmKeywordList, a_enmDefault) \
840 RTACPIASLTERMINAL a_enmKeyword; \
841 do { \
842 int rc2 = rtAcpiAslLexerConsumeIfKeywordInList(pThis, a_aenmKeywordList, &a_enmKeyword); \
843 if (RT_FAILURE(rc2)) \
844 return rc2; \
845 if (a_enmKeyword == RTACPIASLTERMINAL_INVALID) \
846 a_enmKeyword = a_enmDefault; \
847 } while(0)
848
849#define RTACPIASL_PARSE_PUNCTUATOR(a_enmPunctuator, a_chPunctuator) \
850 do { \
851 bool fConsumed2 = false; \
852 int rc2 = rtAcpiAslLexerConsumeIfPunctuator(pThis, a_enmPunctuator, &fConsumed2); \
853 if (RT_FAILURE(rc2)) \
854 return rc2; \
855 if (!fConsumed2) \
856 return RTErrInfoSetF(pThis->pErrInfo, VERR_INVALID_PARAMETER, "Parser: Expected punctuator '%c'", a_chPunctuator); \
857 } while(0)
858
859#define RTACPIASL_PARSE_OPTIONAL_PUNCTUATOR(a_enmPunctuator) \
860 do { \
861 bool fConsumed2 = false; \
862 int rc2 = rtAcpiAslLexerConsumeIfPunctuator(pThis, a_enmPunctuator, &fConsumed2); \
863 if (RT_FAILURE(rc2)) \
864 return rc2; \
865 } while(0)
866
867#define RTACPIASL_PARSE_STRING_LIT(a_pszStrLit) \
868 const char *a_pszStrLit = NULL; \
869 do { \
870 int rc2 = rtAcpiAslLexerConsumeIfStringLit(pThis, &a_pszStrLit); \
871 if (RT_FAILURE(rc2)) \
872 return rc2; \
873 if (!a_pszStrLit) \
874 return RTErrInfoSetF(pThis->pErrInfo, VERR_INVALID_PARAMETER, "Parser: Expected a string literal"); \
875 } while(0)
876
877#define RTACPIASL_PARSE_NAME_STRING(a_pszIde) \
878 const char *a_pszIde = NULL; \
879 do { \
880 int rc2 = rtAcpiAslLexerConsumeIfIdentifier(pThis, &a_pszIde); \
881 if (RT_FAILURE(rc2)) \
882 return rc2; \
883 if (!a_pszIde) \
884 return RTErrInfoSetF(pThis->pErrInfo, VERR_INVALID_PARAMETER, "Parser: Expected an identifier"); \
885 } while(0)
886
887#define RTACPIASL_PARSE_OPTIONAL_NAME_STRING(a_pszIde) \
888 const char *a_pszIde = NULL; \
889 do { \
890 int rc2 = rtAcpiAslLexerConsumeIfIdentifier(pThis, &a_pszIde); \
891 if (RT_FAILURE(rc2)) \
892 return rc2; \
893 } while(0)
894
895#define RTACPIASL_PARSE_NATURAL(a_u64) \
896 uint64_t a_u64 = 0; \
897 do { \
898 bool fConsumed2 = false; \
899 int rc2 = rtAcpiAslLexerConsumeIfNatural(pThis, &a_u64, &fConsumed2); \
900 if (RT_FAILURE(rc2)) \
901 return rc2; \
902 if (!fConsumed2) \
903 return RTErrInfoSetF(pThis->pErrInfo, VERR_INVALID_PARAMETER, "Parser: Expected a natural number"); \
904 } while(0)
905
906#define RTACPIASL_PARSE_OPTIONAL_NATURAL(a_u64, a_u64Def) \
907 uint64_t a_u64 = a_u64Def; \
908 do { \
909 bool fConsumed2 = false; \
910 int rc2 = rtAcpiAslLexerConsumeIfNatural(pThis, &a_u64, &fConsumed2); \
911 if (RT_FAILURE(rc2)) \
912 return rc2; \
913 RT_NOREF(fConsumed2); \
914 } while(0)
915
916#define RTACPIASL_SKIP_CURRENT_TOKEN() \
917 RTScriptLexConsumeToken(pThis->hLexSource);
918
919
920static int rtAcpiTblAslParseInner(PRTACPIASLCU pThis, PRTLISTANCHOR pLstStmts);
921static int rtAcpiTblAslParseTermArg(PRTACPIASLCU pThis, PRTACPIASTNODE *ppAstNd);
922
923
924static const RTACPIASLTERMINAL g_aenmObjTypeKeywords[] = {
925 RTACPIASLTERMINAL_KEYWORD_UNKNOWN_OBJ,
926 RTACPIASLTERMINAL_KEYWORD_INT_OBJ,
927 RTACPIASLTERMINAL_KEYWORD_STR_OBJ,
928 RTACPIASLTERMINAL_KEYWORD_BUFF_OBJ,
929 RTACPIASLTERMINAL_KEYWORD_PKG_OBJ,
930 RTACPIASLTERMINAL_KEYWORD_FIELD_UNIT_OBJ,
931 RTACPIASLTERMINAL_KEYWORD_DEVICE_OBJ,
932 RTACPIASLTERMINAL_KEYWORD_EVENT_OBJ,
933 RTACPIASLTERMINAL_KEYWORD_METHOD_OBJ,
934 RTACPIASLTERMINAL_KEYWORD_MUTEX_OBJ,
935 RTACPIASLTERMINAL_KEYWORD_OP_REGION_OBJ,
936 RTACPIASLTERMINAL_KEYWORD_POWER_RES_OBJ,
937 RTACPIASLTERMINAL_KEYWORD_THERMAL_ZONE_OBJ,
938 RTACPIASLTERMINAL_KEYWORD_BUFF_FIELD_OBJ,
939 RTACPIASLTERMINAL_KEYWORD_PROCESSOR_OBJ,
940 RTACPIASLTERMINAL_INVALID
941};
942
943
944static const RTACPIASLTERMINAL g_aenmSerializeRuleKeywords[] = {
945 RTACPIASLTERMINAL_KEYWORD_SERIALIZED,
946 RTACPIASLTERMINAL_KEYWORD_NOT_SERIALIZED,
947 RTACPIASLTERMINAL_INVALID
948};
949
950
951static const RTACPIASLTERMINAL g_aenmRegionSpaceKeywords[] = {
952 RTACPIASLTERMINAL_KEYWORD_SYSTEM_IO,
953 RTACPIASLTERMINAL_KEYWORD_SYSTEM_MEMORY,
954 RTACPIASLTERMINAL_KEYWORD_PCI_CONFIG,
955 RTACPIASLTERMINAL_KEYWORD_EMBEDDED_CONTROL,
956 RTACPIASLTERMINAL_KEYWORD_SMBUS,
957 RTACPIASLTERMINAL_KEYWORD_SYSTEM_CMOS,
958 RTACPIASLTERMINAL_KEYWORD_PCI_BAR_TARGET,
959 RTACPIASLTERMINAL_KEYWORD_IPMI,
960 RTACPIASLTERMINAL_KEYWORD_GENERAL_PURPOSE_IO,
961 RTACPIASLTERMINAL_KEYWORD_GENERIC_SERIAL_BUS,
962 RTACPIASLTERMINAL_KEYWORD_PCC,
963 RTACPIASLTERMINAL_KEYWORD_PRM,
964 RTACPIASLTERMINAL_KEYWORD_FFIXED_HW,
965 RTACPIASLTERMINAL_INVALID
966};
967
968
969static const RTACPIASLTERMINAL g_aenmAccessTypeKeywords[] = {
970 RTACPIASLTERMINAL_KEYWORD_ANY_ACC,
971 RTACPIASLTERMINAL_KEYWORD_BYTE_ACC,
972 RTACPIASLTERMINAL_KEYWORD_WORD_ACC,
973 RTACPIASLTERMINAL_KEYWORD_DWORD_ACC,
974 RTACPIASLTERMINAL_KEYWORD_QWORD_ACC,
975 RTACPIASLTERMINAL_KEYWORD_BUFFER_ACC,
976 RTACPIASLTERMINAL_INVALID
977};
978
979
980static const RTACPIASLTERMINAL g_aenmLockRuleKeywords[] = {
981 RTACPIASLTERMINAL_KEYWORD_LOCK,
982 RTACPIASLTERMINAL_KEYWORD_NO_LOCK,
983 RTACPIASLTERMINAL_INVALID
984};
985
986
987static const RTACPIASLTERMINAL g_aenmUpdateRuleKeywords[] = {
988 RTACPIASLTERMINAL_KEYWORD_PRESERVE,
989 RTACPIASLTERMINAL_KEYWORD_WRITE_AS_ONES,
990 RTACPIASLTERMINAL_KEYWORD_WRITE_AS_ZEROES,
991 RTACPIASLTERMINAL_INVALID
992};
993
994
995static const RTACPIASLTERMINAL g_aenmRwRoKeywords[] = {
996 RTACPIASLTERMINAL_KEYWORD_READONLY,
997 RTACPIASLTERMINAL_KEYWORD_READWRITE,
998 RTACPIASLTERMINAL_INVALID
999};
1000
1001
1002
1003static DECLCALLBACK(int) rtAcpiTblAslParseExternal(PRTACPIASLCU pThis)
1004{
1005 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_OPEN_BRACKET, '(');
1006
1007 /* Namestring is required. */
1008 RTACPIASL_PARSE_NAME_STRING(pszNameString);
1009
1010 RTACPIOBJTYPE enmObjType = kAcpiObjType_Unknown;
1011
1012 if (rtAcpiAslLexerIsPunctuator(pThis, RTACPIASLTERMINAL_PUNCTUATOR_COMMA))
1013 {
1014 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1015
1016 RTACPIASLTERMINAL enmKeyword;
1017 int rc = rtAcpiAslLexerConsumeIfKeywordInList(pThis, &g_aenmObjTypeKeywords[0], &enmKeyword);
1018 if (RT_FAILURE(rc))
1019 return rc;
1020
1021 if (enmKeyword != RTACPIASLTERMINAL_INVALID)
1022 {
1023 switch (enmKeyword)
1024 {
1025 case RTACPIASLTERMINAL_KEYWORD_UNKNOWN_OBJ: enmObjType = kAcpiObjType_Unknown; break;
1026 case RTACPIASLTERMINAL_KEYWORD_INT_OBJ: enmObjType = kAcpiObjType_Int; break;
1027 case RTACPIASLTERMINAL_KEYWORD_STR_OBJ: enmObjType = kAcpiObjType_Str; break;
1028 case RTACPIASLTERMINAL_KEYWORD_BUFF_OBJ: enmObjType = kAcpiObjType_Buff; break;
1029 case RTACPIASLTERMINAL_KEYWORD_PKG_OBJ: enmObjType = kAcpiObjType_Pkg; break;
1030 case RTACPIASLTERMINAL_KEYWORD_FIELD_UNIT_OBJ: enmObjType = kAcpiObjType_FieldUnit; break;
1031 case RTACPIASLTERMINAL_KEYWORD_DEVICE_OBJ: enmObjType = kAcpiObjType_Device; break;
1032 case RTACPIASLTERMINAL_KEYWORD_EVENT_OBJ: enmObjType = kAcpiObjType_Event; break;
1033 case RTACPIASLTERMINAL_KEYWORD_METHOD_OBJ: enmObjType = kAcpiObjType_Method; break;
1034 case RTACPIASLTERMINAL_KEYWORD_MUTEX_OBJ: enmObjType = kAcpiObjType_MutexObj; break;
1035 case RTACPIASLTERMINAL_KEYWORD_OP_REGION_OBJ: enmObjType = kAcpiObjType_OpRegion; break;
1036 case RTACPIASLTERMINAL_KEYWORD_POWER_RES_OBJ: enmObjType = kAcpiObjType_PowerRes; break;
1037 case RTACPIASLTERMINAL_KEYWORD_THERMAL_ZONE_OBJ: enmObjType = kAcpiObjType_ThermalZone; break;
1038 case RTACPIASLTERMINAL_KEYWORD_BUFF_FIELD_OBJ: enmObjType = kAcpiObjType_BuffField; break;
1039 case RTACPIASLTERMINAL_KEYWORD_PROCESSOR_OBJ: enmObjType = kAcpiObjType_Processor; break;
1040 default:
1041 AssertFailedReturn(VERR_INTERNAL_ERROR);
1042 }
1043 }
1044
1045 if (rtAcpiAslLexerIsPunctuator(pThis, RTACPIASLTERMINAL_PUNCTUATOR_COMMA))
1046 {
1047 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1048
1049 /** @todo ResultType */
1050
1051 if (rtAcpiAslLexerIsPunctuator(pThis, RTACPIASLTERMINAL_PUNCTUATOR_COMMA))
1052 {
1053 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1054
1055 /** @todo ParameterTypes */
1056 }
1057 }
1058 }
1059
1060 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_BRACKET, ')');
1061
1062 /* Query the final name path. */
1063 char achNamePath[_1K];
1064 size_t cchNamePath = RT_ELEMENTS(achNamePath) * sizeof(char);
1065 int rc = rtAcpiNsQueryNamePathForNameString(pThis->pNs, pszNameString, &achNamePath[0], &cchNamePath);
1066 if (RT_FAILURE(rc))
1067 return RTErrInfoSetF(pThis->pErrInfo, rc, "Failed to query name path for External(%s,,,)", pszNameString);
1068
1069 size_t const cbExternal = RT_UOFFSETOF_DYN(RTACPIASLEXTERNAL, szNamePath[cchNamePath + 1]);
1070 PRTACPIASLEXTERNAL pExternal = (PRTACPIASLEXTERNAL)RTMemAllocZ(cbExternal);
1071 if (!pExternal)
1072 return RTErrInfoSetF(pThis->pErrInfo, VERR_NO_MEMORY, "Out of memory allocating %u bytes for External(%s,,,)", pszNameString, cbExternal);
1073
1074 RTListAppend(&pThis->LstExternals, &pExternal->NdExternal);
1075
1076 pExternal->enmObjType = enmObjType;
1077 pExternal->cArgs = UINT32_MAX;
1078 pExternal->pszName = pszNameString;
1079 pExternal->cchNamePath = cchNamePath;
1080 memcpy(&pExternal->szNamePath[0], &achNamePath[0], cchNamePath + 1);
1081
1082 rc = rtAcpiNsAddEntryExternal(pThis->pNs, pszNameString, pExternal);
1083 if (RT_FAILURE(rc))
1084 return RTErrInfoSetF(pThis->pErrInfo, rc, "Failed to add External(%s,,,) to namespace", pszNameString);
1085
1086 return VINF_SUCCESS;
1087}
1088
1089
1090static DECLCALLBACK(int) rtAcpiTblAslParseMethod(PRTACPIASLCU pThis, PCRTACPIASLKEYWORD pKeyword, PRTACPIASTNODE pAstNd)
1091{
1092 RT_NOREF(pKeyword, pAstNd);
1093
1094 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_OPEN_BRACKET, '(');
1095
1096 /* Namestring is required. */
1097 RTACPIASL_PARSE_NAME_STRING(pszNameString);
1098 pAstNd->aArgs[0].enmType = kAcpiAstArgType_NameString;
1099 pAstNd->aArgs[0].u.pszNameString = pszNameString;
1100
1101 /* Defaults for optional arguments. */
1102 pAstNd->aArgs[1].enmType = kAcpiAstArgType_U8;
1103 pAstNd->aArgs[1].u.u8 = 0;
1104 pAstNd->aArgs[2].enmType = kAcpiAstArgType_Bool;
1105 pAstNd->aArgs[2].u.f = false;
1106 pAstNd->aArgs[3].enmType = kAcpiAstArgType_U8;
1107 pAstNd->aArgs[3].u.u8 = 0;
1108
1109 if (rtAcpiAslLexerIsPunctuator(pThis, RTACPIASLTERMINAL_PUNCTUATOR_COMMA))
1110 {
1111 /* NumArgs */
1112 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1113
1114 uint64_t u64 = 0;
1115 bool fConsumed = false;
1116 int rc = rtAcpiAslLexerConsumeIfNatural(pThis, &u64, &fConsumed);
1117 if (RT_FAILURE(rc))
1118 return rc;
1119
1120 if (fConsumed)
1121 {
1122 if (u64 >= 8)
1123 return RTErrInfoSetF(pThis->pErrInfo, VERR_INVALID_PARAMETER,
1124 "Argument count value is out of range [0..7]: %u", u64);
1125 pAstNd->aArgs[1].u.u8 = (uint8_t)u64;
1126 }
1127
1128 if (rtAcpiAslLexerIsPunctuator(pThis, RTACPIASLTERMINAL_PUNCTUATOR_COMMA))
1129 {
1130 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1131
1132 /* Serialized|NotSerialized */
1133 RTACPIASLTERMINAL enmKeyword;
1134 rc = rtAcpiAslLexerConsumeIfKeywordInList(pThis, &g_aenmSerializeRuleKeywords[0], &enmKeyword);
1135 if (RT_FAILURE(rc))
1136 return rc;
1137
1138 if (enmKeyword != RTACPIASLTERMINAL_INVALID)
1139 {
1140 Assert(enmKeyword == RTACPIASLTERMINAL_KEYWORD_SERIALIZED || enmKeyword == RTACPIASLTERMINAL_KEYWORD_NOT_SERIALIZED);
1141 pAstNd->aArgs[2].u.f = enmKeyword == RTACPIASLTERMINAL_KEYWORD_SERIALIZED
1142 ? RTACPI_METHOD_F_SERIALIZED
1143 : RTACPI_METHOD_F_NOT_SERIALIZED;
1144 }
1145
1146 if (rtAcpiAslLexerIsPunctuator(pThis, RTACPIASLTERMINAL_PUNCTUATOR_COMMA))
1147 {
1148 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1149
1150 /* Sync Level */
1151 u64 = 0;
1152 rc = rtAcpiAslLexerConsumeIfNatural(pThis, &u64, &fConsumed);
1153 if (RT_FAILURE(rc))
1154 return rc;
1155
1156 if (fConsumed)
1157 {
1158 if (u64 >= 16)
1159 return RTErrInfoSetF(pThis->pErrInfo, VERR_INVALID_PARAMETER,
1160 "SyncLevel value is out of range [0..15]: %u", u64);
1161 pAstNd->aArgs[3].u.u8 = (uint8_t)u64;
1162 }
1163
1164 if (rtAcpiAslLexerIsPunctuator(pThis, RTACPIASLTERMINAL_PUNCTUATOR_COMMA))
1165 {
1166 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1167
1168 /** @todo ReturnType */
1169
1170 if (rtAcpiAslLexerIsPunctuator(pThis, RTACPIASLTERMINAL_PUNCTUATOR_COMMA))
1171 {
1172 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1173
1174 /** @todo ParameterTypes */
1175 }
1176 }
1177 }
1178 }
1179 }
1180
1181 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_BRACKET, ')');
1182
1183 int rc = rtAcpiNsAddEntryAstNode(pThis->pNs, pAstNd->aArgs[0].u.pszNameString, pAstNd, true /*fSwitchTo*/);
1184 if (RT_FAILURE(rc))
1185 return RTErrInfoSetF(pThis->pErrInfo, rc, "Failed to add Method(%s,,,) to namespace", pAstNd->aArgs[0].u.pszNameString);
1186
1187 return VINF_SUCCESS;
1188}
1189
1190
1191static int rtAcpiTblParseFieldUnitList(PRTACPIASLCU pThis, const char *pszFieldName, PRTACPIASTNODE pAstNd)
1192{
1193 RTACPIFIELDENTRY aFieldEntries[128]; RT_ZERO(aFieldEntries); /** @todo Allow dynamic allocation? */
1194 uint32_t cFields = 0;
1195
1196 uint32_t offBits = 0;
1197 for (;;)
1198 {
1199 /** @todo Is an empty list allowed (currently we allow that)? */
1200 if (rtAcpiAslLexerIsPunctuator(pThis, RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_CURLY_BRACKET))
1201 break;
1202
1203 /*
1204 * Two of the following are possible:
1205 * Offset(Integer)
1206 * NameSeg "," Integer
1207 */
1208 bool fConsumed = false;
1209 int rc = rtAcpiAslLexerConsumeIfKeyword(pThis, RTACPIASLTERMINAL_KEYWORD_OFFSET, &fConsumed);
1210 if (RT_FAILURE(rc))
1211 return rc;
1212
1213 if (fConsumed)
1214 {
1215 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_OPEN_BRACKET, '(');
1216 /* Must be an integer */
1217 RTACPIASL_PARSE_NATURAL(offBytes);
1218 aFieldEntries[cFields].pszName = NULL;
1219 aFieldEntries[cFields].cBits = (offBytes * 8) - offBits;
1220 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_BRACKET, ')');
1221 }
1222 else
1223 {
1224 /* This must be the second case. */
1225 RTACPIASL_PARSE_NAME_STRING(pszName); /** @todo Verify that the name string consists only of a single name segment. */
1226 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1227 RTACPIASL_PARSE_NATURAL(cBits);
1228 aFieldEntries[cFields].pszName = pszName;
1229 aFieldEntries[cFields].cBits = cBits;
1230
1231 rc = rtAcpiNsAddEntryRsrcField(pThis->pNs, pszName, offBits, cBits);
1232 if (RT_FAILURE(rc))
1233 return RTErrInfoSetF(pThis->pErrInfo, rc, "Failed to add '%s.%s' to namespace", pszFieldName, pszName);
1234
1235 }
1236
1237 offBits += aFieldEntries[cFields].cBits;
1238 cFields++;
1239
1240 /* A following "," means there is another entry, otherwise the closing "}" should follow. */
1241 if (!rtAcpiAslLexerIsPunctuator(pThis, RTACPIASLTERMINAL_PUNCTUATOR_COMMA))
1242 break;
1243
1244 RTACPIASL_SKIP_CURRENT_TOKEN(); /* Skip the "," */
1245
1246 if (cFields == RT_ELEMENTS(aFieldEntries))
1247 return RTErrInfoSetF(pThis->pErrInfo, VERR_BUFFER_OVERFLOW,
1248 "The field list overflows the current allowed maximum of %u fields", RT_ELEMENTS(aFieldEntries));
1249 }
1250
1251 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_CURLY_BRACKET, '}');
1252
1253 /* Allocate the list to the node. */
1254 pAstNd->Fields.paFields = (PRTACPIFIELDENTRY)RTMemAllocZ(cFields * sizeof(aFieldEntries[0]));
1255 if (!pAstNd->Fields.paFields)
1256 return RTErrInfoSetF(pThis->pErrInfo, VERR_NO_MEMORY, "Out of memory allocating field unit list with %u entries", cFields);
1257
1258 for (uint32_t i = 0; i < cFields; i++)
1259 pAstNd->Fields.paFields[i] = aFieldEntries[i];
1260
1261 pAstNd->Fields.cFields = cFields;
1262 return VINF_SUCCESS;
1263}
1264
1265
1266static DECLCALLBACK(int) rtAcpiTblAslParseFieldOrIndexField(PRTACPIASLCU pThis, PCRTACPIASLKEYWORD pKeyword, PRTACPIASTNODE pAstNd)
1267{
1268 RT_NOREF(pKeyword);
1269
1270 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_OPEN_BRACKET, '(');
1271
1272 uint8_t idxArg = 0;
1273
1274 if (pKeyword->cArgsReq == 5)
1275 {
1276 /* This is an IndexField. */
1277
1278 /* Namestring is required. */
1279 RTACPIASL_PARSE_NAME_STRING(pszNameString);
1280 pAstNd->aArgs[idxArg].enmType = kAcpiAstArgType_NameString;
1281 pAstNd->aArgs[idxArg].u.pszNameString = pszNameString;
1282 idxArg++;
1283
1284 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1285 }
1286 else /* Field */
1287 Assert(pKeyword->cArgsReq == 4);
1288
1289 /* Namestring is required. */
1290 RTACPIASL_PARSE_NAME_STRING(pszNameString);
1291 pAstNd->aArgs[idxArg].enmType = kAcpiAstArgType_NameString;
1292 pAstNd->aArgs[idxArg].u.pszNameString = pszNameString;
1293 idxArg++;
1294
1295 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1296
1297 /* Must have an access type defined. */
1298 RTACPIASL_PARSE_KEYWORD_LIST(enmAccessType, g_aenmAccessTypeKeywords);
1299 pAstNd->aArgs[idxArg].enmType = kAcpiAstArgType_FieldAcc;
1300 switch (enmAccessType)
1301 {
1302 case RTACPIASLTERMINAL_KEYWORD_ANY_ACC: pAstNd->aArgs[idxArg].u.enmFieldAcc = kAcpiFieldAcc_Any; break;
1303 case RTACPIASLTERMINAL_KEYWORD_BYTE_ACC: pAstNd->aArgs[idxArg].u.enmFieldAcc = kAcpiFieldAcc_Byte; break;
1304 case RTACPIASLTERMINAL_KEYWORD_WORD_ACC: pAstNd->aArgs[idxArg].u.enmFieldAcc = kAcpiFieldAcc_Word; break;
1305 case RTACPIASLTERMINAL_KEYWORD_DWORD_ACC: pAstNd->aArgs[idxArg].u.enmFieldAcc = kAcpiFieldAcc_DWord; break;
1306 case RTACPIASLTERMINAL_KEYWORD_QWORD_ACC: pAstNd->aArgs[idxArg].u.enmFieldAcc = kAcpiFieldAcc_QWord; break;
1307 case RTACPIASLTERMINAL_KEYWORD_BUFFER_ACC: pAstNd->aArgs[idxArg].u.enmFieldAcc = kAcpiFieldAcc_Buffer; break;
1308 default:
1309 AssertFailedReturn(VERR_INTERNAL_ERROR);
1310 }
1311 idxArg++;
1312
1313 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1314
1315 /* Must have a lock rule defined. */
1316 RTACPIASL_PARSE_KEYWORD_LIST(enmLockRule, g_aenmLockRuleKeywords);
1317 pAstNd->aArgs[idxArg].enmType = kAcpiAstArgType_Bool;
1318 switch (enmLockRule)
1319 {
1320 case RTACPIASLTERMINAL_KEYWORD_LOCK: pAstNd->aArgs[idxArg].u.f = true; break;
1321 case RTACPIASLTERMINAL_KEYWORD_NO_LOCK: pAstNd->aArgs[idxArg].u.f = false; break;
1322 default:
1323 AssertFailedReturn(VERR_INTERNAL_ERROR);
1324 }
1325 idxArg++;
1326
1327 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1328
1329 /* Must have an update rule defined. */
1330 RTACPIASL_PARSE_KEYWORD_LIST(enmUpdateRule, g_aenmUpdateRuleKeywords);
1331 pAstNd->aArgs[idxArg].enmType = kAcpiAstArgType_FieldUpdate;
1332 switch (enmUpdateRule)
1333 {
1334 case RTACPIASLTERMINAL_KEYWORD_PRESERVE: pAstNd->aArgs[idxArg].u.enmFieldUpdate = kAcpiFieldUpdate_Preserve; break;
1335 case RTACPIASLTERMINAL_KEYWORD_WRITE_AS_ONES: pAstNd->aArgs[idxArg].u.enmFieldUpdate = kAcpiFieldUpdate_WriteAsOnes; break;
1336 case RTACPIASLTERMINAL_KEYWORD_WRITE_AS_ZEROES: pAstNd->aArgs[idxArg].u.enmFieldUpdate = kAcpiFieldUpdate_WriteAsZeroes; break;
1337 default:
1338 AssertFailedReturn(VERR_INTERNAL_ERROR);
1339 }
1340 idxArg++;
1341
1342 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_BRACKET, ')');
1343
1344 /* Parse the field unit list. */
1345 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_OPEN_CURLY_BRACKET, '{');
1346 return rtAcpiTblParseFieldUnitList(pThis, pszNameString, pAstNd);
1347}
1348
1349
1350/**
1351 * Resource template namespace entry.
1352 */
1353typedef struct RTACPIRSRCNSENTRY
1354{
1355 /** Name of the namespace entry - NULL marks the end of the list. */
1356 const char *pszName;
1357 /** Bit offset from the start of the resource. */
1358 uint32_t offBits;
1359 /** Number of bits this field has. */
1360 uint32_t cBits;
1361} RTACPIRSRCNSENTRY;
1362/** Pointer to a resource template namespace entry. */
1363typedef RTACPIRSRCNSENTRY *PRTACPIRSRCNSENTRY;
1364/** Pointer to a constant resource template namespace entry. */
1365typedef const RTACPIRSRCNSENTRY *PCRTACPIRSRCNSENTRY;
1366
1367
1368static int rtAcpiTblParseResourceNsCreateEntries(PRTACPIASLCU pThis, RTACPIRES hAcpiRes, PRTACPIASTNODE pAstNd,
1369 const char *pszRsrcName, const char *pszName, PCRTACPIRSRCNSENTRY paNsEntries)
1370{
1371 AssertReturn(pszName, VINF_SUCCESS);
1372
1373 uint32_t const offResource = RTAcpiResourceGetOffset(hAcpiRes) * 8;
1374 int rc = rtAcpiNsAddEntryAstNode(pThis->pNs, pszName, pAstNd, true /*fSwitchTo*/);
1375 if (RT_FAILURE(rc))
1376 return RTErrInfoSetF(pThis->pErrInfo, rc, "Failed to add %s() to namespace as '%s'",
1377 pszRsrcName, pszName);
1378
1379 uint32_t idxRsrc = 0;
1380 for (;;)
1381 {
1382 if (paNsEntries[idxRsrc].pszName == NULL)
1383 {
1384 rtAcpiNsPop(pThis->pNs);
1385 return VINF_SUCCESS;
1386 }
1387
1388 rc = rtAcpiNsAddEntryRsrcField(pThis->pNs, paNsEntries[idxRsrc].pszName, offResource + paNsEntries[idxRsrc].offBits, paNsEntries[idxRsrc].cBits);
1389 if (RT_FAILURE(rc))
1390 return RTErrInfoSetF(pThis->pErrInfo, rc, "Failed to add '%s.%s' to namespace", pszName, paNsEntries[idxRsrc].pszName);
1391
1392 idxRsrc++;
1393 }
1394}
1395
1396
1397static int rtAcpiTblParseResourceMemory32Fixed(PRTACPIASLCU pThis, RTACPIRES hAcpiRes, PRTACPIASTNODE pAstNd)
1398{
1399 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_OPEN_BRACKET, '(');
1400 RTACPIASL_PARSE_KEYWORD_LIST(enmKeywordAccess, g_aenmRwRoKeywords);
1401 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1402 RTACPIASL_PARSE_NATURAL(u64PhysAddrStart);
1403 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1404 RTACPIASL_PARSE_NATURAL(cbRegion);
1405 RTACPIASL_PARSE_OPTIONAL_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA);
1406 RTACPIASL_PARSE_OPTIONAL_NAME_STRING(pszName);
1407 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_BRACKET, ')');
1408
1409 /* Check that the given range is within bounds. */
1410 if ( u64PhysAddrStart >= _4G
1411 || cbRegion >= _4G
1412 || u64PhysAddrStart + cbRegion >= _4G
1413 || u64PhysAddrStart + cbRegion < u64PhysAddrStart)
1414 return RTErrInfoSetF(pThis->pErrInfo, VERR_INVALID_PARAMETER,
1415 "The given memory range does not fit into a 32-bit memory address space: Start=%#RX64 Size=%#RX64",
1416 u64PhysAddrStart, cbRegion);
1417
1418 if (pszName)
1419 {
1420 static const RTACPIRSRCNSENTRY s_aRsrcNs[] =
1421 {
1422 { "_BAS", 4 * 8, 32 },
1423 { "_LEN", 8 * 8, 32 },
1424 { NULL, 0, 0 }
1425 };
1426 int rc = rtAcpiTblParseResourceNsCreateEntries(pThis, hAcpiRes, pAstNd, "Memory32Fixed", pszName, &s_aRsrcNs[0]);
1427 if (RT_FAILURE(rc))
1428 return rc;
1429 }
1430
1431 int rc = RTAcpiResourceAdd32BitFixedMemoryRange(hAcpiRes, u64PhysAddrStart, cbRegion, enmKeywordAccess == RTACPIASLTERMINAL_KEYWORD_READWRITE);
1432 if (RT_FAILURE(rc))
1433 return RTErrInfoSetF(pThis->pErrInfo, rc,
1434 "Failed to add Memory32Fixed(fRw=%RTbool, %#RX64 Size=%#RX64, %s)",
1435 enmKeywordAccess == RTACPIASLTERMINAL_KEYWORD_READWRITE, u64PhysAddrStart, cbRegion,
1436 pszName ? pszName : "<NONE>");
1437
1438 return VINF_SUCCESS;
1439}
1440
1441
1442static int rtAcpiTblParseIrqList(PRTACPIASLCU pThis, uint16_t *pbmIntrs)
1443{
1444 uint16_t bmIntrs = 0;
1445 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_OPEN_CURLY_BRACKET, '{');
1446 for (;;)
1447 {
1448 if (rtAcpiAslLexerIsPunctuator(pThis, RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_CURLY_BRACKET))
1449 break;
1450
1451 RTACPIASL_PARSE_NATURAL(u64Intr);
1452 if (u64Intr > 15)
1453 return RTErrInfoSetF(pThis->pErrInfo, VERR_INVALID_PARAMETER,
1454 "Interrupt is out of range [0..15]: %RU64",
1455 u64Intr);
1456 if (bmIntrs & RT_BIT(u64Intr))
1457 return RTErrInfoSetF(pThis->pErrInfo, VERR_INVALID_PARAMETER, "Duplicate interrupt %u in list", u64Intr);
1458
1459 bmIntrs |= RT_BIT(u64Intr);
1460
1461 /* A following "," means there is another entry, otherwise the closing "}" should follow. */
1462 if (!rtAcpiAslLexerIsPunctuator(pThis, RTACPIASLTERMINAL_PUNCTUATOR_COMMA))
1463 break;
1464
1465 RTACPIASL_SKIP_CURRENT_TOKEN(); /* Skip the "," */
1466 }
1467 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_CURLY_BRACKET, '}');
1468
1469 *pbmIntrs = bmIntrs;
1470 return VINF_SUCCESS;
1471}
1472
1473static int rtAcpiTblParseResourceIrq(PRTACPIASLCU pThis, RTACPIRES hAcpiRes, PRTACPIASTNODE pAstNd)
1474{
1475 static const RTACPIASLTERMINAL s_aenmEdgeLevelKeywords[] = { RTACPIASLTERMINAL_KEYWORD_EDGE, RTACPIASLTERMINAL_KEYWORD_LEVEL, RTACPIASLTERMINAL_INVALID };
1476 static const RTACPIASLTERMINAL s_aenmActiveLevelKeywords[] = { RTACPIASLTERMINAL_KEYWORD_ACTIVE_HIGH, RTACPIASLTERMINAL_KEYWORD_ACTIVE_LOW, RTACPIASLTERMINAL_INVALID };
1477 static const RTACPIASLTERMINAL s_aenmSharedExclKeywords[] = { RTACPIASLTERMINAL_KEYWORD_SHARED, RTACPIASLTERMINAL_KEYWORD_EXCLUSIVE,
1478 RTACPIASLTERMINAL_KEYWORD_SHARED_AND_WAKE, RTACPIASLTERMINAL_KEYWORD_EXCLUSIVE_AND_WAKE, RTACPIASLTERMINAL_INVALID };
1479
1480 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_OPEN_BRACKET, '(');
1481 RTACPIASL_PARSE_KEYWORD_LIST(enmEdgeLevel, s_aenmEdgeLevelKeywords);
1482 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1483 RTACPIASL_PARSE_KEYWORD_LIST(enmActiveHigh, s_aenmActiveLevelKeywords);
1484 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1485 RTACPIASL_PARSE_OPTIONAL_KEYWORD_LIST(enmSharedExcl, s_aenmSharedExclKeywords, RTACPIASLTERMINAL_KEYWORD_EXCLUSIVE);
1486 RTACPIASL_PARSE_OPTIONAL_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA);
1487 RTACPIASL_PARSE_OPTIONAL_NAME_STRING(pszName);
1488 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_BRACKET, ')');
1489
1490 uint16_t bmIntrs = 0;
1491 int rc = rtAcpiTblParseIrqList(pThis, &bmIntrs);
1492 if (RT_FAILURE(rc))
1493 return rc;
1494
1495 if (pszName)
1496 {
1497 static const RTACPIRSRCNSENTRY s_aRsrcNs[] =
1498 {
1499 { "_INT", 1 * 8, 16 },
1500 { "_HE_", 3 * 8, 1 },
1501 { "_LL_", 3 * 8 + 3, 1 },
1502 { "_SHR", 3 * 8 + 4, 1 },
1503 { "_WKC", 3 * 8 + 5, 1 },
1504 { NULL, 0, 0 }
1505 };
1506 rc = rtAcpiTblParseResourceNsCreateEntries(pThis, hAcpiRes, pAstNd, "IRQ", pszName, &s_aRsrcNs[0]);
1507 if (RT_FAILURE(rc))
1508 return rc;
1509 }
1510
1511 rc = RTAcpiResourceAddIrq(hAcpiRes,
1512 enmEdgeLevel == RTACPIASLTERMINAL_KEYWORD_EDGE,
1513 enmActiveHigh == RTACPIASLTERMINAL_KEYWORD_ACTIVE_LOW,
1514 enmSharedExcl == RTACPIASLTERMINAL_KEYWORD_SHARED || enmSharedExcl == RTACPIASLTERMINAL_KEYWORD_SHARED_AND_WAKE,
1515 enmSharedExcl == RTACPIASLTERMINAL_KEYWORD_SHARED_AND_WAKE || enmSharedExcl == RTACPIASLTERMINAL_KEYWORD_EXCLUSIVE_AND_WAKE,
1516 bmIntrs);
1517 if (RT_FAILURE(rc))
1518 return RTErrInfoSetF(pThis->pErrInfo, rc,
1519 "Failed to add IRQ(,,,,, %s)", pszName ? pszName : "<NONE>");
1520
1521 return VINF_SUCCESS;
1522}
1523
1524
1525static int rtAcpiTblParseResourceIrqNoFlags(PRTACPIASLCU pThis, RTACPIRES hAcpiRes, PRTACPIASTNODE pAstNd)
1526{
1527 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_OPEN_BRACKET, '(');
1528 RTACPIASL_PARSE_OPTIONAL_NAME_STRING(pszName);
1529 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_BRACKET, ')');
1530
1531 uint16_t bmIntrs = 0;
1532 int rc = rtAcpiTblParseIrqList(pThis, &bmIntrs);
1533 if (RT_FAILURE(rc))
1534 return rc;
1535
1536 if (pszName)
1537 {
1538 static const RTACPIRSRCNSENTRY s_aRsrcNs[] =
1539 {
1540 { "_INT", 1 * 8, 16 },
1541 { NULL, 0, 0 }
1542 };
1543 rc = rtAcpiTblParseResourceNsCreateEntries(pThis, hAcpiRes, pAstNd, "IRQNoFlags", pszName, &s_aRsrcNs[0]);
1544 if (RT_FAILURE(rc))
1545 return rc;
1546 }
1547
1548 rc = RTAcpiResourceAddIrq(hAcpiRes, true /*fEdgeTriggered*/, false /*fActiveLow*/, false /*fShared*/, false /*fWakeCapable*/, bmIntrs);
1549 if (RT_FAILURE(rc))
1550 return RTErrInfoSetF(pThis->pErrInfo, rc,
1551 "Failed to add IRQNoFlags(%s)", pszName ? pszName : "<NONE>");
1552
1553 return VINF_SUCCESS;
1554}
1555
1556
1557static int rtAcpiTblParseResourceIo(PRTACPIASLCU pThis, RTACPIRES hAcpiRes, PRTACPIASTNODE pAstNd)
1558{
1559 static const RTACPIASLTERMINAL s_aenmDecodeKeywords[] = { RTACPIASLTERMINAL_KEYWORD_DECODE_10, RTACPIASLTERMINAL_KEYWORD_DECODE_16, RTACPIASLTERMINAL_INVALID };
1560
1561 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_OPEN_BRACKET, '(');
1562 RTACPIASL_PARSE_KEYWORD_LIST(enmDecode, s_aenmDecodeKeywords);
1563 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1564 RTACPIASL_PARSE_NATURAL(u64AddrMin);
1565 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1566 RTACPIASL_PARSE_NATURAL(u64AddrMax);
1567 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1568 RTACPIASL_PARSE_NATURAL(u64AddrAlignment);
1569 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1570 RTACPIASL_PARSE_NATURAL(u64RangeLength);
1571 RTACPIASL_PARSE_OPTIONAL_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA);
1572 RTACPIASL_PARSE_OPTIONAL_NAME_STRING(pszName);
1573 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_BRACKET, ')');
1574
1575 if ( u64AddrMin > UINT16_MAX
1576 || u64AddrMax > UINT16_MAX
1577 || u64AddrAlignment > UINT8_MAX
1578 || u64RangeLength > UINT8_MAX)
1579 return RTErrInfoSetF(pThis->pErrInfo, VERR_INVALID_PARAMETER,
1580 "Invalid parameters given to IO macro: AddressMin=%#RX16 AddressMax=%#RX16 AddressAlignment=%#RX8 RangeLength=%#RX8",
1581 u64AddrMin, u64AddrMax, u64AddrAlignment, u64RangeLength);
1582
1583 if (pszName)
1584 {
1585 static const RTACPIRSRCNSENTRY s_aRsrcNs[] =
1586 {
1587 { "_DEC", 1 * 8, 1 },
1588 { "_MIN", 2 * 8, 16 },
1589 { "_MAX", 4 * 8, 16 },
1590 { "_ALN", 6 * 8, 8 },
1591 { "_LEN", 7 * 8, 8 },
1592 { NULL, 0, 0 }
1593 };
1594 int rc = rtAcpiTblParseResourceNsCreateEntries(pThis, hAcpiRes, pAstNd, "IO", pszName, &s_aRsrcNs[0]);
1595 if (RT_FAILURE(rc))
1596 return rc;
1597 }
1598
1599 int rc = RTAcpiResourceAddIo(hAcpiRes, enmDecode == RTACPIASLTERMINAL_KEYWORD_DECODE_10 ? kAcpiResIoDecodeType_Decode10 : kAcpiResIoDecodeType_Decode16,
1600 (uint16_t)u64AddrMin, (uint16_t)u64AddrMax, (uint8_t)u64AddrAlignment, (uint8_t)u64RangeLength);
1601 if (RT_FAILURE(rc))
1602 return RTErrInfoSetF(pThis->pErrInfo, rc,
1603 "Failed to add IO(,,,,, %s)", pszName ? pszName : "<NONE>");
1604
1605 return VINF_SUCCESS;
1606}
1607
1608
1609static int rtAcpiTblParseResourceDma(PRTACPIASLCU pThis, RTACPIRES hAcpiRes, PRTACPIASTNODE pAstNd)
1610{
1611 static const RTACPIASLTERMINAL s_aenmDmaTypeKeywords[] = { RTACPIASLTERMINAL_KEYWORD_COMPATIBILITY, RTACPIASLTERMINAL_KEYWORD_TYPE_A,
1612 RTACPIASLTERMINAL_KEYWORD_TYPE_B, RTACPIASLTERMINAL_KEYWORD_TYPE_F,
1613 RTACPIASLTERMINAL_INVALID };
1614 static const RTACPIASLTERMINAL s_aenmBusMasterKeywords[] = { RTACPIASLTERMINAL_KEYWORD_BUS_MASTER, RTACPIASLTERMINAL_KEYWORD_NOT_BUS_MASTER,
1615 RTACPIASLTERMINAL_INVALID };
1616 static const RTACPIASLTERMINAL s_aenmDmaTransferSizeKeywords[] = { RTACPIASLTERMINAL_KEYWORD_TRANSFER_8, RTACPIASLTERMINAL_KEYWORD_TRANSFER_16,
1617 RTACPIASLTERMINAL_KEYWORD_TRANSFER_8_16, RTACPIASLTERMINAL_INVALID };
1618
1619 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_OPEN_BRACKET, '(');
1620 RTACPIASL_PARSE_KEYWORD_LIST(enmDmaType, s_aenmDmaTypeKeywords);
1621 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1622 RTACPIASL_PARSE_OPTIONAL_KEYWORD_LIST(enmBusMaster, s_aenmBusMasterKeywords, RTACPIASLTERMINAL_KEYWORD_BUS_MASTER);
1623 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1624 RTACPIASL_PARSE_KEYWORD_LIST(enmDmaTransferSize, s_aenmDmaTransferSizeKeywords);
1625 RTACPIASL_PARSE_OPTIONAL_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA);
1626 RTACPIASL_PARSE_OPTIONAL_NAME_STRING(pszName);
1627 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_BRACKET, ')');
1628
1629 uint8_t bmDmaChannels = 0;
1630 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_OPEN_CURLY_BRACKET, '{');
1631 for (;;)
1632 {
1633 if (rtAcpiAslLexerIsPunctuator(pThis, RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_CURLY_BRACKET))
1634 break;
1635
1636 RTACPIASL_PARSE_NATURAL(u64DmaChannel);
1637 if (u64DmaChannel > 7)
1638 return RTErrInfoSetF(pThis->pErrInfo, VERR_INVALID_PARAMETER,
1639 "DMA channel number is out of range [0..7]: %RU64",
1640 u64DmaChannel);
1641 if (bmDmaChannels & RT_BIT(u64DmaChannel))
1642 return RTErrInfoSetF(pThis->pErrInfo, VERR_INVALID_PARAMETER, "Duplicate DMA channel %RU64 in list", u64DmaChannel);
1643
1644 bmDmaChannels |= RT_BIT(u64DmaChannel);
1645
1646 /* A following "," means there is another entry, otherwise the closing "}" should follow. */
1647 if (!rtAcpiAslLexerIsPunctuator(pThis, RTACPIASLTERMINAL_PUNCTUATOR_COMMA))
1648 break;
1649
1650 RTACPIASL_SKIP_CURRENT_TOKEN(); /* Skip the "," */
1651 }
1652 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_CURLY_BRACKET, '}');
1653
1654 if (pszName)
1655 {
1656 static const RTACPIRSRCNSENTRY s_aRsrcNs[] =
1657 {
1658 { "_DMA", 1 * 8, 8 },
1659 { "_SIZ", 2 * 8, 2 },
1660 { "_BM_", 2 * 8 + 2, 1 },
1661 { "_TYP", 2 * 8 + 3, 2 },
1662 { NULL, 0, 0 }
1663 };
1664 int rc = rtAcpiTblParseResourceNsCreateEntries(pThis, hAcpiRes, pAstNd, "DMA", pszName, &s_aRsrcNs[0]);
1665 if (RT_FAILURE(rc))
1666 return rc;
1667 }
1668
1669 RTACPIRESDMACHANSPEED enmChanSpeed = kAcpiResDmaChanSpeed_Invalid;
1670 switch (enmDmaType)
1671 {
1672 case RTACPIASLTERMINAL_KEYWORD_COMPATIBILITY: enmChanSpeed = kAcpiResDmaChanSpeed_Compatibility; break;
1673 case RTACPIASLTERMINAL_KEYWORD_TYPE_A: enmChanSpeed = kAcpiResDmaChanSpeed_TypeA; break;
1674 case RTACPIASLTERMINAL_KEYWORD_TYPE_B: enmChanSpeed = kAcpiResDmaChanSpeed_TypeB; break;
1675 case RTACPIASLTERMINAL_KEYWORD_TYPE_F: enmChanSpeed = kAcpiResDmaChanSpeed_TypeF; break;
1676 default:
1677 AssertReleaseFailed();
1678 }
1679
1680 RTACPIRESDMATRANSFERTYPE enmTransferType = kAcpiResDmaTransferType_Invalid;
1681 switch (enmDmaTransferSize)
1682 {
1683 case RTACPIASLTERMINAL_KEYWORD_TRANSFER_8: enmTransferType = kAcpiResDmaTransferType_8Bit; break;
1684 case RTACPIASLTERMINAL_KEYWORD_TRANSFER_16: enmTransferType = kAcpiResDmaTransferType_16Bit; break;
1685 case RTACPIASLTERMINAL_KEYWORD_TRANSFER_8_16: enmTransferType = kAcpiResDmaTransferType_8Bit_16Bit; break;
1686 default:
1687 AssertReleaseFailed();
1688 }
1689
1690 int rc = RTAcpiResourceAddDma(hAcpiRes, enmChanSpeed,
1691 enmBusMaster == RTACPIASLTERMINAL_KEYWORD_BUS_MASTER,
1692 enmTransferType, bmDmaChannels);
1693 if (RT_FAILURE(rc))
1694 return RTErrInfoSetF(pThis->pErrInfo, rc,
1695 "Failed to add DMA(,,,,, %s)", pszName ? pszName : "<NONE>");
1696
1697 return VINF_SUCCESS;
1698}
1699
1700
1701static const RTACPIASLTERMINAL s_aenmResourceUsageKeywords[] = { RTACPIASLTERMINAL_KEYWORD_RESOURCE_CONSUMER, RTACPIASLTERMINAL_KEYWORD_RESOURCE_PRODUCER, RTACPIASLTERMINAL_INVALID };
1702static const RTACPIASLTERMINAL s_aenmIsMinFixedKeywords[] = { RTACPIASLTERMINAL_KEYWORD_MIN_FIXED, RTACPIASLTERMINAL_KEYWORD_MIN_NOT_FIXED, RTACPIASLTERMINAL_INVALID };
1703static const RTACPIASLTERMINAL s_aenmIsMaxFixedKeywords[] = { RTACPIASLTERMINAL_KEYWORD_MAX_FIXED, RTACPIASLTERMINAL_KEYWORD_MAX_NOT_FIXED, RTACPIASLTERMINAL_INVALID };
1704static const RTACPIASLTERMINAL s_aenmDecodeKeywords[] = { RTACPIASLTERMINAL_KEYWORD_POS_DECODE, RTACPIASLTERMINAL_KEYWORD_SUB_DECODE, RTACPIASLTERMINAL_INVALID };
1705static const RTACPIASLTERMINAL s_aenmIsaRangesKeywords[] = { RTACPIASLTERMINAL_KEYWORD_ISA_ONLY, RTACPIASLTERMINAL_KEYWORD_NON_ISA_ONLY,
1706 RTACPIASLTERMINAL_KEYWORD_ENTIRE_RANGE, RTACPIASLTERMINAL_INVALID };
1707static const RTACPIASLTERMINAL s_aenmTranslationTypeKeywords[] = { RTACPIASLTERMINAL_KEYWORD_TYPE_TRANSLATION, RTACPIASLTERMINAL_KEYWORD_TYPE_STATIC, RTACPIASLTERMINAL_INVALID };
1708static const RTACPIASLTERMINAL s_aenmTranslationDensityKeywords[] = { RTACPIASLTERMINAL_KEYWORD_SPARSE_TRANSLATION, RTACPIASLTERMINAL_KEYWORD_DENSE_TRANSLATION, RTACPIASLTERMINAL_INVALID };
1709
1710
1711static int rtAcpiTblParseResourceWordBusNumber(PRTACPIASLCU pThis, RTACPIRES hAcpiRes, PRTACPIASTNODE pAstNd)
1712{
1713 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_OPEN_BRACKET, '(');
1714 RTACPIASL_PARSE_OPTIONAL_KEYWORD_LIST(enmResourceUsage, s_aenmResourceUsageKeywords, RTACPIASLTERMINAL_KEYWORD_RESOURCE_CONSUMER);
1715 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1716 RTACPIASL_PARSE_OPTIONAL_KEYWORD_LIST(enmIsMinFixed, s_aenmIsMinFixedKeywords, RTACPIASLTERMINAL_KEYWORD_MIN_NOT_FIXED);
1717 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1718 RTACPIASL_PARSE_OPTIONAL_KEYWORD_LIST(enmIsMaxFixed, s_aenmIsMaxFixedKeywords, RTACPIASLTERMINAL_KEYWORD_MAX_NOT_FIXED);
1719 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1720 RTACPIASL_PARSE_OPTIONAL_KEYWORD_LIST(enmDecode, s_aenmDecodeKeywords, RTACPIASLTERMINAL_KEYWORD_POS_DECODE);
1721 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1722 RTACPIASL_PARSE_NATURAL(u64AddrGranularity);
1723 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1724 RTACPIASL_PARSE_NATURAL(u64AddrMin);
1725 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1726 RTACPIASL_PARSE_NATURAL(u64AddrMax);
1727 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1728 RTACPIASL_PARSE_NATURAL(u64AddrTranslation);
1729 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1730 RTACPIASL_PARSE_NATURAL(u64RangeLength);
1731 RTACPIASL_PARSE_OPTIONAL_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA);
1732 RTACPIASL_PARSE_OPTIONAL_NATURAL(u64ResSrcIndex, UINT64_MAX);
1733 RTACPIASL_PARSE_OPTIONAL_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA);
1734 RTACPIASL_PARSE_OPTIONAL_NAME_STRING(pszResSrc);
1735 RTACPIASL_PARSE_OPTIONAL_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA);
1736 RTACPIASL_PARSE_OPTIONAL_NAME_STRING(pszName);
1737 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_BRACKET, ')');
1738
1739 if (pszName)
1740 {
1741 static const RTACPIRSRCNSENTRY s_aRsrcNs[] =
1742 {
1743 { "_DEC", 4 * 8 + 1, 1 },
1744 { "_MIF", 4 * 8 + 2, 1 },
1745 { "_MAF", 4 * 8 + 3, 1 },
1746 { "_GRA", 6 * 8, 16 },
1747 { "_MIN", 8 * 8, 16 },
1748 { "_MAX", 10 * 8, 16 },
1749 { "_TRA", 12 * 8, 16 },
1750 { "_LEN", 14 * 8, 16 },
1751 { NULL, 0, 0 }
1752 };
1753 int rc = rtAcpiTblParseResourceNsCreateEntries(pThis, hAcpiRes, pAstNd, "WordBusNumber", pszName, &s_aRsrcNs[0]);
1754 if (RT_FAILURE(rc))
1755 return rc;
1756 }
1757
1758 uint32_t fAddrSpace = 0;
1759 fAddrSpace |= (enmResourceUsage == RTACPIASLTERMINAL_KEYWORD_RESOURCE_CONSUMER) ? RTACPI_RESOURCE_ADDR_RANGE_F_CONSUMER : RTACPI_RESOURCE_ADDR_RANGE_F_PRODUCER;
1760 fAddrSpace |= (enmIsMinFixed == RTACPIASLTERMINAL_KEYWORD_MIN_FIXED) ? RTACPI_RESOURCE_ADDR_RANGE_F_MIN_ADDR_FIXED : RTACPI_RESOURCE_ADDR_RANGE_F_MIN_ADDR_CHANGEABLE;
1761 fAddrSpace |= (enmIsMaxFixed == RTACPIASLTERMINAL_KEYWORD_MAX_FIXED) ? RTACPI_RESOURCE_ADDR_RANGE_F_MAX_ADDR_FIXED : RTACPI_RESOURCE_ADDR_RANGE_F_MAX_ADDR_CHANGEABLE;
1762 fAddrSpace |= (enmDecode == RTACPIASLTERMINAL_KEYWORD_POS_DECODE) ? RTACPI_RESOURCE_ADDR_RANGE_F_DECODE_TYPE_POS : RTACPI_RESOURCE_ADDR_RANGE_F_DECODE_TYPE_SUB;
1763 int rc = RTAcpiResourceAddWordBusNumberEx(hAcpiRes, fAddrSpace, (uint16_t)u64AddrMin, (uint16_t)u64AddrMax,
1764 (uint16_t)u64AddrTranslation, (uint16_t)u64AddrGranularity, (uint16_t)u64RangeLength,
1765 pszResSrc, (uint8_t)u64ResSrcIndex);
1766 if (RT_FAILURE(rc))
1767 return RTErrInfoSetF(pThis->pErrInfo, rc,
1768 "Failed to add WordBusNumber(,,,,, %s)", pszName ? pszName : "<NONE>");
1769
1770 return VINF_SUCCESS;
1771}
1772
1773
1774static int rtAcpiTblParseResourceWordIo(PRTACPIASLCU pThis, RTACPIRES hAcpiRes, PRTACPIASTNODE pAstNd)
1775{
1776 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_OPEN_BRACKET, '(');
1777 RTACPIASL_PARSE_OPTIONAL_KEYWORD_LIST(enmResourceUsage, s_aenmResourceUsageKeywords, RTACPIASLTERMINAL_KEYWORD_RESOURCE_CONSUMER);
1778 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1779 RTACPIASL_PARSE_OPTIONAL_KEYWORD_LIST(enmIsMinFixed, s_aenmIsMinFixedKeywords, RTACPIASLTERMINAL_KEYWORD_MIN_NOT_FIXED);
1780 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1781 RTACPIASL_PARSE_OPTIONAL_KEYWORD_LIST(enmIsMaxFixed, s_aenmIsMaxFixedKeywords, RTACPIASLTERMINAL_KEYWORD_MAX_NOT_FIXED);
1782 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1783 RTACPIASL_PARSE_OPTIONAL_KEYWORD_LIST(enmDecode, s_aenmDecodeKeywords, RTACPIASLTERMINAL_KEYWORD_POS_DECODE);
1784 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1785 RTACPIASL_PARSE_KEYWORD_LIST(enmIsaRange, s_aenmIsaRangesKeywords);
1786 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1787 RTACPIASL_PARSE_NATURAL(u64AddrGranularity);
1788 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1789 RTACPIASL_PARSE_NATURAL(u64AddrMin);
1790 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1791 RTACPIASL_PARSE_NATURAL(u64AddrMax);
1792 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1793 RTACPIASL_PARSE_NATURAL(u64AddrTranslation);
1794 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1795 RTACPIASL_PARSE_NATURAL(u64RangeLength);
1796 RTACPIASL_PARSE_OPTIONAL_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA);
1797 RTACPIASL_PARSE_OPTIONAL_NATURAL(u64ResSrcIndex, UINT64_MAX);
1798 RTACPIASL_PARSE_OPTIONAL_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA);
1799 RTACPIASL_PARSE_OPTIONAL_NAME_STRING(pszResSrc);
1800 RTACPIASL_PARSE_OPTIONAL_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA);
1801 RTACPIASL_PARSE_OPTIONAL_NAME_STRING(pszName);
1802 RTACPIASL_PARSE_OPTIONAL_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA);
1803 RTACPIASL_PARSE_OPTIONAL_KEYWORD_LIST(enmTranslationType, s_aenmTranslationTypeKeywords, RTACPIASLTERMINAL_KEYWORD_TYPE_STATIC);
1804 RTACPIASL_PARSE_OPTIONAL_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA);
1805 RTACPIASL_PARSE_OPTIONAL_KEYWORD_LIST(enmTranslationDensity, s_aenmTranslationDensityKeywords, RTACPIASLTERMINAL_KEYWORD_DENSE_TRANSLATION);
1806 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_BRACKET, ')');
1807
1808 if (pszName)
1809 {
1810 static const RTACPIRSRCNSENTRY s_aRsrcNs[] =
1811 {
1812 { "_DEC", 4 * 8 + 1, 1 },
1813 { "_MIF", 4 * 8 + 2, 1 },
1814 { "_MAF", 4 * 8 + 3, 1 },
1815 { "_GRA", 6 * 8, 16 },
1816 { "_MIN", 8 * 8, 16 },
1817 { "_MAX", 10 * 8, 16 },
1818 { "_TRA", 12 * 8, 16 },
1819 { "_LEN", 14 * 8, 16 },
1820 { NULL, 0, 0 }
1821 };
1822 int rc = rtAcpiTblParseResourceNsCreateEntries(pThis, hAcpiRes, pAstNd, "WordIo", pszName, &s_aRsrcNs[0]);
1823 if (RT_FAILURE(rc))
1824 return rc;
1825 }
1826
1827 RTACPIRESIORANGE enmIoRange = kAcpiResIoRange_Invalid;
1828 switch (enmIsaRange)
1829 {
1830 case RTACPIASLTERMINAL_KEYWORD_ISA_ONLY: enmIoRange = kAcpiResIoRange_IsaOnly; break;
1831 case RTACPIASLTERMINAL_KEYWORD_NON_ISA_ONLY: enmIoRange = kAcpiResIoRange_NonIsaOnly; break;
1832 case RTACPIASLTERMINAL_KEYWORD_ENTIRE_RANGE: enmIoRange = kAcpiResIoRange_Whole; break;
1833 default:
1834 AssertReleaseFailed(); /* Impossible */
1835 }
1836
1837 RTACPIRESIORANGETYPE enmIoType = kAcpiResIoRangeType_Static;
1838 if (enmTranslationType == RTACPIASLTERMINAL_KEYWORD_TYPE_TRANSLATION)
1839 {
1840 if (enmTranslationDensity == RTACPIASLTERMINAL_KEYWORD_SPARSE_TRANSLATION)
1841 enmIoType = kAcpiResIoRangeType_Translation_Sparse;
1842 else
1843 enmIoType = kAcpiResIoRangeType_Translation_Dense;
1844 }
1845
1846 uint32_t fAddrSpace = 0;
1847 fAddrSpace |= (enmResourceUsage == RTACPIASLTERMINAL_KEYWORD_RESOURCE_CONSUMER) ? RTACPI_RESOURCE_ADDR_RANGE_F_CONSUMER : RTACPI_RESOURCE_ADDR_RANGE_F_PRODUCER;
1848 fAddrSpace |= (enmIsMinFixed == RTACPIASLTERMINAL_KEYWORD_MIN_FIXED) ? RTACPI_RESOURCE_ADDR_RANGE_F_MIN_ADDR_FIXED : RTACPI_RESOURCE_ADDR_RANGE_F_MIN_ADDR_CHANGEABLE;
1849 fAddrSpace |= (enmIsMaxFixed == RTACPIASLTERMINAL_KEYWORD_MAX_FIXED) ? RTACPI_RESOURCE_ADDR_RANGE_F_MAX_ADDR_FIXED : RTACPI_RESOURCE_ADDR_RANGE_F_MAX_ADDR_CHANGEABLE;
1850 fAddrSpace |= (enmDecode == RTACPIASLTERMINAL_KEYWORD_POS_DECODE) ? RTACPI_RESOURCE_ADDR_RANGE_F_DECODE_TYPE_POS : RTACPI_RESOURCE_ADDR_RANGE_F_DECODE_TYPE_SUB;
1851 int rc = RTAcpiResourceAddWordIoRangeEx(hAcpiRes, enmIoType, enmIoRange, fAddrSpace,
1852 (uint16_t)u64AddrMin, (uint16_t)u64AddrMax,
1853 (uint16_t)u64AddrTranslation, (uint16_t)u64AddrGranularity, (uint16_t)u64RangeLength,
1854 pszResSrc, (uint8_t)u64ResSrcIndex);
1855 if (RT_FAILURE(rc))
1856 return RTErrInfoSetF(pThis->pErrInfo, rc,
1857 "Failed to add WordIo(,,,,, %s)", pszName ? pszName : "<NONE>");
1858
1859 return VINF_SUCCESS;
1860}
1861
1862
1863static const RTACPIASLTERMINAL s_aenmCacheableKeywords[] = { RTACPIASLTERMINAL_KEYWORD_CACHEABLE, RTACPIASLTERMINAL_KEYWORD_WRITE_COMBINING,
1864 RTACPIASLTERMINAL_KEYWORD_PREFETCHABLE, RTACPIASLTERMINAL_KEYWORD_NON_CACHEABLE,
1865 RTACPIASLTERMINAL_INVALID };
1866static const RTACPIASLTERMINAL s_aenmMemRangeTypeKeywords[] = { RTACPIASLTERMINAL_KEYWORD_ADDRESS_RANGE_MEMORY, RTACPIASLTERMINAL_KEYWORD_ADDRESS_RANGE_NVS,
1867 RTACPIASLTERMINAL_KEYWORD_ADDRESS_RANGE_ACPI, RTACPIASLTERMINAL_KEYWORD_ADDRESS_RANGE_RESERVED,
1868 RTACPIASLTERMINAL_INVALID };
1869
1870static int rtAcpiTblParseResourceDWordMemory(PRTACPIASLCU pThis, RTACPIRES hAcpiRes, PRTACPIASTNODE pAstNd)
1871{
1872 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_OPEN_BRACKET, '(');
1873 RTACPIASL_PARSE_OPTIONAL_KEYWORD_LIST(enmResourceUsage, s_aenmResourceUsageKeywords, RTACPIASLTERMINAL_KEYWORD_RESOURCE_CONSUMER);
1874 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1875 RTACPIASL_PARSE_OPTIONAL_KEYWORD_LIST(enmDecode, s_aenmDecodeKeywords, RTACPIASLTERMINAL_KEYWORD_POS_DECODE);
1876 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1877 RTACPIASL_PARSE_OPTIONAL_KEYWORD_LIST(enmIsMinFixed, s_aenmIsMinFixedKeywords, RTACPIASLTERMINAL_KEYWORD_MIN_NOT_FIXED);
1878 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1879 RTACPIASL_PARSE_OPTIONAL_KEYWORD_LIST(enmIsMaxFixed, s_aenmIsMaxFixedKeywords, RTACPIASLTERMINAL_KEYWORD_MAX_NOT_FIXED);
1880 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1881 RTACPIASL_PARSE_OPTIONAL_KEYWORD_LIST(enmCacheable, s_aenmCacheableKeywords, RTACPIASLTERMINAL_KEYWORD_NON_CACHEABLE);
1882 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1883 RTACPIASL_PARSE_OPTIONAL_KEYWORD_LIST(enmRw, g_aenmRwRoKeywords, RTACPIASLTERMINAL_KEYWORD_READWRITE);
1884 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1885 RTACPIASL_PARSE_NATURAL(u64AddrGranularity);
1886 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1887 RTACPIASL_PARSE_NATURAL(u64AddrMin);
1888 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1889 RTACPIASL_PARSE_NATURAL(u64AddrMax);
1890 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1891 RTACPIASL_PARSE_NATURAL(u64AddrTranslation);
1892 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1893 RTACPIASL_PARSE_NATURAL(u64RangeLength);
1894 RTACPIASL_PARSE_OPTIONAL_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA);
1895 RTACPIASL_PARSE_OPTIONAL_NATURAL(u64ResSrcIndex, UINT64_MAX);
1896 RTACPIASL_PARSE_OPTIONAL_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA);
1897 RTACPIASL_PARSE_OPTIONAL_NAME_STRING(pszResSrc);
1898 RTACPIASL_PARSE_OPTIONAL_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA);
1899 RTACPIASL_PARSE_OPTIONAL_NAME_STRING(pszName);
1900 RTACPIASL_PARSE_OPTIONAL_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA);
1901 RTACPIASL_PARSE_OPTIONAL_KEYWORD_LIST(enmMemRangeType, s_aenmMemRangeTypeKeywords, RTACPIASLTERMINAL_KEYWORD_ADDRESS_RANGE_MEMORY);
1902 RTACPIASL_PARSE_OPTIONAL_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA);
1903 RTACPIASL_PARSE_OPTIONAL_KEYWORD_LIST(enmTranslationType, s_aenmTranslationTypeKeywords, RTACPIASLTERMINAL_KEYWORD_TYPE_STATIC);
1904 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_BRACKET, ')');
1905
1906 if (pszName)
1907 {
1908 static const RTACPIRSRCNSENTRY s_aRsrcNs[] =
1909 {
1910 { "_DEC", 4 * 8 + 1, 1 },
1911 { "_MIF", 4 * 8 + 2, 1 },
1912 { "_MAF", 4 * 8 + 3, 1 },
1913 { "_RW_", 5 * 8, 1 },
1914 { "_MEM", 5 * 8 + 1, 2 },
1915 { "_MTP", 5 * 8 + 3, 2 },
1916 { "_TTP", 5 * 8 + 5, 1 },
1917 { "_GRA", 6 * 8, 32 },
1918 { "_MIN", 10 * 8, 32 },
1919 { "_MAX", 14 * 8, 32 },
1920 { "_TRA", 18 * 8, 32 },
1921 { "_LEN", 22 * 8, 32 },
1922 { NULL, 0, 0 }
1923 };
1924 int rc = rtAcpiTblParseResourceNsCreateEntries(pThis, hAcpiRes, pAstNd, "DWordMemory", pszName, &s_aRsrcNs[0]);
1925 if (RT_FAILURE(rc))
1926 return rc;
1927 }
1928
1929 RTACPIRESMEMRANGECACHEABILITY enmCacheability = kAcpiResMemRangeCacheability_Invalid;
1930 switch (enmCacheable)
1931 {
1932 case RTACPIASLTERMINAL_KEYWORD_CACHEABLE: enmCacheability = kAcpiResMemRangeCacheability_Cacheable; break;
1933 case RTACPIASLTERMINAL_KEYWORD_WRITE_COMBINING: enmCacheability = kAcpiResMemRangeCacheability_CacheableWriteCombining; break;
1934 case RTACPIASLTERMINAL_KEYWORD_PREFETCHABLE: enmCacheability = kAcpiResMemRangeCacheability_CacheablePrefetchable; break;
1935 case RTACPIASLTERMINAL_KEYWORD_NON_CACHEABLE: enmCacheability = kAcpiResMemRangeCacheability_NonCacheable; break;
1936 default:
1937 AssertReleaseFailed(); /* Impossible */
1938 }
1939
1940 RTACPIRESMEMRANGETYPE enmRangeType = kAcpiResMemType_Invalid;
1941 switch (enmMemRangeType)
1942 {
1943 case RTACPIASLTERMINAL_KEYWORD_ADDRESS_RANGE_MEMORY: enmRangeType = kAcpiResMemType_Memory; break;
1944 case RTACPIASLTERMINAL_KEYWORD_ADDRESS_RANGE_NVS: enmRangeType = kAcpiResMemType_Nvs; break;
1945 case RTACPIASLTERMINAL_KEYWORD_ADDRESS_RANGE_ACPI: enmRangeType = kAcpiResMemType_Acpi; break;
1946 case RTACPIASLTERMINAL_KEYWORD_ADDRESS_RANGE_RESERVED: enmRangeType = kAcpiResMemType_Reserved; break;
1947 default:
1948 AssertReleaseFailed(); /* Impossible */
1949 }
1950
1951 uint32_t fAddrSpace = 0;
1952 fAddrSpace |= (enmResourceUsage == RTACPIASLTERMINAL_KEYWORD_RESOURCE_CONSUMER) ? RTACPI_RESOURCE_ADDR_RANGE_F_CONSUMER : RTACPI_RESOURCE_ADDR_RANGE_F_PRODUCER;
1953 fAddrSpace |= (enmIsMinFixed == RTACPIASLTERMINAL_KEYWORD_MIN_FIXED) ? RTACPI_RESOURCE_ADDR_RANGE_F_MIN_ADDR_FIXED : RTACPI_RESOURCE_ADDR_RANGE_F_MIN_ADDR_CHANGEABLE;
1954 fAddrSpace |= (enmIsMaxFixed == RTACPIASLTERMINAL_KEYWORD_MAX_FIXED) ? RTACPI_RESOURCE_ADDR_RANGE_F_MAX_ADDR_FIXED : RTACPI_RESOURCE_ADDR_RANGE_F_MAX_ADDR_CHANGEABLE;
1955 fAddrSpace |= (enmDecode == RTACPIASLTERMINAL_KEYWORD_POS_DECODE) ? RTACPI_RESOURCE_ADDR_RANGE_F_DECODE_TYPE_POS : RTACPI_RESOURCE_ADDR_RANGE_F_DECODE_TYPE_SUB;
1956 int rc = RTAcpiResourceAddDWordMemoryRangeEx(hAcpiRes, enmCacheability, enmRangeType,
1957 enmRw == RTACPIASLTERMINAL_KEYWORD_READWRITE,
1958 enmTranslationType == RTACPIASLTERMINAL_KEYWORD_TYPE_STATIC,
1959 fAddrSpace, (uint32_t)u64AddrMin, (uint32_t)u64AddrMax,
1960 (uint32_t)u64AddrTranslation, (uint32_t)u64AddrGranularity, (uint32_t)u64RangeLength,
1961 pszResSrc, (uint8_t)u64ResSrcIndex);
1962 if (RT_FAILURE(rc))
1963 return RTErrInfoSetF(pThis->pErrInfo, rc,
1964 "Failed to add DWordMemory(,,,,, %s)", pszName ? pszName : "<NONE>");
1965
1966 return VINF_SUCCESS;
1967}
1968
1969
1970static int rtAcpiTblParseResourceQWordMemory(PRTACPIASLCU pThis, RTACPIRES hAcpiRes, PRTACPIASTNODE pAstNd)
1971{
1972 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_OPEN_BRACKET, '(');
1973 RTACPIASL_PARSE_OPTIONAL_KEYWORD_LIST(enmResourceUsage, s_aenmResourceUsageKeywords, RTACPIASLTERMINAL_KEYWORD_RESOURCE_CONSUMER);
1974 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1975 RTACPIASL_PARSE_OPTIONAL_KEYWORD_LIST(enmDecode, s_aenmDecodeKeywords, RTACPIASLTERMINAL_KEYWORD_POS_DECODE);
1976 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1977 RTACPIASL_PARSE_OPTIONAL_KEYWORD_LIST(enmIsMinFixed, s_aenmIsMinFixedKeywords, RTACPIASLTERMINAL_KEYWORD_MIN_NOT_FIXED);
1978 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1979 RTACPIASL_PARSE_OPTIONAL_KEYWORD_LIST(enmIsMaxFixed, s_aenmIsMaxFixedKeywords, RTACPIASLTERMINAL_KEYWORD_MAX_NOT_FIXED);
1980 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1981 RTACPIASL_PARSE_OPTIONAL_KEYWORD_LIST(enmCacheable, s_aenmCacheableKeywords, RTACPIASLTERMINAL_KEYWORD_NON_CACHEABLE);
1982 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1983 RTACPIASL_PARSE_OPTIONAL_KEYWORD_LIST(enmRw, g_aenmRwRoKeywords, RTACPIASLTERMINAL_KEYWORD_READWRITE);
1984 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1985 RTACPIASL_PARSE_NATURAL(u64AddrGranularity);
1986 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1987 RTACPIASL_PARSE_NATURAL(u64AddrMin);
1988 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1989 RTACPIASL_PARSE_NATURAL(u64AddrMax);
1990 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1991 RTACPIASL_PARSE_NATURAL(u64AddrTranslation);
1992 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
1993 RTACPIASL_PARSE_NATURAL(u64RangeLength);
1994 RTACPIASL_PARSE_OPTIONAL_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA);
1995 RTACPIASL_PARSE_OPTIONAL_NATURAL(u64ResSrcIndex, UINT64_MAX);
1996 RTACPIASL_PARSE_OPTIONAL_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA);
1997 RTACPIASL_PARSE_OPTIONAL_NAME_STRING(pszResSrc);
1998 RTACPIASL_PARSE_OPTIONAL_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA);
1999 RTACPIASL_PARSE_OPTIONAL_NAME_STRING(pszName);
2000 RTACPIASL_PARSE_OPTIONAL_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA);
2001 RTACPIASL_PARSE_OPTIONAL_KEYWORD_LIST(enmMemRangeType, s_aenmMemRangeTypeKeywords, RTACPIASLTERMINAL_KEYWORD_ADDRESS_RANGE_MEMORY);
2002 RTACPIASL_PARSE_OPTIONAL_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA);
2003 RTACPIASL_PARSE_OPTIONAL_KEYWORD_LIST(enmTranslationType, s_aenmTranslationTypeKeywords, RTACPIASLTERMINAL_KEYWORD_TYPE_STATIC);
2004 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_BRACKET, ')');
2005
2006 if (pszName)
2007 {
2008 static const RTACPIRSRCNSENTRY s_aRsrcNs[] =
2009 {
2010 { "_DEC", 4 * 8 + 1, 1 },
2011 { "_MIF", 4 * 8 + 2, 1 },
2012 { "_MAF", 4 * 8 + 3, 1 },
2013 { "_RW_", 5 * 8, 1 },
2014 { "_MEM", 5 * 8 + 1, 2 },
2015 { "_MTP", 5 * 8 + 3, 2 },
2016 { "_TTP", 5 * 8 + 5, 1 },
2017 { "_GRA", 6 * 8, 64 },
2018 { "_MIN", 14 * 8, 64 },
2019 { "_MAX", 22 * 8, 64 },
2020 { "_TRA", 30 * 8, 64 },
2021 { "_LEN", 38 * 8, 64 },
2022 { NULL, 0, 0 }
2023 };
2024 int rc = rtAcpiTblParseResourceNsCreateEntries(pThis, hAcpiRes, pAstNd, "QWordMemory", pszName, &s_aRsrcNs[0]);
2025 if (RT_FAILURE(rc))
2026 return rc;
2027 }
2028
2029 RTACPIRESMEMRANGECACHEABILITY enmCacheability = kAcpiResMemRangeCacheability_Invalid;
2030 switch (enmCacheable)
2031 {
2032 case RTACPIASLTERMINAL_KEYWORD_CACHEABLE: enmCacheability = kAcpiResMemRangeCacheability_Cacheable; break;
2033 case RTACPIASLTERMINAL_KEYWORD_WRITE_COMBINING: enmCacheability = kAcpiResMemRangeCacheability_CacheableWriteCombining; break;
2034 case RTACPIASLTERMINAL_KEYWORD_PREFETCHABLE: enmCacheability = kAcpiResMemRangeCacheability_CacheablePrefetchable; break;
2035 case RTACPIASLTERMINAL_KEYWORD_NON_CACHEABLE: enmCacheability = kAcpiResMemRangeCacheability_NonCacheable; break;
2036 default:
2037 AssertReleaseFailed(); /* Impossible */
2038 }
2039
2040 RTACPIRESMEMRANGETYPE enmRangeType = kAcpiResMemType_Invalid;
2041 switch (enmMemRangeType)
2042 {
2043 case RTACPIASLTERMINAL_KEYWORD_ADDRESS_RANGE_MEMORY: enmRangeType = kAcpiResMemType_Memory; break;
2044 case RTACPIASLTERMINAL_KEYWORD_ADDRESS_RANGE_NVS: enmRangeType = kAcpiResMemType_Nvs; break;
2045 case RTACPIASLTERMINAL_KEYWORD_ADDRESS_RANGE_ACPI: enmRangeType = kAcpiResMemType_Acpi; break;
2046 case RTACPIASLTERMINAL_KEYWORD_ADDRESS_RANGE_RESERVED: enmRangeType = kAcpiResMemType_Reserved; break;
2047 default:
2048 AssertReleaseFailed(); /* Impossible */
2049 }
2050
2051 uint32_t fAddrSpace = 0;
2052 fAddrSpace |= (enmResourceUsage == RTACPIASLTERMINAL_KEYWORD_RESOURCE_CONSUMER) ? RTACPI_RESOURCE_ADDR_RANGE_F_CONSUMER : RTACPI_RESOURCE_ADDR_RANGE_F_PRODUCER;
2053 fAddrSpace |= (enmIsMinFixed == RTACPIASLTERMINAL_KEYWORD_MIN_FIXED) ? RTACPI_RESOURCE_ADDR_RANGE_F_MIN_ADDR_FIXED : RTACPI_RESOURCE_ADDR_RANGE_F_MIN_ADDR_CHANGEABLE;
2054 fAddrSpace |= (enmIsMaxFixed == RTACPIASLTERMINAL_KEYWORD_MAX_FIXED) ? RTACPI_RESOURCE_ADDR_RANGE_F_MAX_ADDR_FIXED : RTACPI_RESOURCE_ADDR_RANGE_F_MAX_ADDR_CHANGEABLE;
2055 fAddrSpace |= (enmDecode == RTACPIASLTERMINAL_KEYWORD_POS_DECODE) ? RTACPI_RESOURCE_ADDR_RANGE_F_DECODE_TYPE_POS : RTACPI_RESOURCE_ADDR_RANGE_F_DECODE_TYPE_SUB;
2056 int rc = RTAcpiResourceAddQWordMemoryRangeEx(hAcpiRes, enmCacheability, enmRangeType,
2057 enmRw == RTACPIASLTERMINAL_KEYWORD_READWRITE,
2058 enmTranslationType == RTACPIASLTERMINAL_KEYWORD_TYPE_STATIC,
2059 fAddrSpace, u64AddrMin, u64AddrMax, u64AddrTranslation, u64AddrGranularity, u64RangeLength,
2060 pszResSrc, (uint8_t)u64ResSrcIndex);
2061 if (RT_FAILURE(rc))
2062 return RTErrInfoSetF(pThis->pErrInfo, rc,
2063 "Failed to add QWordMemory(,,,,, %s)", pszName ? pszName : "<NONE>");
2064
2065 return VINF_SUCCESS;
2066}
2067
2068
2069static DECLCALLBACK(int) rtAcpiTblAslParseResourceTemplate(PRTACPIASLCU pThis, PCRTACPIASLKEYWORD pKeyword, PRTACPIASTNODE pAstNd)
2070{
2071 RT_NOREF(pKeyword);
2072
2073 static const RTACPIASLTERMINAL s_aenmResourceTemplateKeywords[] = {
2074 RTACPIASLTERMINAL_KEYWORD_MEMORY32_FIXED,
2075 RTACPIASLTERMINAL_KEYWORD_IRQ,
2076 RTACPIASLTERMINAL_KEYWORD_IRQ_NO_FLAGS,
2077 RTACPIASLTERMINAL_KEYWORD_IO,
2078 RTACPIASLTERMINAL_KEYWORD_DMA,
2079 RTACPIASLTERMINAL_KEYWORD_WORD_BUS_NUMBER,
2080 RTACPIASLTERMINAL_KEYWORD_WORD_IO,
2081 RTACPIASLTERMINAL_KEYWORD_DWORD_MEMORY,
2082 RTACPIASLTERMINAL_KEYWORD_QWORD_MEMORY,
2083 RTACPIASLTERMINAL_INVALID
2084 };
2085
2086 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_OPEN_BRACKET, '(');
2087 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_BRACKET, ')');
2088
2089 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_OPEN_CURLY_BRACKET, '{');
2090
2091 RTACPIRES hAcpiRes = NULL;
2092 int rc = RTAcpiResourceCreate(&hAcpiRes);
2093 if (RT_FAILURE(rc))
2094 return RTErrInfoSetF(pThis->pErrInfo, rc, "Creating the ACPI resource template failed while parsing");
2095
2096 /* Assign here already to have the ACPI resource freed when the node gets destroyed, even if there is an error while parsing. */
2097 pAstNd->hAcpiRes = hAcpiRes;
2098
2099 /* Get to work */
2100 for (;;)
2101 {
2102 RTACPIASL_PARSE_KEYWORD_LIST(enmResourceKeyword, s_aenmResourceTemplateKeywords);
2103 switch (enmResourceKeyword)
2104 {
2105 case RTACPIASLTERMINAL_KEYWORD_MEMORY32_FIXED:
2106 {
2107 rc = rtAcpiTblParseResourceMemory32Fixed(pThis, hAcpiRes, pAstNd);
2108 break;
2109 }
2110 case RTACPIASLTERMINAL_KEYWORD_IRQ:
2111 {
2112 rc = rtAcpiTblParseResourceIrq(pThis, hAcpiRes, pAstNd);
2113 break;
2114 }
2115 case RTACPIASLTERMINAL_KEYWORD_IRQ_NO_FLAGS:
2116 {
2117 rc = rtAcpiTblParseResourceIrqNoFlags(pThis, hAcpiRes, pAstNd);
2118 break;
2119 }
2120 case RTACPIASLTERMINAL_KEYWORD_IO:
2121 {
2122 rc = rtAcpiTblParseResourceIo(pThis, hAcpiRes, pAstNd);
2123 break;
2124 }
2125 case RTACPIASLTERMINAL_KEYWORD_DMA:
2126 {
2127 rc = rtAcpiTblParseResourceDma(pThis, hAcpiRes, pAstNd);
2128 break;
2129 }
2130 case RTACPIASLTERMINAL_KEYWORD_WORD_BUS_NUMBER:
2131 {
2132 rc = rtAcpiTblParseResourceWordBusNumber(pThis, hAcpiRes, pAstNd);
2133 break;
2134 }
2135 case RTACPIASLTERMINAL_KEYWORD_WORD_IO:
2136 {
2137 rc = rtAcpiTblParseResourceWordIo(pThis, hAcpiRes, pAstNd);
2138 break;
2139 }
2140 case RTACPIASLTERMINAL_KEYWORD_DWORD_MEMORY:
2141 {
2142 rc = rtAcpiTblParseResourceDWordMemory(pThis, hAcpiRes, pAstNd);
2143 break;
2144 }
2145 case RTACPIASLTERMINAL_KEYWORD_QWORD_MEMORY:
2146 {
2147 rc = rtAcpiTblParseResourceQWordMemory(pThis, hAcpiRes, pAstNd);
2148 break;
2149 }
2150 default: /* This should never occur. */
2151 AssertReleaseFailed();
2152 }
2153 if (RT_FAILURE(rc))
2154 return rc;
2155
2156 /* Done processing (indicated by the closing "}")?. */
2157 if (rtAcpiAslLexerIsPunctuator(pThis, RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_CURLY_BRACKET))
2158 break;
2159 }
2160
2161 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_CURLY_BRACKET, '}');
2162 rc = RTAcpiResourceSeal(hAcpiRes);
2163 if (RT_FAILURE(rc))
2164 rc = RTErrInfoSetF(pThis->pErrInfo, rc, "Failed to seal the resource after being done parsing");
2165 return rc;
2166}
2167
2168
2169static DECLCALLBACK(int) rtAcpiTblAslParsePackageOrBuffer(PRTACPIASLCU pThis, PCRTACPIASLKEYWORD pKeyword, PRTACPIASTNODE pAstNd)
2170{
2171 RT_NOREF(pKeyword);
2172
2173 /* The scope flag manually because the parsing is done here already. */
2174 RTListInit(&pAstNd->LstScopeNodes);
2175 pAstNd->fFlags |= RTACPI_AST_NODE_F_NEW_SCOPE;
2176
2177 pAstNd->aArgs[0].enmType = kAcpiAstArgType_AstNode;
2178 pAstNd->aArgs[0].u.pAstNd = NULL;
2179
2180 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_OPEN_BRACKET, '(');
2181 if (!rtAcpiAslLexerIsPunctuator(pThis, RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_BRACKET))
2182 {
2183 PRTACPIASTNODE pAstNdSize = NULL;
2184 int rc = rtAcpiTblAslParseTermArg(pThis, &pAstNdSize);
2185 if (RT_FAILURE(rc))
2186 return rc;
2187 pAstNd->aArgs[0].u.pAstNd = pAstNdSize;
2188 }
2189 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_BRACKET, ')');
2190
2191 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_OPEN_CURLY_BRACKET, '{');
2192
2193 /* Get to work */
2194 for (;;)
2195 {
2196 /** @todo Is an empty list allowed (currently we allow that)? */
2197 if (rtAcpiAslLexerIsPunctuator(pThis, RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_CURLY_BRACKET))
2198 break;
2199
2200 /* Parse the object */
2201 PRTACPIASTNODE pAstNdPkg = NULL;
2202 int rc = rtAcpiTblAslParseTermArg(pThis, &pAstNdPkg);
2203 if (RT_FAILURE(rc))
2204 return rc;
2205
2206 RTListAppend(&pAstNd->LstScopeNodes, &pAstNdPkg->NdAst);
2207
2208 /* A following "," means there is another entry, otherwise the closing "}" should follow. */
2209 if (!rtAcpiAslLexerIsPunctuator(pThis, RTACPIASLTERMINAL_PUNCTUATOR_COMMA))
2210 break;
2211
2212 RTACPIASL_SKIP_CURRENT_TOKEN(); /* Skip the "," */
2213 }
2214
2215 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_CURLY_BRACKET, '}');
2216 return VINF_SUCCESS;
2217}
2218
2219
2220static DECLCALLBACK(int) rtAcpiTblAslParseReturn(PRTACPIASLCU pThis, PCRTACPIASLKEYWORD pKeyword, PRTACPIASTNODE pAstNd)
2221{
2222 RT_NOREF(pKeyword);
2223
2224 pAstNd->aArgs[0].enmType = kAcpiAstArgType_AstNode;
2225 pAstNd->aArgs[0].u.pAstNd = NULL;
2226
2227 /*
2228 * Return has three valid forms:
2229 * Return
2230 * Return ()
2231 * Return (TermArg)
2232 */
2233 if (rtAcpiAslLexerIsPunctuator(pThis, RTACPIASLTERMINAL_PUNCTUATOR_OPEN_BRACKET))
2234 {
2235 RTACPIASL_SKIP_CURRENT_TOKEN(); /* Skip the "(" */
2236
2237 if (!rtAcpiAslLexerIsPunctuator(pThis, RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_BRACKET))
2238 {
2239 PRTACPIASTNODE pAstNdSize = NULL;
2240 int rc = rtAcpiTblAslParseTermArg(pThis, &pAstNdSize);
2241 if (RT_FAILURE(rc))
2242 return rc;
2243 pAstNd->aArgs[0].u.pAstNd = pAstNdSize;
2244 }
2245 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_BRACKET, ')');
2246 }
2247
2248 return VINF_SUCCESS;
2249}
2250
2251#define RTACPI_ASL_KEYWORD_DEFINE_INVALID \
2252 { \
2253 NULL, NULL, 0, 0, RTACPI_AST_NODE_F_DEFAULT, \
2254 { kAcpiAstArgType_Invalid, \
2255 kAcpiAstArgType_Invalid, \
2256 kAcpiAstArgType_Invalid, \
2257 kAcpiAstArgType_Invalid, \
2258 kAcpiAstArgType_Invalid}, \
2259 { \
2260 { kAcpiAstArgType_Invalid, { 0 } }, \
2261 { kAcpiAstArgType_Invalid, { 0 } }, \
2262 { kAcpiAstArgType_Invalid, { 0 } } \
2263 } \
2264 }
2265
2266#define RTACPI_ASL_KEYWORD_DEFINE_HANDLER(a_szKeyword, a_pfnHandler, a_cArgReq, a_cArgOpt, a_fFlags) \
2267 { \
2268 a_szKeyword, a_pfnHandler, a_cArgReq, a_cArgOpt, a_fFlags, \
2269 { kAcpiAstArgType_Invalid, \
2270 kAcpiAstArgType_Invalid, \
2271 kAcpiAstArgType_Invalid, \
2272 kAcpiAstArgType_Invalid, \
2273 kAcpiAstArgType_Invalid}, \
2274 { \
2275 { kAcpiAstArgType_Invalid, { 0 } }, \
2276 { kAcpiAstArgType_Invalid, { 0 } }, \
2277 { kAcpiAstArgType_Invalid, { 0 } } \
2278 } \
2279 }
2280
2281#define RTACPI_ASL_KEYWORD_DEFINE_0REQ_0OPT(a_szKeyword, a_fFlags) \
2282 { \
2283 a_szKeyword, NULL, 0, 0, a_fFlags, \
2284 { kAcpiAstArgType_Invalid, \
2285 kAcpiAstArgType_Invalid, \
2286 kAcpiAstArgType_Invalid, \
2287 kAcpiAstArgType_Invalid, \
2288 kAcpiAstArgType_Invalid}, \
2289 { \
2290 { kAcpiAstArgType_Invalid, { 0 } }, \
2291 { kAcpiAstArgType_Invalid, { 0 } }, \
2292 { kAcpiAstArgType_Invalid, { 0 } } \
2293 } \
2294 }
2295
2296#define RTACPI_ASL_KEYWORD_DEFINE_0REQ_1OPT(a_szKeyword, a_fFlags, a_enmArgTypeOpt0) \
2297 { \
2298 a_szKeyword, NULL, 0, 0, a_fFlags, \
2299 { kAcpiAstArgType_Invalid, \
2300 kAcpiAstArgType_Invalid, \
2301 kAcpiAstArgType_Invalid, \
2302 kAcpiAstArgType_Invalid, \
2303 kAcpiAstArgType_Invalid}, \
2304 { \
2305 { a_enmArgTypeOpt0, { 0 } }, \
2306 { kAcpiAstArgType_Invalid, { 0 } }, \
2307 { kAcpiAstArgType_Invalid, { 0 } } \
2308 } \
2309 }
2310
2311#define RTACPI_ASL_KEYWORD_DEFINE_1REQ_0OPT(a_szKeyword, a_fFlags, a_enmArgType0) \
2312 { \
2313 a_szKeyword, NULL, 1, 0, a_fFlags, \
2314 { a_enmArgType0, \
2315 kAcpiAstArgType_Invalid, \
2316 kAcpiAstArgType_Invalid, \
2317 kAcpiAstArgType_Invalid, \
2318 kAcpiAstArgType_Invalid}, \
2319 { \
2320 { kAcpiAstArgType_Invalid, { 0 } }, \
2321 { kAcpiAstArgType_Invalid, { 0 } }, \
2322 { kAcpiAstArgType_Invalid, { 0 } } \
2323 } \
2324 }
2325
2326#define RTACPI_ASL_KEYWORD_DEFINE_2REQ_0OPT(a_szKeyword, a_fFlags, a_enmArgType0, a_enmArgType1) \
2327 { \
2328 a_szKeyword, NULL, 2, 0, a_fFlags, \
2329 { a_enmArgType0, \
2330 a_enmArgType1, \
2331 kAcpiAstArgType_Invalid, \
2332 kAcpiAstArgType_Invalid, \
2333 kAcpiAstArgType_Invalid}, \
2334 { \
2335 { kAcpiAstArgType_Invalid, { 0 } }, \
2336 { kAcpiAstArgType_Invalid, { 0 } }, \
2337 { kAcpiAstArgType_Invalid, { 0 } } \
2338 } \
2339 }
2340
2341#define RTACPI_ASL_KEYWORD_DEFINE_3REQ_0OPT(a_szKeyword, a_fFlags, a_enmArgType0, a_enmArgType1, a_enmArgType2) \
2342 { \
2343 a_szKeyword, NULL, 3, 0, a_fFlags, \
2344 { a_enmArgType0, \
2345 a_enmArgType1, \
2346 a_enmArgType2, \
2347 kAcpiAstArgType_Invalid, \
2348 kAcpiAstArgType_Invalid}, \
2349 { \
2350 { kAcpiAstArgType_Invalid, { 0 } }, \
2351 { kAcpiAstArgType_Invalid, { 0 } }, \
2352 { kAcpiAstArgType_Invalid, { 0 } } \
2353 } \
2354 }
2355
2356#define RTACPI_ASL_KEYWORD_DEFINE_4REQ_0OPT(a_szKeyword, a_fFlags, a_enmArgType0, a_enmArgType1, a_enmArgType2, a_enmArgType3) \
2357 { \
2358 a_szKeyword, NULL, 4, 0, a_fFlags, \
2359 { a_enmArgType0, \
2360 a_enmArgType1, \
2361 a_enmArgType2, \
2362 a_enmArgType3, \
2363 kAcpiAstArgType_Invalid}, \
2364 { \
2365 { kAcpiAstArgType_Invalid, { 0 } }, \
2366 { kAcpiAstArgType_Invalid, { 0 } }, \
2367 { kAcpiAstArgType_Invalid, { 0 } } \
2368 } \
2369 }
2370
2371#define RTACPI_ASL_KEYWORD_DEFINE_2REQ_1OPT(a_szKeyword, a_fFlags, a_enmArgType0, a_enmArgType1, a_enmArgTypeOpt0) \
2372 { \
2373 a_szKeyword, NULL, 2, 1, a_fFlags, \
2374 { a_enmArgType0, \
2375 a_enmArgType1, \
2376 kAcpiAstArgType_Invalid, \
2377 kAcpiAstArgType_Invalid, \
2378 kAcpiAstArgType_Invalid}, \
2379 { \
2380 { a_enmArgTypeOpt0, { 0 } }, \
2381 { kAcpiAstArgType_Invalid, { 0 } }, \
2382 { kAcpiAstArgType_Invalid, { 0 } } \
2383 } \
2384 }
2385
2386#define RTACPI_ASL_KEYWORD_DEFINE_1REQ_1OPT(a_szKeyword, a_fFlags, a_enmArgType0, a_enmArgTypeOpt0) \
2387 { \
2388 a_szKeyword, NULL, 1, 1, a_fFlags, \
2389 { a_enmArgType0, \
2390 kAcpiAstArgType_Invalid, \
2391 kAcpiAstArgType_Invalid, \
2392 kAcpiAstArgType_Invalid, \
2393 kAcpiAstArgType_Invalid}, \
2394 { \
2395 { a_enmArgTypeOpt0, { 0 } }, \
2396 { kAcpiAstArgType_Invalid, { 0 } }, \
2397 { kAcpiAstArgType_Invalid, { 0 } } \
2398 } \
2399 }
2400
2401/**
2402 * Operations encoding table, indexed by kAcpiAstNodeOp_XXX.
2403 */
2404static const RTACPIASLKEYWORD g_aAslOps[] =
2405{
2406 /* kAcpiAstNodeOp_Invalid */ RTACPI_ASL_KEYWORD_DEFINE_INVALID,
2407 /* kAcpiAstNodeOp_Identifier */ RTACPI_ASL_KEYWORD_DEFINE_INVALID,
2408 /* kAcpiAstNodeOp_StringLiteral */ RTACPI_ASL_KEYWORD_DEFINE_INVALID,
2409 /* kAcpiAstNodeOp_Number */ RTACPI_ASL_KEYWORD_DEFINE_INVALID,
2410 /* kAcpiAstNodeOp_Scope */ RTACPI_ASL_KEYWORD_DEFINE_1REQ_0OPT("Scope", RTACPI_AST_NODE_F_NEW_SCOPE | RTACPI_AST_NODE_F_NS_SWITCH, kAcpiAstArgType_NameString),
2411 /* kAcpiAstNodeOp_Processor */ {
2412 "Processor", NULL, 2, 2, RTACPI_AST_NODE_F_NEW_SCOPE | RTACPI_AST_NODE_F_NS_ENTRY,
2413 {
2414 kAcpiAstArgType_NameString,
2415 kAcpiAstArgType_U8,
2416 kAcpiAstArgType_Invalid,
2417 kAcpiAstArgType_Invalid,
2418 kAcpiAstArgType_Invalid
2419 },
2420 {
2421 { kAcpiAstArgType_U32, { 0 } },
2422 { kAcpiAstArgType_U8, { 0 } },
2423 { kAcpiAstArgType_Invalid, { 0 } }
2424 }
2425 },
2426 /* kAcpiAstNodeOp_External */ RTACPI_ASL_KEYWORD_DEFINE_INVALID, /* Special handling. */
2427 /* kAcpiAstNodeOp_Method */ RTACPI_ASL_KEYWORD_DEFINE_HANDLER( "Method", rtAcpiTblAslParseMethod, 1, 3, RTACPI_AST_NODE_F_NEW_SCOPE | RTACPI_AST_NODE_F_NS_ENTRY),
2428 /* kAcpiAstNodeOp_Device */ RTACPI_ASL_KEYWORD_DEFINE_1REQ_0OPT("Device", RTACPI_AST_NODE_F_NEW_SCOPE | RTACPI_AST_NODE_F_NS_ENTRY, kAcpiAstArgType_NameString),
2429 /* kAcpiAstNodeOp_If */ RTACPI_ASL_KEYWORD_DEFINE_1REQ_0OPT("If", RTACPI_AST_NODE_F_NEW_SCOPE, kAcpiAstArgType_AstNode),
2430 /* kAcpiAstNodeOp_Else */ RTACPI_ASL_KEYWORD_DEFINE_0REQ_0OPT("Else", RTACPI_AST_NODE_F_NEW_SCOPE),
2431 /* kAcpiAstNodeOp_LAnd */ RTACPI_ASL_KEYWORD_DEFINE_2REQ_0OPT("LAnd", RTACPI_AST_NODE_F_DEFAULT, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode),
2432 /* kAcpiAstNodeOp_LOr */ RTACPI_ASL_KEYWORD_DEFINE_2REQ_0OPT("LOr", RTACPI_AST_NODE_F_DEFAULT, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode),
2433 /* kAcpiAstNodeOp_LEqual */ RTACPI_ASL_KEYWORD_DEFINE_2REQ_0OPT("LEqual", RTACPI_AST_NODE_F_DEFAULT, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode),
2434 /* kAcpiAstNodeOp_LGreater */ RTACPI_ASL_KEYWORD_DEFINE_2REQ_0OPT("LGreater", RTACPI_AST_NODE_F_DEFAULT, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode),
2435 /* kAcpiAstNodeOp_LGreaterEqual */ RTACPI_ASL_KEYWORD_DEFINE_2REQ_0OPT("LGreaterEqual", RTACPI_AST_NODE_F_DEFAULT, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode),
2436 /* kAcpiAstNodeOp_LLess */ RTACPI_ASL_KEYWORD_DEFINE_2REQ_0OPT("LLess", RTACPI_AST_NODE_F_DEFAULT, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode),
2437 /* kAcpiAstNodeOp_LLessEqual */ RTACPI_ASL_KEYWORD_DEFINE_2REQ_0OPT("LLessEqual", RTACPI_AST_NODE_F_DEFAULT, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode),
2438 /* kAcpiAstNodeOp_LNot */ RTACPI_ASL_KEYWORD_DEFINE_1REQ_0OPT("LNot", RTACPI_AST_NODE_F_DEFAULT, kAcpiAstArgType_AstNode),
2439 /* kAcpiAstNodeOp_LNotEqual */ RTACPI_ASL_KEYWORD_DEFINE_2REQ_0OPT("LNotEqual", RTACPI_AST_NODE_F_DEFAULT, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode),
2440 /* kAcpiAstNodeOp_Zero */ RTACPI_ASL_KEYWORD_DEFINE_0REQ_0OPT("Zero", RTACPI_AST_NODE_F_DEFAULT),
2441 /* kAcpiAstNodeOp_One */ RTACPI_ASL_KEYWORD_DEFINE_0REQ_0OPT("One", RTACPI_AST_NODE_F_DEFAULT),
2442 /* kAcpiAstNodeOp_Ones */ RTACPI_ASL_KEYWORD_DEFINE_0REQ_0OPT("Ones", RTACPI_AST_NODE_F_DEFAULT),
2443 /* kAcpiAstNodeOp_Return */ RTACPI_ASL_KEYWORD_DEFINE_HANDLER( "Return", rtAcpiTblAslParseReturn, 0, 1, RTACPI_AST_NODE_F_DEFAULT),
2444 /* kAcpiAstNodeOp_Unicode */ RTACPI_ASL_KEYWORD_DEFINE_1REQ_0OPT("Unicode", RTACPI_AST_NODE_F_DEFAULT, kAcpiAstArgType_AstNode), /* Actually only String allowed here */
2445 /* kAcpiAstNodeOp_OperationRegion */ RTACPI_ASL_KEYWORD_DEFINE_4REQ_0OPT("OperationRegion", RTACPI_AST_NODE_F_DEFAULT | RTACPI_AST_NODE_F_NS_ENTRY, kAcpiAstArgType_NameString, kAcpiAstArgType_RegionSpace, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode),
2446 /* kAcpiAstNodeOp_Field */ RTACPI_ASL_KEYWORD_DEFINE_HANDLER( "Field", rtAcpiTblAslParseFieldOrIndexField, 4, 0, RTACPI_AST_NODE_F_DEFAULT),
2447 /* kAcpiAstNodeOp_Name */ RTACPI_ASL_KEYWORD_DEFINE_2REQ_0OPT("Name", RTACPI_AST_NODE_F_NS_ENTRY, kAcpiAstArgType_NameString, kAcpiAstArgType_AstNode),
2448 /* kAcpiAstNodeOp_ResourceTemplate */ RTACPI_ASL_KEYWORD_DEFINE_HANDLER( "ResourceTemplate", rtAcpiTblAslParseResourceTemplate, 0, 0, RTACPI_AST_NODE_F_DEFAULT),
2449 /* kAcpiAstNodeOp_Arg0 */ RTACPI_ASL_KEYWORD_DEFINE_0REQ_0OPT("Arg0", RTACPI_AST_NODE_F_DEFAULT),
2450 /* kAcpiAstNodeOp_Arg1 */ RTACPI_ASL_KEYWORD_DEFINE_0REQ_0OPT("Arg1", RTACPI_AST_NODE_F_DEFAULT),
2451 /* kAcpiAstNodeOp_Arg2 */ RTACPI_ASL_KEYWORD_DEFINE_0REQ_0OPT("Arg2", RTACPI_AST_NODE_F_DEFAULT),
2452 /* kAcpiAstNodeOp_Arg3 */ RTACPI_ASL_KEYWORD_DEFINE_0REQ_0OPT("Arg3", RTACPI_AST_NODE_F_DEFAULT),
2453 /* kAcpiAstNodeOp_Arg4 */ RTACPI_ASL_KEYWORD_DEFINE_0REQ_0OPT("Arg4", RTACPI_AST_NODE_F_DEFAULT),
2454 /* kAcpiAstNodeOp_Arg5 */ RTACPI_ASL_KEYWORD_DEFINE_0REQ_0OPT("Arg5", RTACPI_AST_NODE_F_DEFAULT),
2455 /* kAcpiAstNodeOp_Arg6 */ RTACPI_ASL_KEYWORD_DEFINE_0REQ_0OPT("Arg6", RTACPI_AST_NODE_F_DEFAULT),
2456 /* kAcpiAstNodeOp_Local0 */ RTACPI_ASL_KEYWORD_DEFINE_0REQ_0OPT("Local0", RTACPI_AST_NODE_F_DEFAULT),
2457 /* kAcpiAstNodeOp_Local1 */ RTACPI_ASL_KEYWORD_DEFINE_0REQ_0OPT("Local1", RTACPI_AST_NODE_F_DEFAULT),
2458 /* kAcpiAstNodeOp_Local2 */ RTACPI_ASL_KEYWORD_DEFINE_0REQ_0OPT("Local2", RTACPI_AST_NODE_F_DEFAULT),
2459 /* kAcpiAstNodeOp_Local3 */ RTACPI_ASL_KEYWORD_DEFINE_0REQ_0OPT("Local3", RTACPI_AST_NODE_F_DEFAULT),
2460 /* kAcpiAstNodeOp_Local4 */ RTACPI_ASL_KEYWORD_DEFINE_0REQ_0OPT("Local4", RTACPI_AST_NODE_F_DEFAULT),
2461 /* kAcpiAstNodeOp_Local5 */ RTACPI_ASL_KEYWORD_DEFINE_0REQ_0OPT("Local5", RTACPI_AST_NODE_F_DEFAULT),
2462 /* kAcpiAstNodeOp_Local6 */ RTACPI_ASL_KEYWORD_DEFINE_0REQ_0OPT("Local6", RTACPI_AST_NODE_F_DEFAULT),
2463 /* kAcpiAstNodeOp_Local7 */ RTACPI_ASL_KEYWORD_DEFINE_0REQ_0OPT("Local7", RTACPI_AST_NODE_F_DEFAULT),
2464 /* kAcpiAstNodeOp_Package */ RTACPI_ASL_KEYWORD_DEFINE_HANDLER( "Package", rtAcpiTblAslParsePackageOrBuffer, 0, 1, RTACPI_AST_NODE_F_DEFAULT),
2465 /* kAcpiAstNodeOp_Buffer */ RTACPI_ASL_KEYWORD_DEFINE_HANDLER( "Buffer", rtAcpiTblAslParsePackageOrBuffer, 0, 1, RTACPI_AST_NODE_F_DEFAULT),
2466 /* kAcpiAstNodeOp_ToUUid */ RTACPI_ASL_KEYWORD_DEFINE_1REQ_0OPT("ToUUID", RTACPI_AST_NODE_F_DEFAULT, kAcpiAstArgType_AstNode),
2467 /* kAcpiAstNodeOp_DerefOf */ RTACPI_ASL_KEYWORD_DEFINE_1REQ_0OPT("DerefOf", RTACPI_AST_NODE_F_DEFAULT, kAcpiAstArgType_AstNode),
2468 /* kAcpiAstNodeOp_Index */ RTACPI_ASL_KEYWORD_DEFINE_2REQ_1OPT("Index", RTACPI_AST_NODE_F_DEFAULT, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode),
2469 /* kAcpiAstNodeOp_Store */ RTACPI_ASL_KEYWORD_DEFINE_2REQ_0OPT("Store", RTACPI_AST_NODE_F_DEFAULT, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode),
2470 /* kAcpiAstNodeOp_Break */ RTACPI_ASL_KEYWORD_DEFINE_0REQ_0OPT("Break", RTACPI_AST_NODE_F_DEFAULT),
2471 /* kAcpiAstNodeOp_Continue */ RTACPI_ASL_KEYWORD_DEFINE_0REQ_0OPT("Continue", RTACPI_AST_NODE_F_DEFAULT),
2472 /* kAcpiAstNodeOp_Add */ RTACPI_ASL_KEYWORD_DEFINE_2REQ_1OPT("Add", RTACPI_AST_NODE_F_DEFAULT, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode),
2473 /* kAcpiAstNodeOp_Subtract */ RTACPI_ASL_KEYWORD_DEFINE_2REQ_1OPT("Subtract", RTACPI_AST_NODE_F_DEFAULT, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode),
2474 /* kAcpiAstNodeOp_Multiply */ RTACPI_ASL_KEYWORD_DEFINE_2REQ_1OPT("Multiply", RTACPI_AST_NODE_F_DEFAULT, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode),
2475 /* kAcpiAstNodeOp_And */ RTACPI_ASL_KEYWORD_DEFINE_2REQ_1OPT("And", RTACPI_AST_NODE_F_DEFAULT, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode),
2476 /* kAcpiAstNodeOp_Nand */ RTACPI_ASL_KEYWORD_DEFINE_2REQ_1OPT("Nand", RTACPI_AST_NODE_F_DEFAULT, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode),
2477 /* kAcpiAstNodeOp_Or */ RTACPI_ASL_KEYWORD_DEFINE_2REQ_1OPT("Or", RTACPI_AST_NODE_F_DEFAULT, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode),
2478 /* kAcpiAstNodeOp_Xor */ RTACPI_ASL_KEYWORD_DEFINE_2REQ_1OPT("Xor", RTACPI_AST_NODE_F_DEFAULT, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode),
2479 /* kAcpiAstNodeOp_ShiftLeft */ RTACPI_ASL_KEYWORD_DEFINE_2REQ_1OPT("ShiftLeft", RTACPI_AST_NODE_F_DEFAULT, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode),
2480 /* kAcpiAstNodeOp_ShiftRight */ RTACPI_ASL_KEYWORD_DEFINE_2REQ_1OPT("ShiftRight", RTACPI_AST_NODE_F_DEFAULT, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode),
2481 /* kAcpiAstNodeOp_Not */ RTACPI_ASL_KEYWORD_DEFINE_1REQ_1OPT("Not", RTACPI_AST_NODE_F_DEFAULT, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode),
2482 /* kAcpiAstNodeOp_Notify */ RTACPI_ASL_KEYWORD_DEFINE_2REQ_0OPT("Notify", RTACPI_AST_NODE_F_DEFAULT, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode),
2483 /* kAcpiAstNodeOp_SizeOf */ RTACPI_ASL_KEYWORD_DEFINE_1REQ_0OPT("SizeOf", RTACPI_AST_NODE_F_DEFAULT, kAcpiAstArgType_AstNode),
2484 /* kAcpiAstNodeOp_While */ RTACPI_ASL_KEYWORD_DEFINE_1REQ_0OPT("While", RTACPI_AST_NODE_F_NEW_SCOPE, kAcpiAstArgType_AstNode),
2485 /* kAcpiAstNodeOp_Increment */ RTACPI_ASL_KEYWORD_DEFINE_1REQ_0OPT("Increment", RTACPI_AST_NODE_F_DEFAULT, kAcpiAstArgType_AstNode),
2486 /* kAcpiAstNodeOp_Decrement */ RTACPI_ASL_KEYWORD_DEFINE_1REQ_0OPT("Decrement", RTACPI_AST_NODE_F_DEFAULT, kAcpiAstArgType_AstNode),
2487 /* kAcpiAstNodeOp_CondRefOf */ RTACPI_ASL_KEYWORD_DEFINE_1REQ_1OPT("CondRefOf", RTACPI_AST_NODE_F_DEFAULT, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode),
2488 /* kAcpiAstNodeOp_IndexField */ RTACPI_ASL_KEYWORD_DEFINE_HANDLER( "IndexField", rtAcpiTblAslParseFieldOrIndexField, 5, 0, RTACPI_AST_NODE_F_DEFAULT),
2489 /* kAcpiAstNodeOp_EisaId */ RTACPI_ASL_KEYWORD_DEFINE_1REQ_0OPT("EisaId", RTACPI_AST_NODE_F_DEFAULT, kAcpiAstArgType_StringLiteral),
2490 /* kAcpiAstNodeOp_CreateField */ RTACPI_ASL_KEYWORD_DEFINE_4REQ_0OPT("CreateField", RTACPI_AST_NODE_F_DEFAULT, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode, kAcpiAstArgType_NameString),
2491 /* kAcpiAstNodeOp_CreateBitField */ RTACPI_ASL_KEYWORD_DEFINE_3REQ_0OPT("CreateBitField", RTACPI_AST_NODE_F_DEFAULT, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode, kAcpiAstArgType_NameString),
2492 /* kAcpiAstNodeOp_CreateByteField */ RTACPI_ASL_KEYWORD_DEFINE_3REQ_0OPT("CreateByteField", RTACPI_AST_NODE_F_DEFAULT, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode, kAcpiAstArgType_NameString),
2493 /* kAcpiAstNodeOp_CreateWordField */ RTACPI_ASL_KEYWORD_DEFINE_3REQ_0OPT("CreateWordField", RTACPI_AST_NODE_F_DEFAULT, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode, kAcpiAstArgType_NameString),
2494 /* kAcpiAstNodeOp_CreateDWordField */ RTACPI_ASL_KEYWORD_DEFINE_3REQ_0OPT("CreateDWordField", RTACPI_AST_NODE_F_DEFAULT, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode, kAcpiAstArgType_NameString),
2495 /* kAcpiAstNodeOp_CreateQWordField */ RTACPI_ASL_KEYWORD_DEFINE_3REQ_0OPT("CreateQWordField", RTACPI_AST_NODE_F_DEFAULT, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode, kAcpiAstArgType_NameString),
2496 /* kAcpiAstNodeOp_ConcatenateResTemplate */ RTACPI_ASL_KEYWORD_DEFINE_3REQ_0OPT("ConcatenateResTemplate", RTACPI_AST_NODE_F_DEFAULT, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode),
2497 /* kAcpiAstNodeOp_FindSetLeftBit */ RTACPI_ASL_KEYWORD_DEFINE_1REQ_1OPT("FindSetLeftBit", RTACPI_AST_NODE_F_DEFAULT, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode),
2498 /* kAcpiAstNodeOp_FindSetRightBit */ RTACPI_ASL_KEYWORD_DEFINE_1REQ_1OPT("FindSetRightBit", RTACPI_AST_NODE_F_DEFAULT, kAcpiAstArgType_AstNode, kAcpiAstArgType_AstNode),
2499};
2500
2501
2502static int rtAcpiTblAslParseArgument(PRTACPIASLCU pThis, const char *pszKeyword, uint8_t iArg, RTACPIASTARGTYPE enmArgType, PRTACPIASTARG pArg)
2503{
2504 switch (enmArgType)
2505 {
2506 case kAcpiAstArgType_AstNode:
2507 {
2508 PRTACPIASTNODE pAstNd = NULL;
2509 int rc = rtAcpiTblAslParseTermArg(pThis, &pAstNd);
2510 if (RT_FAILURE(rc))
2511 return rc;
2512 pArg->enmType = kAcpiAstArgType_AstNode;
2513 pArg->u.pAstNd = pAstNd;
2514 break;
2515 }
2516 case kAcpiAstArgType_NameString:
2517 {
2518 RTACPIASL_PARSE_NAME_STRING(pszNameString);
2519 pArg->enmType = kAcpiAstArgType_NameString;
2520 pArg->u.pszNameString = pszNameString;
2521 break;
2522 }
2523 case kAcpiAstArgType_U8:
2524 {
2525 RTACPIASL_PARSE_NATURAL(u64);
2526 if (u64 > UINT8_MAX)
2527 return RTErrInfoSetF(pThis->pErrInfo, VERR_INVALID_PARAMETER,
2528 "Value for byte parameter %u is out of range (%#RX64) while processing keyword '%s'",
2529 iArg, u64, pszKeyword);
2530
2531 pArg->enmType = kAcpiAstArgType_U8;
2532 pArg->u.u8 = (uint8_t)u64;
2533 break;
2534 }
2535 case kAcpiAstArgType_U16:
2536 {
2537 RTACPIASL_PARSE_NATURAL(u64);
2538 if (u64 > UINT16_MAX)
2539 return RTErrInfoSetF(pThis->pErrInfo, VERR_INVALID_PARAMETER,
2540 "Value for word parameter %u is out of range (%#RX64) while processing keyword '%s'",
2541 iArg, u64, pszKeyword);
2542
2543 pArg->enmType = kAcpiAstArgType_U16;
2544 pArg->u.u16 = (uint16_t)u64;
2545 break;
2546 }
2547 case kAcpiAstArgType_U32:
2548 {
2549 RTACPIASL_PARSE_NATURAL(u64);
2550 if (u64 > UINT32_MAX)
2551 return RTErrInfoSetF(pThis->pErrInfo, VERR_INVALID_PARAMETER,
2552 "Value for 32-bit parameter %u is out of range (%#RX64) while processing keyword '%s'",
2553 iArg, u64, pszKeyword);
2554
2555 pArg->enmType = kAcpiAstArgType_U32;
2556 pArg->u.u32 = (uint32_t)u64;
2557 break;
2558 }
2559 case kAcpiAstArgType_U64:
2560 {
2561 RTACPIASL_PARSE_NATURAL(u64);
2562 pArg->enmType = kAcpiAstArgType_U64;
2563 pArg->u.u64 = u64;
2564 break;
2565 }
2566 case kAcpiAstArgType_RegionSpace:
2567 {
2568 RTACPIASLTERMINAL enmKeyword;
2569 int rc = rtAcpiAslLexerConsumeIfKeywordInList(pThis, &g_aenmRegionSpaceKeywords[0], &enmKeyword);
2570 if (RT_FAILURE(rc))
2571 return rc;
2572
2573 if (enmKeyword != RTACPIASLTERMINAL_INVALID)
2574 {
2575 pArg->enmType = kAcpiAstArgType_RegionSpace;
2576 switch (enmKeyword)
2577 {
2578 case RTACPIASLTERMINAL_KEYWORD_SYSTEM_IO: pArg->u.enmRegionSpace = kAcpiOperationRegionSpace_SystemIo; break;
2579 case RTACPIASLTERMINAL_KEYWORD_SYSTEM_MEMORY: pArg->u.enmRegionSpace = kAcpiOperationRegionSpace_SystemMemory; break;
2580 case RTACPIASLTERMINAL_KEYWORD_PCI_CONFIG: pArg->u.enmRegionSpace = kAcpiOperationRegionSpace_PciConfig; break;
2581 case RTACPIASLTERMINAL_KEYWORD_EMBEDDED_CONTROL: pArg->u.enmRegionSpace = kAcpiOperationRegionSpace_EmbeddedControl; break;
2582 case RTACPIASLTERMINAL_KEYWORD_SMBUS: pArg->u.enmRegionSpace = kAcpiOperationRegionSpace_SmBus; break;
2583 case RTACPIASLTERMINAL_KEYWORD_SYSTEM_CMOS: pArg->u.enmRegionSpace = kAcpiOperationRegionSpace_SystemCmos; break;
2584 case RTACPIASLTERMINAL_KEYWORD_PCI_BAR_TARGET: pArg->u.enmRegionSpace = kAcpiOperationRegionSpace_PciBarTarget; break;
2585 case RTACPIASLTERMINAL_KEYWORD_IPMI: pArg->u.enmRegionSpace = kAcpiOperationRegionSpace_Ipmi; break;
2586 case RTACPIASLTERMINAL_KEYWORD_GENERAL_PURPOSE_IO: pArg->u.enmRegionSpace = kAcpiOperationRegionSpace_Gpio; break;
2587 case RTACPIASLTERMINAL_KEYWORD_GENERIC_SERIAL_BUS: pArg->u.enmRegionSpace = kAcpiOperationRegionSpace_GenericSerialBus; break;
2588 case RTACPIASLTERMINAL_KEYWORD_PCC: pArg->u.enmRegionSpace = kAcpiOperationRegionSpace_Pcc; break;
2589 case RTACPIASLTERMINAL_KEYWORD_PRM:
2590 case RTACPIASLTERMINAL_KEYWORD_FFIXED_HW:
2591 default:
2592 AssertFailedReturn(VERR_INTERNAL_ERROR);
2593 }
2594 }
2595 else
2596 return RTErrInfoSetF(pThis->pErrInfo, VERR_INVALID_PARAMETER, "Unknown RegionSpace keyword encountered");
2597 break;
2598 }
2599 case kAcpiAstArgType_StringLiteral:
2600 {
2601 RTACPIASL_PARSE_STRING_LIT(psz);
2602 pArg->enmType = kAcpiAstArgType_StringLiteral;
2603 pArg->u.pszStrLit = psz;
2604 break;
2605 }
2606 default:
2607 AssertReleaseFailed();
2608 }
2609
2610 return VINF_SUCCESS;
2611}
2612
2613
2614static int rtAcpiTblAslParseOp(PRTACPIASLCU pThis, RTACPIASTNODEOP enmOp, PRTACPIASTNODE *ppAstNd)
2615{
2616 int rc = VINF_SUCCESS;
2617
2618 AssertReturn(enmOp > kAcpiAstNodeOp_Invalid && (unsigned)enmOp < RT_ELEMENTS(g_aAslOps), VERR_INTERNAL_ERROR);
2619
2620 *ppAstNd = NULL;
2621
2622 PCRTACPIASLKEYWORD pAslKeyword = &g_aAslOps[enmOp];
2623 PRTACPIASTNODE pAstNd = rtAcpiAstNodeAlloc(pThis->pNs, enmOp, pAslKeyword->fFlags, pAslKeyword->cArgsReq + pAslKeyword->cArgsOpt);
2624 if (!pAstNd)
2625 return RTErrInfoSetF(pThis->pErrInfo, VERR_NO_MEMORY, "Failed to allocate ACPI AST node when processing keyword '%s'", pAslKeyword->pszOpc);
2626
2627 *ppAstNd = pAstNd;
2628
2629 /* Call and parse callback if present, otherwise do the default parsing. */
2630 if (pAslKeyword->pfnParse)
2631 {
2632 rc = pAslKeyword->pfnParse(pThis, pAslKeyword, pAstNd);
2633 if (RT_FAILURE(rc))
2634 return rc;
2635 }
2636 else if (pAslKeyword->cArgsReq || pAslKeyword->cArgsOpt)
2637 {
2638 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_OPEN_BRACKET, '(');
2639
2640 /* Process any required arguments. */
2641 for (uint8_t i = 0; i < pAslKeyword->cArgsReq; i++)
2642 {
2643 rc = rtAcpiTblAslParseArgument(pThis, pAslKeyword->pszOpc, i, pAslKeyword->aenmTypes[i], &pAstNd->aArgs[i]);
2644 if (RT_FAILURE(rc))
2645 return rc;
2646
2647 /* There must be a "," between required arguments, not counting the last required argument because it can be closed with ")". */
2648 if (i < (uint8_t)(pAslKeyword->cArgsReq - 1))
2649 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
2650 }
2651
2652 /* Process any optional arguments, this is a bit ugly. */
2653 uint8_t iArg = 0;
2654 while (iArg < pAslKeyword->cArgsOpt)
2655 {
2656 if (rtAcpiAslLexerIsPunctuator(pThis, RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_BRACKET))
2657 break; /* The end of the argument list was reached. */
2658
2659 /*
2660 * It is possible to have empty arguments in the list by having nothing to parse between the "," or something like ",)"
2661 * (like "Method(NAM, 0,,)" for example).
2662 */
2663 if (rtAcpiAslLexerIsPunctuator(pThis, RTACPIASLTERMINAL_PUNCTUATOR_COMMA))
2664 {
2665 RTACPIASL_SKIP_CURRENT_TOKEN(); /* Skip "," */
2666
2667 /*
2668 * If the next token is also a "," there is a hole in the argument list and we have to fill in the default,
2669 * if it is ")" we reached the end.
2670 */
2671 if (rtAcpiAslLexerIsPunctuator(pThis, RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_BRACKET))
2672 break;
2673 else if (rtAcpiAslLexerIsPunctuator(pThis, RTACPIASLTERMINAL_PUNCTUATOR_COMMA))
2674 {
2675 pAstNd->aArgs[pAslKeyword->cArgsReq + iArg] = pAslKeyword->aArgsOpt[iArg];
2676 iArg++;
2677 continue; /* Continue with the next argument. */
2678 }
2679
2680 /* So there is an argument we need to parse. */
2681 rc = rtAcpiTblAslParseArgument(pThis, pAslKeyword->pszOpc, iArg, pAslKeyword->aArgsOpt[iArg].enmType, &pAstNd->aArgs[pAslKeyword->cArgsReq + iArg]);
2682 if (RT_FAILURE(rc))
2683 return rc;
2684
2685 iArg++;
2686 }
2687 }
2688
2689 /* Fill remaining optional arguments with the defaults. */
2690 for (; iArg < pAslKeyword->cArgsOpt; iArg++)
2691 pAstNd->aArgs[pAslKeyword->cArgsReq + iArg] = pAslKeyword->aArgsOpt[iArg];
2692
2693 /* Now there must be a closing ) */
2694 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_BRACKET, ')');
2695
2696 if (pAslKeyword->fFlags & RTACPI_AST_NODE_F_NS_ENTRY)
2697 {
2698 /*
2699 * Create a new namespace entry, we currently assume that the first argument is a namestring
2700 * which gives the path.
2701 */
2702 AssertReturn(pAstNd->aArgs[0].enmType == kAcpiAstArgType_NameString, VERR_NOT_SUPPORTED);
2703
2704 rc = rtAcpiNsAddEntryAstNode(pThis->pNs, pAstNd->aArgs[0].u.pszNameString, pAstNd, RT_BOOL(pAslKeyword->fFlags & RTACPI_AST_NODE_F_NEW_SCOPE) /*fSwitchTo*/);
2705 if (RT_FAILURE(rc))
2706 return rc;
2707 }
2708 else if (pAslKeyword->fFlags & RTACPI_AST_NODE_F_NS_SWITCH)
2709 {
2710 AssertReturn(pAstNd->aArgs[0].enmType == kAcpiAstArgType_NameString, VERR_NOT_SUPPORTED);
2711 Assert(pAslKeyword->fFlags & RTACPI_AST_NODE_F_NEW_SCOPE);
2712
2713 rc = rtAcpiNsSwitchTo(pThis->pNs, pAstNd->aArgs[0].u.pszNameString);
2714 if (RT_FAILURE(rc))
2715 return rc;
2716 }
2717
2718 }
2719
2720 /* For keywords opening a new scope do the parsing now. */
2721 if (pAslKeyword->fFlags & RTACPI_AST_NODE_F_NEW_SCOPE)
2722 {
2723 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_OPEN_CURLY_BRACKET, '{');
2724 rc = rtAcpiTblAslParseInner(pThis, &pAstNd->LstScopeNodes);
2725 if (RT_SUCCESS(rc))
2726 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_CURLY_BRACKET, '}');
2727
2728 if (pAslKeyword->fFlags & (RTACPI_AST_NODE_F_NS_ENTRY | RTACPI_AST_NODE_F_NS_SWITCH))
2729 rtAcpiNsPop(pThis->pNs);
2730 }
2731
2732 return rc;
2733}
2734
2735
2736/**
2737 * Parses what looks like an name string, possibly with a call.
2738 *
2739 * @returns IPRT status code.
2740 * @param pThis The ACPI compilation unit state.
2741 * @param pszIde The identifier.
2742 * @param ppAstNd Where to store the AST node on success.
2743 */
2744static int rtAcpiTblAslParseIde(PRTACPIASLCU pThis, const char *pszIde, PRTACPIASTNODE *ppAstNd)
2745{
2746 *ppAstNd = NULL;
2747
2748 /* If there is a ( following this looks like a function call which can have up to 8 arguments. */
2749 uint8_t cArgs = 0;
2750 RTACPIASTARG aArgs[8]; RT_ZERO(aArgs);
2751 if (rtAcpiAslLexerIsPunctuator(pThis, RTACPIASLTERMINAL_PUNCTUATOR_OPEN_BRACKET))
2752 {
2753 RTACPIASL_SKIP_CURRENT_TOKEN(); /* Skip "(" */
2754
2755 if (!rtAcpiAslLexerIsPunctuator(pThis, RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_BRACKET))
2756 {
2757 while (cArgs < RT_ELEMENTS(aArgs))
2758 {
2759 PRTACPIASTNODE pAstNd = NULL;
2760 int rc = rtAcpiTblAslParseTermArg(pThis, &pAstNd);
2761 if (RT_FAILURE(rc))
2762 return rc;
2763
2764 aArgs[cArgs].enmType = kAcpiAstArgType_AstNode;
2765 aArgs[cArgs].u.pAstNd = pAstNd;
2766 cArgs++;
2767
2768 /* ")" means we are done here. */
2769 if (rtAcpiAslLexerIsPunctuator(pThis, RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_BRACKET))
2770 break;
2771
2772 /* Arguments are separated by "," */
2773 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
2774 }
2775 }
2776
2777 /* Now there must be a closing ) */
2778 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_BRACKET, ')');
2779 }
2780
2781 PRTACPIASTNODE pAstNd = rtAcpiAstNodeAlloc(pThis->pNs, kAcpiAstNodeOp_Identifier, RTACPI_AST_NODE_F_DEFAULT, cArgs);
2782 if (!pAstNd)
2783 return RTErrInfoSetF(pThis->pErrInfo, VERR_NO_MEMORY, "Failed to allocate ACPI AST node when processing identifier '%s'", pszIde);
2784
2785 pAstNd->pszIde = pszIde;
2786
2787 /* Fill in the arguments. */
2788 for (uint8_t i = 0; i < cArgs; i++)
2789 pAstNd->aArgs[i] = aArgs[i];
2790
2791 *ppAstNd = pAstNd;
2792 return VINF_SUCCESS;
2793}
2794
2795
2796static int rtAcpiTblAslParseTermArg(PRTACPIASLCU pThis, PRTACPIASTNODE *ppAstNd)
2797{
2798 int rc;
2799 PCRTSCRIPTLEXTOKEN pTok;
2800
2801 /* External declarations are treated differently so consume all here. */
2802 for (;;)
2803 {
2804 rc = RTScriptLexQueryToken(pThis->hLexSource, &pTok);
2805 if (RT_FAILURE(rc))
2806 return RTErrInfoSetF(pThis->pErrInfo, rc, "Parser: Failed to query next token with %Rrc", rc);
2807
2808 if ( pTok->enmType == RTSCRIPTLEXTOKTYPE_KEYWORD
2809 && pTok->Type.Keyword.pKeyword->u64Val == kAcpiAstNodeOp_External)
2810 {
2811 RTScriptLexConsumeToken(pThis->hLexSource);
2812 rc = rtAcpiTblAslParseExternal(pThis);
2813 if (RT_FAILURE(rc))
2814 return rc;
2815 }
2816 else
2817 break;
2818 }
2819
2820 if (pTok->enmType == RTSCRIPTLEXTOKTYPE_ERROR)
2821 return RTErrInfoSet(pThis->pErrInfo, VERR_INVALID_PARAMETER, pTok->Type.Error.pErr->pszMsg);
2822 if (pTok->enmType == RTSCRIPTLEXTOKTYPE_EOS)
2823 return RTErrInfoSetF(pThis->pErrInfo, VERR_INVALID_PARAMETER, "Parser: Unexpected end of stream");
2824
2825 PRTACPIASTNODE pAstNd = NULL;
2826 if (pTok->enmType == RTSCRIPTLEXTOKTYPE_KEYWORD)
2827 {
2828 uint64_t idKeyword = pTok->Type.Keyword.pKeyword->u64Val;
2829 if (idKeyword < RT_ELEMENTS(g_aAslOps))
2830 {
2831 RTScriptLexConsumeToken(pThis->hLexSource); /* This must come here as rtAcpiTblAslParseOp() will continue parsing. */
2832 rc = rtAcpiTblAslParseOp(pThis, (RTACPIASTNODEOP)idKeyword, &pAstNd);
2833 }
2834 else
2835 return RTErrInfoSetF(pThis->pErrInfo, VERR_INVALID_PARAMETER, "Parser: Unexpected keyword '%s' encountered", pTok->Type.Keyword.pKeyword->pszMatch);
2836 }
2837 else if (pTok->enmType == RTSCRIPTLEXTOKTYPE_IDENTIFIER)
2838 {
2839 /* We can safely consume the token here after getting the pointer to the identifier string as the string is cached and doesn't go away. */
2840 const char *pszIde = pTok->Type.Id.pszIde;
2841 RTScriptLexConsumeToken(pThis->hLexSource);
2842 rc = rtAcpiTblAslParseIde(pThis, pszIde, &pAstNd);
2843 }
2844 else if (pTok->enmType == RTSCRIPTLEXTOKTYPE_STRINGLIT)
2845 {
2846 pAstNd = rtAcpiAstNodeAlloc(pThis->pNs, kAcpiAstNodeOp_StringLiteral, RTACPI_AST_NODE_F_DEFAULT, 0);
2847 if (!pAstNd)
2848 return RTErrInfoSetF(pThis->pErrInfo, VERR_NO_MEMORY, "Failed to allocate ACPI AST node when processing identifier '%s'",
2849 pTok->Type.StringLit.pszString);
2850
2851 pAstNd->pszStrLit = pTok->Type.StringLit.pszString;
2852 RTScriptLexConsumeToken(pThis->hLexSource);
2853 }
2854 else if (pTok->enmType == RTSCRIPTLEXTOKTYPE_NUMBER)
2855 {
2856 Assert(pTok->Type.Number.enmType == RTSCRIPTLEXTOKNUMTYPE_NATURAL);
2857 pAstNd = rtAcpiAstNodeAlloc(pThis->pNs, kAcpiAstNodeOp_Number, RTACPI_AST_NODE_F_DEFAULT, 0);
2858 if (!pAstNd)
2859 return RTErrInfoSetF(pThis->pErrInfo, VERR_NO_MEMORY, "Failed to allocate ACPI AST node when processing number '%#RX64'",
2860 pTok->Type.Number.Type.u64);
2861
2862 pAstNd->u64 = pTok->Type.Number.Type.u64;
2863 RTScriptLexConsumeToken(pThis->hLexSource);
2864 }
2865 else
2866 {
2867 AssertFailed();
2868 return RTErrInfoSetF(pThis->pErrInfo, VERR_INVALID_PARAMETER, "Parser: Unexpected token encountered");
2869 }
2870
2871 if (RT_FAILURE(rc))
2872 {
2873 if (pAstNd)
2874 rtAcpiAstNodeFree(pAstNd);
2875 return rc;
2876 }
2877
2878 AssertPtr(pAstNd);
2879 *ppAstNd = pAstNd;
2880 return VINF_SUCCESS;
2881}
2882
2883
2884static int rtAcpiTblAslParseInner(PRTACPIASLCU pThis, PRTLISTANCHOR pLstStmts)
2885{
2886 for (;;)
2887 {
2888 /* Need to break out of the loop if done processing this scope (consumption is done by the caller). */
2889 if (rtAcpiAslLexerIsPunctuator(pThis, RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_CURLY_BRACKET))
2890 return VINF_SUCCESS;
2891
2892 PRTACPIASTNODE pAstNd = NULL;
2893 int rc = rtAcpiTblAslParseTermArg(pThis, &pAstNd);
2894 if (RT_FAILURE(rc))
2895 return rc;
2896
2897 Assert(pAstNd);
2898 RTListAppend(pLstStmts, &pAstNd->NdAst);
2899 }
2900}
2901
2902
2903static int rtAcpiTblAslParserParse(PRTACPIASLCU pThis)
2904{
2905 /*
2906 * The first keyword must be DefinitionBlock:
2907 *
2908 * DefinitionBlock ("SSDT.aml", "SSDT", 1, "VBOX ", "VBOXCPUT", 2)
2909 */
2910 RTACPIASL_PARSE_KEYWORD(RTACPIASLTERMINAL_KEYWORD_DEFINITION_BLOCK, "DefinitionBlock");
2911 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_OPEN_BRACKET, '(');
2912 RTACPIASL_PARSE_STRING_LIT(pszOutFile);
2913 RT_NOREF(pszOutFile); /* We ignore the output file hint. */
2914 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
2915 RTACPIASL_PARSE_STRING_LIT(pszTblSig);
2916 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
2917 RTACPIASL_PARSE_NATURAL(u64ComplianceRev);
2918 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
2919 RTACPIASL_PARSE_STRING_LIT(pszOemId);
2920 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
2921 RTACPIASL_PARSE_STRING_LIT(pszOemTblId);
2922 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_COMMA, ',');
2923 RTACPIASL_PARSE_NATURAL(u64OemRev);
2924 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_BRACKET, ')');
2925
2926 /* Some additional checks. */
2927 uint32_t u32TblSig = ACPI_TABLE_HDR_SIGNATURE_MISC;
2928 if (!strcmp(pszTblSig, "DSDT"))
2929 u32TblSig = ACPI_TABLE_HDR_SIGNATURE_DSDT;
2930 else if (!strcmp(pszTblSig, "SSDT"))
2931 u32TblSig = ACPI_TABLE_HDR_SIGNATURE_SSDT;
2932
2933 if (u32TblSig == ACPI_TABLE_HDR_SIGNATURE_MISC)
2934 return RTErrInfoSetF(pThis->pErrInfo, VERR_INVALID_PARAMETER, "Table signature must be either 'DSDT' or 'SSDT': %s", pszTblSig);
2935
2936 if (u64ComplianceRev > UINT8_MAX)
2937 return RTErrInfoSetF(pThis->pErrInfo, VERR_INVALID_PARAMETER, "Compliance revision %RU64 is out of range, must be in range [0..255]", u64ComplianceRev);
2938
2939 if (strlen(pszOemId) > 6)
2940 return RTErrInfoSetF(pThis->pErrInfo, VERR_INVALID_PARAMETER, "OEM ID string must be at most 6 characters long");
2941
2942 if (strlen(pszOemTblId) > 8)
2943 return RTErrInfoSetF(pThis->pErrInfo, VERR_INVALID_PARAMETER, "OEM table ID string must be at most 8 characters long");
2944
2945 if (u64OemRev > UINT32_MAX)
2946 return RTErrInfoSetF(pThis->pErrInfo, VERR_INVALID_PARAMETER, "OEM revision ID %RU64 is out of range, must fit into 32-bit unsigned integer", u64OemRev);
2947
2948 int rc = RTAcpiTblCreate(&pThis->hAcpiTbl, u32TblSig, (uint8_t)u64ComplianceRev, pszOemId,
2949 pszOemTblId, (uint32_t)u64OemRev, "VBOX", RTBldCfgRevision());
2950 if (RT_SUCCESS(rc))
2951 {
2952 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_OPEN_CURLY_BRACKET, '{');
2953 rc = rtAcpiTblAslParseInner(pThis, &pThis->LstStmts);
2954 if (RT_SUCCESS(rc))
2955 {
2956 RTACPIASL_PARSE_PUNCTUATOR(RTACPIASLTERMINAL_PUNCTUATOR_CLOSE_CURLY_BRACKET, '}');
2957 rc = rtAcpiAslParserConsumeEos(pThis); /* No junk after the final closing bracket. */
2958 }
2959 }
2960 else
2961 rc = RTErrInfoSetF(pThis->pErrInfo, rc, "Call to RTAcpiTblCreate() failed");
2962
2963 return rc;
2964}
2965
2966
2967DECLHIDDEN(int) rtAcpiTblConvertFromAslToAml(RTVFSIOSTREAM hVfsIosOut, RTVFSIOSTREAM hVfsIosIn, PRTERRINFO pErrInfo)
2968{
2969 int rc;
2970 PRTACPIASLCU pThis = (PRTACPIASLCU)RTMemAllocZ(sizeof(*pThis));
2971 if (pThis)
2972 {
2973 pThis->hVfsIosIn = hVfsIosIn;
2974 pThis->pErrInfo = pErrInfo;
2975 RTListInit(&pThis->LstExternals);
2976 RTListInit(&pThis->LstStmts);
2977
2978 pThis->pNs = rtAcpiNsCreate();
2979 if (pThis->pNs)
2980 {
2981 rc = RTScriptLexCreateFromReader(&pThis->hLexSource, rtAcpiAslLexerRead,
2982 NULL /*pfnDtor*/, pThis /*pvUser*/, 0 /*cchBuf*/,
2983 NULL /*phStrCacheId*/, NULL /*phStrCacheStringLit*/,
2984 NULL /*phStrCacheComments*/, &s_AslLexCfg);
2985 if (RT_SUCCESS(rc))
2986 {
2987 rc = rtAcpiTblAslParserParse(pThis);
2988 if (RT_SUCCESS(rc))
2989 {
2990 /* 2. - Optimize AST (constant folding, etc). */
2991 PRTACPIASTNODE pIt;
2992 RTListForEach(&pThis->LstStmts, pIt, RTACPIASTNODE, NdAst)
2993 {
2994 rc = rtAcpiAstNodeTransform(pIt, pThis->pNs, pErrInfo);
2995 if (RT_FAILURE(rc))
2996 break;
2997 }
2998
2999 /* 3. - Traverse AST and output table. */
3000
3001 /* First external declarations - those are enclosed in an If (0) { } block. */
3002 if (!RTListIsEmpty(&pThis->LstExternals))
3003 {
3004 RTAcpiTblIfStart(pThis->hAcpiTbl);
3005 RTAcpiTblIntegerAppend(pThis->hAcpiTbl, 0);
3006
3007 PRTACPIASLEXTERNAL pExternal;
3008 RTListForEach(&pThis->LstExternals, pExternal, RTACPIASLEXTERNAL, NdExternal)
3009 {
3010 rc = RTAcpiTblExternalAppend(pThis->hAcpiTbl, pExternal->szNamePath, pExternal->enmObjType,
3011 pExternal->cArgs == UINT32_MAX ? 0 : pExternal->cArgs);
3012 if (RT_FAILURE(rc))
3013 break;
3014 }
3015
3016 RTAcpiTblIfFinalize(pThis->hAcpiTbl);
3017 }
3018
3019 if (RT_SUCCESS(rc))
3020 {
3021 RTListForEach(&pThis->LstStmts, pIt, RTACPIASTNODE, NdAst)
3022 {
3023 rc = rtAcpiAstDumpToTbl(pIt, pThis->pNs, pThis->hAcpiTbl);
3024 if (RT_FAILURE(rc))
3025 break;
3026 }
3027 }
3028
3029 /* Finalize and write to the VFS I/O stream. */
3030 if (RT_SUCCESS(rc))
3031 {
3032 rc = RTAcpiTblFinalize(pThis->hAcpiTbl);
3033 if (RT_SUCCESS(rc))
3034 {
3035 rc = RTAcpiTblDumpToVfsIoStrm(pThis->hAcpiTbl, RTACPITBLTYPE_AML, hVfsIosOut);
3036 if (RT_FAILURE(rc))
3037 rc = RTErrInfoSetF(pErrInfo, rc, "Writing the ACPI table failed with %Rrc", rc);
3038 }
3039 else
3040 rc = RTErrInfoSetF(pErrInfo, rc, "Finalizing the ACPI table failed with %Rrc", rc);
3041 }
3042 else
3043 rc = RTErrInfoSetF(pErrInfo, rc, "Dumping AST to ACPI table failed with %Rrc", rc);
3044 }
3045
3046 RTScriptLexDestroy(pThis->hLexSource);
3047 }
3048 else
3049 rc = RTErrInfoSetF(pErrInfo, rc, "Creating the ASL lexer failed with %Rrc", rc);
3050
3051 /* Destroy the AST nodes. */
3052 PRTACPIASTNODE pIt, pItNext;
3053 RTListForEachSafe(&pThis->LstStmts, pIt, pItNext, RTACPIASTNODE, NdAst)
3054 {
3055 RTListNodeRemove(&pIt->NdAst);
3056 rtAcpiAstNodeFree(pIt);
3057 }
3058
3059 rtAcpiNsDestroy(pThis->pNs);
3060 }
3061 else
3062 rc = RTErrInfoSetF(pErrInfo, VERR_NO_MEMORY, "Out of memory allocating the ACPI namespace state");
3063
3064 RTMemFree(pThis);
3065 }
3066 else
3067 rc = RTErrInfoSetF(pErrInfo, VERR_NO_MEMORY, "Out of memory allocating the ASL compilation unit state");
3068
3069 return rc;
3070}
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