mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-24 22:24:37 +02:00
ArmPkg: Tidy GIC code before changes.
This change is purely cosmetic, to tidy some code before change. Mods involve: Re-order #includes Reformat comments. Use ns consistently (always "100ns" not sometimes "100 nS") Split overlength code lines. Make protocol functions STATIC. Remove "Horor vacui" comments. Rationalize GIC register address calculations Replace explicit test and assert with ASSERT_EFI_ERROR. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Girish Pathak <girish.pathak@arm.com> Signed-off-by: Alexei Fedorov <alexei.fedorov@arm.com> Signed-off-by: Evan Lloyd <evan.lloyd@arm.com> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
This commit is contained in:
parent
fe4049471b
commit
b0393756d6
@ -1,6 +1,6 @@
|
|||||||
/*++
|
/*++
|
||||||
|
|
||||||
Copyright (c) 2013-2014, ARM Ltd. All rights reserved.<BR>
|
Copyright (c) 2013-2017, ARM Ltd. All rights reserved.<BR>
|
||||||
|
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
@ -28,14 +28,10 @@ ExitBootServicesEvent (
|
|||||||
IN VOID *Context
|
IN VOID *Context
|
||||||
);
|
);
|
||||||
|
|
||||||
//
|
|
||||||
// Making this global saves a few bytes in image size
|
// Making this global saves a few bytes in image size
|
||||||
//
|
|
||||||
EFI_HANDLE gHardwareInterruptHandle = NULL;
|
EFI_HANDLE gHardwareInterruptHandle = NULL;
|
||||||
|
|
||||||
//
|
|
||||||
// Notifications
|
// Notifications
|
||||||
//
|
|
||||||
EFI_EVENT EfiExitBootServicesEvent = (EFI_EVENT)NULL;
|
EFI_EVENT EfiExitBootServicesEvent = (EFI_EVENT)NULL;
|
||||||
|
|
||||||
// Maximum Number of Interrupts
|
// Maximum Number of Interrupts
|
||||||
@ -94,48 +90,55 @@ InstallAndRegisterInterruptService (
|
|||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
EFI_CPU_ARCH_PROTOCOL *Cpu;
|
EFI_CPU_ARCH_PROTOCOL *Cpu;
|
||||||
|
CONST UINTN RihArraySize =
|
||||||
|
(sizeof(HARDWARE_INTERRUPT_HANDLER) * mGicNumInterrupts);
|
||||||
|
|
||||||
// Initialize the array for the Interrupt Handlers
|
// Initialize the array for the Interrupt Handlers
|
||||||
gRegisteredInterruptHandlers = (HARDWARE_INTERRUPT_HANDLER*)AllocateZeroPool (sizeof(HARDWARE_INTERRUPT_HANDLER) * mGicNumInterrupts);
|
gRegisteredInterruptHandlers = AllocateZeroPool (RihArraySize);
|
||||||
if (gRegisteredInterruptHandlers == NULL) {
|
if (gRegisteredInterruptHandlers == NULL) {
|
||||||
return EFI_OUT_OF_RESOURCES;
|
return EFI_OUT_OF_RESOURCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||||
&gHardwareInterruptHandle,
|
&gHardwareInterruptHandle,
|
||||||
&gHardwareInterruptProtocolGuid, InterruptProtocol,
|
&gHardwareInterruptProtocolGuid,
|
||||||
|
InterruptProtocol,
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Get the CPU protocol that this driver requires.
|
// Get the CPU protocol that this driver requires.
|
||||||
//
|
|
||||||
Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&Cpu);
|
Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&Cpu);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Unregister the default exception handler.
|
// Unregister the default exception handler.
|
||||||
//
|
|
||||||
Status = Cpu->RegisterInterruptHandler (Cpu, ARM_ARCH_EXCEPTION_IRQ, NULL);
|
Status = Cpu->RegisterInterruptHandler (Cpu, ARM_ARCH_EXCEPTION_IRQ, NULL);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Register to receive interrupts
|
// Register to receive interrupts
|
||||||
//
|
Status = Cpu->RegisterInterruptHandler (
|
||||||
Status = Cpu->RegisterInterruptHandler (Cpu, ARM_ARCH_EXCEPTION_IRQ, InterruptHandler);
|
Cpu,
|
||||||
|
ARM_ARCH_EXCEPTION_IRQ,
|
||||||
|
InterruptHandler
|
||||||
|
);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register for an ExitBootServicesEvent
|
// Register for an ExitBootServicesEvent
|
||||||
Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY, ExitBootServicesEvent, NULL, &EfiExitBootServicesEvent);
|
Status = gBS->CreateEvent (
|
||||||
|
EVT_SIGNAL_EXIT_BOOT_SERVICES,
|
||||||
|
TPL_NOTIFY,
|
||||||
|
ExitBootServicesEvent,
|
||||||
|
NULL,
|
||||||
|
&EfiExitBootServicesEvent
|
||||||
|
);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*++
|
/*++
|
||||||
|
|
||||||
Copyright (c) 2013-2014, ARM Ltd. All rights reserved.<BR>
|
Copyright (c) 2013-2017, ARM Ltd. All rights reserved.<BR>
|
||||||
|
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
@ -28,9 +28,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
extern UINTN mGicNumInterrupts;
|
extern UINTN mGicNumInterrupts;
|
||||||
extern HARDWARE_INTERRUPT_HANDLER *gRegisteredInterruptHandlers;
|
extern HARDWARE_INTERRUPT_HANDLER *gRegisteredInterruptHandlers;
|
||||||
|
|
||||||
//
|
|
||||||
// Common API
|
// Common API
|
||||||
//
|
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
InstallAndRegisterInterruptService (
|
InstallAndRegisterInterruptService (
|
||||||
IN EFI_HARDWARE_INTERRUPT_PROTOCOL *InterruptProtocol,
|
IN EFI_HARDWARE_INTERRUPT_PROTOCOL *InterruptProtocol,
|
||||||
@ -46,18 +44,14 @@ RegisterInterruptSource (
|
|||||||
IN HARDWARE_INTERRUPT_HANDLER Handler
|
IN HARDWARE_INTERRUPT_HANDLER Handler
|
||||||
);
|
);
|
||||||
|
|
||||||
//
|
|
||||||
// GicV2 API
|
// GicV2 API
|
||||||
//
|
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
GicV2DxeInitialize (
|
GicV2DxeInitialize (
|
||||||
IN EFI_HANDLE ImageHandle,
|
IN EFI_HANDLE ImageHandle,
|
||||||
IN EFI_SYSTEM_TABLE *SystemTable
|
IN EFI_SYSTEM_TABLE *SystemTable
|
||||||
);
|
);
|
||||||
|
|
||||||
//
|
|
||||||
// GicV3 API
|
// GicV3 API
|
||||||
//
|
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
GicV3DxeInitialize (
|
GicV3DxeInitialize (
|
||||||
IN EFI_HANDLE ImageHandle,
|
IN EFI_HANDLE ImageHandle,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/** @file
|
/** @file
|
||||||
*
|
*
|
||||||
* Copyright (c) 2011-2015, ARM Limited. All rights reserved.
|
* Copyright (c) 2011-2017, ARM Limited. All rights reserved.
|
||||||
*
|
*
|
||||||
* This program and the accompanying materials
|
* This program and the accompanying materials
|
||||||
* are licensed and made available under the terms and conditions of the BSD License
|
* are licensed and made available under the terms and conditions of the BSD License
|
||||||
@ -19,6 +19,13 @@
|
|||||||
#include <Library/IoLib.h>
|
#include <Library/IoLib.h>
|
||||||
#include <Library/PcdLib.h>
|
#include <Library/PcdLib.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define ISENABLER_ADDRESS(base,offset) ((base) + \
|
||||||
|
ARM_GICR_CTLR_FRAME_SIZE + ARM_GICR_ISENABLER + (4 * offset))
|
||||||
|
|
||||||
|
#define ICENABLER_ADDRESS(base,offset) ((base) + \
|
||||||
|
ARM_GICR_CTLR_FRAME_SIZE + ARM_GICR_ICENABLER + (4 * offset))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Return whether the Source interrupt index refers to a shared interrupt (SPI)
|
* Return whether the Source interrupt index refers to a shared interrupt (SPI)
|
||||||
@ -55,13 +62,17 @@ GicGetCpuRedistributorBase (
|
|||||||
UINTN GicCpuRedistributorBase;
|
UINTN GicCpuRedistributorBase;
|
||||||
|
|
||||||
MpId = ArmReadMpidr ();
|
MpId = ArmReadMpidr ();
|
||||||
// Define CPU affinity as Affinity0[0:8], Affinity1[9:15], Affinity2[16:23], Affinity3[24:32]
|
// Define CPU affinity as:
|
||||||
|
// Affinity0[0:8], Affinity1[9:15], Affinity2[16:23], Affinity3[24:32]
|
||||||
// whereas Affinity3 is defined at [32:39] in MPIDR
|
// whereas Affinity3 is defined at [32:39] in MPIDR
|
||||||
CpuAffinity = (MpId & (ARM_CORE_AFF0 | ARM_CORE_AFF1 | ARM_CORE_AFF2)) | ((MpId & ARM_CORE_AFF3) >> 8);
|
CpuAffinity = (MpId & (ARM_CORE_AFF0 | ARM_CORE_AFF1 | ARM_CORE_AFF2)) |
|
||||||
|
((MpId & ARM_CORE_AFF3) >> 8);
|
||||||
|
|
||||||
if (Revision == ARM_GIC_ARCH_REVISION_3) {
|
if (Revision == ARM_GIC_ARCH_REVISION_3) {
|
||||||
// 2 x 64KB frame: Redistributor control frame + SGI Control & Generation frame
|
// 2 x 64KB frame:
|
||||||
GicRedistributorGranularity = ARM_GICR_CTLR_FRAME_SIZE + ARM_GICR_SGI_PPI_FRAME_SIZE;
|
// Redistributor control frame + SGI Control & Generation frame
|
||||||
|
GicRedistributorGranularity = ARM_GICR_CTLR_FRAME_SIZE
|
||||||
|
+ ARM_GICR_SGI_PPI_FRAME_SIZE;
|
||||||
} else {
|
} else {
|
||||||
ASSERT_EFI_ERROR (EFI_UNSUPPORTED);
|
ASSERT_EFI_ERROR (EFI_UNSUPPORTED);
|
||||||
return 0;
|
return 0;
|
||||||
@ -112,7 +123,10 @@ ArmGicSendSgiTo (
|
|||||||
IN INTN SgiId
|
IN INTN SgiId
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
MmioWrite32 (GicDistributorBase + ARM_GIC_ICDSGIR, ((TargetListFilter & 0x3) << 24) | ((CPUTargetList & 0xFF) << 16) | SgiId);
|
MmioWrite32 (
|
||||||
|
GicDistributorBase + ARM_GIC_ICDSGIR,
|
||||||
|
((TargetListFilter & 0x3) << 24) | ((CPUTargetList & 0xFF) << 16) | SgiId
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -123,7 +137,8 @@ ArmGicSendSgiTo (
|
|||||||
* in the GICv3 the register value is only the InterruptId.
|
* in the GICv3 the register value is only the InterruptId.
|
||||||
*
|
*
|
||||||
* @param GicInterruptInterfaceBase Base Address of the GIC CPU Interface
|
* @param GicInterruptInterfaceBase Base Address of the GIC CPU Interface
|
||||||
* @param InterruptId InterruptId read from the Interrupt Acknowledge Register
|
* @param InterruptId InterruptId read from the Interrupt
|
||||||
|
* Acknowledge Register
|
||||||
*
|
*
|
||||||
* @retval value returned by the Interrupt Acknowledge Register
|
* @retval value returned by the Interrupt Acknowledge Register
|
||||||
*
|
*
|
||||||
@ -200,16 +215,25 @@ ArmGicEnableInterrupt (
|
|||||||
FeaturePcdGet (PcdArmGicV3WithV2Legacy) ||
|
FeaturePcdGet (PcdArmGicV3WithV2Legacy) ||
|
||||||
SourceIsSpi (Source)) {
|
SourceIsSpi (Source)) {
|
||||||
// Write set-enable register
|
// Write set-enable register
|
||||||
MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset), 1 << RegShift);
|
MmioWrite32 (
|
||||||
|
GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset),
|
||||||
|
1 << RegShift
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
GicCpuRedistributorBase = GicGetCpuRedistributorBase (GicRedistributorBase, Revision);
|
GicCpuRedistributorBase = GicGetCpuRedistributorBase (
|
||||||
|
GicRedistributorBase,
|
||||||
|
Revision
|
||||||
|
);
|
||||||
if (GicCpuRedistributorBase == 0) {
|
if (GicCpuRedistributorBase == 0) {
|
||||||
ASSERT_EFI_ERROR (EFI_NOT_FOUND);
|
ASSERT_EFI_ERROR (EFI_NOT_FOUND);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write set-enable register
|
// Write set-enable register
|
||||||
MmioWrite32 (GicCpuRedistributorBase + ARM_GICR_CTLR_FRAME_SIZE + ARM_GICR_ISENABLER + (4 * RegOffset), 1 << RegShift);
|
MmioWrite32 (
|
||||||
|
ISENABLER_ADDRESS(GicCpuRedistributorBase, RegOffset),
|
||||||
|
1 << RegShift
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,15 +259,24 @@ ArmGicDisableInterrupt (
|
|||||||
FeaturePcdGet (PcdArmGicV3WithV2Legacy) ||
|
FeaturePcdGet (PcdArmGicV3WithV2Legacy) ||
|
||||||
SourceIsSpi (Source)) {
|
SourceIsSpi (Source)) {
|
||||||
// Write clear-enable register
|
// Write clear-enable register
|
||||||
MmioWrite32 (GicDistributorBase + ARM_GIC_ICDICER + (4 * RegOffset), 1 << RegShift);
|
MmioWrite32 (
|
||||||
|
GicDistributorBase + ARM_GIC_ICDICER + (4 * RegOffset),
|
||||||
|
1 << RegShift
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
GicCpuRedistributorBase = GicGetCpuRedistributorBase (GicRedistributorBase, Revision);
|
GicCpuRedistributorBase = GicGetCpuRedistributorBase (
|
||||||
|
GicRedistributorBase,
|
||||||
|
Revision
|
||||||
|
);
|
||||||
if (GicCpuRedistributorBase == 0) {
|
if (GicCpuRedistributorBase == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write clear-enable register
|
// Write clear-enable register
|
||||||
MmioWrite32 (GicCpuRedistributorBase + ARM_GICR_CTLR_FRAME_SIZE + ARM_GICR_ICENABLER + (4 * RegOffset), 1 << RegShift);
|
MmioWrite32 (
|
||||||
|
ICENABLER_ADDRESS(GicCpuRedistributorBase, RegOffset),
|
||||||
|
1 << RegShift
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,15 +302,23 @@ ArmGicIsInterruptEnabled (
|
|||||||
if ((Revision == ARM_GIC_ARCH_REVISION_2) ||
|
if ((Revision == ARM_GIC_ARCH_REVISION_2) ||
|
||||||
FeaturePcdGet (PcdArmGicV3WithV2Legacy) ||
|
FeaturePcdGet (PcdArmGicV3WithV2Legacy) ||
|
||||||
SourceIsSpi (Source)) {
|
SourceIsSpi (Source)) {
|
||||||
Interrupts = ((MmioRead32 (GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset)) & (1 << RegShift)) != 0);
|
Interrupts = ((MmioRead32 (
|
||||||
|
GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset)
|
||||||
|
)
|
||||||
|
& (1 << RegShift)) != 0);
|
||||||
} else {
|
} else {
|
||||||
GicCpuRedistributorBase = GicGetCpuRedistributorBase (GicRedistributorBase, Revision);
|
GicCpuRedistributorBase = GicGetCpuRedistributorBase (
|
||||||
|
GicRedistributorBase,
|
||||||
|
Revision
|
||||||
|
);
|
||||||
if (GicCpuRedistributorBase == 0) {
|
if (GicCpuRedistributorBase == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read set-enable register
|
// Read set-enable register
|
||||||
Interrupts = MmioRead32 (GicCpuRedistributorBase + ARM_GICR_CTLR_FRAME_SIZE + ARM_GICR_ISENABLER + (4 * RegOffset));
|
Interrupts = MmioRead32 (
|
||||||
|
ISENABLER_ADDRESS(GicCpuRedistributorBase, RegOffset)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ((Interrupts & (1 << RegShift)) != 0);
|
return ((Interrupts & (1 << RegShift)) != 0);
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
Copyright (c) 2009, Hewlett-Packard Company. All rights reserved.<BR>
|
Copyright (c) 2009, Hewlett-Packard Company. All rights reserved.<BR>
|
||||||
Portions copyright (c) 2010, Apple Inc. All rights reserved.<BR>
|
Portions copyright (c) 2010, Apple Inc. All rights reserved.<BR>
|
||||||
Portions copyright (c) 2011-2016, ARM Ltd. All rights reserved.<BR>
|
Portions copyright (c) 2011-2017, ARM Ltd. All rights reserved.<BR>
|
||||||
|
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
@ -43,6 +43,7 @@ STATIC UINT32 mGicDistributorBase;
|
|||||||
@retval EFI_UNSUPPORTED Source interrupt is not supported
|
@retval EFI_UNSUPPORTED Source interrupt is not supported
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
STATIC
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
GicV2EnableInterruptSource (
|
GicV2EnableInterruptSource (
|
||||||
@ -70,6 +71,7 @@ GicV2EnableInterruptSource (
|
|||||||
@retval EFI_UNSUPPORTED Source interrupt is not supported
|
@retval EFI_UNSUPPORTED Source interrupt is not supported
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
STATIC
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
GicV2DisableInterruptSource (
|
GicV2DisableInterruptSource (
|
||||||
@ -98,6 +100,7 @@ GicV2DisableInterruptSource (
|
|||||||
@retval EFI_UNSUPPORTED Source interrupt is not supported
|
@retval EFI_UNSUPPORTED Source interrupt is not supported
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
STATIC
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
GicV2GetInterruptSourceState (
|
GicV2GetInterruptSourceState (
|
||||||
@ -127,6 +130,7 @@ GicV2GetInterruptSourceState (
|
|||||||
@retval EFI_UNSUPPORTED Source interrupt is not supported
|
@retval EFI_UNSUPPORTED Source interrupt is not supported
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
STATIC
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
GicV2EndOfInterrupt (
|
GicV2EndOfInterrupt (
|
||||||
@ -147,13 +151,15 @@ GicV2EndOfInterrupt (
|
|||||||
EFI_CPU_INTERRUPT_HANDLER that is called when a processor interrupt occurs.
|
EFI_CPU_INTERRUPT_HANDLER that is called when a processor interrupt occurs.
|
||||||
|
|
||||||
@param InterruptType Defines the type of interrupt or exception that
|
@param InterruptType Defines the type of interrupt or exception that
|
||||||
occurred on the processor.This parameter is processor architecture specific.
|
occurred on the processor.This parameter is
|
||||||
|
processor architecture specific.
|
||||||
@param SystemContext A pointer to the processor context when
|
@param SystemContext A pointer to the processor context when
|
||||||
the interrupt occurred on the processor.
|
the interrupt occurred on the processor.
|
||||||
|
|
||||||
@return None
|
@return None
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
STATIC
|
||||||
VOID
|
VOID
|
||||||
EFIAPI
|
EFIAPI
|
||||||
GicV2IrqInterruptHandler (
|
GicV2IrqInterruptHandler (
|
||||||
@ -166,9 +172,10 @@ GicV2IrqInterruptHandler (
|
|||||||
|
|
||||||
GicInterrupt = ArmGicV2AcknowledgeInterrupt (mGicInterruptInterfaceBase);
|
GicInterrupt = ArmGicV2AcknowledgeInterrupt (mGicInterruptInterfaceBase);
|
||||||
|
|
||||||
// Special Interrupts (ID1020-ID1023) have an Interrupt ID greater than the number of interrupt (ie: Spurious interrupt).
|
// Special Interrupts (ID1020-ID1023) have an Interrupt ID greater than the
|
||||||
|
// number of interrupt (ie: Spurious interrupt).
|
||||||
if ((GicInterrupt & ARM_GIC_ICCIAR_ACKINTID) >= mGicNumInterrupts) {
|
if ((GicInterrupt & ARM_GIC_ICCIAR_ACKINTID) >= mGicNumInterrupts) {
|
||||||
// The special interrupt do not need to be acknowledge
|
// The special interrupts do not need to be acknowledged
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,14 +184,12 @@ GicV2IrqInterruptHandler (
|
|||||||
// Call the registered interrupt handler.
|
// Call the registered interrupt handler.
|
||||||
InterruptHandler (GicInterrupt, SystemContext);
|
InterruptHandler (GicInterrupt, SystemContext);
|
||||||
} else {
|
} else {
|
||||||
DEBUG ((EFI_D_ERROR, "Spurious GIC interrupt: 0x%x\n", GicInterrupt));
|
DEBUG ((DEBUG_ERROR, "Spurious GIC interrupt: 0x%x\n", GicInterrupt));
|
||||||
GicV2EndOfInterrupt (&gHardwareInterruptV2Protocol, GicInterrupt);
|
GicV2EndOfInterrupt (&gHardwareInterruptV2Protocol, GicInterrupt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// The protocol instance produced by this driver
|
// The protocol instance produced by this driver
|
||||||
//
|
|
||||||
EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptV2Protocol = {
|
EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptV2Protocol = {
|
||||||
RegisterInterruptSource,
|
RegisterInterruptSource,
|
||||||
GicV2EnableInterruptSource,
|
GicV2EnableInterruptSource,
|
||||||
@ -196,12 +201,13 @@ EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptV2Protocol = {
|
|||||||
/**
|
/**
|
||||||
Shutdown our hardware
|
Shutdown our hardware
|
||||||
|
|
||||||
DXE Core will disable interrupts and turn off the timer and disable interrupts
|
DXE Core will disable interrupts and turn off the timer and disable
|
||||||
after all the event handlers have run.
|
interrupts after all the event handlers have run.
|
||||||
|
|
||||||
@param[in] Event The Event that is being processed
|
@param[in] Event The Event that is being processed
|
||||||
@param[in] Context Event Context
|
@param[in] Context Event Context
|
||||||
**/
|
**/
|
||||||
|
STATIC
|
||||||
VOID
|
VOID
|
||||||
EFIAPI
|
EFIAPI
|
||||||
GicV2ExitBootServicesEvent (
|
GicV2ExitBootServicesEvent (
|
||||||
@ -256,7 +262,8 @@ GicV2DxeInitialize (
|
|||||||
UINTN RegShift;
|
UINTN RegShift;
|
||||||
UINT32 CpuTarget;
|
UINT32 CpuTarget;
|
||||||
|
|
||||||
// Make sure the Interrupt Controller Protocol is not already installed in the system.
|
// Make sure the Interrupt Controller Protocol is not already installed in
|
||||||
|
// the system.
|
||||||
ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid);
|
ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid);
|
||||||
|
|
||||||
mGicInterruptInterfaceBase = PcdGet64 (PcdGicInterruptInterfaceBase);
|
mGicInterruptInterfaceBase = PcdGet64 (PcdGicInterruptInterfaceBase);
|
||||||
@ -276,25 +283,27 @@ GicV2DxeInitialize (
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Targets the interrupts to the Primary Cpu
|
// Targets the interrupts to the Primary Cpu
|
||||||
//
|
|
||||||
|
|
||||||
// Only Primary CPU will run this code. We can identify our GIC CPU ID by reading
|
// Only Primary CPU will run this code. We can identify our GIC CPU ID by
|
||||||
// the GIC Distributor Target register. The 8 first GICD_ITARGETSRn are banked to each
|
// reading the GIC Distributor Target register. The 8 first GICD_ITARGETSRn
|
||||||
// connected CPU. These 8 registers hold the CPU targets fields for interrupts 0-31.
|
// are banked to each connected CPU. These 8 registers hold the CPU targets
|
||||||
// More Info in the GIC Specification about "Interrupt Processor Targets Registers"
|
// fields for interrupts 0-31. More Info in the GIC Specification about
|
||||||
//
|
// "Interrupt Processor Targets Registers"
|
||||||
// Read the first Interrupt Processor Targets Register (that corresponds to the 4
|
|
||||||
// first SGIs)
|
// Read the first Interrupt Processor Targets Register (that corresponds to
|
||||||
|
// the 4 first SGIs)
|
||||||
CpuTarget = MmioRead32 (mGicDistributorBase + ARM_GIC_ICDIPTR);
|
CpuTarget = MmioRead32 (mGicDistributorBase + ARM_GIC_ICDIPTR);
|
||||||
|
|
||||||
// The CPU target is a bit field mapping each CPU to a GIC CPU Interface. This value
|
// The CPU target is a bit field mapping each CPU to a GIC CPU Interface.
|
||||||
// is 0 when we run on a uniprocessor platform.
|
// This value is 0 when we run on a uniprocessor platform.
|
||||||
if (CpuTarget != 0) {
|
if (CpuTarget != 0) {
|
||||||
// The 8 first Interrupt Processor Targets Registers are read-only
|
// The 8 first Interrupt Processor Targets Registers are read-only
|
||||||
for (Index = 8; Index < (mGicNumInterrupts / 4); Index++) {
|
for (Index = 8; Index < (mGicNumInterrupts / 4); Index++) {
|
||||||
MmioWrite32 (mGicDistributorBase + ARM_GIC_ICDIPTR + (Index * 4), CpuTarget);
|
MmioWrite32 (
|
||||||
|
mGicDistributorBase + ARM_GIC_ICDIPTR + (Index * 4),
|
||||||
|
CpuTarget
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,7 +320,10 @@ GicV2DxeInitialize (
|
|||||||
ArmGicEnableDistributor (mGicDistributorBase);
|
ArmGicEnableDistributor (mGicDistributorBase);
|
||||||
|
|
||||||
Status = InstallAndRegisterInterruptService (
|
Status = InstallAndRegisterInterruptService (
|
||||||
&gHardwareInterruptV2Protocol, GicV2IrqInterruptHandler, GicV2ExitBootServicesEvent);
|
&gHardwareInterruptV2Protocol,
|
||||||
|
GicV2IrqInterruptHandler,
|
||||||
|
GicV2ExitBootServicesEvent
|
||||||
|
);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/** @file
|
/** @file
|
||||||
*
|
*
|
||||||
* Copyright (c) 2011-2016, ARM Limited. All rights reserved.
|
* Copyright (c) 2011-2017, ARM Limited. All rights reserved.
|
||||||
*
|
*
|
||||||
* This program and the accompanying materials
|
* This program and the accompanying materials
|
||||||
* are licensed and made available under the terms and conditions of the BSD License
|
* are licensed and made available under the terms and conditions of the BSD License
|
||||||
@ -33,6 +33,7 @@ STATIC UINTN mGicRedistributorsBase;
|
|||||||
@retval EFI_DEVICE_ERROR Hardware could not be programmed.
|
@retval EFI_DEVICE_ERROR Hardware could not be programmed.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
STATIC
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
GicV3EnableInterruptSource (
|
GicV3EnableInterruptSource (
|
||||||
@ -60,6 +61,7 @@ GicV3EnableInterruptSource (
|
|||||||
@retval EFI_DEVICE_ERROR Hardware could not be programmed.
|
@retval EFI_DEVICE_ERROR Hardware could not be programmed.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
STATIC
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
GicV3DisableInterruptSource (
|
GicV3DisableInterruptSource (
|
||||||
@ -88,6 +90,7 @@ GicV3DisableInterruptSource (
|
|||||||
@retval EFI_DEVICE_ERROR InterruptState is not valid
|
@retval EFI_DEVICE_ERROR InterruptState is not valid
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
STATIC
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
GicV3GetInterruptSourceState (
|
GicV3GetInterruptSourceState (
|
||||||
@ -101,7 +104,11 @@ GicV3GetInterruptSourceState (
|
|||||||
return EFI_UNSUPPORTED;
|
return EFI_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
*InterruptState = ArmGicIsInterruptEnabled (mGicDistributorBase, mGicRedistributorsBase, Source);
|
*InterruptState = ArmGicIsInterruptEnabled (
|
||||||
|
mGicDistributorBase,
|
||||||
|
mGicRedistributorsBase,
|
||||||
|
Source
|
||||||
|
);
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -117,6 +124,7 @@ GicV3GetInterruptSourceState (
|
|||||||
@retval EFI_DEVICE_ERROR Hardware could not be programmed.
|
@retval EFI_DEVICE_ERROR Hardware could not be programmed.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
STATIC
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
GicV3EndOfInterrupt (
|
GicV3EndOfInterrupt (
|
||||||
@ -137,13 +145,15 @@ GicV3EndOfInterrupt (
|
|||||||
EFI_CPU_INTERRUPT_HANDLER that is called when a processor interrupt occurs.
|
EFI_CPU_INTERRUPT_HANDLER that is called when a processor interrupt occurs.
|
||||||
|
|
||||||
@param InterruptType Defines the type of interrupt or exception that
|
@param InterruptType Defines the type of interrupt or exception that
|
||||||
occurred on the processor.This parameter is processor architecture specific.
|
occurred on the processor. This parameter is
|
||||||
|
processor architecture specific.
|
||||||
@param SystemContext A pointer to the processor context when
|
@param SystemContext A pointer to the processor context when
|
||||||
the interrupt occurred on the processor.
|
the interrupt occurred on the processor.
|
||||||
|
|
||||||
@return None
|
@return None
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
STATIC
|
||||||
VOID
|
VOID
|
||||||
EFIAPI
|
EFIAPI
|
||||||
GicV3IrqInterruptHandler (
|
GicV3IrqInterruptHandler (
|
||||||
@ -168,14 +178,12 @@ GicV3IrqInterruptHandler (
|
|||||||
// Call the registered interrupt handler.
|
// Call the registered interrupt handler.
|
||||||
InterruptHandler (GicInterrupt, SystemContext);
|
InterruptHandler (GicInterrupt, SystemContext);
|
||||||
} else {
|
} else {
|
||||||
DEBUG ((EFI_D_ERROR, "Spurious GIC interrupt: 0x%x\n", GicInterrupt));
|
DEBUG ((DEBUG_ERROR, "Spurious GIC interrupt: 0x%x\n", GicInterrupt));
|
||||||
GicV3EndOfInterrupt (&gHardwareInterruptV3Protocol, GicInterrupt);
|
GicV3EndOfInterrupt (&gHardwareInterruptV3Protocol, GicInterrupt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// The protocol instance produced by this driver
|
// The protocol instance produced by this driver
|
||||||
//
|
|
||||||
EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptV3Protocol = {
|
EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptV3Protocol = {
|
||||||
RegisterInterruptSource,
|
RegisterInterruptSource,
|
||||||
GicV3EnableInterruptSource,
|
GicV3EnableInterruptSource,
|
||||||
@ -242,17 +250,16 @@ GicV3DxeInitialize (
|
|||||||
UINT64 CpuTarget;
|
UINT64 CpuTarget;
|
||||||
UINT64 MpId;
|
UINT64 MpId;
|
||||||
|
|
||||||
// Make sure the Interrupt Controller Protocol is not already installed in the system.
|
// Make sure the Interrupt Controller Protocol is not already installed in
|
||||||
|
// the system.
|
||||||
ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid);
|
ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid);
|
||||||
|
|
||||||
mGicDistributorBase = PcdGet64 (PcdGicDistributorBase);
|
mGicDistributorBase = PcdGet64 (PcdGicDistributorBase);
|
||||||
mGicRedistributorsBase = PcdGet64 (PcdGicRedistributorsBase);
|
mGicRedistributorsBase = PcdGet64 (PcdGicRedistributorsBase);
|
||||||
mGicNumInterrupts = ArmGicGetMaxNumInterrupts (mGicDistributorBase);
|
mGicNumInterrupts = ArmGicGetMaxNumInterrupts (mGicDistributorBase);
|
||||||
|
|
||||||
//
|
|
||||||
// We will be driving this GIC in native v3 mode, i.e., with Affinity
|
// We will be driving this GIC in native v3 mode, i.e., with Affinity
|
||||||
// Routing enabled. So ensure that the ARE bit is set.
|
// Routing enabled. So ensure that the ARE bit is set.
|
||||||
//
|
|
||||||
if (!FeaturePcdGet (PcdArmGicV3WithV2Legacy)) {
|
if (!FeaturePcdGet (PcdArmGicV3WithV2Legacy)) {
|
||||||
MmioOr32 (mGicDistributorBase + ARM_GIC_ICDDCR, ARM_GIC_ICDDCR_ARE);
|
MmioOr32 (mGicDistributorBase + ARM_GIC_ICDDCR, ARM_GIC_ICDDCR_ARE);
|
||||||
}
|
}
|
||||||
@ -270,51 +277,65 @@ GicV3DxeInitialize (
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Targets the interrupts to the Primary Cpu
|
// Targets the interrupts to the Primary Cpu
|
||||||
//
|
|
||||||
|
|
||||||
if (FeaturePcdGet (PcdArmGicV3WithV2Legacy)) {
|
if (FeaturePcdGet (PcdArmGicV3WithV2Legacy)) {
|
||||||
// Only Primary CPU will run this code. We can identify our GIC CPU ID by reading
|
// Only Primary CPU will run this code. We can identify our GIC CPU ID by
|
||||||
// the GIC Distributor Target register. The 8 first GICD_ITARGETSRn are banked to each
|
// reading the GIC Distributor Target register. The 8 first
|
||||||
// connected CPU. These 8 registers hold the CPU targets fields for interrupts 0-31.
|
// GICD_ITARGETSRn are banked to each connected CPU. These 8 registers
|
||||||
// More Info in the GIC Specification about "Interrupt Processor Targets Registers"
|
// hold the CPU targets fields for interrupts 0-31. More Info in the GIC
|
||||||
//
|
// Specification about "Interrupt Processor Targets Registers"
|
||||||
// Read the first Interrupt Processor Targets Register (that corresponds to the 4
|
|
||||||
// first SGIs)
|
// Read the first Interrupt Processor Targets Register (that corresponds
|
||||||
|
// to the 4 first SGIs)
|
||||||
CpuTarget = MmioRead32 (mGicDistributorBase + ARM_GIC_ICDIPTR);
|
CpuTarget = MmioRead32 (mGicDistributorBase + ARM_GIC_ICDIPTR);
|
||||||
|
|
||||||
// The CPU target is a bit field mapping each CPU to a GIC CPU Interface. This value
|
// The CPU target is a bit field mapping each CPU to a GIC CPU Interface.
|
||||||
// is 0 when we run on a uniprocessor platform.
|
// This value is 0 when we run on a uniprocessor platform.
|
||||||
if (CpuTarget != 0) {
|
if (CpuTarget != 0) {
|
||||||
// The 8 first Interrupt Processor Targets Registers are read-only
|
// The 8 first Interrupt Processor Targets Registers are read-only
|
||||||
for (Index = 8; Index < (mGicNumInterrupts / 4); Index++) {
|
for (Index = 8; Index < (mGicNumInterrupts / 4); Index++) {
|
||||||
MmioWrite32 (mGicDistributorBase + ARM_GIC_ICDIPTR + (Index * 4), CpuTarget);
|
MmioWrite32 (
|
||||||
|
mGicDistributorBase + ARM_GIC_ICDIPTR + (Index * 4),
|
||||||
|
CpuTarget
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
MpId = ArmReadMpidr ();
|
MpId = ArmReadMpidr ();
|
||||||
CpuTarget = MpId & (ARM_CORE_AFF0 | ARM_CORE_AFF1 | ARM_CORE_AFF2 | ARM_CORE_AFF3);
|
CpuTarget = MpId &
|
||||||
|
(ARM_CORE_AFF0 | ARM_CORE_AFF1 | ARM_CORE_AFF2 | ARM_CORE_AFF3);
|
||||||
|
|
||||||
|
if ((MmioRead32 (
|
||||||
|
mGicDistributorBase + ARM_GIC_ICDDCR
|
||||||
|
) & ARM_GIC_ICDDCR_DS) != 0) {
|
||||||
|
|
||||||
if ((MmioRead32 (mGicDistributorBase + ARM_GIC_ICDDCR) & ARM_GIC_ICDDCR_DS) != 0) {
|
|
||||||
//
|
|
||||||
// If the Disable Security (DS) control bit is set, we are dealing with a
|
// If the Disable Security (DS) control bit is set, we are dealing with a
|
||||||
// GIC that has only one security state. In this case, let's assume we are
|
// GIC that has only one security state. In this case, let's assume we are
|
||||||
// executing in non-secure state (which is appropriate for DXE modules)
|
// executing in non-secure state (which is appropriate for DXE modules)
|
||||||
// and that no other firmware has performed any configuration on the GIC.
|
// and that no other firmware has performed any configuration on the GIC.
|
||||||
// This means we need to reconfigure all interrupts to non-secure Group 1
|
// This means we need to reconfigure all interrupts to non-secure Group 1
|
||||||
// first.
|
// first.
|
||||||
//
|
|
||||||
MmioWrite32 (mGicRedistributorsBase + ARM_GICR_CTLR_FRAME_SIZE + ARM_GIC_ICDISR, 0xffffffff);
|
MmioWrite32 (
|
||||||
|
mGicRedistributorsBase + ARM_GICR_CTLR_FRAME_SIZE + ARM_GIC_ICDISR,
|
||||||
|
0xffffffff
|
||||||
|
);
|
||||||
|
|
||||||
for (Index = 32; Index < mGicNumInterrupts; Index += 32) {
|
for (Index = 32; Index < mGicNumInterrupts; Index += 32) {
|
||||||
MmioWrite32 (mGicDistributorBase + ARM_GIC_ICDISR + Index / 8, 0xffffffff);
|
MmioWrite32 (
|
||||||
|
mGicDistributorBase + ARM_GIC_ICDISR + Index / 8,
|
||||||
|
0xffffffff
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Route the SPIs to the primary CPU. SPIs start at the INTID 32
|
// Route the SPIs to the primary CPU. SPIs start at the INTID 32
|
||||||
for (Index = 0; Index < (mGicNumInterrupts - 32); Index++) {
|
for (Index = 0; Index < (mGicNumInterrupts - 32); Index++) {
|
||||||
MmioWrite32 (mGicDistributorBase + ARM_GICD_IROUTER + (Index * 8), CpuTarget | ARM_GICD_IROUTER_IRM);
|
MmioWrite32 (
|
||||||
|
mGicDistributorBase + ARM_GICD_IROUTER + (Index * 8),
|
||||||
|
CpuTarget | ARM_GICD_IROUTER_IRM
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -331,7 +352,10 @@ GicV3DxeInitialize (
|
|||||||
ArmGicEnableDistributor (mGicDistributorBase);
|
ArmGicEnableDistributor (mGicDistributorBase);
|
||||||
|
|
||||||
Status = InstallAndRegisterInterruptService (
|
Status = InstallAndRegisterInterruptService (
|
||||||
&gHardwareInterruptV3Protocol, GicV3IrqInterruptHandler, GicV3ExitBootServicesEvent);
|
&gHardwareInterruptV3Protocol,
|
||||||
|
GicV3IrqInterruptHandler,
|
||||||
|
GicV3ExitBootServicesEvent
|
||||||
|
);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/** @file
|
/** @file
|
||||||
*
|
*
|
||||||
* Copyright (c) 2013-2014, ARM Limited. All rights reserved.
|
* Copyright (c) 2013-2017, ARM Limited. All rights reserved.
|
||||||
*
|
*
|
||||||
* This program and the accompanying materials
|
* This program and the accompanying materials
|
||||||
* are licensed and made available under the terms and conditions of the BSD
|
* are licensed and made available under the terms and conditions of the BSD
|
||||||
@ -29,16 +29,16 @@
|
|||||||
|
|
||||||
#include "GenericWatchdog.h"
|
#include "GenericWatchdog.h"
|
||||||
|
|
||||||
// The number of 100ns periods (the unit of time passed to these functions)
|
/* The number of 100ns periods (the unit of time passed to these functions)
|
||||||
// in a second
|
in a second */
|
||||||
#define TIME_UNITS_PER_SECOND 10000000
|
#define TIME_UNITS_PER_SECOND 10000000
|
||||||
|
|
||||||
// Tick frequency of the generic timer that is the basis of the generic watchdog
|
// Tick frequency of the generic timer basis of the generic watchdog.
|
||||||
UINTN mTimerFrequencyHz = 0;
|
UINTN mTimerFrequencyHz = 0;
|
||||||
|
|
||||||
// In cases where the compare register was set manually, information about
|
/* In cases where the compare register was set manually, information about
|
||||||
// how long the watchdog was asked to wait cannot be retrieved from hardware.
|
how long the watchdog was asked to wait cannot be retrieved from hardware.
|
||||||
// It is therefore stored here. 0 means the timer is not running.
|
It is therefore stored here. 0 means the timer is not running. */
|
||||||
UINT64 mNumTimerTicks = 0;
|
UINT64 mNumTimerTicks = 0;
|
||||||
|
|
||||||
EFI_HARDWARE_INTERRUPT_PROTOCOL *mInterruptProtocol;
|
EFI_HARDWARE_INTERRUPT_PROTOCOL *mInterruptProtocol;
|
||||||
@ -75,8 +75,7 @@ WatchdogDisable (
|
|||||||
return MmioWrite32 (GENERIC_WDOG_CONTROL_STATUS_REG, GENERIC_WDOG_DISABLED);
|
return MmioWrite32 (GENERIC_WDOG_CONTROL_STATUS_REG, GENERIC_WDOG_DISABLED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** On exiting boot services we must make sure the Watchdog Timer
|
||||||
On exiting boot services we must make sure the Watchdog Timer
|
|
||||||
is stopped.
|
is stopped.
|
||||||
**/
|
**/
|
||||||
VOID
|
VOID
|
||||||
@ -90,9 +89,8 @@ WatchdogExitBootServicesEvent (
|
|||||||
mNumTimerTicks = 0;
|
mNumTimerTicks = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* This function is called when the watchdog's first signal (WS0) goes high.
|
||||||
This function is called when the watchdog's first signal (WS0) goes high.
|
It uses the ResetSystem Runtime Service to reset the board.
|
||||||
It uses the ResetSystem Runtime Service to reset the board.
|
|
||||||
*/
|
*/
|
||||||
VOID
|
VOID
|
||||||
EFIAPI
|
EFIAPI
|
||||||
@ -101,7 +99,7 @@ WatchdogInterruptHandler (
|
|||||||
IN EFI_SYSTEM_CONTEXT SystemContext
|
IN EFI_SYSTEM_CONTEXT SystemContext
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
STATIC CONST CHAR16 ResetString[] = L"The generic watchdog timer ran out.";
|
STATIC CONST CHAR16 ResetString[]= L"The generic watchdog timer ran out.";
|
||||||
|
|
||||||
WatchdogDisable ();
|
WatchdogDisable ();
|
||||||
|
|
||||||
@ -126,10 +124,10 @@ WatchdogInterruptHandler (
|
|||||||
then the new handler is registered and EFI_SUCCESS is returned.
|
then the new handler is registered and EFI_SUCCESS is returned.
|
||||||
If NotifyFunction is NULL, and a handler is already registered,
|
If NotifyFunction is NULL, and a handler is already registered,
|
||||||
then that handler is unregistered.
|
then that handler is unregistered.
|
||||||
If an attempt is made to register a handler when a handler is already registered,
|
If an attempt is made to register a handler when a handler is already
|
||||||
then EFI_ALREADY_STARTED is returned.
|
registered, then EFI_ALREADY_STARTED is returned.
|
||||||
If an attempt is made to unregister a handler when a handler is not registered,
|
If an attempt is made to unregister a handler when a handler is not
|
||||||
then EFI_INVALID_PARAMETER is returned.
|
registered, then EFI_INVALID_PARAMETER is returned.
|
||||||
|
|
||||||
@param This The EFI_TIMER_ARCH_PROTOCOL instance.
|
@param This The EFI_TIMER_ARCH_PROTOCOL instance.
|
||||||
@param NotifyFunction The function to call when a timer interrupt fires.
|
@param NotifyFunction The function to call when a timer interrupt fires.
|
||||||
@ -139,11 +137,7 @@ WatchdogInterruptHandler (
|
|||||||
information is used to signal timer based events.
|
information is used to signal timer based events.
|
||||||
NULL will unregister the handler.
|
NULL will unregister the handler.
|
||||||
|
|
||||||
@retval EFI_SUCCESS The watchdog timer handler was registered.
|
@retval EFI_UNSUPPORTED The code does not support NotifyFunction.
|
||||||
@retval EFI_ALREADY_STARTED NotifyFunction is not NULL, and a handler is already
|
|
||||||
registered.
|
|
||||||
@retval EFI_INVALID_PARAMETER NotifyFunction is NULL, and a handler was not
|
|
||||||
previously registered.
|
|
||||||
|
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
@ -160,18 +154,18 @@ WatchdogRegisterHandler (
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
This function sets the amount of time to wait before firing the watchdog
|
This function sets the amount of time to wait before firing the watchdog
|
||||||
timer to TimerPeriod 100 nS units. If TimerPeriod is 0, then the watchdog
|
timer to TimerPeriod 100ns units. If TimerPeriod is 0, then the watchdog
|
||||||
timer is disabled.
|
timer is disabled.
|
||||||
|
|
||||||
@param This The EFI_WATCHDOG_TIMER_ARCH_PROTOCOL instance.
|
@param This The EFI_WATCHDOG_TIMER_ARCH_PROTOCOL instance.
|
||||||
@param TimerPeriod The amount of time in 100 nS units to wait before the watchdog
|
@param TimerPeriod The amount of time in 100ns units to wait before
|
||||||
timer is fired. If TimerPeriod is zero, then the watchdog
|
the watchdog timer is fired. If TimerPeriod is zero,
|
||||||
timer is disabled.
|
then the watchdog timer is disabled.
|
||||||
|
|
||||||
@retval EFI_SUCCESS The watchdog timer has been programmed to fire in Time
|
@retval EFI_SUCCESS The watchdog timer has been programmed to fire
|
||||||
100 nS units.
|
in Time 100ns units.
|
||||||
@retval EFI_DEVICE_ERROR A watchdog timer could not be programmed due to a device
|
@retval EFI_DEVICE_ERROR A watchdog timer could not be programmed due
|
||||||
error.
|
to a device error.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
@ -184,7 +178,7 @@ WatchdogSetTimerPeriod (
|
|||||||
UINTN SystemCount;
|
UINTN SystemCount;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
|
||||||
// if TimerPerdiod is 0, this is a request to stop the watchdog.
|
// if TimerPeriod is 0, this is a request to stop the watchdog.
|
||||||
if (TimerPeriod == 0) {
|
if (TimerPeriod == 0) {
|
||||||
mNumTimerTicks = 0;
|
mNumTimerTicks = 0;
|
||||||
return WatchdogDisable ();
|
return WatchdogDisable ();
|
||||||
@ -193,18 +187,14 @@ WatchdogSetTimerPeriod (
|
|||||||
// Work out how many timer ticks will equate to TimerPeriod
|
// Work out how many timer ticks will equate to TimerPeriod
|
||||||
mNumTimerTicks = (mTimerFrequencyHz * TimerPeriod) / TIME_UNITS_PER_SECOND;
|
mNumTimerTicks = (mTimerFrequencyHz * TimerPeriod) / TIME_UNITS_PER_SECOND;
|
||||||
|
|
||||||
//
|
/* If the number of required ticks is greater than the max the watchdog's
|
||||||
// If the number of required ticks is greater than the max number the
|
offset register (WOR) can hold, we need to manually compute and set
|
||||||
// watchdog's offset register (WOR) can hold, we need to manually compute and
|
the compare register (WCV) */
|
||||||
// set the compare register (WCV)
|
|
||||||
//
|
|
||||||
if (mNumTimerTicks > MAX_UINT32) {
|
if (mNumTimerTicks > MAX_UINT32) {
|
||||||
//
|
/* We need to enable the watchdog *before* writing to the compare register,
|
||||||
// We need to enable the watchdog *before* writing to the compare register,
|
because enabling the watchdog causes an "explicit refresh", which
|
||||||
// because enabling the watchdog causes an "explicit refresh", which
|
clobbers the compare register (WCV). In order to make sure this doesn't
|
||||||
// clobbers the compare register (WCV). In order to make sure this doesn't
|
trigger an interrupt, set the offset to max. */
|
||||||
// trigger an interrupt, set the offset to max.
|
|
||||||
//
|
|
||||||
Status = WatchdogWriteOffsetRegister (MAX_UINT32);
|
Status = WatchdogWriteOffsetRegister (MAX_UINT32);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return Status;
|
return Status;
|
||||||
@ -221,14 +211,14 @@ WatchdogSetTimerPeriod (
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This function retrieves the period of timer interrupts in 100 ns units,
|
This function retrieves the period of timer interrupts in 100ns units,
|
||||||
returns that value in TimerPeriod, and returns EFI_SUCCESS. If TimerPeriod
|
returns that value in TimerPeriod, and returns EFI_SUCCESS. If TimerPeriod
|
||||||
is NULL, then EFI_INVALID_PARAMETER is returned. If a TimerPeriod of 0 is
|
is NULL, then EFI_INVALID_PARAMETER is returned. If a TimerPeriod of 0 is
|
||||||
returned, then the timer is currently disabled.
|
returned, then the timer is currently disabled.
|
||||||
|
|
||||||
@param This The EFI_TIMER_ARCH_PROTOCOL instance.
|
@param This The EFI_TIMER_ARCH_PROTOCOL instance.
|
||||||
@param TimerPeriod A pointer to the timer period to retrieve in 100
|
@param TimerPeriod A pointer to the timer period to retrieve in
|
||||||
ns units. If 0 is returned, then the timer is
|
100ns units. If 0 is returned, then the timer is
|
||||||
currently disabled.
|
currently disabled.
|
||||||
|
|
||||||
|
|
||||||
@ -275,19 +265,19 @@ WatchdogGetTimerPeriod (
|
|||||||
this function will not have any chance of executing.
|
this function will not have any chance of executing.
|
||||||
|
|
||||||
@param SetTimerPeriod
|
@param SetTimerPeriod
|
||||||
Sets the period of the timer interrupt in 100 nS units.
|
Sets the period of the timer interrupt in 100ns units.
|
||||||
This function is optional, and may return EFI_UNSUPPORTED.
|
This function is optional, and may return EFI_UNSUPPORTED.
|
||||||
If this function is supported, then the timer period will
|
If this function is supported, then the timer period will
|
||||||
be rounded up to the nearest supported timer period.
|
be rounded up to the nearest supported timer period.
|
||||||
|
|
||||||
@param GetTimerPeriod
|
@param GetTimerPeriod
|
||||||
Retrieves the period of the timer interrupt in 100 nS units.
|
Retrieves the period of the timer interrupt in 100ns units.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
EFI_WATCHDOG_TIMER_ARCH_PROTOCOL gWatchdogTimer = {
|
EFI_WATCHDOG_TIMER_ARCH_PROTOCOL gWatchdogTimer = {
|
||||||
(EFI_WATCHDOG_TIMER_REGISTER_HANDLER) WatchdogRegisterHandler,
|
(EFI_WATCHDOG_TIMER_REGISTER_HANDLER)WatchdogRegisterHandler,
|
||||||
(EFI_WATCHDOG_TIMER_SET_TIMER_PERIOD) WatchdogSetTimerPeriod,
|
(EFI_WATCHDOG_TIMER_SET_TIMER_PERIOD)WatchdogSetTimerPeriod,
|
||||||
(EFI_WATCHDOG_TIMER_GET_TIMER_PERIOD) WatchdogGetTimerPeriod
|
(EFI_WATCHDOG_TIMER_GET_TIMER_PERIOD)WatchdogGetTimerPeriod
|
||||||
};
|
};
|
||||||
|
|
||||||
EFI_EVENT EfiExitBootServicesEvent = (EFI_EVENT)NULL;
|
EFI_EVENT EfiExitBootServicesEvent = (EFI_EVENT)NULL;
|
||||||
@ -302,11 +292,9 @@ GenericWatchdogEntry (
|
|||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
EFI_HANDLE Handle;
|
EFI_HANDLE Handle;
|
||||||
|
|
||||||
//
|
/* Make sure the Watchdog Timer Architectural Protocol has not been installed
|
||||||
// Make sure the Watchdog Timer Architectural Protocol has not been installed
|
in the system yet.
|
||||||
// in the system yet.
|
This will avoid conflicts with the universal watchdog */
|
||||||
// This will avoid conflicts with the universal watchdog
|
|
||||||
//
|
|
||||||
ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiWatchdogTimerArchProtocolGuid);
|
ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiWatchdogTimerArchProtocolGuid);
|
||||||
|
|
||||||
mTimerFrequencyHz = ArmGenericTimerGetTimerFreq ();
|
mTimerFrequencyHz = ArmGenericTimerGetTimerFreq ();
|
||||||
@ -314,8 +302,11 @@ GenericWatchdogEntry (
|
|||||||
|
|
||||||
// Register for an ExitBootServicesEvent
|
// Register for an ExitBootServicesEvent
|
||||||
Status = gBS->CreateEvent (
|
Status = gBS->CreateEvent (
|
||||||
EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY,
|
EVT_SIGNAL_EXIT_BOOT_SERVICES,
|
||||||
WatchdogExitBootServicesEvent, NULL, &EfiExitBootServicesEvent
|
TPL_NOTIFY,
|
||||||
|
WatchdogExitBootServicesEvent,
|
||||||
|
NULL,
|
||||||
|
&EfiExitBootServicesEvent
|
||||||
);
|
);
|
||||||
if (!EFI_ERROR (Status)) {
|
if (!EFI_ERROR (Status)) {
|
||||||
// Install interrupt handler
|
// Install interrupt handler
|
||||||
@ -326,26 +317,24 @@ GenericWatchdogEntry (
|
|||||||
);
|
);
|
||||||
if (!EFI_ERROR (Status)) {
|
if (!EFI_ERROR (Status)) {
|
||||||
Status = mInterruptProtocol->RegisterInterruptSource (
|
Status = mInterruptProtocol->RegisterInterruptSource (
|
||||||
mInterruptProtocol,
|
mInterruptProtocol,
|
||||||
FixedPcdGet32 (PcdGenericWatchdogEl2IntrNum),
|
FixedPcdGet32 (PcdGenericWatchdogEl2IntrNum),
|
||||||
WatchdogInterruptHandler
|
WatchdogInterruptHandler
|
||||||
);
|
);
|
||||||
if (!EFI_ERROR (Status)) {
|
if (!EFI_ERROR (Status)) {
|
||||||
// Install the Timer Architectural Protocol onto a new handle
|
// Install the Timer Architectural Protocol onto a new handle
|
||||||
Handle = NULL;
|
Handle = NULL;
|
||||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||||
&Handle,
|
&Handle,
|
||||||
&gEfiWatchdogTimerArchProtocolGuid, &gWatchdogTimer,
|
&gEfiWatchdogTimerArchProtocolGuid,
|
||||||
|
&gWatchdogTimer,
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
ASSERT_EFI_ERROR (Status);
|
||||||
// The watchdog failed to initialize
|
|
||||||
ASSERT (FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
mNumTimerTicks = 0;
|
mNumTimerTicks = 0;
|
||||||
WatchdogDisable ();
|
WatchdogDisable ();
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/** @file
|
/** @file
|
||||||
*
|
*
|
||||||
* Copyright (c) 2011-2015, ARM Limited. All rights reserved.
|
* Copyright (c) 2011-2017, ARM Limited. All rights reserved.
|
||||||
*
|
*
|
||||||
* This program and the accompanying materials
|
* This program and the accompanying materials
|
||||||
* are licensed and made available under the terms and conditions of the BSD License
|
* are licensed and made available under the terms and conditions of the BSD License
|
||||||
@ -17,9 +17,7 @@
|
|||||||
|
|
||||||
#include <Library/ArmGicArchLib.h>
|
#include <Library/ArmGicArchLib.h>
|
||||||
|
|
||||||
//
|
|
||||||
// GIC Distributor
|
// GIC Distributor
|
||||||
//
|
|
||||||
#define ARM_GIC_ICDDCR 0x000 // Distributor Control Register
|
#define ARM_GIC_ICDDCR 0x000 // Distributor Control Register
|
||||||
#define ARM_GIC_ICDICTR 0x004 // Interrupt Controller Type Register
|
#define ARM_GIC_ICDICTR 0x004 // Interrupt Controller Type Register
|
||||||
#define ARM_GIC_ICDIIDR 0x008 // Implementer Identification Register
|
#define ARM_GIC_ICDIIDR 0x008 // Implementer Identification Register
|
||||||
@ -51,9 +49,7 @@
|
|||||||
#define ARM_GIC_ICDDCR_ARE (1 << 4) // Affinity Routing Enable (ARE)
|
#define ARM_GIC_ICDDCR_ARE (1 << 4) // Affinity Routing Enable (ARE)
|
||||||
#define ARM_GIC_ICDDCR_DS (1 << 6) // Disable Security (DS)
|
#define ARM_GIC_ICDDCR_DS (1 << 6) // Disable Security (DS)
|
||||||
|
|
||||||
//
|
|
||||||
// GIC Redistributor
|
// GIC Redistributor
|
||||||
//
|
|
||||||
|
|
||||||
#define ARM_GICR_CTLR_FRAME_SIZE SIZE_64KB
|
#define ARM_GICR_CTLR_FRAME_SIZE SIZE_64KB
|
||||||
#define ARM_GICR_SGI_PPI_FRAME_SIZE SIZE_64KB
|
#define ARM_GICR_SGI_PPI_FRAME_SIZE SIZE_64KB
|
||||||
@ -65,9 +61,7 @@
|
|||||||
#define ARM_GICR_ISENABLER 0x0100 // Interrupt Set-Enable Registers
|
#define ARM_GICR_ISENABLER 0x0100 // Interrupt Set-Enable Registers
|
||||||
#define ARM_GICR_ICENABLER 0x0180 // Interrupt Clear-Enable Registers
|
#define ARM_GICR_ICENABLER 0x0180 // Interrupt Clear-Enable Registers
|
||||||
|
|
||||||
//
|
|
||||||
// GIC Cpu interface
|
// GIC Cpu interface
|
||||||
//
|
|
||||||
#define ARM_GIC_ICCICR 0x00 // CPU Interface Control Register
|
#define ARM_GIC_ICCICR 0x00 // CPU Interface Control Register
|
||||||
#define ARM_GIC_ICCPMR 0x04 // Interrupt Priority Mask Register
|
#define ARM_GIC_ICCPMR 0x04 // Interrupt Priority Mask Register
|
||||||
#define ARM_GIC_ICCBPR 0x08 // Binary Point Register
|
#define ARM_GIC_ICCBPR 0x08 // Binary Point Register
|
||||||
@ -104,9 +98,7 @@ ArmGicGetInterfaceIdentification (
|
|||||||
IN INTN GicInterruptInterfaceBase
|
IN INTN GicInterruptInterfaceBase
|
||||||
);
|
);
|
||||||
|
|
||||||
//
|
|
||||||
// GIC Secure interfaces
|
// GIC Secure interfaces
|
||||||
//
|
|
||||||
VOID
|
VOID
|
||||||
EFIAPI
|
EFIAPI
|
||||||
ArmGicSetupNonSecure (
|
ArmGicSetupNonSecure (
|
||||||
@ -170,7 +162,8 @@ ArmGicSendSgiTo (
|
|||||||
* in the GICv3 the register value is only the InterruptId.
|
* in the GICv3 the register value is only the InterruptId.
|
||||||
*
|
*
|
||||||
* @param GicInterruptInterfaceBase Base Address of the GIC CPU Interface
|
* @param GicInterruptInterfaceBase Base Address of the GIC CPU Interface
|
||||||
* @param InterruptId InterruptId read from the Interrupt Acknowledge Register
|
* @param InterruptId InterruptId read from the Interrupt
|
||||||
|
* Acknowledge Register
|
||||||
*
|
*
|
||||||
* @retval value returned by the Interrupt Acknowledge Register
|
* @retval value returned by the Interrupt Acknowledge Register
|
||||||
*
|
*
|
||||||
@ -220,12 +213,12 @@ ArmGicIsInterruptEnabled (
|
|||||||
IN UINTN Source
|
IN UINTN Source
|
||||||
);
|
);
|
||||||
|
|
||||||
//
|
|
||||||
// GIC revision 2 specific declarations
|
// GIC revision 2 specific declarations
|
||||||
//
|
|
||||||
|
|
||||||
// Interrupts from 1020 to 1023 are considered as special interrupts (eg: spurious interrupts)
|
// Interrupts from 1020 to 1023 are considered as special interrupts
|
||||||
#define ARM_GIC_IS_SPECIAL_INTERRUPTS(Interrupt) (((Interrupt) >= 1020) && ((Interrupt) <= 1023))
|
// (eg: spurious interrupts)
|
||||||
|
#define ARM_GIC_IS_SPECIAL_INTERRUPTS(Interrupt) \
|
||||||
|
(((Interrupt) >= 1020) && ((Interrupt) <= 1023))
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
EFIAPI
|
EFIAPI
|
||||||
@ -260,9 +253,7 @@ ArmGicV2EndOfInterrupt (
|
|||||||
IN UINTN Source
|
IN UINTN Source
|
||||||
);
|
);
|
||||||
|
|
||||||
//
|
|
||||||
// GIC revision 3 specific declarations
|
// GIC revision 3 specific declarations
|
||||||
//
|
|
||||||
|
|
||||||
#define ICC_SRE_EL2_SRE (1 << 0)
|
#define ICC_SRE_EL2_SRE (1 << 0)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user