2 Handle OMAP35xx interrupt controller
4 Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include <Library/BaseLib.h>
18 #include <Library/DebugLib.h>
19 #include <Library/BaseMemoryLib.h>
20 #include <Library/UefiBootServicesTableLib.h>
21 #include <Library/UefiLib.h>
22 #include <Library/PcdLib.h>
23 #include <Library/IoLib.h>
24 #include <Library/ArmLib.h>
26 #include <Protocol/Cpu.h>
27 #include <Protocol/HardwareInterrupt.h>
29 #include <Omap3530/Omap3530.h>
34 EFI_EVENT EfiExitBootServicesEvent
= (EFI_EVENT
)NULL
;
37 HARDWARE_INTERRUPT_HANDLER gRegisteredInterruptHandlers
[INT_NROF_VECTORS
];
42 DXE Core will disable interrupts and turn off the timer and disable interrupts
43 after all the event handlers have run.
45 @param[in] Event The Event that is being processed
46 @param[in] Context Event Context
50 ExitBootServicesEvent (
55 // Disable all interrupts
56 MmioWrite32 (INTCPS_MIR(0), 0xFFFFFFFF);
57 MmioWrite32 (INTCPS_MIR(1), 0xFFFFFFFF);
58 MmioWrite32 (INTCPS_MIR(2), 0xFFFFFFFF);
59 MmioWrite32 (INTCPS_CONTROL
, INTCPS_CONTROL_NEWIRQAGR
);
61 // Add code here to disable all FIQs as debugger may have turned one on
65 Register Handler for the specified interrupt source.
67 @param This Instance pointer for this protocol
68 @param Source Hardware source of the interrupt
69 @param Handler Callback for interrupt. NULL to unregister
71 @retval EFI_SUCCESS Source was updated to support Handler.
72 @retval EFI_DEVICE_ERROR Hardware could not be programmed.
77 RegisterInterruptSource (
78 IN EFI_HARDWARE_INTERRUPT_PROTOCOL
*This
,
79 IN HARDWARE_INTERRUPT_SOURCE Source
,
80 IN HARDWARE_INTERRUPT_HANDLER Handler
83 if (Source
> MAX_VECTOR
) {
85 return EFI_UNSUPPORTED
;
88 if ((MmioRead32 (INTCPS_ILR(Source
)) & INTCPS_ILR_FIQ
) == INTCPS_ILR_FIQ
) {
89 // This vector has been programmed as FIQ so we can't use it for IRQ
90 // EFI does not use FIQ, but the debugger can use it to check for
91 // ctrl-c. So this ASSERT means you have a conflict with the debug agent
93 return EFI_UNSUPPORTED
;
96 if ((Handler
== NULL
) && (gRegisteredInterruptHandlers
[Source
] == NULL
)) {
97 return EFI_INVALID_PARAMETER
;
100 if ((Handler
!= NULL
) && (gRegisteredInterruptHandlers
[Source
] != NULL
)) {
101 return EFI_ALREADY_STARTED
;
104 gRegisteredInterruptHandlers
[Source
] = Handler
;
105 return This
->EnableInterruptSource(This
, Source
);
110 Enable interrupt source Source.
112 @param This Instance pointer for this protocol
113 @param Source Hardware source of the interrupt
115 @retval EFI_SUCCESS Source interrupt enabled.
116 @retval EFI_DEVICE_ERROR Hardware could not be programmed.
121 EnableInterruptSource (
122 IN EFI_HARDWARE_INTERRUPT_PROTOCOL
*This
,
123 IN HARDWARE_INTERRUPT_SOURCE Source
129 if (Source
> MAX_VECTOR
) {
131 return EFI_UNSUPPORTED
;
135 Bit
= 1UL << (Source
% 32);
137 MmioWrite32 (INTCPS_MIR_CLEAR(Bank
), Bit
);
144 Disable interrupt source Source.
146 @param This Instance pointer for this protocol
147 @param Source Hardware source of the interrupt
149 @retval EFI_SUCCESS Source interrupt disabled.
150 @retval EFI_DEVICE_ERROR Hardware could not be programmed.
155 DisableInterruptSource (
156 IN EFI_HARDWARE_INTERRUPT_PROTOCOL
*This
,
157 IN HARDWARE_INTERRUPT_SOURCE Source
163 if (Source
> MAX_VECTOR
) {
165 return EFI_UNSUPPORTED
;
169 Bit
= 1UL << (Source
% 32);
171 MmioWrite32 (INTCPS_MIR_SET(Bank
), Bit
);
179 Return current state of interrupt source Source.
181 @param This Instance pointer for this protocol
182 @param Source Hardware source of the interrupt
183 @param InterruptState TRUE: source enabled, FALSE: source disabled.
185 @retval EFI_SUCCESS InterruptState is valid
186 @retval EFI_DEVICE_ERROR InterruptState is not valid
191 GetInterruptSourceState (
192 IN EFI_HARDWARE_INTERRUPT_PROTOCOL
*This
,
193 IN HARDWARE_INTERRUPT_SOURCE Source
,
194 IN BOOLEAN
*InterruptState
200 if (InterruptState
== NULL
) {
201 return EFI_INVALID_PARAMETER
;
204 if (Source
> MAX_VECTOR
) {
206 return EFI_UNSUPPORTED
;
210 Bit
= 1UL << (Source
% 32);
212 if ((MmioRead32(INTCPS_MIR(Bank
)) & Bit
) == Bit
) {
213 *InterruptState
= FALSE
;
215 *InterruptState
= TRUE
;
222 Signal to the hardware that the End Of Intrrupt state
225 @param This Instance pointer for this protocol
226 @param Source Hardware source of the interrupt
228 @retval EFI_SUCCESS Source interrupt EOI'ed.
229 @retval EFI_DEVICE_ERROR Hardware could not be programmed.
235 IN EFI_HARDWARE_INTERRUPT_PROTOCOL
*This
,
236 IN HARDWARE_INTERRUPT_SOURCE Source
239 MmioWrite32 (INTCPS_CONTROL
, INTCPS_CONTROL_NEWIRQAGR
);
240 ArmDataSynchronizationBarrier ();
246 EFI_CPU_INTERRUPT_HANDLER that is called when a processor interrupt occurs.
248 @param InterruptType Defines the type of interrupt or exception that
249 occurred on the processor.This parameter is processor architecture specific.
250 @param SystemContext A pointer to the processor context when
251 the interrupt occurred on the processor.
258 IrqInterruptHandler (
259 IN EFI_EXCEPTION_TYPE InterruptType
,
260 IN EFI_SYSTEM_CONTEXT SystemContext
264 HARDWARE_INTERRUPT_HANDLER InterruptHandler
;
266 Vector
= MmioRead32 (INTCPS_SIR_IRQ
) & INTCPS_SIR_IRQ_MASK
;
268 // Needed to prevent infinite nesting when Time Driver lowers TPL
269 MmioWrite32 (INTCPS_CONTROL
, INTCPS_CONTROL_NEWIRQAGR
);
270 ArmDataSynchronizationBarrier ();
272 InterruptHandler
= gRegisteredInterruptHandlers
[Vector
];
273 if (InterruptHandler
!= NULL
) {
274 // Call the registered interrupt handler.
275 InterruptHandler (Vector
, SystemContext
);
278 // Needed to clear after running the handler
279 MmioWrite32 (INTCPS_CONTROL
, INTCPS_CONTROL_NEWIRQAGR
);
280 ArmDataSynchronizationBarrier ();
284 // Making this global saves a few bytes in image size
286 EFI_HANDLE gHardwareInterruptHandle
= NULL
;
289 // The protocol instance produced by this driver
291 EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptProtocol
= {
292 RegisterInterruptSource
,
293 EnableInterruptSource
,
294 DisableInterruptSource
,
295 GetInterruptSourceState
,
300 Initialize the state information for the CPU Architectural Protocol
302 @param ImageHandle of the loaded driver
303 @param SystemTable Pointer to the System Table
305 @retval EFI_SUCCESS Protocol registered
306 @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure
307 @retval EFI_DEVICE_ERROR Hardware problems
311 InterruptDxeInitialize (
312 IN EFI_HANDLE ImageHandle
,
313 IN EFI_SYSTEM_TABLE
*SystemTable
317 EFI_CPU_ARCH_PROTOCOL
*Cpu
;
319 // Make sure the Interrupt Controller Protocol is not already installed in the system.
320 ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL
, &gHardwareInterruptProtocolGuid
);
322 // Make sure all interrupts are disabled by default.
323 MmioWrite32 (INTCPS_MIR(0), 0xFFFFFFFF);
324 MmioWrite32 (INTCPS_MIR(1), 0xFFFFFFFF);
325 MmioWrite32 (INTCPS_MIR(2), 0xFFFFFFFF);
326 MmioOr32 (INTCPS_CONTROL
, INTCPS_CONTROL_NEWIRQAGR
);
328 Status
= gBS
->InstallMultipleProtocolInterfaces(&gHardwareInterruptHandle
,
329 &gHardwareInterruptProtocolGuid
, &gHardwareInterruptProtocol
,
331 ASSERT_EFI_ERROR(Status
);
334 // Get the CPU protocol that this driver requires.
336 Status
= gBS
->LocateProtocol(&gEfiCpuArchProtocolGuid
, NULL
, (VOID
**)&Cpu
);
337 ASSERT_EFI_ERROR(Status
);
340 // Unregister the default exception handler.
342 Status
= Cpu
->RegisterInterruptHandler(Cpu
, EXCEPT_ARM_IRQ
, NULL
);
343 ASSERT_EFI_ERROR(Status
);
346 // Register to receive interrupts
348 Status
= Cpu
->RegisterInterruptHandler(Cpu
, EXCEPT_ARM_IRQ
, IrqInterruptHandler
);
349 ASSERT_EFI_ERROR(Status
);
351 // Register for an ExitBootServicesEvent
352 Status
= gBS
->CreateEvent(EVT_SIGNAL_EXIT_BOOT_SERVICES
, TPL_NOTIFY
, ExitBootServicesEvent
, NULL
, &EfiExitBootServicesEvent
);
353 ASSERT_EFI_ERROR(Status
);