3 * Copyright (c) 2011-2013, 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/ArmPlatformLib.h>
18 #include <Library/DebugLib.h>
19 #include <Library/IoLib.h>
20 #include <Library/ArmGicLib.h>
23 * This function configures the all interrupts to be Non-secure.
28 ArmGicSetupNonSecure (
30 IN INTN GicDistributorBase
,
31 IN INTN GicInterruptInterfaceBase
35 UINTN CachedPriorityMask
;
38 CachedPriorityMask
= MmioRead32 (GicInterruptInterfaceBase
+ ARM_GIC_ICCPMR
);
40 // Set priority Mask so that no interrupts get through to CPU
41 MmioWrite32 (GicInterruptInterfaceBase
+ ARM_GIC_ICCPMR
, 0);
43 InterruptId
= MmioRead32 (GicInterruptInterfaceBase
+ ARM_GIC_ICCIAR
);
45 // Only try to clear valid interrupts. Ignore spurious interrupts.
46 while ((InterruptId
& 0x3FF) < ArmGicGetMaxNumInterrupts (GicDistributorBase
)) {
47 // Some of the SGI's are still pending, read Ack register and send End of Interrupt Signal
48 MmioWrite32 (GicInterruptInterfaceBase
+ ARM_GIC_ICCEIOR
, InterruptId
);
51 InterruptId
= MmioRead32 (GicInterruptInterfaceBase
+ ARM_GIC_ICCIAR
);
54 // Only the primary core should set the Non Secure bit to the SPIs (Shared Peripheral Interrupt).
55 if (ArmPlatformIsPrimaryCore (MpId
)) {
56 // Ensure all GIC interrupts are Non-Secure
57 for (Index
= 0; Index
< (ArmGicGetMaxNumInterrupts (GicDistributorBase
) / 32); Index
++) {
58 MmioWrite32 (GicDistributorBase
+ ARM_GIC_ICDISR
+ (Index
* 4), 0xffffffff);
61 // The secondary cores only set the Non Secure bit to their banked PPIs
62 MmioWrite32 (GicDistributorBase
+ ARM_GIC_ICDISR
, 0xffffffff);
65 // Ensure all interrupts can get through the priority mask
66 MmioWrite32 (GicInterruptInterfaceBase
+ ARM_GIC_ICCPMR
, CachedPriorityMask
);
70 * This function configures the interrupts set by the mask to be secure.
75 ArmGicSetSecureInterrupts (
76 IN UINTN GicDistributorBase
,
77 IN UINTN
* GicSecureInterruptMask
,
78 IN UINTN GicSecureInterruptMaskSize
82 UINT32 InterruptStatus
;
84 // We must not have more interrupts defined by the mask than the number of available interrupts
85 ASSERT(GicSecureInterruptMaskSize
<= (ArmGicGetMaxNumInterrupts (GicDistributorBase
) / 32));
87 // Set all the interrupts defined by the mask as Secure
88 for (Index
= 0; Index
< GicSecureInterruptMaskSize
; Index
++) {
89 InterruptStatus
= MmioRead32 (GicDistributorBase
+ ARM_GIC_ICDISR
+ (Index
* 4));
90 MmioWrite32 (GicDistributorBase
+ ARM_GIC_ICDISR
+ (Index
* 4), InterruptStatus
& (~GicSecureInterruptMask
[Index
]));
96 ArmGicEnableInterruptInterface (
97 IN INTN GicInterruptInterfaceBase
100 // Set Priority Mask to allow interrupts
101 MmioWrite32 (GicInterruptInterfaceBase
+ ARM_GIC_ICCPMR
, 0x000000FF);
103 // Enable CPU interface in Secure world
104 // Enable CPU interface in Non-secure World
105 // Signal Secure Interrupts to CPU using FIQ line *
106 MmioWrite32 (GicInterruptInterfaceBase
+ ARM_GIC_ICCICR
,
107 ARM_GIC_ICCICR_ENABLE_SECURE
|
108 ARM_GIC_ICCICR_ENABLE_NS
|
109 ARM_GIC_ICCICR_SIGNAL_SECURE_TO_FIQ
);
114 ArmGicDisableInterruptInterface (
115 IN INTN GicInterruptInterfaceBase
120 // Disable CPU interface in Secure world and Non-secure World
121 ControlValue
= MmioRead32 (GicInterruptInterfaceBase
+ ARM_GIC_ICCICR
);
122 MmioWrite32 (GicInterruptInterfaceBase
+ ARM_GIC_ICCICR
, ControlValue
& ~(ARM_GIC_ICCICR_ENABLE_SECURE
| ARM_GIC_ICCICR_ENABLE_NS
));
127 ArmGicEnableDistributor (
128 IN INTN GicDistributorBase
131 // Turn on the GIC distributor
132 MmioWrite32 (GicDistributorBase
+ ARM_GIC_ICDDCR
, 1);