]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - ArmPkg/Drivers/PL390Gic/PL390GicSec.c
ArmPkg/ArmGicLib: Added function ArmGicSetSecureInterrupts() to define the secure...
[mirror_edk2.git] / ArmPkg / Drivers / PL390Gic / PL390GicSec.c
... / ...
CommitLineData
1/** @file\r
2*\r
3* Copyright (c) 2011, ARM Limited. All rights reserved.\r
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
15#include <Base.h>\r
16#include <Library/DebugLib.h>\r
17#include <Library/IoLib.h>\r
18#include <Library/ArmGicLib.h>\r
19\r
20/*\r
21 * This function configures the all interrupts to be Non-secure.\r
22 *\r
23 */\r
24VOID\r
25EFIAPI\r
26ArmGicSetupNonSecure (\r
27 IN INTN GicDistributorBase,\r
28 IN INTN GicInterruptInterfaceBase\r
29 )\r
30{\r
31 UINTN InterruptId;\r
32 UINTN CachedPriorityMask;\r
33 UINTN Index;\r
34\r
35 CachedPriorityMask = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR);\r
36\r
37 // Set priority Mask so that no interrupts get through to CPU\r
38 MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, 0);\r
39\r
40 // Check if there are any pending interrupts\r
41 //TODO: could be extended to take Peripheral interrupts into consideration, but at the moment only SGI's are taken into consideration.\r
42 while(0 != (MmioRead32 (GicDistributorBase + ARM_GIC_ICDICPR) & 0xF)) {\r
43 // Some of the SGI's are still pending, read Ack register and send End of Interrupt Signal\r
44 InterruptId = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIAR);\r
45\r
46 // Write to End of interrupt signal\r
47 MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCEIOR, InterruptId);\r
48 }\r
49\r
50 // Ensure all GIC interrupts are Non-Secure\r
51 for (Index = 0; Index < (PcdGet32(PcdGicNumInterrupts) / 32); Index++) {\r
52 MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISR + (Index * 4), 0xffffffff);\r
53 }\r
54\r
55 // Ensure all interrupts can get through the priority mask\r
56 MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, CachedPriorityMask);\r
57}\r
58\r
59/*\r
60 * This function configures the interrupts set by the mask to be secure.\r
61 *\r
62 */\r
63VOID\r
64EFIAPI\r
65ArmGicSetSecureInterrupts (\r
66 IN UINTN GicDistributorBase,\r
67 IN UINTN* GicSecureInterruptMask,\r
68 IN UINTN GicSecureInterruptMaskSize\r
69 )\r
70{\r
71 UINTN Index;\r
72 UINT32 InterruptStatus;\r
73\r
74 // We must not have more interrupts defined by the mask than the number of available interrupts\r
75 ASSERT(GicSecureInterruptMaskSize <= (PcdGet32(PcdGicNumInterrupts) / 32));\r
76\r
77 // Set all the interrupts defined by the mask as Secure\r
78 for (Index = 0; Index < GicSecureInterruptMaskSize; Index++) {\r
79 InterruptStatus = MmioRead32 (GicDistributorBase + ARM_GIC_ICDISR + (Index * 4));\r
80 MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISR + (Index * 4), InterruptStatus & (~GicSecureInterruptMask[Index]));\r
81 }\r
82}\r
83\r
84VOID\r
85EFIAPI\r
86ArmGicEnableInterruptInterface (\r
87 IN INTN GicInterruptInterfaceBase\r
88 )\r
89{\r
90 // Set Priority Mask to allow interrupts\r
91 MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, 0x000000FF);\r
92\r
93 // Enable CPU interface in Secure world\r
94 // Enable CPU inteface in Non-secure World\r
95 // Signal Secure Interrupts to CPU using FIQ line *\r
96 MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR,\r
97 ARM_GIC_ICCICR_ENABLE_SECURE |\r
98 ARM_GIC_ICCICR_ENABLE_NS |\r
99 ARM_GIC_ICCICR_SIGNAL_SECURE_TO_FIQ);\r
100}\r
101\r
102VOID\r
103EFIAPI\r
104ArmGicEnableDistributor (\r
105 IN INTN GicDistributorBase\r
106 )\r
107{\r
108 // Turn on the GIC distributor\r
109 MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 1);\r
110}\r