TianoCore EDK2 master
Loading...
Searching...
No Matches
AmlOption.c
Go to the documentation of this file.
1
9#include "AcpiTable.h"
10
28 IN AML_BYTE_ENCODING *AmlByteEncoding,
29 IN UINT8 *Buffer,
30 IN UINTN MaxBufferSize,
31 IN AML_OP_PARSE_INDEX TermIndex,
32 OUT EFI_ACPI_DATA_TYPE *DataType,
33 OUT VOID **Data,
34 OUT UINTN *DataSize
35 )
36{
37 AML_BYTE_ENCODING *ChildAmlByteEncoding;
38 EFI_STATUS Status;
39
40 if (DataType != NULL) {
41 *DataType = AmlTypeToAcpiType (AmlByteEncoding->Format[TermIndex - 1]);
42 }
43
44 if (Data != NULL) {
45 *Data = Buffer;
46 }
47
48 //
49 // Parse term according to AML type
50 //
51 switch (AmlByteEncoding->Format[TermIndex - 1]) {
52 case AML_UINT8:
53 *DataSize = sizeof (UINT8);
54 break;
55 case AML_UINT16:
56 *DataSize = sizeof (UINT16);
57 break;
58 case AML_UINT32:
59 *DataSize = sizeof (UINT32);
60 break;
61 case AML_UINT64:
62 *DataSize = sizeof (UINT64);
63 break;
64 case AML_STRING:
65 *DataSize = AsciiStrSize ((CHAR8 *)Buffer);
66 break;
67 case AML_NAME:
68 Status = AmlGetNameStringSize (Buffer, DataSize);
69 if (EFI_ERROR (Status)) {
70 return EFI_INVALID_PARAMETER;
71 }
72
73 break;
74 case AML_OBJECT:
75 ChildAmlByteEncoding = AmlSearchByOpByte (Buffer);
76 if (ChildAmlByteEncoding == NULL) {
77 return EFI_INVALID_PARAMETER;
78 }
79
80 //
81 // NOTE: We need override DataType here, if there is a case the AML_OBJECT is AML_NAME.
82 // We need convert type from EFI_ACPI_DATA_TYPE_CHILD to EFI_ACPI_DATA_TYPE_NAME_STRING.
83 // We should not return CHILD because there is NO OpCode for NameString.
84 //
85 if ((ChildAmlByteEncoding->Attribute & AML_IS_NAME_CHAR) != 0) {
86 if (DataType != NULL) {
87 *DataType = AmlTypeToAcpiType (AML_NAME);
88 }
89
90 Status = AmlGetNameStringSize (Buffer, DataSize);
91 if (EFI_ERROR (Status)) {
92 return EFI_INVALID_PARAMETER;
93 }
94
95 break;
96 }
97
98 //
99 // It is real AML_OBJECT
100 //
101 *DataSize = AmlGetObjectSize (
102 ChildAmlByteEncoding,
103 Buffer,
104 MaxBufferSize
105 );
106 if (*DataSize == 0) {
107 return EFI_INVALID_PARAMETER;
108 }
109
110 break;
111 case AML_NONE:
112 //
113 // No term
114 //
115 case AML_OPCODE:
116 default:
117 ASSERT (FALSE);
118 return EFI_INVALID_PARAMETER;
119 }
120
121 if (*DataSize > MaxBufferSize) {
122 return EFI_INVALID_PARAMETER;
123 }
124
125 return EFI_SUCCESS;
126}
127
146 IN AML_BYTE_ENCODING *AmlByteEncoding,
147 IN UINT8 *Buffer,
148 IN UINTN MaxBufferSize,
149 IN AML_OP_PARSE_INDEX Index,
150 OUT EFI_ACPI_DATA_TYPE *DataType,
151 OUT VOID **Data,
152 OUT UINTN *DataSize
153 )
154{
155 UINT8 *CurrentBuffer;
156 UINTN PkgLength;
157 UINTN OpLength;
158 UINTN PkgOffset;
159 AML_OP_PARSE_INDEX TermIndex;
160 EFI_STATUS Status;
161
162 ASSERT ((Index <= AmlByteEncoding->MaxIndex) || (Index == AML_OP_PARSE_INDEX_GET_SIZE));
163
164 //
165 // 0. Check if this is NAME string.
166 //
167 if ((AmlByteEncoding->Attribute & AML_IS_NAME_CHAR) != 0) {
168 //
169 // Only allow GET_SIZE
170 //
171 if (Index != AML_OP_PARSE_INDEX_GET_SIZE) {
172 return EFI_INVALID_PARAMETER;
173 }
174
175 //
176 // return NameString size
177 //
178 Status = AmlGetNameStringSize (Buffer, DataSize);
179 if (EFI_ERROR (Status)) {
180 return EFI_INVALID_PARAMETER;
181 }
182
183 if (*DataSize > MaxBufferSize) {
184 return EFI_INVALID_PARAMETER;
185 }
186
187 return EFI_SUCCESS;
188 }
189
190 //
191 // Not NAME string, start parsing
192 //
193 CurrentBuffer = Buffer;
194
195 //
196 // 1. Get OpCode
197 //
198 if (Index != AML_OP_PARSE_INDEX_GET_SIZE) {
199 *DataType = EFI_ACPI_DATA_TYPE_OPCODE;
200 *Data = (VOID *)CurrentBuffer;
201 }
202
203 if (*CurrentBuffer == AML_EXT_OP) {
204 OpLength = 2;
205 } else {
206 OpLength = 1;
207 }
208
209 *DataSize = OpLength;
210 if (Index == AML_OP_PARSE_INDEX_GET_OPCODE) {
211 return EFI_SUCCESS;
212 }
213
214 if (OpLength > MaxBufferSize) {
215 return EFI_INVALID_PARAMETER;
216 }
217
218 CurrentBuffer += OpLength;
219
220 //
221 // 2. Skip PkgLength field, if have
222 //
223 if ((AmlByteEncoding->Attribute & AML_HAS_PKG_LENGTH) != 0) {
224 PkgOffset = AmlGetPkgLength (CurrentBuffer, &PkgLength);
225 //
226 // Override MaxBufferSize if it is valid PkgLength
227 //
228 if (OpLength + PkgLength > MaxBufferSize) {
229 return EFI_INVALID_PARAMETER;
230 } else {
231 MaxBufferSize = OpLength + PkgLength;
232 }
233 } else {
234 PkgOffset = 0;
235 PkgLength = 0;
236 }
237
238 CurrentBuffer += PkgOffset;
239
240 //
241 // 3. Get Term one by one.
242 //
243 TermIndex = AML_OP_PARSE_INDEX_GET_TERM1;
244 while ((Index >= TermIndex) && (TermIndex <= AmlByteEncoding->MaxIndex) && ((UINTN)CurrentBuffer < (UINTN)Buffer + MaxBufferSize)) {
245 Status = AmlParseOptionTerm (
246 AmlByteEncoding,
247 CurrentBuffer,
248 (UINTN)Buffer + MaxBufferSize - (UINTN)CurrentBuffer,
249 TermIndex,
250 DataType,
251 Data,
252 DataSize
253 );
254 if (EFI_ERROR (Status)) {
255 return EFI_INVALID_PARAMETER;
256 }
257
258 if (Index == TermIndex) {
259 //
260 // Done
261 //
262 return EFI_SUCCESS;
263 }
264
265 //
266 // Parse next one
267 //
268 CurrentBuffer += *DataSize;
269 TermIndex++;
270 }
271
272 //
273 // Finish all options, but no option found.
274 //
275 if ((UINTN)CurrentBuffer > (UINTN)Buffer + MaxBufferSize) {
276 return EFI_INVALID_PARAMETER;
277 }
278
279 if ((UINTN)CurrentBuffer == (UINTN)Buffer + MaxBufferSize) {
280 if (Index != AML_OP_PARSE_INDEX_GET_SIZE) {
281 return EFI_INVALID_PARAMETER;
282 }
283 }
284
285 //
286 // 4. Finish parsing all node, return size
287 //
288 ASSERT (Index == AML_OP_PARSE_INDEX_GET_SIZE);
289 if ((AmlByteEncoding->Attribute & AML_HAS_PKG_LENGTH) != 0) {
290 *DataSize = OpLength + PkgLength;
291 } else {
292 *DataSize = (UINTN)CurrentBuffer - (UINTN)Buffer;
293 }
294
295 return EFI_SUCCESS;
296}
297
307UINTN
309 IN AML_BYTE_ENCODING *AmlByteEncoding,
310 IN UINT8 *Buffer,
311 IN UINTN MaxBufferSize
312 )
313{
314 EFI_STATUS Status;
315 UINTN DataSize;
316
317 Status = AmlParseOptionCommon (
318 AmlByteEncoding,
319 Buffer,
320 MaxBufferSize,
321 AML_OP_PARSE_INDEX_GET_SIZE,
322 NULL,
323 NULL,
324 &DataSize
325 );
326 if (EFI_ERROR (Status)) {
327 return 0;
328 } else {
329 return DataSize;
330 }
331}
332
340CHAR8 *
342 IN EFI_AML_HANDLE *AmlHandle
343 )
344{
345 AML_BYTE_ENCODING *AmlByteEncoding;
346 VOID *NameString;
347 UINTN NameSize;
348 AML_OP_PARSE_INDEX TermIndex;
349 EFI_STATUS Status;
350 EFI_ACPI_DATA_TYPE DataType;
351
352 AmlByteEncoding = AmlHandle->AmlByteEncoding;
353
354 ASSERT ((AmlByteEncoding->Attribute & AML_IN_NAMESPACE) != 0);
355
356 //
357 // Find out Last Name index, according to OpCode table.
358 // The last name will be the node name by design.
359 //
360 TermIndex = AmlByteEncoding->MaxIndex;
361 for (TermIndex = AmlByteEncoding->MaxIndex; TermIndex > 0; TermIndex--) {
362 if (AmlByteEncoding->Format[TermIndex - 1] == AML_NAME) {
363 break;
364 }
365 }
366
367 ASSERT (TermIndex != 0);
368
369 //
370 // Get Name for this node.
371 //
373 AmlHandle,
374 TermIndex,
375 &DataType,
376 &NameString,
377 &NameSize
378 );
379 if (EFI_ERROR (Status)) {
380 return NULL;
381 }
382
383 ASSERT (DataType == EFI_ACPI_DATA_TYPE_NAME_STRING);
384
385 return NameString;
386}
387
399 IN EFI_AML_HANDLE *AmlHandle,
400 OUT UINT8 **Buffer
401 )
402{
403 EFI_ACPI_DATA_TYPE DataType;
404 VOID *Data;
405 UINTN DataSize;
406 EFI_STATUS Status;
407
409 AmlHandle,
410 AmlHandle->AmlByteEncoding->MaxIndex,
411 &DataType,
412 &Data,
413 &DataSize
414 );
415 if (EFI_ERROR (Status)) {
416 return EFI_INVALID_PARAMETER;
417 }
418
419 //
420 // We need to parse the rest buffer after last node.
421 //
422 *Buffer = (UINT8 *)((UINTN)Data + DataSize);
423
424 //
425 // We need skip PkgLength if no Option
426 //
427 if (DataType == EFI_ACPI_DATA_TYPE_OPCODE) {
428 *Buffer += AmlGetPkgLength (*Buffer, &DataSize);
429 }
430
431 return EFI_SUCCESS;
432}
433
450 IN EFI_AML_HANDLE *AmlHandle,
451 IN AML_OP_PARSE_INDEX Index,
452 OUT EFI_ACPI_DATA_TYPE *DataType,
453 OUT VOID **Data,
454 OUT UINTN *DataSize
455 )
456{
457 return AmlParseOptionCommon (
458 AmlHandle->AmlByteEncoding,
459 AmlHandle->Buffer,
460 AmlHandle->Size,
461 Index,
462 DataType,
463 Data,
464 DataSize
465 );
466}
UINT64 UINTN
AML_BYTE_ENCODING * AmlSearchByOpByte(IN UINT8 *OpByteBuffer)
Definition: Aml.c:180
EFI_ACPI_DATA_TYPE AmlTypeToAcpiType(IN AML_OP_PARSE_FORMAT AmlType)
Definition: Aml.c:218
#define AML_IS_NAME_CHAR
Definition: Aml.h:70
#define AML_HAS_PKG_LENGTH
Definition: Aml.h:64
#define AML_IN_NAMESPACE
Definition: Aml.h:98
CHAR8 * AmlGetObjectName(IN EFI_AML_HANDLE *AmlHandle)
Definition: AmlOption.c:341
UINTN AmlGetObjectSize(IN AML_BYTE_ENCODING *AmlByteEncoding, IN UINT8 *Buffer, IN UINTN MaxBufferSize)
Definition: AmlOption.c:308
EFI_STATUS AmlParseOptionTerm(IN AML_BYTE_ENCODING *AmlByteEncoding, IN UINT8 *Buffer, IN UINTN MaxBufferSize, IN AML_OP_PARSE_INDEX TermIndex, OUT EFI_ACPI_DATA_TYPE *DataType, OUT VOID **Data, OUT UINTN *DataSize)
Definition: AmlOption.c:27
EFI_STATUS AmlParseOptionHandleCommon(IN EFI_AML_HANDLE *AmlHandle, IN AML_OP_PARSE_INDEX Index, OUT EFI_ACPI_DATA_TYPE *DataType, OUT VOID **Data, OUT UINTN *DataSize)
Definition: AmlOption.c:449
EFI_STATUS AmlGetOffsetAfterLastOption(IN EFI_AML_HANDLE *AmlHandle, OUT UINT8 **Buffer)
Definition: AmlOption.c:398
EFI_STATUS AmlParseOptionCommon(IN AML_BYTE_ENCODING *AmlByteEncoding, IN UINT8 *Buffer, IN UINTN MaxBufferSize, IN AML_OP_PARSE_INDEX Index, OUT EFI_ACPI_DATA_TYPE *DataType, OUT VOID **Data, OUT UINTN *DataSize)
Definition: AmlOption.c:145
UINTN EFIAPI AsciiStrSize(IN CONST CHAR8 *String)
Definition: String.c:681
UINT32 EFIAPI AmlGetPkgLength(IN CONST UINT8 *Buffer, OUT UINT32 *PkgLength)
Definition: Aml.c:621
EFI_STATUS EFIAPI AmlGetNameStringSize(IN CONST CHAR8 *AmlPath, OUT UINT32 *AmlPathSizePtr)
Definition: AmlString.c:547
#define NULL
Definition: Base.h:319
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
AML_OP_ATTRIBUTE Attribute
Additional information on the AML object.
Definition: Aml.h:145
AML_PARSE_FORMAT Format[EAmlParseIndexMax]
Type of each fixed argument.
Definition: Aml.h:142
EAML_PARSE_INDEX MaxIndex
Definition: Aml.h:134