TianoCore EDK2 master
Loading...
Searching...
No Matches
AmlResourceDataParser.c
Go to the documentation of this file.
1
15
16#include <AmlCoreInterface.h>
18#include <Tree/AmlNode.h>
19#include <Tree/AmlTree.h>
20
36UINT32
37EFIAPI
39 IN CONST AML_STREAM *FStream
40 )
41{
42 CONST AML_RD_HEADER *CurrRdElement;
43
44 if (!IS_STREAM (FStream) ||
45 IS_END_OF_STREAM (FStream) ||
46 !IS_STREAM_FORWARD (FStream))
47 {
48 ASSERT (0);
49 return 0;
50 }
51
52 CurrRdElement = (CONST AML_RD_HEADER *)AmlStreamGetCurrPos (FStream);
53 if (CurrRdElement == NULL) {
54 ASSERT (0);
55 return 0;
56 }
57
58 // If the resource data element is of the large type, check for overflow.
59 if (AML_RD_IS_LARGE (CurrRdElement) &&
60 (AmlStreamGetFreeSpace (FStream) <
61 sizeof (ACPI_LARGE_RESOURCE_HEADER)))
62 {
63 return 0;
64 }
65
66 return AmlRdGetSize (CurrRdElement);
67}
68
88BOOLEAN
89EFIAPI
91 IN CONST AML_STREAM *FStream,
92 IN OUT BOOLEAN *InFunctionDesc
93 )
94{
95 CONST AML_RD_HEADER *CurrRdElement;
96
97 if (!IS_STREAM (FStream) ||
98 IS_END_OF_STREAM (FStream) ||
99 (InFunctionDesc == NULL))
100 {
101 ASSERT (0);
102 return FALSE;
103 }
104
105 CurrRdElement = AmlStreamGetCurrPos (FStream);
106 if (CurrRdElement == NULL) {
107 ASSERT (0);
108 return FALSE;
109 }
110
111 // Starting a dependent function descriptor.
112 // It is possible to start one when one has already started.
114 CurrRdElement,
116 ACPI_SMALL_START_DEPENDENT_DESCRIPTOR_NAME
117 )
118 ))
119 {
120 *InFunctionDesc = TRUE;
121 return TRUE;
122 }
123
124 // Ending a dependent function descriptor.
126 CurrRdElement,
128 ACPI_SMALL_END_DEPENDENT_DESCRIPTOR_NAME
129 )
130 ))
131 {
132 if (*InFunctionDesc) {
133 *InFunctionDesc = FALSE;
134 return TRUE;
135 }
136
137 // It should not be possible to end a dependent function descriptor
138 // when none started.
139 return FALSE;
140 }
141
142 return TRUE;
143}
144
164BOOLEAN
165EFIAPI
167 IN CONST AML_STREAM *FStream
168 )
169{
170 EFI_STATUS Status;
171 UINT32 FreeSpace;
172 AML_STREAM SubStream;
173 CONST AML_RD_HEADER *CurrRdElement;
174 UINT32 CurrRdElementSize;
175 BOOLEAN InFunctionDesc;
176
177 if (!IS_STREAM (FStream) ||
178 IS_END_OF_STREAM (FStream) ||
179 !IS_STREAM_FORWARD (FStream))
180 {
181 ASSERT (0);
182 return FALSE;
183 }
184
185 // Create a sub-stream from the input stream to leave it untouched.
186 Status = AmlStreamInitSubStream (FStream, &SubStream);
187 if (EFI_ERROR (Status)) {
188 ASSERT (0);
189 return FALSE;
190 }
191
192 CurrRdElement = AmlStreamGetCurrPos (&SubStream);
193 if (CurrRdElement == NULL) {
194 ASSERT (0);
195 return FALSE;
196 }
197
198 // The first element cannot be an end tag.
200 CurrRdElement,
201 AML_RD_BUILD_SMALL_DESC_ID (ACPI_SMALL_END_TAG_DESCRIPTOR_NAME)
202 ))
203 {
204 return FALSE;
205 }
206
207 InFunctionDesc = FALSE;
208 while (TRUE) {
209 FreeSpace = AmlStreamGetFreeSpace (&SubStream);
210 CurrRdElement = AmlStreamGetCurrPos (&SubStream);
211 CurrRdElementSize = AmlRdStreamGetRdSize (&SubStream);
212 if ((FreeSpace == 0) ||
213 (CurrRdElement == NULL) ||
214 (CurrRdElementSize == 0))
215 {
216 return FALSE;
217 }
218
219 if (!AmlRdCheckFunctionDescNesting (&SubStream, &InFunctionDesc)) {
220 return FALSE;
221 }
222
223 if (CurrRdElementSize > FreeSpace) {
224 return FALSE;
225 } else if (CurrRdElementSize == FreeSpace) {
226 return TRUE;
227 }
228
229 // @todo Might want to check the CRC when available.
230 // An end tag resource data element must be the last element of the list.
231 // Thus the function should have already returned.
233 CurrRdElement,
234 AML_RD_BUILD_SMALL_DESC_ID (ACPI_SMALL_END_TAG_DESCRIPTOR_NAME)
235 ))
236 {
237 return FALSE;
238 }
239
240 Status = AmlStreamProgress (&SubStream, CurrRdElementSize);
241 if (EFI_ERROR (Status)) {
242 ASSERT (0);
243 return FALSE;
244 }
245 } // while
246
247 return FALSE;
248}
249
268EFIAPI
270 IN AML_OBJECT_NODE *BufferNode,
271 IN AML_STREAM *FStream
272 )
273{
274 EFI_STATUS Status;
275 AML_DATA_NODE *NewNode;
276 UINT32 FreeSpace;
277 CONST AML_RD_HEADER *CurrRdElement;
278 UINT32 CurrRdElementSize;
279
280 // Check that BufferNode is an ObjectNode and has a ByteList.
281 if (!AmlNodeHasAttribute (BufferNode, AML_HAS_BYTE_LIST) ||
282 !IS_STREAM (FStream) ||
283 IS_END_OF_STREAM (FStream) ||
284 !IS_STREAM_FORWARD (FStream))
285 {
286 ASSERT (0);
287 return EFI_INVALID_PARAMETER;
288 }
289
290 // Iterate through the resource data elements and create nodes.
291 // We assume the Buffer has already been validated as a list of
292 // resource data elements, so less checks are made.
293 while (TRUE) {
294 FreeSpace = AmlStreamGetFreeSpace (FStream);
295 if (FreeSpace == 0) {
296 break;
297 }
298
299 CurrRdElement = (CONST AML_RD_HEADER *)AmlStreamGetCurrPos (FStream);
300 CurrRdElementSize = AmlRdStreamGetRdSize (FStream);
301
302 Status = AmlCreateDataNode (
304 (CONST UINT8 *)CurrRdElement,
305 CurrRdElementSize,
306 &NewNode
307 );
308 if (EFI_ERROR (Status)) {
309 ASSERT (0);
310 return Status;
311 }
312
314 (AML_NODE_HEADER *)BufferNode,
315 (AML_NODE_HEADER *)NewNode
316 );
317 if (EFI_ERROR (Status)) {
318 ASSERT (0);
319 AmlDeleteTree ((AML_NODE_HEADER *)NewNode);
320 return Status;
321 }
322
323 Status = AmlStreamProgress (FStream, CurrRdElementSize);
324 if (EFI_ERROR (Status)) {
325 ASSERT (0);
326 return Status;
327 }
328
329 AMLDBG_DUMP_RAW (CurrRdElement, CurrRdElementSize);
330
331 // Exit the loop when finding the resource data end tag.
333 CurrRdElement,
334 AML_RD_BUILD_SMALL_DESC_ID (ACPI_SMALL_END_TAG_DESCRIPTOR_NAME)
335 ))
336 {
337 if (FreeSpace != CurrRdElementSize) {
338 ASSERT (0);
339 return EFI_INVALID_PARAMETER;
340 }
341
342 break;
343 }
344 } // while
345
346 return EFI_SUCCESS;
347}
#define AML_HAS_BYTE_LIST
Definition: Aml.h:82
BOOLEAN EFIAPI AmlNodeHasAttribute(IN CONST AML_OBJECT_NODE *ObjectNode, IN AML_OP_ATTRIBUTE Attribute)
Definition: AmlNode.c:430
EFI_STATUS EFIAPI AmlCreateDataNode(IN EAML_NODE_DATA_TYPE DataType, IN CONST UINT8 *Data, IN UINT32 DataSize, OUT AML_DATA_NODE **NewDataNodePtr)
Definition: AmlNode.c:275
UINT8 AML_RD_HEADER
STATIC BOOLEAN EFIAPI AmlRdCheckFunctionDescNesting(IN CONST AML_STREAM *FStream, IN OUT BOOLEAN *InFunctionDesc)
EFI_STATUS EFIAPI AmlParseResourceData(IN AML_OBJECT_NODE *BufferNode, IN AML_STREAM *FStream)
BOOLEAN EFIAPI AmlRdIsResourceDataBuffer(IN CONST AML_STREAM *FStream)
UINT32 EFIAPI AmlRdStreamGetRdSize(IN CONST AML_STREAM *FStream)
UINT32 EFIAPI AmlStreamGetFreeSpace(IN CONST AML_STREAM *Stream)
Definition: AmlStream.c:292
EFI_STATUS EFIAPI AmlStreamProgress(IN AML_STREAM *Stream, IN UINT32 Offset)
Definition: AmlStream.c:324
UINT8 *EFIAPI AmlStreamGetCurrPos(IN CONST AML_STREAM *Stream)
Definition: AmlStream.c:264
EFI_STATUS EFIAPI AmlStreamInitSubStream(IN CONST AML_STREAM *Stream, OUT AML_STREAM *SubStream)
Definition: AmlStream.c:109
#define IS_STREAM_FORWARD(Stream)
Definition: AmlStream.h:91
#define IS_STREAM(Stream)
Definition: AmlStream.h:69
#define IS_END_OF_STREAM(Stream)
Definition: AmlStream.h:80
EFI_STATUS EFIAPI AmlVarListAddTailInternal(IN AML_NODE_HEADER *ParentNode, IN AML_NODE_HEADER *NewNode)
Definition: AmlTree.c:379
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define TRUE
Definition: Base.h:301
#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
#define AML_RD_IS_LARGE(Header)
UINT32 EFIAPI AmlRdGetSize(IN CONST AML_RD_HEADER *Header)
BOOLEAN EFIAPI AmlRdCompareDescId(IN CONST AML_RD_HEADER *Header, IN AML_RD_HEADER DescriptorId)
#define AML_RD_BUILD_SMALL_DESC_ID(Id)
@ EAmlNodeDataTypeResourceData
Resource data element.
Definition: AmlDefines.h:44
EFI_STATUS EFIAPI AmlDeleteTree(IN AML_NODE_HANDLE Node)