Skip to content

Commit

Permalink
arm64: cpufeature: Add a feature for FIQ support
Browse files Browse the repository at this point in the history
Apple ARM SoCs (A11 and newer) have some interrupt sources hard-wired to
the FIQ line. Introduce a cpufeature that can be used to enable FIQ
unmasking and handling via alternatives.

This is currently enabled for all Apple CPUs. If/when support is
implemented for older (pre-A11) iPhone/iPad SoCs which do not need FIQs,
or if newer SoCs are released without the FIQ requirement, we can
revisit the condition.

Signed-off-by: Hector Martin <marcan@marcan.st>
  • Loading branch information
marcan committed Feb 4, 2021
1 parent d453048 commit 9a53467
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 1 deletion.
10 changes: 10 additions & 0 deletions arch/arm64/Kconfig
Expand Up @@ -1756,6 +1756,16 @@ config ARM64_DEBUG_PRIORITY_MASKING
If unsure, say N
endif

config ARM64_FIQ_SUPPORT
bool "Support for FIQ interrupts"
help
Adds support for handling FIQ interrupts as normal IRQs.
This is required on Apple platforms where some IRQ sources are
hardwired to the FIQ interrupt line.

FIQs are only enabled at runtime on platforms that require them
via the CPU feature framework.

config RELOCATABLE
bool "Build a relocatable kernel image" if EXPERT
select ARCH_HAS_RELR
Expand Down
3 changes: 2 additions & 1 deletion arch/arm64/include/asm/cpucaps.h
Expand Up @@ -66,7 +66,8 @@
#define ARM64_WORKAROUND_1508412 58
#define ARM64_HAS_LDAPR 59
#define ARM64_KVM_PROTECTED_MODE 60
#define ARM64_NEEDS_FIQ 61

#define ARM64_NCAPS 61
#define ARM64_NCAPS 62

#endif /* __ASM_CPUCAPS_H */
6 changes: 6 additions & 0 deletions arch/arm64/include/asm/cpufeature.h
Expand Up @@ -716,6 +716,12 @@ static __always_inline bool system_uses_irq_prio_masking(void)
cpus_have_const_cap(ARM64_HAS_IRQ_PRIO_MASKING);
}

static __always_inline bool system_uses_fiqs(void)
{
return IS_ENABLED(CONFIG_ARM64_FIQ_SUPPORT) &&
cpus_have_const_cap(ARM64_NEEDS_FIQ);
}

static inline bool system_supports_mte(void)
{
return IS_ENABLED(CONFIG_ARM64_MTE) &&
Expand Down
1 change: 1 addition & 0 deletions arch/arm64/include/asm/cputype.h
Expand Up @@ -59,6 +59,7 @@
#define ARM_CPU_IMP_NVIDIA 0x4E
#define ARM_CPU_IMP_FUJITSU 0x46
#define ARM_CPU_IMP_HISI 0x48
#define ARM_CPU_IMP_APPLE 0x61

#define ARM_CPU_PART_AEM_V8 0xD0F
#define ARM_CPU_PART_FOUNDATION 0xD00
Expand Down
32 changes: 32 additions & 0 deletions arch/arm64/kernel/cpufeature.c
Expand Up @@ -1237,6 +1237,29 @@ static bool has_cache_idc(const struct arm64_cpu_capabilities *entry,
return ctr & BIT(CTR_IDC_SHIFT);
}

static void cpu_sync_irq_to_fiq(struct arm64_cpu_capabilities const *cap)
{
u64 daif = read_sysreg(daif);

/*
* By this point in the boot process IRQs are likely masked and FIOs
* aren't, so we need to sync things to avoid spurious early FIQs.
*/

if (daif & PSR_I_BIT)
daif |= PSR_F_BIT;
else
daif &= ~PSR_F_BIT;

write_sysreg(daif, daif);
}

static bool needs_fiq(const struct arm64_cpu_capabilities *entry, int __unused)
{
/* All supported Apple cores need this */
return read_cpuid_implementor() == ARM_CPU_IMP_APPLE;
}

static void cpu_emulate_effective_ctr(const struct arm64_cpu_capabilities *__unused)
{
/*
Expand Down Expand Up @@ -2154,6 +2177,15 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
.matches = has_cpuid_feature,
.min_field_value = 1,
},
#ifdef CONFIG_ARM64_FIQ_SUPPORT
{
.desc = "FIQs",
.capability = ARM64_NEEDS_FIQ,
.type = ARM64_CPUCAP_BOOT_CPU_FEATURE,
.matches = needs_fiq,
.cpu_enable = cpu_sync_irq_to_fiq,
},
#endif
{},
};

Expand Down

0 comments on commit 9a53467

Please sign in to comment.