TianoCore EDK2 master
Loading...
Searching...
No Matches
ArmGenericTimerParser.c
Go to the documentation of this file.
1
12#include "FdtHwInfoParser.h"
13#include "CmObjectDescUtility.h"
16
22 { "arm,armv7-timer" },
23 { "arm,armv8-timer" }
24};
25
31};
32
45EFIAPI
47 IN CONST VOID *Fdt,
48 IN INT32 TimerNode,
49 IN CM_ARM_GENERIC_TIMER_INFO *GenericTimerInfo
50 )
51{
52 EFI_STATUS Status;
53 CONST UINT32 *Data;
54 INT32 IntcNode;
55 UINT32 GicVersion;
56 INT32 DataSize;
57 INT32 IntCells;
58 BOOLEAN AlwaysOnTimer;
59
60 if ((Fdt == NULL) ||
61 (GenericTimerInfo == NULL))
62 {
63 ASSERT (0);
64 return EFI_INVALID_PARAMETER;
65 }
66
67 Data = fdt_getprop (Fdt, TimerNode, "always-on", &DataSize);
68 if ((Data == NULL) || (DataSize < 0)) {
69 AlwaysOnTimer = FALSE;
70 } else {
71 AlwaysOnTimer = TRUE;
72 }
73
74 // Get the associated interrupt-controller.
75 Status = FdtGetIntcParentNode (Fdt, TimerNode, &IntcNode);
76 if (EFI_ERROR (Status)) {
77 ASSERT (0);
78 return Status;
79 }
80
81 // Check that the interrupt-controller node is a Gic.
82 Status = GetGicVersion (Fdt, IntcNode, &GicVersion);
83 if (EFI_ERROR (Status)) {
84 ASSERT (0);
85 return Status;
86 }
87
88 // Get the number of cells used to encode an interrupt.
89 Status = FdtGetInterruptCellsInfo (Fdt, IntcNode, &IntCells);
90 if (EFI_ERROR (Status)) {
91 ASSERT (0);
92 if (Status == EFI_NOT_FOUND) {
93 // Should have found the node.
94 Status = EFI_ABORTED;
95 }
96
97 return Status;
98 }
99
100 Data = fdt_getprop (Fdt, TimerNode, "interrupts", &DataSize);
101 if ((Data == NULL) ||
102 (DataSize != (FdtMaxTimerItem * IntCells * sizeof (UINT32))))
103 {
104 // If error or not FdtMaxTimerItem interrupts.
105 ASSERT (0);
106 return EFI_ABORTED;
107 }
108
109 GenericTimerInfo->SecurePL1TimerGSIV =
110 FdtGetInterruptId (&Data[FdtSecureTimerIrq * IntCells]);
111 GenericTimerInfo->SecurePL1TimerFlags =
112 FdtGetInterruptFlags (&Data[FdtSecureTimerIrq * IntCells]);
113 GenericTimerInfo->NonSecurePL1TimerGSIV =
114 FdtGetInterruptId (&Data[FdtNonSecureTimerIrq * IntCells]);
115 GenericTimerInfo->NonSecurePL1TimerFlags =
116 FdtGetInterruptFlags (&Data[FdtNonSecureTimerIrq * IntCells]);
117 GenericTimerInfo->VirtualTimerGSIV =
118 FdtGetInterruptId (&Data[FdtVirtualTimerIrq * IntCells]);
119 GenericTimerInfo->VirtualTimerFlags =
120 FdtGetInterruptFlags (&Data[FdtVirtualTimerIrq * IntCells]);
121 GenericTimerInfo->NonSecurePL2TimerGSIV =
122 FdtGetInterruptId (&Data[FdtHypervisorTimerIrq * IntCells]);
123 GenericTimerInfo->NonSecurePL2TimerFlags =
125
126 if (AlwaysOnTimer) {
127 GenericTimerInfo->SecurePL1TimerFlags |= BIT2;
128 GenericTimerInfo->NonSecurePL1TimerFlags |= BIT2;
129 GenericTimerInfo->VirtualTimerFlags |= BIT2;
130 GenericTimerInfo->NonSecurePL2TimerFlags |= BIT2;
131 }
132
133 // Setup default values
134 // The CntControlBase & CntReadBase Physical Address are optional if
135 // the system implements EL3 (Security Extensions). So, initialise
136 // these to their default value.
137 GenericTimerInfo->CounterControlBaseAddress = 0xFFFFFFFFFFFFFFFF;
138 GenericTimerInfo->CounterReadBaseAddress = 0xFFFFFFFFFFFFFFFF;
139
140 // For systems not implementing ARMv8.1 VHE, this field is 0.
141 GenericTimerInfo->VirtualPL2TimerGSIV = 0;
142 GenericTimerInfo->VirtualPL2TimerFlags = 0;
143
144 return EFI_SUCCESS;
145}
146
183EFIAPI
185 IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle,
186 IN INT32 FdtBranch
187 )
188{
189 EFI_STATUS Status;
190 UINT32 Index;
191 INT32 TimerNode;
192 UINT32 TimerNodeCount;
193 CM_ARM_GENERIC_TIMER_INFO GenericTimerInfo;
194 VOID *Fdt;
195
196 if (FdtParserHandle == NULL) {
197 ASSERT (0);
198 return EFI_INVALID_PARAMETER;
199 }
200
201 Fdt = FdtParserHandle->Fdt;
203 Fdt,
204 FdtBranch,
206 &TimerNodeCount
207 );
208 if (EFI_ERROR (Status)) {
209 ASSERT (0);
210 return Status;
211 }
212
213 if (TimerNodeCount == 0) {
214 return EFI_NOT_FOUND;
215 }
216
217 // Parse each timer node in the branch.
218 TimerNode = FdtBranch;
219 for (Index = 0; Index < TimerNodeCount; Index++) {
220 ZeroMem (&GenericTimerInfo, sizeof (CM_ARM_GENERIC_TIMER_INFO));
221
223 Fdt,
224 FdtBranch,
226 &TimerNode
227 );
228 if (EFI_ERROR (Status)) {
229 ASSERT (0);
230 if (Status == EFI_NOT_FOUND) {
231 // Should have found the node.
232 Status = EFI_ABORTED;
233 }
234
235 return Status;
236 }
237
238 Status = TimerNodeParser (Fdt, TimerNode, &GenericTimerInfo);
239 if (EFI_ERROR (Status)) {
240 ASSERT (0);
241 return Status;
242 }
243
244 // Add the CmObj to the Configuration Manager.
245 Status = AddSingleCmObj (
246 FdtParserHandle,
248 &GenericTimerInfo,
250 NULL
251 );
252 if (EFI_ERROR (Status)) {
253 ASSERT (0);
254 return Status;
255 }
256 } // for
257
258 return Status;
259}
UINT32 EFIAPI FdtGetInterruptId(UINT32 CONST *Data)
UINT32 EFIAPI FdtGetInterruptFlags(UINT32 CONST *Data)
STATIC CONST COMPATIBILITY_INFO TimerCompatibleInfo
STATIC EFI_STATUS EFIAPI TimerNodeParser(IN CONST VOID *Fdt, IN INT32 TimerNode, IN CM_ARM_GENERIC_TIMER_INFO *GenericTimerInfo)
EFI_STATUS EFIAPI ArmGenericTimerInfoParser(IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, IN INT32 FdtBranch)
STATIC CONST COMPATIBILITY_STR TimerCompatibleStr[]
@ FdtVirtualTimerIrq
Virtual timer IRQ.
@ FdtSecureTimerIrq
Secure timer IRQ.
@ FdtHypervisorTimerIrq
Hypervisor timer IRQ.
@ FdtMaxTimerItem
Max timer item.
@ FdtNonSecureTimerIrq
Non-secure timer IRQ.
EFI_STATUS EFIAPI GetGicVersion(IN CONST VOID *Fdt, IN INT32 IntcNode, OUT UINT32 *GicVersion)
@ EArmObjGenericTimerInfo
7 - Generic Timer Info
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_STATUS EFIAPI AddSingleCmObj(IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, IN CM_OBJECT_ID ObjectId, IN VOID *Data, IN UINT32 Size, OUT CM_OBJECT_TOKEN *Token OPTIONAL)
#define CREATE_CM_ARM_OBJECT_ID(ObjectId)
EFI_STATUS EFIAPI FdtGetNextCompatNodeInBranch(IN CONST VOID *Fdt, IN INT32 FdtBranch, IN CONST COMPATIBILITY_INFO *CompatNamesInfo, IN OUT INT32 *Node)
Definition: FdtUtility.c:398
EFI_STATUS EFIAPI FdtCountCompatNodeInBranch(IN CONST VOID *Fdt, IN INT32 FdtBranch, IN CONST COMPATIBILITY_INFO *CompatNamesInfo, OUT UINT32 *NodeCount)
Definition: FdtUtility.c:573
EFI_STATUS EFIAPI FdtGetIntcParentNode(IN CONST VOID *Fdt, IN INT32 Node, OUT INT32 *IntcNode)
Definition: FdtUtility.c:650
EFI_STATUS EFIAPI FdtGetInterruptCellsInfo(IN CONST VOID *Fdt, IN INT32 IntcNode, OUT INT32 *IntCells)
Definition: FdtUtility.c:726
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define ARRAY_SIZE(Array)
Definition: Base.h:1393
#define IN
Definition: Base.h:279
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112