VirtualBox

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

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

Runtime/RTAcpi*: Parser updates, the code is now able to parse vbox.dsl successfully and generate an AST, bugref:10733

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