X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=ArmEbPkg%2FInterruptDxe%2FInterruptDxe.c;fp=ArmEbPkg%2FInterruptDxe%2FInterruptDxe.c;h=0000000000000000000000000000000000000000;hp=b9e8256f824fd93f3fdbb8a8f16ae0602d709dfd;hb=afdfe8f02bdf8d563554bb620c001072862b064e;hpb=7ee525b2c1f8d3d6da5f788364fe5be36a979c9c diff --git a/ArmEbPkg/InterruptDxe/InterruptDxe.c b/ArmEbPkg/InterruptDxe/InterruptDxe.c deleted file mode 100644 index b9e8256f82..0000000000 --- a/ArmEbPkg/InterruptDxe/InterruptDxe.c +++ /dev/null @@ -1,484 +0,0 @@ -/*++ - -Copyright (c) 2009, Hewlett-Packard Company. All rights reserved.
-Portions copyright (c) 2010, Apple Inc. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -Module Name: - - Gic.c - -Abstract: - - Driver implementing the GIC interrupt controller protocol - ---*/ - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - - -// -// EB board definitions -// -#define EB_GIC1_CPU_INTF_BASE 0x10040000 -#define EB_GIC1_DIST_BASE 0x10041000 -#define EB_GIC2_CPU_INTF_BASE 0x10050000 -#define EB_GIC2_DIST_BASE 0x10051000 -#define EB_GIC3_CPU_INTF_BASE 0x10060000 -#define EB_GIC3_DIST_BASE 0x10061000 -#define EB_GIC4_CPU_INTF_BASE 0x10070000 -#define EB_GIC5_DIST_BASE 0x10071000 - -// number of interrupts sources supported by each GIC on the EB -#define EB_NUM_GIC_INTERRUPTS 96 - -// number of 32-bit registers needed to represent those interrupts as a bit -// (used for enable set, enable clear, pending set, pending clear, and active regs) -#define EB_NUM_GIC_REG_PER_INT_BITS (EB_NUM_GIC_INTERRUPTS / 32) - -// number of 32-bit registers needed to represent those interrupts as two bits -// (used for configuration reg) -#define EB_NUM_GIC_REG_PER_INT_CFG (EB_NUM_GIC_INTERRUPTS / 16) - -// number of 32-bit registers needed to represent interrupts as 8-bit priority field -// (used for priority regs) -#define EB_NUM_GIC_REG_PER_INT_BYTES (EB_NUM_GIC_INTERRUPTS / 4) - -#define GIC_DEFAULT_PRIORITY 0x80 - -// -// GIC definitions -// - -// Distributor -#define GIC_ICDDCR 0x000 // Distributor Control Register -#define GIC_ICDICTR 0x004 // Interrupt Controller Type Register -#define GIC_ICDIIDR 0x008 // Implementer Identification Register - -// each reg base below repeats for EB_NUM_GIC_REG_PER_INT_BITS (see GIC spec) -#define GIC_ICDISR 0x080 // Interrupt Security Registers -#define GIC_ICDISER 0x100 // Interrupt Set-Enable Registers -#define GIC_ICDICER 0x180 // Interrupt Clear-Enable Registers -#define GIC_ICDSPR 0x200 // Interrupt Set-Pending Registers -#define GIC_ICDCPR 0x280 // Interrupt Clear-Pending Registers -#define GIC_ICDABR 0x300 // Active Bit Registers - -// each reg base below repeats for EB_NUM_GIC_REG_PER_INT_BYTES -#define GIC_ICDIPR 0x400 // Interrupt Priority Registers - -// each reg base below repeats for EB_NUM_GIC_INTERRUPTS -#define GIC_ICDIPTR 0x800 // Interrupt Processor Target Registers -#define GIC_ICDICFR 0xC00 // Interrupt Configuration Registers - -// just one of these -#define GIC_ICDSGIR 0xF00 // Software Generated Interrupt Register - - -// Cpu interface -#define GIC_ICCICR 0x00 // CPU Interface Controler Register -#define GIC_ICCPMR 0x04 // Interrupt Priority Mask Register -#define GIC_ICCBPR 0x08 // Binary Point Register -#define GIC_ICCIAR 0x0C // Interrupt Acknowledge Register -#define GIC_ICCEIOR 0x10 // End Of Interrupt Register -#define GIC_ICCRPR 0x14 // Running Priority Register -#define GIC_ICCPIR 0x18 // Highest Pending Interrupt Register -#define GIC_ICCABPR 0x1C // Aliased Binary Point Register -#define GIC_ICCIDR 0xFC // Identification Register - -extern EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptProtocol; - -// -// Notifications -// -VOID *CpuProtocolNotificationToken = NULL; -EFI_EVENT CpuProtocolNotificationEvent = (EFI_EVENT)NULL; -EFI_EVENT EfiExitBootServicesEvent = (EFI_EVENT)NULL; - - -HARDWARE_INTERRUPT_HANDLER gRegisteredInterruptHandlers[EB_NUM_GIC_INTERRUPTS]; - -/** - Register Handler for the specified interrupt source. - - @param This Instance pointer for this protocol - @param Source Hardware source of the interrupt - @param Handler Callback for interrupt. NULL to unregister - - @retval EFI_SUCCESS Source was updated to support Handler. - @retval EFI_DEVICE_ERROR Hardware could not be programmed. - -**/ -EFI_STATUS -EFIAPI -RegisterInterruptSource ( - IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This, - IN HARDWARE_INTERRUPT_SOURCE Source, - IN HARDWARE_INTERRUPT_HANDLER Handler - ) -{ - if (Source > EB_NUM_GIC_INTERRUPTS) { - ASSERT(FALSE); - return EFI_UNSUPPORTED; - } - - if ((Handler == NULL) && (gRegisteredInterruptHandlers[Source] == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if ((Handler != NULL) && (gRegisteredInterruptHandlers[Source] != NULL)) { - return EFI_ALREADY_STARTED; - } - - gRegisteredInterruptHandlers[Source] = Handler; - return This->EnableInterruptSource(This, Source); -} - - -/** - Enable interrupt source Source. - - @param This Instance pointer for this protocol - @param Source Hardware source of the interrupt - - @retval EFI_SUCCESS Source interrupt enabled. - @retval EFI_DEVICE_ERROR Hardware could not be programmed. - -**/ -EFI_STATUS -EFIAPI -EnableInterruptSource ( - IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This, - IN HARDWARE_INTERRUPT_SOURCE Source - ) -{ - UINT32 RegOffset; - UINTN RegShift; - - if (Source > EB_NUM_GIC_INTERRUPTS) { - ASSERT(FALSE); - return EFI_UNSUPPORTED; - } - - // calculate enable register offset and bit position - RegOffset = Source / 32; - RegShift = Source % 32; - - // write set-enable register - MmioWrite32 (EB_GIC1_DIST_BASE+GIC_ICDISER+(4*RegOffset), 1 << RegShift); - - return EFI_SUCCESS; -} - - -/** - Disable interrupt source Source. - - @param This Instance pointer for this protocol - @param Source Hardware source of the interrupt - - @retval EFI_SUCCESS Source interrupt disabled. - @retval EFI_DEVICE_ERROR Hardware could not be programmed. - -**/ -EFI_STATUS -EFIAPI -DisableInterruptSource ( - IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This, - IN HARDWARE_INTERRUPT_SOURCE Source - ) -{ - UINT32 RegOffset; - UINTN RegShift; - - if (Source > EB_NUM_GIC_INTERRUPTS) { - ASSERT(FALSE); - return EFI_UNSUPPORTED; - } - - // calculate enable register offset and bit position - RegOffset = Source / 32; - RegShift = Source % 32; - - // write set-enable register - MmioWrite32 (EB_GIC1_DIST_BASE+GIC_ICDICER+(4*RegOffset), 1 << RegShift); - - return EFI_SUCCESS; -} - - - -/** - Return current state of interrupt source Source. - - @param This Instance pointer for this protocol - @param Source Hardware source of the interrupt - @param InterruptState TRUE: source enabled, FALSE: source disabled. - - @retval EFI_SUCCESS InterruptState is valid - @retval EFI_DEVICE_ERROR InterruptState is not valid - -**/ -EFI_STATUS -EFIAPI -GetInterruptSourceState ( - IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This, - IN HARDWARE_INTERRUPT_SOURCE Source, - IN BOOLEAN *InterruptState - ) -{ - UINT32 RegOffset; - UINTN RegShift; - - if (Source > EB_NUM_GIC_INTERRUPTS) { - ASSERT(FALSE); - return EFI_UNSUPPORTED; - } - - // calculate enable register offset and bit position - RegOffset = Source / 32; - RegShift = Source % 32; - - if ((MmioRead32 (EB_GIC1_DIST_BASE+GIC_ICDISER+(4*RegOffset)) & (1< EB_NUM_GIC_INTERRUPTS) { - ASSERT(FALSE); - return EFI_UNSUPPORTED; - } - - MmioWrite32 (EB_GIC1_CPU_INTF_BASE+GIC_ICCEIOR, Source); - return EFI_SUCCESS; -} - - -/** - EFI_CPU_INTERRUPT_HANDLER that is called when a processor interrupt occurs. - - @param InterruptType Defines the type of interrupt or exception that - occurred on the processor.This parameter is processor architecture specific. - @param SystemContext A pointer to the processor context when - the interrupt occurred on the processor. - - @return None - -**/ -VOID -EFIAPI -IrqInterruptHandler ( - IN EFI_EXCEPTION_TYPE InterruptType, - IN EFI_SYSTEM_CONTEXT SystemContext - ) -{ - UINT32 GicInterrupt; - HARDWARE_INTERRUPT_HANDLER InterruptHandler; - - GicInterrupt = MmioRead32 (EB_GIC1_CPU_INTF_BASE + GIC_ICCIAR); - if (GicInterrupt >= EB_NUM_GIC_INTERRUPTS) { - MmioWrite32 (EB_GIC1_CPU_INTF_BASE+GIC_ICCEIOR, GicInterrupt); - } - - InterruptHandler = gRegisteredInterruptHandlers[GicInterrupt]; - if (InterruptHandler != NULL) { - // Call the registered interrupt handler. - InterruptHandler (GicInterrupt, SystemContext); - } else { - DEBUG ((EFI_D_ERROR, "Spurious GIC interrupt: %x\n", GicInterrupt)); - } - - EndOfInterrupt (&gHardwareInterruptProtocol, GicInterrupt); -} - - -// -// Making this global saves a few bytes in image size -// -EFI_HANDLE gHardwareInterruptHandle = NULL; - -// -// The protocol instance produced by this driver -// -EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptProtocol = { - RegisterInterruptSource, - EnableInterruptSource, - DisableInterruptSource, - GetInterruptSourceState, - EndOfInterrupt -}; - - -/** - Shutdown our hardware - - DXE Core will disable interrupts and turn off the timer and disable interrupts - after all the event handlers have run. - - @param[in] Event The Event that is being processed - @param[in] Context Event Context -**/ -VOID -EFIAPI -ExitBootServicesEvent ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - UINTN i; - - for (i = 0; i < EB_NUM_GIC_INTERRUPTS; i++) { - DisableInterruptSource (&gHardwareInterruptProtocol, i); - } -} - - -// -// Notification routines -// -VOID -CpuProtocolInstalledNotification ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - EFI_STATUS Status; - EFI_CPU_ARCH_PROTOCOL *Cpu; - - // - // Get the cpu protocol that this driver requires. - // - Status = gBS->LocateProtocol(&gEfiCpuArchProtocolGuid, NULL, (VOID **)&Cpu); - ASSERT_EFI_ERROR(Status); - - // - // Unregister the default exception handler. - // - Status = Cpu->RegisterInterruptHandler(Cpu, EXCEPT_ARM_IRQ, NULL); - ASSERT_EFI_ERROR(Status); - - // - // Register to receive interrupts - // - Status = Cpu->RegisterInterruptHandler(Cpu, EXCEPT_ARM_IRQ, IrqInterruptHandler); - ASSERT_EFI_ERROR(Status); -} - -/** - Initialize the state information for the CPU Architectural Protocol - - @param ImageHandle of the loaded driver - @param SystemTable Pointer to the System Table - - @retval EFI_SUCCESS Protocol registered - @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure - @retval EFI_DEVICE_ERROR Hardware problems - -**/ -EFI_STATUS -InterruptDxeInitialize ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - UINTN i; - UINT32 RegOffset; - UINTN RegShift; - - - // Make sure the Interrupt Controller Protocol is not already installed in the system. - ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid); - - for (i = 0; i < EB_NUM_GIC_INTERRUPTS; i++) { - DisableInterruptSource (&gHardwareInterruptProtocol, i); - - // Set Priority - RegOffset = i / 4; - RegShift = (i % 4) * 8; - MmioAndThenOr32 ( - EB_GIC1_DIST_BASE+GIC_ICDIPR+(4*RegOffset), - ~(0xff << RegShift), - GIC_DEFAULT_PRIORITY << RegShift - ); - } - - // configure interrupts for cpu 0 - for (i = 0; i < EB_NUM_GIC_REG_PER_INT_BYTES; i++) { - MmioWrite32 (EB_GIC1_DIST_BASE + GIC_ICDIPTR + (i*4), 0x01010101); - } - - // set binary point reg to 0x7 (no preemption) - MmioWrite32 (EB_GIC1_CPU_INTF_BASE + GIC_ICCBPR, 0x7); - - // set priority mask reg to 0xff to allow all priorities through - MmioWrite32 (EB_GIC1_CPU_INTF_BASE + GIC_ICCPMR, 0xff); - - // enable gic cpu interface - MmioWrite32 (EB_GIC1_CPU_INTF_BASE + GIC_ICCICR, 0x1); - - // enable gic distributor - MmioWrite32 (EB_GIC1_DIST_BASE + GIC_ICCICR, 0x1); - - - ZeroMem (&gRegisteredInterruptHandlers, sizeof (gRegisteredInterruptHandlers)); - - Status = gBS->InstallMultipleProtocolInterfaces ( - &gHardwareInterruptHandle, - &gHardwareInterruptProtocolGuid, &gHardwareInterruptProtocol, - NULL - ); - ASSERT_EFI_ERROR (Status); - - // Set up to be notified when the Cpu protocol is installed. - Status = gBS->CreateEvent (EVT_NOTIFY_SIGNAL, TPL_CALLBACK, CpuProtocolInstalledNotification, NULL, &CpuProtocolNotificationEvent); - ASSERT_EFI_ERROR (Status); - - Status = gBS->RegisterProtocolNotify (&gEfiCpuArchProtocolGuid, CpuProtocolNotificationEvent, (VOID *)&CpuProtocolNotificationToken); - ASSERT_EFI_ERROR (Status); - - // Register for an ExitBootServicesEvent - Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY, ExitBootServicesEvent, NULL, &EfiExitBootServicesEvent); - ASSERT_EFI_ERROR (Status); - - return Status; -} -