diff options
author | Olivier Martin <olivier.martin@arm.com> | 2015-02-16 10:23:42 +0000 |
---|---|---|
committer | oliviermartin <oliviermartin@Edk2> | 2015-02-16 10:23:42 +0000 |
commit | 41fb5d4634c17c042e0a3b2be0e8db85d2a083ad (patch) | |
tree | 12aca0d20fbd7fd1758ba182fd36ee07b1e2708a /ArmPkg/Drivers/ArmGic/ArmGicLib.c | |
parent | 8705cb380654b80fc7b4c2863b1bed521d2a9f82 (diff) | |
download | edk2-41fb5d4634c17c042e0a3b2be0e8db85d2a083ad.tar.gz edk2-41fb5d4634c17c042e0a3b2be0e8db85d2a083ad.tar.bz2 edk2-41fb5d4634c17c042e0a3b2be0e8db85d2a083ad.zip |
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 <olivier.martin@arm.com>
Tested-by: Ard Biesheuvel <ard@linaro.org>
Reviewed-by: Ard Biesheuvel <ard@linaro.org>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16874 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'ArmPkg/Drivers/ArmGic/ArmGicLib.c')
-rw-r--r-- | ArmPkg/Drivers/ArmGic/ArmGicLib.c | 68 |
1 files changed, 57 insertions, 11 deletions
diff --git a/ArmPkg/Drivers/ArmGic/ArmGicLib.c b/ArmPkg/Drivers/ArmGic/ArmGicLib.c index 1e213019fe..7c53e39793 100644 --- a/ArmPkg/Drivers/ArmGic/ArmGicLib.c +++ b/ArmPkg/Drivers/ArmGic/ArmGicLib.c @@ -172,53 +172,99 @@ VOID 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
|