xref: /nrf52832-nimble/rt-thread/libcpu/mips/common/mips_cache.h (revision 104654410c56c573564690304ae786df310c91fc)
1*10465441SEvalZero /*
2*10465441SEvalZero  * File      : mips_cache.h
3*10465441SEvalZero  * This file is part of RT-Thread RTOS
4*10465441SEvalZero  * COPYRIGHT (C) 2008 - 2012, RT-Thread Development Team
5*10465441SEvalZero  *
6*10465441SEvalZero  *  This program is free software; you can redistribute it and/or modify
7*10465441SEvalZero  *  it under the terms of the GNU General Public License as published by
8*10465441SEvalZero  *  the Free Software Foundation; either version 2 of the License, or
9*10465441SEvalZero  *  (at your option) any later version.
10*10465441SEvalZero  *
11*10465441SEvalZero  *  This program is distributed in the hope that it will be useful,
12*10465441SEvalZero  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13*10465441SEvalZero  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*10465441SEvalZero  *  GNU General Public License for more details.
15*10465441SEvalZero  *
16*10465441SEvalZero  *  You should have received a copy of the GNU General Public License along
17*10465441SEvalZero  *  with this program; if not, write to the Free Software Foundation, Inc.,
18*10465441SEvalZero  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*10465441SEvalZero  *
20*10465441SEvalZero  * Change Logs:
21*10465441SEvalZero  * Date           Author       Notes
22*10465441SEvalZero  * 2016��9��10��     Urey         the first version
23*10465441SEvalZero  */
24*10465441SEvalZero 
25*10465441SEvalZero #ifndef _MIPS_CACHE_H_
26*10465441SEvalZero #define _MIPS_CACHE_H_
27*10465441SEvalZero 
28*10465441SEvalZero #ifndef __ASSEMBLER__
29*10465441SEvalZero #include <rtdef.h>
30*10465441SEvalZero #include <mips_cfg.h>
31*10465441SEvalZero 
32*10465441SEvalZero /*
33*10465441SEvalZero  * Cache Operations available on all MIPS processors with R4000-style caches
34*10465441SEvalZero  */
35*10465441SEvalZero #define INDEX_INVALIDATE_I      0x00
36*10465441SEvalZero #define INDEX_WRITEBACK_INV_D   0x01
37*10465441SEvalZero #define INDEX_LOAD_TAG_I        0x04
38*10465441SEvalZero #define INDEX_LOAD_TAG_D        0x05
39*10465441SEvalZero #define INDEX_STORE_TAG_I       0x08
40*10465441SEvalZero #define INDEX_STORE_TAG_D       0x09
41*10465441SEvalZero #if defined(CONFIG_CPU_LOONGSON2)
42*10465441SEvalZero #define HIT_INVALIDATE_I        0x00
43*10465441SEvalZero #else
44*10465441SEvalZero #define HIT_INVALIDATE_I        0x10
45*10465441SEvalZero #endif
46*10465441SEvalZero #define HIT_INVALIDATE_D        0x11
47*10465441SEvalZero #define HIT_WRITEBACK_INV_D     0x15
48*10465441SEvalZero 
49*10465441SEvalZero /*
50*10465441SEvalZero  *The lock state is cleared by executing an Index
51*10465441SEvalZero Invalidate, Index Writeback Invalidate, Hit
52*10465441SEvalZero Invalidate, or Hit Writeback Invalidate
53*10465441SEvalZero operation to the locked line, or via an Index
54*10465441SEvalZero Store Tag operation with the lock bit reset in
55*10465441SEvalZero the TagLo register.
56*10465441SEvalZero  */
57*10465441SEvalZero #define FETCH_AND_LOCK_I        0x1c
58*10465441SEvalZero #define FETCH_AND_LOCK_D        0x1d
59*10465441SEvalZero 
60*10465441SEvalZero 
61*10465441SEvalZero enum dma_data_direction
62*10465441SEvalZero {
63*10465441SEvalZero     DMA_BIDIRECTIONAL = 0,
64*10465441SEvalZero     DMA_TO_DEVICE = 1,
65*10465441SEvalZero     DMA_FROM_DEVICE = 2,
66*10465441SEvalZero     DMA_NONE = 3,
67*10465441SEvalZero };
68*10465441SEvalZero 
69*10465441SEvalZero /*
70*10465441SEvalZero  * R4000-specific cacheops
71*10465441SEvalZero  */
72*10465441SEvalZero #define CREATE_DIRTY_EXCL_D     0x0d
73*10465441SEvalZero #define FILL                    0x14
74*10465441SEvalZero #define HIT_WRITEBACK_I         0x18
75*10465441SEvalZero #define HIT_WRITEBACK_D         0x19
76*10465441SEvalZero 
77*10465441SEvalZero /*
78*10465441SEvalZero  * R4000SC and R4400SC-specific cacheops
79*10465441SEvalZero  */
80*10465441SEvalZero #define INDEX_INVALIDATE_SI     0x02
81*10465441SEvalZero #define INDEX_WRITEBACK_INV_SD  0x03
82*10465441SEvalZero #define INDEX_LOAD_TAG_SI       0x06
83*10465441SEvalZero #define INDEX_LOAD_TAG_SD       0x07
84*10465441SEvalZero #define INDEX_STORE_TAG_SI      0x0A
85*10465441SEvalZero #define INDEX_STORE_TAG_SD      0x0B
86*10465441SEvalZero #define CREATE_DIRTY_EXCL_SD    0x0f
87*10465441SEvalZero #define HIT_INVALIDATE_SI       0x12
88*10465441SEvalZero #define HIT_INVALIDATE_SD       0x13
89*10465441SEvalZero #define HIT_WRITEBACK_INV_SD    0x17
90*10465441SEvalZero #define HIT_WRITEBACK_SD        0x1b
91*10465441SEvalZero #define HIT_SET_VIRTUAL_SI      0x1e
92*10465441SEvalZero #define HIT_SET_VIRTUAL_SD      0x1f
93*10465441SEvalZero 
94*10465441SEvalZero /*
95*10465441SEvalZero  * R5000-specific cacheops
96*10465441SEvalZero  */
97*10465441SEvalZero #define R5K_PAGE_INVALIDATE_S   0x17
98*10465441SEvalZero 
99*10465441SEvalZero /*
100*10465441SEvalZero  * RM7000-specific cacheops
101*10465441SEvalZero  */
102*10465441SEvalZero #define PAGE_INVALIDATE_T       0x16
103*10465441SEvalZero 
104*10465441SEvalZero /*
105*10465441SEvalZero  * R10000-specific cacheops
106*10465441SEvalZero  *
107*10465441SEvalZero  * Cacheops 0x02, 0x06, 0x0a, 0x0c-0x0e, 0x16, 0x1a and 0x1e are unused.
108*10465441SEvalZero  * Most of the _S cacheops are identical to the R4000SC _SD cacheops.
109*10465441SEvalZero  */
110*10465441SEvalZero #define INDEX_WRITEBACK_INV_S   0x03
111*10465441SEvalZero #define INDEX_LOAD_TAG_S        0x07
112*10465441SEvalZero #define INDEX_STORE_TAG_S       0x0B
113*10465441SEvalZero #define HIT_INVALIDATE_S        0x13
114*10465441SEvalZero #define CACHE_BARRIER           0x14
115*10465441SEvalZero #define HIT_WRITEBACK_INV_S     0x17
116*10465441SEvalZero #define INDEX_LOAD_DATA_I       0x18
117*10465441SEvalZero #define INDEX_LOAD_DATA_D       0x19
118*10465441SEvalZero #define INDEX_LOAD_DATA_S       0x1b
119*10465441SEvalZero #define INDEX_STORE_DATA_I      0x1c
120*10465441SEvalZero #define INDEX_STORE_DATA_D      0x1d
121*10465441SEvalZero #define INDEX_STORE_DATA_S      0x1f
122*10465441SEvalZero 
123*10465441SEvalZero #define cache_op(op, addr)		    \
124*10465441SEvalZero     __asm__ __volatile__(        \
125*10465441SEvalZero         ".set   push\n"             \
126*10465441SEvalZero         ".set   noreorder\n"        \
127*10465441SEvalZero         ".set   mips3\n"            \
128*10465441SEvalZero         "cache  %0, %1\n"           \
129*10465441SEvalZero         ".set   pop\n"              \
130*10465441SEvalZero         :                           \
131*10465441SEvalZero         : "i" (op), "R" (*(unsigned char *)(addr)))
132*10465441SEvalZero 
133*10465441SEvalZero #define cache16_unroll32(base, op)					\
134*10465441SEvalZero 	__asm__ __volatile__(						\
135*10465441SEvalZero 	"	.set noreorder					\n"	\
136*10465441SEvalZero 	"	.set mips3					\n"	\
137*10465441SEvalZero 	"	cache %1, 0x000(%0); cache %1, 0x010(%0)	\n"	\
138*10465441SEvalZero 	"	cache %1, 0x020(%0); cache %1, 0x030(%0)	\n"	\
139*10465441SEvalZero 	"	cache %1, 0x040(%0); cache %1, 0x050(%0)	\n"	\
140*10465441SEvalZero 	"	cache %1, 0x060(%0); cache %1, 0x070(%0)	\n"	\
141*10465441SEvalZero 	"	cache %1, 0x080(%0); cache %1, 0x090(%0)	\n"	\
142*10465441SEvalZero 	"	cache %1, 0x0a0(%0); cache %1, 0x0b0(%0)	\n"	\
143*10465441SEvalZero 	"	cache %1, 0x0c0(%0); cache %1, 0x0d0(%0)	\n"	\
144*10465441SEvalZero 	"	cache %1, 0x0e0(%0); cache %1, 0x0f0(%0)	\n"	\
145*10465441SEvalZero 	"	cache %1, 0x100(%0); cache %1, 0x110(%0)	\n"	\
146*10465441SEvalZero 	"	cache %1, 0x120(%0); cache %1, 0x130(%0)	\n"	\
147*10465441SEvalZero 	"	cache %1, 0x140(%0); cache %1, 0x150(%0)	\n"	\
148*10465441SEvalZero 	"	cache %1, 0x160(%0); cache %1, 0x170(%0)	\n"	\
149*10465441SEvalZero 	"	cache %1, 0x180(%0); cache %1, 0x190(%0)	\n"	\
150*10465441SEvalZero 	"	cache %1, 0x1a0(%0); cache %1, 0x1b0(%0)	\n"	\
151*10465441SEvalZero 	"	cache %1, 0x1c0(%0); cache %1, 0x1d0(%0)	\n"	\
152*10465441SEvalZero 	"	cache %1, 0x1e0(%0); cache %1, 0x1f0(%0)	\n"	\
153*10465441SEvalZero 	"	.set mips0					\n"	\
154*10465441SEvalZero 	"	.set reorder					\n"	\
155*10465441SEvalZero 		:							\
156*10465441SEvalZero 		: "r" (base),						\
157*10465441SEvalZero 		  "i" (op));
158*10465441SEvalZero 
159*10465441SEvalZero 
flush_icache_line_indexed(rt_ubase_t addr)160*10465441SEvalZero static inline void flush_icache_line_indexed(rt_ubase_t addr)
161*10465441SEvalZero {
162*10465441SEvalZero 	cache_op(INDEX_INVALIDATE_I, addr);
163*10465441SEvalZero }
164*10465441SEvalZero 
flush_dcache_line_indexed(rt_ubase_t addr)165*10465441SEvalZero static inline void flush_dcache_line_indexed(rt_ubase_t addr)
166*10465441SEvalZero {
167*10465441SEvalZero 	cache_op(INDEX_WRITEBACK_INV_D, addr);
168*10465441SEvalZero }
169*10465441SEvalZero 
flush_icache_line(rt_ubase_t addr)170*10465441SEvalZero static inline void flush_icache_line(rt_ubase_t addr)
171*10465441SEvalZero {
172*10465441SEvalZero 	cache_op(HIT_INVALIDATE_I, addr);
173*10465441SEvalZero }
174*10465441SEvalZero 
lock_icache_line(rt_ubase_t addr)175*10465441SEvalZero static inline void lock_icache_line(rt_ubase_t addr)
176*10465441SEvalZero {
177*10465441SEvalZero 	cache_op(FETCH_AND_LOCK_I, addr);
178*10465441SEvalZero }
179*10465441SEvalZero 
lock_dcache_line(rt_ubase_t addr)180*10465441SEvalZero static inline void lock_dcache_line(rt_ubase_t addr)
181*10465441SEvalZero {
182*10465441SEvalZero 	cache_op(FETCH_AND_LOCK_D, addr);
183*10465441SEvalZero }
184*10465441SEvalZero 
flush_dcache_line(rt_ubase_t addr)185*10465441SEvalZero static inline void flush_dcache_line(rt_ubase_t addr)
186*10465441SEvalZero {
187*10465441SEvalZero 	cache_op(HIT_WRITEBACK_INV_D, addr);
188*10465441SEvalZero }
189*10465441SEvalZero 
invalidate_dcache_line(rt_ubase_t addr)190*10465441SEvalZero static inline void invalidate_dcache_line(rt_ubase_t addr)
191*10465441SEvalZero {
192*10465441SEvalZero 	cache_op(HIT_INVALIDATE_D, addr);
193*10465441SEvalZero }
blast_dcache16(void)194*10465441SEvalZero static inline void blast_dcache16(void)
195*10465441SEvalZero {
196*10465441SEvalZero 	rt_ubase_t start = KSEG0BASE;
197*10465441SEvalZero 	rt_ubase_t end = start + g_mips_core.dcache_size;
198*10465441SEvalZero 	rt_ubase_t addr;
199*10465441SEvalZero 
200*10465441SEvalZero 	for (addr = start; addr < end; addr += g_mips_core.dcache_line_size)
201*10465441SEvalZero 		cache16_unroll32(addr, INDEX_WRITEBACK_INV_D);
202*10465441SEvalZero }
203*10465441SEvalZero 
inv_dcache16(void)204*10465441SEvalZero static inline void inv_dcache16(void)
205*10465441SEvalZero {
206*10465441SEvalZero 	rt_ubase_t start = KSEG0BASE;
207*10465441SEvalZero 	rt_ubase_t end = start + g_mips_core.dcache_size;
208*10465441SEvalZero 	rt_ubase_t addr;
209*10465441SEvalZero 
210*10465441SEvalZero 	for (addr = start; addr < end; addr += g_mips_core.dcache_line_size)
211*10465441SEvalZero 		cache16_unroll32(addr, HIT_INVALIDATE_D);
212*10465441SEvalZero }
213*10465441SEvalZero 
blast_icache16(void)214*10465441SEvalZero static inline void blast_icache16(void)
215*10465441SEvalZero {
216*10465441SEvalZero 	rt_ubase_t start = KSEG0BASE;
217*10465441SEvalZero 	rt_ubase_t end = start + g_mips_core.icache_size;
218*10465441SEvalZero 	rt_ubase_t addr;
219*10465441SEvalZero 
220*10465441SEvalZero 	for (addr = start; addr < end; addr += g_mips_core.icache_line_size)
221*10465441SEvalZero 		cache16_unroll32(addr, INDEX_INVALIDATE_I);
222*10465441SEvalZero }
223*10465441SEvalZero 
224*10465441SEvalZero void r4k_cache_init(void);
225*10465441SEvalZero void r4k_cache_flush_all(void);
226*10465441SEvalZero void r4k_icache_flush_all(void);
227*10465441SEvalZero void r4k_icache_flush_range(rt_ubase_t addr, rt_ubase_t size);
228*10465441SEvalZero void r4k_icache_lock_range(rt_ubase_t addr, rt_ubase_t size);
229*10465441SEvalZero void r4k_dcache_inv(rt_ubase_t addr, rt_ubase_t size);
230*10465441SEvalZero void r4k_dcache_wback_inv(rt_ubase_t addr, rt_ubase_t size);
231*10465441SEvalZero void r4k_dma_cache_sync(rt_ubase_t addr, rt_size_t size, enum dma_data_direction direction);
232*10465441SEvalZero #endif
233*10465441SEvalZero 
234*10465441SEvalZero #endif /* _MIPS_CACHE_H_ */
235