EDK2 doxygen online documents - Firmware Encoding Index 1
EDK2 doxygen online documents - Firmware Encoding Index

Omap35xxPkg/InterruptDxe/HardwareInterrupt.c

Go to the documentation of this file.
00001 
00015 #include <PiDxe.h>
00016 
00017 #include <Library/BaseLib.h>
00018 #include <Library/DebugLib.h>
00019 #include <Library/BaseMemoryLib.h>
00020 #include <Library/UefiBootServicesTableLib.h>
00021 #include <Library/UefiLib.h>
00022 #include <Library/PcdLib.h>
00023 #include <Library/IoLib.h>
00024 #include <Library/ArmLib.h>
00025 
00026 #include <Protocol/Cpu.h>
00027 #include <Protocol/HardwareInterrupt.h>
00028 
00029 #include <Omap3530/Omap3530.h>
00030 
00031 //
00032 // Notifications
00033 //
00034 EFI_EVENT EfiExitBootServicesEvent      = (EFI_EVENT)NULL;
00035 
00036 
00037 HARDWARE_INTERRUPT_HANDLER  gRegisteredInterruptHandlers[INT_NROF_VECTORS];
00038 
00048 VOID
00049 EFIAPI
00050 ExitBootServicesEvent (
00051   IN EFI_EVENT  Event,
00052   IN VOID       *Context
00053   )
00054 {
00055   // Disable all interrupts
00056   MmioWrite32 (INTCPS_MIR(0), 0xFFFFFFFF);
00057   MmioWrite32 (INTCPS_MIR(1), 0xFFFFFFFF);
00058   MmioWrite32 (INTCPS_MIR(2), 0xFFFFFFFF);
00059   MmioWrite32 (INTCPS_CONTROL, INTCPS_CONTROL_NEWIRQAGR);
00060 
00061   // Add code here to disable all FIQs as debugger may have turned one on
00062 }
00063 
00075 EFI_STATUS
00076 EFIAPI
00077 RegisterInterruptSource (
00078   IN EFI_HARDWARE_INTERRUPT_PROTOCOL    *This,
00079   IN HARDWARE_INTERRUPT_SOURCE          Source,
00080   IN HARDWARE_INTERRUPT_HANDLER         Handler
00081   )
00082 {
00083   if (Source > MAX_VECTOR) {
00084     ASSERT(FALSE);
00085     return EFI_UNSUPPORTED;
00086   } 
00087   
00088   if ((MmioRead32 (INTCPS_ILR(Source)) & INTCPS_ILR_FIQ) == INTCPS_ILR_FIQ) {
00089     // This vector has been programmed as FIQ so we can't use it for IRQ
00090     // EFI does not use FIQ, but the debugger can use it to check for 
00091     // ctrl-c. So this ASSERT means you have a conflict with the debug agent
00092     ASSERT (FALSE);
00093     return EFI_UNSUPPORTED;
00094   }
00095   
00096   if ((Handler == NULL) && (gRegisteredInterruptHandlers[Source] == NULL)) {
00097     return EFI_INVALID_PARAMETER;
00098   }
00099 
00100   if ((Handler != NULL) && (gRegisteredInterruptHandlers[Source] != NULL)) {
00101     return EFI_ALREADY_STARTED;
00102   }
00103 
00104   gRegisteredInterruptHandlers[Source] = Handler;
00105   return This->EnableInterruptSource(This, Source);
00106 }
00107 
00108 
00119 EFI_STATUS
00120 EFIAPI
00121 EnableInterruptSource (
00122   IN EFI_HARDWARE_INTERRUPT_PROTOCOL    *This,
00123   IN HARDWARE_INTERRUPT_SOURCE          Source
00124   )
00125 {
00126   UINTN Bank;
00127   UINTN Bit;
00128   
00129   if (Source > MAX_VECTOR) {
00130     ASSERT(FALSE);
00131     return EFI_UNSUPPORTED;
00132   }
00133   
00134   Bank = Source / 32;
00135   Bit  = 1UL << (Source % 32);
00136   
00137   MmioWrite32 (INTCPS_MIR_CLEAR(Bank), Bit);
00138   
00139   return EFI_SUCCESS;
00140 }
00141 
00142 
00153 EFI_STATUS
00154 EFIAPI
00155 DisableInterruptSource (
00156   IN EFI_HARDWARE_INTERRUPT_PROTOCOL    *This,
00157   IN HARDWARE_INTERRUPT_SOURCE          Source
00158   )
00159 {
00160   UINTN Bank;
00161   UINTN Bit;
00162   
00163   if (Source > MAX_VECTOR) {
00164     ASSERT(FALSE);
00165     return EFI_UNSUPPORTED;
00166   }
00167   
00168   Bank = Source / 32;
00169   Bit  = 1UL << (Source % 32);
00170   
00171   MmioWrite32 (INTCPS_MIR_SET(Bank), Bit);
00172   
00173   return EFI_SUCCESS;
00174 }
00175 
00176 
00177 
00189 EFI_STATUS
00190 EFIAPI
00191 GetInterruptSourceState (
00192   IN EFI_HARDWARE_INTERRUPT_PROTOCOL    *This,
00193   IN HARDWARE_INTERRUPT_SOURCE          Source,
00194   IN BOOLEAN                            *InterruptState
00195   )
00196 {
00197   UINTN Bank;
00198   UINTN Bit;
00199   
00200   if (InterruptState == NULL) {
00201     return EFI_INVALID_PARAMETER;
00202   }
00203   
00204   if (Source > MAX_VECTOR) {
00205     ASSERT(FALSE);
00206     return EFI_UNSUPPORTED;
00207   }
00208 
00209   Bank = Source / 32;
00210   Bit  = 1UL << (Source % 32);
00211     
00212   if ((MmioRead32(INTCPS_MIR(Bank)) & Bit) == Bit) {
00213     *InterruptState = FALSE;
00214   } else {
00215     *InterruptState = TRUE;
00216   }
00217   
00218   return EFI_SUCCESS;
00219 }
00220 
00232 EFI_STATUS
00233 EFIAPI
00234 EndOfInterrupt (
00235   IN EFI_HARDWARE_INTERRUPT_PROTOCOL    *This,
00236   IN HARDWARE_INTERRUPT_SOURCE          Source
00237   )
00238 {
00239   MmioWrite32 (INTCPS_CONTROL, INTCPS_CONTROL_NEWIRQAGR);
00240   ArmDataSyncronizationBarrier ();
00241   return EFI_SUCCESS;
00242 }
00243 
00244 
00256 VOID
00257 EFIAPI
00258 IrqInterruptHandler (
00259   IN EFI_EXCEPTION_TYPE           InterruptType,
00260   IN EFI_SYSTEM_CONTEXT           SystemContext
00261   )
00262 {
00263   UINT32                     Vector;
00264   HARDWARE_INTERRUPT_HANDLER InterruptHandler;
00265   
00266   Vector = MmioRead32 (INTCPS_SIR_IRQ) & INTCPS_SIR_IRQ_MASK;
00267 
00268   // Needed to prevent infinite nesting when Time Driver lowers TPL
00269   MmioWrite32 (INTCPS_CONTROL, INTCPS_CONTROL_NEWIRQAGR);
00270   ArmDataSyncronizationBarrier ();
00271   
00272   InterruptHandler = gRegisteredInterruptHandlers[Vector];
00273   if (InterruptHandler != NULL) {
00274     // Call the registered interrupt handler.
00275     InterruptHandler (Vector, SystemContext);
00276   }
00277   
00278   // Needed to clear after running the handler
00279   MmioWrite32 (INTCPS_CONTROL, INTCPS_CONTROL_NEWIRQAGR);
00280   ArmDataSyncronizationBarrier ();
00281 }
00282 
00283 //
00284 // Making this global saves a few bytes in image size
00285 //
00286 EFI_HANDLE  gHardwareInterruptHandle = NULL;
00287 
00288 //
00289 // The protocol instance produced by this driver
00290 //
00291 EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptProtocol = {
00292   RegisterInterruptSource,
00293   EnableInterruptSource,
00294   DisableInterruptSource,
00295   GetInterruptSourceState,
00296   EndOfInterrupt
00297 };
00298 
00310 EFI_STATUS
00311 InterruptDxeInitialize (
00312   IN EFI_HANDLE         ImageHandle,
00313   IN EFI_SYSTEM_TABLE   *SystemTable
00314   )
00315 {
00316   EFI_STATUS  Status;
00317   EFI_CPU_ARCH_PROTOCOL   *Cpu;
00318 
00319   // Make sure the Interrupt Controller Protocol is not already installed in the system.
00320   ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid);
00321 
00322   // Make sure all interrupts are disabled by default.
00323   MmioWrite32 (INTCPS_MIR(0), 0xFFFFFFFF);
00324   MmioWrite32 (INTCPS_MIR(1), 0xFFFFFFFF);
00325   MmioWrite32 (INTCPS_MIR(2), 0xFFFFFFFF);
00326   MmioOr32 (INTCPS_CONTROL, INTCPS_CONTROL_NEWIRQAGR);
00327  
00328   Status = gBS->InstallMultipleProtocolInterfaces(&gHardwareInterruptHandle,
00329                                                   &gHardwareInterruptProtocolGuid,   &gHardwareInterruptProtocol,
00330                                                   NULL);
00331   ASSERT_EFI_ERROR(Status);
00332   
00333   //
00334   // Get the CPU protocol that this driver requires.
00335   //
00336   Status = gBS->LocateProtocol(&gEfiCpuArchProtocolGuid, NULL, (VOID **)&Cpu);
00337   ASSERT_EFI_ERROR(Status);
00338 
00339   //
00340   // Unregister the default exception handler.
00341   //
00342   Status = Cpu->RegisterInterruptHandler(Cpu, EXCEPT_ARM_IRQ, NULL);
00343   ASSERT_EFI_ERROR(Status);
00344 
00345   //
00346   // Register to receive interrupts
00347   //
00348   Status = Cpu->RegisterInterruptHandler(Cpu, EXCEPT_ARM_IRQ, IrqInterruptHandler);
00349   ASSERT_EFI_ERROR(Status);
00350 
00351   // Register for an ExitBootServicesEvent
00352   Status = gBS->CreateEvent(EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY, ExitBootServicesEvent, NULL, &EfiExitBootServicesEvent);
00353   ASSERT_EFI_ERROR(Status);
00354 
00355   return Status;
00356 }
00357 
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Defines