/** @file | |
Flattened device tree utility. | |
Copyright (c) 2021, ARM Limited. All rights reserved.<BR> | |
SPDX-License-Identifier: BSD-2-Clause-Patent | |
@par Reference(s): | |
- Device tree Specification - Release v0.3 | |
- linux/Documentation/devicetree/bindings/interrupt-controller/arm%2Cgic.yaml | |
- linux//Documentation/devicetree/bindings/interrupt-controller/arm%2Cgic.yaml | |
**/ | |
#ifndef FDT_UTILITY_H_ | |
#define FDT_UTILITY_H_ | |
/** Get the offset of an address in a "reg" Device Tree property. | |
In a Device Tree, the "reg" property stores address/size couples. | |
They are stored on N 32-bits cells. | |
Based on the value of the #address-cells, the #size-cells and the | |
index in the "reg" property, compute the number of 32-bits cells | |
to skip. | |
@param [in] Index Index in the reg property. | |
@param [in] AddrCells Number of cells used to store an address. | |
@param [in] SizeCells Number of cells used to store the size of | |
an address. | |
@retval Number of 32-bits cells to skip to access the address. | |
*/ | |
#define GET_DT_REG_ADDRESS_OFFSET(Index, AddrCells, SizeCells) ( \ | |
(Index) * ((AddrCells) + (SizeCells)) \ | |
) | |
/** Get the offset of an address size in a "reg" Device Tree property. | |
In a Device Tree, the "reg" property stores address/size couples. | |
They are stored on N 32-bits cells. | |
Based on the value of the #address-cells, the #size-cells and the | |
index in the "reg" property, compute the number of 32-bits cells | |
to skip. | |
@param [in] Index Index in the reg property. | |
@param [in] AddrCells Number of cells used to store an address. | |
@param [in] SizeCells Number of cells used to store the size of | |
an address. | |
@retval Number of 32-bits cells to skip to access the address size. | |
*/ | |
#define GET_DT_REG_SIZE_OFFSET(Index, AddrCells, SizeCells) ( \ | |
GET_DT_REG_ADDRESS_OFFSET ((Index), (AddrCells), (SizeCells)) + \ | |
(SizeCells) \ | |
) | |
/// Maximum string length for compatible names. | |
#define COMPATIBLE_STR_LEN (32U) | |
/// Interrupt macros | |
#define PPI_OFFSET (16U) | |
#define SPI_OFFSET (32U) | |
#define DT_PPI_IRQ (1U) | |
#define DT_SPI_IRQ (0U) | |
#define DT_IRQ_IS_EDGE_TRIGGERED(x) ((((x) & (BIT0 | BIT1)) != 0)) | |
#define DT_IRQ_IS_ACTIVE_LOW(x) ((((x) & (BIT1 | BIT3)) != 0)) | |
#define IRQ_TYPE_OFFSET (0U) | |
#define IRQ_NUMBER_OFFSET (1U) | |
#define IRQ_FLAGS_OFFSET (2U) | |
/** Get the interrupt Id of an interrupt described in a fdt. | |
Data must describe a GIC interrupt. A GIC interrupt is on at least | |
3 UINT32 cells. | |
This function DOES NOT SUPPORT extended SPI range and extended PPI range. | |
@param [in] Data Pointer to the first cell of an "interrupts" property. | |
@retval The interrupt id. | |
**/ | |
UINT32 | |
EFIAPI | |
FdtGetInterruptId ( | |
UINT32 CONST *Data | |
); | |
/** Get the ACPI interrupt flags of an interrupt described in a fdt. | |
Data must describe a GIC interrupt. A GIC interrupt is on at least | |
3 UINT32 cells. | |
@param [in] Data Pointer to the first cell of an "interrupts" property. | |
@retval The interrupt flags (for ACPI). | |
**/ | |
UINT32 | |
EFIAPI | |
FdtGetInterruptFlags ( | |
UINT32 CONST *Data | |
); | |
/** A structure describing a compatibility string. | |
*/ | |
typedef struct CompatStr { | |
CONST CHAR8 CompatStr[COMPATIBLE_STR_LEN]; | |
} COMPATIBILITY_STR; | |
/** Structure containing a list of compatible names and their count. | |
*/ | |
typedef struct CompatibilityInfo { | |
/// Count of entries in the NAME_TABLE. | |
UINT32 Count; | |
/// Pointer to a table storing the names. | |
CONST COMPATIBILITY_STR *CompatTable; | |
} COMPATIBILITY_INFO; | |
/** Operate a check on a Device Tree node. | |
@param [in] Fdt Pointer to a Flattened Device Tree. | |
@param [in] NodeOffset Offset of the node to compare input string. | |
@param [in] Context Context to operate the check on the node. | |
@retval True The check is correct. | |
@retval FALSE Otherwise, or error. | |
**/ | |
typedef | |
BOOLEAN | |
(EFIAPI *NODE_CHECKER_FUNC)( | |
IN CONST VOID *Fdt, | |
IN INT32 NodeOffset, | |
IN CONST VOID *Context | |
); | |
/** Iterate through the list of strings in the Context, | |
and check whether at least one string is matching the | |
"compatible" property of the node. | |
@param [in] Fdt Pointer to a Flattened Device Tree. | |
@param [in] Node Offset of the node to operate the check on. | |
@param [in] CompatInfo COMPATIBILITY_INFO containing the list of compatible | |
strings to compare with the "compatible" property | |
of the node. | |
@retval TRUE At least one string matched, the node is compatible. | |
@retval FALSE Otherwise, or error. | |
**/ | |
BOOLEAN | |
EFIAPI | |
FdtNodeIsCompatible ( | |
IN CONST VOID *Fdt, | |
IN INT32 Node, | |
IN CONST VOID *CompatInfo | |
); | |
/** Check whether a node has a property. | |
@param [in] Fdt Pointer to a Flattened Device Tree. | |
@param [in] Node Offset of the node to operate the check on. | |
@param [in] PropertyName Name of the property to search. | |
This is a NULL terminated string. | |
@retval True The node has the property. | |
@retval FALSE Otherwise, or error. | |
**/ | |
BOOLEAN | |
EFIAPI | |
FdtNodeHasProperty ( | |
IN CONST VOID *Fdt, | |
IN INT32 Node, | |
IN CONST VOID *PropertyName | |
); | |
/** Get the next node in a branch having a matching name. | |
The Device tree is traversed in a depth-first search, starting from Node. | |
The input Node is skipped. | |
@param [in] Fdt Pointer to a Flattened Device Tree. | |
@param [in] FdtBranch Only search in the sub-nodes of this branch. | |
Write (-1) to search the whole tree. | |
@param [in] NodeName The node name to search. | |
This is a NULL terminated string. | |
@param [in, out] Node At entry: Node offset to start the search. | |
This first node is skipped. | |
Write (-1) to search the whole tree. | |
At exit: If success, contains the offset of | |
the next node in the branch | |
having a matching name. | |
@retval EFI_SUCCESS The function completed successfully. | |
@retval EFI_ABORTED An error occurred. | |
@retval EFI_INVALID_PARAMETER Invalid parameter. | |
@retval EFI_NOT_FOUND No matching node found. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
FdtGetNextNamedNodeInBranch ( | |
IN CONST VOID *Fdt, | |
IN INT32 FdtBranch, | |
IN CONST CHAR8 *NodeName, | |
IN OUT INT32 *Node | |
); | |
/** Get the next node in a branch with at least one compatible property. | |
The Device tree is traversed in a depth-first search, starting from Node. | |
The input Node is skipped. | |
@param [in] Fdt Pointer to a Flattened Device Tree. | |
@param [in] FdtBranch Only search in the sub-nodes of this branch. | |
Write (-1) to search the whole tree. | |
@param [in] CompatNamesInfo Table of compatible strings to compare with | |
the compatible property of the node. | |
@param [in, out] Node At entry: Node offset to start the search. | |
This first node is skipped. | |
Write (-1) to search the whole tree. | |
At exit: If success, contains the offset of | |
the next node in the branch | |
being compatible. | |
@retval EFI_SUCCESS The function completed successfully. | |
@retval EFI_ABORTED An error occurred. | |
@retval EFI_INVALID_PARAMETER Invalid parameter. | |
@retval EFI_NOT_FOUND No matching node found. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
FdtGetNextCompatNodeInBranch ( | |
IN CONST VOID *Fdt, | |
IN INT32 FdtBranch, | |
IN CONST COMPATIBILITY_INFO *CompatNamesInfo, | |
IN OUT INT32 *Node | |
); | |
/** Get the next node in a branch having the PropName property. | |
The Device tree is traversed in a depth-first search, starting from Node. | |
The input Node is skipped. | |
@param [in] Fdt Pointer to a Flattened Device Tree. | |
@param [in] FdtBranch Only search in the sub-nodes of this branch. | |
Write (-1) to search the whole tree. | |
@param [in] PropName Name of the property to search. | |
This is a NULL terminated string. | |
@param [in, out] Node At entry: Node offset to start the search. | |
This first node is skipped. | |
Write (-1) to search the whole tree. | |
At exit: If success, contains the offset of | |
the next node in the branch | |
being compatible. | |
@retval EFI_SUCCESS The function completed successfully. | |
@retval EFI_ABORTED An error occurred. | |
@retval EFI_INVALID_PARAMETER Invalid parameter. | |
@retval EFI_NOT_FOUND No matching node found. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
FdtGetNextPropNodeInBranch ( | |
IN CONST VOID *Fdt, | |
IN INT32 FdtBranch, | |
IN CONST CHAR8 *PropName, | |
IN OUT INT32 *Node | |
); | |
/** Count the number of nodes in a branch with the input name. | |
@param [in] Fdt Pointer to a Flattened Device Tree. | |
@param [in] FdtBranch Only search in the sub-nodes of this branch. | |
Write (-1) to search the whole tree. | |
@param [in] NodeName Node name to search. | |
This is a NULL terminated string. | |
@param [out] NodeCount If success, contains the count of nodes | |
fulfilling the condition. | |
Can be 0. | |
@retval EFI_SUCCESS The function completed successfully. | |
@retval EFI_ABORTED An error occurred. | |
@retval EFI_INVALID_PARAMETER Invalid parameter. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
FdtCountNamedNodeInBranch ( | |
IN CONST VOID *Fdt, | |
IN INT32 FdtBranch, | |
IN CONST CHAR8 *NodeName, | |
OUT UINT32 *NodeCount | |
); | |
/** Count the number of nodes in a branch with at least | |
one compatible property. | |
@param [in] Fdt Pointer to a Flattened Device Tree. | |
@param [in] FdtBranch Only search in the sub-nodes of this branch. | |
Write (-1) to search the whole tree. | |
@param [in] CompatibleTable Table of compatible strings to | |
compare with the compatible property | |
of the node. | |
@param [out] NodeCount If success, contains the count of nodes | |
fulfilling the condition. | |
Can be 0. | |
@retval EFI_SUCCESS The function completed successfully. | |
@retval EFI_ABORTED An error occurred. | |
@retval EFI_INVALID_PARAMETER Invalid parameter. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
FdtCountCompatNodeInBranch ( | |
IN CONST VOID *Fdt, | |
IN INT32 FdtBranch, | |
IN CONST COMPATIBILITY_INFO *CompatNamesInfo, | |
OUT UINT32 *NodeCount | |
); | |
/** Count the number of nodes in a branch having the PropName property. | |
@param [in] Fdt Pointer to a Flattened Device Tree. | |
@param [in] FdtBranch Only search in the sub-nodes of this branch. | |
Write (-1) to search the whole tree. | |
@param [in] PropName Name of the property to search. | |
This is a NULL terminated string. | |
@param [out] NodeCount If success, contains the count of nodes | |
fulfilling the condition. | |
Can be 0. | |
@retval EFI_SUCCESS The function completed successfully. | |
@retval EFI_ABORTED An error occurred. | |
@retval EFI_INVALID_PARAMETER Invalid parameter. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
FdtCountPropNodeInBranch ( | |
IN CONST VOID *Fdt, | |
IN INT32 FdtBranch, | |
IN CONST CHAR8 *PropName, | |
OUT UINT32 *NodeCount | |
); | |
/** Get the interrupt-controller node handling the interrupts of | |
the input node. | |
To do this, recursively search a node with either the "interrupt-controller" | |
or the "interrupt-parent" property in the parents of Node. | |
Devicetree Specification, Release v0.3, | |
2.4.1 "Properties for Interrupt Generating Devices": | |
Because the hierarchy of the nodes in the interrupt tree | |
might not match the devicetree, the interrupt-parent | |
property is available to make the definition of an | |
interrupt parent explicit. The value is the phandle to the | |
interrupt parent. If this property is missing from a | |
device, its interrupt parent is assumed to be its devicetree | |
parent. | |
@param [in] Fdt Pointer to a Flattened Device Tree. | |
@param [in] Node Offset of the node to start the search. | |
@param [out] IntcNode If success, contains the offset of the | |
interrupt-controller node. | |
@retval EFI_SUCCESS The function completed successfully. | |
@retval EFI_NOT_FOUND No interrupt-controller node found. | |
@retval EFI_ABORTED An error occurred. | |
@retval EFI_INVALID_PARAMETER Invalid parameter. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
FdtGetIntcParentNode ( | |
IN CONST VOID *Fdt, | |
IN INT32 Node, | |
OUT INT32 *IntcNode | |
); | |
/** Get the "interrupt-cells" property value of the node. | |
The "interrupts" property requires to know the number of cells used | |
to encode an interrupt. This information is stored in the | |
interrupt-controller of the input Node. | |
@param [in] Fdt Pointer to a Flattened Device Tree (Fdt). | |
@param [in] IntcNode Offset of an interrupt-controller node. | |
@param [out] IntCells If success, contains the "interrupt-cells" | |
property of the IntcNode. | |
@retval EFI_SUCCESS The function completed successfully. | |
@retval EFI_INVALID_PARAMETER Invalid parameter. | |
@retval EFI_UNSUPPORTED Unsupported. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
FdtGetInterruptCellsInfo ( | |
IN CONST VOID *Fdt, | |
IN INT32 IntcNode, | |
OUT INT32 *InterruptCells | |
); | |
/** Get the "#address-cells" and/or "#size-cells" property of the node. | |
According to the Device Tree specification, s2.3.5 "#address-cells and | |
#size-cells": | |
"If missing, a client program should assume a default value of 2 for | |
#address-cells, and a value of 1 for #size-cells." | |
@param [in] Fdt Pointer to a Flattened Device Tree. | |
@param [in] Node Offset of the node having to get the | |
"#address-cells" and "#size-cells" | |
properties from. | |
@param [out] AddressCells If success, number of address-cells. | |
If the property is not available, | |
default value is 2. | |
@param [out] SizeCells If success, number of size-cells. | |
If the property is not available, | |
default value is 1. | |
@retval EFI_SUCCESS The function completed successfully. | |
@retval EFI_ABORTED An error occurred. | |
@retval EFI_INVALID_PARAMETER Invalid parameter. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
FdtGetAddressInfo ( | |
IN CONST VOID *Fdt, | |
IN INT32 Node, | |
OUT INT32 *AddressCells, OPTIONAL | |
OUT INT32 *SizeCells OPTIONAL | |
); | |
/** Get the "#address-cells" and/or "#size-cells" property of the parent node. | |
According to the Device Tree specification, s2.3.5 "#address-cells and | |
#size-cells": | |
"If missing, a client program should assume a default value of 2 for | |
#address-cells, and a value of 1 for #size-cells." | |
@param [in] Fdt Pointer to a Flattened Device Tree. | |
@param [in] Node Offset of the node having to get the | |
"#address-cells" and "#size-cells" | |
properties from its parent. | |
@param [out] AddressCells If success, number of address-cells. | |
If the property is not available, | |
default value is 2. | |
@param [out] SizeCells If success, number of size-cells. | |
If the property is not available, | |
default value is 1. | |
@retval EFI_SUCCESS The function completed successfully. | |
@retval EFI_ABORTED An error occurred. | |
@retval EFI_INVALID_PARAMETER Invalid parameter. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
FdtGetParentAddressInfo ( | |
IN CONST VOID *Fdt, | |
IN INT32 Node, | |
OUT INT32 *AddressCells, OPTIONAL | |
OUT INT32 *SizeCells OPTIONAL | |
); | |
#endif // FDT_UTILITY_H_ |