aboutsummaryrefslogtreecommitdiff
path: root/package/boot/uboot-d1/patches/0076-riscv-cpu-Add-cache-operations-for-T-HEAD-CPUs.patch
blob: 0555b6d9b409d8d79e0082c290c3c30e6440d244 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
From b6da98cd39612bb5660afbcad06e3a6bac43563e Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sat, 11 Sep 2021 23:27:42 -0500
Subject: [PATCH 76/90] riscv: cpu: Add cache operations for T-HEAD CPUs

Signed-off-by: Samuel Holland <samuel@sholland.org>
---
 arch/riscv/cpu/Makefile      |   1 +
 arch/riscv/cpu/thead/cache.c | 119 +++++++++++++++++++++++++++++++++++
 arch/riscv/lib/cache.c       |   2 +-
 3 files changed, 121 insertions(+), 1 deletion(-)
 create mode 100644 arch/riscv/cpu/thead/cache.c

--- a/arch/riscv/cpu/Makefile
+++ b/arch/riscv/cpu/Makefile
@@ -5,3 +5,4 @@
 extra-y = start.o
 
 obj-y += cpu.o mtrap.o
+obj-y += thead/cache.o
--- /dev/null
+++ b/arch/riscv/cpu/thead/cache.c
@@ -0,0 +1,119 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include <asm/cache.h>
+#include <asm/csr.h>
+
+#define CSR_MHCR		0x7c1
+#define CSR_MCOR		0x7c2
+#define CSR_MHINT		0x7c5
+
+#define MHCR_IE			BIT(0)	/* icache enable */
+#define MHCR_DE			BIT(1)	/* dcache enable */
+#define MHCR_WA			BIT(2)	/* dcache write allocate */
+#define MHCR_WB			BIT(3)	/* dcache write back */
+#define MHCR_RS			BIT(4)	/* return stack enable */
+#define MHCR_BPE		BIT(5)	/* branch prediction enable */
+#define MHCR_BTB		BIT(6)	/* branch target prediction enable */
+#define MHCR_WBR		BIT(8)	/* write burst enable */
+#define MHCR_L0BTB		BIT(12)
+
+#define MCOR_CACHE_SEL_ICACHE	(0x1 << 0)
+#define MCOR_CACHE_SEL_DCACHE	(0x2 << 0)
+#define MCOR_CACHE_SEL_BOTH	(0x3 << 0)
+#define MCOR_INV		BIT(4)
+#define MCOR_CLR		BIT(5)
+#define MCOR_BHT_INV		BIT(16)
+#define MCOR_BTB_INV		BIT(17)
+
+#define MHINT_DPLD		BIT(2)	/* dcache prefetch enable */
+#define MHINT_AMR_PAGE		(0x0 << 3)
+#define MHINT_AMR_LIMIT_3	(0x1 << 3)
+#define MHINT_AMR_LIMIT_64	(0x2 << 3)
+#define MHINT_AMR_LIMIT_128	(0x3 << 3)
+#define MHINT_IPLD		BIT(8)	/* icache prefetch enable */
+#define MHINT_IWPE		BIT(9)	/* icache prediction enable */
+#define MHINT_DIS_PREFETCH_2	(0x0 << 13)
+#define MHINT_DIS_PREFETCH_4	(0x1 << 13)
+#define MHINT_DIS_PREFETCH_8	(0x2 << 13)
+#define MHINT_DIS_PREFETCH_16	(0x3 << 13)
+
+#define sync_i()		asm volatile (".long 0x01a0000b" ::: "memory")
+
+void flush_dcache_all(void)
+{
+	asm volatile (".long 0x0030000b" ::: "memory"); /* dcache.ciall */
+	sync_i();
+}
+
+void flush_dcache_range(unsigned long start, unsigned long end)
+{
+	register unsigned long i asm("a0") = start & -CONFIG_SYS_CACHELINE_SIZE;
+
+	for (; i < end; i += CONFIG_SYS_CACHELINE_SIZE)
+		asm volatile (".long 0x02b5000b" ::: "memory"); /* dcache.cipa a0 */
+	sync_i();
+}
+
+void invalidate_icache_range(unsigned long start, unsigned long end)
+{
+	register unsigned long i asm("a0") = start & -CONFIG_SYS_CACHELINE_SIZE;
+
+	for (; i < end; i += CONFIG_SYS_CACHELINE_SIZE)
+		asm volatile (".long 0x0385000b" ::: "memory"); /* icache.ipa a0 */
+	sync_i();
+}
+
+void invalidate_dcache_range(unsigned long start, unsigned long end)
+{
+	register unsigned long i asm("a0") = start & -CONFIG_SYS_CACHELINE_SIZE;
+
+	for (; i < end; i += CONFIG_SYS_CACHELINE_SIZE)
+		asm volatile (".long 0x02a5000b" ::: "memory"); /* dcache.ipa a0 */
+	sync_i();
+}
+
+#if 0
+void icache_enable(void)
+{
+	asm volatile (".long 0x0100000b" ::: "memory"); /* icache.iall */
+	sync_i();
+	csr_set(CSR_MHCR, MHCR_IE | MHCR_RS | MHCR_BPE | MHCR_BTB | MHCR_L0BTB);
+	csr_set(CSR_MHINT, MHINT_IPLD | MHINT_IWPE);
+}
+
+void icache_disable(void)
+{
+	csr_clear(CSR_MHCR, MHCR_IE);
+}
+
+int icache_status(void)
+{
+	return csr_read(CSR_MHCR) & MHCR_IE;
+}
+
+void dcache_enable(void)
+{
+	asm volatile (".long 0x0020000b" ::: "memory"); /* dcache.iall */
+	sync_i();
+	csr_set(CSR_MHCR, MHCR_DE | MHCR_WA | MHCR_WB | MHCR_WBR);
+	csr_set(CSR_MHINT, MHINT_DPLD | MHINT_AMR_LIMIT_3);
+}
+
+void dcache_disable(void)
+{
+	asm volatile (".long 0x0010000b" ::: "memory"); /* dcache.call */
+	sync_i();
+	csr_clear(CSR_MHCR, MHCR_DE);
+}
+
+int dcache_status(void)
+{
+	return csr_read(CSR_MHCR) & MHCR_DE;
+}
+
+void enable_caches(void)
+{
+	icache_enable();
+	dcache_enable();
+}
+#endif
--- a/arch/riscv/lib/cache.c
+++ b/arch/riscv/lib/cache.c
@@ -20,7 +20,7 @@ __weak void flush_dcache_range(unsigned
 {
 }
 
-void invalidate_icache_range(unsigned long start, unsigned long end)
+__weak void invalidate_icache_range(unsigned long start, unsigned long end)
 {
 	/*
 	 * RISC-V does not have an instruction for invalidating parts of the