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
;
97 return This
->EnableInterruptSource(This
, Source
);
102 Enable interrupt source Source.
104 @param This Instance pointer for this protocol
105 @param Source Hardware source of the interrupt
107 @retval EFI_SUCCESS Source interrupt enabled.
108 @retval EFI_DEVICE_ERROR Hardware could not be programmed.
113 EnableInterruptSource (
114 IN EFI_HARDWARE_INTERRUPT_PROTOCOL
*This
,
115 IN HARDWARE_INTERRUPT_SOURCE Source
121 if (Source
> MAX_VECTOR
) {
123 return EFI_UNSUPPORTED
;
127 Bit
= 1UL << (Source
% 32);
129 MmioWrite32(INTCPS_MIR_CLEAR(Bank
), Bit
);
136 Disable interrupt source Source.
138 @param This Instance pointer for this protocol
139 @param Source Hardware source of the interrupt
141 @retval EFI_SUCCESS Source interrupt disabled.
142 @retval EFI_DEVICE_ERROR Hardware could not be programmed.
147 DisableInterruptSource(
148 IN EFI_HARDWARE_INTERRUPT_PROTOCOL
*This
,
149 IN HARDWARE_INTERRUPT_SOURCE Source
155 if (Source
> MAX_VECTOR
) {
157 return EFI_UNSUPPORTED
;
161 Bit
= 1UL << (Source
% 32);
163 MmioWrite32(INTCPS_MIR_SET(Bank
), Bit
);
171 Return current state of interrupt source Source.
173 @param This Instance pointer for this protocol
174 @param Source Hardware source of the interrupt
175 @param InterruptState TRUE: source enabled, FALSE: source disabled.
177 @retval EFI_SUCCESS InterruptState is valid
178 @retval EFI_DEVICE_ERROR InterruptState is not valid
183 GetInterruptSourceState (
184 IN EFI_HARDWARE_INTERRUPT_PROTOCOL
*This
,
185 IN HARDWARE_INTERRUPT_SOURCE Source
,
186 IN BOOLEAN
*InterruptState
192 if (InterruptState
== NULL
) {
193 return EFI_INVALID_PARAMETER
;
196 if (Source
> MAX_VECTOR
) {
198 return EFI_UNSUPPORTED
;
202 Bit
= 1UL << (Source
% 32);
204 if ((MmioRead32(INTCPS_MIR(Bank
)) & Bit
) == Bit
) {
205 *InterruptState
= FALSE
;
207 *InterruptState
= TRUE
;
216 EFI_CPU_INTERRUPT_HANDLER that is called when a processor interrupt occurs.
218 @param InterruptType Defines the type of interrupt or exception that
219 occurred on the processor.This parameter is processor architecture specific.
220 @param SystemContext A pointer to the processor context when
221 the interrupt occurred on the processor.
228 IrqInterruptHandler (
229 IN EFI_EXCEPTION_TYPE InterruptType
,
230 IN EFI_SYSTEM_CONTEXT SystemContext
234 HARDWARE_INTERRUPT_HANDLER InterruptHandler
;
236 Vector
= MmioRead32(INTCPS_SIR_IRQ
) & INTCPS_SIR_IRQ_MASK
;
238 InterruptHandler
= gRegisteredInterruptHandlers
[Vector
];
239 if (InterruptHandler
!= NULL
) {
240 // Call the registered interrupt handler.
241 InterruptHandler(Vector
, SystemContext
);
244 MmioWrite32(INTCPS_CONTROL
, INTCPS_CONTROL_NEWIRQAGR
);
248 // Making this global saves a few bytes in image size
250 EFI_HANDLE gHardwareInterruptHandle
= NULL
;
253 // The protocol instance produced by this driver
255 EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptProtocol
= {
256 RegisterInterruptSource
,
257 EnableInterruptSource
,
258 DisableInterruptSource
,
259 GetInterruptSourceState
263 // Notification routines
266 CpuProtocolInstalledNotification (
272 EFI_CPU_ARCH_PROTOCOL
*Cpu
;
275 // Get the cpu protocol that this driver requires.
277 Status
= gBS
->LocateProtocol(&gEfiCpuArchProtocolGuid
, NULL
, (VOID
**)&Cpu
);
278 ASSERT_EFI_ERROR(Status
);
281 // Unregister the default exception handler.
283 Status
= Cpu
->RegisterInterruptHandler(Cpu
, EXCEPT_ARM_IRQ
, NULL
);
284 ASSERT_EFI_ERROR(Status
);
287 // Register to receive interrupts
289 Status
= Cpu
->RegisterInterruptHandler(Cpu
, EXCEPT_ARM_IRQ
, IrqInterruptHandler
);
290 ASSERT_EFI_ERROR(Status
);
294 Initialize the state information for the CPU Architectural Protocol
296 @param ImageHandle of the loaded driver
297 @param SystemTable Pointer to the System Table
299 @retval EFI_SUCCESS Protocol registered
300 @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure
301 @retval EFI_DEVICE_ERROR Hardware problems
305 InterruptDxeInitialize (
306 IN EFI_HANDLE ImageHandle
,
307 IN EFI_SYSTEM_TABLE
*SystemTable
312 // Make sure the Interrupt Controller Protocol is not already installed in the system.
313 ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL
, &gHardwareInterruptProtocolGuid
);
315 // Make sure all interrupts are disabled by default.
316 MmioWrite32(INTCPS_MIR(0), 0xFFFFFFFF);
317 MmioWrite32(INTCPS_MIR(1), 0xFFFFFFFF);
318 MmioWrite32(INTCPS_MIR(2), 0xFFFFFFFF);
319 MmioWrite32(INTCPS_CONTROL
, INTCPS_CONTROL_NEWIRQAGR
);
321 Status
= gBS
->InstallMultipleProtocolInterfaces(&gHardwareInterruptHandle
,
322 &gHardwareInterruptProtocolGuid
, &gHardwareInterruptProtocol
,
324 ASSERT_EFI_ERROR(Status
);
326 // Set up to be notified when the Cpu protocol is installed.
327 Status
= gBS
->CreateEvent(EVT_NOTIFY_SIGNAL
, TPL_CALLBACK
, CpuProtocolInstalledNotification
, NULL
, &CpuProtocolNotificationEvent
);
328 ASSERT_EFI_ERROR(Status
);
330 Status
= gBS
->RegisterProtocolNotify(&gEfiCpuArchProtocolGuid
, CpuProtocolNotificationEvent
, (VOID
*)&CpuProtocolNotificationToken
);
331 ASSERT_EFI_ERROR(Status
);
333 // Register for an ExitBootServicesEvent
334 Status
= gBS
->CreateEvent(EVT_SIGNAL_EXIT_BOOT_SERVICES
, TPL_NOTIFY
, ExitBootServicesEvent
, NULL
, &EfiExitBootServicesEvent
);
335 ASSERT_EFI_ERROR(Status
);