Revision: 16874
          http://sourceforge.net/p/edk2/code/16874
Author:   oliviermartin
Date:     2015-02-16 10:23:42 +0000 (Mon, 16 Feb 2015)
Log Message:
-----------
ArmPkg/ArmGic: Use the GIC Redistributor instead of GIC Distributor for GICv3

GICv3 controller with no GICv2 legacy support must use the GIC
Redistributor registers instead of the GIC Distributor registers
for some operations (eg: enable/disable interrupts).

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Olivier Martin <[email protected]>
Tested-by: Ard Biesheuvel <[email protected]>
Reviewed-by: Ard Biesheuvel <[email protected]>

Modified Paths:
--------------
    trunk/edk2/ArmPkg/Drivers/ArmGic/ArmGicLib.c
    trunk/edk2/ArmPkg/Drivers/ArmGic/ArmGicNonSecLib.c
    trunk/edk2/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Dxe.c
    trunk/edk2/ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Dxe.c
    trunk/edk2/ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Lib.h
    trunk/edk2/ArmPkg/Include/Library/ArmGicLib.h

Modified: trunk/edk2/ArmPkg/Drivers/ArmGic/ArmGicLib.c
===================================================================
--- trunk/edk2/ArmPkg/Drivers/ArmGic/ArmGicLib.c        2015-02-16 10:22:07 UTC 
(rev 16873)
+++ trunk/edk2/ArmPkg/Drivers/ArmGic/ArmGicLib.c        2015-02-16 10:23:42 UTC 
(rev 16874)
@@ -172,53 +172,99 @@
 EFIAPI
 ArmGicEnableInterrupt (
   IN UINTN                  GicDistributorBase,
+  IN UINTN                  GicRedistributorBase,
   IN UINTN                  Source
   )
 {
-  UINT32    RegOffset;
-  UINTN     RegShift;
+  UINT32                RegOffset;
+  UINTN                 RegShift;
+  ARM_GIC_ARCH_REVISION Revision;
+  UINTN                 GicCpuRedistributorBase;
 
   // Calculate enable register offset and bit position
   RegOffset = Source / 32;
   RegShift = Source % 32;
 
-  // Write set-enable register
-  MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset), 1 << 
RegShift);
+  Revision = ArmGicGetSupportedArchRevision ();
+  if (Revision == ARM_GIC_ARCH_REVISION_2) {
+    // Write set-enable register
+    MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset), 1 << 
RegShift);
+  } else {
+    GicCpuRedistributorBase = GicGetCpuRedistributorBase 
(GicRedistributorBase, Revision);
+    if (GicCpuRedistributorBase == 0) {
+      ASSERT_EFI_ERROR (EFI_NOT_FOUND);
+      return;
+    }
+
+    // Write set-enable register
+    MmioWrite32 (GicCpuRedistributorBase + ARM_GICR_CTLR_FRAME_SIZE + 
ARM_GICR_ISENABLER + (4 * RegOffset), 1 << RegShift);
+  }
 }
 
 VOID
 EFIAPI
 ArmGicDisableInterrupt (
   IN UINTN                  GicDistributorBase,
+  IN UINTN                  GicRedistributorBase,
   IN UINTN                  Source
   )
 {
-  UINT32    RegOffset;
-  UINTN     RegShift;
+  UINT32                RegOffset;
+  UINTN                 RegShift;
+  ARM_GIC_ARCH_REVISION Revision;
+  UINTN                 GicCpuRedistributorBase;
 
   // Calculate enable register offset and bit position
   RegOffset = Source / 32;
   RegShift = Source % 32;
 
-  // Write clear-enable register
-  MmioWrite32 (GicDistributorBase + ARM_GIC_ICDICER + (4 * RegOffset), 1 << 
RegShift);
+  Revision = ArmGicGetSupportedArchRevision ();
+  if (Revision == ARM_GIC_ARCH_REVISION_2) {
+    // Write clear-enable register
+    MmioWrite32 (GicDistributorBase + ARM_GIC_ICDICER + (4 * RegOffset), 1 << 
RegShift);
+  } else {
+    GicCpuRedistributorBase = GicGetCpuRedistributorBase 
(GicRedistributorBase, Revision);
+    if (GicCpuRedistributorBase == 0) {
+      return;
+    }
+
+    // Write clear-enable register
+    MmioWrite32 (GicCpuRedistributorBase + ARM_GICR_CTLR_FRAME_SIZE + 
ARM_GICR_ICENABLER + (4 * RegOffset), 1 << RegShift);
+  }
 }
 
 BOOLEAN
 EFIAPI
 ArmGicIsInterruptEnabled (
   IN UINTN                  GicDistributorBase,
+  IN UINTN                  GicRedistributorBase,
   IN UINTN                  Source
   )
 {
-  UINT32    RegOffset;
-  UINTN     RegShift;
+  UINT32                RegOffset;
+  UINTN                 RegShift;
+  ARM_GIC_ARCH_REVISION Revision;
+  UINTN                 GicCpuRedistributorBase;
+  UINT32                Interrupts;
 
   // Calculate enable register offset and bit position
   RegOffset = Source / 32;
   RegShift = Source % 32;
 
-  return ((MmioRead32 (GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset)) 
& (1 << RegShift)) != 0);
+  Revision = ArmGicGetSupportedArchRevision ();
+  if (Revision == ARM_GIC_ARCH_REVISION_2) {
+    Interrupts = ((MmioRead32 (GicDistributorBase + ARM_GIC_ICDISER + (4 * 
RegOffset)) & (1 << RegShift)) != 0);
+  } else {
+    GicCpuRedistributorBase = GicGetCpuRedistributorBase 
(GicRedistributorBase, Revision);
+    if (GicCpuRedistributorBase == 0) {
+      return 0;
+    }
+
+    // Read set-enable register
+    Interrupts = MmioRead32 (GicCpuRedistributorBase + 
ARM_GICR_CTLR_FRAME_SIZE + ARM_GICR_ISENABLER + (4 * RegOffset));
+  }
+
+  return ((Interrupts & (1 << RegShift)) != 0);
 }
 
 VOID

