~ubuntu-branches/ubuntu/trusty/virtualbox-lts-xenial/trusty-updates

« back to all changes in this revision

Viewing changes to src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AmlNamespace.c

  • Committer: Package Import Robot
  • Author(s): Gianfranco Costamagna
  • Date: 2016-02-23 14:28:26 UTC
  • Revision ID: package-import@ubuntu.com-20160223142826-bdu69el2z6wa2a44
Tags: upstream-4.3.36-dfsg
ImportĀ upstreamĀ versionĀ 4.3.36-dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/** @file
 
2
  ACPI Sdt Protocol Driver
 
3
 
 
4
  Copyright (c) 2010, Intel Corporation. All rights reserved. <BR>
 
5
  This program and the accompanying materials
 
6
  are licensed and made available under the terms and conditions of the BSD License
 
7
  which accompanies this distribution.  The full text of the license may be found at
 
8
  http://opensource.org/licenses/bsd-license.php
 
9
 
 
10
  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 
11
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 
12
 
 
13
**/
 
14
 
 
15
#include "AcpiTable.h"
 
16
 
 
17
/**
 
18
  Construct node list according to the AML handle.
 
19
  
 
20
  @param[in]    AmlHandle            AML handle.
 
21
  @param[in]    AmlRootNodeList      AML root node list.
 
22
  @param[in]    AmlParentNodeList    AML parent node list.
 
23
  
 
24
  @retval       EFI_SUCCESS           Success.
 
25
  @retval       EFI_INVALID_PARAMETER AML handle does not refer to a valid ACPI object.
 
26
**/
 
27
EFI_STATUS
 
28
AmlConstructNodeList (
 
29
  IN EFI_AML_HANDLE      *AmlHandle,
 
30
  IN EFI_AML_NODE_LIST   *AmlRootNodeList,
 
31
  IN EFI_AML_NODE_LIST   *AmlParentNodeList
 
32
  );
 
33
 
 
34
/**
 
35
  Create AML Node.
 
36
  
 
37
  @param[in]    NameSeg              AML NameSeg.
 
38
  @param[in]    Parent               AML parent node list.
 
39
  @param[in]    AmlByteEncoding      AML Byte Encoding.
 
40
  
 
41
  @return       AML Node.
 
42
**/
 
43
EFI_AML_NODE_LIST *
 
44
AmlCreateNode (
 
45
  IN UINT8              *NameSeg,
 
46
  IN EFI_AML_NODE_LIST  *Parent,
 
47
  IN AML_BYTE_ENCODING  *AmlByteEncoding
 
48
  )
 
49
{
 
50
  EFI_AML_NODE_LIST      *AmlNodeList;
 
51
 
 
52
  AmlNodeList = AllocatePool (sizeof(*AmlNodeList));
 
53
  ASSERT (AmlNodeList != NULL);
 
54
 
 
55
  AmlNodeList->Signature = EFI_AML_NODE_LIST_SIGNATURE;
 
56
  CopyMem (AmlNodeList->Name, NameSeg, AML_NAME_SEG_SIZE);
 
57
  AmlNodeList->Buffer    = NULL;
 
58
  AmlNodeList->Size      = 0;
 
59
  InitializeListHead (&AmlNodeList->Link);
 
60
  InitializeListHead (&AmlNodeList->Children);
 
61
  AmlNodeList->Parent = Parent;
 
62
  AmlNodeList->AmlByteEncoding = AmlByteEncoding;
 
63
 
 
64
  return AmlNodeList;
 
65
}
 
66
 
 
67
/**
 
68
  Find the AML NameSeg in the children of AmlParentNodeList.
 
69
  
 
70
  @param[in]    NameSeg              AML NameSeg.
 
71
  @param[in]    AmlParentNodeList    AML parent node list.
 
72
  @param[in]    Create               TRUE means to create node if not found.
 
73
  
 
74
  @return       AmlChildNode whoes name is same as NameSeg.
 
75
**/
 
76
EFI_AML_NODE_LIST *
 
77
AmlFindNodeInThis (
 
78
  IN UINT8               *NameSeg,
 
79
  IN EFI_AML_NODE_LIST   *AmlParentNodeList,
 
80
  IN BOOLEAN             Create
 
81
  )
 
