On Wed, Jan 15, 2025 at 11:11:57AM +0100, Marek Szyprowski wrote: > 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? I should be more carefull when doing c&p. I've posted the fix at https://lore.kernel.org/r/20250115-arm-cacheinfo-fix-v1-1-5f30eeb4e463@xxxxxxxxxx > > > + 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 > -- With best wishes Dmitry