cache.h 3.2 KB
Newer Older
1
/* SPDX-License-Identifier: GPL-2.0-only */
2
3
4
5
6
7
/*
 * Copyright (C) 2012 ARM Ltd.
 */
#ifndef __ASM_CACHE_H
#define __ASM_CACHE_H

8
#include <asm/cputype.h>
9
#include <asm/mte-kasan.h>
10
11
12

#define CTR_L1IP_SHIFT		14
#define CTR_L1IP_MASK		3
13
#define CTR_DMINLINE_SHIFT	16
14
#define CTR_IMINLINE_SHIFT	0
15
#define CTR_IMINLINE_MASK	0xf
16
#define CTR_ERG_SHIFT		20
17
18
#define CTR_CWG_SHIFT		24
#define CTR_CWG_MASK		15
19
20
#define CTR_IDC_SHIFT		28
#define CTR_DIC_SHIFT		29
21

22
#define CTR_CACHE_MINLINE_MASK	\
23
	(0xf << CTR_DMINLINE_SHIFT | CTR_IMINLINE_MASK << CTR_IMINLINE_SHIFT)
24

25
26
#define CTR_L1IP(ctr)		(((ctr) >> CTR_L1IP_SHIFT) & CTR_L1IP_MASK)

27
#define ICACHE_POLICY_VPIPT	0
28
#define ICACHE_POLICY_RESERVED	1
29
30
#define ICACHE_POLICY_VIPT	2
#define ICACHE_POLICY_PIPT	3
31

32
#define L1_CACHE_SHIFT		(6)
33
34
#define L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)

35
36
37
38
39
40
41
42
43

#define CLIDR_LOUU_SHIFT	27
#define CLIDR_LOC_SHIFT		24
#define CLIDR_LOUIS_SHIFT	21

#define CLIDR_LOUU(clidr)	(((clidr) >> CLIDR_LOUU_SHIFT) & 0x7)
#define CLIDR_LOC(clidr)	(((clidr) >> CLIDR_LOC_SHIFT) & 0x7)
#define CLIDR_LOUIS(clidr)	(((clidr) >> CLIDR_LOUIS_SHIFT) & 0x7)

44
45
46
47
48
49
50
/*
 * 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.
 */
51
#define ARCH_DMA_MINALIGN	(128)
52

53
54
#ifdef CONFIG_KASAN_SW_TAGS
#define ARCH_SLAB_MINALIGN	(1ULL << KASAN_SHADOW_SCALE_SHIFT)
55
56
#elif defined(CONFIG_KASAN_HW_TAGS)
#define ARCH_SLAB_MINALIGN	MTE_GRANULE_SIZE
57
58
#endif

59
60
#ifndef __ASSEMBLY__

61
62
63
#include <linux/bitops.h>

#define ICACHEF_ALIASING	0
64
#define ICACHEF_VPIPT		1
65
66
67
68
69
70
71
72
73
74
75
extern unsigned long __icache_flags;

/*
 * Whilst the D-side always behaves as PIPT on AArch64, aliasing is
 * permitted in the I-cache.
 */
static inline int icache_is_aliasing(void)
{
	return test_bit(ICACHEF_ALIASING, &__icache_flags);
}

76
static __always_inline int icache_is_vpipt(void)
77
78
79
80
{
	return test_bit(ICACHEF_VPIPT, &__icache_flags);
}

81
82
83
84
85
static inline u32 cache_type_cwg(void)
{
	return (read_cpuid_cachetype() >> CTR_CWG_SHIFT) & CTR_CWG_MASK;
}

86
#define __read_mostly __section(".data..read_mostly")
87

88
static inline int cache_line_size_of_cpu(void)
89
90
{
	u32 cwg = cache_type_cwg();
91

92
	return cwg ? 4 << cwg : ARCH_DMA_MINALIGN;
93
94
}

95
int cache_line_size(void);
96

97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/*
 * Read the effective value of CTR_EL0.
 *
 * According to ARM ARM for ARMv8-A (ARM DDI 0487C.a),
 * section D10.2.33 "CTR_EL0, Cache Type Register" :
 *
 * CTR_EL0.IDC reports the data cache clean requirements for
 * instruction to data coherence.
 *
 *  0 - dcache clean to PoU is required unless :
 *     (CLIDR_EL1.LoC == 0) || (CLIDR_EL1.LoUIS == 0 && CLIDR_EL1.LoUU == 0)
 *  1 - dcache clean to PoU is not required for i-to-d coherence.
 *
 * This routine provides the CTR_EL0 with the IDC field updated to the
 * effective state.
 */
static inline u32 __attribute_const__ read_cpuid_effective_cachetype(void)
{
	u32 ctr = read_cpuid_cachetype();

	if (!(ctr & BIT(CTR_IDC_SHIFT))) {
		u64 clidr = read_sysreg(clidr_el1);

		if (CLIDR_LOC(clidr) == 0 ||
		    (CLIDR_LOUIS(clidr) == 0 && CLIDR_LOUU(clidr) == 0))
			ctr |= BIT(CTR_IDC_SHIFT);
	}

	return ctr;
}

128
#endif	/* __ASSEMBLY__ */
129
130

#endif