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
|