82
{
 
83
  EFI_AML_NODE_LIST      *CurrentAmlNodeList;
 
84
  LIST_ENTRY             *CurrentLink;
 
85
  LIST_ENTRY             *StartLink;
 
86
  EFI_AML_NODE_LIST      *AmlNodeList;
 
87
 
 
88
  StartLink   = &AmlParentNodeList->Children;
 
89
  CurrentLink = StartLink->ForwardLink;
 
90
 
 
91
  while (CurrentLink != StartLink) {
 
92
    CurrentAmlNodeList = EFI_AML_NODE_LIST_FROM_LINK (CurrentLink);
 
93
    //
 
94
    // AML name is same as the one stored
 
95
    //
 
96
    if (CompareMem (CurrentAmlNodeList->Name, NameSeg, AML_NAME_SEG_SIZE) == 0) {
 
97
      //
 
98
      // Good! Found it
 
99
      //
 
100
      return CurrentAmlNodeList;
 
101
    }
 
102
    CurrentLink = CurrentLink->ForwardLink;
 
103
  }
 
104
 
 
105
  //
 
106
  // Not found
 
107
  //
 
108
  if (!Create) {
 
109
    return NULL;
 
110
  }
 
111
 
 
112
  //
 
113
  // Create new node with NULL buffer - it means namespace not be returned.
 
114
  //
 
115
  AmlNodeList = AmlCreateNode (NameSeg, AmlParentNodeList, NULL);
 
116
  InsertTailList (&AmlParentNodeList->Children, &AmlNodeList->Link);
 
117
 
 
118
  return AmlNodeList;
 
119
}
 
120
 
 
121
/**
 
122
  Find the AML NameString in the children of AmlParentNodeList or AmlRootNodeList.
 
123
  
 
124
  @param[in]    NameString           AML NameString.
 
125
  @param[in]    AmlRootNodeList      AML root node list.
 
126
  @param[in]    AmlParentNodeList    AML parent node list.
 
127
  @param[in]    Create               TRUE means to create node if not found.
 
128
  
 
129
  @return       AmlChildNode whoes name is same as NameSeg.
 
130
**/
 
131
EFI_AML_NODE_LIST *
 
132
AmlFindNodeInTheTree (
 
133
  IN UINT8               *NameString,
 
134
  IN EFI_AML_NODE_LIST   *AmlRootNodeList,
 
135
  IN EFI_AML_NODE_LIST   *AmlParentNodeList,
 
136
  IN BOOLEAN             Create
 
137
  )
 
138
{
 
139
  UINT8               *Buffer;
 
140
  EFI_AML_NODE_LIST   *AmlNodeList;
 
141
  EFI_AML_NODE_LIST   *AmlCurrentNodeList;
 
142
  UINT8               Index;
 
143
  UINT8               SegCount;
 
144
 
 
145
  Buffer = NameString;
 
146
 
 
147
  //
 
148
  // Handle root or parent prefix
 
149
  //
 
150
  if (*Buffer == AML_ROOT_CHAR) {
 
151
    AmlCurrentNodeList = AmlRootNodeList;
 
152
    Buffer += 1;
 
153
  } else if (*Buffer == AML_PARENT_PREFIX_CHAR) {
 
154
    AmlCurrentNodeList = AmlParentNodeList;
 
155
    do {
 
156
      if (AmlCurrentNodeList->Parent != NULL) {
 
157
        AmlCurrentNodeList = AmlCurrentNodeList->Parent;
 
158
      } else {
 
159
        //
 
160
        // Only root has no parent
 
161
        //
 
162
        ASSERT (AmlCurrentNodeList == AmlRootNodeList);
 
163
      }
 
164
      Buffer += 1;
 
165
    } while (*Buffer == AML_PARENT_PREFIX_CHAR);
 
166
  } else {
 
167
    AmlCurrentNodeList = AmlParentNodeList;
 
168
  }
 
169
  
 
170
  //
 
171
  // Handle name segment
 
172
  //
 
173
  if (*Buffer == AML_DUAL_NAME_PREFIX) {
 
174
    Buffer += 1;
 
175
    SegCount = 2;
 
176
  } else if (*Buffer == AML_MULTI_NAME_PREFIX) {
 
177
    Buffer += 1;
 
178
    SegCount = *Buffer;
 
179
    Buffer += 1;
 
180
  } else if (*Buffer == 0) {
 
181
    //
 
182
    // NULL name, only for Root
 
183
    //
 
184
    ASSERT (AmlCurrentNodeList == AmlRootNodeList);
 
185
    return AmlCurrentNodeList;
 
186
  } else {
 
187
    SegCount = 1;
 
188
  }
 
189
 
 
190
  //
 
191
  // Handle NamePath
 
192
  //
 
193
  Index = 0;
 
194
  do {
 
195
    AmlNodeList = AmlFindNodeInThis (Buffer, AmlCurrentNodeList, Create);
 
196
    if (AmlNodeList == NULL) {
 
197
      return NULL;
 
198
    }
 
199
    AmlCurrentNodeList = AmlNodeList;
 
200
    Buffer += AML_NAME_SEG_SIZE;
 
201
    Index ++;
 
202
  } while (Index < SegCount);
 
203
 
 
204
  return AmlNodeList;
 
205
}
 
