blob: c137c95f20587951a850ce280b20ead406ca4b08 [file] [log] [blame]
andrewfish1bfda052011-02-02 22:35:30 +00001/** @file
2*
oliviermartin5e773142012-03-26 11:03:36 +00003* Copyright (c) 2011-2012, ARM Limited. All rights reserved.
andrewfish1bfda052011-02-02 22:35:30 +00004*
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
9*
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.
12*
13**/
14
oliviermartin92534102012-03-26 10:45:27 +000015#include <Base.h>
oliviermartin5e773142012-03-26 11:03:36 +000016#include <Library/ArmLib.h>
oliviermartin92534102012-03-26 10:45:27 +000017#include <Library/DebugLib.h>
andrewfish1bfda052011-02-02 22:35:30 +000018#include <Library/IoLib.h>
oliviermartin55a0d642011-09-22 22:59:52 +000019#include <Library/ArmGicLib.h>
andrewfish1bfda052011-02-02 22:35:30 +000020
21/*
22 * This function configures the all interrupts to be Non-secure.
23 *
24 */
25VOID
26EFIAPI
oliviermartin55a0d642011-09-22 22:59:52 +000027ArmGicSetupNonSecure (
oliviermartin5e773142012-03-26 11:03:36 +000028 IN UINTN MpId,
andrewfish1bfda052011-02-02 22:35:30 +000029 IN INTN GicDistributorBase,
30 IN INTN GicInterruptInterfaceBase
31 )
32{
oliviermartin886f97c2011-09-27 16:42:47 +000033 UINTN InterruptId;
34 UINTN CachedPriorityMask;
oliviermartin92534102012-03-26 10:45:27 +000035 UINTN Index;
oliviermartin886f97c2011-09-27 16:42:47 +000036
37 CachedPriorityMask = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR);
andrewfish1bfda052011-02-02 22:35:30 +000038
oliviermartin9e2b4202011-06-11 11:15:55 +000039 // Set priority Mask so that no interrupts get through to CPU
oliviermartin886f97c2011-09-27 16:42:47 +000040 MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, 0);
andrewfish1bfda052011-02-02 22:35:30 +000041
oliviermartin9e2b4202011-06-11 11:15:55 +000042 // Check if there are any pending interrupts
oliviermartin55a0d642011-09-22 22:59:52 +000043 //TODO: could be extended to take Peripheral interrupts into consideration, but at the moment only SGI's are taken into consideration.
oliviermartin886f97c2011-09-27 16:42:47 +000044 while(0 != (MmioRead32 (GicDistributorBase + ARM_GIC_ICDICPR) & 0xF)) {
oliviermartin9e2b4202011-06-11 11:15:55 +000045 // Some of the SGI's are still pending, read Ack register and send End of Interrupt Signal
oliviermartin886f97c2011-09-27 16:42:47 +000046 InterruptId = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIAR);
andrewfish1bfda052011-02-02 22:35:30 +000047
oliviermartin9e2b4202011-06-11 11:15:55 +000048 // Write to End of interrupt signal
oliviermartin886f97c2011-09-27 16:42:47 +000049 MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCEIOR, InterruptId);
oliviermartin9e2b4202011-06-11 11:15:55 +000050 }
andrewfish1bfda052011-02-02 22:35:30 +000051
oliviermartin5e773142012-03-26 11:03:36 +000052 // Only the primary core should set the Non Secure bit to the SPIs (Shared Peripheral Interrupt).
53 if (IS_PRIMARY_CORE(MpId)) {
54 // Ensure all GIC interrupts are Non-Secure
oliviermartine9f7c582012-05-02 19:48:00 +000055 for (Index = 0; Index < (ArmGicGetMaxNumInterrupts (GicDistributorBase) / 32); Index++) {
oliviermartin5e773142012-03-26 11:03:36 +000056 MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISR + (Index * 4), 0xffffffff);
57 }
58 } else {
59 // The secondary cores only set the Non Secure bit to their banked PPIs
60 MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISR, 0xffffffff);
oliviermartin92534102012-03-26 10:45:27 +000061 }
andrewfish1bfda052011-02-02 22:35:30 +000062
63 // Ensure all interrupts can get through the priority mask
oliviermartin886f97c2011-09-27 16:42:47 +000064 MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, CachedPriorityMask);
andrewfish1bfda052011-02-02 22:35:30 +000065}
66
oliviermartin92534102012-03-26 10:45:27 +000067/*
68 * This function configures the interrupts set by the mask to be secure.
69 *
70 */
71VOID
72EFIAPI
73ArmGicSetSecureInterrupts (
74 IN UINTN GicDistributorBase,
75 IN UINTN* GicSecureInterruptMask,
76 IN UINTN GicSecureInterruptMaskSize
77 )
78{
79 UINTN Index;
80 UINT32 InterruptStatus;
81
82 // We must not have more interrupts defined by the mask than the number of available interrupts
oliviermartine9f7c582012-05-02 19:48:00 +000083 ASSERT(GicSecureInterruptMaskSize <= (ArmGicGetMaxNumInterrupts (GicDistributorBase) / 32));
oliviermartin92534102012-03-26 10:45:27 +000084
85 // Set all the interrupts defined by the mask as Secure
86 for (Index = 0; Index < GicSecureInterruptMaskSize; Index++) {
87 InterruptStatus = MmioRead32 (GicDistributorBase + ARM_GIC_ICDISR + (Index * 4));
88 MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISR + (Index * 4), InterruptStatus & (~GicSecureInterruptMask[Index]));
89 }
90}
91
andrewfish1bfda052011-02-02 22:35:30 +000092VOID
93EFIAPI
oliviermartin55a0d642011-09-22 22:59:52 +000094ArmGicEnableInterruptInterface (
andrewfish1bfda052011-02-02 22:35:30 +000095 IN INTN GicInterruptInterfaceBase
96 )
97{
oliviermartin886f97c2011-09-27 16:42:47 +000098 // Set Priority Mask to allow interrupts
99 MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, 0x000000FF);
andrewfish1bfda052011-02-02 22:35:30 +0000100
oliviermartin886f97c2011-09-27 16:42:47 +0000101 // Enable CPU interface in Secure world
102 // Enable CPU inteface in Non-secure World
103 // Signal Secure Interrupts to CPU using FIQ line *
104 MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR,
oliviermartin55a0d642011-09-22 22:59:52 +0000105 ARM_GIC_ICCICR_ENABLE_SECURE |
106 ARM_GIC_ICCICR_ENABLE_NS |
107 ARM_GIC_ICCICR_SIGNAL_SECURE_TO_FIQ);
andrewfish1bfda052011-02-02 22:35:30 +0000108}
109
110VOID
111EFIAPI
oliviermartin55a0d642011-09-22 22:59:52 +0000112ArmGicEnableDistributor (
andrewfish1bfda052011-02-02 22:35:30 +0000113 IN INTN GicDistributorBase
114 )
115{
oliviermartin886f97c2011-09-27 16:42:47 +0000116 // Turn on the GIC distributor
117 MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 1);
andrewfish1bfda052011-02-02 22:35:30 +0000118}