ArmPkg/CpuDxe: Change chain of dependency for CpuDxe and PL390Gic

Previously the CPU driver had a dependency on the GIC driver.
But by design is should be the opposite. The CPU driver installs the
CPU protocol that exposes the exception registration function.
And then, the interrupt controller registers its IRQ handler through
this interface.


git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11860 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
oliviermartin 2011-06-20 21:30:51 +00:00
parent e7c2a83b3b
commit d7b6c49b78
4 changed files with 38 additions and 60 deletions

View File

@ -76,5 +76,5 @@
gArmTokenSpaceGuid.PcdDebuggerExceptionSupport
gArmTokenSpaceGuid.PcdEfiUncachedMemoryToStronglyOrdered
[depex]
gHardwareInterruptProtocolGuid
[Depex]
TRUE

View File

@ -92,7 +92,6 @@ CommonCExceptionHandler (
IN OUT EFI_SYSTEM_CONTEXT SystemContext
)
{
if (ExceptionType <= MAX_ARM_EXCEPTION) {
if (gExceptionHandlers[ExceptionType]) {
gExceptionHandlers[ExceptionType] (ExceptionType, SystemContext);

View File

@ -54,8 +54,6 @@ 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[FixedPcdGet32(PcdGicNumInterrupts)];
@ -303,19 +301,19 @@ ExitBootServicesEvent (
IN VOID *Context
)
{
UINTN i;
UINTN Index;
for (i = 0; i < PcdGet32(PcdGicNumInterrupts); i++) {
DisableInterruptSource (&gHardwareInterruptProtocol, i);
for (Index = 0; Index < PcdGet32(PcdGicNumInterrupts); Index++) {
DisableInterruptSource (&gHardwareInterruptProtocol, Index);
}
// Acknowledge all pending interrupts
for (i = 0; i < PcdGet32(PcdGicNumInterrupts); i++) {
DisableInterruptSource (&gHardwareInterruptProtocol, i);
for (Index = 0; Index < PcdGet32(PcdGicNumInterrupts); Index++) {
DisableInterruptSource (&gHardwareInterruptProtocol, Index);
}
for (i = 0; i < PcdGet32(PcdGicNumInterrupts); i++) {
EndOfInterrupt (&gHardwareInterruptProtocol, i);
for (Index = 0; Index < PcdGet32(PcdGicNumInterrupts); Index++) {
EndOfInterrupt (&gHardwareInterruptProtocol, Index);
}
// Disable Gic Interface
@ -326,37 +324,6 @@ ExitBootServicesEvent (
MmioWrite32 (PcdGet32(PcdGicDistributorBase) + GIC_ICDDCR, 0x0);
}
//
// 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
@ -374,20 +341,21 @@ InterruptDxeInitialize (
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
UINTN i;
UINT32 RegOffset;
UINTN RegShift;
EFI_STATUS Status;
UINTN Index;
UINT32 RegOffset;
UINTN RegShift;
EFI_CPU_ARCH_PROTOCOL *Cpu;
// Make sure the Interrupt Controller Protocol is not already installed in the system.
ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid);
for (i = 0; i < PcdGet32(PcdGicNumInterrupts); i++) {
DisableInterruptSource (&gHardwareInterruptProtocol, i);
for (Index = 0; Index < PcdGet32(PcdGicNumInterrupts); Index++) {
DisableInterruptSource (&gHardwareInterruptProtocol, Index);
// Set Priority
RegOffset = i / 4;
RegShift = (i % 4) * 8;
RegOffset = Index / 4;
RegShift = (Index % 4) * 8;
MmioAndThenOr32 (
PcdGet32(PcdGicDistributorBase) + GIC_ICDIPR + (4*RegOffset),
~(0xff << RegShift),
@ -396,8 +364,8 @@ InterruptDxeInitialize (
}
// Configure interrupts for cpu 0
for (i = 0; i < GIC_NUM_REG_PER_INT_BYTES; i++) {
MmioWrite32 (PcdGet32(PcdGicDistributorBase) + GIC_ICDIPTR + (i*4), 0x01010101);
for (Index = 0; Index < GIC_NUM_REG_PER_INT_BYTES; Index++) {
MmioWrite32 (PcdGet32(PcdGicDistributorBase) + GIC_ICDIPTR + (Index*4), 0x01010101);
}
// Set binary point reg to 0x7 (no preemption)
@ -421,12 +389,23 @@ InterruptDxeInitialize (
);
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);
//
// Get the CPU protocol that this driver requires.
//
Status = gBS->LocateProtocol(&gEfiCpuArchProtocolGuid, NULL, (VOID **)&Cpu);
ASSERT_EFI_ERROR(Status);
Status = gBS->RegisterProtocolNotify (&gEfiCpuArchProtocolGuid, CpuProtocolNotificationEvent, (VOID *)&CpuProtocolNotificationToken);
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);
// Register for an ExitBootServicesEvent
Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY, ExitBootServicesEvent, NULL, &EfiExitBootServicesEvent);

View File

@ -51,5 +51,5 @@
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase
gArmTokenSpaceGuid.PcdGicNumInterrupts
[depex]
TRUE
[Depex]
gEfiCpuArchProtocolGuid