2 Arm Gic Msi frame Parser.
4 Copyright (c) 2021, ARM Limited. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
8 - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic.yaml
9 - linux/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml
12 #include "CmObjectDescUtility.h"
13 #include "FdtHwInfoParser.h"
14 #include "Gic/ArmGicDispatcher.h"
15 #include "Gic/ArmGicMsiFrameParser.h"
17 /** List of "compatible" property values for Msi-frame nodes.
19 Any other "compatible" value is not supported by this module.
21 STATIC CONST COMPATIBILITY_STR MsiFrameCompatibleStr
[] = {
22 { "arm,gic-v2m-frame" }
25 /** COMPATIBILITY_INFO structure for the MSI frame.
27 STATIC CONST COMPATIBILITY_INFO MsiFrameCompatibleInfo
= {
28 ARRAY_SIZE (MsiFrameCompatibleStr
),
32 /** Parse a Msi frame node.
34 @param [in] Fdt Pointer to a Flattened Device Tree (Fdt).
35 @param [in] MsiFrameNode Offset of a Msi frame node.
36 @param [in] MsiFrameId Frame ID.
37 @param [out] MsiFrameInfo The CM_ARM_GIC_MSI_FRAME_INFO to populate.
39 @retval EFI_SUCCESS The function completed successfully.
40 @retval EFI_ABORTED An error occurred.
41 @retval EFI_INVALID_PARAMETER Invalid parameter.
48 IN INT32 MsiFrameNode
,
50 OUT CM_ARM_GIC_MSI_FRAME_INFO
*MsiFrameInfo
59 (MsiFrameInfo
== NULL
))
62 return EFI_INVALID_PARAMETER
;
65 Status
= FdtGetParentAddressInfo (Fdt
, MsiFrameNode
, &AddressCells
, NULL
);
66 if (EFI_ERROR (Status
)) {
71 // Don't support more than 64 bits and less than 32 bits addresses.
72 if ((AddressCells
< 1) ||
79 Data
= fdt_getprop (Fdt
, MsiFrameNode
, "reg", &DataSize
);
80 if ((Data
== NULL
) || (DataSize
< (INT32
)(AddressCells
* sizeof (UINT32
)))) {
81 // If error or not enough space.
86 if (AddressCells
== 2) {
87 MsiFrameInfo
->PhysicalBaseAddress
= fdt64_to_cpu (*(UINT64
*)Data
);
89 MsiFrameInfo
->PhysicalBaseAddress
= fdt32_to_cpu (*(UINT32
*)Data
);
92 MsiFrameInfo
->GicMsiFrameId
= MsiFrameId
;
97 /** CM_ARM_GIC_MSI_FRAME_INFO parser function.
99 The following structure is populated:
100 typedef struct CmArmGicMsiFrameInfo {
101 UINT32 GicMsiFrameId; // {Populated}
102 UINT64 PhysicalBaseAddress; // {Populated}
103 UINT32 Flags; // {default = 0}
106 } CM_ARM_GIC_MSI_FRAME_INFO;
108 A parser parses a Device Tree to populate a specific CmObj type. None,
109 one or many CmObj can be created by the parser.
110 The created CmObj are then handed to the parser's caller through the
111 HW_INFO_ADD_OBJECT interface.
112 This can also be a dispatcher. I.e. a function that not parsing a
113 Device Tree but calling other parsers.
115 @param [in] FdtParserHandle A handle to the parser instance.
116 @param [in] FdtBranch When searching for DT node name, restrict
117 the search to this Device Tree branch.
119 @retval EFI_SUCCESS The function completed successfully.
120 @retval EFI_ABORTED An error occurred.
121 @retval EFI_INVALID_PARAMETER Invalid parameter.
122 @retval EFI_NOT_FOUND Not found.
123 @retval EFI_UNSUPPORTED Unsupported.
127 ArmGicMsiFrameInfoParser (
128 IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle
,
134 UINT32 MsiFrameNodeCount
;
137 CM_ARM_GIC_MSI_FRAME_INFO MsiFrameInfo
;
140 if (FdtParserHandle
== NULL
) {
142 return EFI_INVALID_PARAMETER
;
145 Fdt
= FdtParserHandle
->Fdt
;
147 // Count the number of nodes having the "interrupt-controller" property.
148 Status
= FdtCountPropNodeInBranch (
154 if (EFI_ERROR (Status
)) {
159 if (MsiFrameNodeCount
== 0) {
160 return EFI_NOT_FOUND
;
163 // Parse each node having the "msi-controller" property.
164 MsiFrameNode
= FdtBranch
;
165 for (Index
= 0; Index
< MsiFrameNodeCount
; Index
++) {
166 ZeroMem (&MsiFrameInfo
, sizeof (CM_ARM_GIC_MSI_FRAME_INFO
));
168 Status
= FdtGetNextPropNodeInBranch (
174 if (EFI_ERROR (Status
)) {
176 if (Status
== EFI_NOT_FOUND
) {
177 // Should have found the node.
178 Status
= EFI_ABORTED
;
184 if (!FdtNodeIsCompatible (Fdt
, MsiFrameNode
, &MsiFrameCompatibleInfo
)) {
186 Status
= EFI_UNSUPPORTED
;
190 // Parse the Msi information.
191 Status
= MsiFrameNodeParser (
197 if (EFI_ERROR (Status
)) {
202 // Add the CmObj to the Configuration Manager.
203 Status
= AddSingleCmObj (
205 CREATE_CM_ARM_OBJECT_ID (EArmObjGicMsiFrameInfo
),
207 sizeof (CM_ARM_GIC_MSI_FRAME_INFO
),
210 if (EFI_ERROR (Status
)) {