Resguardo inicial

This commit is contained in:
lastdragon
2026-09-06 12:53:21 -06:00
parent 662efe3c2a
commit ad2088d178
94853 changed files with 43200404 additions and 0 deletions
+9
View File
@@ -0,0 +1,9 @@
# SPDX-License-Identifier: GPL-2.0
generic-y += early_ioremap.h
generic-y += extable.h
generic-y += flat.h
generic-y += parport.h
generic-y += ring_buffer.h
generated-y += mach-types.h
generated-y += unistd-nr.h
@@ -0,0 +1,261 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* arch/arm/include/asm/arch_gicv3.h
*
* Copyright (C) 2015 ARM Ltd.
*/
#ifndef __ASM_ARCH_GICV3_H
#define __ASM_ARCH_GICV3_H
#ifndef __ASSEMBLER__
#include <linux/io.h>
#include <linux/io-64-nonatomic-lo-hi.h>
#include <asm/barrier.h>
#include <asm/cacheflush.h>
#include <asm/cp15.h>
#define ICC_EOIR1 __ACCESS_CP15(c12, 0, c12, 1)
#define ICC_DIR __ACCESS_CP15(c12, 0, c11, 1)
#define ICC_IAR1 __ACCESS_CP15(c12, 0, c12, 0)
#define ICC_SGI1R __ACCESS_CP15_64(0, c12)
#define ICC_PMR __ACCESS_CP15(c4, 0, c6, 0)
#define ICC_CTLR __ACCESS_CP15(c12, 0, c12, 4)
#define ICC_SRE __ACCESS_CP15(c12, 0, c12, 5)
#define ICC_IGRPEN1 __ACCESS_CP15(c12, 0, c12, 7)
#define ICC_BPR1 __ACCESS_CP15(c12, 0, c12, 3)
#define ICC_RPR __ACCESS_CP15(c12, 0, c11, 3)
#define __ICC_AP0Rx(x) __ACCESS_CP15(c12, 0, c8, 4 | x)
#define ICC_AP0R0 __ICC_AP0Rx(0)
#define ICC_AP0R1 __ICC_AP0Rx(1)
#define ICC_AP0R2 __ICC_AP0Rx(2)
#define ICC_AP0R3 __ICC_AP0Rx(3)
#define __ICC_AP1Rx(x) __ACCESS_CP15(c12, 0, c9, x)
#define ICC_AP1R0 __ICC_AP1Rx(0)
#define ICC_AP1R1 __ICC_AP1Rx(1)
#define ICC_AP1R2 __ICC_AP1Rx(2)
#define ICC_AP1R3 __ICC_AP1Rx(3)
#define CPUIF_MAP(a32, a64) \
static inline void write_ ## a64(u32 val) \
{ \
write_sysreg(val, a32); \
} \
static inline u32 read_ ## a64(void) \
{ \
return read_sysreg(a32); \
} \
CPUIF_MAP(ICC_EOIR1, ICC_EOIR1_EL1)
CPUIF_MAP(ICC_PMR, ICC_PMR_EL1)
CPUIF_MAP(ICC_AP0R0, ICC_AP0R0_EL1)
CPUIF_MAP(ICC_AP0R1, ICC_AP0R1_EL1)
CPUIF_MAP(ICC_AP0R2, ICC_AP0R2_EL1)
CPUIF_MAP(ICC_AP0R3, ICC_AP0R3_EL1)
CPUIF_MAP(ICC_AP1R0, ICC_AP1R0_EL1)
CPUIF_MAP(ICC_AP1R1, ICC_AP1R1_EL1)
CPUIF_MAP(ICC_AP1R2, ICC_AP1R2_EL1)
CPUIF_MAP(ICC_AP1R3, ICC_AP1R3_EL1)
#define read_gicreg(r) read_##r()
#define write_gicreg(v, r) write_##r(v)
/* Low-level accessors */
static inline void gic_write_dir(u32 val)
{
write_sysreg(val, ICC_DIR);
isb();
}
static inline u32 gic_read_iar(void)
{
u32 irqstat = read_sysreg(ICC_IAR1);
dsb(sy);
return irqstat;
}
static inline void gic_write_ctlr(u32 val)
{
write_sysreg(val, ICC_CTLR);
isb();
}
static inline u32 gic_read_ctlr(void)
{
return read_sysreg(ICC_CTLR);
}
static inline void gic_write_grpen1(u32 val)
{
write_sysreg(val, ICC_IGRPEN1);
isb();
}
static inline void gic_write_sgi1r(u64 val)
{
write_sysreg(val, ICC_SGI1R);
}
static inline u32 gic_read_sre(void)
{
return read_sysreg(ICC_SRE);
}
static inline void gic_write_sre(u32 val)
{
write_sysreg(val, ICC_SRE);
isb();
}
static inline void gic_write_bpr1(u32 val)
{
write_sysreg(val, ICC_BPR1);
}
static inline u32 gic_read_pmr(void)
{
return read_sysreg(ICC_PMR);
}
static inline void gic_write_pmr(u32 val)
{
write_sysreg(val, ICC_PMR);
}
static inline u32 gic_read_rpr(void)
{
return read_sysreg(ICC_RPR);
}
/*
* Even in 32bit systems that use LPAE, there is no guarantee that the I/O
* interface provides true 64bit atomic accesses, so using strd/ldrd doesn't
* make much sense.
* Moreover, 64bit I/O emulation is extremely difficult to implement on
* AArch32, since the syndrome register doesn't provide any information for
* them.
* Consequently, the following IO helpers use 32bit accesses.
*/
static inline void __gic_writeq_nonatomic(u64 val, volatile void __iomem *addr)
{
writel_relaxed((u32)val, addr);
writel_relaxed((u32)(val >> 32), addr + 4);
}
static inline u64 __gic_readq_nonatomic(const volatile void __iomem *addr)
{
u64 val;
val = readl_relaxed(addr);
val |= (u64)readl_relaxed(addr + 4) << 32;
return val;
}
#define gic_flush_dcache_to_poc(a,l) __cpuc_flush_dcache_area((a), (l))
/*
* GICD_IROUTERn, contain the affinity values associated to each interrupt.
* The upper-word (aff3) will always be 0, so there is no need for a lock.
*/
#define gic_write_irouter(v, c) __gic_writeq_nonatomic(v, c)
/*
* GICR_TYPER is an ID register and doesn't need atomicity.
*/
#define gic_read_typer(c) __gic_readq_nonatomic(c)
/*
* GITS_BASER - hi and lo bits may be accessed independently.
*/
#define gits_read_baser(c) __gic_readq_nonatomic(c)
#define gits_write_baser(v, c) __gic_writeq_nonatomic(v, c)
/*
* GICR_PENDBASER and GICR_PROPBASE are changed with LPIs disabled, so they
* won't be being used during any updates and can be changed non-atomically
*/
#define gicr_read_propbaser(c) __gic_readq_nonatomic(c)
#define gicr_write_propbaser(v, c) __gic_writeq_nonatomic(v, c)
#define gicr_read_pendbaser(c) __gic_readq_nonatomic(c)
#define gicr_write_pendbaser(v, c) __gic_writeq_nonatomic(v, c)
/*
* GICR_xLPIR - only the lower bits are significant
*/
#define gic_read_lpir(c) readl_relaxed(c)
#define gic_write_lpir(v, c) writel_relaxed(lower_32_bits(v), c)
/*
* GITS_TYPER is an ID register and doesn't need atomicity.
*/
#define gits_read_typer(c) __gic_readq_nonatomic(c)
/*
* GITS_CBASER - hi and lo bits may be accessed independently.
*/
#define gits_read_cbaser(c) __gic_readq_nonatomic(c)
#define gits_write_cbaser(v, c) __gic_writeq_nonatomic(v, c)
/*
* GITS_CWRITER - hi and lo bits may be accessed independently.
*/
#define gits_write_cwriter(v, c) __gic_writeq_nonatomic(v, c)
/*
* GICR_VPROPBASER - hi and lo bits may be accessed independently.
*/
#define gicr_read_vpropbaser(c) __gic_readq_nonatomic(c)
#define gicr_write_vpropbaser(v, c) __gic_writeq_nonatomic(v, c)
/*
* GICR_VPENDBASER - the Valid bit must be cleared before changing
* anything else.
*/
static inline void gicr_write_vpendbaser(u64 val, void __iomem *addr)
{
u32 tmp;
tmp = readl_relaxed(addr + 4);
if (tmp & (GICR_VPENDBASER_Valid >> 32)) {
tmp &= ~(GICR_VPENDBASER_Valid >> 32);
writel_relaxed(tmp, addr + 4);
}
/*
* Use the fact that __gic_writeq_nonatomic writes the second
* half of the 64bit quantity after the first.
*/
__gic_writeq_nonatomic(val, addr);
}
#define gicr_read_vpendbaser(c) __gic_readq_nonatomic(c)
static inline bool gic_prio_masking_enabled(void)
{
return false;
}
static inline void gic_pmr_mask_irqs(void)
{
/* Should not get called. */
WARN_ON_ONCE(true);
}
static inline void gic_arch_enable_irqs(void)
{
/* Should not get called. */
WARN_ON_ONCE(true);
}
static inline bool gic_has_relaxed_pmr_sync(void)
{
return false;
}
#endif /* !__ASSEMBLER__ */
#endif /* !__ASM_ARCH_GICV3_H */
@@ -0,0 +1,146 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASMARM_ARCH_TIMER_H
#define __ASMARM_ARCH_TIMER_H
#include <asm/barrier.h>
#include <asm/errno.h>
#include <asm/hwcap.h>
#include <linux/clocksource.h>
#include <linux/init.h>
#include <linux/io-64-nonatomic-lo-hi.h>
#include <linux/types.h>
#include <clocksource/arm_arch_timer.h>
#ifdef CONFIG_ARM_ARCH_TIMER
/* 32bit ARM doesn't know anything about timer errata... */
#define has_erratum_handler(h) (false)
#define erratum_handler(h) (arch_timer_##h)
int arch_timer_arch_init(void);
/*
* These register accessors are marked inline so the compiler can
* nicely work out which register we want, and chuck away the rest of
* the code. At least it does so with a recent GCC (4.6.3).
*/
static __always_inline
void arch_timer_reg_write_cp15(int access, enum arch_timer_reg reg, u64 val)
{
if (access == ARCH_TIMER_PHYS_ACCESS) {
switch (reg) {
case ARCH_TIMER_REG_CTRL:
asm volatile("mcr p15, 0, %0, c14, c2, 1" : : "r" ((u32)val));
isb();
break;
case ARCH_TIMER_REG_CVAL:
asm volatile("mcrr p15, 2, %Q0, %R0, c14" : : "r" (val));
break;
default:
BUILD_BUG();
}
} else if (access == ARCH_TIMER_VIRT_ACCESS) {
switch (reg) {
case ARCH_TIMER_REG_CTRL:
asm volatile("mcr p15, 0, %0, c14, c3, 1" : : "r" ((u32)val));
isb();
break;
case ARCH_TIMER_REG_CVAL:
asm volatile("mcrr p15, 3, %Q0, %R0, c14" : : "r" (val));
break;
default:
BUILD_BUG();
}
} else {
BUILD_BUG();
}
}
static __always_inline
u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg)
{
u32 val = 0;
if (access == ARCH_TIMER_PHYS_ACCESS) {
switch (reg) {
case ARCH_TIMER_REG_CTRL:
asm volatile("mrc p15, 0, %0, c14, c2, 1" : "=r" (val));
break;
default:
BUILD_BUG();
}
} else if (access == ARCH_TIMER_VIRT_ACCESS) {
switch (reg) {
case ARCH_TIMER_REG_CTRL:
asm volatile("mrc p15, 0, %0, c14, c3, 1" : "=r" (val));
break;
default:
BUILD_BUG();
}
} else {
BUILD_BUG();
}
return val;
}
static inline u32 arch_timer_get_cntfrq(void)
{
u32 val;
asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (val));
return val;
}
static inline u64 __arch_counter_get_cntpct(void)
{
u64 cval;
isb();
asm volatile("mrrc p15, 0, %Q0, %R0, c14" : "=r" (cval));
return cval;
}
static inline u64 __arch_counter_get_cntpct_stable(void)
{
return __arch_counter_get_cntpct();
}
static inline u64 __arch_counter_get_cntvct(void)
{
u64 cval;
isb();
asm volatile("mrrc p15, 1, %Q0, %R0, c14" : "=r" (cval));
return cval;
}
static inline u64 __arch_counter_get_cntvct_stable(void)
{
return __arch_counter_get_cntvct();
}
static inline u32 arch_timer_get_cntkctl(void)
{
u32 cntkctl;
asm volatile("mrc p15, 0, %0, c14, c1, 0" : "=r" (cntkctl));
return cntkctl;
}
static inline void arch_timer_set_cntkctl(u32 cntkctl)
{
asm volatile("mcr p15, 0, %0, c14, c1, 0" : : "r" (cntkctl));
isb();
}
static inline void arch_timer_set_evtstrm_feature(void)
{
elf_hwcap |= HWCAP_EVTSTRM;
}
static inline bool arch_timer_have_evtstrm_feature(void)
{
return elf_hwcap & HWCAP_EVTSTRM;
}
#endif
#endif
@@ -0,0 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_ARCHRANDOM_H
#define _ASM_ARCHRANDOM_H
static inline bool __init smccc_probe_trng(void)
{
return false;
}
#include <asm-generic/archrandom.h>
#endif /* _ASM_ARCHRANDOM_H */
@@ -0,0 +1,31 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* arch/arm/include/asm/arm-cci.h
*
* Copyright (C) 2015 ARM Ltd.
*/
#ifndef __ASM_ARM_CCI_H
#define __ASM_ARM_CCI_H
#ifdef CONFIG_MCPM
#include <asm/mcpm.h>
/*
* We don't have a reliable way of detecting whether,
* if we have access to secure-only registers, unless
* mcpm is registered.
*/
static inline bool platform_has_secure_cci_access(void)
{
return mcpm_is_available();
}
#else
static inline bool platform_has_secure_cci_access(void)
{
return false;
}
#endif
#endif
@@ -0,0 +1,287 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2012 ARM Ltd.
*/
#ifndef __ASM_PMUV3_H
#define __ASM_PMUV3_H
#include <asm/cp15.h>
#include <asm/cputype.h>
#define PMCCNTR __ACCESS_CP15_64(0, c9)
#define PMCR __ACCESS_CP15(c9, 0, c12, 0)
#define PMCNTENSET __ACCESS_CP15(c9, 0, c12, 1)
#define PMCNTENCLR __ACCESS_CP15(c9, 0, c12, 2)
#define PMOVSR __ACCESS_CP15(c9, 0, c12, 3)
#define PMSELR __ACCESS_CP15(c9, 0, c12, 5)
#define PMCEID0 __ACCESS_CP15(c9, 0, c12, 6)
#define PMCEID1 __ACCESS_CP15(c9, 0, c12, 7)
#define PMXEVTYPER __ACCESS_CP15(c9, 0, c13, 1)
#define PMXEVCNTR __ACCESS_CP15(c9, 0, c13, 2)
#define PMUSERENR __ACCESS_CP15(c9, 0, c14, 0)
#define PMINTENSET __ACCESS_CP15(c9, 0, c14, 1)
#define PMINTENCLR __ACCESS_CP15(c9, 0, c14, 2)
#define PMCEID2 __ACCESS_CP15(c9, 0, c14, 4)
#define PMCEID3 __ACCESS_CP15(c9, 0, c14, 5)
#define PMMIR __ACCESS_CP15(c9, 0, c14, 6)
#define PMCCFILTR __ACCESS_CP15(c14, 0, c15, 7)
#define PMEVCNTR0 __ACCESS_CP15(c14, 0, c8, 0)
#define PMEVCNTR1 __ACCESS_CP15(c14, 0, c8, 1)
#define PMEVCNTR2 __ACCESS_CP15(c14, 0, c8, 2)
#define PMEVCNTR3 __ACCESS_CP15(c14, 0, c8, 3)
#define PMEVCNTR4 __ACCESS_CP15(c14, 0, c8, 4)
#define PMEVCNTR5 __ACCESS_CP15(c14, 0, c8, 5)
#define PMEVCNTR6 __ACCESS_CP15(c14, 0, c8, 6)
#define PMEVCNTR7 __ACCESS_CP15(c14, 0, c8, 7)
#define PMEVCNTR8 __ACCESS_CP15(c14, 0, c9, 0)
#define PMEVCNTR9 __ACCESS_CP15(c14, 0, c9, 1)
#define PMEVCNTR10 __ACCESS_CP15(c14, 0, c9, 2)
#define PMEVCNTR11 __ACCESS_CP15(c14, 0, c9, 3)
#define PMEVCNTR12 __ACCESS_CP15(c14, 0, c9, 4)
#define PMEVCNTR13 __ACCESS_CP15(c14, 0, c9, 5)
#define PMEVCNTR14 __ACCESS_CP15(c14, 0, c9, 6)
#define PMEVCNTR15 __ACCESS_CP15(c14, 0, c9, 7)
#define PMEVCNTR16 __ACCESS_CP15(c14, 0, c10, 0)
#define PMEVCNTR17 __ACCESS_CP15(c14, 0, c10, 1)
#define PMEVCNTR18 __ACCESS_CP15(c14, 0, c10, 2)
#define PMEVCNTR19 __ACCESS_CP15(c14, 0, c10, 3)
#define PMEVCNTR20 __ACCESS_CP15(c14, 0, c10, 4)
#define PMEVCNTR21 __ACCESS_CP15(c14, 0, c10, 5)
#define PMEVCNTR22 __ACCESS_CP15(c14, 0, c10, 6)
#define PMEVCNTR23 __ACCESS_CP15(c14, 0, c10, 7)
#define PMEVCNTR24 __ACCESS_CP15(c14, 0, c11, 0)
#define PMEVCNTR25 __ACCESS_CP15(c14, 0, c11, 1)
#define PMEVCNTR26 __ACCESS_CP15(c14, 0, c11, 2)
#define PMEVCNTR27 __ACCESS_CP15(c14, 0, c11, 3)
#define PMEVCNTR28 __ACCESS_CP15(c14, 0, c11, 4)
#define PMEVCNTR29 __ACCESS_CP15(c14, 0, c11, 5)
#define PMEVCNTR30 __ACCESS_CP15(c14, 0, c11, 6)
#define PMEVTYPER0 __ACCESS_CP15(c14, 0, c12, 0)
#define PMEVTYPER1 __ACCESS_CP15(c14, 0, c12, 1)
#define PMEVTYPER2 __ACCESS_CP15(c14, 0, c12, 2)
#define PMEVTYPER3 __ACCESS_CP15(c14, 0, c12, 3)
#define PMEVTYPER4 __ACCESS_CP15(c14, 0, c12, 4)
#define PMEVTYPER5 __ACCESS_CP15(c14, 0, c12, 5)
#define PMEVTYPER6 __ACCESS_CP15(c14, 0, c12, 6)
#define PMEVTYPER7 __ACCESS_CP15(c14, 0, c12, 7)
#define PMEVTYPER8 __ACCESS_CP15(c14, 0, c13, 0)
#define PMEVTYPER9 __ACCESS_CP15(c14, 0, c13, 1)
#define PMEVTYPER10 __ACCESS_CP15(c14, 0, c13, 2)
#define PMEVTYPER11 __ACCESS_CP15(c14, 0, c13, 3)
#define PMEVTYPER12 __ACCESS_CP15(c14, 0, c13, 4)
#define PMEVTYPER13 __ACCESS_CP15(c14, 0, c13, 5)
#define PMEVTYPER14 __ACCESS_CP15(c14, 0, c13, 6)
#define PMEVTYPER15 __ACCESS_CP15(c14, 0, c13, 7)
#define PMEVTYPER16 __ACCESS_CP15(c14, 0, c14, 0)
#define PMEVTYPER17 __ACCESS_CP15(c14, 0, c14, 1)
#define PMEVTYPER18 __ACCESS_CP15(c14, 0, c14, 2)
#define PMEVTYPER19 __ACCESS_CP15(c14, 0, c14, 3)
#define PMEVTYPER20 __ACCESS_CP15(c14, 0, c14, 4)
#define PMEVTYPER21 __ACCESS_CP15(c14, 0, c14, 5)
#define PMEVTYPER22 __ACCESS_CP15(c14, 0, c14, 6)
#define PMEVTYPER23 __ACCESS_CP15(c14, 0, c14, 7)
#define PMEVTYPER24 __ACCESS_CP15(c14, 0, c15, 0)
#define PMEVTYPER25 __ACCESS_CP15(c14, 0, c15, 1)
#define PMEVTYPER26 __ACCESS_CP15(c14, 0, c15, 2)
#define PMEVTYPER27 __ACCESS_CP15(c14, 0, c15, 3)
#define PMEVTYPER28 __ACCESS_CP15(c14, 0, c15, 4)
#define PMEVTYPER29 __ACCESS_CP15(c14, 0, c15, 5)
#define PMEVTYPER30 __ACCESS_CP15(c14, 0, c15, 6)
#define RETURN_READ_PMEVCNTRN(n) \
return read_sysreg(PMEVCNTR##n)
static inline unsigned long read_pmevcntrn(int n)
{
PMEVN_SWITCH(n, RETURN_READ_PMEVCNTRN);
return 0;
}
#define WRITE_PMEVCNTRN(n) \
write_sysreg(val, PMEVCNTR##n)
static inline void write_pmevcntrn(int n, unsigned long val)
{
PMEVN_SWITCH(n, WRITE_PMEVCNTRN);
}
#define WRITE_PMEVTYPERN(n) \
write_sysreg(val, PMEVTYPER##n)
static inline void write_pmevtypern(int n, unsigned long val)
{
PMEVN_SWITCH(n, WRITE_PMEVTYPERN);
}
static inline unsigned long read_pmmir(void)
{
return read_sysreg(PMMIR);
}
static inline u32 read_pmuver(void)
{
/* PMUVers is not a signed field */
u32 dfr0 = read_cpuid_ext(CPUID_EXT_DFR0);
return (dfr0 >> 24) & 0xf;
}
static inline bool pmuv3_has_icntr(void)
{
/* FEAT_PMUv3_ICNTR not accessible for 32-bit */
return false;
}
static inline void write_pmcr(u32 val)
{
write_sysreg(val, PMCR);
}
static inline u32 read_pmcr(void)
{
return read_sysreg(PMCR);
}
static inline void write_pmselr(u32 val)
{
write_sysreg(val, PMSELR);
}
static inline void write_pmccntr(u64 val)
{
write_sysreg(val, PMCCNTR);
}
static inline u64 read_pmccntr(void)
{
return read_sysreg(PMCCNTR);
}
static inline void write_pmicntr(u64 val) {}
static inline u64 read_pmicntr(void)
{
return 0;
}
static inline void write_pmcntenset(u32 val)
{
write_sysreg(val, PMCNTENSET);
}
static inline void write_pmcntenclr(u32 val)
{
write_sysreg(val, PMCNTENCLR);
}
static inline void write_pmintenset(u32 val)
{
write_sysreg(val, PMINTENSET);
}
static inline void write_pmintenclr(u32 val)
{
write_sysreg(val, PMINTENCLR);
}
static inline void write_pmccfiltr(u32 val)
{
write_sysreg(val, PMCCFILTR);
}
static inline void write_pmicfiltr(u64 val) {}
static inline u64 read_pmicfiltr(void)
{
return 0;
}
static inline void write_pmovsclr(u32 val)
{
write_sysreg(val, PMOVSR);
}
static inline u32 read_pmovsclr(void)
{
return read_sysreg(PMOVSR);
}
static inline void write_pmuserenr(u32 val)
{
write_sysreg(val, PMUSERENR);
}
static inline void write_pmuacr(u64 val) {}
static inline void kvm_set_pmu_events(u32 set, struct perf_event_attr *attr) {}
static inline void kvm_clr_pmu_events(u32 clr) {}
static inline bool kvm_pmu_counter_deferred(struct perf_event_attr *attr)
{
return false;
}
static inline bool kvm_set_pmuserenr(u64 val)
{
return false;
}
static inline void kvm_vcpu_pmu_resync_el0(void) {}
/* PMU Version in DFR Register */
#define ARMV8_PMU_DFR_VER_NI 0
#define ARMV8_PMU_DFR_VER_V3P1 0x4
#define ARMV8_PMU_DFR_VER_V3P4 0x5
#define ARMV8_PMU_DFR_VER_V3P5 0x6
#define ARMV8_PMU_DFR_VER_V3P9 0x9
#define ARMV8_PMU_DFR_VER_IMP_DEF 0xF
static inline bool pmuv3_implemented(int pmuver)
{
/*
* PMUVer follows the standard ID scheme for an unsigned field with the
* exception of 0xF (IMP_DEF) which is treated specially and implies
* FEAT_PMUv3 is not implemented.
*
* See DDI0487L.a D24.1.3.2 for more details.
*/
return !(pmuver == ARMV8_PMU_DFR_VER_IMP_DEF ||
pmuver == ARMV8_PMU_DFR_VER_NI);
}
static inline bool is_pmuv3p4(int pmuver)
{
return pmuver >= ARMV8_PMU_DFR_VER_V3P4;
}
static inline bool is_pmuv3p5(int pmuver)
{
return pmuver >= ARMV8_PMU_DFR_VER_V3P5;
}
static inline bool is_pmuv3p9(int pmuver)
{
return pmuver >= ARMV8_PMU_DFR_VER_V3P9;
}
static inline u64 read_pmceid0(void)
{
u64 val = read_sysreg(PMCEID0);
if (read_pmuver() >= ARMV8_PMU_DFR_VER_V3P1)
val |= (u64)read_sysreg(PMCEID2) << 32;
return val;
}
static inline u64 read_pmceid1(void)
{
u64 val = read_sysreg(PMCEID1);
if (read_pmuver() >= ARMV8_PMU_DFR_VER_V3P1)
val |= (u64)read_sysreg(PMCEID3) << 32;
return val;
}
#endif
@@ -0,0 +1 @@
#include <generated/asm-offsets.h>
@@ -0,0 +1,795 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* arch/arm/include/asm/assembler.h
*
* Copyright (C) 1996-2000 Russell King
*
* This file contains arm architecture specific defines
* for the different processors.
*
* Do not include any C declarations in this file - it is included by
* assembler source.
*/
#ifndef __ASM_ASSEMBLER_H__
#define __ASM_ASSEMBLER_H__
#ifndef __ASSEMBLY__
#error "Only include this from assembly code"
#endif
#include <asm/ptrace.h>
#include <asm/opcodes-virt.h>
#include <asm/asm-offsets.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/thread_info.h>
#include <asm/uaccess-asm.h>
#define IOMEM(x) (x)
/*
* Endian independent macros for shifting bytes within registers.
*/
#ifndef __ARMEB__
#define lspull lsr
#define lspush lsl
#define get_byte_0 lsl #0
#define get_byte_1 lsr #8
#define get_byte_2 lsr #16
#define get_byte_3 lsr #24
#define put_byte_0 lsl #0
#define put_byte_1 lsl #8
#define put_byte_2 lsl #16
#define put_byte_3 lsl #24
#else
#define lspull lsl
#define lspush lsr
#define get_byte_0 lsr #24
#define get_byte_1 lsr #16
#define get_byte_2 lsr #8
#define get_byte_3 lsl #0
#define put_byte_0 lsl #24
#define put_byte_1 lsl #16
#define put_byte_2 lsl #8
#define put_byte_3 lsl #0
#endif
/* Select code for any configuration running in BE8 mode */
#ifdef CONFIG_CPU_ENDIAN_BE8
#define ARM_BE8(code...) code
#else
#define ARM_BE8(code...)
#endif
/*
* Data preload for architectures that support it
*/
#if __LINUX_ARM_ARCH__ >= 5
#define PLD(code...) code
#else
#define PLD(code...)
#endif
/*
* This can be used to enable code to cacheline align the destination
* pointer when bulk writing to memory. Experiments on StrongARM and
* XScale didn't show this a worthwhile thing to do when the cache is not
* set to write-allocate (this would need further testing on XScale when WA
* is used).
*
* On Feroceon there is much to gain however, regardless of cache mode.
*/
#ifdef CONFIG_CPU_FEROCEON
#define CALGN(code...) code
#else
#define CALGN(code...)
#endif
#define IMM12_MASK 0xfff
/* the frame pointer used for stack unwinding */
ARM( fpreg .req r11 )
THUMB( fpreg .req r7 )
/*
* Enable and disable interrupts
*/
#if __LINUX_ARM_ARCH__ >= 6
.macro disable_irq_notrace
cpsid i
.endm
.macro enable_irq_notrace
cpsie i
.endm
#else
.macro disable_irq_notrace
msr cpsr_c, #PSR_I_BIT | SVC_MODE
.endm
.macro enable_irq_notrace
msr cpsr_c, #SVC_MODE
.endm
#endif
#if __LINUX_ARM_ARCH__ < 7
.macro dsb, args
mcr p15, 0, r0, c7, c10, 4
.endm
.macro isb, args
mcr p15, 0, r0, c7, c5, 4
.endm
#endif
.macro asm_trace_hardirqs_off, save=1
#if defined(CONFIG_TRACE_IRQFLAGS)
.if \save
stmdb sp!, {r0-r3, ip, lr}
.endif
bl trace_hardirqs_off
.if \save
ldmia sp!, {r0-r3, ip, lr}
.endif
#endif
.endm
.macro asm_trace_hardirqs_on, cond=al, save=1
#if defined(CONFIG_TRACE_IRQFLAGS)
/*
* actually the registers should be pushed and pop'd conditionally, but
* after bl the flags are certainly clobbered
*/
.if \save
stmdb sp!, {r0-r3, ip, lr}
.endif
bl\cond trace_hardirqs_on
.if \save
ldmia sp!, {r0-r3, ip, lr}
.endif
#endif
.endm
.macro disable_irq, save=1
disable_irq_notrace
asm_trace_hardirqs_off \save
.endm
.macro enable_irq
asm_trace_hardirqs_on
enable_irq_notrace
.endm
/*
* Save the current IRQ state and disable IRQs. Note that this macro
* assumes FIQs are enabled, and that the processor is in SVC mode.
*/
.macro save_and_disable_irqs, oldcpsr
#ifdef CONFIG_CPU_V7M
mrs \oldcpsr, primask
#else
mrs \oldcpsr, cpsr
#endif
disable_irq
.endm
.macro save_and_disable_irqs_notrace, oldcpsr
#ifdef CONFIG_CPU_V7M
mrs \oldcpsr, primask
#else
mrs \oldcpsr, cpsr
#endif
disable_irq_notrace
.endm
/*
* Restore interrupt state previously stored in a register. We don't
* guarantee that this will preserve the flags.
*/
.macro restore_irqs_notrace, oldcpsr
#ifdef CONFIG_CPU_V7M
msr primask, \oldcpsr
#else
msr cpsr_c, \oldcpsr
#endif
.endm
.macro restore_irqs, oldcpsr
tst \oldcpsr, #PSR_I_BIT
asm_trace_hardirqs_on cond=eq
restore_irqs_notrace \oldcpsr
.endm
/*
* Assembly version of "adr rd, BSYM(sym)". This should only be used to
* reference local symbols in the same assembly file which are to be
* resolved by the assembler. Other usage is undefined.
*/
.irp c,,eq,ne,cs,cc,mi,pl,vs,vc,hi,ls,ge,lt,gt,le,hs,lo
.macro badr\c, rd, sym
#ifdef CONFIG_THUMB2_KERNEL
adr\c \rd, \sym + 1
#else
adr\c \rd, \sym
#endif
.endm
.endr
/*
* Get current thread_info.
*/
.macro get_thread_info, rd
/* thread_info is the first member of struct task_struct */
get_current \rd
.endm
/*
* Increment/decrement the preempt count.
*/
#ifdef CONFIG_PREEMPT_COUNT
.macro inc_preempt_count, ti, tmp
ldr \tmp, [\ti, #TI_PREEMPT] @ get preempt count
add \tmp, \tmp, #1 @ increment it
str \tmp, [\ti, #TI_PREEMPT]
.endm
.macro dec_preempt_count, ti, tmp
ldr \tmp, [\ti, #TI_PREEMPT] @ get preempt count
sub \tmp, \tmp, #1 @ decrement it
str \tmp, [\ti, #TI_PREEMPT]
.endm
#else
.macro inc_preempt_count, ti, tmp
.endm
.macro dec_preempt_count, ti, tmp
.endm
#endif
#define USERL(l, x...) \
9999: x; \
.pushsection __ex_table,"a"; \
.align 3; \
.long 9999b,l; \
.popsection
#define USER(x...) USERL(9001f, x)
#ifdef CONFIG_SMP
#define ALT_SMP(instr...) \
9998: instr
/*
* Note: if you get assembler errors from ALT_UP() when building with
* CONFIG_THUMB2_KERNEL, you almost certainly need to use
* ALT_SMP( W(instr) ... )
*/
#define ALT_UP(instr...) \
.pushsection ".alt.smp.init", "a" ;\
.align 2 ;\
.long 9998b - . ;\
9997: instr ;\
.if . - 9997b == 2 ;\
nop ;\
.endif ;\
.if . - 9997b != 4 ;\
.error "ALT_UP() content must assemble to exactly 4 bytes";\
.endif ;\
.popsection
#define ALT_UP_B(label) \
.pushsection ".alt.smp.init", "a" ;\
.align 2 ;\
.long 9998b - . ;\
W(b) . + (label - 9998b) ;\
.popsection
#else
#define ALT_SMP(instr...)
#define ALT_UP(instr...) instr
#define ALT_UP_B(label) b label
#endif
/*
* this_cpu_offset - load the per-CPU offset of this CPU into
* register 'rd'
*/
.macro this_cpu_offset, rd:req
#ifdef CONFIG_SMP
ALT_SMP(mrc p15, 0, \rd, c13, c0, 4)
#ifdef CONFIG_CPU_V6
ALT_UP_B(.L1_\@)
.L0_\@:
.subsection 1
.L1_\@: ldr_va \rd, __per_cpu_offset
b .L0_\@
.previous
#endif
#else
mov \rd, #0
#endif
.endm
/*
* set_current - store the task pointer of this CPU's current task
*/
.macro set_current, rn:req, tmp:req
#if defined(CONFIG_CURRENT_POINTER_IN_TPIDRURO) || defined(CONFIG_SMP)
9998: mcr p15, 0, \rn, c13, c0, 3 @ set TPIDRURO register
#ifdef CONFIG_CPU_V6
ALT_UP_B(.L0_\@)
.subsection 1
.L0_\@: str_va \rn, __current, \tmp
b .L1_\@
.previous
.L1_\@:
#endif
#else
str_va \rn, __current, \tmp
#endif
.endm
/*
* get_current - load the task pointer of this CPU's current task
*/
.macro get_current, rd:req
#if defined(CONFIG_CURRENT_POINTER_IN_TPIDRURO) || defined(CONFIG_SMP)
9998: mrc p15, 0, \rd, c13, c0, 3 @ get TPIDRURO register
#ifdef CONFIG_CPU_V6
ALT_UP_B(.L0_\@)
.subsection 1
.L0_\@: ldr_va \rd, __current
b .L1_\@
.previous
.L1_\@:
#endif
#else
ldr_va \rd, __current
#endif
.endm
/*
* reload_current - reload the task pointer of this CPU's current task
* into the TLS register
*/
.macro reload_current, t1:req, t2:req
#if defined(CONFIG_CURRENT_POINTER_IN_TPIDRURO) || defined(CONFIG_SMP)
#ifdef CONFIG_CPU_V6
ALT_SMP(nop)
ALT_UP_B(.L0_\@)
#endif
ldr_this_cpu \t1, __entry_task, \t1, \t2
mcr p15, 0, \t1, c13, c0, 3 @ store in TPIDRURO
.L0_\@:
#endif
.endm
/*
* Instruction barrier
*/
.macro instr_sync
#if __LINUX_ARM_ARCH__ >= 7
isb
#elif __LINUX_ARM_ARCH__ == 6
mcr p15, 0, r0, c7, c5, 4
#endif
.endm
/*
* SMP data memory barrier
*/
.macro smp_dmb mode
#ifdef CONFIG_SMP
#if __LINUX_ARM_ARCH__ >= 7
.ifeqs "\mode","arm"
ALT_SMP(dmb ish)
.else
ALT_SMP(W(dmb) ish)
.endif
#elif __LINUX_ARM_ARCH__ == 6
ALT_SMP(mcr p15, 0, r0, c7, c10, 5) @ dmb
#else
#error Incompatible SMP platform
#endif
.ifeqs "\mode","arm"
ALT_UP(nop)
.else
ALT_UP(W(nop))
.endif
#endif
.endm
/*
* Raw SMP data memory barrier
*/
.macro __smp_dmb mode
#if __LINUX_ARM_ARCH__ >= 7
.ifeqs "\mode","arm"
dmb ish
.else
W(dmb) ish
.endif
#elif __LINUX_ARM_ARCH__ == 6
mcr p15, 0, r0, c7, c10, 5 @ dmb
#else
.error "Incompatible SMP platform"
#endif
.endm
#if defined(CONFIG_CPU_V7M)
/*
* setmode is used to assert to be in svc mode during boot. For v7-M
* this is done in __v7m_setup, so setmode can be empty here.
*/
.macro setmode, mode, reg
.endm
#elif defined(CONFIG_THUMB2_KERNEL)
.macro setmode, mode, reg
mov \reg, #\mode
msr cpsr_c, \reg
.endm
#else
.macro setmode, mode, reg
msr cpsr_c, #\mode
.endm
#endif
/*
* Helper macro to enter SVC mode cleanly and mask interrupts. reg is
* a scratch register for the macro to overwrite.
*
* This macro is intended for forcing the CPU into SVC mode at boot time.
* you cannot return to the original mode.
*/
.macro safe_svcmode_maskall reg:req
#if __LINUX_ARM_ARCH__ >= 6 && !defined(CONFIG_CPU_V7M)
mrs \reg , cpsr
eor \reg, \reg, #HYP_MODE
tst \reg, #MODE_MASK
bic \reg , \reg , #MODE_MASK
orr \reg , \reg , #PSR_I_BIT | PSR_F_BIT | SVC_MODE
THUMB( orr \reg , \reg , #PSR_T_BIT )
bne 1f
orr \reg, \reg, #PSR_A_BIT
badr lr, 2f
msr spsr_cxsf, \reg
__MSR_ELR_HYP(14)
__ERET
1: msr cpsr_c, \reg
2:
#else
/*
* workaround for possibly broken pre-v6 hardware
* (akita, Sharp Zaurus C-1000, PXA270-based)
*/
setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, \reg
#endif
.endm
/*
* STRT/LDRT access macros with ARM and Thumb-2 variants
*/
#ifdef CONFIG_THUMB2_KERNEL
.macro usraccoff, instr, reg, ptr, inc, off, cond, abort, t=TUSER()
9999:
.if \inc == 1
\instr\()b\t\cond\().w \reg, [\ptr, #\off]
.elseif \inc == 4
\instr\t\cond\().w \reg, [\ptr, #\off]
.else
.error "Unsupported inc macro argument"
.endif
.pushsection __ex_table,"a"
.align 3
.long 9999b, \abort
.popsection
.endm
.macro usracc, instr, reg, ptr, inc, cond, rept, abort
@ explicit IT instruction needed because of the label
@ introduced by the USER macro
.ifnc \cond,al
.if \rept == 1
itt \cond
.elseif \rept == 2
ittt \cond
.else
.error "Unsupported rept macro argument"
.endif
.endif
@ Slightly optimised to avoid incrementing the pointer twice
usraccoff \instr, \reg, \ptr, \inc, 0, \cond, \abort
.if \rept == 2
usraccoff \instr, \reg, \ptr, \inc, \inc, \cond, \abort
.endif
add\cond \ptr, #\rept * \inc
.endm
#else /* !CONFIG_THUMB2_KERNEL */
.macro usracc, instr, reg, ptr, inc, cond, rept, abort, t=TUSER()
.rept \rept
9999:
.if \inc == 1
\instr\()b\t\cond \reg, [\ptr], #\inc
.elseif \inc == 4
\instr\t\cond \reg, [\ptr], #\inc
.else
.error "Unsupported inc macro argument"
.endif
.pushsection __ex_table,"a"
.align 3
.long 9999b, \abort
.popsection
.endr
.endm
#endif /* CONFIG_THUMB2_KERNEL */
.macro strusr, reg, ptr, inc, cond=al, rept=1, abort=9001f
usracc str, \reg, \ptr, \inc, \cond, \rept, \abort
.endm
.macro ldrusr, reg, ptr, inc, cond=al, rept=1, abort=9001f
usracc ldr, \reg, \ptr, \inc, \cond, \rept, \abort
.endm
/* Utility macro for declaring string literals */
.macro string name:req, string
.type \name , #object
\name:
.asciz "\string"
.size \name , . - \name
.endm
.irp c,,eq,ne,cs,cc,mi,pl,vs,vc,hi,ls,ge,lt,gt,le,hs,lo
.macro ret\c, reg
#if __LINUX_ARM_ARCH__ < 6
mov\c pc, \reg
#else
.ifeqs "\reg", "lr"
bx\c \reg
.else
mov\c pc, \reg
.endif
#endif
.endm
.endr
.macro ret.w, reg
ret \reg
#ifdef CONFIG_THUMB2_KERNEL
nop
#endif
.endm
.macro bug, msg, line
#ifdef CONFIG_THUMB2_KERNEL
1: .inst 0xde02
#else
1: .inst 0xe7f001f2
#endif
#ifdef CONFIG_DEBUG_BUGVERBOSE
.pushsection .rodata.str, "aMS", %progbits, 1
2: .asciz "\msg"
.popsection
.pushsection __bug_table, "aw"
.align 2
.word 1b, 2b
.hword \line
.popsection
#endif
.endm
#ifdef CONFIG_KPROBES
#define _ASM_NOKPROBE(entry) \
.pushsection "_kprobe_blacklist", "aw" ; \
.balign 4 ; \
.long entry; \
.popsection
#else
#define _ASM_NOKPROBE(entry)
#endif
.macro __adldst_l, op, reg, sym, tmp, c
.if __LINUX_ARM_ARCH__ < 7
ldr\c \tmp, .La\@
.subsection 1
.align 2
.La\@: .long \sym - .Lpc\@
.previous
.else
.ifnb \c
THUMB( ittt \c )
.endif
movw\c \tmp, #:lower16:\sym - .Lpc\@
movt\c \tmp, #:upper16:\sym - .Lpc\@
.endif
#ifndef CONFIG_THUMB2_KERNEL
.set .Lpc\@, . + 8 // PC bias
.ifc \op, add
add\c \reg, \tmp, pc
.else
\op\c \reg, [pc, \tmp]
.endif
#else
.Lb\@: add\c \tmp, \tmp, pc
/*
* In Thumb-2 builds, the PC bias depends on whether we are currently
* emitting into a .arm or a .thumb section. The size of the add opcode
* above will be 2 bytes when emitting in Thumb mode and 4 bytes when
* emitting in ARM mode, so let's use this to account for the bias.
*/
.set .Lpc\@, . + (. - .Lb\@)
.ifnc \op, add
\op\c \reg, [\tmp]
.endif
#endif
.endm
/*
* mov_l - move a constant value or [relocated] address into a register
*/
.macro mov_l, dst:req, imm:req, cond
.if __LINUX_ARM_ARCH__ < 7
ldr\cond \dst, =\imm
.else
movw\cond \dst, #:lower16:\imm
movt\cond \dst, #:upper16:\imm
.endif
.endm
/*
* adr_l - adr pseudo-op with unlimited range
*
* @dst: destination register
* @sym: name of the symbol
* @cond: conditional opcode suffix
*/
.macro adr_l, dst:req, sym:req, cond
__adldst_l add, \dst, \sym, \dst, \cond
.endm
/*
* ldr_l - ldr <literal> pseudo-op with unlimited range
*
* @dst: destination register
* @sym: name of the symbol
* @cond: conditional opcode suffix
*/
.macro ldr_l, dst:req, sym:req, cond
__adldst_l ldr, \dst, \sym, \dst, \cond
.endm
/*
* str_l - str <literal> pseudo-op with unlimited range
*
* @src: source register
* @sym: name of the symbol
* @tmp: mandatory scratch register
* @cond: conditional opcode suffix
*/
.macro str_l, src:req, sym:req, tmp:req, cond
__adldst_l str, \src, \sym, \tmp, \cond
.endm
.macro __ldst_va, op, reg, tmp, sym, cond, offset
#if __LINUX_ARM_ARCH__ >= 7 || \
!defined(CONFIG_ARM_HAS_GROUP_RELOCS) || \
(defined(MODULE) && defined(CONFIG_ARM_MODULE_PLTS))
mov_l \tmp, \sym, \cond
#else
/*
* Avoid a literal load, by emitting a sequence of ADD/LDR instructions
* with the appropriate relocations. The combined sequence has a range
* of -/+ 256 MiB, which should be sufficient for the core kernel and
* for modules loaded into the module region.
*/
.globl \sym
.reloc .L0_\@, R_ARM_ALU_PC_G0_NC, \sym
.reloc .L1_\@, R_ARM_ALU_PC_G1_NC, \sym
.reloc .L2_\@, R_ARM_LDR_PC_G2, \sym
.L0_\@: sub\cond \tmp, pc, #8 - \offset
.L1_\@: sub\cond \tmp, \tmp, #4 - \offset
.L2_\@:
#endif
\op\cond \reg, [\tmp, #\offset]
.endm
/*
* ldr_va - load a 32-bit word from the virtual address of \sym
*/
.macro ldr_va, rd:req, sym:req, cond, tmp, offset=0
.ifnb \tmp
__ldst_va ldr, \rd, \tmp, \sym, \cond, \offset
.else
__ldst_va ldr, \rd, \rd, \sym, \cond, \offset
.endif
.endm
/*
* str_va - store a 32-bit word to the virtual address of \sym
*/
.macro str_va, rn:req, sym:req, tmp:req, cond
__ldst_va str, \rn, \tmp, \sym, \cond, 0
.endm
/*
* ldr_this_cpu_armv6 - Load a 32-bit word from the per-CPU variable 'sym',
* without using a temp register. Supported in ARM mode
* only.
*/
.macro ldr_this_cpu_armv6, rd:req, sym:req
this_cpu_offset \rd
.globl \sym
.reloc .L0_\@, R_ARM_ALU_PC_G0_NC, \sym
.reloc .L1_\@, R_ARM_ALU_PC_G1_NC, \sym
.reloc .L2_\@, R_ARM_LDR_PC_G2, \sym
add \rd, \rd, pc
.L0_\@: sub \rd, \rd, #4
.L1_\@: sub \rd, \rd, #0
.L2_\@: ldr \rd, [\rd, #4]
.endm
/*
* ldr_this_cpu - Load a 32-bit word from the per-CPU variable 'sym'
* into register 'rd', which may be the stack pointer,
* using 't1' and 't2' as general temp registers. These
* are permitted to overlap with 'rd' if != sp
*/
.macro ldr_this_cpu, rd:req, sym:req, t1:req, t2:req
#ifndef CONFIG_SMP
ldr_va \rd, \sym, tmp=\t1
#elif __LINUX_ARM_ARCH__ >= 7 || \
!defined(CONFIG_ARM_HAS_GROUP_RELOCS) || \
(defined(MODULE) && defined(CONFIG_ARM_MODULE_PLTS))
this_cpu_offset \t1
mov_l \t2, \sym
ldr \rd, [\t1, \t2]
#else
ldr_this_cpu_armv6 \rd, \sym
#endif
.endm
/*
* rev_l - byte-swap a 32-bit value
*
* @val: source/destination register
* @tmp: scratch register
*/
.macro rev_l, val:req, tmp:req
.if __LINUX_ARM_ARCH__ < 6
eor \tmp, \val, \val, ror #16
bic \tmp, \tmp, #0x00ff0000
mov \val, \val, ror #8
eor \val, \val, \tmp, lsr #8
.else
rev \val, \val
.endif
.endm
.if __LINUX_ARM_ARCH__ < 6
.set .Lrev_l_uses_tmp, 1
.else
.set .Lrev_l_uses_tmp, 0
.endif
/*
* bl_r - branch and link to register
*
* @dst: target to branch to
* @c: conditional opcode suffix
*/
.macro bl_r, dst:req, c
.if __LINUX_ARM_ARCH__ < 6
mov\c lr, pc
mov\c pc, \dst
.else
blx\c \dst
.endif
.endm
#endif /* __ASM_ASSEMBLER_H__ */
+514
View File
@@ -0,0 +1,514 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* arch/arm/include/asm/atomic.h
*
* Copyright (C) 1996 Russell King.
* Copyright (C) 2002 Deep Blue Solutions Ltd.
*/
#ifndef __ASM_ARM_ATOMIC_H
#define __ASM_ARM_ATOMIC_H
#include <linux/compiler.h>
#include <linux/prefetch.h>
#include <linux/types.h>
#include <linux/irqflags.h>
#include <asm/barrier.h>
#include <asm/cmpxchg.h>
#ifdef __KERNEL__
/*
* On ARM, ordinary assignment (str instruction) doesn't clear the local
* strex/ldrex monitor on some implementations. The reason we can use it for
* atomic_set() is the clrex or dummy strex done on every exception return.
*/
#define arch_atomic_read(v) READ_ONCE((v)->counter)
#define arch_atomic_set(v,i) WRITE_ONCE(((v)->counter), (i))
#if __LINUX_ARM_ARCH__ >= 6
/*
* ARMv6 UP and SMP safe atomic ops. We use load exclusive and
* store exclusive to ensure that these are atomic. We may loop
* to ensure that the update happens.
*/
#define ATOMIC_OP(op, c_op, asm_op) \
static inline void arch_atomic_##op(int i, atomic_t *v) \
{ \
unsigned long tmp; \
int result; \
\
prefetchw(&v->counter); \
__asm__ __volatile__("@ atomic_" #op "\n" \
"1: ldrex %0, [%3]\n" \
" " #asm_op " %0, %0, %4\n" \
" strex %1, %0, [%3]\n" \
" teq %1, #0\n" \
" bne 1b" \
: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) \
: "r" (&v->counter), "Ir" (i) \
: "cc"); \
} \
#define ATOMIC_OP_RETURN(op, c_op, asm_op) \
static inline int arch_atomic_##op##_return_relaxed(int i, atomic_t *v) \
{ \
unsigned long tmp; \
int result; \
\
prefetchw(&v->counter); \
\
__asm__ __volatile__("@ atomic_" #op "_return\n" \
"1: ldrex %0, [%3]\n" \
" " #asm_op " %0, %0, %4\n" \
" strex %1, %0, [%3]\n" \
" teq %1, #0\n" \
" bne 1b" \
: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) \
: "r" (&v->counter), "Ir" (i) \
: "cc"); \
\
return result; \
}
#define ATOMIC_FETCH_OP(op, c_op, asm_op) \
static inline int arch_atomic_fetch_##op##_relaxed(int i, atomic_t *v) \
{ \
unsigned long tmp; \
int result, val; \
\
prefetchw(&v->counter); \
\
__asm__ __volatile__("@ atomic_fetch_" #op "\n" \
"1: ldrex %0, [%4]\n" \
" " #asm_op " %1, %0, %5\n" \
" strex %2, %1, [%4]\n" \
" teq %2, #0\n" \
" bne 1b" \
: "=&r" (result), "=&r" (val), "=&r" (tmp), "+Qo" (v->counter) \
: "r" (&v->counter), "Ir" (i) \
: "cc"); \
\
return result; \
}
#define arch_atomic_add_return_relaxed arch_atomic_add_return_relaxed
#define arch_atomic_sub_return_relaxed arch_atomic_sub_return_relaxed
#define arch_atomic_fetch_add_relaxed arch_atomic_fetch_add_relaxed
#define arch_atomic_fetch_sub_relaxed arch_atomic_fetch_sub_relaxed
#define arch_atomic_fetch_and_relaxed arch_atomic_fetch_and_relaxed
#define arch_atomic_fetch_andnot_relaxed arch_atomic_fetch_andnot_relaxed
#define arch_atomic_fetch_or_relaxed arch_atomic_fetch_or_relaxed
#define arch_atomic_fetch_xor_relaxed arch_atomic_fetch_xor_relaxed
static inline int arch_atomic_cmpxchg_relaxed(atomic_t *ptr, int old, int new)
{
int oldval;
unsigned long res;
prefetchw(&ptr->counter);
do {
__asm__ __volatile__("@ atomic_cmpxchg\n"
"ldrex %1, [%3]\n"
"mov %0, #0\n"
"teq %1, %4\n"
"strexeq %0, %5, [%3]\n"
: "=&r" (res), "=&r" (oldval), "+Qo" (ptr->counter)
: "r" (&ptr->counter), "Ir" (old), "r" (new)
: "cc");
} while (res);
return oldval;
}
#define arch_atomic_cmpxchg_relaxed arch_atomic_cmpxchg_relaxed
static inline int arch_atomic_fetch_add_unless(atomic_t *v, int a, int u)
{
int oldval, newval;
unsigned long tmp;
smp_mb();
prefetchw(&v->counter);
__asm__ __volatile__ ("@ atomic_add_unless\n"
"1: ldrex %0, [%4]\n"
" teq %0, %5\n"
" beq 2f\n"
" add %1, %0, %6\n"
" strex %2, %1, [%4]\n"
" teq %2, #0\n"
" bne 1b\n"
"2:"
: "=&r" (oldval), "=&r" (newval), "=&r" (tmp), "+Qo" (v->counter)
: "r" (&v->counter), "r" (u), "r" (a)
: "cc");
if (oldval != u)
smp_mb();
return oldval;
}
#define arch_atomic_fetch_add_unless arch_atomic_fetch_add_unless
#else /* ARM_ARCH_6 */
#ifdef CONFIG_SMP
#error SMP not supported on pre-ARMv6 CPUs
#endif
#define ATOMIC_OP(op, c_op, asm_op) \
static inline void arch_atomic_##op(int i, atomic_t *v) \
{ \
unsigned long flags; \
\
raw_local_irq_save(flags); \
v->counter c_op i; \
raw_local_irq_restore(flags); \
} \
#define ATOMIC_OP_RETURN(op, c_op, asm_op) \
static inline int arch_atomic_##op##_return(int i, atomic_t *v) \
{ \
unsigned long flags; \
int val; \
\
raw_local_irq_save(flags); \
v->counter c_op i; \
val = v->counter; \
raw_local_irq_restore(flags); \
\
return val; \
}
#define ATOMIC_FETCH_OP(op, c_op, asm_op) \
static inline int arch_atomic_fetch_##op(int i, atomic_t *v) \
{ \
unsigned long flags; \
int val; \
\
raw_local_irq_save(flags); \
val = v->counter; \
v->counter c_op i; \
raw_local_irq_restore(flags); \
\
return val; \
}
#define arch_atomic_add_return arch_atomic_add_return
#define arch_atomic_sub_return arch_atomic_sub_return
#define arch_atomic_fetch_add arch_atomic_fetch_add
#define arch_atomic_fetch_sub arch_atomic_fetch_sub
#define arch_atomic_fetch_and arch_atomic_fetch_and
#define arch_atomic_fetch_andnot arch_atomic_fetch_andnot
#define arch_atomic_fetch_or arch_atomic_fetch_or
#define arch_atomic_fetch_xor arch_atomic_fetch_xor
static inline int arch_atomic_cmpxchg(atomic_t *v, int old, int new)
{
int ret;
unsigned long flags;
raw_local_irq_save(flags);
ret = v->counter;
if (likely(ret == old))
v->counter = new;
raw_local_irq_restore(flags);
return ret;
}
#define arch_atomic_cmpxchg arch_atomic_cmpxchg
#endif /* __LINUX_ARM_ARCH__ */
#define ATOMIC_OPS(op, c_op, asm_op) \
ATOMIC_OP(op, c_op, asm_op) \
ATOMIC_OP_RETURN(op, c_op, asm_op) \
ATOMIC_FETCH_OP(op, c_op, asm_op)
ATOMIC_OPS(add, +=, add)
ATOMIC_OPS(sub, -=, sub)
#define arch_atomic_andnot arch_atomic_andnot
#undef ATOMIC_OPS
#define ATOMIC_OPS(op, c_op, asm_op) \
ATOMIC_OP(op, c_op, asm_op) \
ATOMIC_FETCH_OP(op, c_op, asm_op)
ATOMIC_OPS(and, &=, and)
ATOMIC_OPS(andnot, &= ~, bic)
ATOMIC_OPS(or, |=, orr)
ATOMIC_OPS(xor, ^=, eor)
#undef ATOMIC_OPS
#undef ATOMIC_FETCH_OP
#undef ATOMIC_OP_RETURN
#undef ATOMIC_OP
#ifndef CONFIG_GENERIC_ATOMIC64
typedef struct {
s64 counter;
} atomic64_t;
#define ATOMIC64_INIT(i) { (i) }
#ifdef CONFIG_ARM_LPAE
static inline s64 arch_atomic64_read(const atomic64_t *v)
{
s64 result;
__asm__ __volatile__("@ atomic64_read\n"
" ldrd %0, %H0, [%1]"
: "=&r" (result)
: "r" (&v->counter), "Qo" (v->counter)
);
return result;
}
static inline void arch_atomic64_set(atomic64_t *v, s64 i)
{
__asm__ __volatile__("@ atomic64_set\n"
" strd %2, %H2, [%1]"
: "=Qo" (v->counter)
: "r" (&v->counter), "r" (i)
);
}
#else
static inline s64 arch_atomic64_read(const atomic64_t *v)
{
s64 result;
__asm__ __volatile__("@ atomic64_read\n"
" ldrexd %0, %H0, [%1]"
: "=&r" (result)
: "r" (&v->counter), "Qo" (v->counter)
);
return result;
}
static inline void arch_atomic64_set(atomic64_t *v, s64 i)
{
s64 tmp;
prefetchw(&v->counter);
__asm__ __volatile__("@ atomic64_set\n"
"1: ldrexd %0, %H0, [%2]\n"
" strexd %0, %3, %H3, [%2]\n"
" teq %0, #0\n"
" bne 1b"
: "=&r" (tmp), "=Qo" (v->counter)
: "r" (&v->counter), "r" (i)
: "cc");
}
#endif
#define ATOMIC64_OP(op, op1, op2) \
static inline void arch_atomic64_##op(s64 i, atomic64_t *v) \
{ \
s64 result; \
unsigned long tmp; \
\
prefetchw(&v->counter); \
__asm__ __volatile__("@ atomic64_" #op "\n" \
"1: ldrexd %0, %H0, [%3]\n" \
" " #op1 " %Q0, %Q0, %Q4\n" \
" " #op2 " %R0, %R0, %R4\n" \
" strexd %1, %0, %H0, [%3]\n" \
" teq %1, #0\n" \
" bne 1b" \
: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) \
: "r" (&v->counter), "r" (i) \
: "cc"); \
} \
#define ATOMIC64_OP_RETURN(op, op1, op2) \
static inline s64 \
arch_atomic64_##op##_return_relaxed(s64 i, atomic64_t *v) \
{ \
s64 result; \
unsigned long tmp; \
\
prefetchw(&v->counter); \
\
__asm__ __volatile__("@ atomic64_" #op "_return\n" \
"1: ldrexd %0, %H0, [%3]\n" \
" " #op1 " %Q0, %Q0, %Q4\n" \
" " #op2 " %R0, %R0, %R4\n" \
" strexd %1, %0, %H0, [%3]\n" \
" teq %1, #0\n" \
" bne 1b" \
: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) \
: "r" (&v->counter), "r" (i) \
: "cc"); \
\
return result; \
}
#define ATOMIC64_FETCH_OP(op, op1, op2) \
static inline s64 \
arch_atomic64_fetch_##op##_relaxed(s64 i, atomic64_t *v) \
{ \
s64 result, val; \
unsigned long tmp; \
\
prefetchw(&v->counter); \
\
__asm__ __volatile__("@ atomic64_fetch_" #op "\n" \
"1: ldrexd %0, %H0, [%4]\n" \
" " #op1 " %Q1, %Q0, %Q5\n" \
" " #op2 " %R1, %R0, %R5\n" \
" strexd %2, %1, %H1, [%4]\n" \
" teq %2, #0\n" \
" bne 1b" \
: "=&r" (result), "=&r" (val), "=&r" (tmp), "+Qo" (v->counter) \
: "r" (&v->counter), "r" (i) \
: "cc"); \
\
return result; \
}
#define ATOMIC64_OPS(op, op1, op2) \
ATOMIC64_OP(op, op1, op2) \
ATOMIC64_OP_RETURN(op, op1, op2) \
ATOMIC64_FETCH_OP(op, op1, op2)
ATOMIC64_OPS(add, adds, adc)
ATOMIC64_OPS(sub, subs, sbc)
#define arch_atomic64_add_return_relaxed arch_atomic64_add_return_relaxed
#define arch_atomic64_sub_return_relaxed arch_atomic64_sub_return_relaxed
#define arch_atomic64_fetch_add_relaxed arch_atomic64_fetch_add_relaxed
#define arch_atomic64_fetch_sub_relaxed arch_atomic64_fetch_sub_relaxed
#undef ATOMIC64_OPS
#define ATOMIC64_OPS(op, op1, op2) \
ATOMIC64_OP(op, op1, op2) \
ATOMIC64_FETCH_OP(op, op1, op2)
#define arch_atomic64_andnot arch_atomic64_andnot
ATOMIC64_OPS(and, and, and)
ATOMIC64_OPS(andnot, bic, bic)
ATOMIC64_OPS(or, orr, orr)
ATOMIC64_OPS(xor, eor, eor)
#define arch_atomic64_fetch_and_relaxed arch_atomic64_fetch_and_relaxed
#define arch_atomic64_fetch_andnot_relaxed arch_atomic64_fetch_andnot_relaxed
#define arch_atomic64_fetch_or_relaxed arch_atomic64_fetch_or_relaxed
#define arch_atomic64_fetch_xor_relaxed arch_atomic64_fetch_xor_relaxed
#undef ATOMIC64_OPS
#undef ATOMIC64_FETCH_OP
#undef ATOMIC64_OP_RETURN
#undef ATOMIC64_OP
static inline s64 arch_atomic64_cmpxchg_relaxed(atomic64_t *ptr, s64 old, s64 new)
{
s64 oldval;
unsigned long res;
prefetchw(&ptr->counter);
do {
__asm__ __volatile__("@ atomic64_cmpxchg\n"
"ldrexd %1, %H1, [%3]\n"
"mov %0, #0\n"
"teq %1, %4\n"
"teqeq %H1, %H4\n"
"strexdeq %0, %5, %H5, [%3]"
: "=&r" (res), "=&r" (oldval), "+Qo" (ptr->counter)
: "r" (&ptr->counter), "r" (old), "r" (new)
: "cc");
} while (res);
return oldval;
}
#define arch_atomic64_cmpxchg_relaxed arch_atomic64_cmpxchg_relaxed
static inline s64 arch_atomic64_xchg_relaxed(atomic64_t *ptr, s64 new)
{
s64 result;
unsigned long tmp;
prefetchw(&ptr->counter);
__asm__ __volatile__("@ atomic64_xchg\n"
"1: ldrexd %0, %H0, [%3]\n"
" strexd %1, %4, %H4, [%3]\n"
" teq %1, #0\n"
" bne 1b"
: "=&r" (result), "=&r" (tmp), "+Qo" (ptr->counter)
: "r" (&ptr->counter), "r" (new)
: "cc");
return result;
}
#define arch_atomic64_xchg_relaxed arch_atomic64_xchg_relaxed
static inline s64 arch_atomic64_dec_if_positive(atomic64_t *v)
{
s64 result;
unsigned long tmp;
smp_mb();
prefetchw(&v->counter);
__asm__ __volatile__("@ atomic64_dec_if_positive\n"
"1: ldrexd %0, %H0, [%3]\n"
" subs %Q0, %Q0, #1\n"
" sbc %R0, %R0, #0\n"
" teq %R0, #0\n"
" bmi 2f\n"
" strexd %1, %0, %H0, [%3]\n"
" teq %1, #0\n"
" bne 1b\n"
"2:"
: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
: "r" (&v->counter)
: "cc");
smp_mb();
return result;
}
#define arch_atomic64_dec_if_positive arch_atomic64_dec_if_positive
static inline s64 arch_atomic64_fetch_add_unless(atomic64_t *v, s64 a, s64 u)
{
s64 oldval, newval;
unsigned long tmp;
smp_mb();
prefetchw(&v->counter);
__asm__ __volatile__("@ atomic64_add_unless\n"
"1: ldrexd %0, %H0, [%4]\n"
" teq %0, %5\n"
" teqeq %H0, %H5\n"
" beq 2f\n"
" adds %Q1, %Q0, %Q6\n"
" adc %R1, %R0, %R6\n"
" strexd %2, %1, %H1, [%4]\n"
" teq %2, #0\n"
" bne 1b\n"
"2:"
: "=&r" (oldval), "=&r" (newval), "=&r" (tmp), "+Qo" (v->counter)
: "r" (&v->counter), "r" (u), "r" (a)
: "cc");
if (oldval != u)
smp_mb();
return oldval;
}
#define arch_atomic64_fetch_add_unless arch_atomic64_fetch_add_unless
#endif /* !CONFIG_GENERIC_ATOMIC64 */
#endif
#endif
@@ -0,0 +1 @@
#include <uapi/asm/auxvec.h>
@@ -0,0 +1,74 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* arch/arm/include/asm/bL_switcher.h
*
* Created by: Nicolas Pitre, April 2012
* Copyright: (C) 2012-2013 Linaro Limited
*/
#ifndef ASM_BL_SWITCHER_H
#define ASM_BL_SWITCHER_H
#include <linux/compiler.h>
#include <linux/types.h>
typedef void (*bL_switch_completion_handler)(void *cookie);
int bL_switch_request_cb(unsigned int cpu, unsigned int new_cluster_id,
bL_switch_completion_handler completer,
void *completer_cookie);
static inline int bL_switch_request(unsigned int cpu, unsigned int new_cluster_id)
{
return bL_switch_request_cb(cpu, new_cluster_id, NULL, NULL);
}
/*
* Register here to be notified about runtime enabling/disabling of
* the switcher.
*
* The notifier chain is called with the switcher activation lock held:
* the switcher will not be enabled or disabled during callbacks.
* Callbacks must not call bL_switcher_{get,put}_enabled().
*/
#define BL_NOTIFY_PRE_ENABLE 0
#define BL_NOTIFY_POST_ENABLE 1
#define BL_NOTIFY_PRE_DISABLE 2
#define BL_NOTIFY_POST_DISABLE 3
#ifdef CONFIG_BL_SWITCHER
int bL_switcher_register_notifier(struct notifier_block *nb);
int bL_switcher_unregister_notifier(struct notifier_block *nb);
/*
* Use these functions to temporarily prevent enabling/disabling of
* the switcher.
* bL_switcher_get_enabled() returns true if the switcher is currently
* enabled. Each call to bL_switcher_get_enabled() must be followed
* by a call to bL_switcher_put_enabled(). These functions are not
* recursive.
*/
bool bL_switcher_get_enabled(void);
void bL_switcher_put_enabled(void);
int bL_switcher_trace_trigger(void);
int bL_switcher_get_logical_index(u32 mpidr);
#else
static inline int bL_switcher_register_notifier(struct notifier_block *nb)
{
return 0;
}
static inline int bL_switcher_unregister_notifier(struct notifier_block *nb)
{
return 0;
}
static inline bool bL_switcher_get_enabled(void) { return false; }
static inline void bL_switcher_put_enabled(void) { }
static inline int bL_switcher_trace_trigger(void) { return 0; }
static inline int bL_switcher_get_logical_index(u32 mpidr) { return -EUNATCH; }
#endif /* CONFIG_BL_SWITCHER */
#endif
+103
View File
@@ -0,0 +1,103 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_BARRIER_H
#define __ASM_BARRIER_H
#ifndef __ASSEMBLY__
#define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t");
#if __LINUX_ARM_ARCH__ >= 7 || \
(__LINUX_ARM_ARCH__ == 6 && defined(CONFIG_CPU_32v6K))
#define sev() __asm__ __volatile__ ("sev" : : : "memory")
#define wfe() __asm__ __volatile__ ("wfe" : : : "memory")
#define wfi() __asm__ __volatile__ ("wfi" : : : "memory")
#else
#define wfe() do { } while (0)
#endif
#if __LINUX_ARM_ARCH__ >= 7
#define isb(option) __asm__ __volatile__ ("isb " #option : : : "memory")
#define dsb(option) __asm__ __volatile__ ("dsb " #option : : : "memory")
#define dmb(option) __asm__ __volatile__ ("dmb " #option : : : "memory")
#ifdef CONFIG_THUMB2_KERNEL
#define CSDB ".inst.w 0xf3af8014"
#else
#define CSDB ".inst 0xe320f014"
#endif
#define csdb() __asm__ __volatile__(CSDB : : : "memory")
#elif defined(CONFIG_CPU_XSC3) || __LINUX_ARM_ARCH__ == 6
#define isb(x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \
: : "r" (0) : "memory")
#define dsb(x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \
: : "r" (0) : "memory")
#define dmb(x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \
: : "r" (0) : "memory")
#elif defined(CONFIG_CPU_FA526)
#define isb(x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \
: : "r" (0) : "memory")
#define dsb(x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \
: : "r" (0) : "memory")
#define dmb(x) __asm__ __volatile__ ("" : : : "memory")
#else
#define isb(x) __asm__ __volatile__ ("" : : : "memory")
#define dsb(x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \
: : "r" (0) : "memory")
#define dmb(x) __asm__ __volatile__ ("" : : : "memory")
#endif
#ifndef CSDB
#define CSDB
#endif
#ifndef csdb
#define csdb()
#endif
#ifdef CONFIG_ARM_HEAVY_MB
extern void (*soc_mb)(void);
extern void arm_heavy_mb(void);
#define __arm_heavy_mb(x...) do { dsb(x); arm_heavy_mb(); } while (0)
#else
#define __arm_heavy_mb(x...) dsb(x)
#endif
#if defined(CONFIG_ARM_DMA_MEM_BUFFERABLE) || defined(CONFIG_SMP)
#define mb() __arm_heavy_mb()
#define rmb() dsb()
#define wmb() __arm_heavy_mb(st)
#define dma_rmb() dmb(osh)
#define dma_wmb() dmb(oshst)
#else
#define mb() barrier()
#define rmb() barrier()
#define wmb() barrier()
#define dma_rmb() barrier()
#define dma_wmb() barrier()
#endif
#define __smp_mb() dmb(ish)
#define __smp_rmb() __smp_mb()
#define __smp_wmb() dmb(ishst)
#ifdef CONFIG_CPU_SPECTRE
static inline unsigned long array_index_mask_nospec(unsigned long idx,
unsigned long sz)
{
unsigned long mask;
asm volatile(
"cmp %1, %2\n"
" sbc %0, %1, %1\n"
CSDB
: "=r" (mask)
: "r" (idx), "Ir" (sz)
: "cc");
return mask;
}
#define array_index_mask_nospec array_index_mask_nospec
#endif
#include <asm-generic/barrier.h>
#endif /* !__ASSEMBLY__ */
#endif /* __ASM_BARRIER_H */
+278
View File
@@ -0,0 +1,278 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright 1995, Russell King.
* Various bits and pieces copyrights include:
* Linus Torvalds (test_bit).
* Big endian support: Copyright 2001, Nicolas Pitre
* reworked by rmk.
*
* bit 0 is the LSB of an "unsigned long" quantity.
*
* Please note that the code in this file should never be included
* from user space. Many of these are not implemented in assembler
* since they would be too costly. Also, they require privileged
* instructions (which are not available from user mode) to ensure
* that they are atomic.
*/
#ifndef __ASM_ARM_BITOPS_H
#define __ASM_ARM_BITOPS_H
#ifdef __KERNEL__
#ifndef _LINUX_BITOPS_H
#error only <linux/bitops.h> can be included directly
#endif
#include <linux/compiler.h>
#include <linux/irqflags.h>
#include <asm/barrier.h>
/*
* These functions are the basis of our bit ops.
*
* First, the atomic bitops. These use native endian.
*/
static inline void ____atomic_set_bit(unsigned int bit, volatile unsigned long *p)
{
unsigned long flags;
unsigned long mask = BIT_MASK(bit);
p += BIT_WORD(bit);
raw_local_irq_save(flags);
*p |= mask;
raw_local_irq_restore(flags);
}
static inline void ____atomic_clear_bit(unsigned int bit, volatile unsigned long *p)
{
unsigned long flags;
unsigned long mask = BIT_MASK(bit);
p += BIT_WORD(bit);
raw_local_irq_save(flags);
*p &= ~mask;
raw_local_irq_restore(flags);
}
static inline void ____atomic_change_bit(unsigned int bit, volatile unsigned long *p)
{
unsigned long flags;
unsigned long mask = BIT_MASK(bit);
p += BIT_WORD(bit);
raw_local_irq_save(flags);
*p ^= mask;
raw_local_irq_restore(flags);
}
static inline int
____atomic_test_and_set_bit(unsigned int bit, volatile unsigned long *p)
{
unsigned long flags;
unsigned int res;
unsigned long mask = BIT_MASK(bit);
p += BIT_WORD(bit);
raw_local_irq_save(flags);
res = *p;
*p = res | mask;
raw_local_irq_restore(flags);
return (res & mask) != 0;
}
static inline int
____atomic_test_and_clear_bit(unsigned int bit, volatile unsigned long *p)
{
unsigned long flags;
unsigned int res;
unsigned long mask = BIT_MASK(bit);
p += BIT_WORD(bit);
raw_local_irq_save(flags);
res = *p;
*p = res & ~mask;
raw_local_irq_restore(flags);
return (res & mask) != 0;
}
static inline int
____atomic_test_and_change_bit(unsigned int bit, volatile unsigned long *p)
{
unsigned long flags;
unsigned int res;
unsigned long mask = BIT_MASK(bit);
p += BIT_WORD(bit);
raw_local_irq_save(flags);
res = *p;
*p = res ^ mask;
raw_local_irq_restore(flags);
return (res & mask) != 0;
}
#include <asm-generic/bitops/non-atomic.h>
/*
* A note about Endian-ness.
* -------------------------
*
* When the ARM is put into big endian mode via CR15, the processor
* merely swaps the order of bytes within words, thus:
*
* ------------ physical data bus bits -----------
* D31 ... D24 D23 ... D16 D15 ... D8 D7 ... D0
* little byte 3 byte 2 byte 1 byte 0
* big byte 0 byte 1 byte 2 byte 3
*
* This means that reading a 32-bit word at address 0 returns the same
* value irrespective of the endian mode bit.
*
* Peripheral devices should be connected with the data bus reversed in
* "Big Endian" mode. ARM Application Note 61 is applicable, and is
* available from http://www.arm.com/.
*
* The following assumes that the data bus connectivity for big endian
* mode has been followed.
*
* Note that bit 0 is defined to be 32-bit word bit 0, not byte 0 bit 0.
*/
/*
* Native endian assembly bitops. nr = 0 -> word 0 bit 0.
*/
extern void _set_bit(int nr, volatile unsigned long * p);
extern void _clear_bit(int nr, volatile unsigned long * p);
extern void _change_bit(int nr, volatile unsigned long * p);
extern int _test_and_set_bit(int nr, volatile unsigned long * p);
extern int _test_and_clear_bit(int nr, volatile unsigned long * p);
extern int _test_and_change_bit(int nr, volatile unsigned long * p);
/*
* Little endian assembly bitops. nr = 0 -> byte 0 bit 0.
*/
unsigned long _find_first_zero_bit_le(const unsigned long *p, unsigned long size);
unsigned long _find_next_zero_bit_le(const unsigned long *p,
unsigned long size, unsigned long offset);
unsigned long _find_first_bit_le(const unsigned long *p, unsigned long size);
unsigned long _find_next_bit_le(const unsigned long *p, unsigned long size, unsigned long offset);
/*
* Big endian assembly bitops. nr = 0 -> byte 3 bit 0.
*/
unsigned long _find_first_zero_bit_be(const unsigned long *p, unsigned long size);
unsigned long _find_next_zero_bit_be(const unsigned long *p,
unsigned long size, unsigned long offset);
unsigned long _find_first_bit_be(const unsigned long *p, unsigned long size);
unsigned long _find_next_bit_be(const unsigned long *p, unsigned long size, unsigned long offset);
#ifndef CONFIG_SMP
/*
* The __* form of bitops are non-atomic and may be reordered.
*/
#define ATOMIC_BITOP(name,nr,p) \
(__builtin_constant_p(nr) ? ____atomic_##name(nr, p) : _##name(nr,p))
#else
#define ATOMIC_BITOP(name,nr,p) _##name(nr,p)
#endif
/*
* Native endian atomic definitions.
*/
#define set_bit(nr,p) ATOMIC_BITOP(set_bit,nr,p)
#define clear_bit(nr,p) ATOMIC_BITOP(clear_bit,nr,p)
#define change_bit(nr,p) ATOMIC_BITOP(change_bit,nr,p)
#define test_and_set_bit(nr,p) ATOMIC_BITOP(test_and_set_bit,nr,p)
#define test_and_clear_bit(nr,p) ATOMIC_BITOP(test_and_clear_bit,nr,p)
#define test_and_change_bit(nr,p) ATOMIC_BITOP(test_and_change_bit,nr,p)
#ifndef __ARMEB__
/*
* These are the little endian, atomic definitions.
*/
#define find_first_zero_bit(p,sz) _find_first_zero_bit_le(p,sz)
#define find_next_zero_bit(p,sz,off) _find_next_zero_bit_le(p,sz,off)
#define find_first_bit(p,sz) _find_first_bit_le(p,sz)
#define find_next_bit(p,sz,off) _find_next_bit_le(p,sz,off)
#else
/*
* These are the big endian, atomic definitions.
*/
#define find_first_zero_bit(p,sz) _find_first_zero_bit_be(p,sz)
#define find_next_zero_bit(p,sz,off) _find_next_zero_bit_be(p,sz,off)
#define find_first_bit(p,sz) _find_first_bit_be(p,sz)
#define find_next_bit(p,sz,off) _find_next_bit_be(p,sz,off)
#endif
#if __LINUX_ARM_ARCH__ < 5
#include <asm-generic/bitops/__fls.h>
#include <asm-generic/bitops/__ffs.h>
#include <asm-generic/bitops/fls.h>
#include <asm-generic/bitops/ffs.h>
#else
/*
* On ARMv5 and above, the gcc built-ins may rely on the clz instruction
* and produce optimal inlined code in all cases. On ARMv7 it is even
* better by also using the rbit instruction.
*/
#include <asm-generic/bitops/builtin-__fls.h>
#include <asm-generic/bitops/builtin-__ffs.h>
#include <asm-generic/bitops/builtin-fls.h>
#include <asm-generic/bitops/builtin-ffs.h>
#endif
#include <asm-generic/bitops/ffz.h>
#include <asm-generic/bitops/fls64.h>
#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/hweight.h>
#include <asm-generic/bitops/lock.h>
#ifdef __ARMEB__
static inline int find_first_zero_bit_le(const void *p, unsigned size)
{
return _find_first_zero_bit_le(p, size);
}
#define find_first_zero_bit_le find_first_zero_bit_le
static inline int find_next_zero_bit_le(const void *p, int size, int offset)
{
return _find_next_zero_bit_le(p, size, offset);
}
#define find_next_zero_bit_le find_next_zero_bit_le
static inline int find_next_bit_le(const void *p, int size, int offset)
{
return _find_next_bit_le(p, size, offset);
}
#define find_next_bit_le find_next_bit_le
#endif
#include <asm-generic/bitops/le.h>
/*
* Ext2 is defined to use little-endian byte ordering.
*/
#include <asm-generic/bitops/ext2-atomic-setbit.h>
#endif /* __KERNEL__ */
#endif /* _ARM_BITOPS_H */
+21
View File
@@ -0,0 +1,21 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_BITREV_H
#define __ASM_BITREV_H
static __always_inline __attribute_const__ u32 __arch_bitrev32(u32 x)
{
__asm__ ("rbit %0, %1" : "=r" (x) : "r" (x));
return x;
}
static __always_inline __attribute_const__ u16 __arch_bitrev16(u16 x)
{
return __arch_bitrev32((u32)x) >> 16;
}
static __always_inline __attribute_const__ u8 __arch_bitrev8(u8 x)
{
return __arch_bitrev32((u32)x) >> 24;
}
#endif
+93
View File
@@ -0,0 +1,93 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASMARM_BUG_H
#define _ASMARM_BUG_H
#include <linux/linkage.h>
#include <linux/types.h>
#include <asm/opcodes.h>
/*
* Use a suitable undefined instruction to use for ARM/Thumb2 bug handling.
* We need to be careful not to conflict with those used by other modules and
* the register_undef_hook() system.
*/
#ifdef CONFIG_THUMB2_KERNEL
#define BUG_INSTR_VALUE 0xde02
#define BUG_INSTR(__value) __inst_thumb16(__value)
#else
#define BUG_INSTR_VALUE 0xe7f001f2
#define BUG_INSTR(__value) __inst_arm(__value)
#endif
#define BUG() _BUG(__FILE__, __LINE__, BUG_INSTR_VALUE)
#define _BUG(file, line, value) __BUG(file, line, value)
#ifdef CONFIG_DEBUG_BUGVERBOSE
/*
* The extra indirection is to ensure that the __FILE__ string comes through
* OK. Many version of gcc do not support the asm %c parameter which would be
* preferable to this unpleasantness. We use mergeable string sections to
* avoid multiple copies of the string appearing in the kernel image.
*/
#define __BUG(__file, __line, __value) \
do { \
asm volatile("1:\t" BUG_INSTR(__value) "\n" \
".pushsection .rodata.str, \"aMS\", %progbits, 1\n" \
"2:\t.asciz " #__file "\n" \
".popsection\n" \
".pushsection __bug_table,\"aw\"\n" \
".align 2\n" \
"3:\t.word 1b, 2b\n" \
"\t.hword " #__line ", 0\n" \
".popsection"); \
unreachable(); \
} while (0)
#else
#define __BUG(__file, __line, __value) \
do { \
asm volatile(BUG_INSTR(__value) "\n"); \
unreachable(); \
} while (0)
#endif /* CONFIG_DEBUG_BUGVERBOSE */
#define HAVE_ARCH_BUG
#include <asm-generic/bug.h>
struct pt_regs;
void die(const char *msg, struct pt_regs *regs, int err);
void arm_notify_die(const char *str, struct pt_regs *regs,
int signo, int si_code, void __user *addr,
unsigned long err, unsigned long trap);
#ifdef CONFIG_ARM_LPAE
#define FAULT_CODE_ALIGNMENT 33
#define FAULT_CODE_DEBUG 34
#else
#define FAULT_CODE_ALIGNMENT 1
#define FAULT_CODE_DEBUG 2
#endif
void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
struct pt_regs *),
int sig, int code, const char *name);
void hook_ifault_code(int nr, int (*fn)(unsigned long, unsigned int,
struct pt_regs *),
int sig, int code, const char *name);
extern asmlinkage void c_backtrace(unsigned long fp, int pmode,
const char *loglvl);
struct mm_struct;
void show_pte(const char *lvl, struct mm_struct *mm, unsigned long addr);
extern void __show_regs(struct pt_regs *);
extern void __show_regs_alloc_free(struct pt_regs *regs);
#endif
+16
View File
@@ -0,0 +1,16 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 1995-2003 Russell King
*/
#ifndef __ASM_BUGS_H
#define __ASM_BUGS_H
extern void check_writebuffer_bugs(void);
#ifdef CONFIG_MMU
extern void check_other_bugs(void);
#else
#define check_other_bugs() do { } while (0)
#endif
#endif
+35
View File
@@ -0,0 +1,35 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* arch/arm/include/asm/cache.h
*/
#ifndef __ASMARM_CACHE_H
#define __ASMARM_CACHE_H
#define L1_CACHE_SHIFT CONFIG_ARM_L1_CACHE_SHIFT
#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
/*
* Memory returned by kmalloc() may be used for DMA, so we must make
* sure that all such allocations are cache aligned. Otherwise,
* unrelated code may cause parts of the buffer to be read into the
* cache before the transfer is done, causing old data to be seen by
* the CPU.
*/
#define ARCH_DMA_MINALIGN L1_CACHE_BYTES
/*
* With EABI on ARMv5 and above we must have 64-bit aligned slab pointers.
*/
#if defined(CONFIG_AEABI) && (__LINUX_ARM_ARCH__ >= 5)
#define ARCH_SLAB_MINALIGN 8
#endif
#define __read_mostly __section(".data..read_mostly")
#ifndef __ASSEMBLY__
#ifdef CONFIG_ARCH_HAS_CACHE_LINE_SIZE
int cache_line_size(void);
#endif
#endif
#endif
@@ -0,0 +1,476 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* arch/arm/include/asm/cacheflush.h
*
* Copyright (C) 1999-2002 Russell King
*/
#ifndef _ASMARM_CACHEFLUSH_H
#define _ASMARM_CACHEFLUSH_H
#include <linux/mm.h>
#include <asm/glue-cache.h>
#include <asm/shmparam.h>
#include <asm/cachetype.h>
#include <asm/outercache.h>
#define CACHE_COLOUR(vaddr) ((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT)
/*
* This flag is used to indicate that the page pointed to by a pte is clean
* and does not require cleaning before returning it to the user.
*/
#define PG_dcache_clean PG_arch_1
/*
* MM Cache Management
* ===================
*
* The arch/arm/mm/cache-*.S and arch/arm/mm/proc-*.S files
* implement these methods.
*
* Start addresses are inclusive and end addresses are exclusive;
* start addresses should be rounded down, end addresses up.
*
* See Documentation/core-api/cachetlb.rst for more information.
* Please note that the implementation of these, and the required
* effects are cache-type (VIVT/VIPT/PIPT) specific.
*
* flush_icache_all()
*
* Unconditionally clean and invalidate the entire icache.
* Currently only needed for cache-v6.S and cache-v7.S, see
* __flush_icache_all for the generic implementation.
*
* flush_kern_all()
*
* Unconditionally clean and invalidate the entire cache.
*
* flush_kern_louis()
*
* Flush data cache levels up to the level of unification
* inner shareable and invalidate the I-cache.
* Only needed from v7 onwards, falls back to flush_cache_all()
* for all other processor versions.
*
* flush_user_all()
*
* Clean and invalidate all user space cache entries
* before a change of page tables.
*
* flush_user_range(start, end, flags)
*
* Clean and invalidate a range of cache entries in the
* specified address space before a change of page tables.
* - start - user start address (inclusive, page aligned)
* - end - user end address (exclusive, page aligned)
* - flags - vma->vm_flags field
*
* coherent_kern_range(start, end)
*
* Ensure coherency between the Icache and the Dcache in the
* region described by start, end. If you have non-snooping
* Harvard caches, you need to implement this function.
* - start - virtual start address
* - end - virtual end address
*
* coherent_user_range(start, end)
*
* Ensure coherency between the Icache and the Dcache in the
* region described by start, end. If you have non-snooping
* Harvard caches, you need to implement this function.
* - start - virtual start address
* - end - virtual end address
*
* flush_kern_dcache_area(kaddr, size)
*
* Ensure that the data held in page is written back.
* - kaddr - page address
* - size - region size
*
* DMA Cache Coherency
* ===================
*
* dma_flush_range(start, end)
*
* Clean and invalidate the specified virtual address range.
* - start - virtual start address
* - end - virtual end address
*/
struct cpu_cache_fns {
void (*flush_icache_all)(void);
void (*flush_kern_all)(void);
void (*flush_kern_louis)(void);
void (*flush_user_all)(void);
void (*flush_user_range)(unsigned long, unsigned long, unsigned int);
void (*coherent_kern_range)(unsigned long, unsigned long);
int (*coherent_user_range)(unsigned long, unsigned long);
void (*flush_kern_dcache_area)(void *, size_t);
void (*dma_map_area)(const void *, size_t, int);
void (*dma_unmap_area)(const void *, size_t, int);
void (*dma_flush_range)(const void *, const void *);
} __no_randomize_layout;
/*
* Select the calling method
*/
#ifdef MULTI_CACHE
extern struct cpu_cache_fns cpu_cache;
#define __cpuc_flush_icache_all cpu_cache.flush_icache_all
#define __cpuc_flush_kern_all cpu_cache.flush_kern_all
#define __cpuc_flush_kern_louis cpu_cache.flush_kern_louis
#define __cpuc_flush_user_all cpu_cache.flush_user_all
#define __cpuc_flush_user_range cpu_cache.flush_user_range
#define __cpuc_coherent_kern_range cpu_cache.coherent_kern_range
#define __cpuc_coherent_user_range cpu_cache.coherent_user_range
#define __cpuc_flush_dcache_area cpu_cache.flush_kern_dcache_area
/*
* These are private to the dma-mapping API. Do not use directly.
* Their sole purpose is to ensure that data held in the cache
* is visible to DMA, or data written by DMA to system memory is
* visible to the CPU.
*/
#define dmac_flush_range cpu_cache.dma_flush_range
#else
extern void __cpuc_flush_icache_all(void);
extern void __cpuc_flush_kern_all(void);
extern void __cpuc_flush_kern_louis(void);
extern void __cpuc_flush_user_all(void);
extern void __cpuc_flush_user_range(unsigned long, unsigned long, unsigned int);
extern void __cpuc_coherent_kern_range(unsigned long, unsigned long);
extern int __cpuc_coherent_user_range(unsigned long, unsigned long);
extern void __cpuc_flush_dcache_area(void *, size_t);
/*
* These are private to the dma-mapping API. Do not use directly.
* Their sole purpose is to ensure that data held in the cache
* is visible to DMA, or data written by DMA to system memory is
* visible to the CPU.
*/
extern void dmac_flush_range(const void *, const void *);
#endif
/*
* Copy user data from/to a page which is mapped into a different
* processes address space. Really, we want to allow our "user
* space" model to handle this.
*/
extern void copy_to_user_page(struct vm_area_struct *, struct page *,
unsigned long, void *, const void *, unsigned long);
#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
do { \
memcpy(dst, src, len); \
} while (0)
/*
* Convert calls to our calling convention.
*/
/* Invalidate I-cache */
#define __flush_icache_all_generic() \
asm("mcr p15, 0, %0, c7, c5, 0" \
: : "r" (0));
/* Invalidate I-cache inner shareable */
#define __flush_icache_all_v7_smp() \
asm("mcr p15, 0, %0, c7, c1, 0" \
: : "r" (0));
/*
* Optimized __flush_icache_all for the common cases. Note that UP ARMv7
* will fall through to use __flush_icache_all_generic.
*/
#if (defined(CONFIG_CPU_V7) && \
(defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K))) || \
defined(CONFIG_SMP_ON_UP)
#define __flush_icache_preferred __cpuc_flush_icache_all
#elif __LINUX_ARM_ARCH__ >= 7 && defined(CONFIG_SMP)
#define __flush_icache_preferred __flush_icache_all_v7_smp
#elif __LINUX_ARM_ARCH__ == 6 && defined(CONFIG_ARM_ERRATA_411920)
#define __flush_icache_preferred __cpuc_flush_icache_all
#else
#define __flush_icache_preferred __flush_icache_all_generic
#endif
static inline void __flush_icache_all(void)
{
__flush_icache_preferred();
dsb(ishst);
}
/*
* Flush caches up to Level of Unification Inner Shareable
*/
#define flush_cache_louis() __cpuc_flush_kern_louis()
#define flush_cache_all() __cpuc_flush_kern_all()
static inline void vivt_flush_cache_mm(struct mm_struct *mm)
{
if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm)))
__cpuc_flush_user_all();
}
static inline void
vivt_flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
{
struct mm_struct *mm = vma->vm_mm;
if (!mm || cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm)))
__cpuc_flush_user_range(start & PAGE_MASK, PAGE_ALIGN(end),
vma->vm_flags);
}
static inline void vivt_flush_cache_pages(struct vm_area_struct *vma,
unsigned long user_addr, unsigned long pfn, unsigned int nr)
{
struct mm_struct *mm = vma->vm_mm;
if (!mm || cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm))) {
unsigned long addr = user_addr & PAGE_MASK;
__cpuc_flush_user_range(addr, addr + nr * PAGE_SIZE,
vma->vm_flags);
}
}
#ifndef CONFIG_CPU_CACHE_VIPT
#define flush_cache_mm(mm) \
vivt_flush_cache_mm(mm)
#define flush_cache_range(vma,start,end) \
vivt_flush_cache_range(vma,start,end)
#define flush_cache_pages(vma, addr, pfn, nr) \
vivt_flush_cache_pages(vma, addr, pfn, nr)
#else
void flush_cache_mm(struct mm_struct *mm);
void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end);
void flush_cache_pages(struct vm_area_struct *vma, unsigned long user_addr,
unsigned long pfn, unsigned int nr);
#endif
#define flush_cache_dup_mm(mm) flush_cache_mm(mm)
#define flush_cache_page(vma, addr, pfn) flush_cache_pages(vma, addr, pfn, 1)
/*
* flush_icache_user_range is used when we want to ensure that the
* Harvard caches are synchronised for the user space address range.
* This is used for the ARM private sys_cacheflush system call.
*/
#define flush_icache_user_range(s,e) __cpuc_coherent_user_range(s,e)
/*
* Perform necessary cache operations to ensure that data previously
* stored within this range of addresses can be executed by the CPU.
*/
#define flush_icache_range(s,e) __cpuc_coherent_kern_range(s,e)
/*
* Perform necessary cache operations to ensure that the TLB will
* see data written in the specified area.
*/
#define clean_dcache_area(start,size) cpu_dcache_clean_area(start, size)
/*
* flush_dcache_page is used when the kernel has written to the page
* cache page at virtual address page->virtual.
*
* If this page isn't mapped (ie, folio_mapping == NULL), or it might
* have userspace mappings, then we _must_ always clean + invalidate
* the dcache entries associated with the kernel mapping.
*
* Otherwise we can defer the operation, and clean the cache when we are
* about to change to user space. This is the same method as used on SPARC64.
* See update_mmu_cache for the user space part.
*/
#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
void flush_dcache_page(struct page *);
void flush_dcache_folio(struct folio *folio);
#define flush_dcache_folio flush_dcache_folio
#define ARCH_IMPLEMENTS_FLUSH_KERNEL_VMAP_RANGE 1
static inline void flush_kernel_vmap_range(void *addr, int size)
{
if ((cache_is_vivt() || cache_is_vipt_aliasing()))
__cpuc_flush_dcache_area(addr, (size_t)size);
}
static inline void invalidate_kernel_vmap_range(void *addr, int size)
{
if ((cache_is_vivt() || cache_is_vipt_aliasing()))
__cpuc_flush_dcache_area(addr, (size_t)size);
}
#define ARCH_HAS_FLUSH_ANON_PAGE
static inline void flush_anon_page(struct vm_area_struct *vma,
struct page *page, unsigned long vmaddr)
{
extern void __flush_anon_page(struct vm_area_struct *vma,
struct page *, unsigned long);
if (PageAnon(page))
__flush_anon_page(vma, page, vmaddr);
}
#define flush_dcache_mmap_lock(mapping) xa_lock_irq(&mapping->i_pages)
#define flush_dcache_mmap_unlock(mapping) xa_unlock_irq(&mapping->i_pages)
/*
* flush_cache_vmap() is used when creating mappings (eg, via vmap,
* vmalloc, ioremap etc) in kernel space for pages. On non-VIPT
* caches, since the direct-mappings of these pages may contain cached
* data, we need to do a full cache flush to ensure that writebacks
* don't corrupt data placed into these pages via the new mappings.
*/
static inline void flush_cache_vmap(unsigned long start, unsigned long end)
{
if (!cache_is_vipt_nonaliasing())
flush_cache_all();
else
/*
* set_pte_at() called from vmap_pte_range() does not
* have a DSB after cleaning the cache line.
*/
dsb(ishst);
}
#define flush_cache_vmap_early(start, end) do { } while (0)
static inline void flush_cache_vunmap(unsigned long start, unsigned long end)
{
if (!cache_is_vipt_nonaliasing())
flush_cache_all();
}
/*
* Memory synchronization helpers for mixed cached vs non cached accesses.
*
* Some synchronization algorithms have to set states in memory with the
* cache enabled or disabled depending on the code path. It is crucial
* to always ensure proper cache maintenance to update main memory right
* away in that case.
*
* Any cached write must be followed by a cache clean operation.
* Any cached read must be preceded by a cache invalidate operation.
* Yet, in the read case, a cache flush i.e. atomic clean+invalidate
* operation is needed to avoid discarding possible concurrent writes to the
* accessed memory.
*
* Also, in order to prevent a cached writer from interfering with an
* adjacent non-cached writer, each state variable must be located to
* a separate cache line.
*/
/*
* This needs to be >= the max cache writeback size of all
* supported platforms included in the current kernel configuration.
* This is used to align state variables to their own cache lines.
*/
#define __CACHE_WRITEBACK_ORDER 6 /* guessed from existing platforms */
#define __CACHE_WRITEBACK_GRANULE (1 << __CACHE_WRITEBACK_ORDER)
/*
* There is no __cpuc_clean_dcache_area but we use it anyway for
* code intent clarity, and alias it to __cpuc_flush_dcache_area.
*/
#define __cpuc_clean_dcache_area __cpuc_flush_dcache_area
/*
* Ensure preceding writes to *p by this CPU are visible to
* subsequent reads by other CPUs:
*/
static inline void __sync_cache_range_w(volatile void *p, size_t size)
{
char *_p = (char *)p;
__cpuc_clean_dcache_area(_p, size);
outer_clean_range(__pa(_p), __pa(_p + size));
}
/*
* Ensure preceding writes to *p by other CPUs are visible to
* subsequent reads by this CPU. We must be careful not to
* discard data simultaneously written by another CPU, hence the
* usage of flush rather than invalidate operations.
*/
static inline void __sync_cache_range_r(volatile void *p, size_t size)
{
char *_p = (char *)p;
#ifdef CONFIG_OUTER_CACHE
if (outer_cache.flush_range) {
/*
* Ensure dirty data migrated from other CPUs into our cache
* are cleaned out safely before the outer cache is cleaned:
*/
__cpuc_clean_dcache_area(_p, size);
/* Clean and invalidate stale data for *p from outer ... */
outer_flush_range(__pa(_p), __pa(_p + size));
}
#endif
/* ... and inner cache: */
__cpuc_flush_dcache_area(_p, size);
}
#define sync_cache_w(ptr) __sync_cache_range_w(ptr, sizeof *(ptr))
#define sync_cache_r(ptr) __sync_cache_range_r(ptr, sizeof *(ptr))
/*
* Disabling cache access for one CPU in an ARMv7 SMP system is tricky.
* To do so we must:
*
* - Clear the SCTLR.C bit to prevent further cache allocations
* - Flush the desired level of cache
* - Clear the ACTLR "SMP" bit to disable local coherency
*
* ... and so without any intervening memory access in between those steps,
* not even to the stack.
*
* WARNING -- After this has been called:
*
* - No ldrex/strex (and similar) instructions must be used.
* - The CPU is obviously no longer coherent with the other CPUs.
* - This is unlikely to work as expected if Linux is running non-secure.
*
* Note:
*
* - This is known to apply to several ARMv7 processor implementations,
* however some exceptions may exist. Caveat emptor.
*
* - The clobber list is dictated by the call to v7_flush_dcache_*.
*/
#define v7_exit_coherency_flush(level) \
asm volatile( \
".arch armv7-a \n\t" \
"mrc p15, 0, r0, c1, c0, 0 @ get SCTLR \n\t" \
"bic r0, r0, #"__stringify(CR_C)" \n\t" \
"mcr p15, 0, r0, c1, c0, 0 @ set SCTLR \n\t" \
"isb \n\t" \
"bl v7_flush_dcache_"__stringify(level)" \n\t" \
"mrc p15, 0, r0, c1, c0, 1 @ get ACTLR \n\t" \
"bic r0, r0, #(1 << 6) @ disable local coherency \n\t" \
"mcr p15, 0, r0, c1, c0, 1 @ set ACTLR \n\t" \
"isb \n\t" \
"dsb" \
: : : "r0","r1","r2","r3","r4","r5","r6", \
"r9","r10","ip","lr","memory" )
void flush_uprobe_xol_access(struct page *page, unsigned long uaddr,
void *kaddr, unsigned long len);
#ifdef CONFIG_CPU_ICACHE_MISMATCH_WORKAROUND
void check_cpu_icache_size(int cpuid);
#else
static inline void check_cpu_icache_size(int cpuid) { }
#endif
#endif
@@ -0,0 +1,114 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_ARM_CACHETYPE_H
#define __ASM_ARM_CACHETYPE_H
#define CACHEID_VIVT (1 << 0)
#define CACHEID_VIPT_NONALIASING (1 << 1)
#define CACHEID_VIPT_ALIASING (1 << 2)
#define CACHEID_VIPT (CACHEID_VIPT_ALIASING|CACHEID_VIPT_NONALIASING)
#define CACHEID_ASID_TAGGED (1 << 3)
#define CACHEID_VIPT_I_ALIASING (1 << 4)
#define CACHEID_PIPT (1 << 5)
extern unsigned int cacheid;
#define cache_is_vivt() cacheid_is(CACHEID_VIVT)
#define cache_is_vipt() cacheid_is(CACHEID_VIPT)
#define cache_is_vipt_nonaliasing() cacheid_is(CACHEID_VIPT_NONALIASING)
#define cache_is_vipt_aliasing() cacheid_is(CACHEID_VIPT_ALIASING)
#define icache_is_vivt_asid_tagged() cacheid_is(CACHEID_ASID_TAGGED)
#define icache_is_vipt_aliasing() cacheid_is(CACHEID_VIPT_I_ALIASING)
#define icache_is_pipt() cacheid_is(CACHEID_PIPT)
#define cpu_dcache_is_aliasing() (cache_is_vivt() || cache_is_vipt_aliasing())
/*
* __LINUX_ARM_ARCH__ is the minimum supported CPU architecture
* Mask out support which will never be present on newer CPUs.
* - v6+ is never VIVT
* - v7+ VIPT never aliases on D-side
*/
#if __LINUX_ARM_ARCH__ >= 7
#define __CACHEID_ARCH_MIN (CACHEID_VIPT_NONALIASING |\
CACHEID_ASID_TAGGED |\
CACHEID_VIPT_I_ALIASING |\
CACHEID_PIPT)
#elif __LINUX_ARM_ARCH__ >= 6
#define __CACHEID_ARCH_MIN (~CACHEID_VIVT)
#else
#define __CACHEID_ARCH_MIN (~0)
#endif
/*
* Mask out support which isn't configured
*/
#if defined(CONFIG_CPU_CACHE_VIVT) && !defined(CONFIG_CPU_CACHE_VIPT)
#define __CACHEID_ALWAYS (CACHEID_VIVT)
#define __CACHEID_NEVER (~CACHEID_VIVT)
#elif !defined(CONFIG_CPU_CACHE_VIVT) && defined(CONFIG_CPU_CACHE_VIPT)
#define __CACHEID_ALWAYS (0)
#define __CACHEID_NEVER (CACHEID_VIVT)
#else
#define __CACHEID_ALWAYS (0)
#define __CACHEID_NEVER (0)
#endif
static inline unsigned int __attribute__((pure)) cacheid_is(unsigned int mask)
{
return (__CACHEID_ALWAYS & mask) |
(~__CACHEID_NEVER & __CACHEID_ARCH_MIN & mask & cacheid);
}
#define CSSELR_ICACHE 1
#define CSSELR_DCACHE 0
#define CSSELR_L1 (0 << 1)
#define CSSELR_L2 (1 << 1)
#define CSSELR_L3 (2 << 1)
#define CSSELR_L4 (3 << 1)
#define CSSELR_L5 (4 << 1)
#define CSSELR_L6 (5 << 1)
#define CSSELR_L7 (6 << 1)
#ifndef CONFIG_CPU_V7M
static inline void set_csselr(unsigned int cache_selector)
{
asm volatile("mcr p15, 2, %0, c0, c0, 0" : : "r" (cache_selector));
}
static inline unsigned int read_ccsidr(void)
{
unsigned int val;
asm volatile("mrc p15, 1, %0, c0, c0, 0" : "=r" (val));
return val;
}
static inline unsigned int read_clidr(void)
{
unsigned int val;
asm volatile("mrc p15, 1, %0, c0, c0, 1" : "=r" (val));
return val;
}
#else /* CONFIG_CPU_V7M */
#include <linux/io.h>
#include "asm/v7m.h"
static inline void set_csselr(unsigned int cache_selector)
{
writel(cache_selector, BASEADDR_V7M_SCB + V7M_SCB_CTR);
}
static inline unsigned int read_ccsidr(void)
{
return readl(BASEADDR_V7M_SCB + V7M_SCB_CCSIDR);
}
static inline unsigned int read_clidr(void)
{
return readl(BASEADDR_V7M_SCB + V7M_SCB_CLIDR);
}
#endif
#endif
+166
View File
@@ -0,0 +1,166 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* arch/arm/include/asm/checksum.h
*
* IP checksum routines
*
* Copyright (C) Original authors of ../asm-i386/checksum.h
* Copyright (C) 1996-1999 Russell King
*/
#ifndef __ASM_ARM_CHECKSUM_H
#define __ASM_ARM_CHECKSUM_H
#include <linux/in6.h>
#include <linux/uaccess.h>
/*
* computes the checksum of a memory block at buff, length len,
* and adds in "sum" (32-bit)
*
* returns a 32-bit number suitable for feeding into itself
* or csum_tcpudp_magic
*
* this function must be called with even lengths, except
* for the last fragment, which may be odd
*
* it's best to have buff aligned on a 32-bit boundary
*/
__wsum csum_partial(const void *buff, int len, __wsum sum);
/*
* the same as csum_partial, but copies from src while it
* checksums, and handles user-space pointer exceptions correctly, when needed.
*
* here even more important to align src and dst on a 32-bit (or even
* better 64-bit) boundary
*/
__wsum
csum_partial_copy_nocheck(const void *src, void *dst, int len);
__wsum
csum_partial_copy_from_user(const void __user *src, void *dst, int len);
#define _HAVE_ARCH_COPY_AND_CSUM_FROM_USER
#define _HAVE_ARCH_CSUM_AND_COPY
static inline
__wsum csum_and_copy_from_user(const void __user *src, void *dst, int len)
{
if (!access_ok(src, len))
return 0;
return csum_partial_copy_from_user(src, dst, len);
}
/*
* Fold a partial checksum without adding pseudo headers
*/
static inline __sum16 csum_fold(__wsum sum)
{
__asm__(
"add %0, %1, %1, ror #16 @ csum_fold"
: "=r" (sum)
: "r" (sum)
: "cc");
return (__force __sum16)(~(__force u32)sum >> 16);
}
/*
* This is a version of ip_compute_csum() optimized for IP headers,
* which always checksum on 4 octet boundaries.
*/
static inline __sum16
ip_fast_csum(const void *iph, unsigned int ihl)
{
unsigned int tmp1;
__wsum sum;
__asm__ __volatile__(
"ldr %0, [%1], #4 @ ip_fast_csum \n\
ldr %3, [%1], #4 \n\
sub %2, %2, #5 \n\
adds %0, %0, %3 \n\
ldr %3, [%1], #4 \n\
adcs %0, %0, %3 \n\
ldr %3, [%1], #4 \n\
1: adcs %0, %0, %3 \n\
ldr %3, [%1], #4 \n\
tst %2, #15 @ do this carefully \n\
subne %2, %2, #1 @ without destroying \n\
bne 1b @ the carry flag \n\
adcs %0, %0, %3 \n\
adc %0, %0, #0"
: "=r" (sum), "=r" (iph), "=r" (ihl), "=r" (tmp1)
: "1" (iph), "2" (ihl)
: "cc", "memory");
return csum_fold(sum);
}
static inline __wsum
csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len,
__u8 proto, __wsum sum)
{
u32 lenprot = len + proto;
if (__builtin_constant_p(sum) && sum == 0) {
__asm__(
"adds %0, %1, %2 @ csum_tcpudp_nofold0 \n\t"
#ifdef __ARMEB__
"adcs %0, %0, %3 \n\t"
#else
"adcs %0, %0, %3, ror #8 \n\t"
#endif
"adc %0, %0, #0"
: "=&r" (sum)
: "r" (daddr), "r" (saddr), "r" (lenprot)
: "cc");
} else {
__asm__(
"adds %0, %1, %2 @ csum_tcpudp_nofold \n\t"
"adcs %0, %0, %3 \n\t"
#ifdef __ARMEB__
"adcs %0, %0, %4 \n\t"
#else
"adcs %0, %0, %4, ror #8 \n\t"
#endif
"adc %0, %0, #0"
: "=&r"(sum)
: "r" (sum), "r" (daddr), "r" (saddr), "r" (lenprot)
: "cc");
}
return sum;
}
/*
* computes the checksum of the TCP/UDP pseudo-header
* returns a 16-bit checksum, already complemented
*/
static inline __sum16
csum_tcpudp_magic(__be32 saddr, __be32 daddr, __u32 len,
__u8 proto, __wsum sum)
{
return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
}
/*
* this routine is used for miscellaneous IP-like checksums, mainly
* in icmp.c
*/
static inline __sum16
ip_compute_csum(const void *buff, int len)
{
return csum_fold(csum_partial(buff, len, 0));
}
#define _HAVE_ARCH_IPV6_CSUM
extern __wsum
__csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, __be32 len,
__be32 proto, __wsum sum);
static inline __sum16
csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr,
__u32 len, __u8 proto, __wsum sum)
{
return csum_fold(__csum_ipv6_magic(saddr, daddr, htonl(len),
htonl(proto), sum));
}
#endif
@@ -0,0 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_CLOCKSOURCE_H
#define _ASM_CLOCKSOURCE_H
#include <asm/vdso/clocksource.h>
#endif /* _ASM_CLOCKSOURCE_H */
+285
View File
@@ -0,0 +1,285 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_ARM_CMPXCHG_H
#define __ASM_ARM_CMPXCHG_H
#include <linux/irqflags.h>
#include <linux/prefetch.h>
#include <asm/barrier.h>
#include <linux/cmpxchg-emu.h>
#if defined(CONFIG_CPU_SA1100) || defined(CONFIG_CPU_SA110)
/*
* On the StrongARM, "swp" is terminally broken since it bypasses the
* cache totally. This means that the cache becomes inconsistent, and,
* since we use normal loads/stores as well, this is really bad.
* Typically, this causes oopsen in filp_close, but could have other,
* more disastrous effects. There are two work-arounds:
* 1. Disable interrupts and emulate the atomic swap
* 2. Clean the cache, perform atomic swap, flush the cache
*
* We choose (1) since its the "easiest" to achieve here and is not
* dependent on the processor type.
*
* NOTE that this solution won't work on an SMP system, so explcitly
* forbid it here.
*/
#define swp_is_buggy
#endif
static inline unsigned long
__arch_xchg(unsigned long x, volatile void *ptr, int size)
{
extern void __bad_xchg(volatile void *, int);
unsigned long ret;
#ifdef swp_is_buggy
unsigned long flags;
#endif
#if __LINUX_ARM_ARCH__ >= 6
unsigned int tmp;
#endif
prefetchw((const void *)ptr);
switch (size) {
#if __LINUX_ARM_ARCH__ >= 6
#ifndef CONFIG_CPU_V6 /* MIN ARCH >= V6K */
case 1:
asm volatile("@ __xchg1\n"
"1: ldrexb %0, [%3]\n"
" strexb %1, %2, [%3]\n"
" teq %1, #0\n"
" bne 1b"
: "=&r" (ret), "=&r" (tmp)
: "r" (x), "r" (ptr)
: "memory", "cc");
break;
case 2:
asm volatile("@ __xchg2\n"
"1: ldrexh %0, [%3]\n"
" strexh %1, %2, [%3]\n"
" teq %1, #0\n"
" bne 1b"
: "=&r" (ret), "=&r" (tmp)
: "r" (x), "r" (ptr)
: "memory", "cc");
break;
#endif
case 4:
asm volatile("@ __xchg4\n"
"1: ldrex %0, [%3]\n"
" strex %1, %2, [%3]\n"
" teq %1, #0\n"
" bne 1b"
: "=&r" (ret), "=&r" (tmp)
: "r" (x), "r" (ptr)
: "memory", "cc");
break;
#elif defined(swp_is_buggy)
#ifdef CONFIG_SMP
#error SMP is not supported on this platform
#endif
case 1:
raw_local_irq_save(flags);
ret = *(volatile unsigned char *)ptr;
*(volatile unsigned char *)ptr = x;
raw_local_irq_restore(flags);
break;
case 4:
raw_local_irq_save(flags);
ret = *(volatile unsigned long *)ptr;
*(volatile unsigned long *)ptr = x;
raw_local_irq_restore(flags);
break;
#else
case 1:
asm volatile("@ __xchg1\n"
" swpb %0, %1, [%2]"
: "=&r" (ret)
: "r" (x), "r" (ptr)
: "memory", "cc");
break;
case 4:
asm volatile("@ __xchg4\n"
" swp %0, %1, [%2]"
: "=&r" (ret)
: "r" (x), "r" (ptr)
: "memory", "cc");
break;
#endif
default:
/* Cause a link-time error, the xchg() size is not supported */
__bad_xchg(ptr, size), ret = 0;
break;
}
return ret;
}
#define arch_xchg_relaxed(ptr, x) ({ \
(__typeof__(*(ptr)))__arch_xchg((unsigned long)(x), (ptr), \
sizeof(*(ptr))); \
})
#include <asm-generic/cmpxchg-local.h>
#if __LINUX_ARM_ARCH__ < 6
/* min ARCH < ARMv6 */
#ifdef CONFIG_SMP
#error "SMP is not supported on this platform"
#endif
#define arch_xchg arch_xchg_relaxed
/*
* cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
* them available.
*/
#define arch_cmpxchg_local(ptr, o, n) ({ \
(__typeof(*ptr))__generic_cmpxchg_local((ptr), \
(unsigned long)(o), \
(unsigned long)(n), \
sizeof(*(ptr))); \
})
#define arch_cmpxchg64_local(ptr, o, n) __generic_cmpxchg64_local((ptr), (o), (n))
#include <asm-generic/cmpxchg.h>
#else /* min ARCH >= ARMv6 */
extern void __bad_cmpxchg(volatile void *ptr, int size);
/*
* cmpxchg only support 32-bits operands on ARMv6.
*/
static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
unsigned long new, int size)
{
unsigned long oldval, res;
prefetchw((const void *)ptr);
switch (size) {
#ifdef CONFIG_CPU_V6 /* ARCH == ARMv6 */
case 1:
oldval = cmpxchg_emu_u8((volatile u8 *)ptr, old, new);
break;
#else /* min ARCH > ARMv6 */
case 1:
do {
asm volatile("@ __cmpxchg1\n"
" ldrexb %1, [%2]\n"
" mov %0, #0\n"
" teq %1, %3\n"
" strexbeq %0, %4, [%2]\n"
: "=&r" (res), "=&r" (oldval)
: "r" (ptr), "Ir" (old), "r" (new)
: "memory", "cc");
} while (res);
break;
case 2:
do {
asm volatile("@ __cmpxchg1\n"
" ldrexh %1, [%2]\n"
" mov %0, #0\n"
" teq %1, %3\n"
" strexheq %0, %4, [%2]\n"
: "=&r" (res), "=&r" (oldval)
: "r" (ptr), "Ir" (old), "r" (new)
: "memory", "cc");
} while (res);
break;
#endif
case 4:
do {
asm volatile("@ __cmpxchg4\n"
" ldrex %1, [%2]\n"
" mov %0, #0\n"
" teq %1, %3\n"
" strexeq %0, %4, [%2]\n"
: "=&r" (res), "=&r" (oldval)
: "r" (ptr), "Ir" (old), "r" (new)
: "memory", "cc");
} while (res);
break;
default:
__bad_cmpxchg(ptr, size);
oldval = 0;
}
return oldval;
}
#define arch_cmpxchg_relaxed(ptr,o,n) ({ \
(__typeof__(*(ptr)))__cmpxchg((ptr), \
(unsigned long)(o), \
(unsigned long)(n), \
sizeof(*(ptr))); \
})
static inline unsigned long __cmpxchg_local(volatile void *ptr,
unsigned long old,
unsigned long new, int size)
{
unsigned long ret;
switch (size) {
#ifdef CONFIG_CPU_V6 /* min ARCH == ARMv6 */
case 1:
case 2:
ret = __generic_cmpxchg_local(ptr, old, new, size);
break;
#endif
default:
ret = __cmpxchg(ptr, old, new, size);
}
return ret;
}
#define arch_cmpxchg_local(ptr, o, n) ({ \
(__typeof(*ptr))__cmpxchg_local((ptr), \
(unsigned long)(o), \
(unsigned long)(n), \
sizeof(*(ptr))); \
})
static inline unsigned long long __cmpxchg64(unsigned long long *ptr,
unsigned long long old,
unsigned long long new)
{
unsigned long long oldval;
unsigned long res;
prefetchw(ptr);
__asm__ __volatile__(
"1: ldrexd %1, %H1, [%3]\n"
" teq %1, %4\n"
" teqeq %H1, %H4\n"
" bne 2f\n"
" strexd %0, %5, %H5, [%3]\n"
" teq %0, #0\n"
" bne 1b\n"
"2:"
: "=&r" (res), "=&r" (oldval), "+Qo" (*ptr)
: "r" (ptr), "r" (old), "r" (new)
: "cc");
return oldval;
}
#define arch_cmpxchg64_relaxed(ptr, o, n) ({ \
(__typeof__(*(ptr)))__cmpxchg64((ptr), \
(unsigned long long)(o), \
(unsigned long long)(n)); \
})
#define arch_cmpxchg64_local(ptr, o, n) arch_cmpxchg64_relaxed((ptr), (o), (n))
#endif /* __LINUX_ARM_ARCH__ >= 6 */
#endif /* __ASM_ARM_CMPXCHG_H */
@@ -0,0 +1,29 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_ARM_COMPILER_H
#define __ASM_ARM_COMPILER_H
/*
* This is used to ensure the compiler did actually allocate the register we
* asked it for some inline assembly sequences. Apparently we can't trust
* the compiler from one version to another so a bit of paranoia won't hurt.
* This string is meant to be concatenated with the inline asm string and
* will cause compilation to stop on mismatch.
* (for details, see gcc PR 15089)
* For compatibility with clang, we have to specifically take the equivalence
* of 'r11' <-> 'fp' and 'r12' <-> 'ip' into account as well.
*/
#define __asmeq(x, y) \
".ifnc " x "," y "; " \
".ifnc " x y ",fpr11; " \
".ifnc " x y ",r11fp; " \
".ifnc " x y ",ipr12; " \
".ifnc " x y ",r12ip; " \
".err; " \
".endif; " \
".endif; " \
".endif; " \
".endif; " \
".endif\n\t"
#endif /* __ASM_ARM_COMPILER_H */
+122
View File
@@ -0,0 +1,122 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_ARM_CP15_H
#define __ASM_ARM_CP15_H
#include <asm/barrier.h>
/*
* CR1 bits (CP#15 CR1)
*/
#define CR_M (1 << 0) /* MMU enable */
#define CR_A (1 << 1) /* Alignment abort enable */
#define CR_C (1 << 2) /* Dcache enable */
#define CR_W (1 << 3) /* Write buffer enable */
#define CR_P (1 << 4) /* 32-bit exception handler */
#define CR_D (1 << 5) /* 32-bit data address range */
#define CR_L (1 << 6) /* Implementation defined */
#define CR_B (1 << 7) /* Big endian */
#define CR_S (1 << 8) /* System MMU protection */
#define CR_R (1 << 9) /* ROM MMU protection */
#define CR_F (1 << 10) /* Implementation defined */
#define CR_Z (1 << 11) /* Implementation defined */
#define CR_I (1 << 12) /* Icache enable */
#define CR_V (1 << 13) /* Vectors relocated to 0xffff0000 */
#define CR_RR (1 << 14) /* Round Robin cache replacement */
#define CR_L4 (1 << 15) /* LDR pc can set T bit */
#define CR_DT (1 << 16)
#ifdef CONFIG_MMU
#define CR_HA (1 << 17) /* Hardware management of Access Flag */
#else
#define CR_BR (1 << 17) /* MPU Background region enable (PMSA) */
#endif
#define CR_IT (1 << 18)
#define CR_ST (1 << 19)
#define CR_FI (1 << 21) /* Fast interrupt (lower latency mode) */
#define CR_U (1 << 22) /* Unaligned access operation */
#define CR_XP (1 << 23) /* Extended page tables */
#define CR_VE (1 << 24) /* Vectored interrupts */
#define CR_EE (1 << 25) /* Exception (Big) Endian */
#define CR_TRE (1 << 28) /* TEX remap enable */
#define CR_AFE (1 << 29) /* Access flag enable */
#define CR_TE (1 << 30) /* Thumb exception enable */
#ifndef __ASSEMBLY__
#if __LINUX_ARM_ARCH__ >= 4
#define vectors_high() (get_cr() & CR_V)
#else
#define vectors_high() (0)
#endif
#ifdef CONFIG_CPU_CP15
#include <asm/vdso/cp15.h>
extern unsigned long cr_alignment; /* defined in entry-armv.S */
static inline unsigned long get_cr(void)
{
unsigned long val;
asm("mrc p15, 0, %0, c1, c0, 0 @ get CR" : "=r" (val) : : "cc");
return val;
}
static inline void set_cr(unsigned long val)
{
asm volatile("mcr p15, 0, %0, c1, c0, 0 @ set CR"
: : "r" (val) : "cc");
isb();
}
static inline unsigned int get_auxcr(void)
{
unsigned int val;
asm("mrc p15, 0, %0, c1, c0, 1 @ get AUXCR" : "=r" (val));
return val;
}
static inline void set_auxcr(unsigned int val)
{
asm volatile("mcr p15, 0, %0, c1, c0, 1 @ set AUXCR"
: : "r" (val));
isb();
}
#define CPACC_FULL(n) (3 << (n * 2))
#define CPACC_SVC(n) (1 << (n * 2))
#define CPACC_DISABLE(n) (0 << (n * 2))
static inline unsigned int get_copro_access(void)
{
unsigned int val;
asm("mrc p15, 0, %0, c1, c0, 2 @ get copro access"
: "=r" (val) : : "cc");
return val;
}
static inline void set_copro_access(unsigned int val)
{
asm volatile("mcr p15, 0, %0, c1, c0, 2 @ set copro access"
: : "r" (val) : "cc");
isb();
}
#else /* ifdef CONFIG_CPU_CP15 */
/*
* cr_alignment is tightly coupled to cp15 (at least in the minds of the
* developers). Yielding 0 for machines without a cp15 (and making it
* read-only) is fine for most cases and saves quite some #ifdeffery.
*/
#define cr_alignment UL(0)
static inline unsigned long get_cr(void)
{
return 0;
}
#endif /* ifdef CONFIG_CPU_CP15 / else */
#endif /* ifndef __ASSEMBLY__ */
#endif
+22
View File
@@ -0,0 +1,22 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* arch/arm/include/asm/cpu.h
*
* Copyright (C) 2004-2005 ARM Ltd.
*/
#ifndef __ASM_ARM_CPU_H
#define __ASM_ARM_CPU_H
#include <linux/percpu.h>
#include <linux/cpu.h>
struct cpuinfo_arm {
u32 cpuid;
#ifdef CONFIG_SMP
unsigned int loops_per_jiffy;
#endif
};
DECLARE_PER_CPU(struct cpuinfo_arm, cpu_data);
#endif
@@ -0,0 +1,35 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2017 Linaro Ltd. <ard.biesheuvel@linaro.org>
*/
#ifndef __ASM_CPUFEATURE_H
#define __ASM_CPUFEATURE_H
#include <linux/log2.h>
#include <asm/hwcap.h>
/*
* Due to the fact that ELF_HWCAP is a 32-bit type on ARM, and given the number
* of optional CPU features it defines, ARM's CPU hardware capability bits have
* been distributed over separate elf_hwcap and elf_hwcap2 variables, each of
* which covers a subset of the available CPU features.
*
* Currently, only a few of those are suitable for automatic module loading
* (which is the primary use case of this facility) and those happen to be all
* covered by HWCAP2. So let's only cover those via the cpu_feature()
* convenience macro for now (which is used by module_cpu_feature_match()).
* However, all capabilities are exposed via the modalias, and can be matched
* using an explicit MODULE_DEVICE_TABLE() that uses __hwcap_feature() directly.
*/
#define MAX_CPU_FEATURES 64
#define __hwcap_feature(x) ilog2(HWCAP_ ## x)
#define __hwcap2_feature(x) (32 + ilog2(HWCAP2_ ## x))
#define cpu_feature(x) __hwcap2_feature(x)
static inline bool cpu_have_feature(unsigned int num)
{
return num < 32 ? elf_hwcap & BIT(num) : elf_hwcap2 & BIT(num - 32);
}
#endif
@@ -0,0 +1,58 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_ARM_CPUIDLE_H
#define __ASM_ARM_CPUIDLE_H
#include <asm/proc-fns.h>
#ifdef CONFIG_CPU_IDLE
extern int arm_cpuidle_simple_enter(struct cpuidle_device *dev,
struct cpuidle_driver *drv, int index);
#define __cpuidle_method_section __used __section("__cpuidle_method_of_table")
#else
static inline int arm_cpuidle_simple_enter(struct cpuidle_device *dev,
struct cpuidle_driver *drv, int index) { return -ENODEV; }
#define __cpuidle_method_section __maybe_unused /* drop silently */
#endif
/* Common ARM WFI state */
#define ARM_CPUIDLE_WFI_STATE_PWR(p) {\
.enter = arm_cpuidle_simple_enter,\
.exit_latency = 1,\
.target_residency = 1,\
.power_usage = p,\
.name = "WFI",\
.desc = "ARM WFI",\
}
/*
* in case power_specified == 1, give a default WFI power value needed
* by some governors
*/
#define ARM_CPUIDLE_WFI_STATE ARM_CPUIDLE_WFI_STATE_PWR(UINT_MAX)
struct device_node;
struct cpuidle_ops {
int (*suspend)(unsigned long arg);
int (*init)(struct device_node *, int cpu);
};
struct of_cpuidle_method {
const char *method;
const struct cpuidle_ops *ops;
};
#define CPUIDLE_METHOD_OF_DECLARE(name, _method, _ops) \
static const struct of_cpuidle_method __cpuidle_method_of_table_##name \
__cpuidle_method_section = { .method = _method, .ops = _ops }
extern int arm_cpuidle_suspend(int index);
extern int arm_cpuidle_init(int cpu);
struct arm_cpuidle_irq_context { };
#define arm_cpuidle_save_irq_context(c) (void)c
#define arm_cpuidle_restore_irq_context(c) (void)c
#endif
+348
View File
@@ -0,0 +1,348 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_ARM_CPUTYPE_H
#define __ASM_ARM_CPUTYPE_H
#define CPUID_ID 0
#define CPUID_CACHETYPE 1
#define CPUID_TCM 2
#define CPUID_TLBTYPE 3
#define CPUID_MPUIR 4
#define CPUID_MPIDR 5
#define CPUID_REVIDR 6
#ifdef CONFIG_CPU_V7M
#define CPUID_EXT_PFR0 0x40
#define CPUID_EXT_PFR1 0x44
#define CPUID_EXT_DFR0 0x48
#define CPUID_EXT_AFR0 0x4c
#define CPUID_EXT_MMFR0 0x50
#define CPUID_EXT_MMFR1 0x54
#define CPUID_EXT_MMFR2 0x58
#define CPUID_EXT_MMFR3 0x5c
#define CPUID_EXT_ISAR0 0x60
#define CPUID_EXT_ISAR1 0x64
#define CPUID_EXT_ISAR2 0x68
#define CPUID_EXT_ISAR3 0x6c
#define CPUID_EXT_ISAR4 0x70
#define CPUID_EXT_ISAR5 0x74
#define CPUID_EXT_ISAR6 0x7c
#define CPUID_EXT_PFR2 0x90
#else
#define CPUID_EXT_PFR0 "c1, 0"
#define CPUID_EXT_PFR1 "c1, 1"
#define CPUID_EXT_DFR0 "c1, 2"
#define CPUID_EXT_AFR0 "c1, 3"
#define CPUID_EXT_MMFR0 "c1, 4"
#define CPUID_EXT_MMFR1 "c1, 5"
#define CPUID_EXT_MMFR2 "c1, 6"
#define CPUID_EXT_MMFR3 "c1, 7"
#define CPUID_EXT_ISAR0 "c2, 0"
#define CPUID_EXT_ISAR1 "c2, 1"
#define CPUID_EXT_ISAR2 "c2, 2"
#define CPUID_EXT_ISAR3 "c2, 3"
#define CPUID_EXT_ISAR4 "c2, 4"
#define CPUID_EXT_ISAR5 "c2, 5"
#define CPUID_EXT_ISAR6 "c2, 7"
#define CPUID_EXT_PFR2 "c3, 4"
#endif
#define MPIDR_SMP_BITMASK (0x3 << 30)
#define MPIDR_SMP_VALUE (0x2 << 30)
#define MPIDR_MT_BITMASK (0x1 << 24)
#define MPIDR_HWID_BITMASK 0xFFFFFF
#define MPIDR_INVALID (~MPIDR_HWID_BITMASK)
#define MPIDR_LEVEL_BITS 8
#define MPIDR_LEVEL_MASK ((1 << MPIDR_LEVEL_BITS) - 1)
#define MPIDR_LEVEL_SHIFT(level) (MPIDR_LEVEL_BITS * level)
#define MPIDR_AFFINITY_LEVEL(mpidr, level) \
((mpidr >> (MPIDR_LEVEL_BITS * level)) & MPIDR_LEVEL_MASK)
#define ARM_CPU_IMP_ARM 0x41
#define ARM_CPU_IMP_BRCM 0x42
#define ARM_CPU_IMP_DEC 0x44
#define ARM_CPU_IMP_INTEL 0x69
/* ARM implemented processors */
#define ARM_CPU_PART_ARM1136 0x4100b360
#define ARM_CPU_PART_ARM1156 0x4100b560
#define ARM_CPU_PART_ARM1176 0x4100b760
#define ARM_CPU_PART_ARM11MPCORE 0x4100b020
#define ARM_CPU_PART_CORTEX_A8 0x4100c080
#define ARM_CPU_PART_CORTEX_A9 0x4100c090
#define ARM_CPU_PART_CORTEX_A5 0x4100c050
#define ARM_CPU_PART_CORTEX_A7 0x4100c070
#define ARM_CPU_PART_CORTEX_A12 0x4100c0d0
#define ARM_CPU_PART_CORTEX_A17 0x4100c0e0
#define ARM_CPU_PART_CORTEX_A15 0x4100c0f0
#define ARM_CPU_PART_CORTEX_A53 0x4100d030
#define ARM_CPU_PART_CORTEX_A57 0x4100d070
#define ARM_CPU_PART_CORTEX_A72 0x4100d080
#define ARM_CPU_PART_CORTEX_A73 0x4100d090
#define ARM_CPU_PART_CORTEX_A75 0x4100d0a0
#define ARM_CPU_PART_MASK 0xff00fff0
/* Broadcom implemented processors */
#define ARM_CPU_PART_BRAHMA_B15 0x420000f0
#define ARM_CPU_PART_BRAHMA_B53 0x42001000
/* DEC implemented cores */
#define ARM_CPU_PART_SA1100 0x4400a110
/* Intel implemented cores */
#define ARM_CPU_PART_SA1110 0x6900b110
#define ARM_CPU_REV_SA1110_A0 0
#define ARM_CPU_REV_SA1110_B0 4
#define ARM_CPU_REV_SA1110_B1 5
#define ARM_CPU_REV_SA1110_B2 6
#define ARM_CPU_REV_SA1110_B4 8
#define ARM_CPU_XSCALE_ARCH_MASK 0xe000
#define ARM_CPU_XSCALE_ARCH_V1 0x2000
#define ARM_CPU_XSCALE_ARCH_V2 0x4000
#define ARM_CPU_XSCALE_ARCH_V3 0x6000
/* Qualcomm implemented cores */
#define ARM_CPU_PART_SCORPION 0x510002d0
#ifndef __ASSEMBLY__
#include <linux/stringify.h>
#include <linux/kernel.h>
extern unsigned int processor_id;
struct proc_info_list *lookup_processor(u32 midr);
#ifdef CONFIG_CPU_CP15
#define read_cpuid(reg) \
({ \
unsigned int __val; \
asm("mrc p15, 0, %0, c0, c0, " __stringify(reg) \
: "=r" (__val) \
: \
: "cc"); \
__val; \
})
/*
* The memory clobber prevents gcc 4.5 from reordering the mrc before
* any is_smp() tests, which can cause undefined instruction aborts on
* ARM1136 r0 due to the missing extended CP15 registers.
*/
#define read_cpuid_ext(ext_reg) \
({ \
unsigned int __val; \
asm("mrc p15, 0, %0, c0, " ext_reg \
: "=r" (__val) \
: \
: "memory"); \
__val; \
})
#elif defined(CONFIG_CPU_V7M)
#include <asm/io.h>
#include <asm/v7m.h>
#define read_cpuid(reg) \
({ \
WARN_ON_ONCE(1); \
0; \
})
static inline unsigned int __attribute_const__ read_cpuid_ext(unsigned offset)
{
return readl(BASEADDR_V7M_SCB + offset);
}
#else /* ifdef CONFIG_CPU_CP15 / elif defined (CONFIG_CPU_V7M) */
/*
* read_cpuid and read_cpuid_ext should only ever be called on machines that
* have cp15 so warn on other usages.
*/
#define read_cpuid(reg) \
({ \
WARN_ON_ONCE(1); \
0; \
})
#define read_cpuid_ext(reg) read_cpuid(reg)
#endif /* ifdef CONFIG_CPU_CP15 / else */
#ifdef CONFIG_CPU_CP15
/*
* The CPU ID never changes at run time, so we might as well tell the
* compiler that it's constant. Use this function to read the CPU ID
* rather than directly reading processor_id or read_cpuid() directly.
*/
static inline unsigned int __attribute_const__ read_cpuid_id(void)
{
return read_cpuid(CPUID_ID);
}
static inline unsigned int __attribute_const__ read_cpuid_cachetype(void)
{
return read_cpuid(CPUID_CACHETYPE);
}
static inline unsigned int __attribute_const__ read_cpuid_mputype(void)
{
return read_cpuid(CPUID_MPUIR);
}
#elif defined(CONFIG_CPU_V7M)
static inline unsigned int __attribute_const__ read_cpuid_id(void)
{
return readl(BASEADDR_V7M_SCB + V7M_SCB_CPUID);
}
static inline unsigned int __attribute_const__ read_cpuid_cachetype(void)
{
return readl(BASEADDR_V7M_SCB + V7M_SCB_CTR);
}
static inline unsigned int __attribute_const__ read_cpuid_mputype(void)
{
return readl(BASEADDR_V7M_SCB + MPU_TYPE);
}
#else /* ifdef CONFIG_CPU_CP15 / elif defined(CONFIG_CPU_V7M) */
static inline unsigned int __attribute_const__ read_cpuid_id(void)
{
return processor_id;
}
#endif /* ifdef CONFIG_CPU_CP15 / else */
static inline unsigned int __attribute_const__ read_cpuid_implementor(void)
{
return (read_cpuid_id() & 0xFF000000) >> 24;
}
static inline unsigned int __attribute_const__ read_cpuid_revision(void)
{
return read_cpuid_id() & 0x0000000f;
}
/*
* The CPU part number is meaningless without referring to the CPU
* implementer: implementers are free to define their own part numbers
* which are permitted to clash with other implementer part numbers.
*/
static inline unsigned int __attribute_const__ read_cpuid_part(void)
{
return read_cpuid_id() & ARM_CPU_PART_MASK;
}
static inline unsigned int __attribute_const__ __deprecated read_cpuid_part_number(void)
{
return read_cpuid_id() & 0xFFF0;
}
static inline unsigned int __attribute_const__ xscale_cpu_arch_version(void)
{
return read_cpuid_id() & ARM_CPU_XSCALE_ARCH_MASK;
}
static inline unsigned int __attribute_const__ read_cpuid_tcmstatus(void)
{
return read_cpuid(CPUID_TCM);
}
static inline unsigned int __attribute_const__ read_cpuid_mpidr(void)
{
return read_cpuid(CPUID_MPIDR);
}
/* StrongARM-11x0 CPUs */
#define cpu_is_sa1100() (read_cpuid_part() == ARM_CPU_PART_SA1100)
#define cpu_is_sa1110() (read_cpuid_part() == ARM_CPU_PART_SA1110)
/*
* Intel's XScale3 core supports some v6 features (supersections, L2)
* but advertises itself as v5 as it does not support the v6 ISA. For
* this reason, we need a way to explicitly test for this type of CPU.
*/
#ifndef CONFIG_CPU_XSC3
#define cpu_is_xsc3() 0
#else
static inline int cpu_is_xsc3(void)
{
unsigned int id;
id = read_cpuid_id() & 0xffffe000;
/* It covers both Intel ID and Marvell ID */
if ((id == 0x69056000) || (id == 0x56056000))
return 1;
return 0;
}
#endif
#if !defined(CONFIG_CPU_XSCALE) && !defined(CONFIG_CPU_XSC3) && \
!defined(CONFIG_CPU_MOHAWK)
#define cpu_is_xscale_family() 0
#else
static inline int cpu_is_xscale_family(void)
{
unsigned int id;
id = read_cpuid_id() & 0xffffe000;
switch (id) {
case 0x69052000: /* Intel XScale 1 */
case 0x69054000: /* Intel XScale 2 */
case 0x69056000: /* Intel XScale 3 */
case 0x56056000: /* Marvell XScale 3 */
case 0x56158000: /* Marvell Mohawk */
return 1;
}
return 0;
}
#endif
/*
* Marvell's PJ4 and PJ4B cores are based on V7 version,
* but require a specical sequence for enabling coprocessors.
* For this reason, we need a way to distinguish them.
*/
#if defined(CONFIG_CPU_PJ4) || defined(CONFIG_CPU_PJ4B)
static inline int cpu_is_pj4(void)
{
unsigned int id;
id = read_cpuid_id();
if ((id & 0xff0fff00) == 0x560f5800)
return 1;
return 0;
}
#else
#define cpu_is_pj4() 0
#endif
static inline int __attribute_const__ cpuid_feature_extract_field(u32 features,
int field)
{
int feature = (features >> field) & 15;
/* feature registers are signed values */
if (feature > 7)
feature -= 16;
return feature;
}
#define cpuid_feature_extract(reg, field) \
cpuid_feature_extract_field(read_cpuid_ext(reg), field)
#endif /* __ASSEMBLY__ */
#endif
@@ -0,0 +1,65 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2021 Keith Packard <keithp@keithp.com>
* Copyright (c) 2021 Google, LLC <ardb@kernel.org>
*/
#ifndef _ASM_ARM_CURRENT_H
#define _ASM_ARM_CURRENT_H
#ifndef __ASSEMBLY__
#include <asm/insn.h>
struct task_struct;
extern struct task_struct *__current;
static __always_inline __attribute_const__ struct task_struct *get_current(void)
{
struct task_struct *cur;
#if __has_builtin(__builtin_thread_pointer) && defined(CONFIG_CURRENT_POINTER_IN_TPIDRURO)
/*
* Use the __builtin helper when available - this results in better
* code, especially when using GCC in combination with the per-task
* stack protector, as the compiler will recognize that it needs to
* load the TLS register only once in every function.
*/
cur = __builtin_thread_pointer();
#elif defined(CONFIG_CURRENT_POINTER_IN_TPIDRURO) || defined(CONFIG_SMP)
asm("0: mrc p15, 0, %0, c13, c0, 3 \n\t"
#ifdef CONFIG_CPU_V6
"1: \n\t"
" .subsection 1 \n\t"
#if defined(CONFIG_ARM_HAS_GROUP_RELOCS) && \
!(defined(MODULE) && defined(CONFIG_ARM_MODULE_PLTS))
"2: " LOAD_SYM_ARMV6(%0, __current) " \n\t"
" b 1b \n\t"
#else
"2: ldr %0, 3f \n\t"
" ldr %0, [%0] \n\t"
" b 1b \n\t"
"3: .long __current \n\t"
#endif
" .previous \n\t"
" .pushsection \".alt.smp.init\", \"a\" \n\t"
" .long 0b - . \n\t"
" b . + (2b - 0b) \n\t"
" .popsection \n\t"
#endif
: "=r"(cur));
#elif __LINUX_ARM_ARCH__>= 7 || \
!defined(CONFIG_ARM_HAS_GROUP_RELOCS) || \
(defined(MODULE) && defined(CONFIG_ARM_MODULE_PLTS))
cur = __current;
#else
asm(LOAD_SYM_ARMV6(%0, __current) : "=r"(cur));
#endif
return cur;
}
#define current get_current()
#endif /* __ASSEMBLY__ */
#endif /* _ASM_ARM_CURRENT_H */
+33
View File
@@ -0,0 +1,33 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2010, 2014 The Linux Foundation. All rights reserved.
*/
#include <asm/barrier.h>
static inline u32 __dcc_getstatus(void)
{
u32 __ret;
asm volatile("mrc p14, 0, %0, c0, c1, 0 @ read comms ctrl reg"
: "=r" (__ret) : : "cc");
return __ret;
}
static inline char __dcc_getchar(void)
{
char __c;
asm volatile("mrc p14, 0, %0, c0, c5, 0 @ read comms data reg"
: "=r" (__c));
isb();
return __c;
}
static inline void __dcc_putchar(char c)
{
asm volatile("mcr p14, 0, %0, c0, c5, 0 @ write a char"
: /* no output register */
: "r" (c));
isb();
}
+100
View File
@@ -0,0 +1,100 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 1995-2004 Russell King
*
* Delay routines, using a pre-computed "loops_per_second" value.
*/
#ifndef __ASM_ARM_DELAY_H
#define __ASM_ARM_DELAY_H
#include <asm/page.h>
#include <asm/param.h> /* HZ */
/*
* Loop (or tick) based delay:
*
* loops = loops_per_jiffy * jiffies_per_sec * delay_us / us_per_sec
*
* where:
*
* jiffies_per_sec = HZ
* us_per_sec = 1000000
*
* Therefore the constant part is HZ / 1000000 which is a small
* fractional number. To make this usable with integer math, we
* scale up this constant by 2^31, perform the actual multiplication,
* and scale the result back down by 2^31 with a simple shift:
*
* loops = (loops_per_jiffy * delay_us * UDELAY_MULT) >> 31
*
* where:
*
* UDELAY_MULT = 2^31 * HZ / 1000000
* = (2^31 / 1000000) * HZ
* = 2147.483648 * HZ
* = 2147 * HZ + 483648 * HZ / 1000000
*
* 31 is the biggest scale shift value that won't overflow 32 bits for
* delay_us * UDELAY_MULT assuming HZ <= 1000 and delay_us <= 2000.
*/
#define MAX_UDELAY_MS 2
#define UDELAY_MULT UL(2147 * HZ + 483648 * HZ / 1000000)
#define UDELAY_SHIFT 31
#ifndef __ASSEMBLY__
struct delay_timer {
unsigned long (*read_current_timer)(void);
unsigned long freq;
};
extern struct arm_delay_ops {
void (*delay)(unsigned long);
void (*const_udelay)(unsigned long);
void (*udelay)(unsigned long);
unsigned long ticks_per_jiffy;
} arm_delay_ops;
#define __delay(n) arm_delay_ops.delay(n)
/*
* This function intentionally does not exist; if you see references to
* it, it means that you're calling udelay() with an out of range value.
*
* With currently imposed limits, this means that we support a max delay
* of 2000us. Further limits: HZ<=1000
*/
extern void __bad_udelay(void);
/*
* division by multiplication: you don't have to worry about
* loss of precision.
*
* Use only for very small delays ( < 2 msec). Should probably use a
* lookup table, really, as the multiplications take much too long with
* short delays. This is a "reasonable" implementation, though (and the
* first constant multiplications gets optimized away if the delay is
* a constant)
*/
#define __udelay(n) arm_delay_ops.udelay(n)
#define __const_udelay(n) arm_delay_ops.const_udelay(n)
#define udelay(n) \
(__builtin_constant_p(n) ? \
((n) > (MAX_UDELAY_MS * 1000) ? __bad_udelay() : \
__const_udelay((n) * UDELAY_MULT)) : \
__udelay(n))
/* Loop-based definitions for assembly code. */
extern void __loop_delay(unsigned long loops);
extern void __loop_udelay(unsigned long usecs);
extern void __loop_const_udelay(unsigned long);
/* Delay-loop timer registration. */
#define ARCH_HAS_READ_CURRENT_TIMER
extern void register_current_timer_delay(const struct delay_timer *timer);
#endif /* __ASSEMBLY__ */
#endif /* defined(_ARM_DELAY_H) */
+29
View File
@@ -0,0 +1,29 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Arch specific extensions to struct device
*/
#ifndef ASMARM_DEVICE_H
#define ASMARM_DEVICE_H
struct dev_archdata {
#ifdef CONFIG_ARM_DMA_USE_IOMMU
struct dma_iommu_mapping *mapping;
#endif
unsigned int dma_ops_setup:1;
};
struct omap_device;
struct pdev_archdata {
#ifdef CONFIG_ARCH_OMAP
struct omap_device *od;
#endif
};
#ifdef CONFIG_ARM_DMA_USE_IOMMU
#define to_dma_iommu_mapping(dev) ((dev)->archdata.mapping)
#else
#define to_dma_iommu_mapping(dev) NULL
#endif
#endif
+118
View File
@@ -0,0 +1,118 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_ARM_DIV64
#define __ASM_ARM_DIV64
#include <linux/types.h>
#include <asm/compiler.h>
/*
* The semantics of __div64_32() are:
*
* uint32_t __div64_32(uint64_t *n, uint32_t base)
* {
* uint32_t remainder = *n % base;
* *n = *n / base;
* return remainder;
* }
*
* In other words, a 64-bit dividend with a 32-bit divisor producing
* a 64-bit result and a 32-bit remainder. To accomplish this optimally
* we override the generic version in lib/div64.c to call our __do_div64
* assembly implementation with completely non standard calling convention
* for arguments and results (beware).
*/
static inline uint32_t __div64_32(uint64_t *n, uint32_t base)
{
register unsigned int __base asm("r4") = base;
register unsigned long long __n asm("r0") = *n;
register unsigned long long __res asm("r2");
unsigned int __rem;
asm( __asmeq("%0", "r0")
__asmeq("%1", "r2")
__asmeq("%2", "r4")
"bl __do_div64"
: "+r" (__n), "=r" (__res)
: "r" (__base)
: "ip", "lr", "cc");
__rem = __n >> 32;
*n = __res;
return __rem;
}
#define __div64_32 __div64_32
#if !defined(CONFIG_AEABI)
/*
* In OABI configurations, some uses of the do_div function
* cause gcc to run out of registers. To work around that,
* we can force the use of the out-of-line version for
* configurations that build a OABI kernel.
*/
#define do_div(n, base) __div64_32(&(n), base)
#else
#ifdef CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE
static __always_inline
#else
static inline
#endif
uint64_t __arch_xprod_64(uint64_t m, uint64_t n, bool bias)
{
unsigned long long res;
register unsigned int tmp asm("ip") = 0;
bool no_ovf = __builtin_constant_p(m) &&
((m >> 32) + (m & 0xffffffff) < 0x100000000);
if (!bias) {
asm ( "umull %Q0, %R0, %Q1, %Q2\n\t"
"mov %Q0, #0"
: "=&r" (res)
: "r" (m), "r" (n)
: "cc");
} else if (no_ovf) {
res = m;
asm ( "umlal %Q0, %R0, %Q1, %Q2\n\t"
"mov %Q0, #0"
: "+&r" (res)
: "r" (m), "r" (n)
: "cc");
} else {
asm ( "umull %Q0, %R0, %Q2, %Q3\n\t"
"cmn %Q0, %Q2\n\t"
"adcs %R0, %R0, %R2\n\t"
"adc %Q0, %1, #0"
: "=&r" (res), "+&r" (tmp)
: "r" (m), "r" (n)
: "cc");
}
if (no_ovf) {
asm ( "umlal %R0, %Q0, %R1, %Q2\n\t"
"umlal %R0, %Q0, %Q1, %R2\n\t"
"mov %R0, #0\n\t"
"umlal %Q0, %R0, %R1, %R2"
: "+&r" (res)
: "r" (m), "r" (n)
: "cc");
} else {
asm ( "umlal %R0, %Q0, %R2, %Q3\n\t"
"umlal %R0, %1, %Q2, %R3\n\t"
"mov %R0, #0\n\t"
"adds %Q0, %1, %Q0\n\t"
"adc %R0, %R0, #0\n\t"
"umlal %Q0, %R0, %R2, %R3"
: "+&r" (res), "+&r" (tmp)
: "r" (m), "r" (n)
: "cc");
}
return res;
}
#define __arch_xprod_64 __arch_xprod_64
#include <asm-generic/div64.h>
#endif
#endif
@@ -0,0 +1,36 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef ASMARM_DMA_IOMMU_H
#define ASMARM_DMA_IOMMU_H
#ifdef __KERNEL__
#include <linux/mm_types.h>
#include <linux/scatterlist.h>
#include <linux/kref.h>
struct dma_iommu_mapping {
/* iommu specific data */
struct iommu_domain *domain;
unsigned long **bitmaps; /* array of bitmaps */
unsigned int nr_bitmaps; /* nr of elements in array */
unsigned int extensions;
size_t bitmap_size; /* size of a single bitmap */
size_t bits; /* per bitmap */
dma_addr_t base;
spinlock_t lock;
struct kref kref;
};
struct dma_iommu_mapping *
arm_iommu_create_mapping(struct device *dev, dma_addr_t base, u64 size);
void arm_iommu_release_mapping(struct dma_iommu_mapping *mapping);
int arm_iommu_attach_device(struct device *dev,
struct dma_iommu_mapping *mapping);
void arm_iommu_detach_device(struct device *dev);
#endif /* __KERNEL__ */
#endif
+149
View File
@@ -0,0 +1,149 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_ARM_DMA_H
#define __ASM_ARM_DMA_H
/*
* This is the maximum virtual address which can be DMA'd from.
*/
#ifndef CONFIG_ZONE_DMA
#define MAX_DMA_ADDRESS 0xffffffffUL
#else
#define MAX_DMA_ADDRESS ({ \
extern phys_addr_t arm_dma_zone_size; \
arm_dma_zone_size && arm_dma_zone_size < (0x100000000ULL - PAGE_OFFSET) ? \
(PAGE_OFFSET + arm_dma_zone_size) : 0xffffffffUL; })
extern phys_addr_t arm_dma_limit;
#define ARCH_LOW_ADDRESS_LIMIT arm_dma_limit
#endif
#ifdef CONFIG_ISA_DMA_API
/*
* This is used to support drivers written for the x86 ISA DMA API.
* It should not be re-used except for that purpose.
*/
#include <linux/spinlock.h>
#include <linux/scatterlist.h>
#include <mach/isa-dma.h>
/*
* The DMA modes reflect the settings for the ISA DMA controller
*/
#define DMA_MODE_MASK 0xcc
#define DMA_MODE_READ 0x44
#define DMA_MODE_WRITE 0x48
#define DMA_MODE_CASCADE 0xc0
#define DMA_AUTOINIT 0x10
extern raw_spinlock_t dma_spin_lock;
static inline unsigned long claim_dma_lock(void)
{
unsigned long flags;
raw_spin_lock_irqsave(&dma_spin_lock, flags);
return flags;
}
static inline void release_dma_lock(unsigned long flags)
{
raw_spin_unlock_irqrestore(&dma_spin_lock, flags);
}
/* Clear the 'DMA Pointer Flip Flop'.
* Write 0 for LSB/MSB, 1 for MSB/LSB access.
*/
#define clear_dma_ff(chan)
/* Set only the page register bits of the transfer address.
*
* NOTE: This is an architecture specific function, and should
* be hidden from the drivers
*/
extern void set_dma_page(unsigned int chan, char pagenr);
/* Request a DMA channel
*
* Some architectures may need to do allocate an interrupt
*/
extern int request_dma(unsigned int chan, const char * device_id);
/* Free a DMA channel
*
* Some architectures may need to do free an interrupt
*/
extern void free_dma(unsigned int chan);
/* Enable DMA for this channel
*
* On some architectures, this may have other side effects like
* enabling an interrupt and setting the DMA registers.
*/
extern void enable_dma(unsigned int chan);
/* Disable DMA for this channel
*
* On some architectures, this may have other side effects like
* disabling an interrupt or whatever.
*/
extern void disable_dma(unsigned int chan);
/* Test whether the specified channel has an active DMA transfer
*/
extern int dma_channel_active(unsigned int chan);
/* Set the DMA scatter gather list for this channel
*
* This should not be called if a DMA channel is enabled,
* especially since some DMA architectures don't update the
* DMA address immediately, but defer it to the enable_dma().
*/
extern void set_dma_sg(unsigned int chan, struct scatterlist *sg, int nr_sg);
/* Set the DMA address for this channel
*
* This should not be called if a DMA channel is enabled,
* especially since some DMA architectures don't update the
* DMA address immediately, but defer it to the enable_dma().
*/
extern void __set_dma_addr(unsigned int chan, void *addr);
#define set_dma_addr(chan, addr) \
__set_dma_addr(chan, (void *)isa_bus_to_virt(addr))
/* Set the DMA byte count for this channel
*
* This should not be called if a DMA channel is enabled,
* especially since some DMA architectures don't update the
* DMA count immediately, but defer it to the enable_dma().
*/
extern void set_dma_count(unsigned int chan, unsigned long count);
/* Set the transfer direction for this channel
*
* This should not be called if a DMA channel is enabled,
* especially since some DMA architectures don't update the
* DMA transfer direction immediately, but defer it to the
* enable_dma().
*/
extern void set_dma_mode(unsigned int chan, unsigned int mode);
/* Set the transfer speed for this channel
*/
extern void set_dma_speed(unsigned int chan, int cycle_ns);
/* Get DMA residue count. After a DMA transfer, this
* should return zero. Reading this while a DMA transfer is
* still in progress will return unpredictable results.
* If called before the channel has been used, it may return 1.
* Otherwise, it returns the number of _bytes_ left to transfer.
*/
extern int get_dma_residue(unsigned int chan);
#ifndef NO_DMA
#define NO_DMA 255
#endif
#endif /* CONFIG_ISA_DMA_API */
#endif /* __ASM_ARM_DMA_H */
+15
View File
@@ -0,0 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef __ASM_DMI_H
#define __ASM_DMI_H
#include <linux/io.h>
#include <linux/slab.h>
#define dmi_early_remap(x, l) memremap(x, l, MEMREMAP_WB)
#define dmi_early_unmap(x, l) memunmap(x)
#define dmi_remap(x, l) memremap(x, l, MEMREMAP_WB)
#define dmi_unmap(x) memunmap(x)
#define dmi_alloc(l) kzalloc(l, GFP_KERNEL)
#endif
+141
View File
@@ -0,0 +1,141 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* arch/arm/include/asm/domain.h
*
* Copyright (C) 1999 Russell King.
*/
#ifndef __ASM_PROC_DOMAIN_H
#define __ASM_PROC_DOMAIN_H
#ifndef __ASSEMBLY__
#include <linux/thread_info.h>
#include <asm/barrier.h>
#endif
/*
* Domain numbers
*
* DOMAIN_IO - domain 2 includes all IO only
* DOMAIN_USER - domain 1 includes all user memory only
* DOMAIN_KERNEL - domain 0 includes all kernel memory only
*
* The domain numbering depends on whether we support 36 physical
* address for I/O or not. Addresses above the 32 bit boundary can
* only be mapped using supersections and supersections can only
* be set for domain 0. We could just default to DOMAIN_IO as zero,
* but there may be systems with supersection support and no 36-bit
* addressing. In such cases, we want to map system memory with
* supersections to reduce TLB misses and footprint.
*
* 36-bit addressing and supersections are only available on
* CPUs based on ARMv6+ or the Intel XSC3 core.
*/
#ifndef CONFIG_IO_36
#define DOMAIN_KERNEL 0
#define DOMAIN_USER 1
#define DOMAIN_IO 2
#else
#define DOMAIN_KERNEL 2
#define DOMAIN_USER 1
#define DOMAIN_IO 0
#endif
#define DOMAIN_VECTORS 3
/*
* Domain types
*/
#define DOMAIN_NOACCESS 0
#define DOMAIN_CLIENT 1
#ifdef CONFIG_CPU_USE_DOMAINS
#define DOMAIN_MANAGER 3
#else
#define DOMAIN_MANAGER 1
#endif
#define domain_mask(dom) ((3) << (2 * (dom)))
#define domain_val(dom,type) ((type) << (2 * (dom)))
#ifdef CONFIG_CPU_SW_DOMAIN_PAN
#define DACR_INIT \
(domain_val(DOMAIN_USER, DOMAIN_NOACCESS) | \
domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
domain_val(DOMAIN_IO, DOMAIN_CLIENT) | \
domain_val(DOMAIN_VECTORS, DOMAIN_CLIENT))
#else
#define DACR_INIT \
(domain_val(DOMAIN_USER, DOMAIN_CLIENT) | \
domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
domain_val(DOMAIN_IO, DOMAIN_CLIENT) | \
domain_val(DOMAIN_VECTORS, DOMAIN_CLIENT))
#endif
#define __DACR_DEFAULT \
domain_val(DOMAIN_KERNEL, DOMAIN_CLIENT) | \
domain_val(DOMAIN_IO, DOMAIN_CLIENT) | \
domain_val(DOMAIN_VECTORS, DOMAIN_CLIENT)
#define DACR_UACCESS_DISABLE \
(__DACR_DEFAULT | domain_val(DOMAIN_USER, DOMAIN_NOACCESS))
#define DACR_UACCESS_ENABLE \
(__DACR_DEFAULT | domain_val(DOMAIN_USER, DOMAIN_CLIENT))
#ifndef __ASSEMBLY__
#ifdef CONFIG_CPU_CP15_MMU
static __always_inline unsigned int get_domain(void)
{
unsigned int domain;
asm(
"mrc p15, 0, %0, c3, c0 @ get domain"
: "=r" (domain)
: "m" (current_thread_info()->cpu_domain));
return domain;
}
static __always_inline void set_domain(unsigned int val)
{
asm volatile(
"mcr p15, 0, %0, c3, c0 @ set domain"
: : "r" (val) : "memory");
isb();
}
#else
static __always_inline unsigned int get_domain(void)
{
return 0;
}
static __always_inline void set_domain(unsigned int val)
{
}
#endif
/*
* Generate the T (user) versions of the LDR/STR and related
* instructions (inline assembly)
*/
#ifdef CONFIG_CPU_USE_DOMAINS
#define TUSER(instr) TUSERCOND(instr, )
#define TUSERCOND(instr, cond) #instr "t" #cond
#else
#define TUSER(instr) TUSERCOND(instr, )
#define TUSERCOND(instr, cond) #instr #cond
#endif
#else /* __ASSEMBLY__ */
/*
* Generate the T (user) versions of the LDR/STR and related
* instructions
*/
#ifdef CONFIG_CPU_USE_DOMAINS
#define TUSER(instr) instr ## t
#else
#define TUSER(instr) instr
#endif
#endif /* __ASSEMBLY__ */
#endif /* !__ASM_PROC_DOMAIN_H */
+219
View File
@@ -0,0 +1,219 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* arch/arm/include/asm/ecard.h
*
* definitions for expansion cards
*
* This is a new system as from Linux 1.2.3
*
* Changelog:
* 11-12-1996 RMK Further minor improvements
* 12-09-1997 RMK Added interrupt enable/disable for card level
*
* Reference: Acorns Risc OS 3 Programmers Reference Manuals.
*/
#ifndef __ASM_ECARD_H
#define __ASM_ECARD_H
/*
* Currently understood cards (but not necessarily
* supported):
* Manufacturer Product ID
*/
#define MANU_ACORN 0x0000
#define PROD_ACORN_SCSI 0x0002
#define PROD_ACORN_ETHER1 0x0003
#define PROD_ACORN_MFM 0x000b
#define MANU_ANT2 0x0011
#define PROD_ANT_ETHER3 0x00a4
#define MANU_ATOMWIDE 0x0017
#define PROD_ATOMWIDE_3PSERIAL 0x0090
#define MANU_IRLAM_INSTRUMENTS 0x001f
#define MANU_IRLAM_INSTRUMENTS_ETHERN 0x5678
#define MANU_OAK 0x0021
#define PROD_OAK_SCSI 0x0058
#define MANU_MORLEY 0x002b
#define PROD_MORLEY_SCSI_UNCACHED 0x0067
#define MANU_CUMANA 0x003a
#define PROD_CUMANA_SCSI_2 0x003a
#define PROD_CUMANA_SCSI_1 0x00a0
#define MANU_ICS 0x003c
#define PROD_ICS_IDE 0x00ae
#define MANU_ICS2 0x003d
#define PROD_ICS2_IDE 0x00ae
#define MANU_SERPORT 0x003f
#define PROD_SERPORT_DSPORT 0x00b9
#define MANU_ARXE 0x0041
#define PROD_ARXE_SCSI 0x00be
#define MANU_I3 0x0046
#define PROD_I3_ETHERLAN500 0x00d4
#define PROD_I3_ETHERLAN600 0x00ec
#define PROD_I3_ETHERLAN600A 0x011e
#define MANU_ANT 0x0053
#define PROD_ANT_ETHERM 0x00d8
#define PROD_ANT_ETHERB 0x00e4
#define MANU_ALSYSTEMS 0x005b
#define PROD_ALSYS_SCSIATAPI 0x0107
#define MANU_MCS 0x0063
#define PROD_MCS_CONNECT32 0x0125
#define MANU_EESOX 0x0064
#define PROD_EESOX_SCSI2 0x008c
#define MANU_YELLOWSTONE 0x0096
#define PROD_YELLOWSTONE_RAPIDE32 0x0120
#ifdef ECARD_C
#define CONST
#else
#define CONST const
#endif
#define MAX_ECARDS 9
struct ecard_id { /* Card ID structure */
unsigned short manufacturer;
unsigned short product;
void *data;
};
struct in_ecid { /* Packed card ID information */
unsigned short product; /* Product code */
unsigned short manufacturer; /* Manufacturer code */
unsigned char id:4; /* Simple ID */
unsigned char cd:1; /* Chunk dir present */
unsigned char is:1; /* Interrupt status pointers */
unsigned char w:2; /* Width */
unsigned char country; /* Country */
unsigned char irqmask; /* IRQ mask */
unsigned char fiqmask; /* FIQ mask */
unsigned long irqoff; /* IRQ offset */
unsigned long fiqoff; /* FIQ offset */
};
typedef struct expansion_card ecard_t;
typedef unsigned long *loader_t;
typedef struct expansion_card_ops { /* Card handler routines */
void (*irqenable)(ecard_t *ec, int irqnr);
void (*irqdisable)(ecard_t *ec, int irqnr);
int (*irqpending)(ecard_t *ec);
void (*fiqenable)(ecard_t *ec, int fiqnr);
void (*fiqdisable)(ecard_t *ec, int fiqnr);
int (*fiqpending)(ecard_t *ec);
} expansioncard_ops_t;
#define ECARD_NUM_RESOURCES (6)
#define ECARD_RES_IOCSLOW (0)
#define ECARD_RES_IOCMEDIUM (1)
#define ECARD_RES_IOCFAST (2)
#define ECARD_RES_IOCSYNC (3)
#define ECARD_RES_MEMC (4)
#define ECARD_RES_EASI (5)
#define ecard_resource_start(ec,nr) ((ec)->resource[nr].start)
#define ecard_resource_end(ec,nr) ((ec)->resource[nr].end)
#define ecard_resource_len(ec,nr) ((ec)->resource[nr].end - \
(ec)->resource[nr].start + 1)
#define ecard_resource_flags(ec,nr) ((ec)->resource[nr].flags)
/*
* This contains all the info needed on an expansion card
*/
struct expansion_card {
struct expansion_card *next;
struct device dev;
struct resource resource[ECARD_NUM_RESOURCES];
/* Public data */
void __iomem *irqaddr; /* address of IRQ register */
void __iomem *fiqaddr; /* address of FIQ register */
unsigned char irqmask; /* IRQ mask */
unsigned char fiqmask; /* FIQ mask */
unsigned char claimed; /* Card claimed? */
unsigned char easi; /* EASI card */
void *irq_data; /* Data for use for IRQ by card */
void *fiq_data; /* Data for use for FIQ by card */
const expansioncard_ops_t *ops; /* Enable/Disable Ops for card */
CONST unsigned int slot_no; /* Slot number */
CONST unsigned int dma; /* DMA number (for request_dma) */
CONST unsigned int irq; /* IRQ number (for request_irq) */
CONST unsigned int fiq; /* FIQ number (for request_irq) */
CONST struct in_ecid cid; /* Card Identification */
/* Private internal data */
const char *card_desc; /* Card description */
CONST loader_t loader; /* loader program */
u64 dma_mask;
};
void ecard_setirq(struct expansion_card *ec, const struct expansion_card_ops *ops, void *irq_data);
struct in_chunk_dir {
unsigned int start_offset;
union {
unsigned char string[256];
unsigned char data[1];
} d;
};
/*
* Read a chunk from an expansion card
* cd : where to put read data
* ec : expansion card info struct
* id : id number to find
* num: (n+1)'th id to find.
*/
extern int ecard_readchunk (struct in_chunk_dir *cd, struct expansion_card *ec, int id, int num);
/*
* Request and release ecard resources
*/
extern int ecard_request_resources(struct expansion_card *ec);
extern void ecard_release_resources(struct expansion_card *ec);
void __iomem *ecardm_iomap(struct expansion_card *ec, unsigned int res,
unsigned long offset, unsigned long maxsize);
#define ecardm_iounmap(__ec, __addr) devm_iounmap(&(__ec)->dev, __addr)
extern const struct bus_type ecard_bus_type;
#define ECARD_DEV(_d) container_of((_d), struct expansion_card, dev)
struct ecard_driver {
int (*probe)(struct expansion_card *, const struct ecard_id *id);
void (*remove)(struct expansion_card *);
void (*shutdown)(struct expansion_card *);
const struct ecard_id *id_table;
unsigned int id;
struct device_driver drv;
};
#define ECARD_DRV(_d) container_of((_d), struct ecard_driver, drv)
#define ecard_set_drvdata(ec,data) dev_set_drvdata(&(ec)->dev, (data))
#define ecard_get_drvdata(ec) dev_get_drvdata(&(ec)->dev)
int ecard_register_driver(struct ecard_driver *);
void ecard_remove_driver(struct ecard_driver *);
#endif
+38
View File
@@ -0,0 +1,38 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright 2011 Calxeda, Inc.
* Based on PPC version Copyright 2007 MontaVista Software, Inc.
*/
#ifndef ASM_EDAC_H
#define ASM_EDAC_H
/*
* ECC atomic, DMA, SMP and interrupt safe scrub function.
* Implements the per arch edac_atomic_scrub() that EDAC use for software
* ECC scrubbing. It reads memory and then writes back the original
* value, allowing the hardware to detect and correct memory errors.
*/
static inline void edac_atomic_scrub(void *va, u32 size)
{
#if __LINUX_ARM_ARCH__ >= 6
unsigned int *virt_addr = va;
unsigned int temp, temp2;
unsigned int i;
for (i = 0; i < size / sizeof(*virt_addr); i++, virt_addr++) {
/* Very carefully read and write to memory atomically
* so we are interrupt, DMA and SMP safe.
*/
__asm__ __volatile__("\n"
"1: ldrex %0, [%2]\n"
" strex %1, %0, [%2]\n"
" teq %1, #0\n"
" bne 1b\n"
: "=&r"(temp), "=&r"(temp2)
: "r"(virt_addr)
: "cc");
}
#endif
}
#endif
+94
View File
@@ -0,0 +1,94 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2015 Linaro Ltd <ard.biesheuvel@linaro.org>
*/
#ifndef __ASM_ARM_EFI_H
#define __ASM_ARM_EFI_H
#include <asm/cacheflush.h>
#include <asm/cachetype.h>
#include <asm/early_ioremap.h>
#include <asm/fixmap.h>
#include <asm/highmem.h>
#include <asm/mach/map.h>
#include <asm/mmu_context.h>
#include <asm/ptrace.h>
#include <asm/uaccess.h>
#ifdef CONFIG_EFI
void efi_init(void);
void arm_efi_init(void);
int efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md);
int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md, bool);
#define arch_efi_call_virt_setup() efi_virtmap_load()
#define arch_efi_call_virt_teardown() efi_virtmap_unload()
#ifdef CONFIG_CPU_TTBR0_PAN
#undef arch_efi_call_virt
#define arch_efi_call_virt(p, f, args...) ({ \
unsigned int flags = uaccess_save_and_enable(); \
efi_status_t res = _Generic((p)->f(args), \
efi_status_t: (p)->f(args), \
default: ((p)->f(args), EFI_ABORTED)); \
uaccess_restore(flags); \
res; \
})
#endif
#define ARCH_EFI_IRQ_FLAGS_MASK \
(PSR_J_BIT | PSR_E_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT | \
PSR_T_BIT | MODE_MASK)
static inline void efi_set_pgd(struct mm_struct *mm)
{
check_and_switch_context(mm, NULL);
}
void efi_virtmap_load(void);
void efi_virtmap_unload(void);
#else
#define arm_efi_init()
#endif /* CONFIG_EFI */
/* arch specific definitions used by the stub code */
/*
* A reasonable upper bound for the uncompressed kernel size is 32 MBytes,
* so we will reserve that amount of memory. We have no easy way to tell what
* the actuall size of code + data the uncompressed kernel will use.
* If this is insufficient, the decompressor will relocate itself out of the
* way before performing the decompression.
*/
#define MAX_UNCOMP_KERNEL_SIZE SZ_32M
/*
* phys-to-virt patching requires that the physical to virtual offset is a
* multiple of 2 MiB. However, using an alignment smaller than TEXT_OFFSET
* here throws off the memory allocation logic, so let's use the lowest power
* of two greater than 2 MiB and greater than TEXT_OFFSET.
*/
#define EFI_PHYS_ALIGN max(UL(SZ_2M), roundup_pow_of_two(TEXT_OFFSET))
/* on ARM, the initrd should be loaded in a lowmem region */
static inline unsigned long efi_get_max_initrd_addr(unsigned long image_addr)
{
return round_down(image_addr, SZ_4M) + SZ_512M;
}
struct efi_arm_entry_state {
u32 cpsr_before_ebs;
u32 sctlr_before_ebs;
u32 cpsr_after_ebs;
u32 sctlr_after_ebs;
};
static inline void efi_capsule_flush_cache_range(void *addr, int size)
{
__cpuc_flush_dcache_area(addr, size);
}
#endif /* _ASM_ARM_EFI_H */
+155
View File
@@ -0,0 +1,155 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASMARM_ELF_H
#define __ASMARM_ELF_H
#include <asm/auxvec.h>
#include <asm/hwcap.h>
/*
* ELF register definitions..
*/
#include <asm/ptrace.h>
#include <asm/user.h>
struct task_struct;
typedef unsigned long elf_greg_t;
typedef unsigned long elf_freg_t[3];
#define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t))
typedef elf_greg_t elf_gregset_t[ELF_NGREG];
typedef struct user_fp elf_fpregset_t;
#define EF_ARM_EABI_MASK 0xff000000
#define EF_ARM_EABI_UNKNOWN 0x00000000
#define EF_ARM_EABI_VER1 0x01000000
#define EF_ARM_EABI_VER2 0x02000000
#define EF_ARM_EABI_VER3 0x03000000
#define EF_ARM_EABI_VER4 0x04000000
#define EF_ARM_EABI_VER5 0x05000000
#define EF_ARM_BE8 0x00800000 /* ABI 4,5 */
#define EF_ARM_LE8 0x00400000 /* ABI 4,5 */
#define EF_ARM_MAVERICK_FLOAT 0x00000800 /* ABI 0 */
#define EF_ARM_VFP_FLOAT 0x00000400 /* ABI 0 */
#define EF_ARM_SOFT_FLOAT 0x00000200 /* ABI 0 */
#define EF_ARM_OLD_ABI 0x00000100 /* ABI 0 */
#define EF_ARM_NEW_ABI 0x00000080 /* ABI 0 */
#define EF_ARM_ALIGN8 0x00000040 /* ABI 0 */
#define EF_ARM_PIC 0x00000020 /* ABI 0 */
#define EF_ARM_MAPSYMSFIRST 0x00000010 /* ABI 2 */
#define EF_ARM_APCS_FLOAT 0x00000010 /* ABI 0, floats in fp regs */
#define EF_ARM_DYNSYMSUSESEGIDX 0x00000008 /* ABI 2 */
#define EF_ARM_APCS_26 0x00000008 /* ABI 0 */
#define EF_ARM_SYMSARESORTED 0x00000004 /* ABI 1,2 */
#define EF_ARM_INTERWORK 0x00000004 /* ABI 0 */
#define EF_ARM_HASENTRY 0x00000002 /* All */
#define EF_ARM_RELEXEC 0x00000001 /* All */
#define R_ARM_NONE 0
#define R_ARM_PC24 1
#define R_ARM_ABS32 2
#define R_ARM_REL32 3
#define R_ARM_CALL 28
#define R_ARM_JUMP24 29
#define R_ARM_TARGET1 38
#define R_ARM_V4BX 40
#define R_ARM_PREL31 42
#define R_ARM_MOVW_ABS_NC 43
#define R_ARM_MOVT_ABS 44
#define R_ARM_MOVW_PREL_NC 45
#define R_ARM_MOVT_PREL 46
#define R_ARM_ALU_PC_G0_NC 57
#define R_ARM_ALU_PC_G1_NC 59
#define R_ARM_LDR_PC_G2 63
#define R_ARM_THM_CALL 10
#define R_ARM_THM_JUMP24 30
#define R_ARM_THM_MOVW_ABS_NC 47
#define R_ARM_THM_MOVT_ABS 48
#define R_ARM_THM_MOVW_PREL_NC 49
#define R_ARM_THM_MOVT_PREL 50
/*
* These are used to set parameters in the core dumps.
*/
#define ELF_CLASS ELFCLASS32
#ifdef __ARMEB__
#define ELF_DATA ELFDATA2MSB
#else
#define ELF_DATA ELFDATA2LSB
#endif
#define ELF_ARCH EM_ARM
/*
* This yields a string that ld.so will use to load implementation
* specific libraries for optimization. This is more specific in
* intent than poking at uname or /proc/cpuinfo.
*
* For now we just provide a fairly general string that describes the
* processor family. This could be made more specific later if someone
* implemented optimisations that require it. 26-bit CPUs give you
* "v1l" for ARM2 (no SWP) and "v2l" for anything else (ARM1 isn't
* supported). 32-bit CPUs give you "v3[lb]" for anything based on an
* ARM6 or ARM7 core and "armv4[lb]" for anything based on a StrongARM-1
* core.
*/
#define ELF_PLATFORM_SIZE 8
#define ELF_PLATFORM (elf_platform)
extern char elf_platform[];
struct elf32_hdr;
/*
* This is used to ensure we don't load something for the wrong architecture.
*/
extern int elf_check_arch(const struct elf32_hdr *);
#define elf_check_arch elf_check_arch
#define ELFOSABI_ARM_FDPIC 65 /* ARM FDPIC platform */
#define elf_check_fdpic(x) ((x)->e_ident[EI_OSABI] == ELFOSABI_ARM_FDPIC)
#define elf_check_const_displacement(x) ((x)->e_flags & EF_ARM_PIC)
#define ELF_FDPIC_CORE_EFLAGS 0
#define vmcore_elf64_check_arch(x) (0)
extern int arm_elf_read_implies_exec(int);
#define elf_read_implies_exec(ex,stk) arm_elf_read_implies_exec(stk)
#define CORE_DUMP_USE_REGSET
#define ELF_EXEC_PAGESIZE 4096
/* This is the base location for PIE (ET_DYN with INTERP) loads. */
#define ELF_ET_DYN_BASE 0x400000UL
/* When the program starts, a1 contains a pointer to a function to be
registered with atexit, as per the SVR4 ABI. A value of 0 means we
have no such handler. */
#define ELF_PLAT_INIT(_r, load_addr) (_r)->ARM_r0 = 0
#define ELF_FDPIC_PLAT_INIT(_r, _exec_map_addr, _interp_map_addr, dynamic_addr) \
do { \
(_r)->ARM_r7 = _exec_map_addr; \
(_r)->ARM_r8 = _interp_map_addr; \
(_r)->ARM_r9 = dynamic_addr; \
} while(0)
extern void elf_set_personality(const struct elf32_hdr *);
#define SET_PERSONALITY(ex) elf_set_personality(&(ex))
#ifdef CONFIG_MMU
#ifdef CONFIG_VDSO
#define ARCH_DLINFO \
do { \
NEW_AUX_ENT(AT_SYSINFO_EHDR, \
(elf_addr_t)current->mm->context.vdso); \
} while (0)
#endif
#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
struct linux_binprm;
int arch_setup_additional_pages(struct linux_binprm *, int);
#endif
#endif
@@ -0,0 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Annotations for marking C functions as exception handlers.
*
* These should only be used for C functions that are called from the low
* level exception entry code and not any intervening C code.
*/
#ifndef __ASM_ARM_EXCEPTION_H
#define __ASM_ARM_EXCEPTION_H
#include <linux/interrupt.h>
#define __exception_irq_entry __irq_entry
#endif /* __ASM_ARM_EXCEPTION_H */
+57
View File
@@ -0,0 +1,57 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* arch/arm/include/asm/fiq.h
*
* Support for FIQ on ARM architectures.
* Written by Philip Blundell <philb@gnu.org>, 1998
* Re-written by Russell King
*
* NOTE: The FIQ mode registers are not magically preserved across
* suspend/resume.
*
* Drivers which require these registers to be preserved across power
* management operations must implement appropriate suspend/resume handlers to
* save and restore them.
*/
#ifndef __ASM_FIQ_H
#define __ASM_FIQ_H
#include <asm/ptrace.h>
struct fiq_handler {
struct fiq_handler *next;
/* Name
*/
const char *name;
/* Called to ask driver to relinquish/
* reacquire FIQ
* return zero to accept, or -<errno>
*/
int (*fiq_op)(void *, int relinquish);
/* data for the relinquish/reacquire functions
*/
void *dev_id;
};
extern int claim_fiq(struct fiq_handler *f);
extern void release_fiq(struct fiq_handler *f);
extern void set_fiq_handler(void *start, unsigned int length);
extern void enable_fiq(int fiq);
extern void disable_fiq(int fiq);
/* helpers defined in fiqasm.S: */
extern void __set_fiq_regs(unsigned long const *regs);
extern void __get_fiq_regs(unsigned long *regs);
static inline void set_fiq_regs(struct pt_regs const *regs)
{
__set_fiq_regs(&regs->ARM_r8);
}
static inline void get_fiq_regs(struct pt_regs *regs)
{
__get_fiq_regs(&regs->ARM_r8);
}
#endif
@@ -0,0 +1,79 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2012 Samsung Electronics.
* Kyungmin Park <kyungmin.park@samsung.com>
* Tomasz Figa <t.figa@samsung.com>
*/
#ifndef __ASM_ARM_FIRMWARE_H
#define __ASM_ARM_FIRMWARE_H
#include <linux/bug.h>
/*
* struct firmware_ops
*
* A structure to specify available firmware operations.
*
* A filled up structure can be registered with register_firmware_ops().
*/
struct firmware_ops {
/*
* Inform the firmware we intend to enter CPU idle mode
*/
int (*prepare_idle)(unsigned long mode);
/*
* Enters CPU idle mode
*/
int (*do_idle)(unsigned long mode);
/*
* Sets boot address of specified physical CPU
*/
int (*set_cpu_boot_addr)(int cpu, unsigned long boot_addr);
/*
* Gets boot address of specified physical CPU
*/
int (*get_cpu_boot_addr)(int cpu, unsigned long *boot_addr);
/*
* Boots specified physical CPU
*/
int (*cpu_boot)(int cpu);
/*
* Initializes L2 cache
*/
int (*l2x0_init)(void);
/*
* Enter system-wide suspend.
*/
int (*suspend)(void);
/*
* Restore state of privileged hardware after system-wide suspend.
*/
int (*resume)(void);
};
/* Global pointer for current firmware_ops structure, can't be NULL. */
extern const struct firmware_ops *firmware_ops;
/*
* call_firmware_op(op, ...)
*
* Checks if firmware operation is present and calls it,
* otherwise returns -ENOSYS
*/
#define call_firmware_op(op, ...) \
((firmware_ops->op) ? firmware_ops->op(__VA_ARGS__) : (-ENOSYS))
/*
* register_firmware_ops(ops)
*
* A function to register platform firmware_ops struct.
*/
static inline void register_firmware_ops(const struct firmware_ops *ops)
{
BUG_ON(!ops);
firmware_ops = ops;
}
#endif
+66
View File
@@ -0,0 +1,66 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_FIXMAP_H
#define _ASM_FIXMAP_H
#define FIXADDR_START 0xffc80000UL
#define FIXADDR_END 0xfff00000UL
#define FIXADDR_TOP (FIXADDR_END - PAGE_SIZE)
#include <linux/pgtable.h>
#include <asm/kmap_size.h>
enum fixed_addresses {
FIX_EARLYCON_MEM_BASE,
__end_of_permanent_fixed_addresses,
FIX_KMAP_BEGIN = __end_of_permanent_fixed_addresses,
FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_MAX_IDX * NR_CPUS) - 1,
/* Support writing RO kernel text via kprobes, jump labels, etc. */
FIX_TEXT_POKE0,
FIX_TEXT_POKE1,
__end_of_fixmap_region,
/*
* Share the kmap() region with early_ioremap(): this is guaranteed
* not to clash since early_ioremap() is only available before
* paging_init(), and kmap() only after.
*/
#define NR_FIX_BTMAPS 32
#define FIX_BTMAPS_SLOTS 7
#define TOTAL_FIX_BTMAPS (NR_FIX_BTMAPS * FIX_BTMAPS_SLOTS)
FIX_BTMAP_END = __end_of_permanent_fixed_addresses,
FIX_BTMAP_BEGIN = FIX_BTMAP_END + TOTAL_FIX_BTMAPS - 1,
__end_of_early_ioremap_region
};
static const enum fixed_addresses __end_of_fixed_addresses =
__end_of_fixmap_region > __end_of_early_ioremap_region ?
__end_of_fixmap_region : __end_of_early_ioremap_region;
#define FIXMAP_PAGE_COMMON (L_PTE_YOUNG | L_PTE_PRESENT | L_PTE_XN | L_PTE_DIRTY)
#define FIXMAP_PAGE_NORMAL (pgprot_kernel | L_PTE_XN)
#define FIXMAP_PAGE_RO (FIXMAP_PAGE_NORMAL | L_PTE_RDONLY)
/* Used by set_fixmap_(io|nocache), both meant for mapping a device */
#define FIXMAP_PAGE_IO (FIXMAP_PAGE_COMMON | L_PTE_MT_DEV_SHARED | L_PTE_SHARED)
#define FIXMAP_PAGE_NOCACHE FIXMAP_PAGE_IO
#define __early_set_fixmap __set_fixmap
#ifdef CONFIG_MMU
void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot);
void __init early_fixmap_init(void);
#include <asm-generic/fixmap.h>
#else
static inline void early_fixmap_init(void) { }
#endif
#endif
+81
View File
@@ -0,0 +1,81 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* arch/arm/include/asm/floppy.h
*
* Copyright (C) 1996-2000 Russell King
*
* Note that we don't touch FLOPPY_DMA nor FLOPPY_IRQ here
*/
#ifndef __ASM_ARM_FLOPPY_H
#define __ASM_ARM_FLOPPY_H
#define fd_outb(val, base, reg) \
do { \
int new_val = (val); \
if ((reg) == FD_DOR) { \
if (new_val & 0xf0) \
new_val = (new_val & 0x0c) | \
floppy_selects[new_val & 3]; \
else \
new_val &= 0x0c; \
} \
outb(new_val, (base) + (reg)); \
} while(0)
#define fd_inb(base, reg) inb((base) + (reg))
#define fd_request_irq() request_irq(IRQ_FLOPPYDISK,floppy_interrupt,\
0,"floppy",NULL)
#define fd_free_irq() free_irq(IRQ_FLOPPYDISK,NULL)
#define fd_disable_irq() disable_irq(IRQ_FLOPPYDISK)
#define fd_enable_irq() enable_irq(IRQ_FLOPPYDISK)
static inline int fd_dma_setup(void *data, unsigned int length,
unsigned int mode, unsigned long addr)
{
set_dma_mode(DMA_FLOPPY, mode);
__set_dma_addr(DMA_FLOPPY, data);
set_dma_count(DMA_FLOPPY, length);
virtual_dma_port = addr;
enable_dma(DMA_FLOPPY);
return 0;
}
#define fd_dma_setup fd_dma_setup
#define fd_request_dma() request_dma(DMA_FLOPPY,"floppy")
#define fd_free_dma() free_dma(DMA_FLOPPY)
#define fd_disable_dma() disable_dma(DMA_FLOPPY)
/* need to clean up dma.h */
#define DMA_FLOPPYDISK DMA_FLOPPY
/* Floppy_selects is the list of DOR's to select drive fd
*
* On initialisation, the floppy list is scanned, and the drives allocated
* in the order that they are found. This is done by seeking the drive
* to a non-zero track, and then restoring it to track 0. If an error occurs,
* then there is no floppy drive present. [to be put back in again]
*/
static unsigned char floppy_selects[4] = { 0x10, 0x21, 0x23, 0x33 };
#define FDC1 (0x3f0)
#define FLOPPY0_TYPE 4
#define FLOPPY1_TYPE 4
#define N_FDC 1
#define N_DRIVE 4
/*
* This allows people to reverse the order of
* fd0 and fd1, in case their hardware is
* strangely connected (as some RiscPCs
* and A5000s seem to be).
*/
static void driveswap(int *ints, int dummy, int dummy2)
{
swap(floppy_selects[0], floppy_selects[1]);
}
#define EXTRA_FLOPPY_PARAMS ,{ "driveswap", &driveswap, NULL, 0, 0 }
#endif
+82
View File
@@ -0,0 +1,82 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* arch/arm/include/asm/fncpy.h - helper macros for function body copying
*
* Copyright (C) 2011 Linaro Limited
*/
/*
* These macros are intended for use when there is a need to copy a low-level
* function body into special memory.
*
* For example, when reconfiguring the SDRAM controller, the code doing the
* reconfiguration may need to run from SRAM.
*
* NOTE: that the copied function body must be entirely self-contained and
* position-independent in order for this to work properly.
*
* NOTE: in order for embedded literals and data to get referenced correctly,
* the alignment of functions must be preserved when copying. To ensure this,
* the source and destination addresses for fncpy() must be aligned to a
* multiple of 8 bytes: you will be get a BUG() if this condition is not met.
* You will typically need a ".align 3" directive in the assembler where the
* function to be copied is defined, and ensure that your allocator for the
* destination buffer returns 8-byte-aligned pointers.
*
* Typical usage example:
*
* extern int f(args);
* extern uint32_t size_of_f;
* int (*copied_f)(args);
* void *sram_buffer;
*
* copied_f = fncpy(sram_buffer, &f, size_of_f);
*
* ... later, call the function: ...
*
* copied_f(args);
*
* The size of the function to be copied can't be determined from C:
* this must be determined by other means, such as adding assmbler directives
* in the file where f is defined.
*/
#ifndef __ASM_FNCPY_H
#define __ASM_FNCPY_H
#include <linux/types.h>
#include <linux/string.h>
#include <asm/bug.h>
#include <asm/cacheflush.h>
/*
* Minimum alignment requirement for the source and destination addresses
* for function copying.
*/
#define FNCPY_ALIGN 8
#define fncpy(dest_buf, funcp, size) ({ \
uintptr_t __funcp_address; \
typeof(funcp) __result; \
\
asm("" : "=r" (__funcp_address) : "0" (funcp)); \
\
/* \
* Ensure alignment of source and destination addresses, \
* disregarding the function's Thumb bit: \
*/ \
BUG_ON((uintptr_t)(dest_buf) & (FNCPY_ALIGN - 1) || \
(__funcp_address & ~(uintptr_t)1 & (FNCPY_ALIGN - 1))); \
\
memcpy(dest_buf, (void const *)(__funcp_address & ~1), size); \
flush_icache_range((unsigned long)(dest_buf), \
(unsigned long)(dest_buf) + (size)); \
\
asm("" : "=r" (__result) \
: "0" ((uintptr_t)(dest_buf) | (__funcp_address & 1))); \
\
__result; \
})
#endif /* !__ASM_FNCPY_H */
@@ -0,0 +1,79 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* arch/arm/include/asm/fpstate.h
*
* Copyright (C) 1995 Russell King
*/
#ifndef __ASM_ARM_FPSTATE_H
#define __ASM_ARM_FPSTATE_H
#ifndef __ASSEMBLY__
/*
* VFP storage area has:
* - FPEXC, FPSCR, FPINST and FPINST2.
* - 16 or 32 double precision data registers
* - an implementation-dependent word of state for FLDMX/FSTMX (pre-ARMv6)
*
* FPEXC will always be non-zero once the VFP has been used in this process.
*/
struct vfp_hard_struct {
#ifdef CONFIG_VFPv3
__u64 fpregs[32];
#else
__u64 fpregs[16];
#endif
#if __LINUX_ARM_ARCH__ < 6
__u32 fpmx_state;
#endif
__u32 fpexc;
__u32 fpscr;
/*
* VFP implementation specific state
*/
__u32 fpinst;
__u32 fpinst2;
#ifdef CONFIG_SMP
__u32 cpu;
#endif
};
union vfp_state {
struct vfp_hard_struct hard;
};
#define FP_HARD_SIZE 35
struct fp_hard_struct {
unsigned int save[FP_HARD_SIZE]; /* as yet undefined */
};
#define FP_SOFT_SIZE 35
struct fp_soft_struct {
unsigned int save[FP_SOFT_SIZE]; /* undefined information */
};
#define IWMMXT_SIZE 0x98
struct iwmmxt_struct {
unsigned int save[IWMMXT_SIZE / sizeof(unsigned int)];
};
union fp_state {
struct fp_hard_struct hard;
struct fp_soft_struct soft;
#ifdef CONFIG_IWMMXT
struct iwmmxt_struct iwmmxt;
#endif
};
#define FP_SIZE (sizeof(union fp_state) / sizeof(int))
#endif
#endif
+15
View File
@@ -0,0 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2023 SiFive
*/
#ifndef __ASM_FPU_H
#define __ASM_FPU_H
#include <asm/neon.h>
#define kernel_fpu_available() cpu_has_neon()
#define kernel_fpu_begin() kernel_neon_begin()
#define kernel_fpu_end() kernel_neon_end()
#endif /* ! __ASM_FPU_H */
+84
View File
@@ -0,0 +1,84 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_ARM_FTRACE
#define _ASM_ARM_FTRACE
#define HAVE_FUNCTION_GRAPH_FP_TEST
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
#define ARCH_SUPPORTS_FTRACE_OPS 1
#endif
#ifdef CONFIG_FUNCTION_TRACER
#define MCOUNT_ADDR ((unsigned long)(__gnu_mcount_nc))
#define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */
#ifndef __ASSEMBLY__
extern void __gnu_mcount_nc(void);
#ifdef CONFIG_DYNAMIC_FTRACE
struct dyn_arch_ftrace {
#ifdef CONFIG_ARM_MODULE_PLTS
struct module *mod;
#endif
};
static inline unsigned long ftrace_call_adjust(unsigned long addr)
{
/* With Thumb-2, the recorded addresses have the lsb set */
return addr & ~1;
}
#endif
#endif
#endif
#ifndef __ASSEMBLY__
#if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND)
/*
* return_address uses walk_stackframe to do it's work. If both
* CONFIG_FRAME_POINTER=y and CONFIG_ARM_UNWIND=y walk_stackframe uses unwind
* information. For this to work in the function tracer many functions would
* have to be marked with __notrace. So for now just depend on
* !CONFIG_ARM_UNWIND.
*/
void *return_address(unsigned int);
#else
static inline void *return_address(unsigned int level)
{
return NULL;
}
#endif
#define ftrace_return_address(n) return_address(n)
#define ARCH_HAS_SYSCALL_MATCH_SYM_NAME
static inline bool arch_syscall_match_sym_name(const char *sym,
const char *name)
{
if (!strcmp(sym, "sys_mmap2"))
sym = "sys_mmap_pgoff";
else if (!strcmp(sym, "sys_statfs64_wrapper"))
sym = "sys_statfs64";
else if (!strcmp(sym, "sys_fstatfs64_wrapper"))
sym = "sys_fstatfs64";
else if (!strcmp(sym, "sys_arm_fadvise64_64"))
sym = "sys_fadvise64_64";
/* Ignore case since sym may start with "SyS" instead of "sys" */
return !strcasecmp(sym, name);
}
void prepare_ftrace_return(unsigned long *parent, unsigned long self,
unsigned long frame_pointer,
unsigned long stack_pointer);
#endif /* ifndef __ASSEMBLY__ */
#endif /* _ASM_ARM_FTRACE */
+180
View File
@@ -0,0 +1,180 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_ARM_FUTEX_H
#define _ASM_ARM_FUTEX_H
#ifdef __KERNEL__
#include <linux/futex.h>
#include <linux/uaccess.h>
#include <asm/errno.h>
#define __futex_atomic_ex_table(err_reg) \
"3:\n" \
" .pushsection __ex_table,\"a\"\n" \
" .align 3\n" \
" .long 1b, 4f, 2b, 4f\n" \
" .popsection\n" \
" .pushsection .text.fixup,\"ax\"\n" \
" .align 2\n" \
"4: mov %0, " err_reg "\n" \
" b 3b\n" \
" .popsection"
#ifdef CONFIG_SMP
#define __futex_atomic_op(insn, ret, oldval, tmp, uaddr, oparg) \
({ \
unsigned int __ua_flags; \
smp_mb(); \
prefetchw(uaddr); \
__ua_flags = uaccess_save_and_enable(); \
__asm__ __volatile__( \
"1: ldrex %1, [%3]\n" \
" " insn "\n" \
"2: strex %2, %0, [%3]\n" \
" teq %2, #0\n" \
" bne 1b\n" \
" mov %0, #0\n" \
__futex_atomic_ex_table("%5") \
: "=&r" (ret), "=&r" (oldval), "=&r" (tmp) \
: "r" (uaddr), "r" (oparg), "Ir" (-EFAULT) \
: "cc", "memory"); \
uaccess_restore(__ua_flags); \
})
static inline int
futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
u32 oldval, u32 newval)
{
unsigned int __ua_flags;
int ret;
u32 val;
if (!access_ok(uaddr, sizeof(u32)))
return -EFAULT;
smp_mb();
/* Prefetching cannot fault */
prefetchw(uaddr);
__ua_flags = uaccess_save_and_enable();
__asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n"
"1: ldrex %1, [%4]\n"
" teq %1, %2\n"
" ite eq @ explicit IT needed for the 2b label\n"
"2: strexeq %0, %3, [%4]\n"
" movne %0, #0\n"
" teq %0, #0\n"
" bne 1b\n"
__futex_atomic_ex_table("%5")
: "=&r" (ret), "=&r" (val)
: "r" (oldval), "r" (newval), "r" (uaddr), "Ir" (-EFAULT)
: "cc", "memory");
uaccess_restore(__ua_flags);
smp_mb();
*uval = val;
return ret;
}
#else /* !SMP, we can work around lack of atomic ops by disabling preemption */
#include <linux/preempt.h>
#include <asm/domain.h>
#define __futex_atomic_op(insn, ret, oldval, tmp, uaddr, oparg) \
({ \
unsigned int __ua_flags = uaccess_save_and_enable(); \
__asm__ __volatile__( \
"1: " TUSER(ldr) " %1, [%3]\n" \
" " insn "\n" \
"2: " TUSER(str) " %0, [%3]\n" \
" mov %0, #0\n" \
__futex_atomic_ex_table("%5") \
: "=&r" (ret), "=&r" (oldval), "=&r" (tmp) \
: "r" (uaddr), "r" (oparg), "Ir" (-EFAULT) \
: "cc", "memory"); \
uaccess_restore(__ua_flags); \
})
static inline int
futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
u32 oldval, u32 newval)
{
unsigned int __ua_flags;
int ret = 0;
u32 val;
if (!access_ok(uaddr, sizeof(u32)))
return -EFAULT;
preempt_disable();
__ua_flags = uaccess_save_and_enable();
__asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n"
" .syntax unified\n"
"1: " TUSER(ldr) " %1, [%4]\n"
" teq %1, %2\n"
" it eq @ explicit IT needed for the 2b label\n"
"2: " TUSERCOND(str, eq) " %3, [%4]\n"
__futex_atomic_ex_table("%5")
: "+r" (ret), "=&r" (val)
: "r" (oldval), "r" (newval), "r" (uaddr), "Ir" (-EFAULT)
: "cc", "memory");
uaccess_restore(__ua_flags);
*uval = val;
preempt_enable();
return ret;
}
#endif /* !SMP */
static inline int
arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
{
int oldval = 0, ret, tmp;
if (!access_ok(uaddr, sizeof(u32)))
return -EFAULT;
#ifndef CONFIG_SMP
preempt_disable();
#endif
switch (op) {
case FUTEX_OP_SET:
__futex_atomic_op("mov %0, %4", ret, oldval, tmp, uaddr, oparg);
break;
case FUTEX_OP_ADD:
__futex_atomic_op("add %0, %1, %4", ret, oldval, tmp, uaddr, oparg);
break;
case FUTEX_OP_OR:
__futex_atomic_op("orr %0, %1, %4", ret, oldval, tmp, uaddr, oparg);
break;
case FUTEX_OP_ANDN:
__futex_atomic_op("and %0, %1, %4", ret, oldval, tmp, uaddr, ~oparg);
break;
case FUTEX_OP_XOR:
__futex_atomic_op("eor %0, %1, %4", ret, oldval, tmp, uaddr, oparg);
break;
default:
ret = -ENOSYS;
}
#ifndef CONFIG_SMP
preempt_enable();
#endif
/*
* Store unconditionally. If ret != 0 the extra store is the least
* of the worries but GCC cannot figure out that __futex_atomic_op()
* is either setting ret to -EFAULT or storing the old value in
* oldval which results in a uninitialized warning at the call site.
*/
*oval = oldval;
return ret;
}
#endif /* __KERNEL__ */
#endif /* _ASM_ARM_FUTEX_H */
@@ -0,0 +1,151 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* arch/arm/include/asm/glue-cache.h
*
* Copyright (C) 1999-2002 Russell King
*/
#ifndef ASM_GLUE_CACHE_H
#define ASM_GLUE_CACHE_H
#include <asm/glue.h>
/*
* Cache Model
* ===========
*/
#undef _CACHE
#undef MULTI_CACHE
#if defined(CONFIG_CPU_CACHE_V4)
# ifdef _CACHE
# define MULTI_CACHE 1
# else
# define _CACHE v4
# endif
#endif
#if defined(CONFIG_CPU_ARM920T) || defined(CONFIG_CPU_ARM922T) || \
defined(CONFIG_CPU_ARM925T) || defined(CONFIG_CPU_ARM1020) || \
defined(CONFIG_CPU_ARM1026)
# define MULTI_CACHE 1
#endif
#if defined(CONFIG_CPU_FA526)
# ifdef _CACHE
# define MULTI_CACHE 1
# else
# define _CACHE fa
# endif
#endif
#if defined(CONFIG_CPU_ARM926T)
# ifdef _CACHE
# define MULTI_CACHE 1
# else
# define _CACHE arm926
# endif
#endif
#if defined(CONFIG_CPU_ARM940T)
# ifdef _CACHE
# define MULTI_CACHE 1
# else
# define _CACHE arm940
# endif
#endif
#if defined(CONFIG_CPU_ARM946E)
# ifdef _CACHE
# define MULTI_CACHE 1
# else
# define _CACHE arm946
# endif
#endif
#if defined(CONFIG_CPU_CACHE_V4WB)
# ifdef _CACHE
# define MULTI_CACHE 1
# else
# define _CACHE v4wb
# endif
#endif
#if defined(CONFIG_CPU_XSCALE)
# ifdef _CACHE
# define MULTI_CACHE 1
# else
# define _CACHE xscale
# endif
#endif
#if defined(CONFIG_CPU_XSC3)
# ifdef _CACHE
# define MULTI_CACHE 1
# else
# define _CACHE xsc3
# endif
#endif
#if defined(CONFIG_CPU_MOHAWK)
# ifdef _CACHE
# define MULTI_CACHE 1
# else
# define _CACHE mohawk
# endif
#endif
#if defined(CONFIG_CPU_FEROCEON)
# define MULTI_CACHE 1
#endif
#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K)
# ifdef _CACHE
# define MULTI_CACHE 1
# else
# define _CACHE v6
# endif
#endif
#if defined(CONFIG_CPU_V7)
# ifdef _CACHE
# define MULTI_CACHE 1
# else
# define _CACHE v7
# endif
#endif
#if defined(CONFIG_CACHE_B15_RAC)
# define MULTI_CACHE 1
#endif
#ifdef CONFIG_CPU_CACHE_NOP
# define MULTI_CACHE 1
#endif
#if defined(CONFIG_CPU_V7M)
# define MULTI_CACHE 1
#endif
#if !defined(_CACHE) && !defined(MULTI_CACHE)
#error Unknown cache maintenance model
#endif
#ifndef MULTI_CACHE
#define __cpuc_flush_icache_all __glue(_CACHE,_flush_icache_all)
#define __cpuc_flush_kern_all __glue(_CACHE,_flush_kern_cache_all)
/* This function only has a dedicated assembly callback on the v7 cache */
#ifdef CONFIG_CPU_CACHE_V7
#define __cpuc_flush_kern_louis __glue(_CACHE,_flush_kern_cache_louis)
#else
#define __cpuc_flush_kern_louis __glue(_CACHE,_flush_kern_cache_all)
#endif
#define __cpuc_flush_user_all __glue(_CACHE,_flush_user_cache_all)
#define __cpuc_flush_user_range __glue(_CACHE,_flush_user_cache_range)
#define __cpuc_coherent_kern_range __glue(_CACHE,_coherent_kern_range)
#define __cpuc_coherent_user_range __glue(_CACHE,_coherent_user_range)
#define __cpuc_flush_dcache_area __glue(_CACHE,_flush_kern_dcache_area)
#define dmac_flush_range __glue(_CACHE,_dma_flush_range)
#endif
#endif
@@ -0,0 +1,99 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* arch/arm/include/asm/glue-df.h
*
* Copyright (C) 1997-1999 Russell King
* Copyright (C) 2000-2002 Deep Blue Solutions Ltd.
*/
#ifndef ASM_GLUE_DF_H
#define ASM_GLUE_DF_H
#include <asm/glue.h>
/*
* Data Abort Model
* ================
*
* We have the following to choose from:
* arm7 - ARM7 style
* v4_early - ARMv4 without Thumb early abort handler
* v4t_late - ARMv4 with Thumb late abort handler
* v4t_early - ARMv4 with Thumb early abort handler
* v5t_early - ARMv5 with Thumb early abort handler
* v5tj_early - ARMv5 with Thumb and Java early abort handler
* xscale - ARMv5 with Thumb with Xscale extensions
* v6_early - ARMv6 generic early abort handler
* v7_early - ARMv7 generic early abort handler
*/
#undef CPU_DABORT_HANDLER
#undef MULTI_DABORT
#ifdef CONFIG_CPU_ABRT_EV4
# ifdef CPU_DABORT_HANDLER
# define MULTI_DABORT 1
# else
# define CPU_DABORT_HANDLER v4_early_abort
# endif
#endif
#ifdef CONFIG_CPU_ABRT_LV4T
# ifdef CPU_DABORT_HANDLER
# define MULTI_DABORT 1
# else
# define CPU_DABORT_HANDLER v4t_late_abort
# endif
#endif
#ifdef CONFIG_CPU_ABRT_EV4T
# ifdef CPU_DABORT_HANDLER
# define MULTI_DABORT 1
# else
# define CPU_DABORT_HANDLER v4t_early_abort
# endif
#endif
#ifdef CONFIG_CPU_ABRT_EV5T
# ifdef CPU_DABORT_HANDLER
# define MULTI_DABORT 1
# else
# define CPU_DABORT_HANDLER v5t_early_abort
# endif
#endif
#ifdef CONFIG_CPU_ABRT_EV5TJ
# ifdef CPU_DABORT_HANDLER
# define MULTI_DABORT 1
# else
# define CPU_DABORT_HANDLER v5tj_early_abort
# endif
#endif
#ifdef CONFIG_CPU_ABRT_EV6
# ifdef CPU_DABORT_HANDLER
# define MULTI_DABORT 1
# else
# define CPU_DABORT_HANDLER v6_early_abort
# endif
#endif
#ifdef CONFIG_CPU_ABRT_EV7
# ifdef CPU_DABORT_HANDLER
# define MULTI_DABORT 1
# else
# define CPU_DABORT_HANDLER v7_early_abort
# endif
#endif
#ifdef CONFIG_CPU_ABRT_NOMMU
# ifdef CPU_DABORT_HANDLER
# define MULTI_DABORT 1
# else
# define CPU_DABORT_HANDLER nommu_early_abort
# endif
#endif
#ifndef CPU_DABORT_HANDLER
#error Unknown data abort handler type
#endif
#endif
@@ -0,0 +1,54 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* arch/arm/include/asm/glue-pf.h
*
* Copyright (C) 1997-1999 Russell King
* Copyright (C) 2000-2002 Deep Blue Solutions Ltd.
*/
#ifndef ASM_GLUE_PF_H
#define ASM_GLUE_PF_H
#include <asm/glue.h>
/*
* Prefetch Abort Model
* ================
*
* We have the following to choose from:
* legacy - no IFSR, no IFAR
* v6 - ARMv6: IFSR, no IFAR
* v7 - ARMv7: IFSR and IFAR
*/
#undef CPU_PABORT_HANDLER
#undef MULTI_PABORT
#ifdef CONFIG_CPU_PABRT_LEGACY
# ifdef CPU_PABORT_HANDLER
# define MULTI_PABORT 1
# else
# define CPU_PABORT_HANDLER legacy_pabort
# endif
#endif
#ifdef CONFIG_CPU_PABRT_V6
# ifdef CPU_PABORT_HANDLER
# define MULTI_PABORT 1
# else
# define CPU_PABORT_HANDLER v6_pabort
# endif
#endif
#ifdef CONFIG_CPU_PABRT_V7
# ifdef CPU_PABORT_HANDLER
# define MULTI_PABORT 1
# else
# define CPU_PABORT_HANDLER v7_pabort
# endif
#endif
#ifndef CPU_PABORT_HANDLER
#error Unknown prefetch abort handler type
#endif
#endif
@@ -0,0 +1,261 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* arch/arm/include/asm/glue-proc.h
*
* Copyright (C) 1997-1999 Russell King
* Copyright (C) 2000 Deep Blue Solutions Ltd
*/
#ifndef ASM_GLUE_PROC_H
#define ASM_GLUE_PROC_H
#include <asm/glue.h>
/*
* Work out if we need multiple CPU support
*/
#undef MULTI_CPU
#undef CPU_NAME
/*
* CPU_NAME - the prefix for CPU related functions
*/
#ifdef CONFIG_CPU_ARM7TDMI
# ifdef CPU_NAME
# undef MULTI_CPU
# define MULTI_CPU
# else
# define CPU_NAME cpu_arm7tdmi
# endif
#endif
#ifdef CONFIG_CPU_ARM720T
# ifdef CPU_NAME
# undef MULTI_CPU
# define MULTI_CPU
# else
# define CPU_NAME cpu_arm720
# endif
#endif
#ifdef CONFIG_CPU_ARM740T
# ifdef CPU_NAME
# undef MULTI_CPU
# define MULTI_CPU
# else
# define CPU_NAME cpu_arm740
# endif
#endif
#ifdef CONFIG_CPU_ARM9TDMI
# ifdef CPU_NAME
# undef MULTI_CPU
# define MULTI_CPU
# else
# define CPU_NAME cpu_arm9tdmi
# endif
#endif
#ifdef CONFIG_CPU_ARM920T
# ifdef CPU_NAME
# undef MULTI_CPU
# define MULTI_CPU
# else
# define CPU_NAME cpu_arm920
# endif
#endif
#ifdef CONFIG_CPU_ARM922T
# ifdef CPU_NAME
# undef MULTI_CPU
# define MULTI_CPU
# else
# define CPU_NAME cpu_arm922
# endif
#endif
#ifdef CONFIG_CPU_FA526
# ifdef CPU_NAME
# undef MULTI_CPU
# define MULTI_CPU
# else
# define CPU_NAME cpu_fa526
# endif
#endif
#ifdef CONFIG_CPU_ARM925T
# ifdef CPU_NAME
# undef MULTI_CPU
# define MULTI_CPU
# else
# define CPU_NAME cpu_arm925
# endif
#endif
#ifdef CONFIG_CPU_ARM926T
# ifdef CPU_NAME
# undef MULTI_CPU
# define MULTI_CPU
# else
# define CPU_NAME cpu_arm926
# endif
#endif
#ifdef CONFIG_CPU_ARM940T
# ifdef CPU_NAME
# undef MULTI_CPU
# define MULTI_CPU
# else
# define CPU_NAME cpu_arm940
# endif
#endif
#ifdef CONFIG_CPU_ARM946E
# ifdef CPU_NAME
# undef MULTI_CPU
# define MULTI_CPU
# else
# define CPU_NAME cpu_arm946
# endif
#endif
#ifdef CONFIG_CPU_SA110
# ifdef CPU_NAME
# undef MULTI_CPU
# define MULTI_CPU
# else
# define CPU_NAME cpu_sa110
# endif
#endif
#ifdef CONFIG_CPU_SA1100
# ifdef CPU_NAME
# undef MULTI_CPU
# define MULTI_CPU
# else
# define CPU_NAME cpu_sa1100
# endif
#endif
#ifdef CONFIG_CPU_ARM1020
# ifdef CPU_NAME
# undef MULTI_CPU
# define MULTI_CPU
# else
# define CPU_NAME cpu_arm1020
# endif
#endif
#ifdef CONFIG_CPU_ARM1020E
# ifdef CPU_NAME
# undef MULTI_CPU
# define MULTI_CPU
# else
# define CPU_NAME cpu_arm1020e
# endif
#endif
#ifdef CONFIG_CPU_ARM1022
# ifdef CPU_NAME
# undef MULTI_CPU
# define MULTI_CPU
# else
# define CPU_NAME cpu_arm1022
# endif
#endif
#ifdef CONFIG_CPU_ARM1026
# ifdef CPU_NAME
# undef MULTI_CPU
# define MULTI_CPU
# else
# define CPU_NAME cpu_arm1026
# endif
#endif
#ifdef CONFIG_CPU_XSCALE
# ifdef CPU_NAME
# undef MULTI_CPU
# define MULTI_CPU
# else
# define CPU_NAME cpu_xscale
# endif
#endif
#ifdef CONFIG_CPU_XSC3
# ifdef CPU_NAME
# undef MULTI_CPU
# define MULTI_CPU
# else
# define CPU_NAME cpu_xsc3
# endif
#endif
#ifdef CONFIG_CPU_MOHAWK
# ifdef CPU_NAME
# undef MULTI_CPU
# define MULTI_CPU
# else
# define CPU_NAME cpu_mohawk
# endif
#endif
#ifdef CONFIG_CPU_FEROCEON
# ifdef CPU_NAME
# undef MULTI_CPU
# define MULTI_CPU
# else
# define CPU_NAME cpu_feroceon
# endif
#endif
#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K)
# ifdef CPU_NAME
# undef MULTI_CPU
# define MULTI_CPU
# else
# define CPU_NAME cpu_v6
# endif
#endif
#ifdef CONFIG_CPU_V7M
# ifdef CPU_NAME
# undef MULTI_CPU
# define MULTI_CPU
# else
# define CPU_NAME cpu_v7m
# endif
#endif
#ifdef CONFIG_CPU_PJ4B
# ifdef CPU_NAME
# undef MULTI_CPU
# define MULTI_CPU
# else
# define CPU_NAME cpu_pj4b
# endif
#endif
#ifdef CONFIG_CPU_V7
/*
* Cortex-A9 needs a different suspend/resume function, so we need
* multiple CPU support for ARMv7 anyway.
*/
# undef MULTI_CPU
# define MULTI_CPU
#endif
#ifndef MULTI_CPU
#define cpu_proc_init __glue(CPU_NAME,_proc_init)
#define cpu_proc_fin __glue(CPU_NAME,_proc_fin)
#define cpu_reset __glue(CPU_NAME,_reset)
#define cpu_do_idle __glue(CPU_NAME,_do_idle)
#define cpu_dcache_clean_area __glue(CPU_NAME,_dcache_clean_area)
#define cpu_do_switch_mm __glue(CPU_NAME,_switch_mm)
#define cpu_set_pte_ext __glue(CPU_NAME,_set_pte_ext)
#define cpu_suspend_size __glue(CPU_NAME,_suspend_size)
#define cpu_do_suspend __glue(CPU_NAME,_do_suspend)
#define cpu_do_resume __glue(CPU_NAME,_do_resume)
#endif
#endif
+22
View File
@@ -0,0 +1,22 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* arch/arm/include/asm/glue.h
*
* Copyright (C) 1997-1999 Russell King
* Copyright (C) 2000-2002 Deep Blue Solutions Ltd.
*
* This file provides the glue to stick the processor-specific bits
* into the kernel in an efficient manner. The idea is to use branches
* when we're only targeting one class of TLB, or indirect calls
* when we're targeting multiple classes of TLBs.
*/
#ifdef __KERNEL__
#ifdef __STDC__
#define ____glue(name,fn) name##fn
#else
#define ____glue(name,fn) name/**/fn
#endif
#define __glue(name,fn) ____glue(name,fn)
#endif
@@ -0,0 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_HARDIRQ_H
#define __ASM_HARDIRQ_H
#include <asm/irq.h>
#define __ARCH_IRQ_EXIT_IRQS_DISABLED 1
#define ack_bad_irq ack_bad_irq
#include <asm-generic/hardirq.h>
#endif /* __ASM_HARDIRQ_H */
@@ -0,0 +1,100 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* AURORA shared L2 cache controller support
*
* Copyright (C) 2012 Marvell
*
* Yehuda Yitschak <yehuday@marvell.com>
* Gregory CLEMENT <gregory.clement@free-electrons.com>
*/
#ifndef __ASM_ARM_HARDWARE_AURORA_L2_H
#define __ASM_ARM_HARDWARE_AURORA_L2_H
#define AURORA_SYNC_REG 0x700
#define AURORA_RANGE_BASE_ADDR_REG 0x720
#define AURORA_FLUSH_PHY_ADDR_REG 0x7f0
#define AURORA_INVAL_RANGE_REG 0x774
#define AURORA_CLEAN_RANGE_REG 0x7b4
#define AURORA_FLUSH_RANGE_REG 0x7f4
#define AURORA_ACR_REPLACEMENT_OFFSET 27
#define AURORA_ACR_REPLACEMENT_MASK \
(0x3 << AURORA_ACR_REPLACEMENT_OFFSET)
#define AURORA_ACR_REPLACEMENT_TYPE_WAYRR \
(0 << AURORA_ACR_REPLACEMENT_OFFSET)
#define AURORA_ACR_REPLACEMENT_TYPE_LFSR \
(1 << AURORA_ACR_REPLACEMENT_OFFSET)
#define AURORA_ACR_REPLACEMENT_TYPE_SEMIPLRU \
(3 << AURORA_ACR_REPLACEMENT_OFFSET)
#define AURORA_ACR_PARITY_EN (1 << 21)
#define AURORA_ACR_ECC_EN (1 << 20)
#define AURORA_ACR_FORCE_WRITE_POLICY_OFFSET 0
#define AURORA_ACR_FORCE_WRITE_POLICY_MASK \
(0x3 << AURORA_ACR_FORCE_WRITE_POLICY_OFFSET)
#define AURORA_ACR_FORCE_WRITE_POLICY_DIS \
(0 << AURORA_ACR_FORCE_WRITE_POLICY_OFFSET)
#define AURORA_ACR_FORCE_WRITE_BACK_POLICY \
(1 << AURORA_ACR_FORCE_WRITE_POLICY_OFFSET)
#define AURORA_ACR_FORCE_WRITE_THRO_POLICY \
(2 << AURORA_ACR_FORCE_WRITE_POLICY_OFFSET)
#define AURORA_ERR_CNT_REG 0x600
#define AURORA_ERR_ATTR_CAP_REG 0x608
#define AURORA_ERR_ADDR_CAP_REG 0x60c
#define AURORA_ERR_WAY_CAP_REG 0x610
#define AURORA_ERR_INJECT_CTL_REG 0x614
#define AURORA_ERR_INJECT_MASK_REG 0x618
#define AURORA_ERR_CNT_CLR_OFFSET 31
#define AURORA_ERR_CNT_CLR \
(0x1 << AURORA_ERR_CNT_CLR_OFFSET)
#define AURORA_ERR_CNT_UE_OFFSET 16
#define AURORA_ERR_CNT_UE_MASK \
(0x7fff << AURORA_ERR_CNT_UE_OFFSET)
#define AURORA_ERR_CNT_CE_OFFSET 0
#define AURORA_ERR_CNT_CE_MASK \
(0xffff << AURORA_ERR_CNT_CE_OFFSET)
#define AURORA_ERR_ATTR_SRC_OFF 16
#define AURORA_ERR_ATTR_SRC_MSK \
(0x7 << AURORA_ERR_ATTR_SRC_OFF)
#define AURORA_ERR_ATTR_TXN_OFF 12
#define AURORA_ERR_ATTR_TXN_MSK \
(0xf << AURORA_ERR_ATTR_TXN_OFF)
#define AURORA_ERR_ATTR_ERR_OFF 8
#define AURORA_ERR_ATTR_ERR_MSK \
(0x3 << AURORA_ERR_ATTR_ERR_OFF)
#define AURORA_ERR_ATTR_CAP_VALID_OFF 0
#define AURORA_ERR_ATTR_CAP_VALID \
(0x1 << AURORA_ERR_ATTR_CAP_VALID_OFF)
#define AURORA_ERR_ADDR_CAP_ADDR_MASK 0xffffffe0
#define AURORA_ERR_WAY_IDX_OFF 8
#define AURORA_ERR_WAY_IDX_MSK \
(0xfff << AURORA_ERR_WAY_IDX_OFF)
#define AURORA_ERR_WAY_CAP_WAY_OFFSET 1
#define AURORA_ERR_WAY_CAP_WAY_MASK \
(0xf << AURORA_ERR_WAY_CAP_WAY_OFFSET)
#define AURORA_ERR_INJECT_CTL_ADDR_MASK 0xfffffff0
#define AURORA_ERR_ATTR_TXN_OFF 12
#define AURORA_ERR_INJECT_CTL_EN_MASK 0x3
#define AURORA_ERR_INJECT_CTL_EN_PARITY 0x2
#define AURORA_ERR_INJECT_CTL_EN_ECC 0x1
#define AURORA_MAX_RANGE_SIZE 1024
#define AURORA_WAY_SIZE_SHIFT 2
#define AURORA_CTRL_FW 0x100
/* chose a number outside L2X0_CACHE_ID_PART_MASK to be sure to make
* the distinction between a number coming from hardware and a number
* coming from the device tree */
#define AURORA_CACHE_ID 0x100
#endif /* __ASM_ARM_HARDWARE_AURORA_L2_H */
@@ -0,0 +1,10 @@
#ifndef __ASM_ARM_HARDWARE_CACHE_B15_RAC_H
#define __ASM_ARM_HARDWARE_CACHE_B15_RAC_H
#ifndef __ASSEMBLY__
void b15_flush_kern_cache_all(void);
#endif
#endif
@@ -0,0 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* arch/arm/include/asm/hardware/cache-feroceon-l2.h
*
* Copyright (C) 2008 Marvell Semiconductor
*/
extern void __init feroceon_l2_init(int l2_wt_override);
extern int __init feroceon_of_init(void);
@@ -0,0 +1,192 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* arch/arm/include/asm/hardware/cache-l2x0.h
*
* Copyright (C) 2007 ARM Limited
*/
#ifndef __ASM_ARM_HARDWARE_L2X0_H
#define __ASM_ARM_HARDWARE_L2X0_H
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/types.h>
#define L2X0_CACHE_ID 0x000
#define L2X0_CACHE_TYPE 0x004
#define L2X0_CTRL 0x100
#define L2X0_AUX_CTRL 0x104
#define L310_TAG_LATENCY_CTRL 0x108
#define L310_DATA_LATENCY_CTRL 0x10C
#define L2X0_EVENT_CNT_CTRL 0x200
#define L2X0_EVENT_CNT1_CFG 0x204
#define L2X0_EVENT_CNT0_CFG 0x208
#define L2X0_EVENT_CNT1_VAL 0x20C
#define L2X0_EVENT_CNT0_VAL 0x210
#define L2X0_INTR_MASK 0x214
#define L2X0_MASKED_INTR_STAT 0x218
#define L2X0_RAW_INTR_STAT 0x21C
#define L2X0_INTR_CLEAR 0x220
#define L2X0_CACHE_SYNC 0x730
#define L2X0_DUMMY_REG 0x740
#define L2X0_INV_LINE_PA 0x770
#define L2X0_INV_WAY 0x77C
#define L2X0_CLEAN_LINE_PA 0x7B0
#define L2X0_CLEAN_LINE_IDX 0x7B8
#define L2X0_CLEAN_WAY 0x7BC
#define L2X0_CLEAN_INV_LINE_PA 0x7F0
#define L2X0_CLEAN_INV_LINE_IDX 0x7F8
#define L2X0_CLEAN_INV_WAY 0x7FC
/*
* The lockdown registers repeat 8 times for L310, the L210 has only one
* D and one I lockdown register at 0x0900 and 0x0904.
*/
#define L2X0_LOCKDOWN_WAY_D_BASE 0x900
#define L2X0_LOCKDOWN_WAY_I_BASE 0x904
#define L2X0_LOCKDOWN_STRIDE 0x08
#define L310_ADDR_FILTER_START 0xC00
#define L310_ADDR_FILTER_END 0xC04
#define L2X0_TEST_OPERATION 0xF00
#define L2X0_LINE_DATA 0xF10
#define L2X0_LINE_TAG 0xF30
#define L2X0_DEBUG_CTRL 0xF40
#define L310_PREFETCH_CTRL 0xF60
#define L310_POWER_CTRL 0xF80
#define L310_DYNAMIC_CLK_GATING_EN (1 << 1)
#define L310_STNDBY_MODE_EN (1 << 0)
/* Registers shifts and masks */
#define L2X0_CACHE_ID_PART_MASK (0xf << 6)
#define L2X0_CACHE_ID_PART_L210 (1 << 6)
#define L2X0_CACHE_ID_PART_L220 (2 << 6)
#define L2X0_CACHE_ID_PART_L310 (3 << 6)
#define L2X0_CACHE_ID_RTL_MASK 0x3f
#define L210_CACHE_ID_RTL_R0P2_02 0x00
#define L210_CACHE_ID_RTL_R0P1 0x01
#define L210_CACHE_ID_RTL_R0P2_01 0x02
#define L210_CACHE_ID_RTL_R0P3 0x03
#define L210_CACHE_ID_RTL_R0P4 0x0b
#define L210_CACHE_ID_RTL_R0P5 0x0f
#define L220_CACHE_ID_RTL_R1P7_01REL0 0x06
#define L310_CACHE_ID_RTL_R0P0 0x00
#define L310_CACHE_ID_RTL_R1P0 0x02
#define L310_CACHE_ID_RTL_R2P0 0x04
#define L310_CACHE_ID_RTL_R3P0 0x05
#define L310_CACHE_ID_RTL_R3P1 0x06
#define L310_CACHE_ID_RTL_R3P1_50REL0 0x07
#define L310_CACHE_ID_RTL_R3P2 0x08
#define L310_CACHE_ID_RTL_R3P3 0x09
#define L2X0_EVENT_CNT_CTRL_ENABLE BIT(0)
#define L2X0_EVENT_CNT_CFG_SRC_SHIFT 2
#define L2X0_EVENT_CNT_CFG_SRC_MASK 0xf
#define L2X0_EVENT_CNT_CFG_SRC_DISABLED 0
#define L2X0_EVENT_CNT_CFG_INT_DISABLED 0
#define L2X0_EVENT_CNT_CFG_INT_INCR 1
#define L2X0_EVENT_CNT_CFG_INT_OVERFLOW 2
/* L2C auxiliary control register - bits common to L2C-210/220/310 */
#define L2C_AUX_CTRL_WAY_SIZE_SHIFT 17
#define L2C_AUX_CTRL_WAY_SIZE_MASK (7 << 17)
#define L2C_AUX_CTRL_WAY_SIZE(n) ((n) << 17)
#define L2C_AUX_CTRL_EVTMON_ENABLE BIT(20)
#define L2C_AUX_CTRL_PARITY_ENABLE BIT(21)
#define L2C_AUX_CTRL_SHARED_OVERRIDE BIT(22)
/* L2C-210/220 common bits */
#define L2X0_AUX_CTRL_DATA_RD_LATENCY_SHIFT 0
#define L2X0_AUX_CTRL_DATA_RD_LATENCY_MASK (7 << 0)
#define L2X0_AUX_CTRL_DATA_WR_LATENCY_SHIFT 3
#define L2X0_AUX_CTRL_DATA_WR_LATENCY_MASK (7 << 3)
#define L2X0_AUX_CTRL_TAG_LATENCY_SHIFT 6
#define L2X0_AUX_CTRL_TAG_LATENCY_MASK (7 << 6)
#define L2X0_AUX_CTRL_DIRTY_LATENCY_SHIFT 9
#define L2X0_AUX_CTRL_DIRTY_LATENCY_MASK (7 << 9)
#define L2X0_AUX_CTRL_ASSOC_SHIFT 13
#define L2X0_AUX_CTRL_ASSOC_MASK (15 << 13)
/* L2C-210 specific bits */
#define L210_AUX_CTRL_WRAP_DISABLE BIT(12)
#define L210_AUX_CTRL_WA_OVERRIDE BIT(23)
#define L210_AUX_CTRL_EXCLUSIVE_ABORT BIT(24)
/* L2C-220 specific bits */
#define L220_AUX_CTRL_EXCLUSIVE_CACHE BIT(12)
#define L220_AUX_CTRL_FWA_SHIFT 23
#define L220_AUX_CTRL_FWA_MASK (3 << 23)
#define L220_AUX_CTRL_NS_LOCKDOWN BIT(26)
#define L220_AUX_CTRL_NS_INT_CTRL BIT(27)
/* L2C-310 specific bits */
#define L310_AUX_CTRL_FULL_LINE_ZERO BIT(0) /* R2P0+ */
#define L310_AUX_CTRL_HIGHPRIO_SO_DEV BIT(10) /* R2P0+ */
#define L310_AUX_CTRL_STORE_LIMITATION BIT(11) /* R2P0+ */
#define L310_AUX_CTRL_EXCLUSIVE_CACHE BIT(12)
#define L310_AUX_CTRL_ASSOCIATIVITY_16 BIT(16)
#define L310_AUX_CTRL_FWA_SHIFT 23
#define L310_AUX_CTRL_FWA_MASK (3 << 23)
#define L310_AUX_CTRL_CACHE_REPLACE_RR BIT(25) /* R2P0+ */
#define L310_AUX_CTRL_NS_LOCKDOWN BIT(26)
#define L310_AUX_CTRL_NS_INT_CTRL BIT(27)
#define L310_AUX_CTRL_DATA_PREFETCH BIT(28)
#define L310_AUX_CTRL_INSTR_PREFETCH BIT(29)
#define L310_AUX_CTRL_EARLY_BRESP BIT(30) /* R2P0+ */
#define L310_LATENCY_CTRL_SETUP(n) ((n) << 0)
#define L310_LATENCY_CTRL_RD(n) ((n) << 4)
#define L310_LATENCY_CTRL_WR(n) ((n) << 8)
#define L310_ADDR_FILTER_EN 1
#define L310_PREFETCH_CTRL_OFFSET_MASK 0x1f
#define L310_PREFETCH_CTRL_DBL_LINEFILL_INCR BIT(23)
#define L310_PREFETCH_CTRL_PREFETCH_DROP BIT(24)
#define L310_PREFETCH_CTRL_DBL_LINEFILL_WRAP BIT(27)
#define L310_PREFETCH_CTRL_DATA_PREFETCH BIT(28)
#define L310_PREFETCH_CTRL_INSTR_PREFETCH BIT(29)
#define L310_PREFETCH_CTRL_DBL_LINEFILL BIT(30)
#define L2X0_CTRL_EN 1
#define L2X0_WAY_SIZE_SHIFT 3
#ifndef __ASSEMBLY__
extern void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask);
#if defined(CONFIG_CACHE_L2X0) && defined(CONFIG_OF)
extern int l2x0_of_init(u32 aux_val, u32 aux_mask);
#else
static inline int l2x0_of_init(u32 aux_val, u32 aux_mask)
{
return -ENODEV;
}
#endif
#ifdef CONFIG_CACHE_L2X0_PMU
void l2x0_pmu_register(void __iomem *base, u32 part);
void l2x0_pmu_suspend(void);
void l2x0_pmu_resume(void);
#else
static inline void l2x0_pmu_register(void __iomem *base, u32 part) {}
static inline void l2x0_pmu_suspend(void) {}
static inline void l2x0_pmu_resume(void) {}
#endif
struct l2x0_regs {
unsigned long phy_base;
unsigned long aux_ctrl;
/*
* Whether the following registers need to be saved/restored
* depends on platform
*/
unsigned long tag_latency;
unsigned long data_latency;
unsigned long filter_start;
unsigned long filter_end;
unsigned long prefetch_ctrl;
unsigned long pwr_ctrl;
unsigned long ctrl;
unsigned long aux2_ctrl;
};
extern struct l2x0_regs l2x0_saved_regs;
#endif /* __ASSEMBLY__ */
#endif
@@ -0,0 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* arch/arm/include/asm/hardware/cache-tauros2.h
*
* Copyright (C) 2008 Marvell Semiconductor
*/
#define CACHE_TAUROS2_PREFETCH_ON (1 << 0)
#define CACHE_TAUROS2_LINEFILL_BURST8 (1 << 1)
extern void __init tauros2_init(unsigned int features);
@@ -0,0 +1,21 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (C) 2015-2016 Socionext Inc.
* Author: Masahiro Yamada <yamada.masahiro@socionext.com>
*/
#ifndef __CACHE_UNIPHIER_H
#define __CACHE_UNIPHIER_H
#include <linux/errno.h>
#ifdef CONFIG_CACHE_UNIPHIER
int uniphier_cache_init(void);
#else
static inline int uniphier_cache_init(void)
{
return -ENODEV;
}
#endif
#endif /* __CACHE_UNIPHIER_H */
@@ -0,0 +1,534 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
*/
#ifndef __ASM_HARDWARE_CP14_H
#define __ASM_HARDWARE_CP14_H
#include <linux/types.h>
/* Accessors for CP14 registers */
#define dbg_read(reg) RCP14_##reg()
#define dbg_write(val, reg) WCP14_##reg(val)
#define etm_read(reg) RCP14_##reg()
#define etm_write(val, reg) WCP14_##reg(val)
/* MRC14 and MCR14 */
#define MRC14(op1, crn, crm, op2) \
({ \
u32 val; \
asm volatile("mrc p14, "#op1", %0, "#crn", "#crm", "#op2 : "=r" (val)); \
val; \
})
#define MCR14(val, op1, crn, crm, op2) \
({ \
asm volatile("mcr p14, "#op1", %0, "#crn", "#crm", "#op2 : : "r" (val));\
})
/*
* Debug Registers
*
* Available only in DBGv7
* DBGECR, DBGDSCCR, DBGDSMCR, DBGDRCR
*
* Available only in DBGv7.1
* DBGBXVRm, DBGOSDLR, DBGDEVID2, DBGDEVID1
*
* Read only
* DBGDIDR, DBGDSCRint, DBGDTRRXint, DBGDRAR, DBGOSLSR, DBGOSSRR, DBGPRSR,
* DBGPRSR, DBGDSAR, DBGAUTHSTATUS, DBGDEVID2, DBGDEVID1, DBGDEVID
*
* Write only
* DBGDTRTXint, DBGOSLAR
*/
#define RCP14_DBGDIDR() MRC14(0, c0, c0, 0)
#define RCP14_DBGDSCRint() MRC14(0, c0, c1, 0)
#define RCP14_DBGDTRRXint() MRC14(0, c0, c5, 0)
#define RCP14_DBGWFAR() MRC14(0, c0, c6, 0)
#define RCP14_DBGVCR() MRC14(0, c0, c7, 0)
#define RCP14_DBGECR() MRC14(0, c0, c9, 0)
#define RCP14_DBGDSCCR() MRC14(0, c0, c10, 0)
#define RCP14_DBGDSMCR() MRC14(0, c0, c11, 0)
#define RCP14_DBGDTRRXext() MRC14(0, c0, c0, 2)
#define RCP14_DBGDSCRext() MRC14(0, c0, c2, 2)
#define RCP14_DBGDTRTXext() MRC14(0, c0, c3, 2)
#define RCP14_DBGDRCR() MRC14(0, c0, c4, 2)
#define RCP14_DBGBVR0() MRC14(0, c0, c0, 4)
#define RCP14_DBGBVR1() MRC14(0, c0, c1, 4)
#define RCP14_DBGBVR2() MRC14(0, c0, c2, 4)
#define RCP14_DBGBVR3() MRC14(0, c0, c3, 4)
#define RCP14_DBGBVR4() MRC14(0, c0, c4, 4)
#define RCP14_DBGBVR5() MRC14(0, c0, c5, 4)
#define RCP14_DBGBVR6() MRC14(0, c0, c6, 4)
#define RCP14_DBGBVR7() MRC14(0, c0, c7, 4)
#define RCP14_DBGBVR8() MRC14(0, c0, c8, 4)
#define RCP14_DBGBVR9() MRC14(0, c0, c9, 4)
#define RCP14_DBGBVR10() MRC14(0, c0, c10, 4)
#define RCP14_DBGBVR11() MRC14(0, c0, c11, 4)
#define RCP14_DBGBVR12() MRC14(0, c0, c12, 4)
#define RCP14_DBGBVR13() MRC14(0, c0, c13, 4)
#define RCP14_DBGBVR14() MRC14(0, c0, c14, 4)
#define RCP14_DBGBVR15() MRC14(0, c0, c15, 4)
#define RCP14_DBGBCR0() MRC14(0, c0, c0, 5)
#define RCP14_DBGBCR1() MRC14(0, c0, c1, 5)
#define RCP14_DBGBCR2() MRC14(0, c0, c2, 5)
#define RCP14_DBGBCR3() MRC14(0, c0, c3, 5)
#define RCP14_DBGBCR4() MRC14(0, c0, c4, 5)
#define RCP14_DBGBCR5() MRC14(0, c0, c5, 5)
#define RCP14_DBGBCR6() MRC14(0, c0, c6, 5)
#define RCP14_DBGBCR7() MRC14(0, c0, c7, 5)
#define RCP14_DBGBCR8() MRC14(0, c0, c8, 5)
#define RCP14_DBGBCR9() MRC14(0, c0, c9, 5)
#define RCP14_DBGBCR10() MRC14(0, c0, c10, 5)
#define RCP14_DBGBCR11() MRC14(0, c0, c11, 5)
#define RCP14_DBGBCR12() MRC14(0, c0, c12, 5)
#define RCP14_DBGBCR13() MRC14(0, c0, c13, 5)
#define RCP14_DBGBCR14() MRC14(0, c0, c14, 5)
#define RCP14_DBGBCR15() MRC14(0, c0, c15, 5)
#define RCP14_DBGWVR0() MRC14(0, c0, c0, 6)
#define RCP14_DBGWVR1() MRC14(0, c0, c1, 6)
#define RCP14_DBGWVR2() MRC14(0, c0, c2, 6)
#define RCP14_DBGWVR3() MRC14(0, c0, c3, 6)
#define RCP14_DBGWVR4() MRC14(0, c0, c4, 6)
#define RCP14_DBGWVR5() MRC14(0, c0, c5, 6)
#define RCP14_DBGWVR6() MRC14(0, c0, c6, 6)
#define RCP14_DBGWVR7() MRC14(0, c0, c7, 6)
#define RCP14_DBGWVR8() MRC14(0, c0, c8, 6)
#define RCP14_DBGWVR9() MRC14(0, c0, c9, 6)
#define RCP14_DBGWVR10() MRC14(0, c0, c10, 6)
#define RCP14_DBGWVR11() MRC14(0, c0, c11, 6)
#define RCP14_DBGWVR12() MRC14(0, c0, c12, 6)
#define RCP14_DBGWVR13() MRC14(0, c0, c13, 6)
#define RCP14_DBGWVR14() MRC14(0, c0, c14, 6)
#define RCP14_DBGWVR15() MRC14(0, c0, c15, 6)
#define RCP14_DBGWCR0() MRC14(0, c0, c0, 7)
#define RCP14_DBGWCR1() MRC14(0, c0, c1, 7)
#define RCP14_DBGWCR2() MRC14(0, c0, c2, 7)
#define RCP14_DBGWCR3() MRC14(0, c0, c3, 7)
#define RCP14_DBGWCR4() MRC14(0, c0, c4, 7)
#define RCP14_DBGWCR5() MRC14(0, c0, c5, 7)
#define RCP14_DBGWCR6() MRC14(0, c0, c6, 7)
#define RCP14_DBGWCR7() MRC14(0, c0, c7, 7)
#define RCP14_DBGWCR8() MRC14(0, c0, c8, 7)
#define RCP14_DBGWCR9() MRC14(0, c0, c9, 7)
#define RCP14_DBGWCR10() MRC14(0, c0, c10, 7)
#define RCP14_DBGWCR11() MRC14(0, c0, c11, 7)
#define RCP14_DBGWCR12() MRC14(0, c0, c12, 7)
#define RCP14_DBGWCR13() MRC14(0, c0, c13, 7)
#define RCP14_DBGWCR14() MRC14(0, c0, c14, 7)
#define RCP14_DBGWCR15() MRC14(0, c0, c15, 7)
#define RCP14_DBGDRAR() MRC14(0, c1, c0, 0)
#define RCP14_DBGBXVR0() MRC14(0, c1, c0, 1)
#define RCP14_DBGBXVR1() MRC14(0, c1, c1, 1)
#define RCP14_DBGBXVR2() MRC14(0, c1, c2, 1)
#define RCP14_DBGBXVR3() MRC14(0, c1, c3, 1)
#define RCP14_DBGBXVR4() MRC14(0, c1, c4, 1)
#define RCP14_DBGBXVR5() MRC14(0, c1, c5, 1)
#define RCP14_DBGBXVR6() MRC14(0, c1, c6, 1)
#define RCP14_DBGBXVR7() MRC14(0, c1, c7, 1)
#define RCP14_DBGBXVR8() MRC14(0, c1, c8, 1)
#define RCP14_DBGBXVR9() MRC14(0, c1, c9, 1)
#define RCP14_DBGBXVR10() MRC14(0, c1, c10, 1)
#define RCP14_DBGBXVR11() MRC14(0, c1, c11, 1)
#define RCP14_DBGBXVR12() MRC14(0, c1, c12, 1)
#define RCP14_DBGBXVR13() MRC14(0, c1, c13, 1)
#define RCP14_DBGBXVR14() MRC14(0, c1, c14, 1)
#define RCP14_DBGBXVR15() MRC14(0, c1, c15, 1)
#define RCP14_DBGOSLSR() MRC14(0, c1, c1, 4)
#define RCP14_DBGOSSRR() MRC14(0, c1, c2, 4)
#define RCP14_DBGOSDLR() MRC14(0, c1, c3, 4)
#define RCP14_DBGPRCR() MRC14(0, c1, c4, 4)
#define RCP14_DBGPRSR() MRC14(0, c1, c5, 4)
#define RCP14_DBGDSAR() MRC14(0, c2, c0, 0)
#define RCP14_DBGITCTRL() MRC14(0, c7, c0, 4)
#define RCP14_DBGCLAIMSET() MRC14(0, c7, c8, 6)
#define RCP14_DBGCLAIMCLR() MRC14(0, c7, c9, 6)
#define RCP14_DBGAUTHSTATUS() MRC14(0, c7, c14, 6)
#define RCP14_DBGDEVID2() MRC14(0, c7, c0, 7)
#define RCP14_DBGDEVID1() MRC14(0, c7, c1, 7)
#define RCP14_DBGDEVID() MRC14(0, c7, c2, 7)
#define WCP14_DBGDTRTXint(val) MCR14(val, 0, c0, c5, 0)
#define WCP14_DBGWFAR(val) MCR14(val, 0, c0, c6, 0)
#define WCP14_DBGVCR(val) MCR14(val, 0, c0, c7, 0)
#define WCP14_DBGECR(val) MCR14(val, 0, c0, c9, 0)
#define WCP14_DBGDSCCR(val) MCR14(val, 0, c0, c10, 0)
#define WCP14_DBGDSMCR(val) MCR14(val, 0, c0, c11, 0)
#define WCP14_DBGDTRRXext(val) MCR14(val, 0, c0, c0, 2)
#define WCP14_DBGDSCRext(val) MCR14(val, 0, c0, c2, 2)
#define WCP14_DBGDTRTXext(val) MCR14(val, 0, c0, c3, 2)
#define WCP14_DBGDRCR(val) MCR14(val, 0, c0, c4, 2)
#define WCP14_DBGBVR0(val) MCR14(val, 0, c0, c0, 4)
#define WCP14_DBGBVR1(val) MCR14(val, 0, c0, c1, 4)
#define WCP14_DBGBVR2(val) MCR14(val, 0, c0, c2, 4)
#define WCP14_DBGBVR3(val) MCR14(val, 0, c0, c3, 4)
#define WCP14_DBGBVR4(val) MCR14(val, 0, c0, c4, 4)
#define WCP14_DBGBVR5(val) MCR14(val, 0, c0, c5, 4)
#define WCP14_DBGBVR6(val) MCR14(val, 0, c0, c6, 4)
#define WCP14_DBGBVR7(val) MCR14(val, 0, c0, c7, 4)
#define WCP14_DBGBVR8(val) MCR14(val, 0, c0, c8, 4)
#define WCP14_DBGBVR9(val) MCR14(val, 0, c0, c9, 4)
#define WCP14_DBGBVR10(val) MCR14(val, 0, c0, c10, 4)
#define WCP14_DBGBVR11(val) MCR14(val, 0, c0, c11, 4)
#define WCP14_DBGBVR12(val) MCR14(val, 0, c0, c12, 4)
#define WCP14_DBGBVR13(val) MCR14(val, 0, c0, c13, 4)
#define WCP14_DBGBVR14(val) MCR14(val, 0, c0, c14, 4)
#define WCP14_DBGBVR15(val) MCR14(val, 0, c0, c15, 4)
#define WCP14_DBGBCR0(val) MCR14(val, 0, c0, c0, 5)
#define WCP14_DBGBCR1(val) MCR14(val, 0, c0, c1, 5)
#define WCP14_DBGBCR2(val) MCR14(val, 0, c0, c2, 5)
#define WCP14_DBGBCR3(val) MCR14(val, 0, c0, c3, 5)
#define WCP14_DBGBCR4(val) MCR14(val, 0, c0, c4, 5)
#define WCP14_DBGBCR5(val) MCR14(val, 0, c0, c5, 5)
#define WCP14_DBGBCR6(val) MCR14(val, 0, c0, c6, 5)
#define WCP14_DBGBCR7(val) MCR14(val, 0, c0, c7, 5)
#define WCP14_DBGBCR8(val) MCR14(val, 0, c0, c8, 5)
#define WCP14_DBGBCR9(val) MCR14(val, 0, c0, c9, 5)
#define WCP14_DBGBCR10(val) MCR14(val, 0, c0, c10, 5)
#define WCP14_DBGBCR11(val) MCR14(val, 0, c0, c11, 5)
#define WCP14_DBGBCR12(val) MCR14(val, 0, c0, c12, 5)
#define WCP14_DBGBCR13(val) MCR14(val, 0, c0, c13, 5)
#define WCP14_DBGBCR14(val) MCR14(val, 0, c0, c14, 5)
#define WCP14_DBGBCR15(val) MCR14(val, 0, c0, c15, 5)
#define WCP14_DBGWVR0(val) MCR14(val, 0, c0, c0, 6)
#define WCP14_DBGWVR1(val) MCR14(val, 0, c0, c1, 6)
#define WCP14_DBGWVR2(val) MCR14(val, 0, c0, c2, 6)
#define WCP14_DBGWVR3(val) MCR14(val, 0, c0, c3, 6)
#define WCP14_DBGWVR4(val) MCR14(val, 0, c0, c4, 6)
#define WCP14_DBGWVR5(val) MCR14(val, 0, c0, c5, 6)
#define WCP14_DBGWVR6(val) MCR14(val, 0, c0, c6, 6)
#define WCP14_DBGWVR7(val) MCR14(val, 0, c0, c7, 6)
#define WCP14_DBGWVR8(val) MCR14(val, 0, c0, c8, 6)
#define WCP14_DBGWVR9(val) MCR14(val, 0, c0, c9, 6)
#define WCP14_DBGWVR10(val) MCR14(val, 0, c0, c10, 6)
#define WCP14_DBGWVR11(val) MCR14(val, 0, c0, c11, 6)
#define WCP14_DBGWVR12(val) MCR14(val, 0, c0, c12, 6)
#define WCP14_DBGWVR13(val) MCR14(val, 0, c0, c13, 6)
#define WCP14_DBGWVR14(val) MCR14(val, 0, c0, c14, 6)
#define WCP14_DBGWVR15(val) MCR14(val, 0, c0, c15, 6)
#define WCP14_DBGWCR0(val) MCR14(val, 0, c0, c0, 7)
#define WCP14_DBGWCR1(val) MCR14(val, 0, c0, c1, 7)
#define WCP14_DBGWCR2(val) MCR14(val, 0, c0, c2, 7)
#define WCP14_DBGWCR3(val) MCR14(val, 0, c0, c3, 7)
#define WCP14_DBGWCR4(val) MCR14(val, 0, c0, c4, 7)
#define WCP14_DBGWCR5(val) MCR14(val, 0, c0, c5, 7)
#define WCP14_DBGWCR6(val) MCR14(val, 0, c0, c6, 7)
#define WCP14_DBGWCR7(val) MCR14(val, 0, c0, c7, 7)
#define WCP14_DBGWCR8(val) MCR14(val, 0, c0, c8, 7)
#define WCP14_DBGWCR9(val) MCR14(val, 0, c0, c9, 7)
#define WCP14_DBGWCR10(val) MCR14(val, 0, c0, c10, 7)
#define WCP14_DBGWCR11(val) MCR14(val, 0, c0, c11, 7)
#define WCP14_DBGWCR12(val) MCR14(val, 0, c0, c12, 7)
#define WCP14_DBGWCR13(val) MCR14(val, 0, c0, c13, 7)
#define WCP14_DBGWCR14(val) MCR14(val, 0, c0, c14, 7)
#define WCP14_DBGWCR15(val) MCR14(val, 0, c0, c15, 7)
#define WCP14_DBGBXVR0(val) MCR14(val, 0, c1, c0, 1)
#define WCP14_DBGBXVR1(val) MCR14(val, 0, c1, c1, 1)
#define WCP14_DBGBXVR2(val) MCR14(val, 0, c1, c2, 1)
#define WCP14_DBGBXVR3(val) MCR14(val, 0, c1, c3, 1)
#define WCP14_DBGBXVR4(val) MCR14(val, 0, c1, c4, 1)
#define WCP14_DBGBXVR5(val) MCR14(val, 0, c1, c5, 1)
#define WCP14_DBGBXVR6(val) MCR14(val, 0, c1, c6, 1)
#define WCP14_DBGBXVR7(val) MCR14(val, 0, c1, c7, 1)
#define WCP14_DBGBXVR8(val) MCR14(val, 0, c1, c8, 1)
#define WCP14_DBGBXVR9(val) MCR14(val, 0, c1, c9, 1)
#define WCP14_DBGBXVR10(val) MCR14(val, 0, c1, c10, 1)
#define WCP14_DBGBXVR11(val) MCR14(val, 0, c1, c11, 1)
#define WCP14_DBGBXVR12(val) MCR14(val, 0, c1, c12, 1)
#define WCP14_DBGBXVR13(val) MCR14(val, 0, c1, c13, 1)
#define WCP14_DBGBXVR14(val) MCR14(val, 0, c1, c14, 1)
#define WCP14_DBGBXVR15(val) MCR14(val, 0, c1, c15, 1)
#define WCP14_DBGOSLAR(val) MCR14(val, 0, c1, c0, 4)
#define WCP14_DBGOSSRR(val) MCR14(val, 0, c1, c2, 4)
#define WCP14_DBGOSDLR(val) MCR14(val, 0, c1, c3, 4)
#define WCP14_DBGPRCR(val) MCR14(val, 0, c1, c4, 4)
#define WCP14_DBGITCTRL(val) MCR14(val, 0, c7, c0, 4)
#define WCP14_DBGCLAIMSET(val) MCR14(val, 0, c7, c8, 6)
#define WCP14_DBGCLAIMCLR(val) MCR14(val, 0, c7, c9, 6)
/*
* ETM Registers
*
* Available only in ETMv3.3, 3.4, 3.5
* ETMASICCR, ETMTECR2, ETMFFRR, ETMVDEVR, ETMVDCR1, ETMVDCR2, ETMVDCR3,
* ETMDCVRn, ETMDCMRn
*
* Available only in ETMv3.5 as read only
* ETMIDR2
*
* Available only in ETMv3.5, PFTv1.0, 1.1
* ETMTSEVR, ETMVMIDCVR, ETMPDCR
*
* Read only
* ETMCCR, ETMSCR, ETMIDR, ETMCCER, ETMOSLSR
* ETMLSR, ETMAUTHSTATUS, ETMDEVID, ETMDEVTYPE, ETMPIDR4, ETMPIDR5, ETMPIDR6,
* ETMPIDR7, ETMPIDR0, ETMPIDR1, ETMPIDR2, ETMPIDR2, ETMPIDR3, ETMCIDR0,
* ETMCIDR1, ETMCIDR2, ETMCIDR3
*
* Write only
* ETMOSLAR, ETMLAR
* Note: ETMCCER[11] controls WO nature of certain regs. Refer ETM arch spec.
*/
#define RCP14_ETMCR() MRC14(1, c0, c0, 0)
#define RCP14_ETMCCR() MRC14(1, c0, c1, 0)
#define RCP14_ETMTRIGGER() MRC14(1, c0, c2, 0)
#define RCP14_ETMASICCR() MRC14(1, c0, c3, 0)
#define RCP14_ETMSR() MRC14(1, c0, c4, 0)
#define RCP14_ETMSCR() MRC14(1, c0, c5, 0)
#define RCP14_ETMTSSCR() MRC14(1, c0, c6, 0)
#define RCP14_ETMTECR2() MRC14(1, c0, c7, 0)
#define RCP14_ETMTEEVR() MRC14(1, c0, c8, 0)
#define RCP14_ETMTECR1() MRC14(1, c0, c9, 0)
#define RCP14_ETMFFRR() MRC14(1, c0, c10, 0)
#define RCP14_ETMFFLR() MRC14(1, c0, c11, 0)
#define RCP14_ETMVDEVR() MRC14(1, c0, c12, 0)
#define RCP14_ETMVDCR1() MRC14(1, c0, c13, 0)
#define RCP14_ETMVDCR2() MRC14(1, c0, c14, 0)
#define RCP14_ETMVDCR3() MRC14(1, c0, c15, 0)
#define RCP14_ETMACVR0() MRC14(1, c0, c0, 1)
#define RCP14_ETMACVR1() MRC14(1, c0, c1, 1)
#define RCP14_ETMACVR2() MRC14(1, c0, c2, 1)
#define RCP14_ETMACVR3() MRC14(1, c0, c3, 1)
#define RCP14_ETMACVR4() MRC14(1, c0, c4, 1)
#define RCP14_ETMACVR5() MRC14(1, c0, c5, 1)
#define RCP14_ETMACVR6() MRC14(1, c0, c6, 1)
#define RCP14_ETMACVR7() MRC14(1, c0, c7, 1)
#define RCP14_ETMACVR8() MRC14(1, c0, c8, 1)
#define RCP14_ETMACVR9() MRC14(1, c0, c9, 1)
#define RCP14_ETMACVR10() MRC14(1, c0, c10, 1)
#define RCP14_ETMACVR11() MRC14(1, c0, c11, 1)
#define RCP14_ETMACVR12() MRC14(1, c0, c12, 1)
#define RCP14_ETMACVR13() MRC14(1, c0, c13, 1)
#define RCP14_ETMACVR14() MRC14(1, c0, c14, 1)
#define RCP14_ETMACVR15() MRC14(1, c0, c15, 1)
#define RCP14_ETMACTR0() MRC14(1, c0, c0, 2)
#define RCP14_ETMACTR1() MRC14(1, c0, c1, 2)
#define RCP14_ETMACTR2() MRC14(1, c0, c2, 2)
#define RCP14_ETMACTR3() MRC14(1, c0, c3, 2)
#define RCP14_ETMACTR4() MRC14(1, c0, c4, 2)
#define RCP14_ETMACTR5() MRC14(1, c0, c5, 2)
#define RCP14_ETMACTR6() MRC14(1, c0, c6, 2)
#define RCP14_ETMACTR7() MRC14(1, c0, c7, 2)
#define RCP14_ETMACTR8() MRC14(1, c0, c8, 2)
#define RCP14_ETMACTR9() MRC14(1, c0, c9, 2)
#define RCP14_ETMACTR10() MRC14(1, c0, c10, 2)
#define RCP14_ETMACTR11() MRC14(1, c0, c11, 2)
#define RCP14_ETMACTR12() MRC14(1, c0, c12, 2)
#define RCP14_ETMACTR13() MRC14(1, c0, c13, 2)
#define RCP14_ETMACTR14() MRC14(1, c0, c14, 2)
#define RCP14_ETMACTR15() MRC14(1, c0, c15, 2)
#define RCP14_ETMDCVR0() MRC14(1, c0, c0, 3)
#define RCP14_ETMDCVR2() MRC14(1, c0, c2, 3)
#define RCP14_ETMDCVR4() MRC14(1, c0, c4, 3)
#define RCP14_ETMDCVR6() MRC14(1, c0, c6, 3)
#define RCP14_ETMDCVR8() MRC14(1, c0, c8, 3)
#define RCP14_ETMDCVR10() MRC14(1, c0, c10, 3)
#define RCP14_ETMDCVR12() MRC14(1, c0, c12, 3)
#define RCP14_ETMDCVR14() MRC14(1, c0, c14, 3)
#define RCP14_ETMDCMR0() MRC14(1, c0, c0, 4)
#define RCP14_ETMDCMR2() MRC14(1, c0, c2, 4)
#define RCP14_ETMDCMR4() MRC14(1, c0, c4, 4)
#define RCP14_ETMDCMR6() MRC14(1, c0, c6, 4)
#define RCP14_ETMDCMR8() MRC14(1, c0, c8, 4)
#define RCP14_ETMDCMR10() MRC14(1, c0, c10, 4)
#define RCP14_ETMDCMR12() MRC14(1, c0, c12, 4)
#define RCP14_ETMDCMR14() MRC14(1, c0, c14, 4)
#define RCP14_ETMCNTRLDVR0() MRC14(1, c0, c0, 5)
#define RCP14_ETMCNTRLDVR1() MRC14(1, c0, c1, 5)
#define RCP14_ETMCNTRLDVR2() MRC14(1, c0, c2, 5)
#define RCP14_ETMCNTRLDVR3() MRC14(1, c0, c3, 5)
#define RCP14_ETMCNTENR0() MRC14(1, c0, c4, 5)
#define RCP14_ETMCNTENR1() MRC14(1, c0, c5, 5)
#define RCP14_ETMCNTENR2() MRC14(1, c0, c6, 5)
#define RCP14_ETMCNTENR3() MRC14(1, c0, c7, 5)
#define RCP14_ETMCNTRLDEVR0() MRC14(1, c0, c8, 5)
#define RCP14_ETMCNTRLDEVR1() MRC14(1, c0, c9, 5)
#define RCP14_ETMCNTRLDEVR2() MRC14(1, c0, c10, 5)
#define RCP14_ETMCNTRLDEVR3() MRC14(1, c0, c11, 5)
#define RCP14_ETMCNTVR0() MRC14(1, c0, c12, 5)
#define RCP14_ETMCNTVR1() MRC14(1, c0, c13, 5)
#define RCP14_ETMCNTVR2() MRC14(1, c0, c14, 5)
#define RCP14_ETMCNTVR3() MRC14(1, c0, c15, 5)
#define RCP14_ETMSQ12EVR() MRC14(1, c0, c0, 6)
#define RCP14_ETMSQ21EVR() MRC14(1, c0, c1, 6)
#define RCP14_ETMSQ23EVR() MRC14(1, c0, c2, 6)
#define RCP14_ETMSQ31EVR() MRC14(1, c0, c3, 6)
#define RCP14_ETMSQ32EVR() MRC14(1, c0, c4, 6)
#define RCP14_ETMSQ13EVR() MRC14(1, c0, c5, 6)
#define RCP14_ETMSQR() MRC14(1, c0, c7, 6)
#define RCP14_ETMEXTOUTEVR0() MRC14(1, c0, c8, 6)
#define RCP14_ETMEXTOUTEVR1() MRC14(1, c0, c9, 6)
#define RCP14_ETMEXTOUTEVR2() MRC14(1, c0, c10, 6)
#define RCP14_ETMEXTOUTEVR3() MRC14(1, c0, c11, 6)
#define RCP14_ETMCIDCVR0() MRC14(1, c0, c12, 6)
#define RCP14_ETMCIDCVR1() MRC14(1, c0, c13, 6)
#define RCP14_ETMCIDCVR2() MRC14(1, c0, c14, 6)
#define RCP14_ETMCIDCMR() MRC14(1, c0, c15, 6)
#define RCP14_ETMIMPSPEC0() MRC14(1, c0, c0, 7)
#define RCP14_ETMIMPSPEC1() MRC14(1, c0, c1, 7)
#define RCP14_ETMIMPSPEC2() MRC14(1, c0, c2, 7)
#define RCP14_ETMIMPSPEC3() MRC14(1, c0, c3, 7)
#define RCP14_ETMIMPSPEC4() MRC14(1, c0, c4, 7)
#define RCP14_ETMIMPSPEC5() MRC14(1, c0, c5, 7)
#define RCP14_ETMIMPSPEC6() MRC14(1, c0, c6, 7)
#define RCP14_ETMIMPSPEC7() MRC14(1, c0, c7, 7)
#define RCP14_ETMSYNCFR() MRC14(1, c0, c8, 7)
#define RCP14_ETMIDR() MRC14(1, c0, c9, 7)
#define RCP14_ETMCCER() MRC14(1, c0, c10, 7)
#define RCP14_ETMEXTINSELR() MRC14(1, c0, c11, 7)
#define RCP14_ETMTESSEICR() MRC14(1, c0, c12, 7)
#define RCP14_ETMEIBCR() MRC14(1, c0, c13, 7)
#define RCP14_ETMTSEVR() MRC14(1, c0, c14, 7)
#define RCP14_ETMAUXCR() MRC14(1, c0, c15, 7)
#define RCP14_ETMTRACEIDR() MRC14(1, c1, c0, 0)
#define RCP14_ETMIDR2() MRC14(1, c1, c2, 0)
#define RCP14_ETMVMIDCVR() MRC14(1, c1, c0, 1)
#define RCP14_ETMOSLSR() MRC14(1, c1, c1, 4)
/* Not available in PFTv1.1 */
#define RCP14_ETMOSSRR() MRC14(1, c1, c2, 4)
#define RCP14_ETMPDCR() MRC14(1, c1, c4, 4)
#define RCP14_ETMPDSR() MRC14(1, c1, c5, 4)
#define RCP14_ETMITCTRL() MRC14(1, c7, c0, 4)
#define RCP14_ETMCLAIMSET() MRC14(1, c7, c8, 6)
#define RCP14_ETMCLAIMCLR() MRC14(1, c7, c9, 6)
#define RCP14_ETMLSR() MRC14(1, c7, c13, 6)
#define RCP14_ETMAUTHSTATUS() MRC14(1, c7, c14, 6)
#define RCP14_ETMDEVID() MRC14(1, c7, c2, 7)
#define RCP14_ETMDEVTYPE() MRC14(1, c7, c3, 7)
#define RCP14_ETMPIDR4() MRC14(1, c7, c4, 7)
#define RCP14_ETMPIDR5() MRC14(1, c7, c5, 7)
#define RCP14_ETMPIDR6() MRC14(1, c7, c6, 7)
#define RCP14_ETMPIDR7() MRC14(1, c7, c7, 7)
#define RCP14_ETMPIDR0() MRC14(1, c7, c8, 7)
#define RCP14_ETMPIDR1() MRC14(1, c7, c9, 7)
#define RCP14_ETMPIDR2() MRC14(1, c7, c10, 7)
#define RCP14_ETMPIDR3() MRC14(1, c7, c11, 7)
#define RCP14_ETMCIDR0() MRC14(1, c7, c12, 7)
#define RCP14_ETMCIDR1() MRC14(1, c7, c13, 7)
#define RCP14_ETMCIDR2() MRC14(1, c7, c14, 7)
#define RCP14_ETMCIDR3() MRC14(1, c7, c15, 7)
#define WCP14_ETMCR(val) MCR14(val, 1, c0, c0, 0)
#define WCP14_ETMTRIGGER(val) MCR14(val, 1, c0, c2, 0)
#define WCP14_ETMASICCR(val) MCR14(val, 1, c0, c3, 0)
#define WCP14_ETMSR(val) MCR14(val, 1, c0, c4, 0)
#define WCP14_ETMTSSCR(val) MCR14(val, 1, c0, c6, 0)
#define WCP14_ETMTECR2(val) MCR14(val, 1, c0, c7, 0)
#define WCP14_ETMTEEVR(val) MCR14(val, 1, c0, c8, 0)
#define WCP14_ETMTECR1(val) MCR14(val, 1, c0, c9, 0)
#define WCP14_ETMFFRR(val) MCR14(val, 1, c0, c10, 0)
#define WCP14_ETMFFLR(val) MCR14(val, 1, c0, c11, 0)
#define WCP14_ETMVDEVR(val) MCR14(val, 1, c0, c12, 0)
#define WCP14_ETMVDCR1(val) MCR14(val, 1, c0, c13, 0)
#define WCP14_ETMVDCR2(val) MCR14(val, 1, c0, c14, 0)
#define WCP14_ETMVDCR3(val) MCR14(val, 1, c0, c15, 0)
#define WCP14_ETMACVR0(val) MCR14(val, 1, c0, c0, 1)
#define WCP14_ETMACVR1(val) MCR14(val, 1, c0, c1, 1)
#define WCP14_ETMACVR2(val) MCR14(val, 1, c0, c2, 1)
#define WCP14_ETMACVR3(val) MCR14(val, 1, c0, c3, 1)
#define WCP14_ETMACVR4(val) MCR14(val, 1, c0, c4, 1)
#define WCP14_ETMACVR5(val) MCR14(val, 1, c0, c5, 1)
#define WCP14_ETMACVR6(val) MCR14(val, 1, c0, c6, 1)
#define WCP14_ETMACVR7(val) MCR14(val, 1, c0, c7, 1)
#define WCP14_ETMACVR8(val) MCR14(val, 1, c0, c8, 1)
#define WCP14_ETMACVR9(val) MCR14(val, 1, c0, c9, 1)
#define WCP14_ETMACVR10(val) MCR14(val, 1, c0, c10, 1)
#define WCP14_ETMACVR11(val) MCR14(val, 1, c0, c11, 1)
#define WCP14_ETMACVR12(val) MCR14(val, 1, c0, c12, 1)
#define WCP14_ETMACVR13(val) MCR14(val, 1, c0, c13, 1)
#define WCP14_ETMACVR14(val) MCR14(val, 1, c0, c14, 1)
#define WCP14_ETMACVR15(val) MCR14(val, 1, c0, c15, 1)
#define WCP14_ETMACTR0(val) MCR14(val, 1, c0, c0, 2)
#define WCP14_ETMACTR1(val) MCR14(val, 1, c0, c1, 2)
#define WCP14_ETMACTR2(val) MCR14(val, 1, c0, c2, 2)
#define WCP14_ETMACTR3(val) MCR14(val, 1, c0, c3, 2)
#define WCP14_ETMACTR4(val) MCR14(val, 1, c0, c4, 2)
#define WCP14_ETMACTR5(val) MCR14(val, 1, c0, c5, 2)
#define WCP14_ETMACTR6(val) MCR14(val, 1, c0, c6, 2)
#define WCP14_ETMACTR7(val) MCR14(val, 1, c0, c7, 2)
#define WCP14_ETMACTR8(val) MCR14(val, 1, c0, c8, 2)
#define WCP14_ETMACTR9(val) MCR14(val, 1, c0, c9, 2)
#define WCP14_ETMACTR10(val) MCR14(val, 1, c0, c10, 2)
#define WCP14_ETMACTR11(val) MCR14(val, 1, c0, c11, 2)
#define WCP14_ETMACTR12(val) MCR14(val, 1, c0, c12, 2)
#define WCP14_ETMACTR13(val) MCR14(val, 1, c0, c13, 2)
#define WCP14_ETMACTR14(val) MCR14(val, 1, c0, c14, 2)
#define WCP14_ETMACTR15(val) MCR14(val, 1, c0, c15, 2)
#define WCP14_ETMDCVR0(val) MCR14(val, 1, c0, c0, 3)
#define WCP14_ETMDCVR2(val) MCR14(val, 1, c0, c2, 3)
#define WCP14_ETMDCVR4(val) MCR14(val, 1, c0, c4, 3)
#define WCP14_ETMDCVR6(val) MCR14(val, 1, c0, c6, 3)
#define WCP14_ETMDCVR8(val) MCR14(val, 1, c0, c8, 3)
#define WCP14_ETMDCVR10(val) MCR14(val, 1, c0, c10, 3)
#define WCP14_ETMDCVR12(val) MCR14(val, 1, c0, c12, 3)
#define WCP14_ETMDCVR14(val) MCR14(val, 1, c0, c14, 3)
#define WCP14_ETMDCMR0(val) MCR14(val, 1, c0, c0, 4)
#define WCP14_ETMDCMR2(val) MCR14(val, 1, c0, c2, 4)
#define WCP14_ETMDCMR4(val) MCR14(val, 1, c0, c4, 4)
#define WCP14_ETMDCMR6(val) MCR14(val, 1, c0, c6, 4)
#define WCP14_ETMDCMR8(val) MCR14(val, 1, c0, c8, 4)
#define WCP14_ETMDCMR10(val) MCR14(val, 1, c0, c10, 4)
#define WCP14_ETMDCMR12(val) MCR14(val, 1, c0, c12, 4)
#define WCP14_ETMDCMR14(val) MCR14(val, 1, c0, c14, 4)
#define WCP14_ETMCNTRLDVR0(val) MCR14(val, 1, c0, c0, 5)
#define WCP14_ETMCNTRLDVR1(val) MCR14(val, 1, c0, c1, 5)
#define WCP14_ETMCNTRLDVR2(val) MCR14(val, 1, c0, c2, 5)
#define WCP14_ETMCNTRLDVR3(val) MCR14(val, 1, c0, c3, 5)
#define WCP14_ETMCNTENR0(val) MCR14(val, 1, c0, c4, 5)
#define WCP14_ETMCNTENR1(val) MCR14(val, 1, c0, c5, 5)
#define WCP14_ETMCNTENR2(val) MCR14(val, 1, c0, c6, 5)
#define WCP14_ETMCNTENR3(val) MCR14(val, 1, c0, c7, 5)
#define WCP14_ETMCNTRLDEVR0(val) MCR14(val, 1, c0, c8, 5)
#define WCP14_ETMCNTRLDEVR1(val) MCR14(val, 1, c0, c9, 5)
#define WCP14_ETMCNTRLDEVR2(val) MCR14(val, 1, c0, c10, 5)
#define WCP14_ETMCNTRLDEVR3(val) MCR14(val, 1, c0, c11, 5)
#define WCP14_ETMCNTVR0(val) MCR14(val, 1, c0, c12, 5)
#define WCP14_ETMCNTVR1(val) MCR14(val, 1, c0, c13, 5)
#define WCP14_ETMCNTVR2(val) MCR14(val, 1, c0, c14, 5)
#define WCP14_ETMCNTVR3(val) MCR14(val, 1, c0, c15, 5)
#define WCP14_ETMSQ12EVR(val) MCR14(val, 1, c0, c0, 6)
#define WCP14_ETMSQ21EVR(val) MCR14(val, 1, c0, c1, 6)
#define WCP14_ETMSQ23EVR(val) MCR14(val, 1, c0, c2, 6)
#define WCP14_ETMSQ31EVR(val) MCR14(val, 1, c0, c3, 6)
#define WCP14_ETMSQ32EVR(val) MCR14(val, 1, c0, c4, 6)
#define WCP14_ETMSQ13EVR(val) MCR14(val, 1, c0, c5, 6)
#define WCP14_ETMSQR(val) MCR14(val, 1, c0, c7, 6)
#define WCP14_ETMEXTOUTEVR0(val) MCR14(val, 1, c0, c8, 6)
#define WCP14_ETMEXTOUTEVR1(val) MCR14(val, 1, c0, c9, 6)
#define WCP14_ETMEXTOUTEVR2(val) MCR14(val, 1, c0, c10, 6)
#define WCP14_ETMEXTOUTEVR3(val) MCR14(val, 1, c0, c11, 6)
#define WCP14_ETMCIDCVR0(val) MCR14(val, 1, c0, c12, 6)
#define WCP14_ETMCIDCVR1(val) MCR14(val, 1, c0, c13, 6)
#define WCP14_ETMCIDCVR2(val) MCR14(val, 1, c0, c14, 6)
#define WCP14_ETMCIDCMR(val) MCR14(val, 1, c0, c15, 6)
#define WCP14_ETMIMPSPEC0(val) MCR14(val, 1, c0, c0, 7)
#define WCP14_ETMIMPSPEC1(val) MCR14(val, 1, c0, c1, 7)
#define WCP14_ETMIMPSPEC2(val) MCR14(val, 1, c0, c2, 7)
#define WCP14_ETMIMPSPEC3(val) MCR14(val, 1, c0, c3, 7)
#define WCP14_ETMIMPSPEC4(val) MCR14(val, 1, c0, c4, 7)
#define WCP14_ETMIMPSPEC5(val) MCR14(val, 1, c0, c5, 7)
#define WCP14_ETMIMPSPEC6(val) MCR14(val, 1, c0, c6, 7)
#define WCP14_ETMIMPSPEC7(val) MCR14(val, 1, c0, c7, 7)
/* Can be read only in ETMv3.4, ETMv3.5 */
#define WCP14_ETMSYNCFR(val) MCR14(val, 1, c0, c8, 7)
#define WCP14_ETMEXTINSELR(val) MCR14(val, 1, c0, c11, 7)
#define WCP14_ETMTESSEICR(val) MCR14(val, 1, c0, c12, 7)
#define WCP14_ETMEIBCR(val) MCR14(val, 1, c0, c13, 7)
#define WCP14_ETMTSEVR(val) MCR14(val, 1, c0, c14, 7)
#define WCP14_ETMAUXCR(val) MCR14(val, 1, c0, c15, 7)
#define WCP14_ETMTRACEIDR(val) MCR14(val, 1, c1, c0, 0)
#define WCP14_ETMIDR2(val) MCR14(val, 1, c1, c2, 0)
#define WCP14_ETMVMIDCVR(val) MCR14(val, 1, c1, c0, 1)
#define WCP14_ETMOSLAR(val) MCR14(val, 1, c1, c0, 4)
/* Not available in PFTv1.1 */
#define WCP14_ETMOSSRR(val) MCR14(val, 1, c1, c2, 4)
#define WCP14_ETMPDCR(val) MCR14(val, 1, c1, c4, 4)
#define WCP14_ETMPDSR(val) MCR14(val, 1, c1, c5, 4)
#define WCP14_ETMITCTRL(val) MCR14(val, 1, c7, c0, 4)
#define WCP14_ETMCLAIMSET(val) MCR14(val, 1, c7, c8, 6)
#define WCP14_ETMCLAIMCLR(val) MCR14(val, 1, c7, c9, 6)
/* Writes to this from CP14 interface are ignored */
#define WCP14_ETMLAR(val) MCR14(val, 1, c7, c12, 6)
#endif
@@ -0,0 +1,138 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* arch/arm/include/asm/hardware/dec21285.h
*
* Copyright (C) 1998 Russell King
*
* DC21285 registers
*/
#define DC21285_PCI_IACK 0x79000000
#define DC21285_ARMCSR_BASE 0x42000000
#define DC21285_PCI_TYPE_0_CONFIG 0x7b000000
#define DC21285_PCI_TYPE_1_CONFIG 0x7a000000
#define DC21285_OUTBOUND_WRITE_FLUSH 0x78000000
#define DC21285_FLASH 0x41000000
#define DC21285_PCI_IO 0x7c000000
#define DC21285_PCI_MEM 0x80000000
#ifndef __ASSEMBLY__
#include <mach/hardware.h>
#define DC21285_IO(x) ((volatile unsigned long *)(ARMCSR_BASE+(x)))
#else
#define DC21285_IO(x) (x)
#endif
/*
* The footbridge is programmed to expose the system RAM at 0xe0000000.
* The requirement is that the RAM isn't placed at bus address 0, which
* would clash with VGA cards.
*/
#define BUS_OFFSET 0xe0000000
#define CSR_PCICMD DC21285_IO(0x0004)
#define CSR_CLASSREV DC21285_IO(0x0008)
#define CSR_PCICACHELINESIZE DC21285_IO(0x000c)
#define CSR_PCICSRBASE DC21285_IO(0x0010)
#define CSR_PCICSRIOBASE DC21285_IO(0x0014)
#define CSR_PCISDRAMBASE DC21285_IO(0x0018)
#define CSR_PCIROMBASE DC21285_IO(0x0030)
#define CSR_MBOX0 DC21285_IO(0x0050)
#define CSR_MBOX1 DC21285_IO(0x0054)
#define CSR_MBOX2 DC21285_IO(0x0058)
#define CSR_MBOX3 DC21285_IO(0x005c)
#define CSR_DOORBELL DC21285_IO(0x0060)
#define CSR_DOORBELL_SETUP DC21285_IO(0x0064)
#define CSR_ROMWRITEREG DC21285_IO(0x0068)
#define CSR_CSRBASEMASK DC21285_IO(0x00f8)
#define CSR_CSRBASEOFFSET DC21285_IO(0x00fc)
#define CSR_SDRAMBASEMASK DC21285_IO(0x0100)
#define CSR_SDRAMBASEOFFSET DC21285_IO(0x0104)
#define CSR_ROMBASEMASK DC21285_IO(0x0108)
#define CSR_SDRAMTIMING DC21285_IO(0x010c)
#define CSR_SDRAMADDRSIZE0 DC21285_IO(0x0110)
#define CSR_SDRAMADDRSIZE1 DC21285_IO(0x0114)
#define CSR_SDRAMADDRSIZE2 DC21285_IO(0x0118)
#define CSR_SDRAMADDRSIZE3 DC21285_IO(0x011c)
#define CSR_I2O_INFREEHEAD DC21285_IO(0x0120)
#define CSR_I2O_INPOSTTAIL DC21285_IO(0x0124)
#define CSR_I2O_OUTPOSTHEAD DC21285_IO(0x0128)
#define CSR_I2O_OUTFREETAIL DC21285_IO(0x012c)
#define CSR_I2O_INFREECOUNT DC21285_IO(0x0130)
#define CSR_I2O_OUTPOSTCOUNT DC21285_IO(0x0134)
#define CSR_I2O_INPOSTCOUNT DC21285_IO(0x0138)
#define CSR_SA110_CNTL DC21285_IO(0x013c)
#define SA110_CNTL_INITCMPLETE (1 << 0)
#define SA110_CNTL_ASSERTSERR (1 << 1)
#define SA110_CNTL_RXSERR (1 << 3)
#define SA110_CNTL_SA110DRAMPARITY (1 << 4)
#define SA110_CNTL_PCISDRAMPARITY (1 << 5)
#define SA110_CNTL_DMASDRAMPARITY (1 << 6)
#define SA110_CNTL_DISCARDTIMER (1 << 8)
#define SA110_CNTL_PCINRESET (1 << 9)
#define SA110_CNTL_I2O_256 (0 << 10)
#define SA110_CNTL_I20_512 (1 << 10)
#define SA110_CNTL_I2O_1024 (2 << 10)
#define SA110_CNTL_I2O_2048 (3 << 10)
#define SA110_CNTL_I2O_4096 (4 << 10)
#define SA110_CNTL_I2O_8192 (5 << 10)
#define SA110_CNTL_I2O_16384 (6 << 10)
#define SA110_CNTL_I2O_32768 (7 << 10)
#define SA110_CNTL_WATCHDOG (1 << 13)
#define SA110_CNTL_ROMWIDTH_UNDEF (0 << 14)
#define SA110_CNTL_ROMWIDTH_16 (1 << 14)
#define SA110_CNTL_ROMWIDTH_32 (2 << 14)
#define SA110_CNTL_ROMWIDTH_8 (3 << 14)
#define SA110_CNTL_ROMACCESSTIME(x) ((x)<<16)
#define SA110_CNTL_ROMBURSTTIME(x) ((x)<<20)
#define SA110_CNTL_ROMTRISTATETIME(x) ((x)<<24)
#define SA110_CNTL_XCSDIR(x) ((x)<<28)
#define SA110_CNTL_PCICFN (1 << 31)
#define CSR_PCIADDR_EXTN DC21285_IO(0x0140)
#define CSR_PREFETCHMEMRANGE DC21285_IO(0x0144)
#define CSR_XBUS_CYCLE DC21285_IO(0x0148)
#define CSR_XBUS_IOSTROBE DC21285_IO(0x014c)
#define CSR_DOORBELL_PCI DC21285_IO(0x0150)
#define CSR_DOORBELL_SA110 DC21285_IO(0x0154)
#define CSR_UARTDR DC21285_IO(0x0160)
#define CSR_RXSTAT DC21285_IO(0x0164)
#define CSR_H_UBRLCR DC21285_IO(0x0168)
#define CSR_M_UBRLCR DC21285_IO(0x016c)
#define CSR_L_UBRLCR DC21285_IO(0x0170)
#define CSR_UARTCON DC21285_IO(0x0174)
#define CSR_UARTFLG DC21285_IO(0x0178)
#define CSR_IRQ_STATUS DC21285_IO(0x0180)
#define CSR_IRQ_RAWSTATUS DC21285_IO(0x0184)
#define CSR_IRQ_ENABLE DC21285_IO(0x0188)
#define CSR_IRQ_DISABLE DC21285_IO(0x018c)
#define CSR_IRQ_SOFT DC21285_IO(0x0190)
#define CSR_FIQ_STATUS DC21285_IO(0x0280)
#define CSR_FIQ_RAWSTATUS DC21285_IO(0x0284)
#define CSR_FIQ_ENABLE DC21285_IO(0x0288)
#define CSR_FIQ_DISABLE DC21285_IO(0x028c)
#define CSR_FIQ_SOFT DC21285_IO(0x0290)
#define CSR_TIMER1_LOAD DC21285_IO(0x0300)
#define CSR_TIMER1_VALUE DC21285_IO(0x0304)
#define CSR_TIMER1_CNTL DC21285_IO(0x0308)
#define CSR_TIMER1_CLR DC21285_IO(0x030c)
#define CSR_TIMER2_LOAD DC21285_IO(0x0320)
#define CSR_TIMER2_VALUE DC21285_IO(0x0324)
#define CSR_TIMER2_CNTL DC21285_IO(0x0328)
#define CSR_TIMER2_CLR DC21285_IO(0x032c)
#define CSR_TIMER3_LOAD DC21285_IO(0x0340)
#define CSR_TIMER3_VALUE DC21285_IO(0x0344)
#define CSR_TIMER3_CNTL DC21285_IO(0x0348)
#define CSR_TIMER3_CLR DC21285_IO(0x034c)
#define CSR_TIMER4_LOAD DC21285_IO(0x0360)
#define CSR_TIMER4_VALUE DC21285_IO(0x0364)
#define CSR_TIMER4_CNTL DC21285_IO(0x0368)
#define CSR_TIMER4_CLR DC21285_IO(0x036c)
#define TIMER_CNTL_ENABLE (1 << 7)
#define TIMER_CNTL_AUTORELOAD (1 << 6)
#define TIMER_CNTL_DIV1 (0)
#define TIMER_CNTL_DIV16 (1 << 2)
#define TIMER_CNTL_DIV256 (2 << 2)
#define TIMER_CNTL_CNTEXT (3 << 2)
@@ -0,0 +1,69 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* arch/arm/include/asm/hardware/ioc.h
*
* Copyright (C) Russell King
*
* Use these macros to read/write the IOC. All it does is perform the actual
* read/write.
*/
#ifndef __ASMARM_HARDWARE_IOC_H
#define __ASMARM_HARDWARE_IOC_H
#ifndef __ASSEMBLY__
/*
* We use __raw_base variants here so that we give the compiler the
* chance to keep IOC_BASE in a register.
*/
#define ioc_readb(off) __raw_readb(IOC_BASE + (off))
#define ioc_writeb(val,off) __raw_writeb(val, IOC_BASE + (off))
#endif
#define IOC_CONTROL (0x00)
#define IOC_KARTTX (0x04)
#define IOC_KARTRX (0x04)
#define IOC_IRQSTATA (0x10)
#define IOC_IRQREQA (0x14)
#define IOC_IRQCLRA (0x14)
#define IOC_IRQMASKA (0x18)
#define IOC_IRQSTATB (0x20)
#define IOC_IRQREQB (0x24)
#define IOC_IRQMASKB (0x28)
#define IOC_FIQSTAT (0x30)
#define IOC_FIQREQ (0x34)
#define IOC_FIQMASK (0x38)
#define IOC_T0CNTL (0x40)
#define IOC_T0LTCHL (0x40)
#define IOC_T0CNTH (0x44)
#define IOC_T0LTCHH (0x44)
#define IOC_T0GO (0x48)
#define IOC_T0LATCH (0x4c)
#define IOC_T1CNTL (0x50)
#define IOC_T1LTCHL (0x50)
#define IOC_T1CNTH (0x54)
#define IOC_T1LTCHH (0x54)
#define IOC_T1GO (0x58)
#define IOC_T1LATCH (0x5c)
#define IOC_T2CNTL (0x60)
#define IOC_T2LTCHL (0x60)
#define IOC_T2CNTH (0x64)
#define IOC_T2LTCHH (0x64)
#define IOC_T2GO (0x68)
#define IOC_T2LATCH (0x6c)
#define IOC_T3CNTL (0x70)
#define IOC_T3LTCHL (0x70)
#define IOC_T3CNTH (0x74)
#define IOC_T3LTCHH (0x74)
#define IOC_T3GO (0x78)
#define IOC_T3LATCH (0x7c)
#endif
@@ -0,0 +1,182 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* arch/arm/include/asm/hardware/iomd.h
*
* Copyright (C) 1999 Russell King
*
* This file contains information out the IOMD ASIC used in the
* Acorn RiscPC and subsequently integrated into the CLPS7500 chips.
*/
#ifndef __ASMARM_HARDWARE_IOMD_H
#define __ASMARM_HARDWARE_IOMD_H
#ifndef __ASSEMBLY__
/*
* We use __raw_base variants here so that we give the compiler the
* chance to keep IOC_BASE in a register.
*/
#define iomd_readb(off) __raw_readb(IOMD_BASE + (off))
#define iomd_readl(off) __raw_readl(IOMD_BASE + (off))
#define iomd_writeb(val,off) __raw_writeb(val, IOMD_BASE + (off))
#define iomd_writel(val,off) __raw_writel(val, IOMD_BASE + (off))
#endif
#define IOMD_CONTROL (0x000)
#define IOMD_KARTTX (0x004)
#define IOMD_KARTRX (0x004)
#define IOMD_KCTRL (0x008)
#define IOMD_IRQSTATA (0x010)
#define IOMD_IRQREQA (0x014)
#define IOMD_IRQCLRA (0x014)
#define IOMD_IRQMASKA (0x018)
#define IOMD_IRQSTATB (0x020)
#define IOMD_IRQREQB (0x024)
#define IOMD_IRQMASKB (0x028)
#define IOMD_FIQSTAT (0x030)
#define IOMD_FIQREQ (0x034)
#define IOMD_FIQMASK (0x038)
#define IOMD_T0CNTL (0x040)
#define IOMD_T0LTCHL (0x040)
#define IOMD_T0CNTH (0x044)
#define IOMD_T0LTCHH (0x044)
#define IOMD_T0GO (0x048)
#define IOMD_T0LATCH (0x04c)
#define IOMD_T1CNTL (0x050)
#define IOMD_T1LTCHL (0x050)
#define IOMD_T1CNTH (0x054)
#define IOMD_T1LTCHH (0x054)
#define IOMD_T1GO (0x058)
#define IOMD_T1LATCH (0x05c)
#define IOMD_ROMCR0 (0x080)
#define IOMD_ROMCR1 (0x084)
#ifdef CONFIG_ARCH_RPC
#define IOMD_DRAMCR (0x088)
#endif
#define IOMD_REFCR (0x08C)
#define IOMD_FSIZE (0x090)
#define IOMD_ID0 (0x094)
#define IOMD_ID1 (0x098)
#define IOMD_VERSION (0x09C)
#ifdef CONFIG_ARCH_RPC
#define IOMD_MOUSEX (0x0A0)
#define IOMD_MOUSEY (0x0A4)
#endif
#ifdef CONFIG_ARCH_RPC
#define IOMD_DMATCR (0x0C0)
#endif
#define IOMD_IOTCR (0x0C4)
#define IOMD_ECTCR (0x0C8)
#ifdef CONFIG_ARCH_RPC
#define IOMD_DMAEXT (0x0CC)
#endif
#ifdef CONFIG_ARCH_RPC
#define DMA_EXT_IO0 1
#define DMA_EXT_IO1 2
#define DMA_EXT_IO2 4
#define DMA_EXT_IO3 8
#define IOMD_IO0CURA (0x100)
#define IOMD_IO0ENDA (0x104)
#define IOMD_IO0CURB (0x108)
#define IOMD_IO0ENDB (0x10C)
#define IOMD_IO0CR (0x110)
#define IOMD_IO0ST (0x114)
#define IOMD_IO1CURA (0x120)
#define IOMD_IO1ENDA (0x124)
#define IOMD_IO1CURB (0x128)
#define IOMD_IO1ENDB (0x12C)
#define IOMD_IO1CR (0x130)
#define IOMD_IO1ST (0x134)
#define IOMD_IO2CURA (0x140)
#define IOMD_IO2ENDA (0x144)
#define IOMD_IO2CURB (0x148)
#define IOMD_IO2ENDB (0x14C)
#define IOMD_IO2CR (0x150)
#define IOMD_IO2ST (0x154)
#define IOMD_IO3CURA (0x160)
#define IOMD_IO3ENDA (0x164)
#define IOMD_IO3CURB (0x168)
#define IOMD_IO3ENDB (0x16C)
#define IOMD_IO3CR (0x170)
#define IOMD_IO3ST (0x174)
#endif
#define IOMD_SD0CURA (0x180)
#define IOMD_SD0ENDA (0x184)
#define IOMD_SD0CURB (0x188)
#define IOMD_SD0ENDB (0x18C)
#define IOMD_SD0CR (0x190)
#define IOMD_SD0ST (0x194)
#ifdef CONFIG_ARCH_RPC
#define IOMD_SD1CURA (0x1A0)
#define IOMD_SD1ENDA (0x1A4)
#define IOMD_SD1CURB (0x1A8)
#define IOMD_SD1ENDB (0x1AC)
#define IOMD_SD1CR (0x1B0)
#define IOMD_SD1ST (0x1B4)
#endif
#define IOMD_CURSCUR (0x1C0)
#define IOMD_CURSINIT (0x1C4)
#define IOMD_VIDCUR (0x1D0)
#define IOMD_VIDEND (0x1D4)
#define IOMD_VIDSTART (0x1D8)
#define IOMD_VIDINIT (0x1DC)
#define IOMD_VIDCR (0x1E0)
#define IOMD_DMASTAT (0x1F0)
#define IOMD_DMAREQ (0x1F4)
#define IOMD_DMAMASK (0x1F8)
#define DMA_END_S (1 << 31)
#define DMA_END_L (1 << 30)
#define DMA_CR_C 0x80
#define DMA_CR_D 0x40
#define DMA_CR_E 0x20
#define DMA_ST_OFL 4
#define DMA_ST_INT 2
#define DMA_ST_AB 1
/*
* DMA (MEMC) compatibility
*/
#define HALF_SAM vram_half_sam
#define VDMA_ALIGNMENT (HALF_SAM * 2)
#define VDMA_XFERSIZE (HALF_SAM)
#define VDMA_INIT IOMD_VIDINIT
#define VDMA_START IOMD_VIDSTART
#define VDMA_END IOMD_VIDEND
#ifndef __ASSEMBLY__
extern unsigned int vram_half_sam;
#define video_set_dma(start,end,offset) \
do { \
outl (SCREEN_START + start, VDMA_START); \
outl (SCREEN_START + end - VDMA_XFERSIZE, VDMA_END); \
if (offset >= end - VDMA_XFERSIZE) \
offset |= 0x40000000; \
outl (SCREEN_START + offset, VDMA_INIT); \
} while (0)
#endif
#endif
@@ -0,0 +1,217 @@
/*
* arch/arm/include/asm/hardware/locomo.h
*
* This file contains the definitions for the LoCoMo G/A Chip
*
* (C) Copyright 2004 John Lenz
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* Based on sa1111.h
*/
#ifndef _ASM_ARCH_LOCOMO
#define _ASM_ARCH_LOCOMO
#define locomo_writel(val,addr) ({ *(volatile u16 *)(addr) = (val); })
#define locomo_readl(addr) (*(volatile u16 *)(addr))
/* LOCOMO version */
#define LOCOMO_VER 0x00
/* Pin status */
#define LOCOMO_ST 0x04
/* Pin status */
#define LOCOMO_C32K 0x08
/* Interrupt controller */
#define LOCOMO_ICR 0x0C
/* MCS decoder for boot selecting */
#define LOCOMO_MCSX0 0x10
#define LOCOMO_MCSX1 0x14
#define LOCOMO_MCSX2 0x18
#define LOCOMO_MCSX3 0x1c
/* Touch panel controller */
#define LOCOMO_ASD 0x20 /* AD start delay */
#define LOCOMO_HSD 0x28 /* HSYS delay */
#define LOCOMO_HSC 0x2c /* HSYS period */
#define LOCOMO_TADC 0x30 /* tablet ADC clock */
/* Long time timer */
#define LOCOMO_LTC 0xd8 /* LTC interrupt setting */
#define LOCOMO_LTINT 0xdc /* LTC interrupt */
/* DAC control signal for LCD (COMADJ ) */
#define LOCOMO_DAC 0xe0
/* DAC control */
#define LOCOMO_DAC_SCLOEB 0x08 /* SCL pin output data */
#define LOCOMO_DAC_TEST 0x04 /* Test bit */
#define LOCOMO_DAC_SDA 0x02 /* SDA pin level (read-only) */
#define LOCOMO_DAC_SDAOEB 0x01 /* SDA pin output data */
/* SPI interface */
#define LOCOMO_SPI 0x60
#define LOCOMO_SPIMD 0x00 /* SPI mode setting */
#define LOCOMO_SPICT 0x04 /* SPI mode control */
#define LOCOMO_SPIST 0x08 /* SPI status */
#define LOCOMO_SPI_TEND (1 << 3) /* Transfer end bit */
#define LOCOMO_SPI_REND (1 << 2) /* Receive end bit */
#define LOCOMO_SPI_RFW (1 << 1) /* write buffer bit */
#define LOCOMO_SPI_RFR (1) /* read buffer bit */
#define LOCOMO_SPIIS 0x10 /* SPI interrupt status */
#define LOCOMO_SPIWE 0x14 /* SPI interrupt status write enable */
#define LOCOMO_SPIIE 0x18 /* SPI interrupt enable */
#define LOCOMO_SPIIR 0x1c /* SPI interrupt request */
#define LOCOMO_SPITD 0x20 /* SPI transfer data write */
#define LOCOMO_SPIRD 0x24 /* SPI receive data read */
#define LOCOMO_SPITS 0x28 /* SPI transfer data shift */
#define LOCOMO_SPIRS 0x2C /* SPI receive data shift */
/* GPIO */
#define LOCOMO_GPD 0x90 /* GPIO direction */
#define LOCOMO_GPE 0x94 /* GPIO input enable */
#define LOCOMO_GPL 0x98 /* GPIO level */
#define LOCOMO_GPO 0x9c /* GPIO out data setting */
#define LOCOMO_GRIE 0xa0 /* GPIO rise detection */
#define LOCOMO_GFIE 0xa4 /* GPIO fall detection */
#define LOCOMO_GIS 0xa8 /* GPIO edge detection status */
#define LOCOMO_GWE 0xac /* GPIO status write enable */
#define LOCOMO_GIE 0xb0 /* GPIO interrupt enable */
#define LOCOMO_GIR 0xb4 /* GPIO interrupt request */
#define LOCOMO_GPIO(Nb) (0x01 << (Nb))
#define LOCOMO_GPIO_RTS LOCOMO_GPIO(0)
#define LOCOMO_GPIO_CTS LOCOMO_GPIO(1)
#define LOCOMO_GPIO_DSR LOCOMO_GPIO(2)
#define LOCOMO_GPIO_DTR LOCOMO_GPIO(3)
#define LOCOMO_GPIO_LCD_VSHA_ON LOCOMO_GPIO(4)
#define LOCOMO_GPIO_LCD_VSHD_ON LOCOMO_GPIO(5)
#define LOCOMO_GPIO_LCD_VEE_ON LOCOMO_GPIO(6)
#define LOCOMO_GPIO_LCD_MOD LOCOMO_GPIO(7)
#define LOCOMO_GPIO_DAC_ON LOCOMO_GPIO(8)
#define LOCOMO_GPIO_FL_VR LOCOMO_GPIO(9)
#define LOCOMO_GPIO_DAC_SDATA LOCOMO_GPIO(10)
#define LOCOMO_GPIO_DAC_SCK LOCOMO_GPIO(11)
#define LOCOMO_GPIO_DAC_SLOAD LOCOMO_GPIO(12)
#define LOCOMO_GPIO_CARD_DETECT LOCOMO_GPIO(13)
#define LOCOMO_GPIO_WRITE_PROT LOCOMO_GPIO(14)
#define LOCOMO_GPIO_CARD_POWER LOCOMO_GPIO(15)
/* Start the definitions of the devices. Each device has an initial
* base address and a series of offsets from that base address. */
/* Keyboard controller */
#define LOCOMO_KEYBOARD 0x40
#define LOCOMO_KIB 0x00 /* KIB level */
#define LOCOMO_KSC 0x04 /* KSTRB control */
#define LOCOMO_KCMD 0x08 /* KSTRB command */
#define LOCOMO_KIC 0x0c /* Key interrupt */
/* Front light adjustment controller */
#define LOCOMO_FRONTLIGHT 0xc8
#define LOCOMO_ALS 0x00 /* Adjust light cycle */
#define LOCOMO_ALD 0x04 /* Adjust light duty */
#define LOCOMO_ALC_EN 0x8000
/* Backlight controller: TFT signal */
#define LOCOMO_BACKLIGHT 0x38
#define LOCOMO_TC 0x00 /* TFT control signal */
#define LOCOMO_CPSD 0x04 /* CPS delay */
/* Audio controller */
#define LOCOMO_AUDIO 0x54
#define LOCOMO_ACC 0x00 /* Audio clock */
#define LOCOMO_PAIF 0xD0 /* PCM audio interface */
/* Audio clock */
#define LOCOMO_ACC_XON 0x80
#define LOCOMO_ACC_XEN 0x40
#define LOCOMO_ACC_XSEL0 0x00
#define LOCOMO_ACC_XSEL1 0x20
#define LOCOMO_ACC_MCLKEN 0x10
#define LOCOMO_ACC_64FSEN 0x08
#define LOCOMO_ACC_CLKSEL000 0x00 /* mclk 2 */
#define LOCOMO_ACC_CLKSEL001 0x01 /* mclk 3 */
#define LOCOMO_ACC_CLKSEL010 0x02 /* mclk 4 */
#define LOCOMO_ACC_CLKSEL011 0x03 /* mclk 6 */
#define LOCOMO_ACC_CLKSEL100 0x04 /* mclk 8 */
#define LOCOMO_ACC_CLKSEL101 0x05 /* mclk 12 */
/* PCM audio interface */
#define LOCOMO_PAIF_SCINV 0x20
#define LOCOMO_PAIF_SCEN 0x10
#define LOCOMO_PAIF_LRCRST 0x08
#define LOCOMO_PAIF_LRCEVE 0x04
#define LOCOMO_PAIF_LRCINV 0x02
#define LOCOMO_PAIF_LRCEN 0x01
/* LED controller */
#define LOCOMO_LED 0xe8
#define LOCOMO_LPT0 0x00
#define LOCOMO_LPT1 0x04
/* LED control */
#define LOCOMO_LPT_TOFH 0x80
#define LOCOMO_LPT_TOFL 0x08
#define LOCOMO_LPT_TOH(TOH) ((TOH & 0x7) << 4)
#define LOCOMO_LPT_TOL(TOL) ((TOL & 0x7))
#define LOCOMO_DEVID_KEYBOARD 0
#define LOCOMO_DEVID_FRONTLIGHT 1
#define LOCOMO_DEVID_BACKLIGHT 2
#define LOCOMO_DEVID_AUDIO 3
#define LOCOMO_DEVID_LED 4
#define LOCOMO_DEVID_UART 5
#define LOCOMO_DEVID_SPI 6
struct locomo_dev {
struct device dev;
unsigned int devid;
unsigned int irq[1];
void *mapbase;
unsigned long length;
u64 dma_mask;
};
#define LOCOMO_DEV(_d) container_of((_d), struct locomo_dev, dev)
#define locomo_get_drvdata(d) dev_get_drvdata(&(d)->dev)
#define locomo_set_drvdata(d,p) dev_set_drvdata(&(d)->dev, p)
struct locomo_driver {
struct device_driver drv;
unsigned int devid;
int (*probe)(struct locomo_dev *);
void (*remove)(struct locomo_dev *);
};
#define LOCOMO_DRV(_d) container_of_const((_d), struct locomo_driver, drv)
#define LOCOMO_DRIVER_NAME(_ldev) ((_ldev)->dev.driver->name)
extern void locomolcd_power(int on);
int locomo_driver_register(struct locomo_driver *);
void locomo_driver_unregister(struct locomo_driver *);
/* GPIO control functions */
void locomo_gpio_set_dir(struct device *dev, unsigned int bits, unsigned int dir);
int locomo_gpio_read_level(struct device *dev, unsigned int bits);
int locomo_gpio_read_output(struct device *dev, unsigned int bits);
void locomo_gpio_write(struct device *dev, unsigned int bits, unsigned int set);
/* M62332 control function */
void locomo_m62332_senddata(struct locomo_dev *ldev, unsigned int dac_data, int channel);
/* Frontlight control */
void locomo_frontlight_set(struct locomo_dev *dev, int duty, int vr, int bpwf);
struct locomo_platform_data {
int irq_base; /* IRQ base for cascaded on-chip IRQs */
};
#endif
@@ -0,0 +1,23 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* arch/arm/include/asm/hardware/memc.h
*
* Copyright (C) Russell King.
*/
#define VDMA_ALIGNMENT PAGE_SIZE
#define VDMA_XFERSIZE 16
#define VDMA_INIT 0
#define VDMA_START 1
#define VDMA_END 2
#ifndef __ASSEMBLY__
extern void memc_write(unsigned int reg, unsigned long val);
#define video_set_dma(start,end,offset) \
do { \
memc_write (VDMA_START, (start >> 2)); \
memc_write (VDMA_END, (end - VDMA_XFERSIZE) >> 2); \
memc_write (VDMA_INIT, (offset >> 2)); \
} while (0)
#endif
@@ -0,0 +1,442 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* arch/arm/include/asm/hardware/sa1111.h
*
* Copyright (C) 2000 John G Dorsey <john+@cs.cmu.edu>
*
* This file contains definitions for the SA-1111 Companion Chip.
* (Structure and naming borrowed from SA-1101.h, by Peter Danielsson.)
*
* Macro that calculates real address for registers in the SA-1111
*/
#ifndef _ASM_ARCH_SA1111
#define _ASM_ARCH_SA1111
/*
* Don't ask the (SAC) DMA engines to move less than this amount.
*/
#define SA1111_SAC_DMA_MIN_XFER (0x800)
/*
* System Bus Interface (SBI)
*
* Registers
* SKCR Control Register
* SMCR Shared Memory Controller Register
* SKID ID Register
*/
#define SA1111_SKCR 0x0000
#define SA1111_SMCR 0x0004
#define SA1111_SKID 0x0008
#define SKCR_PLL_BYPASS (1<<0)
#define SKCR_RCLKEN (1<<1)
#define SKCR_SLEEP (1<<2)
#define SKCR_DOZE (1<<3)
#define SKCR_VCO_OFF (1<<4)
#define SKCR_SCANTSTEN (1<<5)
#define SKCR_CLKTSTEN (1<<6)
#define SKCR_RDYEN (1<<7)
#define SKCR_SELAC (1<<8)
#define SKCR_OPPC (1<<9)
#define SKCR_PLLTSTEN (1<<10)
#define SKCR_USBIOTSTEN (1<<11)
/*
* Don't believe the specs! Take them, throw them outside. Leave them
* there for a week. Spit on them. Walk on them. Stamp on them.
* Pour gasoline over them and finally burn them. Now think about coding.
* - The October 1999 errata (278260-007) says its bit 13, 1 to enable.
* - The Feb 2001 errata (278260-010) says that the previous errata
* (278260-009) is wrong, and its bit actually 12, fixed in spec
* 278242-003.
* - The SA1111 manual (278242) says bit 12, but 0 to enable.
* - Reality is bit 13, 1 to enable.
* -- rmk
*/
#define SKCR_OE_EN (1<<13)
#define SMCR_DTIM (1<<0)
#define SMCR_MBGE (1<<1)
#define SMCR_DRAC_0 (1<<2)
#define SMCR_DRAC_1 (1<<3)
#define SMCR_DRAC_2 (1<<4)
#define SMCR_DRAC Fld(3, 2)
#define SMCR_CLAT (1<<5)
#define SKID_SIREV_MASK (0x000000f0)
#define SKID_MTREV_MASK (0x0000000f)
#define SKID_ID_MASK (0xffffff00)
#define SKID_SA1111_ID (0x690cc200)
/*
* System Controller
*
* Registers
* SKPCR Power Control Register
* SKCDR Clock Divider Register
* SKAUD Audio Clock Divider Register
* SKPMC PS/2 Mouse Clock Divider Register
* SKPTC PS/2 Track Pad Clock Divider Register
* SKPEN0 PWM0 Enable Register
* SKPWM0 PWM0 Clock Register
* SKPEN1 PWM1 Enable Register
* SKPWM1 PWM1 Clock Register
*/
#define SA1111_SKPCR 0x0200
#define SA1111_SKCDR 0x0204
#define SA1111_SKAUD 0x0208
#define SA1111_SKPMC 0x020c
#define SA1111_SKPTC 0x0210
#define SA1111_SKPEN0 0x0214
#define SA1111_SKPWM0 0x0218
#define SA1111_SKPEN1 0x021c
#define SA1111_SKPWM1 0x0220
#define SKPCR_UCLKEN (1<<0)
#define SKPCR_ACCLKEN (1<<1)
#define SKPCR_I2SCLKEN (1<<2)
#define SKPCR_L3CLKEN (1<<3)
#define SKPCR_SCLKEN (1<<4)
#define SKPCR_PMCLKEN (1<<5)
#define SKPCR_PTCLKEN (1<<6)
#define SKPCR_DCLKEN (1<<7)
#define SKPCR_PWMCLKEN (1<<8)
/* USB Host controller */
#define SA1111_USB 0x0400
/*
* Serial Audio Controller
*
* Registers
* SACR0 Serial Audio Common Control Register
* SACR1 Serial Audio Alternate Mode (I2C/MSB) Control Register
* SACR2 Serial Audio AC-link Control Register
* SASR0 Serial Audio I2S/MSB Interface & FIFO Status Register
* SASR1 Serial Audio AC-link Interface & FIFO Status Register
* SASCR Serial Audio Status Clear Register
* L3_CAR L3 Control Bus Address Register
* L3_CDR L3 Control Bus Data Register
* ACCAR AC-link Command Address Register
* ACCDR AC-link Command Data Register
* ACSAR AC-link Status Address Register
* ACSDR AC-link Status Data Register
* SADTCS Serial Audio DMA Transmit Control/Status Register
* SADTSA Serial Audio DMA Transmit Buffer Start Address A
* SADTCA Serial Audio DMA Transmit Buffer Count Register A
* SADTSB Serial Audio DMA Transmit Buffer Start Address B
* SADTCB Serial Audio DMA Transmit Buffer Count Register B
* SADRCS Serial Audio DMA Receive Control/Status Register
* SADRSA Serial Audio DMA Receive Buffer Start Address A
* SADRCA Serial Audio DMA Receive Buffer Count Register A
* SADRSB Serial Audio DMA Receive Buffer Start Address B
* SADRCB Serial Audio DMA Receive Buffer Count Register B
* SAITR Serial Audio Interrupt Test Register
* SADR Serial Audio Data Register (16 x 32-bit)
*/
#define SA1111_SERAUDIO 0x0600
/*
* These are offsets from the above base.
*/
#define SA1111_SACR0 0x00
#define SA1111_SACR1 0x04
#define SA1111_SACR2 0x08
#define SA1111_SASR0 0x0c
#define SA1111_SASR1 0x10
#define SA1111_SASCR 0x18
#define SA1111_L3_CAR 0x1c
#define SA1111_L3_CDR 0x20
#define SA1111_ACCAR 0x24
#define SA1111_ACCDR 0x28
#define SA1111_ACSAR 0x2c
#define SA1111_ACSDR 0x30
#define SA1111_SADTCS 0x34
#define SA1111_SADTSA 0x38
#define SA1111_SADTCA 0x3c
#define SA1111_SADTSB 0x40
#define SA1111_SADTCB 0x44
#define SA1111_SADRCS 0x48
#define SA1111_SADRSA 0x4c
#define SA1111_SADRCA 0x50
#define SA1111_SADRSB 0x54
#define SA1111_SADRCB 0x58
#define SA1111_SAITR 0x5c
#define SA1111_SADR 0x80
#ifndef CONFIG_ARCH_PXA
#define SACR0_ENB (1<<0)
#define SACR0_BCKD (1<<2)
#define SACR0_RST (1<<3)
#define SACR1_AMSL (1<<0)
#define SACR1_L3EN (1<<1)
#define SACR1_L3MB (1<<2)
#define SACR1_DREC (1<<3)
#define SACR1_DRPL (1<<4)
#define SACR1_ENLBF (1<<5)
#define SACR2_TS3V (1<<0)
#define SACR2_TS4V (1<<1)
#define SACR2_WKUP (1<<2)
#define SACR2_DREC (1<<3)
#define SACR2_DRPL (1<<4)
#define SACR2_ENLBF (1<<5)
#define SACR2_RESET (1<<6)
#define SASR0_TNF (1<<0)
#define SASR0_RNE (1<<1)
#define SASR0_BSY (1<<2)
#define SASR0_TFS (1<<3)
#define SASR0_RFS (1<<4)
#define SASR0_TUR (1<<5)
#define SASR0_ROR (1<<6)
#define SASR0_L3WD (1<<16)
#define SASR0_L3RD (1<<17)
#define SASR1_TNF (1<<0)
#define SASR1_RNE (1<<1)
#define SASR1_BSY (1<<2)
#define SASR1_TFS (1<<3)
#define SASR1_RFS (1<<4)
#define SASR1_TUR (1<<5)
#define SASR1_ROR (1<<6)
#define SASR1_CADT (1<<16)
#define SASR1_SADR (1<<17)
#define SASR1_RSTO (1<<18)
#define SASR1_CLPM (1<<19)
#define SASR1_CRDY (1<<20)
#define SASR1_RS3V (1<<21)
#define SASR1_RS4V (1<<22)
#define SASCR_TUR (1<<5)
#define SASCR_ROR (1<<6)
#define SASCR_DTS (1<<16)
#define SASCR_RDD (1<<17)
#define SASCR_STO (1<<18)
#define SADTCS_TDEN (1<<0)
#define SADTCS_TDIE (1<<1)
#define SADTCS_TDBDA (1<<3)
#define SADTCS_TDSTA (1<<4)
#define SADTCS_TDBDB (1<<5)
#define SADTCS_TDSTB (1<<6)
#define SADTCS_TBIU (1<<7)
#define SADRCS_RDEN (1<<0)
#define SADRCS_RDIE (1<<1)
#define SADRCS_RDBDA (1<<3)
#define SADRCS_RDSTA (1<<4)
#define SADRCS_RDBDB (1<<5)
#define SADRCS_RDSTB (1<<6)
#define SADRCS_RBIU (1<<7)
#define SAD_CS_DEN (1<<0)
#define SAD_CS_DIE (1<<1) /* Not functional on metal 1 */
#define SAD_CS_DBDA (1<<3) /* Not functional on metal 1 */
#define SAD_CS_DSTA (1<<4)
#define SAD_CS_DBDB (1<<5) /* Not functional on metal 1 */
#define SAD_CS_DSTB (1<<6)
#define SAD_CS_BIU (1<<7) /* Not functional on metal 1 */
#define SAITR_TFS (1<<0)
#define SAITR_RFS (1<<1)
#define SAITR_TUR (1<<2)
#define SAITR_ROR (1<<3)
#define SAITR_CADT (1<<4)
#define SAITR_SADR (1<<5)
#define SAITR_RSTO (1<<6)
#define SAITR_TDBDA (1<<8)
#define SAITR_TDBDB (1<<9)
#define SAITR_RDBDA (1<<10)
#define SAITR_RDBDB (1<<11)
#endif /* !CONFIG_ARCH_PXA */
/*
* General-Purpose I/O Interface
*
* Registers
* PA_DDR GPIO Block A Data Direction
* PA_DRR/PA_DWR GPIO Block A Data Value Register (read/write)
* PA_SDR GPIO Block A Sleep Direction
* PA_SSR GPIO Block A Sleep State
* PB_DDR GPIO Block B Data Direction
* PB_DRR/PB_DWR GPIO Block B Data Value Register (read/write)
* PB_SDR GPIO Block B Sleep Direction
* PB_SSR GPIO Block B Sleep State
* PC_DDR GPIO Block C Data Direction
* PC_DRR/PC_DWR GPIO Block C Data Value Register (read/write)
* PC_SDR GPIO Block C Sleep Direction
* PC_SSR GPIO Block C Sleep State
*/
#define SA1111_GPIO 0x1000
#define SA1111_GPIO_PADDR (0x000)
#define SA1111_GPIO_PADRR (0x004)
#define SA1111_GPIO_PADWR (0x004)
#define SA1111_GPIO_PASDR (0x008)
#define SA1111_GPIO_PASSR (0x00c)
#define SA1111_GPIO_PBDDR (0x010)
#define SA1111_GPIO_PBDRR (0x014)
#define SA1111_GPIO_PBDWR (0x014)
#define SA1111_GPIO_PBSDR (0x018)
#define SA1111_GPIO_PBSSR (0x01c)
#define SA1111_GPIO_PCDDR (0x020)
#define SA1111_GPIO_PCDRR (0x024)
#define SA1111_GPIO_PCDWR (0x024)
#define SA1111_GPIO_PCSDR (0x028)
#define SA1111_GPIO_PCSSR (0x02c)
#define GPIO_A0 (1 << 0)
#define GPIO_A1 (1 << 1)
#define GPIO_A2 (1 << 2)
#define GPIO_A3 (1 << 3)
#define GPIO_B0 (1 << 8)
#define GPIO_B1 (1 << 9)
#define GPIO_B2 (1 << 10)
#define GPIO_B3 (1 << 11)
#define GPIO_B4 (1 << 12)
#define GPIO_B5 (1 << 13)
#define GPIO_B6 (1 << 14)
#define GPIO_B7 (1 << 15)
#define GPIO_C0 (1 << 16)
#define GPIO_C1 (1 << 17)
#define GPIO_C2 (1 << 18)
#define GPIO_C3 (1 << 19)
#define GPIO_C4 (1 << 20)
#define GPIO_C5 (1 << 21)
#define GPIO_C6 (1 << 22)
#define GPIO_C7 (1 << 23)
/*
* Interrupt Controller
*
* Registers
* INTTEST0 Test register 0
* INTTEST1 Test register 1
* INTEN0 Interrupt Enable register 0
* INTEN1 Interrupt Enable register 1
* INTPOL0 Interrupt Polarity selection 0
* INTPOL1 Interrupt Polarity selection 1
* INTTSTSEL Interrupt source selection
* INTSTATCLR0 Interrupt Status/Clear 0
* INTSTATCLR1 Interrupt Status/Clear 1
* INTSET0 Interrupt source set 0
* INTSET1 Interrupt source set 1
* WAKE_EN0 Wake-up source enable 0
* WAKE_EN1 Wake-up source enable 1
* WAKE_POL0 Wake-up polarity selection 0
* WAKE_POL1 Wake-up polarity selection 1
*/
#define SA1111_INTC 0x1600
/*
* These are offsets from the above base.
*/
#define SA1111_INTTEST0 0x0000
#define SA1111_INTTEST1 0x0004
#define SA1111_INTEN0 0x0008
#define SA1111_INTEN1 0x000c
#define SA1111_INTPOL0 0x0010
#define SA1111_INTPOL1 0x0014
#define SA1111_INTTSTSEL 0x0018
#define SA1111_INTSTATCLR0 0x001c
#define SA1111_INTSTATCLR1 0x0020
#define SA1111_INTSET0 0x0024
#define SA1111_INTSET1 0x0028
#define SA1111_WAKEEN0 0x002c
#define SA1111_WAKEEN1 0x0030
#define SA1111_WAKEPOL0 0x0034
#define SA1111_WAKEPOL1 0x0038
/* PS/2 Trackpad and Mouse Interfaces */
#define SA1111_KBD 0x0a00
#define SA1111_MSE 0x0c00
/* PCMCIA Interface */
#define SA1111_PCMCIA 0x1600
extern const struct bus_type sa1111_bus_type;
#define SA1111_DEVID_SBI (1 << 0)
#define SA1111_DEVID_SK (1 << 1)
#define SA1111_DEVID_USB (1 << 2)
#define SA1111_DEVID_SAC (1 << 3)
#define SA1111_DEVID_SSP (1 << 4)
#define SA1111_DEVID_PS2 (3 << 5)
#define SA1111_DEVID_PS2_KBD (1 << 5)
#define SA1111_DEVID_PS2_MSE (1 << 6)
#define SA1111_DEVID_GPIO (1 << 7)
#define SA1111_DEVID_INT (1 << 8)
#define SA1111_DEVID_PCMCIA (1 << 9)
struct sa1111_dev {
struct device dev;
unsigned int devid;
struct resource res;
void __iomem *mapbase;
unsigned int skpcr_mask;
unsigned int hwirq[6];
u64 dma_mask;
};
#define to_sa1111_device(x) container_of(x, struct sa1111_dev, dev)
#define sa1111_get_drvdata(d) dev_get_drvdata(&(d)->dev)
#define sa1111_set_drvdata(d,p) dev_set_drvdata(&(d)->dev, p)
struct sa1111_driver {
struct device_driver drv;
unsigned int devid;
int (*probe)(struct sa1111_dev *);
void (*remove)(struct sa1111_dev *);
};
#define SA1111_DRV(_d) container_of_const((_d), struct sa1111_driver, drv)
#define SA1111_DRIVER_NAME(_sadev) ((_sadev)->dev.driver->name)
/*
* These frob the SKPCR register, and call platform specific
* enable/disable functions.
*/
int sa1111_enable_device(struct sa1111_dev *);
void sa1111_disable_device(struct sa1111_dev *);
int sa1111_get_irq(struct sa1111_dev *, unsigned num);
unsigned int sa1111_pll_clock(struct sa1111_dev *);
#define SA1111_AUDIO_ACLINK 0
#define SA1111_AUDIO_I2S 1
void sa1111_select_audio_mode(struct sa1111_dev *sadev, int mode);
int sa1111_set_audio_rate(struct sa1111_dev *sadev, int rate);
int sa1111_get_audio_rate(struct sa1111_dev *sadev);
int sa1111_check_dma_bug(dma_addr_t addr);
int sa1111_driver_register(struct sa1111_driver *);
void sa1111_driver_unregister(struct sa1111_driver *);
struct sa1111_platform_data {
int irq_base; /* base for cascaded on-chip IRQs */
unsigned disable_devs;
void *data;
int (*enable)(void *, unsigned);
void (*disable)(void *, unsigned);
};
#endif /* _ASM_ARCH_SA1111 */
@@ -0,0 +1,67 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Definitions for the SCOOP interface found on various Sharp PDAs
*
* Copyright (c) 2004 Richard Purdie
*/
#define SCOOP_MCR 0x00
#define SCOOP_CDR 0x04
#define SCOOP_CSR 0x08
#define SCOOP_CPR 0x0C
#define SCOOP_CCR 0x10
#define SCOOP_IRR 0x14
#define SCOOP_IRM 0x14
#define SCOOP_IMR 0x18
#define SCOOP_ISR 0x1C
#define SCOOP_GPCR 0x20
#define SCOOP_GPWR 0x24
#define SCOOP_GPRR 0x28
#define SCOOP_CPR_OUT (1 << 7)
#define SCOOP_CPR_SD_3V (1 << 2)
#define SCOOP_CPR_CF_XV (1 << 1)
#define SCOOP_CPR_CF_3V (1 << 0)
#define SCOOP_GPCR_PA22 (1 << 12)
#define SCOOP_GPCR_PA21 (1 << 11)
#define SCOOP_GPCR_PA20 (1 << 10)
#define SCOOP_GPCR_PA19 (1 << 9)
#define SCOOP_GPCR_PA18 (1 << 8)
#define SCOOP_GPCR_PA17 (1 << 7)
#define SCOOP_GPCR_PA16 (1 << 6)
#define SCOOP_GPCR_PA15 (1 << 5)
#define SCOOP_GPCR_PA14 (1 << 4)
#define SCOOP_GPCR_PA13 (1 << 3)
#define SCOOP_GPCR_PA12 (1 << 2)
#define SCOOP_GPCR_PA11 (1 << 1)
struct scoop_config {
unsigned short io_out;
unsigned short io_dir;
unsigned short suspend_clr;
unsigned short suspend_set;
int gpio_base;
};
/* Structure for linking scoop devices to PCMCIA sockets */
struct scoop_pcmcia_dev {
struct device *dev; /* Pointer to this socket's scoop device */
int irq; /* irq for socket */
int cd_irq;
const char *cd_irq_str;
unsigned char keep_vs;
unsigned char keep_rd;
};
struct scoop_pcmcia_config {
struct scoop_pcmcia_dev *devs;
int num_devs;
void (*power_ctrl)(struct device *scoop, unsigned short cpr, int nr);
};
extern struct scoop_pcmcia_config *platform_scoop_config;
void reset_scoop(struct device *dev);
unsigned short read_scoop_reg(struct device *dev, unsigned short reg);
void write_scoop_reg(struct device *dev, unsigned short reg, unsigned short data);
@@ -0,0 +1,25 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* ssp.h
*
* Copyright (C) 2003 Russell King, All Rights Reserved.
*/
#ifndef SSP_H
#define SSP_H
struct ssp_state {
unsigned int cr0;
unsigned int cr1;
};
int ssp_write_word(u16 data);
int ssp_read_word(u16 *data);
int ssp_flush(void);
void ssp_enable(void);
void ssp_disable(void);
void ssp_save_state(struct ssp_state *ssp);
void ssp_restore_state(struct ssp_state *ssp);
int ssp_init(void);
void ssp_exit(void);
#endif
@@ -0,0 +1,78 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_HIGHMEM_H
#define _ASM_HIGHMEM_H
#include <asm/cachetype.h>
#include <asm/fixmap.h>
#define PKMAP_BASE (PAGE_OFFSET - PMD_SIZE)
#define LAST_PKMAP PTRS_PER_PTE
#define LAST_PKMAP_MASK (LAST_PKMAP - 1)
#define PKMAP_NR(virt) (((virt) - PKMAP_BASE) >> PAGE_SHIFT)
#define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT))
#define flush_cache_kmaps() \
do { \
if (cache_is_vivt()) \
flush_cache_all(); \
} while (0)
extern pte_t *pkmap_page_table;
/*
* The reason for kmap_high_get() is to ensure that the currently kmap'd
* page usage count does not decrease to zero while we're using its
* existing virtual mapping in an atomic context. With a VIVT cache this
* is essential to do, but with a VIPT cache this is only an optimization
* so not to pay the price of establishing a second mapping if an existing
* one can be used. However, on platforms without hardware TLB maintenance
* broadcast, we simply cannot use ARCH_NEEDS_KMAP_HIGH_GET at all since
* the locking involved must also disable IRQs which is incompatible with
* the IPI mechanism used by global TLB operations.
*/
#define ARCH_NEEDS_KMAP_HIGH_GET
#if defined(CONFIG_SMP) && defined(CONFIG_CPU_TLB_V6)
#undef ARCH_NEEDS_KMAP_HIGH_GET
#if defined(CONFIG_HIGHMEM) && defined(CONFIG_CPU_CACHE_VIVT)
#error "The sum of features in your kernel config cannot be supported together"
#endif
#endif
/*
* Needed to be able to broadcast the TLB invalidation for kmap.
*/
#ifdef CONFIG_ARM_ERRATA_798181
#undef ARCH_NEEDS_KMAP_HIGH_GET
#endif
#ifdef ARCH_NEEDS_KMAP_HIGH_GET
extern void *kmap_high_get(const struct page *page);
static inline void *arch_kmap_local_high_get(const struct page *page)
{
if (IS_ENABLED(CONFIG_DEBUG_HIGHMEM) && !cache_is_vivt())
return NULL;
return kmap_high_get(page);
}
#define arch_kmap_local_high_get arch_kmap_local_high_get
#else /* ARCH_NEEDS_KMAP_HIGH_GET */
static inline void *kmap_high_get(const struct page *page)
{
return NULL;
}
#endif /* !ARCH_NEEDS_KMAP_HIGH_GET */
#define arch_kmap_local_post_map(vaddr, pteval) \
local_flush_tlb_kernel_page(vaddr)
#define arch_kmap_local_pre_unmap(vaddr) \
do { \
if (cache_is_vivt()) \
__cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE); \
} while (0)
#define arch_kmap_local_post_unmap(vaddr) \
local_flush_tlb_kernel_page(vaddr)
#endif
@@ -0,0 +1,29 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* arch/arm/include/asm/hugetlb-3level.h
*
* Copyright (C) 2012 ARM Ltd.
*
* Based on arch/x86/include/asm/hugetlb.h.
*/
#ifndef _ASM_ARM_HUGETLB_3LEVEL_H
#define _ASM_ARM_HUGETLB_3LEVEL_H
/*
* If our huge pte is non-zero then mark the valid bit.
* This allows pte_present(huge_ptep_get(mm,addr,ptep)) to return true for non-zero
* ptes.
* (The valid bit is automatically cleared by set_pte_at for PROT_NONE ptes).
*/
#define __HAVE_ARCH_HUGE_PTEP_GET
static inline pte_t huge_ptep_get(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
{
pte_t retval = *ptep;
if (pte_val(retval))
pte_val(retval) |= L_PTE_VALID;
return retval;
}
#endif /* _ASM_ARM_HUGETLB_3LEVEL_H */
@@ -0,0 +1,24 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* arch/arm/include/asm/hugetlb.h
*
* Copyright (C) 2012 ARM Ltd.
*
* Based on arch/x86/include/asm/hugetlb.h
*/
#ifndef _ASM_ARM_HUGETLB_H
#define _ASM_ARM_HUGETLB_H
#include <asm/cacheflush.h>
#include <asm/page.h>
#include <asm/hugetlb-3level.h>
#include <asm-generic/hugetlb.h>
static inline void arch_clear_hugetlb_flags(struct folio *folio)
{
clear_bit(PG_dcache_clean, &folio->flags.f);
}
#define arch_clear_hugetlb_flags arch_clear_hugetlb_flags
#endif /* _ASM_ARM_HUGETLB_H */
@@ -0,0 +1,146 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ARM_HW_BREAKPOINT_H
#define _ARM_HW_BREAKPOINT_H
#ifdef __KERNEL__
struct task_struct;
#ifdef CONFIG_HAVE_HW_BREAKPOINT
struct arch_hw_breakpoint_ctrl {
u32 __reserved : 9,
mismatch : 1,
: 9,
len : 8,
type : 2,
privilege : 2,
enabled : 1;
};
struct arch_hw_breakpoint {
u32 address;
u32 trigger;
struct arch_hw_breakpoint_ctrl step_ctrl;
struct arch_hw_breakpoint_ctrl ctrl;
};
static inline u32 encode_ctrl_reg(struct arch_hw_breakpoint_ctrl ctrl)
{
return (ctrl.mismatch << 22) | (ctrl.len << 5) | (ctrl.type << 3) |
(ctrl.privilege << 1) | ctrl.enabled;
}
static inline void decode_ctrl_reg(u32 reg,
struct arch_hw_breakpoint_ctrl *ctrl)
{
ctrl->enabled = reg & 0x1;
reg >>= 1;
ctrl->privilege = reg & 0x3;
reg >>= 2;
ctrl->type = reg & 0x3;
reg >>= 2;
ctrl->len = reg & 0xff;
reg >>= 17;
ctrl->mismatch = reg & 0x1;
}
/* Debug architecture numbers. */
#define ARM_DEBUG_ARCH_RESERVED 0 /* In case of ptrace ABI updates. */
#define ARM_DEBUG_ARCH_V6 1
#define ARM_DEBUG_ARCH_V6_1 2
#define ARM_DEBUG_ARCH_V7_ECP14 3
#define ARM_DEBUG_ARCH_V7_MM 4
#define ARM_DEBUG_ARCH_V7_1 5
#define ARM_DEBUG_ARCH_V8 6
#define ARM_DEBUG_ARCH_V8_1 7
#define ARM_DEBUG_ARCH_V8_2 8
#define ARM_DEBUG_ARCH_V8_4 9
/* Breakpoint */
#define ARM_BREAKPOINT_EXECUTE 0
/* Watchpoints */
#define ARM_BREAKPOINT_LOAD 1
#define ARM_BREAKPOINT_STORE 2
#define ARM_FSR_ACCESS_MASK (1 << 11)
/* Privilege Levels */
#define ARM_BREAKPOINT_PRIV 1
#define ARM_BREAKPOINT_USER 2
/* Lengths */
#define ARM_BREAKPOINT_LEN_1 0x1
#define ARM_BREAKPOINT_LEN_2 0x3
#define ARM_BREAKPOINT_LEN_4 0xf
#define ARM_BREAKPOINT_LEN_8 0xff
/* Limits */
#define ARM_MAX_BRP 16
#define ARM_MAX_WRP 16
#define ARM_MAX_HBP_SLOTS (ARM_MAX_BRP + ARM_MAX_WRP)
/* DSCR method of entry bits. */
#define ARM_DSCR_MOE(x) ((x >> 2) & 0xf)
#define ARM_ENTRY_BREAKPOINT 0x1
#define ARM_ENTRY_ASYNC_WATCHPOINT 0x2
#define ARM_ENTRY_CFI_BREAKPOINT 0x3
#define ARM_ENTRY_SYNC_WATCHPOINT 0xa
/* DSCR monitor/halting bits. */
#define ARM_DSCR_HDBGEN (1 << 14)
#define ARM_DSCR_MDBGEN (1 << 15)
/* OSLSR os lock model bits */
#define ARM_OSLSR_OSLM0 (1 << 0)
/* opcode2 numbers for the co-processor instructions. */
#define ARM_OP2_BVR 4
#define ARM_OP2_BCR 5
#define ARM_OP2_WVR 6
#define ARM_OP2_WCR 7
/* Base register numbers for the debug registers. */
#define ARM_BASE_BVR 64
#define ARM_BASE_BCR 80
#define ARM_BASE_WVR 96
#define ARM_BASE_WCR 112
/* Accessor macros for the debug registers. */
#define ARM_DBG_READ(N, M, OP2, VAL) do {\
asm volatile("mrc p14, 0, %0, " #N "," #M ", " #OP2 : "=r" (VAL));\
} while (0)
#define ARM_DBG_WRITE(N, M, OP2, VAL) do {\
asm volatile("mcr p14, 0, %0, " #N "," #M ", " #OP2 : : "r" (VAL));\
} while (0)
struct perf_event_attr;
struct notifier_block;
struct perf_event;
struct pmu;
extern int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl,
int *gen_len, int *gen_type);
extern int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw);
extern int hw_breakpoint_arch_parse(struct perf_event *bp,
const struct perf_event_attr *attr,
struct arch_hw_breakpoint *hw);
extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
unsigned long val, void *data);
extern u8 arch_get_debug_arch(void);
extern u8 arch_get_max_wp_len(void);
extern void clear_ptrace_hw_breakpoint(struct task_struct *tsk);
int arch_install_hw_breakpoint(struct perf_event *bp);
void arch_uninstall_hw_breakpoint(struct perf_event *bp);
void hw_breakpoint_pmu_read(struct perf_event *bp);
int hw_breakpoint_slots(int type);
#else
static inline void clear_ptrace_hw_breakpoint(struct task_struct *tsk) {}
#endif /* CONFIG_HAVE_HW_BREAKPOINT */
#endif /* __KERNEL__ */
#endif /* _ARM_HW_BREAKPOINT_H */
+17
View File
@@ -0,0 +1,17 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Nothing to see here yet
*/
#ifndef _ARCH_ARM_HW_IRQ_H
#define _ARCH_ARM_HW_IRQ_H
static inline void ack_bad_irq(int irq)
{
extern unsigned long irq_err_count;
irq_err_count++;
pr_crit("unexpected IRQ trap at vector %02x\n", irq);
}
#define ARCH_IRQ_INIT_FLAGS (IRQ_NOREQUEST | IRQ_NOPROBE)
#endif
+16
View File
@@ -0,0 +1,16 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASMARM_HWCAP_H
#define __ASMARM_HWCAP_H
#include <uapi/asm/hwcap.h>
#if !defined(__ASSEMBLY__)
/*
* This yields a mask that user programs can use to figure out what
* instruction set this cpu supports.
*/
#define ELF_HWCAP (elf_hwcap)
#define ELF_HWCAP2 (elf_hwcap2)
extern unsigned int elf_hwcap, elf_hwcap2;
#endif
#endif
@@ -0,0 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_ARM_HYPERVISOR_H
#define _ASM_ARM_HYPERVISOR_H
#include <asm/xen/hypervisor.h>
void kvm_init_hyp_services(void);
bool kvm_arm_hyp_service_available(u32 func_id);
static inline void kvm_arch_init_hyp_services(void) { };
#endif
+15
View File
@@ -0,0 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_IDMAP_H
#define __ASM_IDMAP_H
#include <linux/compiler.h>
#include <linux/pgtable.h>
/* Tag a function as requiring to be executed via an identity mapping. */
#define __idmap __section(".idmap.text") noinline notrace
extern pgd_t *idmap_pgd;
void setup_mm_for_reboot(void);
#endif /* __ASM_IDMAP_H */
+47
View File
@@ -0,0 +1,47 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_ARM_INSN_H
#define __ASM_ARM_INSN_H
#include <linux/types.h>
/*
* Avoid a literal load by emitting a sequence of ADD/LDR instructions with the
* appropriate relocations. The combined sequence has a range of -/+ 256 MiB,
* which should be sufficient for the core kernel as well as modules loaded
* into the module region. (Not supported by LLD before release 14)
*/
#define LOAD_SYM_ARMV6(reg, sym) \
" .globl " #sym " \n\t" \
" .reloc 10f, R_ARM_ALU_PC_G0_NC, " #sym " \n\t" \
" .reloc 11f, R_ARM_ALU_PC_G1_NC, " #sym " \n\t" \
" .reloc 12f, R_ARM_LDR_PC_G2, " #sym " \n\t" \
"10: sub " #reg ", pc, #8 \n\t" \
"11: sub " #reg ", " #reg ", #4 \n\t" \
"12: ldr " #reg ", [" #reg ", #0] \n\t"
static inline unsigned long
arm_gen_nop(void)
{
#ifdef CONFIG_THUMB2_KERNEL
return 0xf3af8000; /* nop.w */
#else
return 0xe1a00000; /* mov r0, r0 */
#endif
}
unsigned long
__arm_gen_branch(unsigned long pc, unsigned long addr, bool link, bool warn);
static inline unsigned long
arm_gen_branch(unsigned long pc, unsigned long addr)
{
return __arm_gen_branch(pc, addr, false, true);
}
static inline unsigned long
arm_gen_branch_link(unsigned long pc, unsigned long addr, bool warn)
{
return __arm_gen_branch(pc, addr, true, warn);
}
#endif
+440
View File
@@ -0,0 +1,440 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* arch/arm/include/asm/io.h
*
* Copyright (C) 1996-2000 Russell King
*
* Modifications:
* 16-Sep-1996 RMK Inlined the inx/outx functions & optimised for both
* constant addresses and variable addresses.
* 04-Dec-1997 RMK Moved a lot of this stuff to the new architecture
* specific IO header files.
* 27-Mar-1999 PJB Second parameter of memcpy_toio is const..
* 04-Apr-1999 PJB Added check_signature.
* 12-Dec-1999 RMK More cleanups
* 18-Jun-2000 RMK Removed virt_to_* and friends definitions
* 05-Oct-2004 BJD Moved memory string functions to use void __iomem
*/
#ifndef __ASM_ARM_IO_H
#define __ASM_ARM_IO_H
#ifdef __KERNEL__
#include <linux/string.h>
#include <linux/types.h>
#include <asm/byteorder.h>
#include <asm/page.h>
#include <asm-generic/pci_iomap.h>
/*
* ISA I/O bus memory addresses are 1:1 with the physical address.
*/
#define isa_virt_to_bus virt_to_phys
#define isa_bus_to_virt phys_to_virt
/*
* Atomic MMIO-wide IO modify
*/
extern void atomic_io_modify(void __iomem *reg, u32 mask, u32 set);
extern void atomic_io_modify_relaxed(void __iomem *reg, u32 mask, u32 set);
/*
* Generic IO read/write. These perform native-endian accesses. Note
* that some architectures will want to re-define __raw_{read,write}w.
*/
void __raw_writesb(volatile void __iomem *addr, const void *data, int bytelen);
void __raw_writesw(volatile void __iomem *addr, const void *data, int wordlen);
void __raw_writesl(volatile void __iomem *addr, const void *data, int longlen);
void __raw_readsb(const volatile void __iomem *addr, void *data, int bytelen);
void __raw_readsw(const volatile void __iomem *addr, void *data, int wordlen);
void __raw_readsl(const volatile void __iomem *addr, void *data, int longlen);
#if __LINUX_ARM_ARCH__ < 6
/*
* Half-word accesses are problematic with RiscPC due to limitations of
* the bus. Rather than special-case the machine, just let the compiler
* generate the access for CPUs prior to ARMv6.
*/
#define __raw_writew __raw_writew
static __no_kasan_or_inline void __raw_writew(u16 val, volatile void __iomem *addr)
{
__chk_io_ptr(addr);
*(volatile unsigned short __force *)addr = val;
}
#define __raw_readw __raw_readw
static __no_kasan_or_inline u16 __raw_readw(const volatile void __iomem *addr)
{
__chk_io_ptr(addr);
return *(const volatile unsigned short __force *)addr;
}
#else
/*
* When running under a hypervisor, we want to avoid I/O accesses with
* writeback addressing modes as these incur a significant performance
* overhead (the address generation must be emulated in software).
*/
#define __raw_writew __raw_writew
static inline void __raw_writew(u16 val, volatile void __iomem *addr)
{
asm volatile("strh %1, %0"
: : "Q" (*(volatile u16 __force *)addr), "r" (val));
}
#define __raw_readw __raw_readw
static inline u16 __raw_readw(const volatile void __iomem *addr)
{
u16 val;
asm volatile("ldrh %0, %1"
: "=r" (val)
: "Q" (*(volatile u16 __force *)addr));
return val;
}
#endif
#define __raw_writeb __raw_writeb
static inline void __raw_writeb(u8 val, volatile void __iomem *addr)
{
asm volatile("strb %1, %0"
: : "Qo" (*(volatile u8 __force *)addr), "r" (val));
}
#define __raw_writel __raw_writel
static inline void __raw_writel(u32 val, volatile void __iomem *addr)
{
asm volatile("str %1, %0"
: : "Qo" (*(volatile u32 __force *)addr), "r" (val));
}
#define __raw_readb __raw_readb
static inline u8 __raw_readb(const volatile void __iomem *addr)
{
u8 val;
asm volatile("ldrb %0, %1"
: "=r" (val)
: "Qo" (*(volatile u8 __force *)addr));
return val;
}
#define __raw_readl __raw_readl
static inline u32 __raw_readl(const volatile void __iomem *addr)
{
u32 val;
asm volatile("ldr %0, %1"
: "=r" (val)
: "Qo" (*(volatile u32 __force *)addr));
return val;
}
/*
* Architecture ioremap implementation.
*/
#define MT_DEVICE 0
#define MT_DEVICE_NONSHARED 1
#define MT_DEVICE_CACHED 2
#define MT_DEVICE_WC 3
/*
* types 4 onwards can be found in asm/mach/map.h and are undefined
* for ioremap
*/
/*
* __arm_ioremap takes CPU physical address.
* __arm_ioremap_pfn takes a Page Frame Number and an offset into that page
* The _caller variety takes a __builtin_return_address(0) value for
* /proc/vmalloc to use - and should only be used in non-inline functions.
*/
extern void __iomem *__arm_ioremap_caller(phys_addr_t, size_t, unsigned int,
void *);
extern void __iomem *__arm_ioremap_pfn(unsigned long, unsigned long, size_t, unsigned int);
extern void __iomem *__arm_ioremap_exec(phys_addr_t, size_t, bool cached);
void __arm_iomem_set_ro(void __iomem *ptr, size_t size);
extern void __iomem * (*arch_ioremap_caller)(phys_addr_t, size_t,
unsigned int, void *);
/*
* Bad read/write accesses...
*/
extern void __readwrite_bug(const char *fn);
/*
* A typesafe __io() helper
*/
static inline void __iomem *__typesafe_io(unsigned long addr)
{
return (void __iomem *)addr;
}
#define IOMEM(x) ((void __force __iomem *)(x))
/* IO barriers */
#ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE
#include <asm/barrier.h>
#define __iormb() rmb()
#define __iowmb() wmb()
#else
#define __iormb() do { } while (0)
#define __iowmb() do { } while (0)
#endif
/* PCI fixed i/o mapping */
#define PCI_IO_VIRT_BASE 0xfee00000
#define PCI_IOBASE ((void __iomem *)PCI_IO_VIRT_BASE)
#if defined(CONFIG_PCI) || IS_ENABLED(CONFIG_PCMCIA)
void pci_ioremap_set_mem_type(int mem_type);
#else
static inline void pci_ioremap_set_mem_type(int mem_type) {}
#endif
struct resource;
#define pci_remap_iospace pci_remap_iospace
int pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr);
/*
* PCI configuration space mapping function.
*
* The PCI specification does not allow configuration write
* transactions to be posted. Add an arch specific
* pci_remap_cfgspace() definition that is implemented
* through strongly ordered memory mappings.
*/
#define pci_remap_cfgspace pci_remap_cfgspace
void __iomem *pci_remap_cfgspace(resource_size_t res_cookie, size_t size);
/*
* Now, pick up the machine-defined IO definitions
*/
#ifdef CONFIG_NEED_MACH_IO_H
#include <mach/io.h>
#else
#if IS_ENABLED(CONFIG_PCMCIA) || defined(CONFIG_PCI)
#define IO_SPACE_LIMIT ((resource_size_t)0xfffff)
#else
#define IO_SPACE_LIMIT ((resource_size_t)0)
#endif
#define __io(a) __typesafe_io(PCI_IO_VIRT_BASE + ((a) & IO_SPACE_LIMIT))
#endif
/*
* IO port access primitives
* -------------------------
*
* The ARM doesn't have special IO access instructions; all IO is memory
* mapped. Note that these are defined to perform little endian accesses
* only. Their primary purpose is to access PCI and ISA peripherals.
*
* Note that for a big endian machine, this implies that the following
* big endian mode connectivity is in place, as described by numerous
* ARM documents:
*
* PCI: D0-D7 D8-D15 D16-D23 D24-D31
* ARM: D24-D31 D16-D23 D8-D15 D0-D7
*
* The machine specific io.h include defines __io to translate an "IO"
* address to a memory address.
*
* Note that we prevent GCC re-ordering or caching values in expressions
* by introducing sequence points into the in*() definitions. Note that
* __raw_* do not guarantee this behaviour.
*
* The {in,out}[bwl] macros are for emulating x86-style PCI/ISA IO space.
*/
#ifdef __io
#define outb(v,p) ({ __iowmb(); __raw_writeb(v,__io(p)); })
#define outw(v,p) ({ __iowmb(); __raw_writew((__force __u16) \
cpu_to_le16(v),__io(p)); })
#define outl(v,p) ({ __iowmb(); __raw_writel((__force __u32) \
cpu_to_le32(v),__io(p)); })
#define inb(p) ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
#define inw(p) ({ __u16 __v = le16_to_cpu((__force __le16) \
__raw_readw(__io(p))); __iormb(); __v; })
#define inl(p) ({ __u32 __v = le32_to_cpu((__force __le32) \
__raw_readl(__io(p))); __iormb(); __v; })
#define outsb(p,d,l) __raw_writesb(__io(p),d,l)
#define outsw(p,d,l) __raw_writesw(__io(p),d,l)
#define outsl(p,d,l) __raw_writesl(__io(p),d,l)
#define insb(p,d,l) __raw_readsb(__io(p),d,l)
#define insw(p,d,l) __raw_readsw(__io(p),d,l)
#define insl(p,d,l) __raw_readsl(__io(p),d,l)
#endif
/*
* String version of IO memory access ops:
*/
extern void _memcpy_fromio(void *, const volatile void __iomem *, size_t);
extern void _memcpy_toio(volatile void __iomem *, const void *, size_t);
extern void _memset_io(volatile void __iomem *, int, size_t);
/*
* Memory access primitives
* ------------------------
*
* These perform PCI memory accesses via an ioremap region. They don't
* take an address as such, but a cookie.
*
* Again, these are defined to perform little endian accesses. See the
* IO port primitives for more information.
*/
#ifndef readl
#define readb_relaxed(c) ({ u8 __r = __raw_readb(c); __r; })
#define readw_relaxed(c) ({ u16 __r = le16_to_cpu((__force __le16) \
__raw_readw(c)); __r; })
#define readl_relaxed(c) ({ u32 __r = le32_to_cpu((__force __le32) \
__raw_readl(c)); __r; })
#define writeb_relaxed(v,c) __raw_writeb(v,c)
#define writew_relaxed(v,c) __raw_writew((__force u16) cpu_to_le16(v),c)
#define writel_relaxed(v,c) __raw_writel((__force u32) cpu_to_le32(v),c)
#define readb(c) ({ u8 __v = readb_relaxed(c); __iormb(); __v; })
#define readw(c) ({ u16 __v = readw_relaxed(c); __iormb(); __v; })
#define readl(c) ({ u32 __v = readl_relaxed(c); __iormb(); __v; })
#define writeb(v,c) ({ __iowmb(); writeb_relaxed(v,c); })
#define writew(v,c) ({ __iowmb(); writew_relaxed(v,c); })
#define writel(v,c) ({ __iowmb(); writel_relaxed(v,c); })
#define readsb(p,d,l) __raw_readsb(p,d,l)
#define readsw(p,d,l) __raw_readsw(p,d,l)
#define readsl(p,d,l) __raw_readsl(p,d,l)
#define writesb(p,d,l) __raw_writesb(p,d,l)
#define writesw(p,d,l) __raw_writesw(p,d,l)
#define writesl(p,d,l) __raw_writesl(p,d,l)
#ifndef __ARMBE__
static inline void memset_io(volatile void __iomem *dst, unsigned c,
size_t count)
{
extern void mmioset(void *, unsigned int, size_t);
mmioset((void __force *)dst, c, count);
}
#define memset_io(dst,c,count) memset_io(dst,c,count)
static inline void memcpy_fromio(void *to, const volatile void __iomem *from,
size_t count)
{
extern void mmiocpy(void *, const void *, size_t);
mmiocpy(to, (const void __force *)from, count);
}
#define memcpy_fromio(to,from,count) memcpy_fromio(to,from,count)
static inline void memcpy_toio(volatile void __iomem *to, const void *from,
size_t count)
{
extern void mmiocpy(void *, const void *, size_t);
mmiocpy((void __force *)to, from, count);
}
#define memcpy_toio(to,from,count) memcpy_toio(to,from,count)
#else
#define memset_io(c,v,l) _memset_io(c,(v),(l))
#define memcpy_fromio(a,c,l) _memcpy_fromio((a),c,(l))
#define memcpy_toio(c,a,l) _memcpy_toio(c,(a),(l))
#endif
#endif /* readl */
/*
* ioremap() and friends.
*
* ioremap() takes a resource address, and size. Due to the ARM memory
* types, it is important to use the correct ioremap() function as each
* mapping has specific properties.
*
* Function Memory type Cacheability Cache hint
* ioremap() Device n/a n/a
* ioremap_cache() Normal Writeback Read allocate
* ioremap_wc() Normal Non-cacheable n/a
* ioremap_wt() Normal Non-cacheable n/a
*
* All device mappings have the following properties:
* - no access speculation
* - no repetition (eg, on return from an exception)
* - number, order and size of accesses are maintained
* - unaligned accesses are "unpredictable"
* - writes may be delayed before they hit the endpoint device
*
* All normal memory mappings have the following properties:
* - reads can be repeated with no side effects
* - repeated reads return the last value written
* - reads can fetch additional locations without side effects
* - writes can be repeated (in certain cases) with no side effects
* - writes can be merged before accessing the target
* - unaligned accesses can be supported
* - ordering is not guaranteed without explicit dependencies or barrier
* instructions
* - writes may be delayed before they hit the endpoint memory
*
* The cache hint is only a performance hint: CPUs may alias these hints.
* Eg, a CPU not implementing read allocate but implementing write allocate
* will provide a write allocate mapping instead.
*/
void __iomem *ioremap(resource_size_t res_cookie, size_t size);
#define ioremap ioremap
/*
* Do not use ioremap_cache for mapping memory. Use memremap instead.
*/
void __iomem *ioremap_cache(resource_size_t res_cookie, size_t size);
#define ioremap_cache ioremap_cache
void __iomem *ioremap_wc(resource_size_t res_cookie, size_t size);
#define ioremap_wc ioremap_wc
#define ioremap_wt ioremap_wc
void iounmap(volatile void __iomem *io_addr);
#define iounmap iounmap
void *arch_memremap_wb(phys_addr_t phys_addr, size_t size, unsigned long flags);
#define arch_memremap_wb arch_memremap_wb
/*
* io{read,write}{16,32}be() macros
*/
#define ioread16be(p) ({ __u16 __v = be16_to_cpu((__force __be16)__raw_readw(p)); __iormb(); __v; })
#define ioread32be(p) ({ __u32 __v = be32_to_cpu((__force __be32)__raw_readl(p)); __iormb(); __v; })
#define iowrite16be(v,p) ({ __iowmb(); __raw_writew((__force __u16)cpu_to_be16(v), p); })
#define iowrite32be(v,p) ({ __iowmb(); __raw_writel((__force __u32)cpu_to_be32(v), p); })
#ifndef ioport_map
#define ioport_map ioport_map
extern void __iomem *ioport_map(unsigned long port, unsigned int nr);
#endif
#ifndef ioport_unmap
#define ioport_unmap ioport_unmap
extern void ioport_unmap(void __iomem *addr);
#endif
struct pci_dev;
#define pci_iounmap pci_iounmap
extern void pci_iounmap(struct pci_dev *dev, void __iomem *addr);
#include <asm-generic/io.h>
#ifdef CONFIG_MMU
#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
extern int valid_phys_addr_range(phys_addr_t addr, size_t size);
extern int valid_mmap_phys_addr_range(unsigned long pfn, size_t size);
extern bool arch_memremap_can_ram_remap(resource_size_t offset, size_t size,
unsigned long flags);
#define arch_memremap_can_ram_remap arch_memremap_can_ram_remap
#endif
/*
* Register ISA memory and port locations for glibc iopl/inb/outb
* emulation.
*/
extern void register_isa_ports(unsigned int mmio, unsigned int io,
unsigned int io_shift);
#endif /* __KERNEL__ */
#endif /* __ASM_ARM_IO_H */
+47
View File
@@ -0,0 +1,47 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_ARM_IRQ_H
#define __ASM_ARM_IRQ_H
#define NR_IRQS_LEGACY 16
#ifndef CONFIG_SPARSE_IRQ
#include <mach/irqs.h>
#else
#define NR_IRQS NR_IRQS_LEGACY
#endif
#ifndef irq_canonicalize
#define irq_canonicalize(i) (i)
#endif
/*
* Use this value to indicate lack of interrupt
* capability
*/
#ifndef NO_IRQ
#define NO_IRQ ((unsigned int)(-1))
#endif
#ifndef __ASSEMBLY__
struct irqaction;
struct pt_regs;
void handle_IRQ(unsigned int, struct pt_regs *);
#ifdef CONFIG_SMP
#include <linux/cpumask.h>
extern void arch_trigger_cpumask_backtrace(const cpumask_t *mask,
int exclude_cpu);
#define arch_trigger_cpumask_backtrace arch_trigger_cpumask_backtrace
#endif
static inline int nr_legacy_irqs(void)
{
return NR_IRQS_LEGACY;
}
#endif
#endif
@@ -0,0 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_ARM_IRQ_WORK_H
#define __ASM_ARM_IRQ_WORK_H
#include <asm/smp_plat.h>
static inline bool arch_irq_work_has_interrupt(void)
{
return is_smp();
}
#endif /* _ASM_ARM_IRQ_WORK_H */
+187
View File
@@ -0,0 +1,187 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_ARM_IRQFLAGS_H
#define __ASM_ARM_IRQFLAGS_H
#ifdef __KERNEL__
#include <asm/ptrace.h>
/*
* CPU interrupt mask handling.
*/
#ifdef CONFIG_CPU_V7M
#define IRQMASK_REG_NAME_R "primask"
#define IRQMASK_REG_NAME_W "primask"
#define IRQMASK_I_BIT 1
#else
#define IRQMASK_REG_NAME_R "cpsr"
#define IRQMASK_REG_NAME_W "cpsr_c"
#define IRQMASK_I_BIT PSR_I_BIT
#endif
#if __LINUX_ARM_ARCH__ >= 6
#define arch_local_irq_save arch_local_irq_save
static inline unsigned long arch_local_irq_save(void)
{
unsigned long flags;
asm volatile(
" mrs %0, " IRQMASK_REG_NAME_R " @ arch_local_irq_save\n"
" cpsid i"
: "=r" (flags) : : "memory", "cc");
return flags;
}
#define arch_local_irq_enable arch_local_irq_enable
static inline void arch_local_irq_enable(void)
{
asm volatile(
" cpsie i @ arch_local_irq_enable"
:
:
: "memory", "cc");
}
#define arch_local_irq_disable arch_local_irq_disable
static inline void arch_local_irq_disable(void)
{
asm volatile(
" cpsid i @ arch_local_irq_disable"
:
:
: "memory", "cc");
}
#define local_fiq_enable() __asm__("cpsie f @ __stf" : : : "memory", "cc")
#define local_fiq_disable() __asm__("cpsid f @ __clf" : : : "memory", "cc")
#ifndef CONFIG_CPU_V7M
#define local_abt_enable() __asm__("cpsie a @ __sta" : : : "memory", "cc")
#define local_abt_disable() __asm__("cpsid a @ __cla" : : : "memory", "cc")
#else
#define local_abt_enable() do { } while (0)
#define local_abt_disable() do { } while (0)
#endif
#else
/*
* Save the current interrupt enable state & disable IRQs
*/
#define arch_local_irq_save arch_local_irq_save
static inline unsigned long arch_local_irq_save(void)
{
unsigned long flags, temp;
asm volatile(
" mrs %0, cpsr @ arch_local_irq_save\n"
" orr %1, %0, #128\n"
" msr cpsr_c, %1"
: "=r" (flags), "=r" (temp)
:
: "memory", "cc");
return flags;
}
/*
* Enable IRQs
*/
#define arch_local_irq_enable arch_local_irq_enable
static inline void arch_local_irq_enable(void)
{
unsigned long temp;
asm volatile(
" mrs %0, cpsr @ arch_local_irq_enable\n"
" bic %0, %0, #128\n"
" msr cpsr_c, %0"
: "=r" (temp)
:
: "memory", "cc");
}
/*
* Disable IRQs
*/
#define arch_local_irq_disable arch_local_irq_disable
static inline void arch_local_irq_disable(void)
{
unsigned long temp;
asm volatile(
" mrs %0, cpsr @ arch_local_irq_disable\n"
" orr %0, %0, #128\n"
" msr cpsr_c, %0"
: "=r" (temp)
:
: "memory", "cc");
}
/*
* Enable FIQs
*/
#define local_fiq_enable() \
({ \
unsigned long temp; \
__asm__ __volatile__( \
"mrs %0, cpsr @ stf\n" \
" bic %0, %0, #64\n" \
" msr cpsr_c, %0" \
: "=r" (temp) \
: \
: "memory", "cc"); \
})
/*
* Disable FIQs
*/
#define local_fiq_disable() \
({ \
unsigned long temp; \
__asm__ __volatile__( \
"mrs %0, cpsr @ clf\n" \
" orr %0, %0, #64\n" \
" msr cpsr_c, %0" \
: "=r" (temp) \
: \
: "memory", "cc"); \
})
#define local_abt_enable() do { } while (0)
#define local_abt_disable() do { } while (0)
#endif
/*
* Save the current interrupt enable state.
*/
#define arch_local_save_flags arch_local_save_flags
static inline unsigned long arch_local_save_flags(void)
{
unsigned long flags;
asm volatile(
" mrs %0, " IRQMASK_REG_NAME_R " @ local_save_flags"
: "=r" (flags) : : "memory", "cc");
return flags;
}
/*
* restore saved IRQ & FIQ state
*/
#define arch_local_irq_restore arch_local_irq_restore
static inline void arch_local_irq_restore(unsigned long flags)
{
asm volatile(
" msr " IRQMASK_REG_NAME_W ", %0 @ local_irq_restore"
:
: "r" (flags)
: "memory", "cc");
}
#define arch_irqs_disabled_flags arch_irqs_disabled_flags
static inline int arch_irqs_disabled_flags(unsigned long flags)
{
return flags & IRQMASK_I_BIT;
}
#include <asm-generic/irqflags.h>
#endif /* ifdef __KERNEL__ */
#endif /* ifndef __ASM_ARM_IRQFLAGS_H */
@@ -0,0 +1,53 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_ARM_JUMP_LABEL_H
#define _ASM_ARM_JUMP_LABEL_H
#ifndef __ASSEMBLY__
#include <linux/types.h>
#include <asm/unified.h>
#define JUMP_LABEL_NOP_SIZE 4
/* This macro is also expanded on the Rust side. */
#define ARCH_STATIC_BRANCH_ASM(key, label) \
"1:\n\t" \
WASM(nop) "\n\t" \
".pushsection __jump_table, \"aw\"\n\t" \
".word 1b, " label ", " key "\n\t" \
".popsection\n\t" \
static __always_inline bool arch_static_branch(struct static_key *key, bool branch)
{
asm goto(ARCH_STATIC_BRANCH_ASM("%c0", "%l[l_yes]")
: : "i" (&((char *)key)[branch]) : : l_yes);
return false;
l_yes:
return true;
}
static __always_inline bool arch_static_branch_jump(struct static_key *key, bool branch)
{
asm goto("1:\n\t"
WASM(b) " %l[l_yes]\n\t"
".pushsection __jump_table, \"aw\"\n\t"
".word 1b, %l[l_yes], %c0\n\t"
".popsection\n\t"
: : "i" (&((char *)key)[branch]) : : l_yes);
return false;
l_yes:
return true;
}
typedef u32 jump_label_t;
struct jump_entry {
jump_label_t code;
jump_label_t target;
jump_label_t key;
};
#endif /* __ASSEMBLY__ */
#endif
+33
View File
@@ -0,0 +1,33 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* arch/arm/include/asm/kasan.h
*
* Copyright (c) 2015 Samsung Electronics Co., Ltd.
* Author: Andrey Ryabinin <ryabinin.a.a@gmail.com>
*
*/
#ifndef __ASM_KASAN_H
#define __ASM_KASAN_H
#ifdef CONFIG_KASAN
#include <asm/kasan_def.h>
#define KASAN_SHADOW_SCALE_SHIFT 3
/*
* The compiler uses a shadow offset assuming that addresses start
* from 0. Kernel addresses don't start from 0, so shadow
* for kernel really starts from 'compiler's shadow offset' +
* ('kernel address space start' >> KASAN_SHADOW_SCALE_SHIFT)
*/
asmlinkage void kasan_early_init(void);
extern void kasan_init(void);
#else
static inline void kasan_init(void) { }
#endif
#endif
@@ -0,0 +1,81 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* arch/arm/include/asm/kasan_def.h
*
* Copyright (c) 2018 Huawei Technologies Co., Ltd.
*
* Author: Abbott Liu <liuwenliang@huawei.com>
*/
#ifndef __ASM_KASAN_DEF_H
#define __ASM_KASAN_DEF_H
#ifdef CONFIG_KASAN
/*
* Define KASAN_SHADOW_OFFSET,KASAN_SHADOW_START and KASAN_SHADOW_END for
* the Arm kernel address sanitizer. We are "stealing" lowmem (the 4GB
* addressable by a 32bit architecture) out of the virtual address
* space to use as shadow memory for KASan as follows:
*
* +----+ 0xffffffff
* | | \
* | | |-> Static kernel image (vmlinux) BSS and page table
* | |/
* +----+ PAGE_OFFSET
* | | \
* | | |-> Loadable kernel modules virtual address space area
* | |/
* +----+ MODULES_VADDR = KASAN_SHADOW_END
* | | \
* | | |-> The shadow area of kernel virtual address.
* | |/
* +----+-> TASK_SIZE (start of kernel space) = KASAN_SHADOW_START the
* | |\ shadow address of MODULES_VADDR
* | | |
* | | |
* | | |-> The user space area in lowmem. The kernel address
* | | | sanitizer do not use this space, nor does it map it.
* | | |
* | | |
* | | |
* | | |
* | |/
* ------ 0
*
* 1) KASAN_SHADOW_START
* This value begins with the MODULE_VADDR's shadow address. It is the
* start of kernel virtual space. Since we have modules to load, we need
* to cover also that area with shadow memory so we can find memory
* bugs in modules.
*
* 2) KASAN_SHADOW_END
* This value is the 0x100000000's shadow address: the mapping that would
* be after the end of the kernel memory at 0xffffffff. It is the end of
* kernel address sanitizer shadow area. It is also the start of the
* module area.
*
* 3) KASAN_SHADOW_OFFSET:
* This value is used to map an address to the corresponding shadow
* address by the following formula:
*
* shadow_addr = (address >> 3) + KASAN_SHADOW_OFFSET;
*
* As you would expect, >> 3 is equal to dividing by 8, meaning each
* byte in the shadow memory covers 8 bytes of kernel memory, so one
* bit shadow memory per byte of kernel memory is used.
*
* The KASAN_SHADOW_OFFSET is provided in a Kconfig option depending
* on the VMSPLIT layout of the system: the kernel and userspace can
* split up lowmem in different ways according to needs, so we calculate
* the shadow offset depending on this.
*/
#define KASAN_SHADOW_SCALE_SHIFT 3
#define KASAN_SHADOW_OFFSET _AC(CONFIG_KASAN_SHADOW_OFFSET, UL)
#define KASAN_SHADOW_END ((UL(1) << (32 - KASAN_SHADOW_SCALE_SHIFT)) \
+ KASAN_SHADOW_OFFSET)
#define KASAN_SHADOW_START ((KASAN_SHADOW_END >> 3) + KASAN_SHADOW_OFFSET)
#endif
#endif
@@ -0,0 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ARM_KEXEC_INTERNAL_H
#define _ARM_KEXEC_INTERNAL_H
struct kexec_relocate_data {
unsigned long kexec_start_address;
unsigned long kexec_indirection_page;
unsigned long kexec_mach_type;
unsigned long kexec_r2;
};
#endif
+83
View File
@@ -0,0 +1,83 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ARM_KEXEC_H
#define _ARM_KEXEC_H
/* Maximum physical address we can use pages from */
#define KEXEC_SOURCE_MEMORY_LIMIT (-1UL)
/* Maximum address we can reach in physical address mode */
#define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL)
/* Maximum address we can use for the control code buffer */
#define KEXEC_CONTROL_MEMORY_LIMIT (-1UL)
#define KEXEC_CONTROL_PAGE_SIZE 4096
#define KEXEC_ARCH KEXEC_ARCH_ARM
#define KEXEC_ARM_ATAGS_OFFSET 0x1000
#define KEXEC_ARM_ZIMAGE_OFFSET 0x8000
#ifndef __ASSEMBLY__
#define ARCH_HAS_KIMAGE_ARCH
struct kimage_arch {
u32 kernel_r2;
};
/**
* crash_setup_regs() - save registers for the panic kernel
* @newregs: registers are saved here
* @oldregs: registers to be saved (may be %NULL)
*
* Function copies machine registers from @oldregs to @newregs. If @oldregs is
* %NULL then current registers are stored there.
*/
static inline void crash_setup_regs(struct pt_regs *newregs,
struct pt_regs *oldregs)
{
if (oldregs) {
memcpy(newregs, oldregs, sizeof(*newregs));
} else {
__asm__ __volatile__ (
"stmia %[regs_base], {r0-r12}\n\t"
"mov %[_ARM_sp], sp\n\t"
"str lr, %[_ARM_lr]\n\t"
"adr %[_ARM_pc], 1f\n\t"
"mrs %[_ARM_cpsr], cpsr\n\t"
"1:"
: [_ARM_pc] "=r" (newregs->ARM_pc),
[_ARM_cpsr] "=r" (newregs->ARM_cpsr),
[_ARM_sp] "=r" (newregs->ARM_sp),
[_ARM_lr] "=o" (newregs->ARM_lr)
: [regs_base] "r" (&newregs->ARM_r0)
: "memory"
);
}
}
static inline unsigned long phys_to_boot_phys(phys_addr_t phys)
{
return phys_to_idmap(phys);
}
#define phys_to_boot_phys phys_to_boot_phys
static inline phys_addr_t boot_phys_to_phys(unsigned long entry)
{
return idmap_to_phys(entry);
}
#define boot_phys_to_phys boot_phys_to_phys
static inline unsigned long page_to_boot_pfn(struct page *page)
{
return page_to_pfn(page) + (arch_phys_to_idmap_offset >> PAGE_SHIFT);
}
#define page_to_boot_pfn page_to_boot_pfn
static inline struct page *boot_pfn_to_page(unsigned long boot_pfn)
{
return pfn_to_page(boot_pfn - (arch_phys_to_idmap_offset >> PAGE_SHIFT));
}
#define boot_pfn_to_page boot_pfn_to_page
#endif /* __ASSEMBLY__ */
#endif /* _ARM_KEXEC_H */
+53
View File
@@ -0,0 +1,53 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_ARM_KFENCE_H
#define __ASM_ARM_KFENCE_H
#include <linux/kfence.h>
#include <asm/pgalloc.h>
#include <asm/set_memory.h>
static inline int split_pmd_page(pmd_t *pmd, unsigned long addr)
{
int i;
unsigned long pfn = PFN_DOWN(__pa(addr));
pte_t *pte = pte_alloc_one_kernel(&init_mm);
if (!pte)
return -ENOMEM;
for (i = 0; i < PTRS_PER_PTE; i++)
set_pte_ext(pte + i, pfn_pte(pfn + i, PAGE_KERNEL), 0);
pmd_populate_kernel(&init_mm, pmd, pte);
flush_tlb_kernel_range(addr, addr + PMD_SIZE);
return 0;
}
static inline bool arch_kfence_init_pool(void)
{
unsigned long addr;
pmd_t *pmd;
for (addr = (unsigned long)__kfence_pool; is_kfence_address((void *)addr);
addr += PAGE_SIZE) {
pmd = pmd_off_k(addr);
if (pmd_leaf(*pmd)) {
if (split_pmd_page(pmd, addr & PMD_MASK))
return false;
}
}
return true;
}
static inline bool kfence_protect_page(unsigned long addr, bool protect)
{
set_memory_valid(addr, 1, !protect);
return true;
}
#endif /* __ASM_ARM_KFENCE_H */
+107
View File
@@ -0,0 +1,107 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* ARM KGDB support
*
* Author: Deepak Saxena <dsaxena@mvista.com>
*
* Copyright (C) 2002 MontaVista Software Inc.
*
*/
#ifndef __ARM_KGDB_H__
#define __ARM_KGDB_H__
#include <linux/ptrace.h>
#include <asm/opcodes.h>
/*
* GDB assumes that we're a user process being debugged, so
* it will send us an SWI command to write into memory as the
* debug trap. When an SWI occurs, the next instruction addr is
* placed into R14_svc before jumping to the vector trap.
* This doesn't work for kernel debugging as we are already in SVC
* we would loose the kernel's LR, which is a bad thing. This
* is bad thing.
*
* By doing this as an undefined instruction trap, we force a mode
* switch from SVC to UND mode, allowing us to save full kernel state.
*
* We also define a KGDB_COMPILED_BREAK which can be used to compile
* in breakpoints. This is important for things like sysrq-G and for
* the initial breakpoint from trap_init().
*
* Note to ARM HW designers: Add real trap support like SH && PPC to
* make our lives much much simpler. :)
*/
#define BREAK_INSTR_SIZE 4
#define GDB_BREAKINST 0xef9f0001
#define KGDB_BREAKINST 0xe7ffdefe
#define KGDB_COMPILED_BREAK 0xe7ffdeff
#define CACHE_FLUSH_IS_SAFE 1
#ifndef __ASSEMBLY__
static inline void arch_kgdb_breakpoint(void)
{
asm(__inst_arm(0xe7ffdeff));
}
extern void kgdb_handle_bus_error(void);
extern int kgdb_fault_expected;
#endif /* !__ASSEMBLY__ */
/*
* From Kevin Hilman:
*
* gdb is expecting the following registers layout.
*
* r0-r15: 1 long word each
* f0-f7: unused, 3 long words each !!
* fps: unused, 1 long word
* cpsr: 1 long word
*
* Even though f0-f7 and fps are not used, they need to be
* present in the registers sent for correct processing in
* the host-side gdb.
*
* In particular, it is crucial that CPSR is in the right place,
* otherwise gdb will not be able to correctly interpret stepping over
* conditional branches.
*/
#define _GP_REGS 16
#define _FP_REGS 8
#define _EXTRA_REGS 2
#define GDB_MAX_REGS (_GP_REGS + (_FP_REGS * 3) + _EXTRA_REGS)
#define DBG_MAX_REG_NUM (_GP_REGS + _FP_REGS + _EXTRA_REGS)
#define KGDB_MAX_NO_CPUS 1
#define BUFMAX 400
#define NUMREGBYTES (GDB_MAX_REGS << 2)
#define NUMCRITREGBYTES (32 << 2)
#define _R0 0
#define _R1 1
#define _R2 2
#define _R3 3
#define _R4 4
#define _R5 5
#define _R6 6
#define _R7 7
#define _R8 8
#define _R9 9
#define _R10 10
#define _FP 11
#define _IP 12
#define _SPT 13
#define _LR 14
#define _PC 15
#define _CPSR (GDB_MAX_REGS - 1)
/*
* So that we can denote the end of a frame for tracing,
* in the simple case:
*/
#define CFI_END_FRAME(func) __CFI_END_FRAME(_PC, _SPT, func)
#endif /* __ASM_KGDB_H__ */
@@ -0,0 +1,78 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* arch/arm/include/asm/kprobes.h
*
* Copyright (C) 2006, 2007 Motorola Inc.
*/
#ifndef _ARM_KPROBES_H
#define _ARM_KPROBES_H
#include <asm-generic/kprobes.h>
#ifdef CONFIG_KPROBES
#include <linux/types.h>
#include <linux/ptrace.h>
#include <linux/notifier.h>
#define __ARCH_WANT_KPROBES_INSN_SLOT
#define MAX_INSN_SIZE 2
#define flush_insn_slot(p) do { } while (0)
#define kretprobe_blacklist_size 0
typedef u32 kprobe_opcode_t;
struct kprobe;
#include <asm/probes.h>
#define arch_specific_insn arch_probes_insn
struct prev_kprobe {
struct kprobe *kp;
unsigned int status;
};
/* per-cpu kprobe control block */
struct kprobe_ctlblk {
unsigned int kprobe_status;
struct prev_kprobe prev_kprobe;
};
void arch_remove_kprobe(struct kprobe *);
int kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr);
/* optinsn template addresses */
extern __visible kprobe_opcode_t optprobe_template_entry[];
extern __visible kprobe_opcode_t optprobe_template_val[];
extern __visible kprobe_opcode_t optprobe_template_call[];
extern __visible kprobe_opcode_t optprobe_template_end[];
extern __visible kprobe_opcode_t optprobe_template_sub_sp[];
extern __visible kprobe_opcode_t optprobe_template_add_sp[];
extern __visible kprobe_opcode_t optprobe_template_restore_begin[];
extern __visible kprobe_opcode_t optprobe_template_restore_orig_insn[];
extern __visible kprobe_opcode_t optprobe_template_restore_end[];
#define MAX_OPTIMIZED_LENGTH 4
#define MAX_OPTINSN_SIZE \
((unsigned long)optprobe_template_end - \
(unsigned long)optprobe_template_entry)
#define RELATIVEJUMP_SIZE 4
struct arch_optimized_insn {
/*
* copy of the original instructions.
* Different from x86, ARM kprobe_opcode_t is u32.
*/
#define MAX_COPIED_INSN DIV_ROUND_UP(RELATIVEJUMP_SIZE, sizeof(kprobe_opcode_t))
kprobe_opcode_t copied_insn[MAX_COPIED_INSN];
/* detour code buffer */
kprobe_opcode_t *insn;
/*
* We always copy one instruction on ARM,
* so size will always be 4, and unlike x86, there is no
* need for a size field.
*/
};
#endif /* CONFIG_KPROBES */
#endif /* _ARM_KPROBES_H */
@@ -0,0 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASMARM_KRAIT_L2_ACCESSORS_H
#define __ASMARM_KRAIT_L2_ACCESSORS_H
extern void krait_set_l2_indirect_reg(u32 addr, u32 val);
extern u32 krait_get_l2_indirect_reg(u32 addr);
#endif
@@ -0,0 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_LINKAGE_H
#define __ASM_LINKAGE_H
#define __ALIGN .align 0
#define __ALIGN_STR ".align 0"
#define ENDPROC(name) \
.type name, %function; \
END(name)
#endif
@@ -0,0 +1,95 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* arch/arm/include/asm/mach/arch.h
*
* Copyright (C) 2000 Russell King
*/
#include <linux/types.h>
#ifndef __ASSEMBLY__
#include <linux/reboot.h>
struct tag;
struct pt_regs;
struct smp_operations;
#ifdef CONFIG_SMP
#define smp_ops(ops) (&(ops))
#define smp_init_ops(ops) (&(ops))
#else
#define smp_ops(ops) (struct smp_operations *)NULL
#define smp_init_ops(ops) (bool (*)(void))NULL
#endif
struct machine_desc {
unsigned int nr; /* architecture number */
const char *name; /* architecture name */
unsigned long atag_offset; /* tagged list (relative) */
const char *const *dt_compat; /* array of device tree
* 'compatible' strings */
unsigned int nr_irqs; /* number of IRQs */
#ifdef CONFIG_ZONE_DMA
phys_addr_t dma_zone_size; /* size of DMA-able area */
#endif
unsigned int video_start; /* start of video RAM */
unsigned int video_end; /* end of video RAM */
unsigned char reserve_lp0 :1; /* never has lp0 */
unsigned char reserve_lp1 :1; /* never has lp1 */
unsigned char reserve_lp2 :1; /* never has lp2 */
enum reboot_mode reboot_mode; /* default restart mode */
unsigned l2c_aux_val; /* L2 cache aux value */
unsigned l2c_aux_mask; /* L2 cache aux mask */
void (*l2c_write_sec)(unsigned long, unsigned);
const struct smp_operations *smp; /* SMP operations */
bool (*smp_init)(void);
void (*fixup)(struct tag *, char **);
void (*dt_fixup)(void);
long long (*pv_fixup)(void);
void (*reserve)(void);/* reserve mem blocks */
void (*map_io)(void);/* IO mapping function */
void (*init_early)(void);
void (*init_irq)(void);
void (*init_time)(void);
void (*init_machine)(void);
void (*init_late)(void);
void (*restart)(enum reboot_mode, const char *);
};
/*
* Current machine - only accessible during boot.
*/
extern const struct machine_desc *machine_desc;
/*
* Machine type table - also only accessible during boot
*/
extern const struct machine_desc __arch_info_begin[], __arch_info_end[];
#define for_each_machine_desc(p) \
for (p = __arch_info_begin; p < __arch_info_end; p++)
/*
* Set of macros to define architecture features. This is built into
* a table by the linker.
*/
#define MACHINE_START(_type,_name) \
static const struct machine_desc __mach_desc_##_type \
__used \
__section(".arch.info.init") = { \
.nr = MACH_TYPE_##_type, \
.name = _name,
#define MACHINE_END \
};
#define DT_MACHINE_START(_name, _namestr) \
static const struct machine_desc __mach_desc_##_name \
__used \
__section(".arch.info.init") = { \
.nr = ~0, \
.name = _namestr,
#endif
@@ -0,0 +1,46 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* arch/arm/include/asm/mach/dma.h
*
* Copyright (C) 1998-2000 Russell King
*
* This header file describes the interface between the generic DMA handler
* (dma.c) and the architecture-specific DMA backends (dma-*.c)
*/
struct dma_struct;
typedef struct dma_struct dma_t;
struct dma_ops {
int (*request)(unsigned int, dma_t *); /* optional */
void (*free)(unsigned int, dma_t *); /* optional */
void (*enable)(unsigned int, dma_t *); /* mandatory */
void (*disable)(unsigned int, dma_t *); /* mandatory */
int (*residue)(unsigned int, dma_t *); /* optional */
int (*setspeed)(unsigned int, dma_t *, int); /* optional */
const char *type;
};
struct dma_struct {
void *addr; /* single DMA address */
unsigned long count; /* single DMA size */
struct scatterlist buf; /* single DMA */
int sgcount; /* number of DMA SG */
struct scatterlist *sg; /* DMA Scatter-Gather List */
unsigned int active:1; /* Transfer active */
unsigned int invalid:1; /* Address/Count changed */
unsigned int dma_mode; /* DMA mode */
int speed; /* DMA speed */
unsigned int lock; /* Device is allocated */
const char *device_id; /* Device name */
const struct dma_ops *d_ops;
};
/*
* isa_dma_add - add an ISA-style DMA channel
*/
extern int isa_dma_add(unsigned int, dma_t *dma);
@@ -0,0 +1,36 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* arch/arm/include/asm/mach/flash.h
*
* Copyright (C) 2003 Russell King, All Rights Reserved.
*/
#ifndef ASMARM_MACH_FLASH_H
#define ASMARM_MACH_FLASH_H
struct mtd_partition;
struct mtd_info;
/*
* map_name: the map probe function name
* name: flash device name (eg, as used with mtdparts=)
* width: width of mapped device
* init: method called at driver/device initialisation
* exit: method called at driver/device removal
* set_vpp: method called to enable or disable VPP
* mmcontrol: method called to enable or disable Sync. Burst Read in OneNAND
* parts: optional array of mtd_partitions for static partitioning
* nr_parts: number of mtd_partitions for static partitioning
*/
struct flash_platform_data {
const char *map_name;
const char *name;
unsigned int width;
int (*init)(void);
void (*exit)(void);
void (*set_vpp)(int on);
void (*mmcontrol)(struct mtd_info *mtd, int sync_read);
struct mtd_partition *parts;
unsigned int nr_parts;
};
#endif
@@ -0,0 +1,20 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* arch/arm/include/asm/mach/irq.h
*
* Copyright (C) 1995-2000 Russell King.
*/
#ifndef __ASM_ARM_MACH_IRQ_H
#define __ASM_ARM_MACH_IRQ_H
#include <linux/irq.h>
struct seq_file;
/*
* This is internal. Do not use it.
*/
extern void init_FIQ(int);
extern int show_fiq_list(struct seq_file *, int);
#endif
@@ -0,0 +1,65 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* arch/arm/include/asm/map.h
*
* Copyright (C) 1999-2000 Russell King
*
* Page table mapping constructs and function prototypes
*/
#ifndef __ASM_MACH_MAP_H
#define __ASM_MACH_MAP_H
#include <asm/io.h>
struct map_desc {
unsigned long virtual;
unsigned long pfn;
unsigned long length;
unsigned int type;
};
/* types 0-3 are defined in asm/io.h */
enum {
MT_UNCACHED = 4,
MT_CACHECLEAN,
MT_MINICLEAN,
MT_LOW_VECTORS,
MT_HIGH_VECTORS,
MT_MEMORY_RWX,
MT_MEMORY_RW,
MT_MEMORY_RO,
MT_ROM,
MT_MEMORY_RWX_NONCACHED,
MT_MEMORY_RW_DTCM,
MT_MEMORY_RWX_ITCM,
MT_MEMORY_RW_SO,
MT_MEMORY_DMA_READY,
};
#ifdef CONFIG_MMU
extern void iotable_init(struct map_desc *, int);
extern void vm_reserve_area_early(unsigned long addr, unsigned long size,
void *caller);
extern void create_mapping_late(struct mm_struct *mm, struct map_desc *md,
bool ng);
#ifdef CONFIG_DEBUG_LL
extern void debug_ll_addr(unsigned long *paddr, unsigned long *vaddr);
extern void debug_ll_io_init(void);
#else
static inline void debug_ll_io_init(void) {}
#endif
struct mem_type;
extern const struct mem_type *get_mem_type(unsigned int type);
/*
* external interface to remap single page with appropriate type
*/
extern int ioremap_page(unsigned long virt, unsigned long phys,
const struct mem_type *mtype);
#else
#define iotable_init(map,num) do { } while (0)
#define vm_reserve_area_early(a,s,c) do { } while (0)
#endif
#endif

Some files were not shown because too many files have changed in this diff Show More