Home | History | Annotate | Download | only in GicV2
      1 /** @file
      2 *
      3 *  Copyright (c) 2011-2014, ARM Limited. All rights reserved.
      4 *
      5 *  This program and the accompanying materials
      6 *  are licensed and made available under the terms and conditions of the BSD License
      7 *  which accompanies this distribution.  The full text of the license may be found at
      8 *  http://opensource.org/licenses/bsd-license.php
      9 *
     10 *  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11 *  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 *
     13 **/
     14 
     15 #include <Base.h>
     16 #include <Library/ArmLib.h>
     17 #include <Library/ArmPlatformLib.h>
     18 #include <Library/DebugLib.h>
     19 #include <Library/IoLib.h>
     20 #include <Library/ArmGicLib.h>
     21 
     22 /*
     23  * This function configures the all interrupts to be Non-secure.
     24  *
     25  */
     26 VOID
     27 EFIAPI
     28 ArmGicV2SetupNonSecure (
     29   IN  UINTN         MpId,
     30   IN  INTN          GicDistributorBase,
     31   IN  INTN          GicInterruptInterfaceBase
     32   )
     33 {
     34   UINTN InterruptId;
     35   UINTN CachedPriorityMask;
     36   UINTN Index;
     37   UINTN MaxInterrupts;
     38 
     39   CachedPriorityMask = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR);
     40 
     41   // Set priority Mask so that no interrupts get through to CPU
     42   MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, 0);
     43 
     44   InterruptId   = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIAR);
     45   MaxInterrupts = ArmGicGetMaxNumInterrupts (GicDistributorBase);
     46 
     47   // Only try to clear valid interrupts. Ignore spurious interrupts.
     48   while ((InterruptId & 0x3FF) < MaxInterrupts) {
     49     // Some of the SGI's are still pending, read Ack register and send End of Interrupt Signal
     50     ArmGicEndOfInterrupt (GicInterruptInterfaceBase, InterruptId);
     51 
     52     // Next
     53     InterruptId = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIAR);
     54   }
     55 
     56   // Only the primary core should set the Non Secure bit to the SPIs (Shared Peripheral Interrupt).
     57   if (ArmPlatformIsPrimaryCore (MpId)) {
     58     // Ensure all GIC interrupts are Non-Secure
     59     for (Index = 0; Index < (MaxInterrupts / 32); Index++) {
     60       MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISR + (Index * 4), 0xffffffff);
     61     }
     62   } else {
     63     // The secondary cores only set the Non Secure bit to their banked PPIs
     64     MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISR, 0xffffffff);
     65   }
     66 
     67   // Ensure all interrupts can get through the priority mask
     68   MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, CachedPriorityMask);
     69 }
     70 
     71 VOID
     72 EFIAPI
     73 ArmGicV2EnableInterruptInterface (
     74   IN  INTN          GicInterruptInterfaceBase
     75   )
     76 {
     77   // Set Priority Mask to allow interrupts
     78   MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, 0x000000FF);
     79 
     80   // Enable CPU interface in Secure world
     81   // Enable CPU interface in Non-secure World
     82   // Signal Secure Interrupts to CPU using FIQ line *
     83   MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR,
     84       ARM_GIC_ICCICR_ENABLE_SECURE |
     85       ARM_GIC_ICCICR_ENABLE_NS |
     86       ARM_GIC_ICCICR_SIGNAL_SECURE_TO_FIQ);
     87 }
     88 
     89 VOID
     90 EFIAPI
     91 ArmGicV2DisableInterruptInterface (
     92   IN  INTN          GicInterruptInterfaceBase
     93   )
     94 {
     95   UINT32    ControlValue;
     96 
     97   // Disable CPU interface in Secure world and Non-secure World
     98   ControlValue = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR);
     99   MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR, ControlValue & ~(ARM_GIC_ICCICR_ENABLE_SECURE | ARM_GIC_ICCICR_ENABLE_NS));
    100 }
    101