1 /*
2 * File : mips_cache.c
3 * This file is part of RT-Thread RTOS
4 * COPYRIGHT (C) 2008 - 2012, RT-Thread Development Team
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Change Logs:
21 * Date Author Notes
22 * 2016��9��7�� Urey the first version
23 */
24
25 #include <rtthread.h>
26 #include "mips.h"
27
28 extern void cache_init(rt_ubase_t cache_size, rt_ubase_t cache_line_size);
r4k_cache_init(void)29 void r4k_cache_init(void)
30 {
31 // cache_init(dcache_size, cpu_dcache_line_size);
32 }
33
r4k_cache_flush_all(void)34 void r4k_cache_flush_all(void)
35 {
36 blast_dcache16();
37 blast_icache16();
38 }
39
40
r4k_icache_flush_all(void)41 void r4k_icache_flush_all(void)
42 {
43 blast_icache16();
44 }
45
r4k_icache_flush_range(rt_ubase_t addr,rt_ubase_t size)46 void r4k_icache_flush_range(rt_ubase_t addr, rt_ubase_t size)
47 {
48 rt_ubase_t end, a;
49
50 if (size > g_mips_core.icache_size)
51 {
52 blast_icache16();
53 }
54 else
55 {
56 rt_ubase_t ic_lsize = g_mips_core.icache_line_size;
57
58 a = addr & ~(ic_lsize - 1);
59 end = ((addr + size) - 1) & ~(ic_lsize - 1);
60 while (1)
61 {
62 flush_icache_line(a);
63 if (a == end)
64 break;
65 a += ic_lsize;
66 }
67 }
68 }
69
r4k_icache_lock_range(rt_ubase_t addr,rt_ubase_t size)70 void r4k_icache_lock_range(rt_ubase_t addr, rt_ubase_t size)
71 {
72 rt_ubase_t end, a;
73 rt_ubase_t ic_lsize = g_mips_core.icache_line_size;
74
75 a = addr & ~(ic_lsize - 1);
76 end = ((addr + size) - 1) & ~(ic_lsize - 1);
77 while (1)
78 {
79 lock_icache_line(a);
80 if (a == end)
81 break;
82 a += ic_lsize;
83 }
84 }
85
r4k_dcache_inv(rt_ubase_t addr,rt_ubase_t size)86 void r4k_dcache_inv(rt_ubase_t addr, rt_ubase_t size)
87 {
88 rt_ubase_t end, a;
89 rt_ubase_t dc_lsize = g_mips_core.dcache_line_size;
90
91 a = addr & ~(dc_lsize - 1);
92 end = ((addr + size) - 1) & ~(dc_lsize - 1);
93 while (1)
94 {
95 invalidate_dcache_line(a);
96 if (a == end)
97 break;
98 a += dc_lsize;
99 }
100 }
101
r4k_dcache_wback_inv(rt_ubase_t addr,rt_ubase_t size)102 void r4k_dcache_wback_inv(rt_ubase_t addr, rt_ubase_t size)
103 {
104 rt_ubase_t end, a;
105
106 if (size >= g_mips_core.dcache_size)
107 {
108 blast_dcache16();
109 }
110 else
111 {
112 rt_ubase_t dc_lsize = g_mips_core.dcache_line_size;
113
114 a = addr & ~(dc_lsize - 1);
115 end = ((addr + size) - 1) & ~(dc_lsize - 1);
116 while (1)
117 {
118 flush_dcache_line(a);
119 if (a == end)
120 break;
121 a += dc_lsize;
122 }
123 }
124 }
125
126 #define dma_cache_wback_inv(start,size) \
127 do { (void) (start); (void) (size); } while (0)
128 #define dma_cache_wback(start,size) \
129 do { (void) (start); (void) (size); } while (0)
130 #define dma_cache_inv(start,size) \
131 do { (void) (start); (void) (size); } while (0)
132
133
r4k_dma_cache_sync(rt_ubase_t addr,rt_size_t size,enum dma_data_direction direction)134 void r4k_dma_cache_sync(rt_ubase_t addr, rt_size_t size, enum dma_data_direction direction)
135 {
136 switch (direction)
137 {
138 case DMA_TO_DEVICE:
139 r4k_dcache_wback_inv(addr, size);
140 break;
141
142 case DMA_FROM_DEVICE:
143 r4k_dcache_wback_inv(addr, size);
144 break;
145
146 case DMA_BIDIRECTIONAL:
147 dma_cache_wback_inv(addr, size);
148 break;
149 default:
150 RT_ASSERT(0) ;
151 }
152 }
153
154