X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=ArmPkg%2FDrivers%2FPL390Gic%2FPL390GicSec.c;h=bae76e441ba34c4a2f83d262bd57883efd3d5bbd;hp=46b14e074633b9d830e4cb4a2cf9902d591e6d08;hb=bebda7ceec3d3024c76b3c2ed0c9b4e502a13d61;hpb=1bfda055dfbc52678655ab2ded721f9f7c0cd496 diff --git a/ArmPkg/Drivers/PL390Gic/PL390GicSec.c b/ArmPkg/Drivers/PL390Gic/PL390GicSec.c index 46b14e0746..bae76e441b 100644 --- a/ArmPkg/Drivers/PL390Gic/PL390GicSec.c +++ b/ArmPkg/Drivers/PL390Gic/PL390GicSec.c @@ -1,6 +1,6 @@ /** @file * -* Copyright (c) 2011, ARM Limited. All rights reserved. +* Copyright (c) 2011-2013, 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 @@ -12,8 +12,12 @@ * **/ +#include +#include +#include +#include #include -#include +#include /* * This function configures the all interrupts to be Non-secure. @@ -21,115 +25,109 @@ */ VOID EFIAPI -PL390GicSetupNonSecure ( +ArmGicSetupNonSecure ( + IN UINTN MpId, IN INTN GicDistributorBase, IN INTN GicInterruptInterfaceBase ) { - UINTN CachedPriorityMask = MmioRead32(GicInterruptInterfaceBase + GIC_ICCPMR); + UINTN InterruptId; + UINTN CachedPriorityMask; + UINTN Index; - //Set priority Mask so that no interrupts get through to CPU - MmioWrite32(GicInterruptInterfaceBase + GIC_ICCPMR, 0); + CachedPriorityMask = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR); - //Check if there are any pending interrupts - while(0 != (MmioRead32(GicDistributorBase + GIC_ICDICPR) & 0xF)) - { - //Some of the SGI's are still pending, read Ack register and send End of Interrupt Signal - UINTN InterruptId = MmioRead32(GicInterruptInterfaceBase + GIC_ICCIAR); + // Set priority Mask so that no interrupts get through to CPU + MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, 0); - //Write to End of interrupt signal - MmioWrite32(GicInterruptInterfaceBase + GIC_ICCEIOR, InterruptId); - } + InterruptId = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIAR); - // Ensure all GIC interrupts are Non-Secure - MmioWrite32(GicDistributorBase + GIC_ICDISR, 0xffffffff); // IRQs 0-31 are Non-Secure : Private Peripheral Interrupt[31:16] & Software Generated Interrupt[15:0] - MmioWrite32(GicDistributorBase + GIC_ICDISR + 4, 0xffffffff); // IRQs 32-63 are Non-Secure : Shared Peripheral Interrupt - MmioWrite32(GicDistributorBase + GIC_ICDISR + 8, 0xffffffff); // And another 32 in case we're on the testchip : Shared Peripheral Interrupt (2) + // Only try to clear valid interrupts. Ignore spurious interrupts. + while ((InterruptId & 0x3FF) < ArmGicGetMaxNumInterrupts (GicDistributorBase)) { + // Some of the SGI's are still pending, read Ack register and send End of Interrupt Signal + MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCEIOR, InterruptId); + + // Next + InterruptId = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIAR); + } + + // Only the primary core should set the Non Secure bit to the SPIs (Shared Peripheral Interrupt). + if (ArmPlatformIsPrimaryCore (MpId)) { + // Ensure all GIC interrupts are Non-Secure + for (Index = 0; Index < (ArmGicGetMaxNumInterrupts (GicDistributorBase) / 32); Index++) { + MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISR + (Index * 4), 0xffffffff); + } + } else { + // The secondary cores only set the Non Secure bit to their banked PPIs + MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISR, 0xffffffff); + } // Ensure all interrupts can get through the priority mask - MmioWrite32(GicInterruptInterfaceBase + GIC_ICCPMR, CachedPriorityMask); + MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, CachedPriorityMask); } +/* + * This function configures the interrupts set by the mask to be secure. + * + */ VOID EFIAPI -PL390GicEnableInterruptInterface ( - IN INTN GicInterruptInterfaceBase +ArmGicSetSecureInterrupts ( + IN UINTN GicDistributorBase, + IN UINTN* GicSecureInterruptMask, + IN UINTN GicSecureInterruptMaskSize ) { - MmioWrite32(GicInterruptInterfaceBase + GIC_ICCPMR, 0x000000FF); /* Set Priority Mask to allow interrupts */ - - /* - * Enable CPU interface in Secure world - * Enable CPU inteface in Non-secure World - * Signal Secure Interrupts to CPU using FIQ line * - */ - MmioWrite32(GicInterruptInterfaceBase + GIC_ICCICR, - GIC_ICCICR_ENABLE_SECURE(1) | - GIC_ICCICR_ENABLE_NS(1) | - GIC_ICCICR_ACK_CTL(0) | - GIC_ICCICR_SIGNAL_SECURE_TO_FIQ(1) | - GIC_ICCICR_USE_SBPR(0)); -} + UINTN Index; + UINT32 InterruptStatus; -VOID -EFIAPI -PL390GicEnableDistributor ( - IN INTN GicDistributorBase - ) -{ - MmioWrite32(GicDistributorBase + GIC_ICDDCR, 1); // turn on the GIC distributor + // We must not have more interrupts defined by the mask than the number of available interrupts + ASSERT(GicSecureInterruptMaskSize <= (ArmGicGetMaxNumInterrupts (GicDistributorBase) / 32)); + + // Set all the interrupts defined by the mask as Secure + for (Index = 0; Index < GicSecureInterruptMaskSize; Index++) { + InterruptStatus = MmioRead32 (GicDistributorBase + ARM_GIC_ICDISR + (Index * 4)); + MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISR + (Index * 4), InterruptStatus & (~GicSecureInterruptMask[Index])); + } } VOID EFIAPI -PL390GicSendSgiTo ( - IN INTN GicDistributorBase, - IN INTN TargetListFilter, - IN INTN CPUTargetList +ArmGicEnableInterruptInterface ( + IN INTN GicInterruptInterfaceBase ) { - MmioWrite32(GicDistributorBase + GIC_ICDSGIR, ((TargetListFilter & 0x3) << 24) | ((CPUTargetList & 0xFF) << 16)); + // Set Priority Mask to allow interrupts + MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, 0x000000FF); + + // Enable CPU interface in Secure world + // Enable CPU interface in Non-secure World + // Signal Secure Interrupts to CPU using FIQ line * + MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR, + ARM_GIC_ICCICR_ENABLE_SECURE | + ARM_GIC_ICCICR_ENABLE_NS | + ARM_GIC_ICCICR_SIGNAL_SECURE_TO_FIQ); } -UINT32 +VOID EFIAPI -PL390GicAcknowledgeSgiFrom ( - IN INTN GicInterruptInterfaceBase, - IN INTN CoreId +ArmGicDisableInterruptInterface ( + IN INTN GicInterruptInterfaceBase ) { - INTN InterruptId; - - InterruptId = MmioRead32(GicInterruptInterfaceBase + GIC_ICCIAR); + UINT32 ControlValue; - //Check if the Interrupt ID is valid, The read from Interrupt Ack register returns CPU ID and Interrupt ID - if (((CoreId & 0x7) << 10) == (InterruptId & 0x1C00)) { - //Got SGI number 0 hence signal End of Interrupt by writing to ICCEOIR - MmioWrite32(GicInterruptInterfaceBase + GIC_ICCEIOR, InterruptId); - return 1; - } else { - return 0; - } + // Disable CPU interface in Secure world and Non-secure World + ControlValue = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR); + MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR, ControlValue & ~(ARM_GIC_ICCICR_ENABLE_SECURE | ARM_GIC_ICCICR_ENABLE_NS)); } -UINT32 +VOID EFIAPI -PL390GicAcknowledgeSgi2From ( - IN INTN GicInterruptInterfaceBase, - IN INTN CoreId, - IN INTN SgiId +ArmGicEnableDistributor ( + IN INTN GicDistributorBase ) { - INTN InterruptId; - - InterruptId = MmioRead32(GicInterruptInterfaceBase + GIC_ICCIAR); - - //Check if the Interrupt ID is valid, The read from Interrupt Ack register returns CPU ID and Interrupt ID - if((((CoreId & 0x7) << 10) | (SgiId & 0x3FF)) == (InterruptId & 0x1FFF)) { - //Got SGI number 0 hence signal End of Interrupt by writing to ICCEOIR - MmioWrite32(GicInterruptInterfaceBase + GIC_ICCEIOR, InterruptId); - return 1; - } else { - return 0; - } + // Turn on the GIC distributor + MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 1); }