Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rmk/linux

Pull ARM updates from Russell King:

- fix typos in vfpmodule.c

- drop obsolete VFP accessor fallback for old assemblers

- add cache line identifier register accessor functions

- add cacheinfo support

* tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rmk/linux:
ARM: 9440/1: cacheinfo fix format field mask
ARM: 9433/2: implement cacheinfo support
ARM: 9432/2: add CLIDR accessor functions
ARM: 9438/1: assembler: Drop obsolete VFP accessor fallback
ARM: 9437/1: vfp: Fix typographical errors in vfpmodule.c

+196 -53
+1 -2
arch/arm/Kconfig
··· 5 5 select ARCH_32BIT_OFF_T 6 6 select ARCH_CORRECT_STACKTRACE_ON_KRETPROBE if HAVE_KRETPROBES && FRAME_POINTER && !ARM_UNWIND 7 7 select ARCH_HAS_BINFMT_FLAT 8 + select ARCH_HAS_CACHE_LINE_SIZE if OF 8 9 select ARCH_HAS_CPU_CACHE_ALIASING 9 10 select ARCH_HAS_CPU_FINALIZE_INIT if MMU 10 11 select ARCH_HAS_CRC32 if KERNEL_MODE_NEON ··· 1754 1753 default y if ARCH_SUSPEND_POSSIBLE 1755 1754 1756 1755 endmenu 1757 - 1758 - source "arch/arm/Kconfig.assembler"
-6
arch/arm/Kconfig.assembler
··· 1 - # SPDX-License-Identifier: GPL-2.0 2 - 3 - config AS_VFP_VMRS_FPINST 4 - def_bool $(as-instr,.fpu vfpv2\nvmrs r0$(comma)FPINST) 5 - help 6 - Supported by binutils >= 2.24 and LLVM integrated assembler.
+6
arch/arm/include/asm/cache.h
··· 26 26 27 27 #define __read_mostly __section(".data..read_mostly") 28 28 29 + #ifndef __ASSEMBLY__ 30 + #ifdef CONFIG_ARCH_HAS_CACHE_LINE_SIZE 31 + int cache_line_size(void); 32 + #endif 33 + #endif 34 + 29 35 #endif
+13
arch/arm/include/asm/cachetype.h
··· 83 83 asm volatile("mrc p15, 1, %0, c0, c0, 0" : "=r" (val)); 84 84 return val; 85 85 } 86 + 87 + static inline unsigned int read_clidr(void) 88 + { 89 + unsigned int val; 90 + 91 + asm volatile("mrc p15, 1, %0, c0, c0, 1" : "=r" (val)); 92 + return val; 93 + } 86 94 #else /* CONFIG_CPU_V7M */ 87 95 #include <linux/io.h> 88 96 #include "asm/v7m.h" ··· 103 95 static inline unsigned int read_ccsidr(void) 104 96 { 105 97 return readl(BASEADDR_V7M_SCB + V7M_SCB_CCSIDR); 98 + } 99 + 100 + static inline unsigned int read_clidr(void) 101 + { 102 + return readl(BASEADDR_V7M_SCB + V7M_SCB_CLIDR); 106 103 } 107 104 #endif 108 105
-10
arch/arm/include/asm/vfp.h
··· 9 9 #ifndef __ASM_VFP_H 10 10 #define __ASM_VFP_H 11 11 12 - #ifndef CONFIG_AS_VFP_VMRS_FPINST 13 - #define FPSID cr0 14 - #define FPSCR cr1 15 - #define MVFR1 cr6 16 - #define MVFR0 cr7 17 - #define FPEXC cr8 18 - #define FPINST cr9 19 - #define FPINST2 cr10 20 - #endif 21 - 22 12 /* FPSID bits */ 23 13 #define FPSID_IMPLEMENTER_BIT (24) 24 14 #define FPSID_IMPLEMENTER_MASK (0xff << FPSID_IMPLEMENTER_BIT)
-11
arch/arm/include/asm/vfpmacros.h
··· 8 8 9 9 #include <asm/vfp.h> 10 10 11 - #ifdef CONFIG_AS_VFP_VMRS_FPINST 12 11 .macro VFPFMRX, rd, sysreg, cond 13 12 vmrs\cond \rd, \sysreg 14 13 .endm ··· 15 16 .macro VFPFMXR, sysreg, rd, cond 16 17 vmsr\cond \sysreg, \rd 17 18 .endm 18 - #else 19 - @ Macros to allow building with old toolkits (with no VFP support) 20 - .macro VFPFMRX, rd, sysreg, cond 21 - MRC\cond p10, 7, \rd, \sysreg, cr0, 0 @ FMRX \rd, \sysreg 22 - .endm 23 - 24 - .macro VFPFMXR, sysreg, rd, cond 25 - MCR\cond p10, 7, \rd, \sysreg, cr0, 0 @ FMXR \sysreg, \rd 26 - .endm 27 - #endif 28 19 29 20 @ read all the working registers back into the VFP 30 21 .macro VFPFLDMIA, base, tmp
+1
arch/arm/kernel/Makefile
··· 40 40 endif 41 41 42 42 obj-$(CONFIG_MMU) += bugs.o 43 + obj-$(CONFIG_OF) += cacheinfo.o 43 44 obj-$(CONFIG_CPU_IDLE) += cpuidle.o 44 45 obj-$(CONFIG_ISA_DMA_API) += dma.o 45 46 obj-$(CONFIG_FIQ) += fiq.o fiqasm.o
+173
arch/arm/kernel/cacheinfo.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * ARM cacheinfo support 4 + * 5 + * Copyright (C) 2023 Linaro Ltd. 6 + * Copyright (C) 2015 ARM Ltd. 7 + * All Rights Reserved 8 + */ 9 + 10 + #include <linux/bitfield.h> 11 + #include <linux/cacheinfo.h> 12 + #include <linux/of.h> 13 + 14 + #include <asm/cachetype.h> 15 + #include <asm/cputype.h> 16 + #include <asm/system_info.h> 17 + 18 + /* Ctypen, bits[3(n - 1) + 2 : 3(n - 1)], for n = 1 to 7 */ 19 + #define CLIDR_CTYPE_SHIFT(level) (3 * (level - 1)) 20 + #define CLIDR_CTYPE_MASK(level) (7 << CLIDR_CTYPE_SHIFT(level)) 21 + #define CLIDR_CTYPE(clidr, level) \ 22 + (((clidr) & CLIDR_CTYPE_MASK(level)) >> CLIDR_CTYPE_SHIFT(level)) 23 + 24 + #define MAX_CACHE_LEVEL 7 /* Max 7 level supported */ 25 + 26 + #define CTR_FORMAT_MASK GENMASK(31, 29) 27 + #define CTR_FORMAT_ARMV6 0 28 + #define CTR_FORMAT_ARMV7 4 29 + #define CTR_CWG_MASK GENMASK(27, 24) 30 + #define CTR_DSIZE_LEN_MASK GENMASK(13, 12) 31 + #define CTR_ISIZE_LEN_MASK GENMASK(1, 0) 32 + 33 + /* Also valid for v7m */ 34 + static inline int cache_line_size_cp15(void) 35 + { 36 + u32 ctr = read_cpuid_cachetype(); 37 + u32 format = FIELD_GET(CTR_FORMAT_MASK, ctr); 38 + 39 + if (format == CTR_FORMAT_ARMV7) { 40 + u32 cwg = FIELD_GET(CTR_CWG_MASK, ctr); 41 + 42 + return cwg ? 4 << cwg : ARCH_DMA_MINALIGN; 43 + } else if (WARN_ON_ONCE(format != CTR_FORMAT_ARMV6)) { 44 + return ARCH_DMA_MINALIGN; 45 + } 46 + 47 + return 8 << max(FIELD_GET(CTR_ISIZE_LEN_MASK, ctr), 48 + FIELD_GET(CTR_DSIZE_LEN_MASK, ctr)); 49 + } 50 + 51 + int cache_line_size(void) 52 + { 53 + if (coherency_max_size != 0) 54 + return coherency_max_size; 55 + 56 + /* CP15 is optional / implementation defined before ARMv6 */ 57 + if (cpu_architecture() < CPU_ARCH_ARMv6) 58 + return ARCH_DMA_MINALIGN; 59 + 60 + return cache_line_size_cp15(); 61 + } 62 + EXPORT_SYMBOL_GPL(cache_line_size); 63 + 64 + static inline enum cache_type get_cache_type(int level) 65 + { 66 + u32 clidr; 67 + 68 + if (level > MAX_CACHE_LEVEL) 69 + return CACHE_TYPE_NOCACHE; 70 + 71 + clidr = read_clidr(); 72 + 73 + return CLIDR_CTYPE(clidr, level); 74 + } 75 + 76 + static void ci_leaf_init(struct cacheinfo *this_leaf, 77 + enum cache_type type, unsigned int level) 78 + { 79 + this_leaf->level = level; 80 + this_leaf->type = type; 81 + } 82 + 83 + static int detect_cache_level(unsigned int *level_p, unsigned int *leaves_p) 84 + { 85 + unsigned int ctype, level, leaves; 86 + u32 ctr, format; 87 + 88 + /* CLIDR is not present before ARMv7/v7m */ 89 + if (cpu_architecture() < CPU_ARCH_ARMv7) 90 + return -EOPNOTSUPP; 91 + 92 + /* Don't try reading CLIDR if CTR declares old format */ 93 + ctr = read_cpuid_cachetype(); 94 + format = FIELD_GET(CTR_FORMAT_MASK, ctr); 95 + if (format != CTR_FORMAT_ARMV7) 96 + return -EOPNOTSUPP; 97 + 98 + for (level = 1, leaves = 0; level <= MAX_CACHE_LEVEL; level++) { 99 + ctype = get_cache_type(level); 100 + if (ctype == CACHE_TYPE_NOCACHE) { 101 + level--; 102 + break; 103 + } 104 + /* Separate instruction and data caches */ 105 + leaves += (ctype == CACHE_TYPE_SEPARATE) ? 2 : 1; 106 + } 107 + 108 + *level_p = level; 109 + *leaves_p = leaves; 110 + 111 + return 0; 112 + } 113 + 114 + int early_cache_level(unsigned int cpu) 115 + { 116 + struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); 117 + 118 + return detect_cache_level(&this_cpu_ci->num_levels, &this_cpu_ci->num_leaves); 119 + } 120 + 121 + int init_cache_level(unsigned int cpu) 122 + { 123 + unsigned int level, leaves; 124 + struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); 125 + int fw_level; 126 + int ret; 127 + 128 + ret = detect_cache_level(&level, &leaves); 129 + if (ret) 130 + return ret; 131 + 132 + fw_level = of_find_last_cache_level(cpu); 133 + 134 + if (level < fw_level) { 135 + /* 136 + * some external caches not specified in CLIDR_EL1 137 + * the information may be available in the device tree 138 + * only unified external caches are considered here 139 + */ 140 + leaves += (fw_level - level); 141 + level = fw_level; 142 + } 143 + 144 + this_cpu_ci->num_levels = level; 145 + this_cpu_ci->num_leaves = leaves; 146 + return 0; 147 + } 148 + 149 + int populate_cache_leaves(unsigned int cpu) 150 + { 151 + unsigned int level, idx; 152 + enum cache_type type; 153 + struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); 154 + struct cacheinfo *this_leaf = this_cpu_ci->info_list; 155 + unsigned int arch = cpu_architecture(); 156 + 157 + /* CLIDR is not present before ARMv7/v7m */ 158 + if (arch < CPU_ARCH_ARMv7) 159 + return -EOPNOTSUPP; 160 + 161 + for (idx = 0, level = 1; level <= this_cpu_ci->num_levels && 162 + idx < this_cpu_ci->num_leaves; idx++, level++) { 163 + type = get_cache_type(level); 164 + if (type == CACHE_TYPE_SEPARATE) { 165 + ci_leaf_init(this_leaf++, CACHE_TYPE_DATA, level); 166 + ci_leaf_init(this_leaf++, CACHE_TYPE_INST, level); 167 + } else { 168 + ci_leaf_init(this_leaf++, type, level); 169 + } 170 + } 171 + 172 + return 0; 173 + }
-22
arch/arm/vfp/vfpinstr.h
··· 62 62 #define FPSCR_C (1 << 29) 63 63 #define FPSCR_V (1 << 28) 64 64 65 - #ifdef CONFIG_AS_VFP_VMRS_FPINST 66 - 67 65 #define fmrx(_vfp_) ({ \ 68 66 u32 __v; \ 69 67 asm volatile (".fpu vfpv2\n" \ ··· 75 77 "vmsr " #_vfp_ ", %0" \ 76 78 : : "r" (_var_) : "cc"); \ 77 79 }) 78 - 79 - #else 80 - 81 - #define vfpreg(_vfp_) #_vfp_ 82 - 83 - #define fmrx(_vfp_) ({ \ 84 - u32 __v; \ 85 - asm volatile ("mrc p10, 7, %0, " vfpreg(_vfp_) "," \ 86 - "cr0, 0 @ fmrx %0, " #_vfp_ \ 87 - : "=r" (__v) : : "cc"); \ 88 - __v; \ 89 - }) 90 - 91 - #define fmxr(_vfp_, _var_) ({ \ 92 - asm volatile ("mcr p10, 7, %0, " vfpreg(_vfp_) "," \ 93 - "cr0, 0 @ fmxr " #_vfp_ ", %0" \ 94 - : : "r" (_var_) : "cc"); \ 95 - }) 96 - 97 - #endif 98 80 99 81 u32 vfp_single_cpdo(u32 inst, u32 fpscr); 100 82 u32 vfp_single_cprt(u32 inst, u32 fpscr, struct pt_regs *regs);
+1 -1
arch/arm/vfp/vfpmodule.c
··· 168 168 /* 169 169 * When this function is called with the following 'cmd's, the following 170 170 * is true while this function is being run: 171 - * THREAD_NOFTIFY_SWTICH: 171 + * THREAD_NOTIFY_SWITCH: 172 172 * - the previously running thread will not be scheduled onto another CPU. 173 173 * - the next thread to be run (v) will not be running on another CPU. 174 174 * - thread->cpu is the local CPU number
+1 -1
include/linux/cacheinfo.h
··· 147 147 return ci ? ci->id : -1; 148 148 } 149 149 150 - #ifdef CONFIG_ARM64 150 + #if defined(CONFIG_ARM64) || defined(CONFIG_ARM) 151 151 #define use_arch_cache_info() (true) 152 152 #else 153 153 #define use_arch_cache_info() (false)