mips_cache.c
2.87 KB
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
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2016-09-07 Urey the first version
*/
#include <rtthread.h>
#include "mips.h"
extern void cache_init(rt_ubase_t cache_size, rt_ubase_t cache_line_size);
void r4k_cache_init(void)
{
// cache_init(dcache_size, cpu_dcache_line_size);
}
void r4k_cache_flush_all(void)
{
blast_dcache16();
blast_icache16();
}
void r4k_icache_flush_all(void)
{
blast_icache16();
}
void r4k_icache_flush_range(rt_ubase_t addr, rt_ubase_t size)
{
rt_ubase_t end, a;
if (size > g_mips_core.icache_size)
{
blast_icache16();
}
else
{
rt_ubase_t ic_lsize = g_mips_core.icache_line_size;
a = addr & ~(ic_lsize - 1);
end = ((addr + size) - 1) & ~(ic_lsize - 1);
while (1)
{
flush_icache_line(a);
if (a == end)
break;
a += ic_lsize;
}
}
}
void r4k_icache_lock_range(rt_ubase_t addr, rt_ubase_t size)
{
rt_ubase_t end, a;
rt_ubase_t ic_lsize = g_mips_core.icache_line_size;
a = addr & ~(ic_lsize - 1);
end = ((addr + size) - 1) & ~(ic_lsize - 1);
while (1)
{
lock_icache_line(a);
if (a == end)
break;
a += ic_lsize;
}
}
void r4k_dcache_inv(rt_ubase_t addr, rt_ubase_t size)
{
rt_ubase_t end, a;
rt_ubase_t dc_lsize = g_mips_core.dcache_line_size;
a = addr & ~(dc_lsize - 1);
end = ((addr + size) - 1) & ~(dc_lsize - 1);
while (1)
{
invalidate_dcache_line(a);
if (a == end)
break;
a += dc_lsize;
}
}
void r4k_dcache_wback_inv(rt_ubase_t addr, rt_ubase_t size)
{
rt_ubase_t end, a;
if (size >= g_mips_core.dcache_size)
{
blast_dcache16();
}
else
{
rt_ubase_t dc_lsize = g_mips_core.dcache_line_size;
a = addr & ~(dc_lsize - 1);
end = ((addr + size) - 1) & ~(dc_lsize - 1);
while (1)
{
flush_dcache_line(a);
if (a == end)
break;
a += dc_lsize;
}
}
}
#define dma_cache_wback_inv(start,size) \
do { (void) (start); (void) (size); } while (0)
#define dma_cache_wback(start,size) \
do { (void) (start); (void) (size); } while (0)
#define dma_cache_inv(start,size) \
do { (void) (start); (void) (size); } while (0)
void r4k_dma_cache_sync(rt_ubase_t addr, rt_size_t size, enum dma_data_direction direction)
{
switch (direction)
{
case DMA_TO_DEVICE:
r4k_dcache_wback_inv(addr, size);
break;
case DMA_FROM_DEVICE:
r4k_dcache_wback_inv(addr, size);
break;
case DMA_BIDIRECTIONAL:
dma_cache_wback_inv(addr, size);
break;
default:
RT_ASSERT(0) ;
}
}