3 * Copyright (c) 2011-2012, ARM Limited. All rights reserved.
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
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.
16 #include <Library/ArmLib.h>
17 #include <Library/DebugLib.h>
18 #include <Library/IoLib.h>
19 #include <Library/ArmGicLib.h>
22 * This function configures the all interrupts to be Non-secure.
27 ArmGicSetupNonSecure (
29 IN INTN GicDistributorBase
,
30 IN INTN GicInterruptInterfaceBase
34 UINTN CachedPriorityMask
;
37 CachedPriorityMask
= MmioRead32 (GicInterruptInterfaceBase
+ ARM_GIC_ICCPMR
);
39 // Set priority Mask so that no interrupts get through to CPU
40 MmioWrite32 (GicInterruptInterfaceBase
+ ARM_GIC_ICCPMR
, 0);
42 // Check if there are any pending interrupts
43 //TODO: could be extended to take Peripheral interrupts into consideration, but at the moment only SGI's are taken into consideration.
44 while(0 != (MmioRead32 (GicDistributorBase
+ ARM_GIC_ICDICPR
) & 0xF)) {
45 // Some of the SGI's are still pending, read Ack register and send End of Interrupt Signal
46 InterruptId
= MmioRead32 (GicInterruptInterfaceBase
+ ARM_GIC_ICCIAR
);
48 // Write to End of interrupt signal
49 MmioWrite32 (GicInterruptInterfaceBase
+ ARM_GIC_ICCEIOR
, InterruptId
);
52 // Only the primary core should set the Non Secure bit to the SPIs (Shared Peripheral Interrupt).
53 if (IS_PRIMARY_CORE(MpId
)) {
54 // Ensure all GIC interrupts are Non-Secure
55 for (Index
= 0; Index
< (ArmGicGetMaxNumInterrupts (GicDistributorBase
) / 32); Index
++) {
56 MmioWrite32 (GicDistributorBase
+ ARM_GIC_ICDISR
+ (Index
* 4), 0xffffffff);
59 // The secondary cores only set the Non Secure bit to their banked PPIs
60 MmioWrite32 (GicDistributorBase
+ ARM_GIC_ICDISR
, 0xffffffff);
63 // Ensure all interrupts can get through the priority mask
64 MmioWrite32 (GicInterruptInterfaceBase
+ ARM_GIC_ICCPMR
, CachedPriorityMask
);
68 * This function configures the interrupts set by the mask to be secure.
73 ArmGicSetSecureInterrupts (
74 IN UINTN GicDistributorBase
,
75 IN UINTN
* GicSecureInterruptMask
,
76 IN UINTN GicSecureInterruptMaskSize
80 UINT32 InterruptStatus
;
82 // We must not have more interrupts defined by the mask than the number of available interrupts
83 ASSERT(GicSecureInterruptMaskSize
<= (ArmGicGetMaxNumInterrupts (GicDistributorBase
) / 32));
85 // Set all the interrupts defined by the mask as Secure
86 for (Index
= 0; Index
< GicSecureInterruptMaskSize
; Index
++) {
87 InterruptStatus
= MmioRead32 (GicDistributorBase
+ ARM_GIC_ICDISR
+ (Index
* 4));
88 MmioWrite32 (GicDistributorBase
+ ARM_GIC_ICDISR
+ (Index
* 4), InterruptStatus
& (~GicSecureInterruptMask
[Index
]));
94 ArmGicEnableInterruptInterface (
95 IN INTN GicInterruptInterfaceBase
98 // Set Priority Mask to allow interrupts
99 MmioWrite32 (GicInterruptInterfaceBase
+ ARM_GIC_ICCPMR
, 0x000000FF);
101 // Enable CPU interface in Secure world
102 // Enable CPU inteface in Non-secure World
103 // Signal Secure Interrupts to CPU using FIQ line *
104 MmioWrite32 (GicInterruptInterfaceBase
+ ARM_GIC_ICCICR
,
105 ARM_GIC_ICCICR_ENABLE_SECURE
|
106 ARM_GIC_ICCICR_ENABLE_NS
|
107 ARM_GIC_ICCICR_SIGNAL_SECURE_TO_FIQ
);
112 ArmGicEnableDistributor (
113 IN INTN GicDistributorBase
116 // Turn on the GIC distributor
117 MmioWrite32 (GicDistributorBase
+ ARM_GIC_ICDDCR
, 1);