1
2
3
4
5
6
7
8#include <common.h>
9#include <command.h>
10#include <asm/processor.h>
11#include <asm/io.h>
12
13
14
15
16
17#define jump_to_P2() \
18 do { \
19 unsigned long __dummy; \
20 __asm__ __volatile__( \
21 "mov.l 1f, %0\n\t" \
22 "or %1, %0\n\t" \
23 "jmp @%0\n\t" \
24 " nop\n\t" \
25 ".balign 4\n" \
26 "1: .long 2f\n" \
27 "2:" \
28 : "=&r" (__dummy) \
29 : "r" (0x20000000)); \
30 } while (0)
31
32
33
34
35#define back_to_P1() \
36 do { \
37 unsigned long __dummy; \
38 __asm__ __volatile__( \
39 "nop;nop;nop;nop;nop;nop;nop\n\t" \
40 "mov.l 1f, %0\n\t" \
41 "jmp @%0\n\t" \
42 " nop\n\t" \
43 ".balign 4\n" \
44 "1: .long 2f\n" \
45 "2:" \
46 : "=&r" (__dummy)); \
47 } while (0)
48
49#define CACHE_VALID 1
50#define CACHE_UPDATED 2
51
52static inline void cache_wback_all(void)
53{
54 unsigned long addr, data, i, j;
55
56 jump_to_P2();
57 for (i = 0; i < CACHE_OC_NUM_ENTRIES; i++){
58 for (j = 0; j < CACHE_OC_NUM_WAYS; j++) {
59 addr = CACHE_OC_ADDRESS_ARRAY | (j << CACHE_OC_WAY_SHIFT)
60 | (i << CACHE_OC_ENTRY_SHIFT);
61 data = inl(addr);
62 if (data & CACHE_UPDATED) {
63 data &= ~CACHE_UPDATED;
64 outl(data, addr);
65 }
66 }
67 }
68 back_to_P1();
69}
70
71
72#define CACHE_ENABLE 0
73#define CACHE_DISABLE 1
74
75int cache_control(unsigned int cmd)
76{
77 unsigned long ccr;
78
79 jump_to_P2();
80 ccr = inl(CCR);
81
82 if (ccr & CCR_CACHE_ENABLE)
83 cache_wback_all();
84
85 if (cmd == CACHE_DISABLE)
86 outl(CCR_CACHE_STOP, CCR);
87 else
88 outl(CCR_CACHE_INIT, CCR);
89 back_to_P1();
90
91 return 0;
92}
93
94void flush_dcache_range(unsigned long start, unsigned long end)
95{
96 u32 v;
97
98 start &= ~(L1_CACHE_BYTES - 1);
99 for (v = start; v < end; v += L1_CACHE_BYTES) {
100 asm volatile ("ocbwb %0" :
101 : "m" (__m(v)));
102 }
103}
104
105void invalidate_dcache_range(unsigned long start, unsigned long end)
106{
107 u32 v;
108
109 start &= ~(L1_CACHE_BYTES - 1);
110 for (v = start; v < end; v += L1_CACHE_BYTES) {
111 asm volatile ("ocbi %0" :
112 : "m" (__m(v)));
113 }
114}
115