Home | History | Annotate | Download | only in AcpiTableDxe
      1 /** @file
      2   ACPI Sdt Protocol Driver
      3 
      4   Copyright (c) 2010 - 2014, 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   Return the child objects buffer from AML Handle's buffer.
     19 
     20   @param[in]        AmlParentHandle Parent handle.
     21   @param[in]        CurrentBuffer   The current child buffer.
     22   @param[out]       Buffer          On return, points to the next returned child buffer or NULL if there are no
     23                                     child buffer.
     24 
     25   @retval EFI_SUCCESS               Success
     26   @retval EFI_INVALID_PARAMETER     AmlParentHandle does not refer to a valid ACPI object.
     27 **/
     28 EFI_STATUS
     29 AmlGetChildFromObjectBuffer (
     30   IN EFI_AML_HANDLE         *AmlParentHandle,
     31   IN UINT8                  *CurrentBuffer,
     32   OUT VOID                  **Buffer
     33   )
     34 {
     35   AML_BYTE_ENCODING   *AmlByteEncoding;
     36   UINTN               DataSize;
     37 
     38   //
     39   // Root is considered as SCOPE, which has TermList.
     40   // We need return only Object in TermList.
     41   //
     42   while ((UINTN)CurrentBuffer < (UINTN)(AmlParentHandle->Buffer + AmlParentHandle->Size)) {
     43     AmlByteEncoding = AmlSearchByOpByte (CurrentBuffer);
     44     if (AmlByteEncoding == NULL) {
     45       return EFI_INVALID_PARAMETER;
     46     }
     47     //
     48     // NOTE: We need return everything, because user might need parse the returned object.
     49     //
     50     if ((AmlByteEncoding->Attribute & AML_IS_NAME_CHAR) == 0) {
     51       *Buffer = CurrentBuffer;
     52       return EFI_SUCCESS;
     53     }
     54 
     55     DataSize = AmlGetObjectSize (
     56                  AmlByteEncoding,
     57                  CurrentBuffer,
     58                  (UINTN)AmlParentHandle->Buffer + AmlParentHandle->Size - (UINTN)CurrentBuffer
     59                  );
     60     if (DataSize == 0) {
     61       return EFI_INVALID_PARAMETER;
     62     }
     63     CurrentBuffer += DataSize;
     64   }
     65 
     66   //
     67   // No more
     68   //
     69   *Buffer = NULL;
     70   return EFI_SUCCESS;
     71 }
     72 
     73 /**
     74   Return the child ACPI objects from Root Handle.
     75 
     76   @param[in]        AmlParentHandle Parent handle. It is Root Handle.
     77   @param[in]        AmlHandle       The previously returned handle or NULL to start with the first handle.
     78   @param[out]       Buffer          On return, points to the next returned ACPI handle or NULL if there are no
     79                                     child objects.
     80 
     81   @retval EFI_SUCCESS               Success
     82   @retval EFI_INVALID_PARAMETER     ParentHandle is NULL or does not refer to a valid ACPI object.
     83 **/
     84 EFI_STATUS
     85 AmlGetChildFromRoot (
     86   IN EFI_AML_HANDLE         *AmlParentHandle,
     87   IN EFI_AML_HANDLE         *AmlHandle,
     88   OUT VOID                  **Buffer
     89   )
     90 {
     91   UINT8               *CurrentBuffer;
     92 
     93   if (AmlHandle == NULL) {
     94     //
     95     // First One
     96     //
     97     CurrentBuffer = (VOID *)AmlParentHandle->Buffer;
     98   } else {
     99     CurrentBuffer = (VOID *)(AmlHandle->Buffer + AmlHandle->Size);
    100   }
    101 
    102   return AmlGetChildFromObjectBuffer (AmlParentHandle, CurrentBuffer, Buffer);
    103 }
    104 
    105 /**
    106   Return the child objects buffer from AML Handle's option list.
    107 
    108   @param[in]        AmlParentHandle Parent handle.
    109   @param[in]        AmlHandle       The current child handle.
    110   @param[out]       Buffer          On return, points to the next returned child buffer or NULL if there are no
    111                                     child buffer.
    112 
    113   @retval EFI_SUCCESS               Success
    114   @retval EFI_INVALID_PARAMETER     AmlParentHandle does not refer to a valid ACPI object.
    115 **/
    116 EFI_STATUS
    117 AmlGetChildFromOptionList (
    118   IN EFI_AML_HANDLE         *AmlParentHandle,
    119   IN EFI_AML_HANDLE         *AmlHandle,
    120   OUT VOID                  **Buffer
    121   )
    122 {
    123   EFI_ACPI_DATA_TYPE  DataType;
    124   VOID                *Data;
    125   UINTN               DataSize;
    126   AML_OP_PARSE_INDEX  Index;
    127   EFI_STATUS          Status;
    128   AML_OP_PARSE_INDEX  MaxTerm;
    129 
    130   Index = AML_OP_PARSE_INDEX_GET_TERM1;
    131   MaxTerm = AmlParentHandle->AmlByteEncoding->MaxIndex;
    132   while (Index <= MaxTerm) {
    133     Status = AmlParseOptionHandleCommon (
    134                AmlParentHandle,
    135                (AML_OP_PARSE_INDEX)Index,
    136                &DataType,
    137                (VOID **)&Data,
    138                &DataSize
    139                );
    140     if (EFI_ERROR (Status)) {
    141       return EFI_INVALID_PARAMETER;
    142     }
    143     if (DataType == EFI_ACPI_DATA_TYPE_NONE) {
    144       //
    145       // Not found
    146       //
    147       break;
    148     }
    149 
    150     //
    151     // Find it, and Check Data
    152     //
    153     if ((DataType == EFI_ACPI_DATA_TYPE_CHILD) &&
    154         ((UINTN)AmlHandle->Buffer < (UINTN)Data)) {
    155       //
    156       // Buffer < Data means current node is next one
    157       //
    158       *Buffer = Data;
    159       return EFI_SUCCESS;
    160     }
    161     //
    162     // Not Child
    163     //
    164     Index ++;
    165   }
    166 
    167   *Buffer = NULL;
    168   return EFI_SUCCESS;
    169 }
    170 
    171 /**
    172   Return the child objects buffer from AML Handle's object child list.
    173 
    174   @param[in]        AmlParentHandle Parent handle.
    175   @param[in]        AmlHandle       The current child handle.
    176   @param[out]       Buffer          On return, points to the next returned child buffer or NULL if there are no
    177                                     child buffer.
    178 
    179   @retval EFI_SUCCESS               Success
    180   @retval EFI_INVALID_PARAMETER     AmlParentHandle does not refer to a valid ACPI object.
    181 **/
    182 EFI_STATUS
    183 AmlGetChildFromObjectChildList (
    184   IN EFI_AML_HANDLE         *AmlParentHandle,
    185   IN EFI_AML_HANDLE         *AmlHandle,
    186   OUT VOID                  **Buffer
    187   )
    188 {
    189   EFI_STATUS          Status;
    190   UINT8               *CurrentBuffer;
    191 
    192   CurrentBuffer = NULL;
    193 
    194   if ((AmlParentHandle->AmlByteEncoding->Attribute & AML_HAS_CHILD_OBJ) == 0) {
    195     //
    196     // No ObjectList
    197     //
    198     *Buffer = NULL;
    199     return EFI_SUCCESS;
    200   }
    201 
    202   //
    203   // Do we need add node within METHOD?
    204   // Yes, just add Object is OK. But we need filter NameString for METHOD invoke.
    205   //
    206 
    207   //
    208   // Now, we get the last node.
    209   //
    210   Status = AmlGetOffsetAfterLastOption (AmlParentHandle, &CurrentBuffer);
    211   if (EFI_ERROR (Status)) {
    212     return EFI_INVALID_PARAMETER;
    213   }
    214 
    215   //
    216   // Go through all the reset buffer.
    217   //
    218   if ((UINTN)AmlHandle->Buffer < (UINTN)CurrentBuffer) {
    219     //
    220     // Buffer < Data means next node is first object
    221     //
    222   } else if ((UINTN)AmlHandle->Buffer + AmlHandle->Size < (UINTN)AmlParentHandle->Buffer + AmlParentHandle->Size) {
    223     //
    224     // There is still more node
    225     //
    226     CurrentBuffer = AmlHandle->Buffer + AmlHandle->Size;
    227   } else {
    228     //
    229     // No more data
    230     //
    231     *Buffer = NULL;
    232     return EFI_SUCCESS;
    233   }
    234 
    235   return AmlGetChildFromObjectBuffer (AmlParentHandle, CurrentBuffer, Buffer);
    236 }
    237 
    238 /**
    239   Return the child ACPI objects from Non-Root Handle.
    240 
    241   @param[in]        AmlParentHandle Parent handle. It is Non-Root Handle.
    242   @param[in]        AmlHandle       The previously returned handle or NULL to start with the first handle.
    243   @param[out]       Buffer          On return, points to the next returned ACPI handle or NULL if there are no
    244                                     child objects.
    245 
    246   @retval EFI_SUCCESS               Success
    247   @retval EFI_INVALID_PARAMETER     ParentHandle is NULL or does not refer to a valid ACPI object.
    248 **/
    249 EFI_STATUS
    250 AmlGetChildFromNonRoot (
    251   IN EFI_AML_HANDLE         *AmlParentHandle,
    252   IN EFI_AML_HANDLE         *AmlHandle,
    253   OUT VOID                  **Buffer
    254   )
    255 {
    256   EFI_STATUS          Status;
    257 
    258   if (AmlHandle == NULL) {
    259     //
    260     // NULL means first one
    261     //
    262     AmlHandle = AmlParentHandle;
    263   }
    264 
    265   //
    266   // 1. Get Option
    267   //
    268   Status = AmlGetChildFromOptionList (AmlParentHandle, AmlHandle, Buffer);
    269   if (EFI_ERROR (Status)) {
    270     return EFI_INVALID_PARAMETER;
    271   }
    272   if (*Buffer != NULL) {
    273     return EFI_SUCCESS;
    274   }
    275 
    276   //
    277   // 2. search ObjectList
    278   //
    279   return AmlGetChildFromObjectChildList (AmlParentHandle, AmlHandle, Buffer);
    280 }
    281