206
 
 
207
/**
 
208
  Insert the NameString to the AmlNodeList.
 
209
  
 
210
  @param[in]    NameString           AML NameString.
 
211
  @param[in]    Buffer               Buffer for the Node.
 
212
  @param[in]    Size                 Size for the Node.
 
213
  @param[in]    AmlRootNodeList      AML root node list.
 
214
  @param[in]    AmlParentNodeList    AML parent node list.
 
215
  
 
216
  @return       AmlChildNode whoes name is NameString.
 
217
**/
 
218
EFI_AML_NODE_LIST *
 
219
AmlInsertNodeToTree (
 
220
  IN UINT8               *NameString,
 
221
  IN VOID                *Buffer,
 
222
  IN UINTN               Size,
 
223
  IN EFI_AML_NODE_LIST   *AmlRootNodeList,
 
224
  IN EFI_AML_NODE_LIST   *AmlParentNodeList
 
225
  )
 
226
{
 
227
  EFI_AML_NODE_LIST   *AmlNodeList;
 
228
 
 
229
  AmlNodeList = AmlFindNodeInTheTree (
 
230
                  NameString,
 
231
                  AmlRootNodeList,
 
232
                  AmlParentNodeList,
 
233
                  TRUE  // Find and Create
 
234
                  );
 
235
  ASSERT (AmlNodeList != NULL);
 
236
  if (AmlNodeList == NULL) {
 
237
    return NULL;
 
238
  }
 
239
 
 
240
  //
 
241
  // Check buffer
 
242
  //
 
243
  if (AmlNodeList->Buffer == NULL) {
 
244
    //
 
245
    // NULL means new added one or SCOPE_OP
 
246
    //
 
247
    if (*(UINT8 *)Buffer != AML_SCOPE_OP) {
 
248
      //
 
249
      // We need check if new one is SCOPE_OP, because SCOPE_OP just means namespace, not a real device.
 
250
      // We should not return SCOPE_OP.
 
251
      //
 
252
      AmlNodeList->Buffer = Buffer;
 
253
      AmlNodeList->Size   = Size;
 
254
      AmlNodeList->AmlByteEncoding = AmlSearchByOpByte (Buffer);
 
255
    }
 
256
    return AmlNodeList;
 
257
  }
 
258
 
 
259
  //
 
260
  // Already added
 
261
  //
 
262
  if (*(UINT8 *)Buffer == AML_SCOPE_OP) {
 
263
    //
 
264
    // The new one is SCOPE_OP, OK just return;
 
265
    //
 
266
    return AmlNodeList;
 
267
  }
 
268
 
 
269
  //
 
270
  // Oops!!!, There must be something wrong.
 
271
  //
 
272
  DEBUG ((EFI_D_ERROR, "AML: Override Happen - %a!\n", NameString));
 
273
  DEBUG ((EFI_D_ERROR, "AML: Existing Node - %x\n", AmlNodeList->Buffer));
 
274
  DEBUG ((EFI_D_ERROR, "AML: New Buffer - %x\n", Buffer));
 
275
 
 
276
  return NULL;
 
277
}
 
