1 /*
2  * Copyright (c) 2006-2021, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2016-09-07    Urey         the first version
9  */
10 
11 #include <rtthread.h>
12 #include "mips.h"
13 
14 extern void cache_init(rt_ubase_t cache_size, rt_ubase_t cache_line_size);
r4k_cache_init(void)15 void r4k_cache_init(void)
16 {
17 //  cache_init(dcache_size, cpu_dcache_line_size);
18 }
19 
r4k_cache_flush_all(void)20 void r4k_cache_flush_all(void)
21 {
22     blast_dcache16();
23     blast_icache16();
24 }
25 
26 
r4k_icache_flush_all(void)27 void r4k_icache_flush_all(void)
28 {
29     blast_icache16();
30 }
31 
r4k_icache_flush_range(rt_ubase_t addr,rt_ubase_t size)32 void r4k_icache_flush_range(rt_ubase_t addr, rt_ubase_t size)
33 {
34     rt_ubase_t end, a;
35 
36     if (size > g_mips_core.icache_size)
37     {
38         blast_icache16();
39     }
40     else
41     {
42         rt_ubase_t ic_lsize = g_mips_core.icache_line_size;
43 
44         a = addr & ~(ic_lsize - 1);
45         end = ((addr + size) - 1) & ~(ic_lsize - 1);
46         while (1)
47         {
48             flush_icache_line(a);
49             if (a == end)
50                 break;
51             a += ic_lsize;
52         }
53     }
54 }
55 
r4k_icache_lock_range(rt_ubase_t addr,rt_ubase_t size)56 void r4k_icache_lock_range(rt_ubase_t addr, rt_ubase_t size)
57 {
58     rt_ubase_t end, a;
59     rt_ubase_t ic_lsize = g_mips_core.icache_line_size;
60 
61     a = addr & ~(ic_lsize - 1);
62     end = ((addr + size) - 1) & ~(ic_lsize - 1);
63     while (1)
64     {
65         lock_icache_line(a);
66         if (a == end)
67             break;
68         a += ic_lsize;
69     }
70 }
71 
r4k_dcache_inv(rt_ubase_t addr,rt_ubase_t size)72 void r4k_dcache_inv(rt_ubase_t addr, rt_ubase_t size)
73 {
74     rt_ubase_t end, a;
75     rt_ubase_t dc_lsize = g_mips_core.dcache_line_size;
76 
77     a = addr & ~(dc_lsize - 1);
78     end = ((addr + size) - 1) & ~(dc_lsize - 1);
79     while (1)
80     {
81         invalidate_dcache_line(a);
82         if (a == end)
83             break;
84         a += dc_lsize;
85     }
86 }
87 
r4k_dcache_wback_inv(rt_ubase_t addr,rt_ubase_t size)88 void r4k_dcache_wback_inv(rt_ubase_t addr, rt_ubase_t size)
89 {
90     rt_ubase_t end, a;
91 
92     if (size >= g_mips_core.dcache_size)
93     {
94         blast_dcache16();
95     }
96     else
97     {
98         rt_ubase_t dc_lsize = g_mips_core.dcache_line_size;
99 
100         a = addr & ~(dc_lsize - 1);
101         end = ((addr + size) - 1) & ~(dc_lsize - 1);
102         while (1)
103         {
104             flush_dcache_line(a);
105             if (a == end)
106                 break;
107             a += dc_lsize;
108         }
109     }
110 }
111 
112 #define dma_cache_wback_inv(start,size) \
113     do { (void) (start); (void) (size); } while (0)
114 #define dma_cache_wback(start,size) \
115     do { (void) (start); (void) (size); } while (0)
116 #define dma_cache_inv(start,size)   \
117     do { (void) (start); (void) (size); } while (0)
118 
119 
r4k_dma_cache_sync(rt_ubase_t addr,rt_size_t size,enum dma_data_direction direction)120 void r4k_dma_cache_sync(rt_ubase_t addr, rt_size_t size, enum dma_data_direction direction)
121 {
122     switch (direction)
123     {
124         case DMA_TO_DEVICE:
125             r4k_dcache_wback_inv(addr, size);
126         break;
127 
128         case DMA_FROM_DEVICE:
129             r4k_dcache_wback_inv(addr, size);
130         break;
131 
132         case DMA_BIDIRECTIONAL:
133             dma_cache_wback_inv(addr, size);
134         break;
135         default:
136             RT_ASSERT(0) ;
137     }
138 }
139 
140