]> git.proxmox.com Git - mirror_edk2.git/blob - DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtUtility.h
DynamicTables: Fix DT PCI interrupt flags parsing
[mirror_edk2.git] / DynamicTablesPkg / Library / FdtHwInfoParserLib / FdtUtility.h
1 /** @file
2 Flattened device tree utility.
3
4 Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 @par Reference(s):
8 - Device tree Specification - Release v0.3
9 - linux/Documentation/devicetree/bindings/interrupt-controller/arm%2Cgic.yaml
10 - linux//Documentation/devicetree/bindings/interrupt-controller/arm%2Cgic.yaml
11 **/
12
13 #ifndef FDT_UTILITY_H_
14 #define FDT_UTILITY_H_
15
16 /** Get the offset of an address in a "reg" Device Tree property.
17
18 In a Device Tree, the "reg" property stores address/size couples.
19 They are stored on N 32-bits cells.
20 Based on the value of the #address-cells, the #size-cells and the
21 index in the "reg" property, compute the number of 32-bits cells
22 to skip.
23
24 @param [in] Index Index in the reg property.
25 @param [in] AddrCells Number of cells used to store an address.
26 @param [in] SizeCells Number of cells used to store the size of
27 an address.
28
29 @retval Number of 32-bits cells to skip to access the address.
30 */
31 #define GET_DT_REG_ADDRESS_OFFSET(Index, AddrCells, SizeCells) ( \
32 (Index) * ((AddrCells) + (SizeCells)) \
33 )
34
35 /** Get the offset of an address size in a "reg" Device Tree property.
36
37 In a Device Tree, the "reg" property stores address/size couples.
38 They are stored on N 32-bits cells.
39 Based on the value of the #address-cells, the #size-cells and the
40 index in the "reg" property, compute the number of 32-bits cells
41 to skip.
42
43 @param [in] Index Index in the reg property.
44 @param [in] AddrCells Number of cells used to store an address.
45 @param [in] SizeCells Number of cells used to store the size of
46 an address.
47
48 @retval Number of 32-bits cells to skip to access the address size.
49 */
50 #define GET_DT_REG_SIZE_OFFSET(Index, AddrCells, SizeCells) ( \
51 GET_DT_REG_ADDRESS_OFFSET ((Index), (AddrCells), (SizeCells)) + \
52 (SizeCells) \
53 )
54
55 /// Maximum string length for compatible names.
56 #define COMPATIBLE_STR_LEN (32U)
57
58 /// Interrupt macros
59 #define PPI_OFFSET (16U)
60 #define SPI_OFFSET (32U)
61 #define DT_PPI_IRQ (1U)
62 #define DT_SPI_IRQ (0U)
63 #define DT_IRQ_IS_EDGE_TRIGGERED(x) ((((x) & (BIT0 | BIT1)) != 0))
64 #define DT_IRQ_IS_ACTIVE_LOW(x) ((((x) & (BIT1 | BIT3)) != 0))
65 #define IRQ_TYPE_OFFSET (0U)
66 #define IRQ_NUMBER_OFFSET (1U)
67 #define IRQ_FLAGS_OFFSET (2U)
68
69 /** Get the interrupt Id of an interrupt described in a fdt.
70
71 Data must describe a GIC interrupt. A GIC interrupt is on at least
72 3 UINT32 cells.
73 This function DOES NOT SUPPORT extended SPI range and extended PPI range.
74
75 @param [in] Data Pointer to the first cell of an "interrupts" property.
76
77 @retval The interrupt id.
78 **/
79 UINT32
80 EFIAPI
81 FdtGetInterruptId (
82 UINT32 CONST *Data
83 );
84
85 /** Get the ACPI interrupt flags of an interrupt described in a fdt.
86
87 Data must describe a GIC interrupt. A GIC interrupt is on at least
88 3 UINT32 cells.
89
90 @param [in] Data Pointer to the first cell of an "interrupts" property.
91
92 @retval The interrupt flags (for ACPI).
93 **/
94 UINT32
95 EFIAPI
96 FdtGetInterruptFlags (
97 UINT32 CONST *Data
98 );
99
100 /** A structure describing a compatibility string.
101 */
102 typedef struct CompatStr {
103 CONST CHAR8 CompatStr[COMPATIBLE_STR_LEN];
104 } COMPATIBILITY_STR;
105
106 /** Structure containing a list of compatible names and their count.
107 */
108 typedef struct CompatibilityInfo {
109 /// Count of entries in the NAME_TABLE.
110 UINT32 Count;
111
112 /// Pointer to a table storing the names.
113 CONST COMPATIBILITY_STR *CompatTable;
114 } COMPATIBILITY_INFO;
115
116 /** Operate a check on a Device Tree node.
117
118 @param [in] Fdt Pointer to a Flattened Device Tree.
119 @param [in] NodeOffset Offset of the node to compare input string.
120 @param [in] Context Context to operate the check on the node.
121
122 @retval True The check is correct.
123 @retval FALSE Otherwise, or error.
124 **/
125 typedef
126 BOOLEAN
127 (EFIAPI *NODE_CHECKER_FUNC)(
128 IN CONST VOID *Fdt,
129 IN INT32 NodeOffset,
130 IN CONST VOID *Context
131 );
132
133 /** Iterate through the list of strings in the Context,
134 and check whether at least one string is matching the
135 "compatible" property of the node.
136
137 @param [in] Fdt Pointer to a Flattened Device Tree.
138 @param [in] Node Offset of the node to operate the check on.
139 @param [in] CompatInfo COMPATIBILITY_INFO containing the list of compatible
140 strings to compare with the "compatible" property
141 of the node.
142
143 @retval TRUE At least one string matched, the node is compatible.
144 @retval FALSE Otherwise, or error.
145 **/
146 BOOLEAN
147 EFIAPI
148 FdtNodeIsCompatible (
149 IN CONST VOID *Fdt,
150 IN INT32 Node,
151 IN CONST VOID *CompatInfo
152 );
153
154 /** Check whether a node has a property.
155
156 @param [in] Fdt Pointer to a Flattened Device Tree.
157 @param [in] Node Offset of the node to operate the check on.
158 @param [in] PropertyName Name of the property to search.
159 This is a NULL terminated string.
160
161 @retval True The node has the property.
162 @retval FALSE Otherwise, or error.
163 **/
164 BOOLEAN
165 EFIAPI
166 FdtNodeHasProperty (
167 IN CONST VOID *Fdt,
168 IN INT32 Node,
169 IN CONST VOID *PropertyName
170 );
171
172 /** Get the next node in a branch having a matching name.
173
174 The Device tree is traversed in a depth-first search, starting from Node.
175 The input Node is skipped.
176
177 @param [in] Fdt Pointer to a Flattened Device Tree.
178 @param [in] FdtBranch Only search in the sub-nodes of this branch.
179 Write (-1) to search the whole tree.
180 @param [in] NodeName The node name to search.
181 This is a NULL terminated string.
182 @param [in, out] Node At entry: Node offset to start the search.
183 This first node is skipped.
184 Write (-1) to search the whole tree.
185 At exit: If success, contains the offset of
186 the next node in the branch
187 having a matching name.
188
189 @retval EFI_SUCCESS The function completed successfully.
190 @retval EFI_ABORTED An error occurred.
191 @retval EFI_INVALID_PARAMETER Invalid parameter.
192 @retval EFI_NOT_FOUND No matching node found.
193 **/
194 EFI_STATUS
195 EFIAPI
196 FdtGetNextNamedNodeInBranch (
197 IN CONST VOID *Fdt,
198 IN INT32 FdtBranch,
199 IN CONST CHAR8 *NodeName,
200 IN OUT INT32 *Node
201 );
202
203 /** Get the next node in a branch with at least one compatible property.
204
205 The Device tree is traversed in a depth-first search, starting from Node.
206 The input Node is skipped.
207
208 @param [in] Fdt Pointer to a Flattened Device Tree.
209 @param [in] FdtBranch Only search in the sub-nodes of this branch.
210 Write (-1) to search the whole tree.
211 @param [in] CompatNamesInfo Table of compatible strings to compare with
212 the compatible property of the node.
213 @param [in, out] Node At entry: Node offset to start the search.
214 This first node is skipped.
215 Write (-1) to search the whole tree.
216 At exit: If success, contains the offset of
217 the next node in the branch
218 being compatible.
219
220 @retval EFI_SUCCESS The function completed successfully.
221 @retval EFI_ABORTED An error occurred.
222 @retval EFI_INVALID_PARAMETER Invalid parameter.
223 @retval EFI_NOT_FOUND No matching node found.
224 **/
225 EFI_STATUS
226 EFIAPI
227 FdtGetNextCompatNodeInBranch (
228 IN CONST VOID *Fdt,
229 IN INT32 FdtBranch,
230 IN CONST COMPATIBILITY_INFO *CompatNamesInfo,
231 IN OUT INT32 *Node
232 );
233
234 /** Get the next node in a branch having the PropName property.
235
236 The Device tree is traversed in a depth-first search, starting from Node.
237 The input Node is skipped.
238
239 @param [in] Fdt Pointer to a Flattened Device Tree.
240 @param [in] FdtBranch Only search in the sub-nodes of this branch.
241 Write (-1) to search the whole tree.
242 @param [in] PropName Name of the property to search.
243 This is a NULL terminated string.
244 @param [in, out] Node At entry: Node offset to start the search.
245 This first node is skipped.
246 Write (-1) to search the whole tree.
247 At exit: If success, contains the offset of
248 the next node in the branch
249 being compatible.
250
251 @retval EFI_SUCCESS The function completed successfully.
252 @retval EFI_ABORTED An error occurred.
253 @retval EFI_INVALID_PARAMETER Invalid parameter.
254 @retval EFI_NOT_FOUND No matching node found.
255 **/
256 EFI_STATUS
257 EFIAPI
258 FdtGetNextPropNodeInBranch (
259 IN CONST VOID *Fdt,
260 IN INT32 FdtBranch,
261 IN CONST CHAR8 *PropName,
262 IN OUT INT32 *Node
263 );
264
265 /** Count the number of nodes in a branch with the input name.
266
267 @param [in] Fdt Pointer to a Flattened Device Tree.
268 @param [in] FdtBranch Only search in the sub-nodes of this branch.
269 Write (-1) to search the whole tree.
270 @param [in] NodeName Node name to search.
271 This is a NULL terminated string.
272 @param [out] NodeCount If success, contains the count of nodes
273 fulfilling the condition.
274 Can be 0.
275
276 @retval EFI_SUCCESS The function completed successfully.
277 @retval EFI_ABORTED An error occurred.
278 @retval EFI_INVALID_PARAMETER Invalid parameter.
279 **/
280 EFI_STATUS
281 EFIAPI
282 FdtCountNamedNodeInBranch (
283 IN CONST VOID *Fdt,
284 IN INT32 FdtBranch,
285 IN CONST CHAR8 *NodeName,
286 OUT UINT32 *NodeCount
287 );
288
289 /** Count the number of nodes in a branch with at least
290 one compatible property.
291
292 @param [in] Fdt Pointer to a Flattened Device Tree.
293 @param [in] FdtBranch Only search in the sub-nodes of this branch.
294 Write (-1) to search the whole tree.
295 @param [in] CompatibleTable Table of compatible strings to
296 compare with the compatible property
297 of the node.
298 @param [out] NodeCount If success, contains the count of nodes
299 fulfilling the condition.
300 Can be 0.
301
302 @retval EFI_SUCCESS The function completed successfully.
303 @retval EFI_ABORTED An error occurred.
304 @retval EFI_INVALID_PARAMETER Invalid parameter.
305 **/
306 EFI_STATUS
307 EFIAPI
308 FdtCountCompatNodeInBranch (
309 IN CONST VOID *Fdt,
310 IN INT32 FdtBranch,
311 IN CONST COMPATIBILITY_INFO *CompatNamesInfo,
312 OUT UINT32 *NodeCount
313 );
314
315 /** Count the number of nodes in a branch having the PropName property.
316
317 @param [in] Fdt Pointer to a Flattened Device Tree.
318 @param [in] FdtBranch Only search in the sub-nodes of this branch.
319 Write (-1) to search the whole tree.
320 @param [in] PropName Name of the property to search.
321 This is a NULL terminated string.
322 @param [out] NodeCount If success, contains the count of nodes
323 fulfilling the condition.
324 Can be 0.
325
326 @retval EFI_SUCCESS The function completed successfully.
327 @retval EFI_ABORTED An error occurred.
328 @retval EFI_INVALID_PARAMETER Invalid parameter.
329 **/
330 EFI_STATUS
331 EFIAPI
332 FdtCountPropNodeInBranch (
333 IN CONST VOID *Fdt,
334 IN INT32 FdtBranch,
335 IN CONST CHAR8 *PropName,
336 OUT UINT32 *NodeCount
337 );
338
339 /** Get the interrupt-controller node handling the interrupts of
340 the input node.
341
342 To do this, recursively search a node with either the "interrupt-controller"
343 or the "interrupt-parent" property in the parents of Node.
344
345 Devicetree Specification, Release v0.3,
346 2.4.1 "Properties for Interrupt Generating Devices":
347 Because the hierarchy of the nodes in the interrupt tree
348 might not match the devicetree, the interrupt-parent
349 property is available to make the definition of an
350 interrupt parent explicit. The value is the phandle to the
351 interrupt parent. If this property is missing from a
352 device, its interrupt parent is assumed to be its devicetree
353 parent.
354
355 @param [in] Fdt Pointer to a Flattened Device Tree.
356 @param [in] Node Offset of the node to start the search.
357 @param [out] IntcNode If success, contains the offset of the
358 interrupt-controller node.
359
360 @retval EFI_SUCCESS The function completed successfully.
361 @retval EFI_NOT_FOUND No interrupt-controller node found.
362 @retval EFI_ABORTED An error occurred.
363 @retval EFI_INVALID_PARAMETER Invalid parameter.
364 **/
365 EFI_STATUS
366 EFIAPI
367 FdtGetIntcParentNode (
368 IN CONST VOID *Fdt,
369 IN INT32 Node,
370 OUT INT32 *IntcNode
371 );
372
373 /** Get the "interrupt-cells" property value of the node.
374
375 The "interrupts" property requires to know the number of cells used
376 to encode an interrupt. This information is stored in the
377 interrupt-controller of the input Node.
378
379 @param [in] Fdt Pointer to a Flattened Device Tree (Fdt).
380 @param [in] IntcNode Offset of an interrupt-controller node.
381 @param [out] IntCells If success, contains the "interrupt-cells"
382 property of the IntcNode.
383
384 @retval EFI_SUCCESS The function completed successfully.
385 @retval EFI_INVALID_PARAMETER Invalid parameter.
386 @retval EFI_UNSUPPORTED Unsupported.
387 **/
388 EFI_STATUS
389 EFIAPI
390 FdtGetInterruptCellsInfo (
391 IN CONST VOID *Fdt,
392 IN INT32 IntcNode,
393 OUT INT32 *InterruptCells
394 );
395
396 /** Get the "#address-cells" and/or "#size-cells" property of the node.
397
398 According to the Device Tree specification, s2.3.5 "#address-cells and
399 #size-cells":
400 "If missing, a client program should assume a default value of 2 for
401 #address-cells, and a value of 1 for #size-cells."
402
403 @param [in] Fdt Pointer to a Flattened Device Tree.
404 @param [in] Node Offset of the node having to get the
405 "#address-cells" and "#size-cells"
406 properties from.
407 @param [out] AddressCells If success, number of address-cells.
408 If the property is not available,
409 default value is 2.
410 @param [out] SizeCells If success, number of size-cells.
411 If the property is not available,
412 default value is 1.
413
414 @retval EFI_SUCCESS The function completed successfully.
415 @retval EFI_ABORTED An error occurred.
416 @retval EFI_INVALID_PARAMETER Invalid parameter.
417 **/
418 EFI_STATUS
419 EFIAPI
420 FdtGetAddressInfo (
421 IN CONST VOID *Fdt,
422 IN INT32 Node,
423 OUT INT32 *AddressCells, OPTIONAL
424 OUT INT32 *SizeCells OPTIONAL
425 );
426
427 /** Get the "#address-cells" and/or "#size-cells" property of the parent node.
428
429 According to the Device Tree specification, s2.3.5 "#address-cells and
430 #size-cells":
431 "If missing, a client program should assume a default value of 2 for
432 #address-cells, and a value of 1 for #size-cells."
433
434 @param [in] Fdt Pointer to a Flattened Device Tree.
435 @param [in] Node Offset of the node having to get the
436 "#address-cells" and "#size-cells"
437 properties from its parent.
438 @param [out] AddressCells If success, number of address-cells.
439 If the property is not available,
440 default value is 2.
441 @param [out] SizeCells If success, number of size-cells.
442 If the property is not available,
443 default value is 1.
444
445 @retval EFI_SUCCESS The function completed successfully.
446 @retval EFI_ABORTED An error occurred.
447 @retval EFI_INVALID_PARAMETER Invalid parameter.
448 **/
449 EFI_STATUS
450 EFIAPI
451 FdtGetParentAddressInfo (
452 IN CONST VOID *Fdt,
453 IN INT32 Node,
454 OUT INT32 *AddressCells, OPTIONAL
455 OUT INT32 *SizeCells OPTIONAL
456 );
457
458 #endif // FDT_UTILITY_H_