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