]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Acpi/AcpiTableDxe/AmlChild.c
MdeModulePkg:
[mirror_edk2.git] / MdeModulePkg / Universal / Acpi / AcpiTableDxe / AmlChild.c
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 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 if ((AmlParentHandle->AmlByteEncoding->Attribute & AML_HAS_CHILD_OBJ) == 0) {
193 //
194 // No ObjectList
195 //
196 *Buffer = NULL;
197 return EFI_SUCCESS;
198 }
199
200 //
201 // Do we need add node within METHOD?
202 // Yes, just add Object is OK. But we need filter NameString for METHOD invoke.
203 //
204
205 //
206 // Now, we get the last node.
207 //
208 Status = AmlGetOffsetAfterLastOption (AmlParentHandle, &CurrentBuffer);
209 if (EFI_ERROR (Status)) {
210 return EFI_INVALID_PARAMETER;
211 }
212
213 //
214 // Go through all the reset buffer.
215 //
216 if ((UINTN)AmlHandle->Buffer < (UINTN)CurrentBuffer) {
217 //
218 // Buffer < Data means next node is first object
219 //
220 } else if ((UINTN)AmlHandle->Buffer + AmlHandle->Size < (UINTN)AmlParentHandle->Buffer + AmlParentHandle->Size) {
221 //
222 // There is still more node
223 //
224 CurrentBuffer = AmlHandle->Buffer + AmlHandle->Size;
225 } else {
226 //
227 // No more data
228 //
229 *Buffer = NULL;
230 return EFI_SUCCESS;
231 }
232
233 return AmlGetChildFromObjectBuffer (AmlParentHandle, CurrentBuffer, Buffer);
234 }
235
236 /**
237 Return the child ACPI objects from Non-Root Handle.
238
239 @param[in] AmlParentHandle Parent handle. It is Non-Root Handle.
240 @param[in] AmlHandle The previously returned handle or NULL to start with the first handle.
241 @param[out] Buffer On return, points to the next returned ACPI handle or NULL if there are no
242 child objects.
243
244 @retval EFI_SUCCESS Success
245 @retval EFI_INVALID_PARAMETER ParentHandle is NULL or does not refer to a valid ACPI object.
246 **/
247 EFI_STATUS
248 AmlGetChildFromNonRoot (
249 IN EFI_AML_HANDLE *AmlParentHandle,
250 IN EFI_AML_HANDLE *AmlHandle,
251 OUT VOID **Buffer
252 )
253 {
254 EFI_STATUS Status;
255
256 if (AmlHandle == NULL) {
257 //
258 // NULL means first one
259 //
260 AmlHandle = AmlParentHandle;
261 }
262
263 //
264 // 1. Get Option
265 //
266 Status = AmlGetChildFromOptionList (AmlParentHandle, AmlHandle, Buffer);
267 if (EFI_ERROR (Status)) {
268 return EFI_INVALID_PARAMETER;
269 }
270 if (*Buffer != NULL) {
271 return EFI_SUCCESS;
272 }
273
274 //
275 // 2. search ObjectList
276 //
277 return AmlGetChildFromObjectChildList (AmlParentHandle, AmlHandle, Buffer);
278 }