xref: /nrf52832-nimble/rt-thread/libcpu/mips/common/mips_cache.c (revision 104654410c56c573564690304ae786df310c91fc)
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