/** @file\r
*\r
-* Copyright (c) 2011-2017, ARM Limited. All rights reserved.\r
+* Copyright (c) 2011-2018, ARM Limited. All rights reserved.\r
*\r
* This program and the accompanying materials\r
* are licensed and made available under the terms and conditions of the BSD License\r
#include <Library/IoLib.h>\r
#include <Library/PcdLib.h>\r
\r
+// In GICv3, there are 2 x 64KB frames:\r
+// Redistributor control frame + SGI Control & Generation frame\r
+#define GIC_V3_REDISTRIBUTOR_GRANULARITY (ARM_GICR_CTLR_FRAME_SIZE \\r
+ + ARM_GICR_SGI_PPI_FRAME_SIZE)\r
+\r
+// In GICv4, there are 2 additional 64KB frames:\r
+// VLPI frame + Reserved page frame\r
+#define GIC_V4_REDISTRIBUTOR_GRANULARITY (GIC_V3_REDISTRIBUTOR_GRANULARITY \\r
+ + ARM_GICR_SGI_VLPI_FRAME_SIZE \\r
+ + ARM_GICR_SGI_RESERVED_FRAME_SIZE)\r
\r
#define ISENABLER_ADDRESS(base,offset) ((base) + \\r
ARM_GICR_CTLR_FRAME_SIZE + ARM_GICR_ISENABLER + (4 * offset))\r
IN ARM_GIC_ARCH_REVISION Revision\r
)\r
{\r
- UINTN Index;\r
UINTN MpId;\r
UINTN CpuAffinity;\r
UINTN Affinity;\r
- UINTN GicRedistributorGranularity;\r
UINTN GicCpuRedistributorBase;\r
+ UINT64 TypeRegister;\r
\r
MpId = ArmReadMpidr ();\r
// Define CPU affinity as:\r
CpuAffinity = (MpId & (ARM_CORE_AFF0 | ARM_CORE_AFF1 | ARM_CORE_AFF2)) |\r
((MpId & ARM_CORE_AFF3) >> 8);\r
\r
- if (Revision == ARM_GIC_ARCH_REVISION_3) {\r
- // 2 x 64KB frame:\r
- // Redistributor control frame + SGI Control & Generation frame\r
- GicRedistributorGranularity = ARM_GICR_CTLR_FRAME_SIZE\r
- + ARM_GICR_SGI_PPI_FRAME_SIZE;\r
- } else {\r
+ if (Revision < ARM_GIC_ARCH_REVISION_3) {\r
ASSERT_EFI_ERROR (EFI_UNSUPPORTED);\r
return 0;\r
}\r
\r
GicCpuRedistributorBase = GicRedistributorBase;\r
\r
- for (Index = 0; Index < PcdGet32 (PcdCoreCount); Index++) {\r
- Affinity = MmioRead64 (GicCpuRedistributorBase + ARM_GICR_TYPER) >> 32;\r
+ do {\r
+ TypeRegister = MmioRead64 (GicCpuRedistributorBase + ARM_GICR_TYPER);\r
+ Affinity = ARM_GICR_TYPER_GET_AFFINITY (TypeRegister);\r
if (Affinity == CpuAffinity) {\r
return GicCpuRedistributorBase;\r
}\r
\r
- // Move to the next GIC Redistributor frame\r
- GicCpuRedistributorBase += GicRedistributorGranularity;\r
- }\r
+ // Move to the next GIC Redistributor frame.\r
+ // The GIC specification does not forbid a mixture of redistributors\r
+ // with or without support for virtual LPIs, so we test Virtual LPIs\r
+ // Support (VLPIS) bit for each frame to decide the granularity.\r
+ // Note: The assumption here is that the redistributors are adjacent\r
+ // for all CPUs. However this may not be the case for NUMA systems.\r
+ GicCpuRedistributorBase += (((ARM_GICR_TYPER_VLPIS & TypeRegister) != 0)\r
+ ? GIC_V4_REDISTRIBUTOR_GRANULARITY\r
+ : GIC_V3_REDISTRIBUTOR_GRANULARITY);\r
+ } while ((TypeRegister & ARM_GICR_TYPER_LAST) == 0);\r
\r
// The Redistributor has not been found for the current CPU\r
ASSERT_EFI_ERROR (EFI_NOT_FOUND);\r
/** @file\r
*\r
-* Copyright (c) 2011-2017, ARM Limited. All rights reserved.\r
+* Copyright (c) 2011-2018, ARM Limited. All rights reserved.\r
*\r
* This program and the accompanying materials\r
* are licensed and made available under the terms and conditions of the BSD License\r
\r
\r
// GIC Redistributor\r
-#define ARM_GICR_CTLR_FRAME_SIZE SIZE_64KB\r
-#define ARM_GICR_SGI_PPI_FRAME_SIZE SIZE_64KB\r
+#define ARM_GICR_CTLR_FRAME_SIZE SIZE_64KB\r
+#define ARM_GICR_SGI_PPI_FRAME_SIZE SIZE_64KB\r
+#define ARM_GICR_SGI_VLPI_FRAME_SIZE SIZE_64KB\r
+#define ARM_GICR_SGI_RESERVED_FRAME_SIZE SIZE_64KB\r
\r
// GIC Redistributor Control frame\r
#define ARM_GICR_TYPER 0x0008 // Redistributor Type Register\r
\r
+// GIC Redistributor TYPER bit assignments\r
+#define ARM_GICR_TYPER_PLPIS (1 << 0) // Physical LPIs\r
+#define ARM_GICR_TYPER_VLPIS (1 << 1) // Virtual LPIs\r
+#define ARM_GICR_TYPER_DIRECTLPI (1 << 3) // Direct LPIs\r
+#define ARM_GICR_TYPER_LAST (1 << 4) // Last Redistributor in series\r
+#define ARM_GICR_TYPER_DPGS (1 << 5) // Disable Processor Group\r
+ // Selection Support\r
+#define ARM_GICR_TYPER_PROCNO (0xFFFF << 8) // Processor Number\r
+#define ARM_GICR_TYPER_COMMONLPIAFF (0x3 << 24) // Common LPI Affinity\r
+#define ARM_GICR_TYPER_AFFINITY (0xFFFFFFFFULL << 32) // Redistributor Affinity\r
+\r
+#define ARM_GICR_TYPER_GET_AFFINITY(TypeReg) (((TypeReg) & \\r
+ ARM_GICR_TYPER_AFFINITY) >> 32)\r
+\r
// GIC SGI & PPI Redistributor frame\r
#define ARM_GICR_ISENABLER 0x0100 // Interrupt Set-Enable Registers\r
#define ARM_GICR_ICENABLER 0x0180 // Interrupt Clear-Enable Registers\r