Modified: trunk/edk2/ArmPkg/Drivers/ArmGic/ArmGicNonSecLib.c
===================================================================
--- trunk/edk2/ArmPkg/Drivers/ArmGic/ArmGicNonSecLib.c  2015-02-16 10:22:07 UTC 
(rev 16873)
+++ trunk/edk2/ArmPkg/Drivers/ArmGic/ArmGicNonSecLib.c  2015-02-16 10:23:42 UTC 
(rev 16874)
@@ -1,6 +1,6 @@
 /** @file
 *
-*  Copyright (c) 2011-2014, ARM Limited. All rights reserved.
+*  Copyright (c) 2011-2015, ARM Limited. All rights reserved.
 *
 *  This program and the accompanying materials
 *  are licensed and made available under the terms and conditions of the BSD 
License
@@ -22,9 +22,16 @@
   IN  INTN          GicDistributorBase
   )
 {
+  ARM_GIC_ARCH_REVISION Revision;
+
   /*
    * Enable GIC distributor in Non-Secure world.
    * Note: The ICDDCR register is banked when Security extensions are 
implemented
    */
-  MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 0x1);
+  Revision = ArmGicGetSupportedArchRevision ();
+  if (Revision == ARM_GIC_ARCH_REVISION_2) {
+    MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 0x1);
+  } else {
+    MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 0x2);
+  }
 }

Modified: trunk/edk2/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Dxe.c
===================================================================
--- trunk/edk2/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Dxe.c        2015-02-16 
10:22:07 UTC (rev 16873)
+++ trunk/edk2/ArmPkg/Drivers/ArmGic/GicV2/ArmGicV2Dxe.c        2015-02-16 
10:23:42 UTC (rev 16874)
@@ -2,7 +2,7 @@
 
 Copyright (c) 2009, Hewlett-Packard Company. All rights reserved.<BR>
 Portions copyright (c) 2010, Apple Inc. All rights reserved.<BR>
-Portions copyright (c) 2011-2014, ARM Ltd. All rights reserved.<BR>
+Portions copyright (c) 2011-2015, ARM Ltd. All rights reserved.<BR>
 
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD 
License
@@ -54,7 +54,7 @@
     return EFI_UNSUPPORTED;
   }
 
-  ArmGicEnableInterrupt (mGicDistributorBase, Source);
+  ArmGicEnableInterrupt (mGicDistributorBase, 0, Source);
 
   return EFI_SUCCESS;
 }
@@ -81,7 +81,7 @@
     return EFI_UNSUPPORTED;
   }
 
-  ArmGicDisableInterrupt (mGicDistributorBase, Source);
+  ArmGicDisableInterrupt (mGicDistributorBase, 0, Source);
 
   return EFI_SUCCESS;
 }
@@ -110,7 +110,7 @@
     return EFI_UNSUPPORTED;
   }
 
-  *InterruptState = ArmGicIsInterruptEnabled (mGicDistributorBase, Source);
+  *InterruptState = ArmGicIsInterruptEnabled (mGicDistributorBase, 0, Source);
 
   return EFI_SUCCESS;
 }

Modified: trunk/edk2/ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Dxe.c
===================================================================
--- trunk/edk2/ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Dxe.c        2015-02-16 
10:22:07 UTC (rev 16873)
+++ trunk/edk2/ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Dxe.c        2015-02-16 
10:23:42 UTC (rev 16874)
@@ -44,7 +44,7 @@
     return EFI_UNSUPPORTED;
   }
 
-  ArmGicEnableInterrupt (mGicDistributorBase, Source);
+  ArmGicEnableInterrupt (mGicDistributorBase, mGicRedistributorsBase, Source);
 
   return EFI_SUCCESS;
 }
@@ -71,7 +71,7 @@
     return EFI_UNSUPPORTED;
   }
 
-  ArmGicDisableInterrupt (mGicDistributorBase, Source);
+  ArmGicDisableInterrupt (mGicDistributorBase, mGicRedistributorsBase, Source);
 
   return EFI_SUCCESS;
 }