278
 
 
279
/**
 
280
  Construct child node list according to the AML handle.
 
281
  
 
282
  @param[in]    AmlHandle            AML handle.
 
283
  @param[in]    AmlRootNodeList      AML root node list.
 
284
  @param[in]    AmlParentNodeList    AML parent node list.
 
285
  
 
286
  @retval       EFI_SUCCESS           Success.
 
287
  @retval       EFI_INVALID_PARAMETER AML handle does not refer to a valid ACPI object.
 
288
**/
 
289
EFI_STATUS
 
290
AmlConstructNodeListForChild (
 
291
  IN EFI_AML_HANDLE      *AmlHandle,
 
292
  IN EFI_AML_NODE_LIST   *AmlRootNodeList,
 
293
  IN EFI_AML_NODE_LIST   *AmlParentNodeList
 
294
  )
 
295
{
 
296
  AML_BYTE_ENCODING   *AmlByteEncoding;
 
297
  UINT8               *Buffer;
 
298
  UINTN               BufferSize;
 
299
  UINT8               *CurrentBuffer;
 
300
  EFI_AML_HANDLE      *AmlChildHandle;
 
301
  EFI_STATUS          Status;
 
302
 
 
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
 
 
368
/**
 
369
  Construct node list according to the AML handle.
 
370
  
 
371
  @param[in]    AmlHandle            AML handle.
 
372
  @param[in]    AmlRootNodeList      AML root node list.
 
373
  @param[in]    AmlParentNodeList    AML parent node list.
 
374
  
 
375
  @retval       EFI_SUCCESS           Success.
 
376
  @retval       EFI_INVALID_PARAMETER AML handle does not refer to a valid ACPI object.
 
377
**/
 
378
EFI_STATUS
 
379
AmlConstructNodeList (
 
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
 
 
419
/**
 
420
  Destruct node list
 
421
  
 
422
  @param[in]    AmlParentNodeList    AML parent node list.
 
423
**/
 
424
VOID
 
425
AmlDestructNodeList (
 
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
 
 
464
/**
 
465
  Dump node list
 
466
  
 
467
  @param[in]    AmlParentNodeList    AML parent node list.
 
468
  @param[in]    Level                Output debug level.
 
469
**/
 
470
VOID
 
471
AmlDumpNodeInfo (
 
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 ((EFI_D_ERROR, "\\"));
 
484
  } else {
 
485
    for (Index = 0; Index < Level; Index++) {
 
486
      DEBUG ((EFI_D_ERROR, "    "));
 
487
    }
 
488
    AmlPrintNameSeg (AmlParentNodeList->Name);
 
489
  }
 
490
  DEBUG ((EFI_D_ERROR, "\n"));
 
491
 
 
492
  while (CurrentLink != &AmlParentNodeList->Children) {
 
493
    CurrentAmlNodeList = EFI_AML_NODE_LIST_FROM_LINK (CurrentLink);
 
494
    AmlDumpNodeInfo (CurrentAmlNodeList, Level + 1);
 
495
    CurrentLink = CurrentLink->ForwardLink;
 
496
  }
 
497
 
 
498
  return ;
 
499
}
 
500
 
 
501
/**
 
502
  Returns the handle of the ACPI object representing the specified ACPI AML path
 
503
  
 
504
  @param[in]    AmlHandle   Points to the handle of the object representing the starting point for the path search.
 
505
  @param[in]    AmlPath     Points to the ACPI AML path.
 
506
  @param[out]   Buffer      On return, points to the ACPI object which represents AcpiPath, relative to
 
507
                            HandleIn.
 
508
  @param[in]    FromRoot    TRUE means to find AML path from \ (Root) Node.
 
509
                            FALSE means to find AML path from this Node (The HandleIn).
 
510
                            
 
511
  @retval EFI_SUCCESS           Success
 
512
  @retval EFI_INVALID_PARAMETER HandleIn does not refer to a valid ACPI object.                            
 
513
**/
 
514
EFI_STATUS
 
515
AmlFindPath (
 
516
  IN    EFI_AML_HANDLE  *AmlHandle,
 
517
  IN    UINT8           *AmlPath,
 
518
  OUT   VOID            **Buffer,
 
519
  IN    BOOLEAN         FromRoot
 
520
  )
 
521
{
 
522
  EFI_AML_NODE_LIST   *AmlRootNodeList;
 
523
  EFI_STATUS          Status;
 
524
  EFI_AML_NODE_LIST   *AmlNodeList;
 
525
  UINT8               RootNameSeg[AML_NAME_SEG_SIZE];
 
526
  EFI_AML_NODE_LIST   *CurrentAmlNodeList;
 
527
  LIST_ENTRY          *CurrentLink;
 
528
 
 
529
  //
 
530
  // 1. create tree
 
531
  //
 
532
 
 
533
  //
 
534
  // Create root handle
 
535
  //
 
536
  RootNameSeg[0] = AML_ROOT_CHAR;
 
537
  RootNameSeg[1] = 0;
 
538
  AmlRootNodeList = AmlCreateNode (RootNameSeg, NULL, AmlHandle->AmlByteEncoding);
 
539
 
 
540
  Status = AmlConstructNodeList (
 
541
             AmlHandle,
 
542
             AmlRootNodeList, // Root
 
543
             AmlRootNodeList  // Parent
 
544
             );
 
545
  if (EFI_ERROR (Status)) {
 
546
    return EFI_INVALID_PARAMETER;
 
547
  }
 
548
 
 
549
  DEBUG_CODE_BEGIN ();
 
550
  DEBUG ((EFI_D_ERROR, "AcpiSdt: NameSpace:\n"));
 
551
  AmlDumpNodeInfo (AmlRootNodeList, 0);
 
552
  DEBUG_CODE_END ();
 
553
 
 
554
  //
 
555
  // 2. Search the node in the tree
 
556
  //
 
557
  if (FromRoot) {
 
558
    //
 
559
    // Search from Root
 
560
    //
 
561
    CurrentAmlNodeList = AmlRootNodeList;
 
562
  } else {
 
563
    //
 
564
    // Search from this node, NOT ROOT.
 
565
    // Since we insert node to ROOT one by one, we just get the first node and search from it.
 
566
    //
 
567
    CurrentLink = AmlRootNodeList->Children.ForwardLink;
 
568
    if (CurrentLink != &AmlRootNodeList->Children) {
 
569
      //
 
570
      // First node
 
571
      //
 
572
      CurrentAmlNodeList = EFI_AML_NODE_LIST_FROM_LINK (CurrentLink);
 
573
    } else {
 
574
      //
 
575
      // No child
 
576
      //
 
577
      CurrentAmlNodeList = NULL;
 
578
    }
 
579
  }
 
580
 
 
581
  //
 
582
  // Search
 
583
  //
 
584
  if (CurrentAmlNodeList != NULL) {
 
585
    DEBUG_CODE_BEGIN ();
 
586
    DEBUG ((EFI_D_ERROR, "AcpiSdt: Search from: \\"));
 
587
    AmlPrintNameSeg (CurrentAmlNodeList->Name);
 
588
    DEBUG ((EFI_D_ERROR, "\n"));
 
589
    DEBUG_CODE_END ();
 
590
    AmlNodeList = AmlFindNodeInTheTree (
 
591
                    AmlPath,
 
592
                    AmlRootNodeList,    // Root
 
593
                    CurrentAmlNodeList, // Parent
 
594
                    FALSE
 
595
                    );
 
596
  } else {
 
597
    AmlNodeList = NULL;
 
598
  }
 
599
 
 
600
  *Buffer = NULL;
 
601
  Status = EFI_SUCCESS;
 
602
  if (AmlNodeList != NULL && AmlNodeList->Buffer != NULL) {
 
603
    *Buffer = AmlNodeList->Buffer;
 
604
  }
 
605
 
 
606
  //
 
607
  // 3. free the tree
 
608
  //
 
609
  AmlDestructNodeList (AmlRootNodeList);
 
610
 
 
611
  return Status;
 
612
}