2 Template for Metronome Architecture Protocol driver of the ARM flavor
4 Copyright (c) 2008-2009, Apple Inc. All rights reserved.
6 All rights reserved. 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>
25 #include <Protocol/Cpu.h>
26 #include <Protocol/HardwareInterrupt.h>
28 #include <Omap3530/Omap3530.h>
33 VOID
*CpuProtocolNotificationToken
= NULL
;
34 EFI_EVENT CpuProtocolNotificationEvent
= (EFI_EVENT
)NULL
;
35 EFI_EVENT EfiExitBootServicesEvent
= (EFI_EVENT
)NULL
;
38 HARDWARE_INTERRUPT_HANDLER gRegisteredInterruptHandlers
[INT_NROF_VECTORS
];
43 DXE Core will disable interrupts and turn off the timer and disable interrupts
44 after all the event handlers have run.
46 @param[in] Event The Event that is being processed
47 @param[in] Context Event Context
51 ExitBootServicesEvent (
56 // Disable all interrupts
57 MmioWrite32(INTCPS_MIR(0), 0xFFFFFFFF);
58 MmioWrite32(INTCPS_MIR(1), 0xFFFFFFFF);
59 MmioWrite32(INTCPS_MIR(2), 0xFFFFFFFF);
60 MmioWrite32(INTCPS_CONTROL
, INTCPS_CONTROL_NEWIRQAGR
);
64 Register Handler for the specified interrupt source.
66 @param This Instance pointer for this protocol
67 @param Source Hardware source of the interrupt
68 @param Handler Callback for interrupt. NULL to unregister
70 @retval EFI_SUCCESS Source was updated to support Handler.
71 @retval EFI_DEVICE_ERROR Hardware could not be programmed.
76 RegisterInterruptSource (
77 IN EFI_HARDWARE_INTERRUPT_PROTOCOL
*This
,
78 IN HARDWARE_INTERRUPT_SOURCE Source
,
79 IN HARDWARE_INTERRUPT_HANDLER Handler
82 if (Source
> MAX_VECTOR
) {
84 return EFI_UNSUPPORTED
;
87 if ((Handler
== NULL
) && (gRegisteredInterruptHandlers
[Source
] == NULL
)) {
88 return EFI_INVALID_PARAMETER
;
91 if ((Handler
!= NULL
) && (gRegisteredInterruptHandlers
[Source
] != NULL
)) {
92 return EFI_ALREADY_STARTED
;
95 gRegisteredInterruptHandlers
[Source
] = Handler
;
96 return This
->EnableInterruptSource(This
, Source
);
101 Enable interrupt source Source.
103 @param This Instance pointer for this protocol
104 @param Source Hardware source of the interrupt
106 @retval EFI_SUCCESS Source interrupt enabled.
107 @retval EFI_DEVICE_ERROR Hardware could not be programmed.
112 EnableInterruptSource (
113 IN EFI_HARDWARE_INTERRUPT_PROTOCOL
*This
,
114 IN HARDWARE_INTERRUPT_SOURCE Source
120 if (Source
> MAX_VECTOR
) {
122 return EFI_UNSUPPORTED
;
126 Bit
= 1UL << (Source
% 32);
128 MmioWrite32(INTCPS_MIR_CLEAR(Bank
), Bit
);
135 Disable interrupt source Source.
137 @param This Instance pointer for this protocol
138 @param Source Hardware source of the interrupt
140 @retval EFI_SUCCESS Source interrupt disabled.
141 @retval EFI_DEVICE_ERROR Hardware could not be programmed.
146 DisableInterruptSource(
147 IN EFI_HARDWARE_INTERRUPT_PROTOCOL
*This
,
148 IN HARDWARE_INTERRUPT_SOURCE Source
154 if (Source
> MAX_VECTOR
) {
156 return EFI_UNSUPPORTED
;
160 Bit
= 1UL << (Source
% 32);
162 MmioWrite32(INTCPS_MIR_SET(Bank
), Bit
);
170 Return current state of interrupt source Source.
172 @param This Instance pointer for this protocol
173 @param Source Hardware source of the interrupt
174 @param InterruptState TRUE: source enabled, FALSE: source disabled.
176 @retval EFI_SUCCESS InterruptState is valid
177 @retval EFI_DEVICE_ERROR InterruptState is not valid
182 GetInterruptSourceState (
183 IN EFI_HARDWARE_INTERRUPT_PROTOCOL
*This
,
184 IN HARDWARE_INTERRUPT_SOURCE Source
,
185 IN BOOLEAN
*InterruptState
191 if (InterruptState
== NULL
) {
192 return EFI_INVALID_PARAMETER
;
195 if (Source
> MAX_VECTOR
) {
197 return EFI_UNSUPPORTED
;
201 Bit
= 1UL << (Source
% 32);
203 if ((MmioRead32(INTCPS_MIR(Bank
)) & Bit
) == Bit
) {
204 *InterruptState
= FALSE
;
206 *InterruptState
= TRUE
;
215 EFI_CPU_INTERRUPT_HANDLER that is called when a processor interrupt occurs.
217 @param InterruptType Defines the type of interrupt or exception that
218 occurred on the processor.This parameter is processor architecture specific.
219 @param SystemContext A pointer to the processor context when
220 the interrupt occurred on the processor.
227 IrqInterruptHandler (
228 IN EFI_EXCEPTION_TYPE InterruptType
,
229 IN EFI_SYSTEM_CONTEXT SystemContext
233 HARDWARE_INTERRUPT_HANDLER InterruptHandler
;
235 Vector
= MmioRead32(INTCPS_SIR_IRQ
) & INTCPS_SIR_IRQ_MASK
;
237 // Needed to prevent infinite nesting when Time Driver lowers TPL
238 MmioWrite32(INTCPS_CONTROL
, INTCPS_CONTROL_NEWIRQAGR
);
240 InterruptHandler
= gRegisteredInterruptHandlers
[Vector
];
241 if (InterruptHandler
!= NULL
) {
242 // Call the registered interrupt handler.
243 InterruptHandler(Vector
, SystemContext
);
246 // Needed to clear after running the handler
247 MmioWrite32(INTCPS_CONTROL
, INTCPS_CONTROL_NEWIRQAGR
);
251 // Making this global saves a few bytes in image size
253 EFI_HANDLE gHardwareInterruptHandle
= NULL
;
256 // The protocol instance produced by this driver
258 EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptProtocol
= {
259 RegisterInterruptSource
,
260 EnableInterruptSource
,
261 DisableInterruptSource
,
262 GetInterruptSourceState
266 // Notification routines
269 CpuProtocolInstalledNotification (
275 EFI_CPU_ARCH_PROTOCOL
*Cpu
;
278 // Get the cpu protocol that this driver requires.
280 Status
= gBS
->LocateProtocol(&gEfiCpuArchProtocolGuid
, NULL
, (VOID
**)&Cpu
);
281 ASSERT_EFI_ERROR(Status
);
284 // Unregister the default exception handler.
286 Status
= Cpu
->RegisterInterruptHandler(Cpu
, EXCEPT_ARM_IRQ
, NULL
);
287 ASSERT_EFI_ERROR(Status
);
290 // Register to receive interrupts
292 Status
= Cpu
->RegisterInterruptHandler(Cpu
, EXCEPT_ARM_IRQ
, IrqInterruptHandler
);
293 ASSERT_EFI_ERROR(Status
);
297 Initialize the state information for the CPU Architectural Protocol
299 @param ImageHandle of the loaded driver
300 @param SystemTable Pointer to the System Table
302 @retval EFI_SUCCESS Protocol registered
303 @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure
304 @retval EFI_DEVICE_ERROR Hardware problems
308 InterruptDxeInitialize (
309 IN EFI_HANDLE ImageHandle
,
310 IN EFI_SYSTEM_TABLE
*SystemTable
315 // Make sure the Interrupt Controller Protocol is not already installed in the system.
316 ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL
, &gHardwareInterruptProtocolGuid
);
318 // Make sure all interrupts are disabled by default.
319 MmioWrite32(INTCPS_MIR(0), 0xFFFFFFFF);
320 MmioWrite32(INTCPS_MIR(1), 0xFFFFFFFF);
321 MmioWrite32(INTCPS_MIR(2), 0xFFFFFFFF);
322 MmioWrite32(INTCPS_CONTROL
, INTCPS_CONTROL_NEWIRQAGR
);
324 Status
= gBS
->InstallMultipleProtocolInterfaces(&gHardwareInterruptHandle
,
325 &gHardwareInterruptProtocolGuid
, &gHardwareInterruptProtocol
,
327 ASSERT_EFI_ERROR(Status
);
329 // Set up to be notified when the Cpu protocol is installed.
330 Status
= gBS
->CreateEvent(EVT_NOTIFY_SIGNAL
, TPL_CALLBACK
, CpuProtocolInstalledNotification
, NULL
, &CpuProtocolNotificationEvent
);
331 ASSERT_EFI_ERROR(Status
);
333 Status
= gBS
->RegisterProtocolNotify(&gEfiCpuArchProtocolGuid
, CpuProtocolNotificationEvent
, (VOID
*)&CpuProtocolNotificationToken
);
334 ASSERT_EFI_ERROR(Status
);
336 // Register for an ExitBootServicesEvent
337 Status
= gBS
->CreateEvent(EVT_SIGNAL_EXIT_BOOT_SERVICES
, TPL_NOTIFY
, ExitBootServicesEvent
, NULL
, &EfiExitBootServicesEvent
);
338 ASSERT_EFI_ERROR(Status
);