]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPkg/Drivers/ArmGic/ArmGicSec.c
ArmPkg/Drivers/ArmGic: Introduced ArmGicEndOfInterrupt()
[mirror_edk2.git] / ArmPkg / Drivers / ArmGic / ArmGicSec.c
CommitLineData
1bfda055 1/** @file\r
2*\r
bebda7ce 3* Copyright (c) 2011-2013, ARM Limited. All rights reserved.\r
1bfda055 4* \r
5* This program and the accompanying materials \r
6* are licensed and made available under the terms and conditions of the BSD License \r
7* which accompanies this distribution. The full text of the license may be found at \r
8* http://opensource.org/licenses/bsd-license.php \r
9*\r
10* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
11* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
12*\r
13**/\r
14\r
92534106 15#include <Base.h>\r
5e773144 16#include <Library/ArmLib.h>\r
bebda7ce 17#include <Library/ArmPlatformLib.h>\r
92534106 18#include <Library/DebugLib.h>\r
1bfda055 19#include <Library/IoLib.h>\r
55a0d64b 20#include <Library/ArmGicLib.h>\r
1bfda055 21\r
22/*\r
23 * This function configures the all interrupts to be Non-secure.\r
24 *\r
25 */\r
26VOID\r
27EFIAPI\r
55a0d64b 28ArmGicSetupNonSecure (\r
5e773144 29 IN UINTN MpId,\r
1bfda055 30 IN INTN GicDistributorBase,\r
31 IN INTN GicInterruptInterfaceBase\r
32 )\r
33{\r
886f97c8 34 UINTN InterruptId;\r
35 UINTN CachedPriorityMask;\r
92534106 36 UINTN Index;\r
886f97c8 37\r
38 CachedPriorityMask = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR);\r
1bfda055 39\r
9e2b420e 40 // Set priority Mask so that no interrupts get through to CPU\r
886f97c8 41 MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, 0);\r
1bfda055 42\r
81742bb0 43 InterruptId = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIAR);\r
1bfda055 44\r
81742bb0 45 // Only try to clear valid interrupts. Ignore spurious interrupts.\r
46 while ((InterruptId & 0x3FF) < ArmGicGetMaxNumInterrupts (GicDistributorBase)) {\r
47 // Some of the SGI's are still pending, read Ack register and send End of Interrupt Signal\r
d80401a1 48 ArmGicEndOfInterrupt (GicInterruptInterfaceBase, InterruptId);\r
81742bb0 49\r
50 // Next\r
51 InterruptId = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIAR);\r
9e2b420e 52 }\r
1bfda055 53\r
5e773144 54 // Only the primary core should set the Non Secure bit to the SPIs (Shared Peripheral Interrupt).\r
bebda7ce 55 if (ArmPlatformIsPrimaryCore (MpId)) {\r
5e773144 56 // Ensure all GIC interrupts are Non-Secure\r
e9f7c58f 57 for (Index = 0; Index < (ArmGicGetMaxNumInterrupts (GicDistributorBase) / 32); Index++) {\r
5e773144 58 MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISR + (Index * 4), 0xffffffff);\r
59 }\r
60 } else {\r
61 // The secondary cores only set the Non Secure bit to their banked PPIs\r
62 MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISR, 0xffffffff);\r
92534106 63 }\r
1bfda055 64\r
65 // Ensure all interrupts can get through the priority mask\r
886f97c8 66 MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, CachedPriorityMask);\r
1bfda055 67}\r
68\r
92534106 69/*\r
70 * This function configures the interrupts set by the mask to be secure.\r
71 *\r
72 */\r
73VOID\r
74EFIAPI\r
75ArmGicSetSecureInterrupts (\r
76 IN UINTN GicDistributorBase,\r
77 IN UINTN* GicSecureInterruptMask,\r
78 IN UINTN GicSecureInterruptMaskSize\r
79 )\r
80{\r
81 UINTN Index;\r
82 UINT32 InterruptStatus;\r
83\r
84 // We must not have more interrupts defined by the mask than the number of available interrupts\r
e9f7c58f 85 ASSERT(GicSecureInterruptMaskSize <= (ArmGicGetMaxNumInterrupts (GicDistributorBase) / 32));\r
92534106 86\r
87 // Set all the interrupts defined by the mask as Secure\r
88 for (Index = 0; Index < GicSecureInterruptMaskSize; Index++) {\r
89 InterruptStatus = MmioRead32 (GicDistributorBase + ARM_GIC_ICDISR + (Index * 4));\r
90 MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISR + (Index * 4), InterruptStatus & (~GicSecureInterruptMask[Index]));\r
91 }\r
92}\r
93\r
1bfda055 94VOID\r
95EFIAPI\r
55a0d64b 96ArmGicEnableInterruptInterface (\r
1bfda055 97 IN INTN GicInterruptInterfaceBase\r
98 )\r
99{\r
886f97c8 100 // Set Priority Mask to allow interrupts\r
101 MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, 0x000000FF);\r
1bfda055 102\r
886f97c8 103 // Enable CPU interface in Secure world\r
ce88684e 104 // Enable CPU interface in Non-secure World\r
886f97c8 105 // Signal Secure Interrupts to CPU using FIQ line *\r
106 MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR,\r
55a0d64b 107 ARM_GIC_ICCICR_ENABLE_SECURE |\r
108 ARM_GIC_ICCICR_ENABLE_NS |\r
109 ARM_GIC_ICCICR_SIGNAL_SECURE_TO_FIQ);\r
1bfda055 110}\r
111\r
9736c297 112VOID\r
113EFIAPI\r
114ArmGicDisableInterruptInterface (\r
115 IN INTN GicInterruptInterfaceBase\r
116 )\r
117{\r
118 UINT32 ControlValue;\r
119\r
120 // Disable CPU interface in Secure world and Non-secure World\r
121 ControlValue = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR);\r
122 MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR, ControlValue & ~(ARM_GIC_ICCICR_ENABLE_SECURE | ARM_GIC_ICCICR_ENABLE_NS));\r
123}\r
124\r
1bfda055 125VOID\r
126EFIAPI\r
55a0d64b 127ArmGicEnableDistributor (\r
1bfda055 128 IN INTN GicDistributorBase\r
129 )\r
130{\r
886f97c8 131 // Turn on the GIC distributor\r
132 MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 1);\r
1bfda055 133}\r