@@ -100,7 +100,7 @@
     return EFI_UNSUPPORTED;
   }
 
-  *InterruptState = ArmGicIsInterruptEnabled (mGicDistributorBase, Source);
+  *InterruptState = ArmGicIsInterruptEnabled (mGicDistributorBase, 
mGicRedistributorsBase, Source);
 
   return EFI_SUCCESS;
 }
@@ -239,7 +239,8 @@
   UINTN                   Index;
   UINT32                  RegOffset;
   UINTN                   RegShift;
-  UINT32                  CpuTarget;
+  UINT64                  CpuTarget;
+  UINT64                  MpId;
 
   // Make sure the Interrupt Controller Protocol is not already installed in 
the system.
   ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid);
@@ -265,22 +266,12 @@
   // Targets the interrupts to the Primary Cpu
   //
 
-  // Only Primary CPU will run this code. We can identify our GIC CPU ID by 
reading
-  // the GIC Distributor Target register. The 8 first GICD_ITARGETSRn are 
banked to each
-  // connected CPU. These 8 registers hold the CPU targets fields for 
interrupts 0-31.
-  // More Info in the GIC Specification about "Interrupt Processor Targets 
Registers"
-  //
-  // Read the first Interrupt Processor Targets Register (that corresponds to 
the 4
-  // first SGIs)
-  CpuTarget = MmioRead32 (mGicDistributorBase + ARM_GIC_ICDIPTR);
+  MpId = ArmReadMpidr ();
+  CpuTarget = MpId & (ARM_CORE_AFF0 | ARM_CORE_AFF1 | ARM_CORE_AFF2 | 
ARM_CORE_AFF3);
 
-  // The CPU target is a bit field mapping each CPU to a GIC CPU Interface. 
This value
-  // is 0 when we run on a uniprocessor platform.
-  if (CpuTarget != 0) {
-    // The 8 first Interrupt Processor Targets Registers are read-only
-    for (Index = 8; Index < (mGicNumInterrupts / 4); Index++) {
-      MmioWrite32 (mGicDistributorBase + ARM_GIC_ICDIPTR + (Index * 4), 
CpuTarget);
-    }
+  // Route the SPIs to the primary CPU. SPIs start at the INTID 32
+  for (Index = 0; Index < (mGicNumInterrupts - 32); Index++) {
+    MmioWrite32 (mGicDistributorBase + ARM_GICD_IROUTER + (Index * 8), 
CpuTarget | ARM_GICD_IROUTER_IRM);
   }
 
   // Set binary point reg to 0x7 (no preemption)

Modified: trunk/edk2/ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Lib.h
===================================================================
--- trunk/edk2/ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Lib.h        2015-02-16 
10:22:07 UTC (rev 16873)
+++ trunk/edk2/ArmPkg/Drivers/ArmGic/GicV3/ArmGicV3Lib.h        2015-02-16 
10:23:42 UTC (rev 16874)
@@ -1,6 +1,6 @@
 /** @file
 *
-*  Copyright (c) 2014, ARM Limited. All rights reserved.
+*  Copyright (c) 2014-2015, ARM Limited. All rights reserved.
 *
 *  This program and the accompanying materials are licensed and made available
 *  under the terms and conditions of the BSD License which accompanies this
@@ -17,6 +17,8 @@
 
 #define ICC_SRE_EL2_SRE         (1 << 0)
 
+#define ARM_GICD_IROUTER_IRM BIT31
+
 UINT32
 EFIAPI
 ArmGicV3GetControlSystemRegisterEnable (

Modified: trunk/edk2/ArmPkg/Include/Library/ArmGicLib.h
===================================================================
--- trunk/edk2/ArmPkg/Include/Library/ArmGicLib.h       2015-02-16 10:22:07 UTC 
(rev 16873)
+++ trunk/edk2/ArmPkg/Include/Library/ArmGicLib.h       2015-02-16 10:23:42 UTC 
(rev 16874)
@@ -208,6 +208,7 @@
 EFIAPI
 ArmGicEnableInterrupt (
   IN UINTN                  GicDistributorBase,
+  IN UINTN                  GicRedistributorBase,
   IN UINTN                  Source
   );
 
@@ -215,6 +216,7 @@
 EFIAPI
 ArmGicDisableInterrupt (
   IN UINTN                  GicDistributorBase,
+  IN UINTN                  GicRedistributorBase,
   IN UINTN                  Source
   );
 
@@ -222,6 +224,7 @@
 EFIAPI
 ArmGicIsInterruptEnabled (
   IN UINTN                  GicDistributorBase,
+  IN UINTN                  GicRedistributorBase,
   IN UINTN                  Source
   );
 


------------------------------------------------------------------------------
Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server
from Actuate! Instantly Supercharge Your Business Reports and Dashboards
with Interactivity, Sharing, Native Excel Exports, App Integration & more
Get technology previously reserved for billion-dollar corporations, FREE
http://pubads.g.doubleclick.net/gampad/clk?id=190641631&iu=/4140/ostg.clktrk
_______________________________________________
edk2-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-commits

Reply via email to