TianoCore EDK2 master
Loading...
Searching...
No Matches
ArmGicCParser.c
Go to the documentation of this file.
1
14#include <Library/ArmLib.h>
15#include "FdtHwInfoParser.h"
16#include "CmObjectDescUtility.h"
19
25 { "arm,arm-v7" },
26 { "arm,arm-v8" },
27 { "arm,armv8" },
28 { "arm,cortex-a15" },
29 { "arm,cortex-a7" },
30 { "arm,cortex-a57" }
31};
32
38};
39
45 { "arm,armv8-pmuv3" }
46};
47
53};
54
71EFIAPI
73 IN CONST VOID *Fdt,
74 IN INT32 CpuNode,
75 IN UINT32 GicVersion,
76 IN UINT32 AddressCells,
77 OUT CM_ARM_GICC_INFO *GicCInfo
78 )
79{
80 CONST UINT8 *Data;
81 INT32 DataSize;
82 UINT32 ProcUid;
83 UINT64 MpIdr;
84 UINT64 CheckAffMask;
85
86 MpIdr = 0;
87 CheckAffMask = ARM_CORE_AFF0 | ARM_CORE_AFF1 | ARM_CORE_AFF2;
88
89 if (GicCInfo == NULL) {
90 ASSERT (0);
91 return EFI_INVALID_PARAMETER;
92 }
93
94 Data = fdt_getprop (Fdt, CpuNode, "reg", &DataSize);
95 if ((Data == NULL) ||
96 ((DataSize != sizeof (UINT32)) &&
97 (DataSize != sizeof (UINT64))))
98 {
99 ASSERT (0);
100 return EFI_ABORTED;
101 }
102
103 /* If cpus node's #address-cells property is set to 2
104 The first reg cell bits [7:0] must be set to
105 bits [39:32] of MPIDR_EL1.
106 The second reg cell bits [23:0] must be set to
107 bits [23:0] of MPIDR_EL1.
108 */
109 if (AddressCells == 2) {
110 MpIdr = fdt64_to_cpu (*((UINT64 *)Data));
111 CheckAffMask |= ARM_CORE_AFF3;
112 } else {
113 MpIdr = fdt32_to_cpu (*((UINT32 *)Data));
114 }
115
116 if ((MpIdr & ~CheckAffMask) != 0) {
117 ASSERT (0);
118 return EFI_INVALID_PARAMETER;
119 }
120
121 // To fit the Affinity [0-3] a 32bits value, place the Aff3 on bits
122 // [31:24] instead of their original place ([39:32]).
123 ProcUid = MpIdr | ((MpIdr & ARM_CORE_AFF3) >> 8);
124
125 /* ACPI 6.3, s5.2.12.14 GIC CPU Interface (GICC) Structure:
126 GIC 's CPU Interface Number. In GICv1/v2 implementations,
127 this value matches the bit index of the associated processor
128 in the GIC distributor's GICD_ITARGETSR register. For
129 GICv3/4 implementations this field must be provided by the
130 platform, if compatibility mode is supported. If it is not supported
131 by the implementation, then this field must be zero.
132
133 Note: We do not support compatibility mode for GicV3
134 */
135 if (GicVersion == 2) {
136 GicCInfo->CPUInterfaceNumber = ProcUid;
137 } else {
138 GicCInfo->CPUInterfaceNumber = 0;
139 }
140
141 GicCInfo->AcpiProcessorUid = ProcUid;
142 GicCInfo->Flags = EFI_ACPI_6_3_GIC_ENABLED;
143 GicCInfo->MPIDR = MpIdr;
144
145 return EFI_SUCCESS;
146}
147
163STATIC
165EFIAPI
167 IN CONST VOID *Fdt,
168 IN INT32 CpusNode,
169 IN UINT32 GicVersion,
170 OUT CM_OBJ_DESCRIPTOR **NewGicCmObjDesc
171 )
172{
173 EFI_STATUS Status;
174 INT32 CpuNode;
175 UINT32 CpuNodeCount;
176 INT32 AddressCells;
177
178 UINT32 Index;
179 CM_ARM_GICC_INFO *GicCInfoBuffer;
180 UINT32 GicCInfoBufferSize;
181
182 if (NewGicCmObjDesc == NULL) {
183 ASSERT (0);
184 return EFI_INVALID_PARAMETER;
185 }
186
187 AddressCells = fdt_address_cells (Fdt, CpusNode);
188 if (AddressCells < 0) {
189 ASSERT (0);
190 return EFI_ABORTED;
191 }
192
193 // Count the number of "cpu" nodes under the "cpus" node.
194 Status = FdtCountNamedNodeInBranch (Fdt, CpusNode, "cpu", &CpuNodeCount);
195 if (EFI_ERROR (Status)) {
196 ASSERT (0);
197 return Status;
198 }
199
200 if (CpuNodeCount == 0) {
201 ASSERT (0);
202 return EFI_NOT_FOUND;
203 }
204
205 // Allocate memory for CpuNodeCount CM_ARM_GICC_INFO structures.
206 GicCInfoBufferSize = CpuNodeCount * sizeof (CM_ARM_GICC_INFO);
207 GicCInfoBuffer = AllocateZeroPool (GicCInfoBufferSize);
208 if (GicCInfoBuffer == NULL) {
209 ASSERT (0);
210 return EFI_OUT_OF_RESOURCES;
211 }
212
213 CpuNode = CpusNode;
214 for (Index = 0; Index < CpuNodeCount; Index++) {
215 Status = FdtGetNextNamedNodeInBranch (Fdt, CpusNode, "cpu", &CpuNode);
216 if (EFI_ERROR (Status)) {
217 ASSERT (0);
218 if (Status == EFI_NOT_FOUND) {
219 // Should have found the node.
220 Status = EFI_ABORTED;
221 }
222
223 goto exit_handler;
224 }
225
226 // Parse the "cpu" node.
227 if (!FdtNodeIsCompatible (Fdt, CpuNode, &CpuCompatibleInfo)) {
228 ASSERT (0);
229 Status = EFI_UNSUPPORTED;
230 goto exit_handler;
231 }
232
233 Status = CpuNodeParser (
234 Fdt,
235 CpuNode,
236 GicVersion,
237 AddressCells,
238 &GicCInfoBuffer[Index]
239 );
240 if (EFI_ERROR (Status)) {
241 ASSERT (0);
242 goto exit_handler;
243 }
244 } // for
245
246 Status = CreateCmObjDesc (
248 CpuNodeCount,
249 GicCInfoBuffer,
250 GicCInfoBufferSize,
251 NewGicCmObjDesc
252 );
253 ASSERT_EFI_ERROR (Status);
254
255exit_handler:
256 FreePool (GicCInfoBuffer);
257 return Status;
258}
259
277STATIC
279EFIAPI
281 IN CONST VOID *Fdt,
282 IN INT32 GicIntcNode,
283 IN OUT CM_OBJ_DESCRIPTOR *GicCCmObjDesc
284 )
285{
286 EFI_STATUS Status;
287 INT32 IntCells;
288 CM_ARM_GICC_INFO *GicCInfo;
289
290 CONST UINT8 *Data;
291 INT32 DataSize;
292
293 if (GicCCmObjDesc == NULL) {
294 ASSERT (0);
295 return EFI_INVALID_PARAMETER;
296 }
297
298 // Get the number of cells used to encode an interrupt.
299 Status = FdtGetInterruptCellsInfo (Fdt, GicIntcNode, &IntCells);
300 if (EFI_ERROR (Status)) {
301 ASSERT (0);
302 return Status;
303 }
304
305 // Get the GSIV maintenance interrupt.
306 // According to the DT bindings, this could be the:
307 // "Interrupt source of the parent interrupt controller on secondary GICs"
308 // but it is assumed that only one Gic is available.
309 Data = fdt_getprop (Fdt, GicIntcNode, "interrupts", &DataSize);
310 if ((Data != NULL) && (DataSize == (IntCells * sizeof (UINT32)))) {
311 GicCInfo = (CM_ARM_GICC_INFO *)GicCCmObjDesc->Data;
312 GicCInfo->VGICMaintenanceInterrupt =
313 FdtGetInterruptId ((CONST UINT32 *)Data);
314 GicCInfo->Flags = DT_IRQ_IS_EDGE_TRIGGERED (
315 fdt32_to_cpu (((UINT32 *)Data)[IRQ_FLAGS_OFFSET])
316 ) ?
317 EFI_ACPI_6_3_VGIC_MAINTENANCE_INTERRUPT_MODE_FLAGS :
318 0;
319 return Status;
320 } else if (DataSize < 0) {
321 // This property is optional and was not found. Just return.
322 return Status;
323 }
324
325 // The property exists and its size doesn't match for one interrupt.
326 ASSERT (0);
327 return EFI_ABORTED;
328}
329
348STATIC
350EFIAPI
352 IN CONST VOID *Fdt,
353 IN INT32 Gicv2IntcNode,
354 IN OUT CM_OBJ_DESCRIPTOR *GicCCmObjDesc
355 )
356{
357 EFI_STATUS Status;
358 UINT32 Index;
359 CM_ARM_GICC_INFO *GicCInfo;
360 INT32 AddressCells;
361 INT32 SizeCells;
362
363 CONST UINT8 *GicCValue;
364 CONST UINT8 *GicVValue;
365 CONST UINT8 *GicHValue;
366
367 CONST UINT8 *Data;
368 INT32 DataSize;
369 UINT32 RegSize;
370 UINT32 RegCount;
371
372 if (GicCCmObjDesc == NULL) {
373 ASSERT (0);
374 return EFI_INVALID_PARAMETER;
375 }
376
377 GicCInfo = (CM_ARM_GICC_INFO *)GicCCmObjDesc->Data;
378 GicVValue = NULL;
379 GicHValue = NULL;
380
381 // Get the #address-cells and #size-cells property values.
382 Status = FdtGetParentAddressInfo (
383 Fdt,
384 Gicv2IntcNode,
385 &AddressCells,
386 &SizeCells
387 );
388 if (EFI_ERROR (Status)) {
389 ASSERT (0);
390 return Status;
391 }
392
393 // Don't support more than 64 bits and less than 32 bits addresses.
394 if ((AddressCells < 1) ||
395 (AddressCells > 2) ||
396 (SizeCells < 1) ||
397 (SizeCells > 2))
398 {
399 ASSERT (0);
400 return EFI_ABORTED;
401 }
402
403 RegSize = (AddressCells + SizeCells) * sizeof (UINT32);
404
405 Data = fdt_getprop (Fdt, Gicv2IntcNode, "reg", &DataSize);
406 if ((Data == NULL) ||
407 (DataSize < 0) ||
408 ((DataSize % RegSize) != 0))
409 {
410 // If error or wrong size.
411 ASSERT (0);
412 return EFI_ABORTED;
413 }
414
415 RegCount = DataSize/RegSize;
416
417 switch (RegCount) {
418 case 4:
419 {
420 // GicV is at index 3 in the reg property. GicV is optional.
421 GicVValue = Data + (sizeof (UINT32) *
422 GET_DT_REG_ADDRESS_OFFSET (3, AddressCells, SizeCells));
423 // fall-through.
424 }
425 case 3:
426 {
427 // GicH is at index 2 in the reg property. GicH is optional.
428 GicHValue = Data + (sizeof (UINT32) *
429 GET_DT_REG_ADDRESS_OFFSET (2, AddressCells, SizeCells));
430 // fall-through.
431 }
432 case 2:
433 {
434 // GicC is at index 1 in the reg property. GicC is mandatory.
435 GicCValue = Data + (sizeof (UINT32) *
436 GET_DT_REG_ADDRESS_OFFSET (1, AddressCells, SizeCells));
437 break;
438 }
439 default:
440 {
441 // Not enough or too much information.
442 ASSERT (0);
443 return EFI_ABORTED;
444 }
445 }
446
447 // Patch the relevant fields of the CM_ARM_GICC_INFO objects.
448 for (Index = 0; Index < GicCCmObjDesc->Count; Index++) {
449 if (AddressCells == 2) {
450 GicCInfo[Index].PhysicalBaseAddress = fdt64_to_cpu (*(UINT64 *)GicCValue);
451 GicCInfo[Index].GICH = (GicHValue == NULL) ? 0 :
452 fdt64_to_cpu (*(UINT64 *)GicHValue);
453 GicCInfo[Index].GICV = (GicVValue == NULL) ? 0 :
454 fdt64_to_cpu (*(UINT64 *)GicVValue);
455 } else {
456 GicCInfo[Index].PhysicalBaseAddress = fdt32_to_cpu (*(UINT32 *)GicCValue);
457 GicCInfo[Index].GICH = (GicHValue == NULL) ? 0 :
458 fdt32_to_cpu (*(UINT32 *)GicHValue);
459 GicCInfo[Index].GICV = (GicVValue == NULL) ? 0 :
460 fdt32_to_cpu (*(UINT32 *)GicVValue);
461 }
462 } // for
463
464 return EFI_SUCCESS;
465}
466
485STATIC
487EFIAPI
489 IN CONST VOID *Fdt,
490 IN INT32 Gicv3IntcNode,
491 IN OUT CM_OBJ_DESCRIPTOR *GicCCmObjDesc
492 )
493{
494 EFI_STATUS Status;
495 UINT32 Index;
496 CM_ARM_GICC_INFO *GicCInfo;
497 INT32 AddressCells;
498 INT32 SizeCells;
499 UINT32 AdditionalRedistReg;
500
501 CONST UINT8 *GicCValue;
502 CONST UINT8 *GicVValue;
503 CONST UINT8 *GicHValue;
504
505 CONST UINT8 *Data;
506 INT32 DataSize;
507 UINT32 RegSize;
508 UINT32 RegCount;
509
510 if (GicCCmObjDesc == NULL) {
511 ASSERT (0);
512 return EFI_INVALID_PARAMETER;
513 }
514
515 GicCInfo = (CM_ARM_GICC_INFO *)GicCCmObjDesc->Data;
516 GicCValue = NULL;
517 GicVValue = NULL;
518 GicHValue = NULL;
519
520 // Get the #address-cells and #size-cells property values.
521 Status = FdtGetParentAddressInfo (
522 Fdt,
523 Gicv3IntcNode,
524 &AddressCells,
525 &SizeCells
526 );
527 if (EFI_ERROR (Status)) {
528 ASSERT (0);
529 return Status;
530 }
531
532 // Don't support more than 64 bits and less than 32 bits addresses.
533 if ((AddressCells < 1) ||
534 (AddressCells > 2) ||
535 (SizeCells < 1) ||
536 (SizeCells > 2))
537 {
538 ASSERT (0);
539 return EFI_ABORTED;
540 }
541
542 // The "#redistributor-regions" property is optional.
543 Data = fdt_getprop (Fdt, Gicv3IntcNode, "#redistributor-regions", &DataSize);
544 if ((Data != NULL) && (DataSize == sizeof (UINT32))) {
545 ASSERT (fdt32_to_cpu (*(UINT32 *)Data) > 1);
546 AdditionalRedistReg = fdt32_to_cpu (*(UINT32 *)Data) - 1;
547 } else {
548 AdditionalRedistReg = 0;
549 }
550
551 RegSize = (AddressCells + SizeCells) * sizeof (UINT32);
552
553 /*
554 Ref: linux/blob/master/Documentation/devicetree/bindings/
555 interrupt-controller/arm%2Cgic-v3.yaml
556
557 reg:
558 description: |
559 Specifies base physical address(s) and size of the GIC
560 registers, in the following order:
561 - GIC Distributor interface (GICD)
562 - GIC Redistributors (GICR), one range per redistributor region
563 - GIC CPU interface (GICC)
564 - GIC Hypervisor interface (GICH)
565 - GIC Virtual CPU interface (GICV)
566 GICC, GICH and GICV are optional.
567 minItems: 2
568 maxItems: 4096
569 */
570 Data = fdt_getprop (Fdt, Gicv3IntcNode, "reg", &DataSize);
571 if ((Data == NULL) ||
572 (DataSize < 0) ||
573 ((DataSize % RegSize) != 0))
574 {
575 // If error or wrong size.
576 ASSERT (0);
577 return EFI_ABORTED;
578 }
579
580 RegCount = (DataSize / RegSize) - AdditionalRedistReg;
581
582 // The GicD and GicR info is mandatory.
583 switch (RegCount) {
584 case 5:
585 {
586 // GicV is at index 4 in the reg property. GicV is optional.
587 GicVValue = Data + (sizeof (UINT32) *
589 4 + AdditionalRedistReg,
590 AddressCells,
591 SizeCells
592 ));
593 // fall-through.
594 }
595 case 4:
596 {
597 // GicH is at index 3 in the reg property. GicH is optional.
598 GicHValue = Data + (sizeof (UINT32) *
600 3 + AdditionalRedistReg,
601 AddressCells,
602 SizeCells
603 ));
604 // fall-through.
605 }
606 case 3:
607 {
608 // GicC is at index 2 in the reg property. GicC is optional.
609 // Even though GicC is optional, it is made mandatory in this parser.
610 GicCValue = Data + (sizeof (UINT32) *
612 2 + AdditionalRedistReg,
613 AddressCells,
614 SizeCells
615 ));
616 // fall-through
617 }
618 case 2:
619 {
620 // GicR is discribed by the CM_ARM_GIC_REDIST_INFO object.
621 // GicD is described by the CM_ARM_GICD_INFO object.
622 break;
623 }
624 default:
625 {
626 // Not enough or too much information.
627 ASSERT (0);
628 return EFI_ABORTED;
629 }
630 }
631
632 // Patch the relevant fields of the CM_ARM_GICC_INFO objects.
633 if (AddressCells == 2) {
634 for (Index = 0; Index < GicCCmObjDesc->Count; Index++) {
635 // GicR is discribed by the CM_ARM_GIC_REDIST_INFO object.
636 GicCInfo[Index].GICRBaseAddress = 0;
637 GicCInfo[Index].PhysicalBaseAddress = (GicCValue == NULL) ? 0 :
638 fdt64_to_cpu (*(UINT64 *)GicCValue);
639 GicCInfo[Index].GICH = (GicHValue == NULL) ? 0 :
640 fdt64_to_cpu (*(UINT64 *)GicHValue);
641 GicCInfo[Index].GICV = (GicVValue == NULL) ? 0 :
642 fdt64_to_cpu (*(UINT64 *)GicVValue);
643 }
644 } else {
645 for (Index = 0; Index < GicCCmObjDesc->Count; Index++) {
646 // GicR is discribed by the CM_ARM_GIC_REDIST_INFO object.
647 GicCInfo[Index].GICRBaseAddress = 0;
648 GicCInfo[Index].PhysicalBaseAddress = (GicCValue == NULL) ? 0 :
649 fdt32_to_cpu (*(UINT32 *)GicCValue);
650 GicCInfo[Index].GICH = (GicHValue == NULL) ? 0 :
651 fdt32_to_cpu (*(UINT32 *)GicHValue);
652 GicCInfo[Index].GICV = (GicVValue == NULL) ? 0 :
653 fdt32_to_cpu (*(UINT32 *)GicVValue);
654 }
655 }
656
657 return EFI_SUCCESS;
658}
659
675STATIC
677EFIAPI
679 IN CONST VOID *Fdt,
680 IN INT32 GicIntcNode,
681 IN OUT CM_OBJ_DESCRIPTOR *GicCCmObjDesc
682 )
683{
684 EFI_STATUS Status;
685 INT32 IntCells;
686 INT32 PmuNode;
687 UINT32 PmuNodeCount;
688 UINT32 PmuIrq;
689 UINT32 Index;
690 CM_ARM_GICC_INFO *GicCInfo;
691 CONST UINT8 *Data;
692 INT32 DataSize;
693
694 if (GicCCmObjDesc == NULL) {
695 ASSERT (GicCCmObjDesc != NULL);
696 return EFI_INVALID_PARAMETER;
697 }
698
699 GicCInfo = (CM_ARM_GICC_INFO *)GicCCmObjDesc->Data;
700 PmuNode = 0;
701
702 // Count the number of pmu nodes.
704 Fdt,
705 0,
707 &PmuNodeCount
708 );
709 if (EFI_ERROR (Status)) {
710 ASSERT_EFI_ERROR (Status);
711 return Status;
712 }
713
714 if (PmuNodeCount == 0) {
715 return EFI_NOT_FOUND;
716 }
717
719 Fdt,
720 0,
722 &PmuNode
723 );
724 if (EFI_ERROR (Status)) {
725 ASSERT_EFI_ERROR (Status);
726 if (Status == EFI_NOT_FOUND) {
727 // Should have found the node.
728 Status = EFI_ABORTED;
729 }
730 }
731
732 // Get the number of cells used to encode an interrupt.
733 Status = FdtGetInterruptCellsInfo (Fdt, GicIntcNode, &IntCells);
734 if (EFI_ERROR (Status)) {
735 ASSERT_EFI_ERROR (Status);
736 return Status;
737 }
738
739 Data = fdt_getprop (Fdt, PmuNode, "interrupts", &DataSize);
740 if ((Data == NULL) || (DataSize != (IntCells * sizeof (UINT32)))) {
741 // If error or not 1 interrupt.
742 ASSERT (Data != NULL);
743 ASSERT (DataSize == (IntCells * sizeof (UINT32)));
744 return EFI_ABORTED;
745 }
746
747 PmuIrq = FdtGetInterruptId ((CONST UINT32 *)Data);
748
749 // Only supports PPI 23 for now.
750 // According to BSA 1.0 s3.6 PPI assignments, PMU IRQ ID is 23. A non BSA
751 // compliant system may assign a different IRQ for the PMU, however this
752 // is not implemented for now.
753 if (PmuIrq != BSA_PMU_IRQ) {
754 ASSERT (PmuIrq == BSA_PMU_IRQ);
755 return EFI_ABORTED;
756 }
757
758 for (Index = 0; Index < GicCCmObjDesc->Count; Index++) {
759 GicCInfo[Index].PerformanceInterruptGsiv = PmuIrq;
760 }
761
762 return EFI_SUCCESS;
763}
764
808EFIAPI
810 IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle,
811 IN INT32 FdtBranch
812 )
813{
814 EFI_STATUS Status;
815 INT32 IntcNode;
816 UINT32 GicVersion;
817 CM_OBJ_DESCRIPTOR *NewCmObjDesc;
818 VOID *Fdt;
819
820 if (FdtParserHandle == NULL) {
821 ASSERT (0);
822 return EFI_INVALID_PARAMETER;
823 }
824
825 Fdt = FdtParserHandle->Fdt;
826 NewCmObjDesc = NULL;
827
828 // The FdtBranch points to the Cpus Node.
829 // Get the interrupt-controller node associated to the "cpus" node.
830 Status = FdtGetIntcParentNode (Fdt, FdtBranch, &IntcNode);
831 if (EFI_ERROR (Status)) {
832 ASSERT (0);
833 if (Status == EFI_NOT_FOUND) {
834 // Should have found the node.
835 Status = EFI_ABORTED;
836 }
837
838 return Status;
839 }
840
841 Status = GetGicVersion (Fdt, IntcNode, &GicVersion);
842 if (EFI_ERROR (Status)) {
843 ASSERT (0);
844 return Status;
845 }
846
847 // Parse the "cpus" nodes and its children "cpu" nodes,
848 // and create a CM_OBJ_DESCRIPTOR.
849 Status = CpusNodeParser (Fdt, FdtBranch, GicVersion, &NewCmObjDesc);
850 if (EFI_ERROR (Status)) {
851 ASSERT (0);
852 return Status;
853 }
854
855 // Parse the interrupt-controller node according to the Gic version.
856 switch (GicVersion) {
857 case 2:
858 {
859 Status = GicCv2IntcNodeParser (Fdt, IntcNode, NewCmObjDesc);
860 break;
861 }
862 case 3:
863 {
864 Status = GicCv3IntcNodeParser (Fdt, IntcNode, NewCmObjDesc);
865 break;
866 }
867 default:
868 {
869 // Unsupported Gic version.
870 ASSERT (0);
871 Status = EFI_UNSUPPORTED;
872 }
873 }
874
875 if (EFI_ERROR (Status)) {
876 ASSERT (0);
877 goto exit_handler;
878 }
879
880 // Parse the Gic information common to Gic v2 and v3.
881 Status = GicCIntcNodeParser (Fdt, IntcNode, NewCmObjDesc);
882 if (EFI_ERROR (Status)) {
883 ASSERT (0);
884 goto exit_handler;
885 }
886
887 // Parse the Pmu Interrupt.
888 Status = GicCPmuNodeParser (Fdt, IntcNode, NewCmObjDesc);
889 if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
890 ASSERT_EFI_ERROR (Status);
891 goto exit_handler;
892 }
893
894 // Add all the CmObjs to the Configuration Manager.
895 Status = AddMultipleCmObj (FdtParserHandle, NewCmObjDesc, 0, NULL);
896 if (EFI_ERROR (Status)) {
897 ASSERT (0);
898 goto exit_handler;
899 }
900
901exit_handler:
902 FreeCmObjDesc (NewCmObjDesc);
903 return Status;
904}
#define EFI_ACPI_6_3_GIC_ENABLED
Definition: Acpi63.h:534
UINT32 EFIAPI FdtGetInterruptId(UINT32 CONST *Data)
STATIC CONST COMPATIBILITY_STR CpuCompatibleStr[]
Definition: ArmGicCParser.c:24
STATIC EFI_STATUS EFIAPI GicCIntcNodeParser(IN CONST VOID *Fdt, IN INT32 GicIntcNode, IN OUT CM_OBJ_DESCRIPTOR *GicCCmObjDesc)
STATIC EFI_STATUS EFIAPI CpuNodeParser(IN CONST VOID *Fdt, IN INT32 CpuNode, IN UINT32 GicVersion, IN UINT32 AddressCells, OUT CM_ARM_GICC_INFO *GicCInfo)
Definition: ArmGicCParser.c:72
CONST COMPATIBILITY_INFO PmuCompatibleInfo
Definition: ArmGicCParser.c:50
STATIC EFI_STATUS EFIAPI GicCPmuNodeParser(IN CONST VOID *Fdt, IN INT32 GicIntcNode, IN OUT CM_OBJ_DESCRIPTOR *GicCCmObjDesc)
STATIC CONST COMPATIBILITY_STR PmuCompatibleStr[]
Definition: ArmGicCParser.c:44
STATIC CONST COMPATIBILITY_INFO CpuCompatibleInfo
Definition: ArmGicCParser.c:35
STATIC EFI_STATUS EFIAPI GicCv2IntcNodeParser(IN CONST VOID *Fdt, IN INT32 Gicv2IntcNode, IN OUT CM_OBJ_DESCRIPTOR *GicCCmObjDesc)
STATIC EFI_STATUS EFIAPI CpusNodeParser(IN CONST VOID *Fdt, IN INT32 CpusNode, IN UINT32 GicVersion, OUT CM_OBJ_DESCRIPTOR **NewGicCmObjDesc)
EFI_STATUS EFIAPI ArmGicCInfoParser(IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, IN INT32 FdtBranch)
STATIC EFI_STATUS EFIAPI GicCv3IntcNodeParser(IN CONST VOID *Fdt, IN INT32 Gicv3IntcNode, IN OUT CM_OBJ_DESCRIPTOR *GicCCmObjDesc)
EFI_STATUS EFIAPI GetGicVersion(IN CONST VOID *Fdt, IN INT32 IntcNode, OUT UINT32 *GicVersion)
@ EArmObjGicCInfo
2 - GIC CPU Interface Info
struct CmArmGicCInfo CM_ARM_GICC_INFO
EFI_STATUS EFIAPI FreeCmObjDesc(IN CM_OBJ_DESCRIPTOR *CmObjDesc)
EFI_STATUS EFIAPI AddMultipleCmObj(IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, IN CONST CM_OBJ_DESCRIPTOR *CmObjDesc, IN UINT32 TokenCount, OPTIONAL OUT CM_OBJECT_TOKEN *TokenTable OPTIONAL)
EFI_STATUS EFIAPI CreateCmObjDesc(IN CM_OBJECT_ID ObjectId, IN UINT32 Count, IN VOID *Data, IN UINT32 Size, OUT CM_OBJ_DESCRIPTOR **NewCmObjDesc)
#define CREATE_CM_ARM_OBJECT_ID(ObjectId)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
EFI_STATUS EFIAPI FdtGetNextCompatNodeInBranch(IN CONST VOID *Fdt, IN INT32 FdtBranch, IN CONST COMPATIBILITY_INFO *CompatNamesInfo, IN OUT INT32 *Node)
Definition: FdtUtility.c:398
BOOLEAN EFIAPI FdtNodeIsCompatible(IN CONST VOID *Fdt, IN INT32 Node, IN CONST VOID *CompatInfo)
Definition: FdtUtility.c:90
EFI_STATUS EFIAPI FdtGetParentAddressInfo(IN CONST VOID *Fdt, IN INT32 Node, OUT INT32 *AddressCells, OPTIONAL OUT INT32 *SizeCells OPTIONAL)
Definition: FdtUtility.c:833
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
EFI_STATUS EFIAPI FdtGetNextNamedNodeInBranch(IN CONST VOID *Fdt, IN INT32 FdtBranch, IN CONST CHAR8 *NodeName, IN OUT INT32 *Node)
Definition: FdtUtility.c:358
EFI_STATUS EFIAPI FdtCountNamedNodeInBranch(IN CONST VOID *Fdt, IN INT32 FdtBranch, IN CONST CHAR8 *NodeName, OUT UINT32 *NodeCount)
Definition: FdtUtility.c:538
#define GET_DT_REG_ADDRESS_OFFSET(Index, AddrCells, SizeCells)
Definition: FdtUtility.h:31
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define ARRAY_SIZE(Array)
Definition: Base.h:1393
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
UINT32 VGICMaintenanceInterrupt
UINT32 PerformanceInterruptGsiv