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