@@ -7,18 +7,63 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
7
7
--*/
8
8
9
9
#include "ArmGicDxe.h"
10
+ #include "Uefi/UefiBaseType.h"
10
11
11
12
// Making this global saves a few bytes in image size
12
13
EFI_HANDLE gHardwareInterruptHandle = NULL ;
13
14
14
15
// Notifications
15
16
EFI_EVENT EfiExitBootServicesEvent = (EFI_EVENT )NULL ;
16
17
17
- // Maximum Number of Interrupts
18
- UINTN mGicNumInterrupts = 0 ;
18
+ EFI_CPU_ARCH_PROTOCOL * gCpuArch ;
19
19
20
- HARDWARE_INTERRUPT_HANDLER * gRegisteredInterruptHandlers = NULL ;
21
- EFI_CPU_ARCH_PROTOCOL * gCpuArch ;
20
+ /**
21
+ *
22
+ * Return whether the Source interrupt index refers to an extended shared
23
+ * interrupt.
24
+ *
25
+ * @param Source The source intid to test
26
+ *
27
+ * @return True if Source is an extended SPI intid, false otherwise.
28
+ */
29
+ BOOLEAN
30
+ GicCommonSourceIsExtSpi (
31
+ IN UINTN Source
32
+ )
33
+ {
34
+ return Source >= ARM_GIC_ARCH_EXT_SPI_MIN && Source <= ARM_GIC_ARCH_EXT_SPI_MAX ;
35
+ }
36
+
37
+ /**
38
+ * Return whether this is a special interrupt.
39
+ *
40
+ * @param Source The source intid to test
41
+ *
42
+ * @return True if Source is a special interrupt intid, false otherwise.
43
+ */
44
+ BOOLEAN
45
+ GicCommonSourceIsSpecialInterrupt (
46
+ IN UINTN Source
47
+ )
48
+ {
49
+ return Source >= 1020 && Source <= 1023 ;
50
+ }
51
+
52
+ /**
53
+ *
54
+ * Return whether the Source interrupt index refers to a shared interrupt (SPI)
55
+ *
56
+ * @param Source The source intid to test
57
+ *
58
+ * @return True if Source is a SPI intid, false otherwise.
59
+ */
60
+ BOOLEAN
61
+ GicCommonSourceIsSpi (
62
+ IN UINTN Source
63
+ )
64
+ {
65
+ return Source >= 32 && Source <= 1019 ;
66
+ }
22
67
23
68
/**
24
69
Calculate GICD_ICFGRn base address and corresponding bit
@@ -32,24 +77,26 @@ EFI_CPU_ARCH_PROTOCOL *gCpuArch;
32
77
@retval EFI_UNSUPPORTED Source interrupt is not supported.
33
78
**/
34
79
EFI_STATUS
35
- GicGetDistributorIcfgBaseAndBit (
80
+ GicCommonGetDistributorIcfgBaseAndBit (
36
81
IN HARDWARE_INTERRUPT_SOURCE Source ,
37
82
OUT UINTN * RegAddress ,
38
83
OUT UINTN * Config1Bit
39
84
)
40
85
{
41
- UINTN RegIndex ;
42
- UINTN Field ;
86
+ UINTN RegIndex ;
87
+ UINTN Field ;
88
+ UINTN RegOffset ;
89
+ HARDWARE_INTERRUPT_SOURCE AdjustedSource ;
43
90
44
- if ( Source >= mGicNumInterrupts ) {
45
- ASSERT ( Source < mGicNumInterrupts );
46
- return EFI_UNSUPPORTED ;
47
- }
91
+ // Translate ESPI sources into the SPI range for indexing purposes.
92
+ AdjustedSource = Source & ~( ARM_GIC_ARCH_EXT_SPI_MIN );
93
+
94
+ RegOffset = ( GicCommonSourceIsExtSpi ( Source )) ? ARM_GIC_ICDICFR_E : ARM_GIC_ICDICFR ;
48
95
49
- RegIndex = Source / ARM_GIC_ICDICFR_F_STRIDE ; // NOTE: truncation is significant
50
- Field = Source % ARM_GIC_ICDICFR_F_STRIDE ;
96
+ RegIndex = AdjustedSource / ARM_GIC_ICDICFR_F_STRIDE ; // NOTE: truncation is significant
97
+ Field = AdjustedSource % ARM_GIC_ICDICFR_F_STRIDE ;
51
98
* RegAddress = (UINTN )PcdGet64 (PcdGicDistributorBase )
52
- + ARM_GIC_ICDICFR
99
+ + RegOffset
53
100
+ (ARM_GIC_ICDICFR_BYTES * RegIndex );
54
101
* Config1Bit = ((Field * ARM_GIC_ICDICFR_F_WIDTH )
55
102
+ ARM_GIC_ICDICFR_F_CONFIG1_BIT );
@@ -60,36 +107,37 @@ GicGetDistributorIcfgBaseAndBit (
60
107
/**
61
108
Register Handler for the specified interrupt source.
62
109
63
- @param This Instance pointer for this protocol
64
- @param Source Hardware source of the interrupt
65
- @param Handler Callback for interrupt. NULL to unregister
110
+ @param This Instance pointer for this protocol
111
+ @param Source Hardware source of the interrupt
112
+ @param Handler Callback for interrupt. NULL to unregister
113
+ @param HandlerDest Address of where to store Handler.
66
114
67
115
@retval EFI_SUCCESS Source was updated to support Handler.
68
116
@retval EFI_DEVICE_ERROR Hardware could not be programmed.
69
117
70
118
**/
71
119
EFI_STATUS
72
120
EFIAPI
73
- RegisterInterruptSource (
121
+ GicCommonRegisterInterruptSource (
74
122
IN EFI_HARDWARE_INTERRUPT_PROTOCOL * This ,
75
123
IN HARDWARE_INTERRUPT_SOURCE Source ,
76
- IN HARDWARE_INTERRUPT_HANDLER Handler
124
+ IN HARDWARE_INTERRUPT_HANDLER Handler ,
125
+ IN HARDWARE_INTERRUPT_HANDLER * HandlerDest
77
126
)
78
127
{
79
- if (Source >= mGicNumInterrupts ) {
80
- ASSERT (FALSE);
81
- return EFI_UNSUPPORTED ;
128
+ if (HandlerDest == NULL ) {
129
+ return EFI_INVALID_PARAMETER ;
82
130
}
83
131
84
- if ((Handler == NULL ) && (gRegisteredInterruptHandlers [ Source ] == NULL )) {
132
+ if ((Handler == NULL ) && (* HandlerDest == NULL )) {
85
133
return EFI_INVALID_PARAMETER ;
86
134
}
87
135
88
- if ((Handler != NULL ) && (gRegisteredInterruptHandlers [ Source ] != NULL )) {
136
+ if ((Handler != NULL ) && (* HandlerDest != NULL )) {
89
137
return EFI_ALREADY_STARTED ;
90
138
}
91
139
92
- gRegisteredInterruptHandlers [ Source ] = Handler ;
140
+ * HandlerDest = Handler ;
93
141
94
142
// If the interrupt handler is unregistered then disable the interrupt
95
143
if (NULL == Handler ) {
@@ -100,28 +148,19 @@ RegisterInterruptSource (
100
148
}
101
149
102
150
EFI_STATUS
103
- InstallAndRegisterInterruptService (
151
+ GicCommonInstallAndRegisterInterruptService (
104
152
IN EFI_HARDWARE_INTERRUPT_PROTOCOL * InterruptProtocol ,
105
153
IN EFI_HARDWARE_INTERRUPT2_PROTOCOL * Interrupt2Protocol ,
106
154
IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler ,
107
155
IN EFI_EVENT_NOTIFY ExitBootServicesEvent
108
156
)
109
157
{
110
- EFI_STATUS Status ;
111
- CONST UINTN RihArraySize =
112
- (sizeof (HARDWARE_INTERRUPT_HANDLER ) * mGicNumInterrupts );
113
-
114
- // Initialize the array for the Interrupt Handlers
115
- gRegisteredInterruptHandlers = AllocateZeroPool (RihArraySize );
116
- if (gRegisteredInterruptHandlers == NULL ) {
117
- return EFI_OUT_OF_RESOURCES ;
118
- }
158
+ EFI_STATUS Status ;
119
159
120
160
// Register to receive interrupts
121
161
Status = gCpuArch -> RegisterInterruptHandler (gCpuArch , ARM_ARCH_EXCEPTION_IRQ , InterruptHandler );
122
162
if (EFI_ERROR (Status )) {
123
163
DEBUG ((DEBUG_ERROR , "%a: Cpu->RegisterInterruptHandler() - %r\n" , __func__ , Status ));
124
- FreePool (gRegisteredInterruptHandlers );
125
164
return Status ;
126
165
}
127
166
0 commit comments