/** @file\r
*\r
-* Copyright (c) 2011-2014, ARM Limited. All rights reserved.\r
+* Copyright (c) 2011-2015, 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
#include <Base.h>\r
#include <Library/ArmGicLib.h>\r
+#include <Library/ArmLib.h>\r
#include <Library/DebugLib.h>\r
#include <Library/IoLib.h>\r
+#include <Library/PcdLib.h>\r
\r
#include "GicV2/ArmGicV2Lib.h"\r
#include "GicV3/ArmGicV3Lib.h"\r
\r
+/**\r
+ * Return the base address of the GIC redistributor for the current CPU\r
+ *\r
+ * @param Revision GIC Revision. The GIC redistributor might have a different\r
+ * granularity following the GIC revision.\r
+ *\r
+ * @retval Base address of the associated GIC Redistributor\r
+ */\r
+STATIC\r
+UINTN\r
+GicGetCpuRedistributorBase (\r
+ IN UINTN GicRedistributorBase,\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
+\r
+ MpId = ArmReadMpidr ();\r
+ // Define CPU affinity as Affinity0[0:8], Affinity1[9:15], Affinity2[16:23], Affinity3[24:32]\r
+ // whereas Affinity3 is defined at [32:39] in MPIDR\r
+ CpuAffinity = (MpId & (ARM_CORE_AFF0 | ARM_CORE_AFF1 | ARM_CORE_AFF2)) | ((MpId & ARM_CORE_AFF3) >> 8);\r
+\r
+ if (Revision == ARM_GIC_ARCH_REVISION_3) {\r
+ // 2 x 64KB frame: Redistributor control frame + SGI Control & Generation frame\r
+ GicRedistributorGranularity = ARM_GICR_CTLR_FRAME_SIZE + ARM_GICR_SGI_PPI_FRAME_SIZE;\r
+ } else {\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
+ if (Affinity == CpuAffinity) {\r
+ return GicCpuRedistributorBase;\r
+ }\r
+\r
+ // Move to the next GIC Redistributor frame\r
+ GicRedistributorBase += GicRedistributorGranularity;\r
+ }\r
+\r
+ // The Redistributor has not been found for the current CPU\r
+ ASSERT_EFI_ERROR (EFI_NOT_FOUND);\r
+ return 0;\r
+}\r
+\r
UINTN\r
EFIAPI\r
ArmGicGetInterfaceIdentification (\r