Skip to content

Commit 816cef9

Browse files
committed
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
2 parents 3cbb9ce + f520fab commit 816cef9

File tree

11 files changed

+196
-53
lines changed

11 files changed

+196
-53
lines changed

arch/arm/Kconfig

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ config ARM
55
select ARCH_32BIT_OFF_T
66
select ARCH_CORRECT_STACKTRACE_ON_KRETPROBE if HAVE_KRETPROBES && FRAME_POINTER && !ARM_UNWIND
77
select ARCH_HAS_BINFMT_FLAT
8+
select ARCH_HAS_CACHE_LINE_SIZE if OF
89
select ARCH_HAS_CPU_CACHE_ALIASING
910
select ARCH_HAS_CPU_FINALIZE_INIT if MMU
1011
select ARCH_HAS_CRC32 if KERNEL_MODE_NEON
@@ -1753,5 +1754,3 @@ config ARCH_HIBERNATION_POSSIBLE
17531754
default y if ARCH_SUSPEND_POSSIBLE
17541755

17551756
endmenu
1756-
1757-
source "arch/arm/Kconfig.assembler"

arch/arm/Kconfig.assembler

Lines changed: 0 additions & 6 deletions
This file was deleted.

arch/arm/include/asm/cache.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,10 @@
2626

2727
#define __read_mostly __section(".data..read_mostly")
2828

29+
#ifndef __ASSEMBLY__
30+
#ifdef CONFIG_ARCH_HAS_CACHE_LINE_SIZE
31+
int cache_line_size(void);
32+
#endif
33+
#endif
34+
2935
#endif

arch/arm/include/asm/cachetype.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,14 @@ static inline unsigned int read_ccsidr(void)
8383
asm volatile("mrc p15, 1, %0, c0, c0, 0" : "=r" (val));
8484
return val;
8585
}
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+
}
8694
#else /* CONFIG_CPU_V7M */
8795
#include <linux/io.h>
8896
#include "asm/v7m.h"
@@ -96,6 +104,11 @@ static inline unsigned int read_ccsidr(void)
96104
{
97105
return readl(BASEADDR_V7M_SCB + V7M_SCB_CCSIDR);
98106
}
107+
108+
static inline unsigned int read_clidr(void)
109+
{
110+
return readl(BASEADDR_V7M_SCB + V7M_SCB_CLIDR);
111+
}
99112
#endif
100113

101114
#endif

arch/arm/include/asm/vfp.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,6 @@
99
#ifndef __ASM_VFP_H
1010
#define __ASM_VFP_H
1111

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-
2212
/* FPSID bits */
2313
#define FPSID_IMPLEMENTER_BIT (24)
2414
#define FPSID_IMPLEMENTER_MASK (0xff << FPSID_IMPLEMENTER_BIT)

arch/arm/include/asm/vfpmacros.h

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,24 +8,13 @@
88

99
#include <asm/vfp.h>
1010

11-
#ifdef CONFIG_AS_VFP_VMRS_FPINST
1211
.macro VFPFMRX, rd, sysreg, cond
1312
vmrs\cond \rd, \sysreg
1413
.endm
1514

1615
.macro VFPFMXR, sysreg, rd, cond
1716
vmsr\cond \sysreg, \rd
1817
.endm
19-
#else
20-
@ Macros to allow building with old toolkits (with no VFP support)
21-
.macro VFPFMRX, rd, sysreg, cond
22-
MRC\cond p10, 7, \rd, \sysreg, cr0, 0 @ FMRX \rd, \sysreg
23-
.endm
24-
25-
.macro VFPFMXR, sysreg, rd, cond
26-
MCR\cond p10, 7, \rd, \sysreg, cr0, 0 @ FMXR \sysreg, \rd
27-
.endm
28-
#endif
2918

3019
@ read all the working registers back into the VFP
3120
.macro VFPFLDMIA, base, tmp

arch/arm/kernel/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ obj-y += entry-armv.o
4040
endif
4141

4242
obj-$(CONFIG_MMU) += bugs.o
43+
obj-$(CONFIG_OF) += cacheinfo.o
4344
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
4445
obj-$(CONFIG_ISA_DMA_API) += dma.o
4546
obj-$(CONFIG_FIQ) += fiq.o fiqasm.o

arch/arm/kernel/cacheinfo.c

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
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+
}

arch/arm/vfp/vfpinstr.h

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,6 @@
6262
#define FPSCR_C (1 << 29)
6363
#define FPSCR_V (1 << 28)
6464

65-
#ifdef CONFIG_AS_VFP_VMRS_FPINST
66-
6765
#define fmrx(_vfp_) ({ \
6866
u32 __v; \
6967
asm volatile (".fpu vfpv2\n" \
@@ -78,26 +76,6 @@
7876
: : "r" (_var_) : "cc"); \
7977
})
8078

81-
#else
82-
83-
#define vfpreg(_vfp_) #_vfp_
84-
85-
#define fmrx(_vfp_) ({ \
86-
u32 __v; \
87-
asm volatile ("mrc p10, 7, %0, " vfpreg(_vfp_) "," \
88-
"cr0, 0 @ fmrx %0, " #_vfp_ \
89-
: "=r" (__v) : : "cc"); \
90-
__v; \
91-
})
92-
93-
#define fmxr(_vfp_, _var_) ({ \
94-
asm volatile ("mcr p10, 7, %0, " vfpreg(_vfp_) "," \
95-
"cr0, 0 @ fmxr " #_vfp_ ", %0" \
96-
: : "r" (_var_) : "cc"); \
97-
})
98-
99-
#endif
100-
10179
u32 vfp_single_cpdo(u32 inst, u32 fpscr);
10280
u32 vfp_single_cprt(u32 inst, u32 fpscr, struct pt_regs *regs);
10381

arch/arm/vfp/vfpmodule.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ static void vfp_thread_copy(struct thread_info *thread)
168168
/*
169169
* When this function is called with the following 'cmd's, the following
170170
* is true while this function is being run:
171-
* THREAD_NOFTIFY_SWTICH:
171+
* THREAD_NOTIFY_SWITCH:
172172
* - the previously running thread will not be scheduled onto another CPU.
173173
* - the next thread to be run (v) will not be running on another CPU.
174174
* - thread->cpu is the local CPU number

0 commit comments

Comments
 (0)