On 14.10.2024 15:55, Dmitry Baryshkov wrote: > On ARMv7 / v7m machines read CTR and CLIDR registers to provide > information regarding the cache topology. Earlier machines should > describe full cache topology in the device tree. > > Note, this follows the ARM64 cacheinfo support and provides only minimal > support required to bootstrap cache info. All useful properties should > be decribed in Device Tree. > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@xxxxxxxxxx> > --- > arch/arm/Kconfig | 1 + > arch/arm/include/asm/cache.h | 6 ++ > arch/arm/kernel/Makefile | 1 + > arch/arm/kernel/cacheinfo.c | 173 +++++++++++++++++++++++++++++++++++++++++++ > include/linux/cacheinfo.h | 2 +- > 5 files changed, 182 insertions(+), 1 deletion(-) > > diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig > index 749179a1d162..e790543c3eaf 100644 > --- a/arch/arm/Kconfig > +++ b/arch/arm/Kconfig > @@ -5,6 +5,7 @@ config ARM > select ARCH_32BIT_OFF_T > select ARCH_CORRECT_STACKTRACE_ON_KRETPROBE if HAVE_KRETPROBES && FRAME_POINTER && !ARM_UNWIND > select ARCH_HAS_BINFMT_FLAT > + select ARCH_HAS_CACHE_LINE_SIZE if OF > select ARCH_HAS_CPU_CACHE_ALIASING > select ARCH_HAS_CPU_FINALIZE_INIT if MMU > select ARCH_HAS_CURRENT_STACK_POINTER > diff --git a/arch/arm/include/asm/cache.h b/arch/arm/include/asm/cache.h > index e3ea34558ada..ecbc100d22a5 100644 > --- a/arch/arm/include/asm/cache.h > +++ b/arch/arm/include/asm/cache.h > @@ -26,4 +26,10 @@ > > #define __read_mostly __section(".data..read_mostly") > > +#ifndef __ASSEMBLY__ > +#ifdef CONFIG_ARCH_HAS_CACHE_LINE_SIZE > +int cache_line_size(void); > +#endif > +#endif > + > #endif > diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile > index aaae31b8c4a5..b3333d070390 100644 > --- a/arch/arm/kernel/Makefile > +++ b/arch/arm/kernel/Makefile > @@ -40,6 +40,7 @@ obj-y += entry-armv.o > endif > > obj-$(CONFIG_MMU) += bugs.o > +obj-$(CONFIG_OF) += cacheinfo.o > obj-$(CONFIG_CPU_IDLE) += cpuidle.o > obj-$(CONFIG_ISA_DMA_API) += dma.o > obj-$(CONFIG_FIQ) += fiq.o fiqasm.o > diff --git a/arch/arm/kernel/cacheinfo.c b/arch/arm/kernel/cacheinfo.c > new file mode 100644 > index 000000000000..a8eabcaa18d8 > --- /dev/null > +++ b/arch/arm/kernel/cacheinfo.c > @@ -0,0 +1,173 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* > + * ARM cacheinfo support > + * > + * Copyright (C) 2023 Linaro Ltd. > + * Copyright (C) 2015 ARM Ltd. > + * All Rights Reserved > + */ > + > +#include <linux/bitfield.h> > +#include <linux/cacheinfo.h> > +#include <linux/of.h> > + > +#include <asm/cachetype.h> > +#include <asm/cputype.h> > +#include <asm/system_info.h> > + > +/* Ctypen, bits[3(n - 1) + 2 : 3(n - 1)], for n = 1 to 7 */ > +#define CLIDR_CTYPE_SHIFT(level) (3 * (level - 1)) > +#define CLIDR_CTYPE_MASK(level) (7 << CLIDR_CTYPE_SHIFT(level)) > +#define CLIDR_CTYPE(clidr, level) \ > + (((clidr) & CLIDR_CTYPE_MASK(level)) >> CLIDR_CTYPE_SHIFT(level)) > + > +#define MAX_CACHE_LEVEL 7 /* Max 7 level supported */ > + > +#define CTR_FORMAT_MASK GENMASK(27, 24) > +#define CTR_FORMAT_ARMV6 0 > +#define CTR_FORMAT_ARMV7 4 > +#define CTR_CWG_MASK GENMASK(27, 24) > +#define CTR_DSIZE_LEN_MASK GENMASK(13, 12) > +#define CTR_ISIZE_LEN_MASK GENMASK(1, 0) > + > +/* Also valid for v7m */ > +static inline int cache_line_size_cp15(void) > +{ > + u32 ctr = read_cpuid_cachetype(); > + u32 format = FIELD_GET(CTR_FORMAT_MASK, ctr); > + On Samsung Exynos421x (CortexA9 based) format is read as 0x3, which causes a warning later in the code. How such value should be handled to avoid warning? > + if (format == CTR_FORMAT_ARMV7) { > + u32 cwg = FIELD_GET(CTR_CWG_MASK, ctr); > + > + return cwg ? 4 << cwg : ARCH_DMA_MINALIGN; > + } else if (WARN_ON_ONCE(format != CTR_FORMAT_ARMV6)) { > + return ARCH_DMA_MINALIGN; > + } > + > + return 8 << max(FIELD_GET(CTR_ISIZE_LEN_MASK, ctr), > + FIELD_GET(CTR_DSIZE_LEN_MASK, ctr)); > +} > + > >... Best regards -- Marek Szyprowski, PhD Samsung R&D Institute Poland