• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
ArmGicV2SetupNonSecure(IN UINTN MpId,IN INTN GicDistributorBase,IN INTN GicInterruptInterfaceBase)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
ArmGicV2EnableInterruptInterface(IN INTN GicInterruptInterfaceBase)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
ArmGicV2DisableInterruptInterface(IN INTN GicInterruptInterfaceBase)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