1
2
3
4
5
6
7
8#include <common.h>
9#include <asm/cacheops.h>
10#include <asm/mipsregs.h>
11
12static inline unsigned long icache_line_size(void)
13{
14 unsigned long conf1, il;
15
16 if (!config_enabled(CONFIG_SYS_CACHE_SIZE_AUTO))
17 return CONFIG_SYS_ICACHE_LINE_SIZE;
18
19 conf1 = read_c0_config1();
20 il = (conf1 & MIPS_CONF1_IL) >> MIPS_CONF1_IL_SHF;
21 if (!il)
22 return 0;
23 return 2 << il;
24}
25
26static inline unsigned long dcache_line_size(void)
27{
28 unsigned long conf1, dl;
29
30 if (!config_enabled(CONFIG_SYS_CACHE_SIZE_AUTO))
31 return CONFIG_SYS_DCACHE_LINE_SIZE;
32
33 conf1 = read_c0_config1();
34 dl = (conf1 & MIPS_CONF1_DL) >> MIPS_CONF1_DL_SHF;
35 if (!dl)
36 return 0;
37 return 2 << dl;
38}
39
40#define cache_loop(start, end, lsize, ops...) do { \
41 const void *addr = (const void *)(start & ~(lsize - 1)); \
42 const void *aend = (const void *)((end - 1) & ~(lsize - 1)); \
43 const unsigned int cache_ops[] = { ops }; \
44 unsigned int i; \
45 \
46 for (; addr <= aend; addr += lsize) { \
47 for (i = 0; i < ARRAY_SIZE(cache_ops); i++) \
48 mips_cache(cache_ops[i], addr); \
49 } \
50} while (0)
51
52void flush_cache(ulong start_addr, ulong size)
53{
54 unsigned long ilsize = icache_line_size();
55 unsigned long dlsize = dcache_line_size();
56
57
58 if (size == 0)
59 return;
60
61 if (ilsize == dlsize) {
62
63 cache_loop(start_addr, start_addr + size, ilsize,
64 HIT_WRITEBACK_INV_D, HIT_INVALIDATE_I);
65 return;
66 }
67
68
69 cache_loop(start_addr, start_addr + size, dlsize, HIT_WRITEBACK_INV_D);
70
71
72 cache_loop(start_addr, start_addr + size, ilsize, HIT_INVALIDATE_I);
73}
74
75void flush_dcache_range(ulong start_addr, ulong stop)
76{
77 unsigned long lsize = dcache_line_size();
78
79
80 if (start_addr == stop)
81 return;
82
83 cache_loop(start_addr, stop, lsize, HIT_WRITEBACK_INV_D);
84}
85
86void invalidate_dcache_range(ulong start_addr, ulong stop)
87{
88 unsigned long lsize = dcache_line_size();
89
90
91 if (start_addr == stop)
92 return;
93
94 cache_loop(start_addr, stop, lsize, HIT_INVALIDATE_D);
95}
96