TianoCore EDK2 master
Loading...
Searching...
No Matches
AmlResourceDataApi.c
Go to the documentation of this file.
1
9/* Even though this file has access to the internal Node definition,
10 i.e. AML_ROOT_NODE, AML_OBJECT_NODE, etc. Only the external node
11 handle types should be used, i.e. AML_NODE_HANDLE, AML_ROOT_NODE_HANDLE,
12 etc.
13 Indeed, the functions in the "Api" folder should be implemented only
14 using the "safe" functions available in the "Include" folder. This
15 makes the functions available in the "Api" folder easy to export.
16*/
17#include <AmlNodeDefines.h>
18
19#include <AmlCoreInterface.h>
20#include <AmlInclude.h>
21#include <Api/AmlApiHelper.h>
23
42EFIAPI
44 IN AML_DATA_NODE_HANDLE InterruptRdNode,
45 IN UINT32 Irq
46 )
47{
48 EFI_STATUS Status;
49 UINT32 *FirstInterrupt;
50 UINT8 *QueryBuffer;
51 UINT32 QueryBufferSize;
52
53 if ((InterruptRdNode == NULL) ||
54 (AmlGetNodeType ((AML_NODE_HANDLE)InterruptRdNode) != EAmlNodeData) ||
56 InterruptRdNode,
58 )) ||
60 InterruptRdNode,
62 ACPI_LARGE_EXTENDED_IRQ_DESCRIPTOR_NAME
63 )
64 )))
65 {
66 ASSERT (0);
67 return EFI_INVALID_PARAMETER;
68 }
69
70 QueryBuffer = NULL;
71
72 // Get the size of the InterruptRdNode buffer.
73 Status = AmlGetDataNodeBuffer (
74 InterruptRdNode,
75 NULL,
76 &QueryBufferSize
77 );
78 if (EFI_ERROR (Status)) {
79 ASSERT (0);
80 return Status;
81 }
82
83 // Check the Buffer is large enough.
84 if (QueryBufferSize < sizeof (EFI_ACPI_EXTENDED_INTERRUPT_DESCRIPTOR)) {
85 ASSERT (0);
86 return EFI_INVALID_PARAMETER;
87 }
88
89 // Allocate a buffer to fetch the data.
90 QueryBuffer = AllocatePool (QueryBufferSize);
91 if (QueryBuffer == NULL) {
92 ASSERT (0);
93 return EFI_OUT_OF_RESOURCES;
94 }
95
96 // Get the data.
97 Status = AmlGetDataNodeBuffer (
98 InterruptRdNode,
99 QueryBuffer,
100 &QueryBufferSize
101 );
102 if (EFI_ERROR (Status)) {
103 ASSERT (0);
104 goto error_handler;
105 }
106
107 // Get the address of the first interrupt field.
108 FirstInterrupt =
109 ((EFI_ACPI_EXTENDED_INTERRUPT_DESCRIPTOR *)QueryBuffer)->InterruptNumber;
110
111 *FirstInterrupt = Irq;
112
113 // Update the InterruptRdNode buffer.
114 Status = AmlUpdateDataNode (
115 InterruptRdNode,
117 QueryBuffer,
118 QueryBufferSize
119 );
120 if (EFI_ERROR (Status)) {
121 ASSERT (0);
122 }
123
124error_handler:
125 if (QueryBuffer != NULL) {
126 FreePool (QueryBuffer);
127 }
128
129 return Status;
130}
131
157EFIAPI
159 IN AML_DATA_NODE_HANDLE InterruptRdNode,
160 IN BOOLEAN ResourceConsumer,
161 IN BOOLEAN EdgeTriggered,
162 IN BOOLEAN ActiveLow,
163 IN BOOLEAN Shared,
164 IN UINT32 *IrqList,
165 IN UINT8 IrqCount
166 )
167{
168 EFI_STATUS Status;
169
171 UINT32 *FirstInterrupt;
172 UINT8 *UpdateBuffer;
173 UINT16 UpdateBufferSize;
174
175 if ((InterruptRdNode == NULL) ||
176 (AmlGetNodeType ((AML_NODE_HANDLE)InterruptRdNode) != EAmlNodeData) ||
178 InterruptRdNode,
180 )) ||
182 InterruptRdNode,
184 ACPI_LARGE_EXTENDED_IRQ_DESCRIPTOR_NAME
185 )
186 )) ||
187 (IrqList == NULL) ||
188 (IrqCount == 0))
189 {
190 ASSERT (0);
191 return EFI_INVALID_PARAMETER;
192 }
193
194 UpdateBuffer = NULL;
195 UpdateBufferSize = sizeof (EFI_ACPI_EXTENDED_INTERRUPT_DESCRIPTOR) +
196 ((IrqCount - 1) * sizeof (UINT32));
197
198 // Allocate a buffer to update the data.
199 UpdateBuffer = AllocatePool (UpdateBufferSize);
200 if (UpdateBuffer == NULL) {
201 ASSERT (0);
202 return EFI_OUT_OF_RESOURCES;
203 }
204
205 // Update the Resource Data information (structure size, interrupt count).
206 RdInterrupt = (EFI_ACPI_EXTENDED_INTERRUPT_DESCRIPTOR *)UpdateBuffer;
207 RdInterrupt->Header.Header.Byte =
208 AML_RD_BUILD_LARGE_DESC_ID (ACPI_LARGE_EXTENDED_IRQ_DESCRIPTOR_NAME);
209 RdInterrupt->Header.Length =
210 UpdateBufferSize - sizeof (ACPI_LARGE_RESOURCE_HEADER);
211 RdInterrupt->InterruptTableLength = IrqCount;
212 RdInterrupt->InterruptVectorFlags = (ResourceConsumer ? BIT0 : 0) |
213 (EdgeTriggered ? BIT1 : 0) |
214 (ActiveLow ? BIT2 : 0) |
215 (Shared ? BIT3 : 0);
216
217 // Get the address of the first interrupt field.
218 FirstInterrupt =
219 ((EFI_ACPI_EXTENDED_INTERRUPT_DESCRIPTOR *)UpdateBuffer)->InterruptNumber;
220
221 // Copy the input list of interrupts.
222 CopyMem (FirstInterrupt, IrqList, (sizeof (UINT32) * IrqCount));
223
224 // Update the InterruptRdNode buffer.
225 Status = AmlUpdateDataNode (
226 InterruptRdNode,
228 UpdateBuffer,
229 UpdateBufferSize
230 );
231 if (EFI_ERROR (Status)) {
232 ASSERT (0);
233 }
234
235 // Cleanup
236 FreePool (UpdateBuffer);
237
238 return Status;
239}
240
253EFIAPI
255 IN AML_DATA_NODE_HANDLE QWordRdNode,
256 IN UINT64 BaseAddress,
257 IN UINT64 BaseAddressLength
258 )
259{
260 EFI_STATUS Status;
262
263 UINT8 *QueryBuffer;
264 UINT32 QueryBufferSize;
265
266 if ((QWordRdNode == NULL) ||
267 (AmlGetNodeType ((AML_NODE_HANDLE)QWordRdNode) != EAmlNodeData) ||
270 QWordRdNode,
272 ACPI_LARGE_QWORD_ADDRESS_SPACE_DESCRIPTOR_NAME
273 )
274 )))
275 {
276 ASSERT (0);
277 return EFI_INVALID_PARAMETER;
278 }
279
280 // Get the size of the QWordRdNode's buffer.
281 Status = AmlGetDataNodeBuffer (
282 QWordRdNode,
283 NULL,
284 &QueryBufferSize
285 );
286 if (EFI_ERROR (Status)) {
287 ASSERT (0);
288 return Status;
289 }
290
291 // Allocate a buffer to fetch the data.
292 QueryBuffer = AllocatePool (QueryBufferSize);
293 if (QueryBuffer == NULL) {
294 ASSERT (0);
295 return EFI_OUT_OF_RESOURCES;
296 }
297
298 // Get the data.
299 Status = AmlGetDataNodeBuffer (
300 QWordRdNode,
301 QueryBuffer,
302 &QueryBufferSize
303 );
304 if (EFI_ERROR (Status)) {
305 ASSERT (0);
306 goto error_handler;
307 }
308
309 RdQWord = (EFI_ACPI_QWORD_ADDRESS_SPACE_DESCRIPTOR *)QueryBuffer;
310
311 // Update the Base Address and Length.
312 RdQWord->AddrRangeMin = BaseAddress;
313 RdQWord->AddrRangeMax = BaseAddress + BaseAddressLength - 1;
314 RdQWord->AddrLen = BaseAddressLength;
315
316 // Update Base Address Resource Data node.
317 Status = AmlUpdateDataNode (
318 QWordRdNode,
320 QueryBuffer,
321 QueryBufferSize
322 );
323 if (EFI_ERROR (Status)) {
324 ASSERT (0);
325 }
326
327error_handler:
328 if (QueryBuffer != NULL) {
329 FreePool (QueryBuffer);
330 }
331
332 return Status;
333}
PACKED struct @103 EFI_ACPI_EXTENDED_INTERRUPT_DESCRIPTOR
PACKED struct @100 EFI_ACPI_QWORD_ADDRESS_SPACE_DESCRIPTOR
BOOLEAN EFIAPI AmlNodeHasDataType(IN AML_DATA_NODE_HANDLE DataNode, IN EAML_NODE_DATA_TYPE DataType)
Definition: AmlApiHelper.c:168
BOOLEAN EFIAPI AmlNodeHasRdDataType(IN AML_DATA_NODE_HANDLE RdNode, IN AML_RD_HEADER RdDataType)
Definition: AmlApiHelper.c:202
void * AML_DATA_NODE_HANDLE
Definition: AmlLib.h:59
void * AML_NODE_HANDLE
Definition: AmlLib.h:47
EFI_STATUS EFIAPI AmlUpdateRdInterruptEx(IN AML_DATA_NODE_HANDLE InterruptRdNode, IN BOOLEAN ResourceConsumer, IN BOOLEAN EdgeTriggered, IN BOOLEAN ActiveLow, IN BOOLEAN Shared, IN UINT32 *IrqList, IN UINT8 IrqCount)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define IN
Definition: Base.h:279
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
EFI_STATUS EFIAPI AmlGetDataNodeBuffer(IN AML_DATA_NODE_HANDLE DataNode, OUT UINT8 *Buffer OPTIONAL, IN OUT UINT32 *BufferSize)
EFI_STATUS EFIAPI AmlUpdateDataNode(IN AML_DATA_NODE_HANDLE DataNode, IN EAML_NODE_DATA_TYPE DataType, IN UINT8 *Buffer, IN UINT32 Size)
EAML_NODE_TYPE EFIAPI AmlGetNodeType(IN AML_NODE_HANDLE Node)
#define AML_RD_BUILD_LARGE_DESC_ID(Id)
@ EAmlNodeData
Definition: AmlDefines.h:176
@ EAmlNodeDataTypeResourceData
Resource data element.
Definition: AmlDefines.h:44
EFI_STATUS EFIAPI AmlUpdateRdQWord(IN AML_DATA_NODE_HANDLE QWordRdNode, IN UINT64 BaseAddress, IN UINT64 BaseAddressLength)
EFI_STATUS EFIAPI AmlUpdateRdInterrupt(IN AML_DATA_NODE_HANDLE InterruptRdNode, IN UINT32 Irq)