mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-25 06:34:30 +02:00
ArmPkg/ArmGic: Disentangle v2 and v3 versions of IRQ en/disable APIs
ArmGicLib is agnostic about the difference between v2 and v3, but its APIs are only called from code that is either v2-specific or v3-specific. That makes the generic interface kind of pointless, and we can just merge this code into the callers. Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
This commit is contained in:
parent
a4928a0cfc
commit
4e874fcf09
@ -13,97 +13,6 @@
|
|||||||
#include <Library/IoLib.h>
|
#include <Library/IoLib.h>
|
||||||
#include <Library/PcdLib.h>
|
#include <Library/PcdLib.h>
|
||||||
|
|
||||||
// In GICv3, there are 2 x 64KB frames:
|
|
||||||
// Redistributor control frame + SGI Control & Generation frame
|
|
||||||
#define GIC_V3_REDISTRIBUTOR_GRANULARITY (ARM_GICR_CTLR_FRAME_SIZE \
|
|
||||||
+ ARM_GICR_SGI_PPI_FRAME_SIZE)
|
|
||||||
|
|
||||||
// In GICv4, there are 2 additional 64KB frames:
|
|
||||||
// VLPI frame + Reserved page frame
|
|
||||||
#define GIC_V4_REDISTRIBUTOR_GRANULARITY (GIC_V3_REDISTRIBUTOR_GRANULARITY \
|
|
||||||
+ ARM_GICR_SGI_VLPI_FRAME_SIZE \
|
|
||||||
+ ARM_GICR_SGI_RESERVED_FRAME_SIZE)
|
|
||||||
|
|
||||||
#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))
|
|
||||||
|
|
||||||
#define IPRIORITY_ADDRESS(base, offset) ((base) +\
|
|
||||||
ARM_GICR_CTLR_FRAME_SIZE + ARM_GIC_ICDIPR + 4 * (offset))
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Return whether the Source interrupt index refers to a shared interrupt (SPI)
|
|
||||||
*/
|
|
||||||
STATIC
|
|
||||||
BOOLEAN
|
|
||||||
SourceIsSpi (
|
|
||||||
IN UINTN Source
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return Source >= 32 && Source < 1020;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the base address of the GIC redistributor for the current CPU
|
|
||||||
*
|
|
||||||
* @param Revision GIC Revision. The GIC redistributor might have a different
|
|
||||||
* granularity following the GIC revision.
|
|
||||||
*
|
|
||||||
* @retval Base address of the associated GIC Redistributor
|
|
||||||
*/
|
|
||||||
STATIC
|
|
||||||
UINTN
|
|
||||||
GicGetCpuRedistributorBase (
|
|
||||||
IN UINTN GicRedistributorBase,
|
|
||||||
IN ARM_GIC_ARCH_REVISION Revision
|
|
||||||
)
|
|
||||||
{
|
|
||||||
UINTN MpId;
|
|
||||||
UINTN CpuAffinity;
|
|
||||||
UINTN Affinity;
|
|
||||||
UINTN GicCpuRedistributorBase;
|
|
||||||
UINT64 TypeRegister;
|
|
||||||
|
|
||||||
MpId = ArmReadMpidr ();
|
|
||||||
// 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
|
|
||||||
CpuAffinity = (MpId & (ARM_CORE_AFF0 | ARM_CORE_AFF1 | ARM_CORE_AFF2)) |
|
|
||||||
((MpId & ARM_CORE_AFF3) >> 8);
|
|
||||||
|
|
||||||
if (Revision < ARM_GIC_ARCH_REVISION_3) {
|
|
||||||
ASSERT_EFI_ERROR (EFI_UNSUPPORTED);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
GicCpuRedistributorBase = GicRedistributorBase;
|
|
||||||
|
|
||||||
do {
|
|
||||||
TypeRegister = MmioRead64 (GicCpuRedistributorBase + ARM_GICR_TYPER);
|
|
||||||
Affinity = ARM_GICR_TYPER_GET_AFFINITY (TypeRegister);
|
|
||||||
if (Affinity == CpuAffinity) {
|
|
||||||
return GicCpuRedistributorBase;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move to the next GIC Redistributor frame.
|
|
||||||
// The GIC specification does not forbid a mixture of redistributors
|
|
||||||
// with or without support for virtual LPIs, so we test Virtual LPIs
|
|
||||||
// Support (VLPIS) bit for each frame to decide the granularity.
|
|
||||||
// Note: The assumption here is that the redistributors are adjacent
|
|
||||||
// for all CPUs. However this may not be the case for NUMA systems.
|
|
||||||
GicCpuRedistributorBase += (((ARM_GICR_TYPER_VLPIS & TypeRegister) != 0)
|
|
||||||
? GIC_V4_REDISTRIBUTOR_GRANULARITY
|
|
||||||
: GIC_V3_REDISTRIBUTOR_GRANULARITY);
|
|
||||||
} while ((TypeRegister & ARM_GICR_TYPER_LAST) == 0);
|
|
||||||
|
|
||||||
// The Redistributor has not been found for the current CPU
|
|
||||||
ASSERT_EFI_ERROR (EFI_NOT_FOUND);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Return the GIC CPU Interrupt Interface ID.
|
Return the GIC CPU Interrupt Interface ID.
|
||||||
|
|
||||||
@ -137,180 +46,6 @@ ArmGicGetMaxNumInterrupts (
|
|||||||
return (ItLines == 0x1f) ? 1020 : 32 * (ItLines + 1);
|
return (ItLines == 0x1f) ? 1020 : 32 * (ItLines + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
|
||||||
EFIAPI
|
|
||||||
ArmGicSetInterruptPriority (
|
|
||||||
IN UINTN GicDistributorBase,
|
|
||||||
IN UINTN GicRedistributorBase,
|
|
||||||
IN UINTN Source,
|
|
||||||
IN UINT32 Priority
|
|
||||||
)
|
|
||||||
{
|
|
||||||
UINT32 RegOffset;
|
|
||||||
UINT8 RegShift;
|
|
||||||
ARM_GIC_ARCH_REVISION Revision;
|
|
||||||
UINTN GicCpuRedistributorBase;
|
|
||||||
|
|
||||||
// Calculate register offset and bit position
|
|
||||||
RegOffset = (UINT32)(Source / 4);
|
|
||||||
RegShift = (UINT8)((Source % 4) * 8);
|
|
||||||
|
|
||||||
Revision = ArmGicGetSupportedArchRevision ();
|
|
||||||
if ((Revision == ARM_GIC_ARCH_REVISION_2) ||
|
|
||||||
SourceIsSpi (Source))
|
|
||||||
{
|
|
||||||
MmioAndThenOr32 (
|
|
||||||
GicDistributorBase + ARM_GIC_ICDIPR + (4 * RegOffset),
|
|
||||||
~(0xff << RegShift),
|
|
||||||
Priority << RegShift
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
GicCpuRedistributorBase = GicGetCpuRedistributorBase (
|
|
||||||
GicRedistributorBase,
|
|
||||||
Revision
|
|
||||||
);
|
|
||||||
if (GicCpuRedistributorBase == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MmioAndThenOr32 (
|
|
||||||
IPRIORITY_ADDRESS (GicCpuRedistributorBase, RegOffset),
|
|
||||||
~(0xff << RegShift),
|
|
||||||
Priority << RegShift
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
|
||||||
EFIAPI
|
|
||||||
ArmGicEnableInterrupt (
|
|
||||||
IN UINTN GicDistributorBase,
|
|
||||||
IN UINTN GicRedistributorBase,
|
|
||||||
IN UINTN Source
|
|
||||||
)
|
|
||||||
{
|
|
||||||
UINT32 RegOffset;
|
|
||||||
UINT8 RegShift;
|
|
||||||
ARM_GIC_ARCH_REVISION Revision;
|
|
||||||
UINTN GicCpuRedistributorBase;
|
|
||||||
|
|
||||||
// Calculate enable register offset and bit position
|
|
||||||
RegOffset = (UINT32)(Source / 32);
|
|
||||||
RegShift = (UINT8)(Source % 32);
|
|
||||||
|
|
||||||
Revision = ArmGicGetSupportedArchRevision ();
|
|
||||||
if ((Revision == ARM_GIC_ARCH_REVISION_2) ||
|
|
||||||
SourceIsSpi (Source))
|
|
||||||
{
|
|
||||||
// Write set-enable register
|
|
||||||
MmioWrite32 (
|
|
||||||
GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset),
|
|
||||||
1 << RegShift
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
GicCpuRedistributorBase = GicGetCpuRedistributorBase (
|
|
||||||
GicRedistributorBase,
|
|
||||||
Revision
|
|
||||||
);
|
|
||||||
if (GicCpuRedistributorBase == 0) {
|
|
||||||
ASSERT_EFI_ERROR (EFI_NOT_FOUND);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write set-enable register
|
|
||||||
MmioWrite32 (
|
|
||||||
ISENABLER_ADDRESS (GicCpuRedistributorBase, RegOffset),
|
|
||||||
1 << RegShift
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
|
||||||
EFIAPI
|
|
||||||
ArmGicDisableInterrupt (
|
|
||||||
IN UINTN GicDistributorBase,
|
|
||||||
IN UINTN GicRedistributorBase,
|
|
||||||
IN UINTN Source
|
|
||||||
)
|
|
||||||
{
|
|
||||||
UINT32 RegOffset;
|
|
||||||
UINT8 RegShift;
|
|
||||||
ARM_GIC_ARCH_REVISION Revision;
|
|
||||||
UINTN GicCpuRedistributorBase;
|
|
||||||
|
|
||||||
// Calculate enable register offset and bit position
|
|
||||||
RegOffset = (UINT32)(Source / 32);
|
|
||||||
RegShift = (UINT8)(Source % 32);
|
|
||||||
|
|
||||||
Revision = ArmGicGetSupportedArchRevision ();
|
|
||||||
if ((Revision == ARM_GIC_ARCH_REVISION_2) ||
|
|
||||||
SourceIsSpi (Source))
|
|
||||||
{
|
|
||||||
// Write clear-enable register
|
|
||||||
MmioWrite32 (
|
|
||||||
GicDistributorBase + ARM_GIC_ICDICER + (4 * RegOffset),
|
|
||||||
1 << RegShift
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
GicCpuRedistributorBase = GicGetCpuRedistributorBase (
|
|
||||||
GicRedistributorBase,
|
|
||||||
Revision
|
|
||||||
);
|
|
||||||
if (GicCpuRedistributorBase == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write clear-enable register
|
|
||||||
MmioWrite32 (
|
|
||||||
ICENABLER_ADDRESS (GicCpuRedistributorBase, RegOffset),
|
|
||||||
1 << RegShift
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOLEAN
|
|
||||||
EFIAPI
|
|
||||||
ArmGicIsInterruptEnabled (
|
|
||||||
IN UINTN GicDistributorBase,
|
|
||||||
IN UINTN GicRedistributorBase,
|
|
||||||
IN UINTN Source
|
|
||||||
)
|
|
||||||
{
|
|
||||||
UINT32 RegOffset;
|
|
||||||
UINT8 RegShift;
|
|
||||||
ARM_GIC_ARCH_REVISION Revision;
|
|
||||||
UINTN GicCpuRedistributorBase;
|
|
||||||
UINT32 Interrupts;
|
|
||||||
|
|
||||||
// Calculate enable register offset and bit position
|
|
||||||
RegOffset = (UINT32)(Source / 32);
|
|
||||||
RegShift = (UINT8)(Source % 32);
|
|
||||||
|
|
||||||
Revision = ArmGicGetSupportedArchRevision ();
|
|
||||||
if ((Revision == ARM_GIC_ARCH_REVISION_2) ||
|
|
||||||
SourceIsSpi (Source))
|
|
||||||
{
|
|
||||||
Interrupts = MmioRead32 (
|
|
||||||
GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset)
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
GicCpuRedistributorBase = GicGetCpuRedistributorBase (
|
|
||||||
GicRedistributorBase,
|
|
||||||
Revision
|
|
||||||
);
|
|
||||||
if (GicCpuRedistributorBase == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read set-enable register
|
|
||||||
Interrupts = MmioRead32 (
|
|
||||||
ISENABLER_ADDRESS (GicCpuRedistributorBase, RegOffset)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ((Interrupts & (1 << RegShift)) != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
EFIAPI
|
EFIAPI
|
||||||
ArmGicDisableDistributor (
|
ArmGicDisableDistributor (
|
||||||
|
@ -28,6 +28,73 @@ extern EFI_HARDWARE_INTERRUPT2_PROTOCOL gHardwareInterrupt2V2Protocol;
|
|||||||
STATIC UINTN mGicInterruptInterfaceBase;
|
STATIC UINTN mGicInterruptInterfaceBase;
|
||||||
STATIC UINTN mGicDistributorBase;
|
STATIC UINTN mGicDistributorBase;
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
ArmGicEnableInterrupt (
|
||||||
|
IN UINTN GicDistributorBase,
|
||||||
|
IN UINTN GicRedistributorBase,
|
||||||
|
IN UINTN Source
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT32 RegOffset;
|
||||||
|
UINT8 RegShift;
|
||||||
|
|
||||||
|
// Calculate enable register offset and bit position
|
||||||
|
RegOffset = (UINT32)(Source / 32);
|
||||||
|
RegShift = (UINT8)(Source % 32);
|
||||||
|
|
||||||
|
// Write set-enable register
|
||||||
|
MmioWrite32 (
|
||||||
|
GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset),
|
||||||
|
1 << RegShift
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
ArmGicDisableInterrupt (
|
||||||
|
IN UINTN GicDistributorBase,
|
||||||
|
IN UINTN GicRedistributorBase,
|
||||||
|
IN UINTN Source
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT32 RegOffset;
|
||||||
|
UINT8 RegShift;
|
||||||
|
|
||||||
|
// Calculate enable register offset and bit position
|
||||||
|
RegOffset = (UINT32)(Source / 32);
|
||||||
|
RegShift = (UINT8)(Source % 32);
|
||||||
|
|
||||||
|
// Write clear-enable register
|
||||||
|
MmioWrite32 (
|
||||||
|
GicDistributorBase + ARM_GIC_ICDICER + (4 * RegOffset),
|
||||||
|
1 << RegShift
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
BOOLEAN
|
||||||
|
ArmGicIsInterruptEnabled (
|
||||||
|
IN UINTN GicDistributorBase,
|
||||||
|
IN UINTN GicRedistributorBase,
|
||||||
|
IN UINTN Source
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT32 RegOffset;
|
||||||
|
UINT8 RegShift;
|
||||||
|
UINT32 Interrupts;
|
||||||
|
|
||||||
|
// Calculate enable register offset and bit position
|
||||||
|
RegOffset = (UINT32)(Source / 32);
|
||||||
|
RegShift = (UINT8)(Source % 32);
|
||||||
|
|
||||||
|
Interrupts = MmioRead32 (
|
||||||
|
GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset)
|
||||||
|
);
|
||||||
|
|
||||||
|
return ((Interrupts & (1 << RegShift)) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Enable interrupt source Source.
|
Enable interrupt source Source.
|
||||||
|
|
||||||
|
@ -1,35 +0,0 @@
|
|||||||
/** @file
|
|
||||||
*
|
|
||||||
* Copyright (c) 2011-2023, Arm Limited. All rights reserved.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
||||||
*
|
|
||||||
**/
|
|
||||||
|
|
||||||
#include <Uefi.h>
|
|
||||||
#include <Library/IoLib.h>
|
|
||||||
#include <Library/ArmGicLib.h>
|
|
||||||
|
|
||||||
VOID
|
|
||||||
EFIAPI
|
|
||||||
ArmGicV2EnableInterruptInterface (
|
|
||||||
IN UINTN GicInterruptInterfaceBase
|
|
||||||
)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Enable the CPU interface in Non-Secure world
|
|
||||||
* Note: The ICCICR register is banked when Security extensions are implemented
|
|
||||||
*/
|
|
||||||
MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR, 0x1);
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
|
||||||
EFIAPI
|
|
||||||
ArmGicV2DisableInterruptInterface (
|
|
||||||
IN UINTN GicInterruptInterfaceBase
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// Disable Gic Interface
|
|
||||||
MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR, 0x0);
|
|
||||||
MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, 0x0);
|
|
||||||
}
|
|
@ -12,12 +12,248 @@
|
|||||||
|
|
||||||
#define ARM_GIC_DEFAULT_PRIORITY 0x80
|
#define ARM_GIC_DEFAULT_PRIORITY 0x80
|
||||||
|
|
||||||
|
// In GICv3, there are 2 x 64KB frames:
|
||||||
|
// Redistributor control frame + SGI Control & Generation frame
|
||||||
|
#define GIC_V3_REDISTRIBUTOR_GRANULARITY (ARM_GICR_CTLR_FRAME_SIZE \
|
||||||
|
+ ARM_GICR_SGI_PPI_FRAME_SIZE)
|
||||||
|
|
||||||
|
// In GICv4, there are 2 additional 64KB frames:
|
||||||
|
// VLPI frame + Reserved page frame
|
||||||
|
#define GIC_V4_REDISTRIBUTOR_GRANULARITY (GIC_V3_REDISTRIBUTOR_GRANULARITY \
|
||||||
|
+ ARM_GICR_SGI_VLPI_FRAME_SIZE \
|
||||||
|
+ ARM_GICR_SGI_RESERVED_FRAME_SIZE)
|
||||||
|
|
||||||
|
#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))
|
||||||
|
|
||||||
|
#define IPRIORITY_ADDRESS(base, offset) ((base) +\
|
||||||
|
ARM_GICR_CTLR_FRAME_SIZE + ARM_GIC_ICDIPR + 4 * (offset))
|
||||||
|
|
||||||
extern EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptV3Protocol;
|
extern EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptV3Protocol;
|
||||||
extern EFI_HARDWARE_INTERRUPT2_PROTOCOL gHardwareInterrupt2V3Protocol;
|
extern EFI_HARDWARE_INTERRUPT2_PROTOCOL gHardwareInterrupt2V3Protocol;
|
||||||
|
|
||||||
STATIC UINTN mGicDistributorBase;
|
STATIC UINTN mGicDistributorBase;
|
||||||
STATIC UINTN mGicRedistributorsBase;
|
STATIC UINTN mGicRedistributorsBase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Return whether the Source interrupt index refers to a shared interrupt (SPI)
|
||||||
|
*/
|
||||||
|
STATIC
|
||||||
|
BOOLEAN
|
||||||
|
SourceIsSpi (
|
||||||
|
IN UINTN Source
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return Source >= 32 && Source < 1020;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the base address of the GIC redistributor for the current CPU
|
||||||
|
*
|
||||||
|
* @retval Base address of the associated GIC Redistributor
|
||||||
|
*/
|
||||||
|
STATIC
|
||||||
|
UINTN
|
||||||
|
GicGetCpuRedistributorBase (
|
||||||
|
IN UINTN GicRedistributorBase
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINTN MpId;
|
||||||
|
UINTN CpuAffinity;
|
||||||
|
UINTN Affinity;
|
||||||
|
UINTN GicCpuRedistributorBase;
|
||||||
|
UINT64 TypeRegister;
|
||||||
|
|
||||||
|
MpId = ArmReadMpidr ();
|
||||||
|
// 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
|
||||||
|
CpuAffinity = (MpId & (ARM_CORE_AFF0 | ARM_CORE_AFF1 | ARM_CORE_AFF2)) |
|
||||||
|
((MpId & ARM_CORE_AFF3) >> 8);
|
||||||
|
|
||||||
|
GicCpuRedistributorBase = GicRedistributorBase;
|
||||||
|
|
||||||
|
do {
|
||||||
|
TypeRegister = MmioRead64 (GicCpuRedistributorBase + ARM_GICR_TYPER);
|
||||||
|
Affinity = ARM_GICR_TYPER_GET_AFFINITY (TypeRegister);
|
||||||
|
if (Affinity == CpuAffinity) {
|
||||||
|
return GicCpuRedistributorBase;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move to the next GIC Redistributor frame.
|
||||||
|
// The GIC specification does not forbid a mixture of redistributors
|
||||||
|
// with or without support for virtual LPIs, so we test Virtual LPIs
|
||||||
|
// Support (VLPIS) bit for each frame to decide the granularity.
|
||||||
|
// Note: The assumption here is that the redistributors are adjacent
|
||||||
|
// for all CPUs. However this may not be the case for NUMA systems.
|
||||||
|
GicCpuRedistributorBase += (((ARM_GICR_TYPER_VLPIS & TypeRegister) != 0)
|
||||||
|
? GIC_V4_REDISTRIBUTOR_GRANULARITY
|
||||||
|
: GIC_V3_REDISTRIBUTOR_GRANULARITY);
|
||||||
|
} while ((TypeRegister & ARM_GICR_TYPER_LAST) == 0);
|
||||||
|
|
||||||
|
// The Redistributor has not been found for the current CPU
|
||||||
|
ASSERT_EFI_ERROR (EFI_NOT_FOUND);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
ArmGicSetInterruptPriority (
|
||||||
|
IN UINTN GicDistributorBase,
|
||||||
|
IN UINTN GicRedistributorBase,
|
||||||
|
IN UINTN Source,
|
||||||
|
IN UINT32 Priority
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT32 RegOffset;
|
||||||
|
UINT8 RegShift;
|
||||||
|
UINTN GicCpuRedistributorBase;
|
||||||
|
|
||||||
|
// Calculate register offset and bit position
|
||||||
|
RegOffset = (UINT32)(Source / 4);
|
||||||
|
RegShift = (UINT8)((Source % 4) * 8);
|
||||||
|
|
||||||
|
if (SourceIsSpi (Source)) {
|
||||||
|
MmioAndThenOr32 (
|
||||||
|
GicDistributorBase + ARM_GIC_ICDIPR + (4 * RegOffset),
|
||||||
|
~(0xff << RegShift),
|
||||||
|
Priority << RegShift
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
GicCpuRedistributorBase = GicGetCpuRedistributorBase (
|
||||||
|
GicRedistributorBase
|
||||||
|
);
|
||||||
|
if (GicCpuRedistributorBase == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MmioAndThenOr32 (
|
||||||
|
IPRIORITY_ADDRESS (GicCpuRedistributorBase, RegOffset),
|
||||||
|
~(0xff << RegShift),
|
||||||
|
Priority << RegShift
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
ArmGicEnableInterrupt (
|
||||||
|
IN UINTN GicDistributorBase,
|
||||||
|
IN UINTN GicRedistributorBase,
|
||||||
|
IN UINTN Source
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT32 RegOffset;
|
||||||
|
UINT8 RegShift;
|
||||||
|
UINTN GicCpuRedistributorBase;
|
||||||
|
|
||||||
|
// Calculate enable register offset and bit position
|
||||||
|
RegOffset = (UINT32)(Source / 32);
|
||||||
|
RegShift = (UINT8)(Source % 32);
|
||||||
|
|
||||||
|
if (SourceIsSpi (Source)) {
|
||||||
|
// Write set-enable register
|
||||||
|
MmioWrite32 (
|
||||||
|
GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset),
|
||||||
|
1 << RegShift
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
GicCpuRedistributorBase = GicGetCpuRedistributorBase (
|
||||||
|
GicRedistributorBase
|
||||||
|
);
|
||||||
|
if (GicCpuRedistributorBase == 0) {
|
||||||
|
ASSERT_EFI_ERROR (EFI_NOT_FOUND);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write set-enable register
|
||||||
|
MmioWrite32 (
|
||||||
|
ISENABLER_ADDRESS (GicCpuRedistributorBase, RegOffset),
|
||||||
|
1 << RegShift
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
ArmGicDisableInterrupt (
|
||||||
|
IN UINTN GicDistributorBase,
|
||||||
|
IN UINTN GicRedistributorBase,
|
||||||
|
IN UINTN Source
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT32 RegOffset;
|
||||||
|
UINT8 RegShift;
|
||||||
|
UINTN GicCpuRedistributorBase;
|
||||||
|
|
||||||
|
// Calculate enable register offset and bit position
|
||||||
|
RegOffset = (UINT32)(Source / 32);
|
||||||
|
RegShift = (UINT8)(Source % 32);
|
||||||
|
|
||||||
|
if (SourceIsSpi (Source)) {
|
||||||
|
// Write clear-enable register
|
||||||
|
MmioWrite32 (
|
||||||
|
GicDistributorBase + ARM_GIC_ICDICER + (4 * RegOffset),
|
||||||
|
1 << RegShift
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
GicCpuRedistributorBase = GicGetCpuRedistributorBase (
|
||||||
|
GicRedistributorBase
|
||||||
|
);
|
||||||
|
if (GicCpuRedistributorBase == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write clear-enable register
|
||||||
|
MmioWrite32 (
|
||||||
|
ICENABLER_ADDRESS (GicCpuRedistributorBase, RegOffset),
|
||||||
|
1 << RegShift
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
BOOLEAN
|
||||||
|
ArmGicIsInterruptEnabled (
|
||||||
|
IN UINTN GicDistributorBase,
|
||||||
|
IN UINTN GicRedistributorBase,
|
||||||
|
IN UINTN Source
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT32 RegOffset;
|
||||||
|
UINT8 RegShift;
|
||||||
|
UINTN GicCpuRedistributorBase;
|
||||||
|
UINT32 Interrupts;
|
||||||
|
|
||||||
|
// Calculate enable register offset and bit position
|
||||||
|
RegOffset = (UINT32)(Source / 32);
|
||||||
|
RegShift = (UINT8)(Source % 32);
|
||||||
|
|
||||||
|
if (SourceIsSpi (Source)) {
|
||||||
|
Interrupts = MmioRead32 (
|
||||||
|
GicDistributorBase + ARM_GIC_ICDISER + (4 * RegOffset)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
GicCpuRedistributorBase = GicGetCpuRedistributorBase (
|
||||||
|
GicRedistributorBase
|
||||||
|
);
|
||||||
|
if (GicCpuRedistributorBase == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read set-enable register
|
||||||
|
Interrupts = MmioRead32 (
|
||||||
|
ISENABLER_ADDRESS (GicCpuRedistributorBase, RegOffset)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ((Interrupts & (1 << RegShift)) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Enable interrupt source Source.
|
Enable interrupt source Source.
|
||||||
|
|
||||||
|
@ -158,39 +158,6 @@ ArmGicSetPriorityMask (
|
|||||||
IN INTN PriorityMask
|
IN INTN PriorityMask
|
||||||
);
|
);
|
||||||
|
|
||||||
VOID
|
|
||||||
EFIAPI
|
|
||||||
ArmGicSetInterruptPriority (
|
|
||||||
IN UINTN GicDistributorBase,
|
|
||||||
IN UINTN GicRedistributorBase,
|
|
||||||
IN UINTN Source,
|
|
||||||
IN UINT32 Priority
|
|
||||||
);
|
|
||||||
|
|
||||||
VOID
|
|
||||||
EFIAPI
|
|
||||||
ArmGicEnableInterrupt (
|
|
||||||
IN UINTN GicDistributorBase,
|
|
||||||
IN UINTN GicRedistributorBase,
|
|
||||||
IN UINTN Source
|
|
||||||
);
|
|
||||||
|
|
||||||
VOID
|
|
||||||
EFIAPI
|
|
||||||
ArmGicDisableInterrupt (
|
|
||||||
IN UINTN GicDistributorBase,
|
|
||||||
IN UINTN GicRedistributorBase,
|
|
||||||
IN UINTN Source
|
|
||||||
);
|
|
||||||
|
|
||||||
BOOLEAN
|
|
||||||
EFIAPI
|
|
||||||
ArmGicIsInterruptEnabled (
|
|
||||||
IN UINTN GicDistributorBase,
|
|
||||||
IN UINTN GicRedistributorBase,
|
|
||||||
IN UINTN Source
|
|
||||||
);
|
|
||||||
|
|
||||||
// GIC revision 2 specific declarations
|
// GIC revision 2 specific declarations
|
||||||
|
|
||||||
// Interrupts from 1020 to 1023 are considered as special interrupts
|
// Interrupts from 1020 to 1023 are considered as special interrupts
|
||||||
|
Loading…
x
Reference in New Issue
Block a user