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 InterruptId
= MmioRead32 (GicInterruptInterfaceBase
+ ARM_GIC_ICCIAR
);
44 // Only try to clear valid interrupts. Ignore spurious interrupts.
45 while ((InterruptId
& 0x3FF) < ArmGicGetMaxNumInterrupts (GicDistributorBase
)) {
46 // Some of the SGI's are still pending, read Ack register and send End of Interrupt Signal
47 MmioWrite32 (GicInterruptInterfaceBase
+ ARM_GIC_ICCEIOR
, InterruptId
);
50 InterruptId
= MmioRead32 (GicInterruptInterfaceBase
+ ARM_GIC_ICCIAR
);
53 // Only the primary core should set the Non Secure bit to the SPIs (Shared Peripheral Interrupt).
54 if (IS_PRIMARY_CORE(MpId
)) {
55 // Ensure all GIC interrupts are Non-Secure
56 for (Index
= 0; Index
< (ArmGicGetMaxNumInterrupts (GicDistributorBase
) / 32); Index
++) {
57 MmioWrite32 (GicDistributorBase
+ ARM_GIC_ICDISR
+ (Index
* 4), 0xffffffff);
60 // The secondary cores only set the Non Secure bit to their banked PPIs
61 MmioWrite32 (GicDistributorBase
+ ARM_GIC_ICDISR
, 0xffffffff);
64 // Ensure all interrupts can get through the priority mask
65 MmioWrite32 (GicInterruptInterfaceBase
+ ARM_GIC_ICCPMR
, CachedPriorityMask
);
69 * This function configures the interrupts set by the mask to be secure.
74 ArmGicSetSecureInterrupts (
75 IN UINTN GicDistributorBase
,
76 IN UINTN
* GicSecureInterruptMask
,
77 IN UINTN GicSecureInterruptMaskSize
81 UINT32 InterruptStatus
;
83 // We must not have more interrupts defined by the mask than the number of available interrupts
84 ASSERT(GicSecureInterruptMaskSize
<= (ArmGicGetMaxNumInterrupts (GicDistributorBase
) / 32));
86 // Set all the interrupts defined by the mask as Secure
87 for (Index
= 0; Index
< GicSecureInterruptMaskSize
; Index
++) {
88 InterruptStatus
= MmioRead32 (GicDistributorBase
+ ARM_GIC_ICDISR
+ (Index
* 4));
89 MmioWrite32 (GicDistributorBase
+ ARM_GIC_ICDISR
+ (Index
* 4), InterruptStatus
& (~GicSecureInterruptMask
[Index
]));
95 ArmGicEnableInterruptInterface (
96 IN INTN GicInterruptInterfaceBase
99 // Set Priority Mask to allow interrupts
100 MmioWrite32 (GicInterruptInterfaceBase
+ ARM_GIC_ICCPMR
, 0x000000FF);
102 // Enable CPU interface in Secure world
103 // Enable CPU interface in Non-secure World
104 // Signal Secure Interrupts to CPU using FIQ line *
105 MmioWrite32 (GicInterruptInterfaceBase
+ ARM_GIC_ICCICR
,
106 ARM_GIC_ICCICR_ENABLE_SECURE
|
107 ARM_GIC_ICCICR_ENABLE_NS
|
108 ARM_GIC_ICCICR_SIGNAL_SECURE_TO_FIQ
);
113 ArmGicDisableInterruptInterface (
114 IN INTN GicInterruptInterfaceBase
119 // Disable CPU interface in Secure world and Non-secure World
120 ControlValue
= MmioRead32 (GicInterruptInterfaceBase
+ ARM_GIC_ICCICR
);
121 MmioWrite32 (GicInterruptInterfaceBase
+ ARM_GIC_ICCICR
, ControlValue
& ~(ARM_GIC_ICCICR_ENABLE_SECURE
| ARM_GIC_ICCICR_ENABLE_NS
));
126 ArmGicEnableDistributor (
127 IN INTN GicDistributorBase
130 // Turn on the GIC distributor
131 MmioWrite32 (GicDistributorBase
+ ARM_GIC_ICDDCR
, 1);