]> git.proxmox.com Git - mirror_edk2.git/blame - ArmPkg/Drivers/PL390Gic/PL390GicSec.c
ArmPkg/PL390Gic: Added support for ArmGicDisableInterruptInterface()
[mirror_edk2.git] / ArmPkg / Drivers / PL390Gic / PL390GicSec.c
CommitLineData
1bfda055 1/** @file\r
2*\r
5e773144 3* Copyright (c) 2011-2012, 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
92534106 17#include <Library/DebugLib.h>\r
1bfda055 18#include <Library/IoLib.h>\r
55a0d64b 19#include <Library/ArmGicLib.h>\r
1bfda055 20\r
21/*\r
22 * This function configures the all interrupts to be Non-secure.\r
23 *\r
24 */\r
25VOID\r
26EFIAPI\r
55a0d64b 27ArmGicSetupNonSecure (\r
5e773144 28 IN UINTN MpId,\r
1bfda055 29 IN INTN GicDistributorBase,\r
30 IN INTN GicInterruptInterfaceBase\r
31 )\r
32{\r
886f97c8 33 UINTN InterruptId;\r
34 UINTN CachedPriorityMask;\r
92534106 35 UINTN Index;\r
886f97c8 36\r
37 CachedPriorityMask = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR);\r
1bfda055 38\r
9e2b420e 39 // Set priority Mask so that no interrupts get through to CPU\r
886f97c8 40 MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, 0);\r
1bfda055 41\r
9e2b420e 42 // Check if there are any pending interrupts\r
55a0d64b 43 //TODO: could be extended to take Peripheral interrupts into consideration, but at the moment only SGI's are taken into consideration.\r
886f97c8 44 while(0 != (MmioRead32 (GicDistributorBase + ARM_GIC_ICDICPR) & 0xF)) {\r
9e2b420e 45 // Some of the SGI's are still pending, read Ack register and send End of Interrupt Signal\r
886f97c8 46 InterruptId = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIAR);\r
1bfda055 47\r
9e2b420e 48 // Write to End of interrupt signal\r
886f97c8 49 MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCEIOR, InterruptId);\r
9e2b420e 50 }\r
1bfda055 51\r
5e773144 52 // Only the primary core should set the Non Secure bit to the SPIs (Shared Peripheral Interrupt).\r
53 if (IS_PRIMARY_CORE(MpId)) {\r
54 // Ensure all GIC interrupts are Non-Secure\r
e9f7c58f 55 for (Index = 0; Index < (ArmGicGetMaxNumInterrupts (GicDistributorBase) / 32); Index++) {\r
5e773144 56 MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISR + (Index * 4), 0xffffffff);\r
57 }\r
58 } else {\r
59 // The secondary cores only set the Non Secure bit to their banked PPIs\r
60 MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISR, 0xffffffff);\r
92534106 61 }\r
1bfda055 62\r
63 // Ensure all interrupts can get through the priority mask\r
886f97c8 64 MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, CachedPriorityMask);\r
1bfda055 65}\r
66\r
92534106 67/*\r
68 * This function configures the interrupts set by the mask to be secure.\r
69 *\r
70 */\r
71VOID\r
72EFIAPI\r
73ArmGicSetSecureInterrupts (\r
74 IN UINTN GicDistributorBase,\r
75 IN UINTN* GicSecureInterruptMask,\r
76 IN UINTN GicSecureInterruptMaskSize\r
77 )\r
78{\r
79 UINTN Index;\r
80 UINT32 InterruptStatus;\r
81\r
82 // We must not have more interrupts defined by the mask than the number of available interrupts\r
e9f7c58f 83 ASSERT(GicSecureInterruptMaskSize <= (ArmGicGetMaxNumInterrupts (GicDistributorBase) / 32));\r
92534106 84\r
85 // Set all the interrupts defined by the mask as Secure\r
86 for (Index = 0; Index < GicSecureInterruptMaskSize; Index++) {\r
87 InterruptStatus = MmioRead32 (GicDistributorBase + ARM_GIC_ICDISR + (Index * 4));\r
88 MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISR + (Index * 4), InterruptStatus & (~GicSecureInterruptMask[Index]));\r
89 }\r
90}\r
91\r
1bfda055 92VOID\r
93EFIAPI\r
55a0d64b 94ArmGicEnableInterruptInterface (\r
1bfda055 95 IN INTN GicInterruptInterfaceBase\r
96 )\r
97{\r
886f97c8 98 // Set Priority Mask to allow interrupts\r
99 MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, 0x000000FF);\r
1bfda055 100\r
886f97c8 101 // Enable CPU interface in Secure world\r
102 // Enable CPU inteface in Non-secure World\r
103 // Signal Secure Interrupts to CPU using FIQ line *\r
104 MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR,\r
55a0d64b 105 ARM_GIC_ICCICR_ENABLE_SECURE |\r
106 ARM_GIC_ICCICR_ENABLE_NS |\r
107 ARM_GIC_ICCICR_SIGNAL_SECURE_TO_FIQ);\r
1bfda055 108}\r
109\r
9736c297 110VOID\r
111EFIAPI\r
112ArmGicDisableInterruptInterface (\r
113 IN INTN GicInterruptInterfaceBase\r
114 )\r
115{\r
116 UINT32 ControlValue;\r
117\r
118 // Disable CPU interface in Secure world and Non-secure World\r
119 ControlValue = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR);\r
120 MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR, ControlValue & ~(ARM_GIC_ICCICR_ENABLE_SECURE | ARM_GIC_ICCICR_ENABLE_NS));\r
121}\r
122\r
1bfda055 123VOID\r
124EFIAPI\r
55a0d64b 125ArmGicEnableDistributor (\r
1bfda055 126 IN INTN GicDistributorBase\r
127 )\r
128{\r
886f97c8 129 // Turn on the GIC distributor\r
130 MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 1);\r
1bfda055 131}\r