TianoCore EDK2 master
Loading...
Searching...
No Matches
AmlNamespace.c
Go to the documentation of this file.
1
9#include "AcpiTable.h"
10
23 IN EFI_AML_HANDLE *AmlHandle,
24 IN EFI_AML_NODE_LIST *AmlRootNodeList,
25 IN EFI_AML_NODE_LIST *AmlParentNodeList
26 );
27
39 IN UINT8 *NameSeg,
40 IN EFI_AML_NODE_LIST *Parent,
41 IN AML_BYTE_ENCODING *AmlByteEncoding
42 )
43{
44 EFI_AML_NODE_LIST *AmlNodeList;
45
46 AmlNodeList = AllocatePool (sizeof (*AmlNodeList));
47 ASSERT (AmlNodeList != NULL);
48
49 AmlNodeList->Signature = EFI_AML_NODE_LIST_SIGNATURE;
50 CopyMem (AmlNodeList->Name, NameSeg, AML_NAME_SEG_SIZE);
51 AmlNodeList->Buffer = NULL;
52 AmlNodeList->Size = 0;
53 InitializeListHead (&AmlNodeList->Link);
54 InitializeListHead (&AmlNodeList->Children);
55 AmlNodeList->Parent = Parent;
56 AmlNodeList->AmlByteEncoding = AmlByteEncoding;
57
58 return AmlNodeList;
59}
60
72 IN UINT8 *NameSeg,
73 IN EFI_AML_NODE_LIST *AmlParentNodeList,
74 IN BOOLEAN Create
75 )
76{
77 EFI_AML_NODE_LIST *CurrentAmlNodeList;
78 LIST_ENTRY *CurrentLink;
79 LIST_ENTRY *StartLink;
80 EFI_AML_NODE_LIST *AmlNodeList;
81
82 StartLink = &AmlParentNodeList->Children;
83 CurrentLink = StartLink->ForwardLink;
84
85 while (CurrentLink != StartLink) {
86 CurrentAmlNodeList = EFI_AML_NODE_LIST_FROM_LINK (CurrentLink);
87 //
88 // AML name is same as the one stored
89 //
90 if (CompareMem (CurrentAmlNodeList->Name, NameSeg, AML_NAME_SEG_SIZE) == 0) {
91 //
92 // Good! Found it
93 //
94 return CurrentAmlNodeList;
95 }
96
97 CurrentLink = CurrentLink->ForwardLink;
98 }
99
100 //
101 // Not found
102 //
103 if (!Create) {
104 return NULL;
105 }
106
107 //
108 // Create new node with NULL buffer - it means namespace not be returned.
109 //
110 AmlNodeList = AmlCreateNode (NameSeg, AmlParentNodeList, NULL);
111 InsertTailList (&AmlParentNodeList->Children, &AmlNodeList->Link);
112
113 return AmlNodeList;
114}
115
128 IN UINT8 *NameString,
129 IN EFI_AML_NODE_LIST *AmlRootNodeList,
130 IN EFI_AML_NODE_LIST *AmlParentNodeList,
131 IN BOOLEAN Create
132 )
133{
134 UINT8 *Buffer;
135 EFI_AML_NODE_LIST *AmlNodeList;
136 EFI_AML_NODE_LIST *AmlCurrentNodeList;
137 UINT8 Index;
138 UINT8 SegCount;
139
140 Buffer = NameString;
141
142 //
143 // Handle root or parent prefix
144 //
145 if (*Buffer == AML_ROOT_CHAR) {
146 AmlCurrentNodeList = AmlRootNodeList;
147 Buffer += 1;
148 } else if (*Buffer == AML_PARENT_PREFIX_CHAR) {
149 AmlCurrentNodeList = AmlParentNodeList;
150 do {
151 if (AmlCurrentNodeList->Parent != NULL) {
152 AmlCurrentNodeList = AmlCurrentNodeList->Parent;
153 } else {
154 //
155 // Only root has no parent
156 //
157 ASSERT (AmlCurrentNodeList == AmlRootNodeList);
158 }
159
160 Buffer += 1;
161 } while (*Buffer == AML_PARENT_PREFIX_CHAR);
162 } else {
163 AmlCurrentNodeList = AmlParentNodeList;
164 }
165
166 //
167 // Handle name segment
168 //
169 if (*Buffer == AML_DUAL_NAME_PREFIX) {
170 Buffer += 1;
171 SegCount = 2;
172 } else if (*Buffer == AML_MULTI_NAME_PREFIX) {
173 Buffer += 1;
174 SegCount = *Buffer;
175 Buffer += 1;
176 } else if (*Buffer == 0) {
177 //
178 // NULL name, only for Root
179 //
180 ASSERT (AmlCurrentNodeList == AmlRootNodeList);
181 return AmlCurrentNodeList;
182 } else {
183 SegCount = 1;
184 }
185
186 //
187 // Handle NamePath
188 //
189 Index = 0;
190 do {
191 AmlNodeList = AmlFindNodeInThis (Buffer, AmlCurrentNodeList, Create);
192 if (AmlNodeList == NULL) {
193 return NULL;
194 }
195
196 AmlCurrentNodeList = AmlNodeList;
197 Buffer += AML_NAME_SEG_SIZE;
198 Index++;
199 } while (Index < SegCount);
200
201 return AmlNodeList;
202}
203
217 IN UINT8 *NameString,
218 IN VOID *Buffer,
219 IN UINTN Size,
220 IN EFI_AML_NODE_LIST *AmlRootNodeList,
221 IN EFI_AML_NODE_LIST *AmlParentNodeList
222 )
223{
224 EFI_AML_NODE_LIST *AmlNodeList;
225
226 AmlNodeList = AmlFindNodeInTheTree (
227 NameString,
228 AmlRootNodeList,
229 AmlParentNodeList,
230 TRUE // Find and Create
231 );
232 ASSERT (AmlNodeList != NULL);
233 if (AmlNodeList == NULL) {
234 return NULL;
235 }
236
237 //
238 // Check buffer
239 //
240 if (AmlNodeList->Buffer == NULL) {
241 //
242 // NULL means new added one or SCOPE_OP
243 //
244 if (*(UINT8 *)Buffer != AML_SCOPE_OP) {
245 //
246 // We need check if new one is SCOPE_OP, because SCOPE_OP just means namespace, not a real device.
247 // We should not return SCOPE_OP.
248 //
249 AmlNodeList->Buffer = Buffer;
250 AmlNodeList->Size = Size;
251 AmlNodeList->AmlByteEncoding = AmlSearchByOpByte (Buffer);
252 }
253
254 return AmlNodeList;
255 }
256
257 //
258 // Already added
259 //
260 if (*(UINT8 *)Buffer == AML_SCOPE_OP) {
261 //
262 // The new one is SCOPE_OP, OK just return;
263 //
264 return AmlNodeList;
265 }
266
267 //
268 // Oops!!!, There must be something wrong.
269 //
270 DEBUG ((DEBUG_ERROR, "AML: Override Happen - %a!\n", NameString));
271 DEBUG ((DEBUG_ERROR, "AML: Existing Node - %x\n", AmlNodeList->Buffer));
272 DEBUG ((DEBUG_ERROR, "AML: New Buffer - %x\n", Buffer));
273
274 return NULL;
275}
276
289 IN EFI_AML_HANDLE *AmlHandle,
290 IN EFI_AML_NODE_LIST *AmlRootNodeList,
291 IN EFI_AML_NODE_LIST *AmlParentNodeList
292 )
293{
294 AML_BYTE_ENCODING *AmlByteEncoding;
295 UINT8 *Buffer;
296 UINTN BufferSize;
297 UINT8 *CurrentBuffer;
298 EFI_AML_HANDLE *AmlChildHandle;
299 EFI_STATUS Status;
300
301 CurrentBuffer = NULL;
302 AmlChildHandle = NULL;
303 AmlByteEncoding = AmlHandle->AmlByteEncoding;
304 Buffer = AmlHandle->Buffer;
305 BufferSize = AmlHandle->Size;
306
307 //
308 // Check if we need recursively add node
309 //
310 if ((AmlByteEncoding->Attribute & AML_HAS_CHILD_OBJ) == 0) {
311 //
312 // No more node need to be added
313 //
314 return EFI_SUCCESS;
315 }
316
317 //
318 // Do we need add node within METHOD?
319 // Yes, just add Object is OK. But we need filter NameString for METHOD invoke.
320 //
321
322 //
323 // Now, we get the last node.
324 //
325 Status = AmlGetOffsetAfterLastOption (AmlHandle, &CurrentBuffer);
326 if (EFI_ERROR (Status)) {
327 return EFI_INVALID_PARAMETER;
328 }
329
330 //
331 // Go through all the reset buffer.
332 //
333 while ((UINTN)CurrentBuffer < (UINTN)Buffer + BufferSize) {
334 //
335 // Find the child node.
336 //
337 Status = SdtOpenEx (CurrentBuffer, (UINTN)Buffer + BufferSize - (UINTN)CurrentBuffer, (EFI_ACPI_HANDLE *)&AmlChildHandle);
338 if (EFI_ERROR (Status)) {
339 //
340 // No child found, break now.
341 //
342 break;
343 }
344
345 //
346 // Good, find the child. Construct node recursively
347 //
348 Status = AmlConstructNodeList (
349 AmlChildHandle,
350 AmlRootNodeList,
351 AmlParentNodeList
352 );
353 if (EFI_ERROR (Status)) {
354 break;
355 }
356
357 //
358 // Parse next one
359 //
360 CurrentBuffer += AmlChildHandle->Size;
361
362 Close ((EFI_ACPI_HANDLE)AmlChildHandle);
363 }
364
365 return EFI_SUCCESS;
366}
367
380 IN EFI_AML_HANDLE *AmlHandle,
381 IN EFI_AML_NODE_LIST *AmlRootNodeList,
382 IN EFI_AML_NODE_LIST *AmlParentNodeList
383 )
384{
385 VOID *NameString;
386 EFI_AML_NODE_LIST *AmlNodeList;
387
388 //
389 // 1. Check if there is need to construct node for this OpCode.
390 //
391 if ((AmlHandle->AmlByteEncoding->Attribute & AML_IN_NAMESPACE) == 0) {
392 //
393 // No need to construct node, so we just skip this OpCode.
394 //
395 return EFI_SUCCESS;
396 }
397
398 //
399 // 2. Now, we need construct node for this OpCode.
400 //
401 NameString = AmlGetObjectName (AmlHandle);
402 if (NameString == NULL) {
403 return EFI_INVALID_PARAMETER;
404 }
405
406 //
407 // Now, we need to insert node to the node list.
408 // NOTE: The name here could be AML NameString. So the callee need parse it.
409 //
410 AmlNodeList = AmlInsertNodeToTree (NameString, AmlHandle->Buffer, AmlHandle->Size, AmlRootNodeList, AmlParentNodeList);
411 ASSERT (AmlNodeList != NULL);
412
413 //
414 // 3. Ok, we need to parse the object list to see if there are more node to be added.
415 //
416 return AmlConstructNodeListForChild (AmlHandle, AmlRootNodeList, AmlNodeList);
417}
418
424VOID
426 IN EFI_AML_NODE_LIST *AmlParentNodeList
427 )
428{
429 EFI_AML_NODE_LIST *CurrentAmlNodeList;
430 LIST_ENTRY *CurrentLink;
431 LIST_ENTRY *StartLink;
432
433 //
434 // Get the children link
435 //
436 StartLink = &AmlParentNodeList->Children;
437 CurrentLink = StartLink->ForwardLink;
438
439 //
440 // Go through all the children
441 //
442 while (CurrentLink != StartLink) {
443 //
444 // Destruct the child's list recursively
445 //
446 CurrentAmlNodeList = EFI_AML_NODE_LIST_FROM_LINK (CurrentLink);
447 CurrentLink = CurrentLink->ForwardLink;
448
449 //
450 // Remove this child from list and free the node
451 //
452 RemoveEntryList (&(CurrentAmlNodeList->Link));
453
454 AmlDestructNodeList (CurrentAmlNodeList);
455 }
456
457 //
458 // Done.
459 //
460 FreePool (AmlParentNodeList);
461 return;
462}
463
470VOID
472 IN EFI_AML_NODE_LIST *AmlParentNodeList,
473 IN UINTN Level
474 )
475{
476 EFI_AML_NODE_LIST *CurrentAmlNodeList;
477 volatile LIST_ENTRY *CurrentLink;
478 UINTN Index;
479
480 CurrentLink = AmlParentNodeList->Children.ForwardLink;
481
482 if (Level == 0) {
483 DEBUG ((DEBUG_ERROR, "\\"));
484 } else {
485 for (Index = 0; Index < Level; Index++) {
486 DEBUG ((DEBUG_ERROR, " "));
487 }
488
489 AmlPrintNameSeg (AmlParentNodeList->Name);
490 }
491
492 DEBUG ((DEBUG_ERROR, "\n"));
493
494 while (CurrentLink != &AmlParentNodeList->Children) {
495 CurrentAmlNodeList = EFI_AML_NODE_LIST_FROM_LINK (CurrentLink);
496 AmlDumpNodeInfo (CurrentAmlNodeList, Level + 1);
497 CurrentLink = CurrentLink->ForwardLink;
498 }
499
500 return;
501}
502
518 IN EFI_AML_HANDLE *AmlHandle,
519 IN UINT8 *AmlPath,
520 OUT VOID **Buffer,
521 IN BOOLEAN FromRoot
522 )
523{
524 EFI_AML_NODE_LIST *AmlRootNodeList;
525 EFI_STATUS Status;
526 EFI_AML_NODE_LIST *AmlNodeList;
527 UINT8 RootNameSeg[AML_NAME_SEG_SIZE];
528 EFI_AML_NODE_LIST *CurrentAmlNodeList;
529 LIST_ENTRY *CurrentLink;
530
531 //
532 // 1. create tree
533 //
534
535 //
536 // Create root handle
537 //
538 RootNameSeg[0] = AML_ROOT_CHAR;
539 RootNameSeg[1] = 0;
540 AmlRootNodeList = AmlCreateNode (RootNameSeg, NULL, AmlHandle->AmlByteEncoding);
541
542 Status = AmlConstructNodeList (
543 AmlHandle,
544 AmlRootNodeList, // Root
545 AmlRootNodeList // Parent
546 );
547 if (EFI_ERROR (Status)) {
548 return EFI_INVALID_PARAMETER;
549 }
550
552 DEBUG ((DEBUG_ERROR, "AcpiSdt: NameSpace:\n"));
553 AmlDumpNodeInfo (AmlRootNodeList, 0);
555
556 //
557 // 2. Search the node in the tree
558 //
559 if (FromRoot) {
560 //
561 // Search from Root
562 //
563 CurrentAmlNodeList = AmlRootNodeList;
564 } else {
565 //
566 // Search from this node, NOT ROOT.
567 // Since we insert node to ROOT one by one, we just get the first node and search from it.
568 //
569 CurrentLink = AmlRootNodeList->Children.ForwardLink;
570 if (CurrentLink != &AmlRootNodeList->Children) {
571 //
572 // First node
573 //
574 CurrentAmlNodeList = EFI_AML_NODE_LIST_FROM_LINK (CurrentLink);
575 } else {
576 //
577 // No child
578 //
579 CurrentAmlNodeList = NULL;
580 }
581 }
582
583 //
584 // Search
585 //
586 if (CurrentAmlNodeList != NULL) {
588 DEBUG ((DEBUG_ERROR, "AcpiSdt: Search from: \\"));
589 AmlPrintNameSeg (CurrentAmlNodeList->Name);
590 DEBUG ((DEBUG_ERROR, "\n"));
592 AmlNodeList = AmlFindNodeInTheTree (
593 AmlPath,
594 AmlRootNodeList, // Root
595 CurrentAmlNodeList, // Parent
596 FALSE
597 );
598 } else {
599 AmlNodeList = NULL;
600 }
601
602 *Buffer = NULL;
603 Status = EFI_SUCCESS;
604 if ((AmlNodeList != NULL) && (AmlNodeList->Buffer != NULL)) {
605 *Buffer = AmlNodeList->Buffer;
606 }
607
608 //
609 // 3. free the tree
610 //
611 AmlDestructNodeList (AmlRootNodeList);
612
613 return Status;
614}
UINT64 UINTN
EFI_STATUS SdtOpenEx(IN VOID *Buffer, IN UINTN BufferSize, OUT EFI_ACPI_HANDLE *Handle)
Definition: AcpiSdt.c:537
EFI_STATUS EFIAPI Close(IN EFI_ACPI_HANDLE Handle)
Definition: AcpiSdt.c:628
CHAR8 * AmlGetObjectName(IN EFI_AML_HANDLE *AmlHandle)
Definition: AmlOption.c:341
VOID AmlPrintNameSeg(IN UINT8 *Buffer)
Definition: AmlString.c:466
AML_BYTE_ENCODING * AmlSearchByOpByte(IN UINT8 *OpByteBuffer)
Definition: Aml.c:180
EFI_STATUS AmlGetOffsetAfterLastOption(IN EFI_AML_HANDLE *AmlHandle, OUT UINT8 **Buffer)
Definition: AmlOption.c:398
#define AML_HAS_CHILD_OBJ
Definition: Aml.h:75
#define AML_IN_NAMESPACE
Definition: Aml.h:98
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
Definition: LinkedList.c:590
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
Definition: LinkedList.c:182
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:259
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID EFIAPI FreePool(IN VOID *Buffer)
EFI_STATUS AmlConstructNodeList(IN EFI_AML_HANDLE *AmlHandle, IN EFI_AML_NODE_LIST *AmlRootNodeList, IN EFI_AML_NODE_LIST *AmlParentNodeList)
Definition: AmlNamespace.c:379
EFI_STATUS AmlFindPath(IN EFI_AML_HANDLE *AmlHandle, IN UINT8 *AmlPath, OUT VOID **Buffer, IN BOOLEAN FromRoot)
Definition: AmlNamespace.c:517
EFI_AML_NODE_LIST * AmlFindNodeInTheTree(IN UINT8 *NameString, IN EFI_AML_NODE_LIST *AmlRootNodeList, IN EFI_AML_NODE_LIST *AmlParentNodeList, IN BOOLEAN Create)
Definition: AmlNamespace.c:127
EFI_AML_NODE_LIST * AmlFindNodeInThis(IN UINT8 *NameSeg, IN EFI_AML_NODE_LIST *AmlParentNodeList, IN BOOLEAN Create)
Definition: AmlNamespace.c:71
EFI_AML_NODE_LIST * AmlCreateNode(IN UINT8 *NameSeg, IN EFI_AML_NODE_LIST *Parent, IN AML_BYTE_ENCODING *AmlByteEncoding)
Definition: AmlNamespace.c:38
EFI_STATUS AmlConstructNodeListForChild(IN EFI_AML_HANDLE *AmlHandle, IN EFI_AML_NODE_LIST *AmlRootNodeList, IN EFI_AML_NODE_LIST *AmlParentNodeList)
Definition: AmlNamespace.c:288
EFI_AML_NODE_LIST * AmlInsertNodeToTree(IN UINT8 *NameString, IN VOID *Buffer, IN UINTN Size, IN EFI_AML_NODE_LIST *AmlRootNodeList, IN EFI_AML_NODE_LIST *AmlParentNodeList)
Definition: AmlNamespace.c:216
VOID AmlDestructNodeList(IN EFI_AML_NODE_LIST *AmlParentNodeList)
Definition: AmlNamespace.c:425
VOID AmlDumpNodeInfo(IN EFI_AML_NODE_LIST *AmlParentNodeList, IN UINTN Level)
Definition: AmlNamespace.c:471
#define NULL
Definition: Base.h:319
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG_CODE_BEGIN()
Definition: DebugLib.h:564
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define DEBUG_CODE_END()
Definition: DebugLib.h:578
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
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