]> git.proxmox.com Git - mirror_edk2.git/blob - ArmPkg/Drivers/PL390Gic/PL390Gic.c
ArmPkg/ArmGicLib: Changed ArmGicSendSgiTo() to allow to send a specific SGI
[mirror_edk2.git] / ArmPkg / Drivers / PL390Gic / PL390Gic.c
1 /** @file
2 *
3 * Copyright (c) 2011-2012, ARM Limited. All rights reserved.
4 *
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
15 #include <Uefi.h>
16 #include <Library/IoLib.h>
17 #include <Library/ArmGicLib.h>
18 #include <Library/PcdLib.h>
19
20 UINTN
21 EFIAPI
22 ArmGicGetMaxNumInterrupts (
23 IN INTN GicDistributorBase
24 )
25 {
26 return 32 * ((MmioRead32 (GicDistributorBase + ARM_GIC_ICDICTR) & 0x1F) + 1);
27 }
28
29 VOID
30 EFIAPI
31 ArmGicSendSgiTo (
32 IN INTN GicDistributorBase,
33 IN INTN TargetListFilter,
34 IN INTN CPUTargetList,
35 IN INTN SgiId
36 )
37 {
38 MmioWrite32 (GicDistributorBase + ARM_GIC_ICDSGIR, ((TargetListFilter & 0x3) << 24) | ((CPUTargetList & 0xFF) << 16) | SgiId);
39 }
40
41 UINT32
42 EFIAPI
43 ArmGicAcknowledgeSgiFrom (
44 IN INTN GicInterruptInterfaceBase,
45 IN INTN CoreId
46 )
47 {
48 INTN InterruptId;
49
50 InterruptId = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIAR);
51
52 // Check if the Interrupt ID is valid, The read from Interrupt Ack register returns CPU ID and Interrupt ID
53 if ((((CoreId & 0x7) << 10) | PcdGet32(PcdGicSgiIntId)) == InterruptId) {
54 // Got SGI number 0 hence signal End of Interrupt by writing to ICCEOIR
55 MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCEIOR, InterruptId);
56 return 1;
57 } else {
58 return 0;
59 }
60 }
61
62 UINT32
63 EFIAPI
64 ArmGicAcknowledgeSgi2From (
65 IN INTN GicInterruptInterfaceBase,
66 IN INTN CoreId,
67 IN INTN SgiId
68 )
69 {
70 INTN InterruptId;
71
72 InterruptId = MmioRead32(GicInterruptInterfaceBase + ARM_GIC_ICCIAR);
73
74 // Check if the Interrupt ID is valid, The read from Interrupt Ack register returns CPU ID and Interrupt ID
75 if((((CoreId & 0x7) << 10) | (SgiId & 0x3FF)) == (InterruptId & 0x1FFF)) {
76 // Got SGI number 0 hence signal End of Interrupt by writing to ICCEOIR
77 MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCEIOR, InterruptId);
78 return 1;
79 } else {
80 return 0;
81 }
82 }