X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=ArmPkg%2FDrivers%2FPL390Gic%2FPL390GicSec.c;h=4f10e4e5129ded2c4aad6bf40be238404e15e476;hp=46b14e074633b9d830e4cb4a2cf9902d591e6d08;hb=9253410646466768a15099ac169f9ee852b2f563;hpb=1bfda055dfbc52678655ab2ded721f9f7c0cd496 diff --git a/ArmPkg/Drivers/PL390Gic/PL390GicSec.c b/ArmPkg/Drivers/PL390Gic/PL390GicSec.c index 46b14e0746..4f10e4e512 100644 --- a/ArmPkg/Drivers/PL390Gic/PL390GicSec.c +++ b/ArmPkg/Drivers/PL390Gic/PL390GicSec.c @@ -12,8 +12,10 @@ * **/ +#include +#include #include -#include +#include /* * This function configures the all interrupts to be Non-secure. @@ -21,115 +23,88 @@ */ VOID EFIAPI -PL390GicSetupNonSecure ( +ArmGicSetupNonSecure ( 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); - } + // Check if there are any pending interrupts + //TODO: could be extended to take Peripheral interrupts into consideration, but at the moment only SGI's are taken into consideration. + while(0 != (MmioRead32 (GicDistributorBase + ARM_GIC_ICDICPR) & 0xF)) { + // Some of the SGI's are still pending, read Ack register and send End of Interrupt Signal + InterruptId = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIAR); + + // Write to End of interrupt signal + MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCEIOR, InterruptId); + } // 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) + for (Index = 0; Index < (PcdGet32(PcdGicNumInterrupts) / 32); Index++) { + MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISR + (Index * 4), 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 */ + UINTN Index; + UINT32 InterruptStatus; - /* - * 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)); -} + // We must not have more interrupts defined by the mask than the number of available interrupts + ASSERT(GicSecureInterruptMaskSize <= (PcdGet32(PcdGicNumInterrupts) / 32)); -VOID -EFIAPI -PL390GicEnableDistributor ( - IN INTN GicDistributorBase - ) -{ - MmioWrite32(GicDistributorBase + GIC_ICDDCR, 1); // turn on the GIC distributor + // 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 - ) -{ - MmioWrite32(GicDistributorBase + GIC_ICDSGIR, ((TargetListFilter & 0x3) << 24) | ((CPUTargetList & 0xFF) << 16)); -} - -UINT32 -EFIAPI -PL390GicAcknowledgeSgiFrom ( - IN INTN GicInterruptInterfaceBase, - IN INTN CoreId +ArmGicEnableInterruptInterface ( + IN INTN GicInterruptInterfaceBase ) { - 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) == (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; - } + // Set Priority Mask to allow interrupts + MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, 0x000000FF); + + // Enable CPU interface in Secure world + // Enable CPU inteface 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 -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); }