cache.s
3.42 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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#include <asm.h>
#include <regdef.h>
#include <R4300.h>
/*
* invalICache(void *addr, int nbytes)
*/
LEAF(invalICache)
.set mips3
blez a1,2f # If nbytes <= 0, bail
li t3,ICACHE_SIZE
bgeu a1,t3,3f # Is nbytes >= I-Cache size?
move t0,a0
addu t1,a0,a1
bgeu t0,t1,2f # (Check for address wrap)
subu t1,ICACHE_LINESIZE
andi t2,t0,ICACHE_LINEMASK
subu t0,t2
1:
.set noreorder
cache CACH_PI|C_HINV,0(t0) # If not, use hit invalidate
bltu t0,t1,1b # only on given range
addu t0,ICACHE_LINESIZE
.set reorder
2:
j ra
3:
li t0,K0BASE
addu t1,t0,t3
subu t1,ICACHE_LINESIZE
4:
.set noreorder
cache CACH_PI|C_IINV,0(t0) # If so, use index invalidate on
bltu t0,t1,4b # entire cache
addu t0,ICACHE_LINESIZE
.set reorder
j ra
.set mips0
END(invalICache)
/*
* invalDCache(void *addr, int nbytes)
*/
LEAF(invalDCache)
.set mips3
blez a1,3f # If nbytes <= 0, bail
li t3,DCACHE_SIZE
bgeu a1,t3,4f # Is nbytes >= D-Cache size?
move t0,a0
addu t1,a0,a1
bgeu t0,t1,3f # (Check for address wrap)
subu t1,DCACHE_LINESIZE
andi t2,t0,DCACHE_LINEMASK
beq t2,zero,1f # Check if beginning address is aligned
subu t0,t2 # If not, back up to cache line address
.set noreorder
cache CACH_PD|C_HWBINV,0(t0) # Use hit writeback invalidate on first
.set reorder
bgeu t0,t1,3f
addu t0,DCACHE_LINESIZE
1:
and t2,t1,DCACHE_LINEMASK
beq t2,zero,2f # Check if ending address is aligned
subu t1,t2
.set noreorder
cache CACH_PD|C_HWBINV,DCACHE_LINESIZE(t1)
.set reorder
bgtu t0,t1,3f
2:
.set noreorder
cache CACH_PD|C_HINV,0(t0) # If not, use hit invalidate
bltu t0,t1,2b # only on given range
addu t0,DCACHE_LINESIZE
.set reorder
3:
j ra
4:
li t0,K0BASE
addu t1,t0,t3
subu t1,DCACHE_LINESIZE
5:
.set noreorder
cache CACH_PD|C_IWBINV,0(t0) # If so, use index writeback invalidate
bltu t0,t1,5b # on entire cache
addu t0,DCACHE_LINESIZE
.set reorder
j ra
.set mips0
END(invalDCache)
/*
* writebackDCache(void *addr, int nbytes)
*/
LEAF(writebackDCache)
.set mips3
blez a1,2f # If nbytes <= 0, bail
li t3,DCACHE_SIZE
bgeu a1,t3,3f # Is nbytes >= D-Cache size?
move t0,a0
addu t1,a0,a1
bgeu t0,t1,2f # (Check for address wrap)
subu t1,DCACHE_LINESIZE
andi t2,t0,DCACHE_LINEMASK
subu t0,t2
1:
.set noreorder
cache CACH_PD|C_HWB,0(t0) # If not, use hit writeback
bltu t0,t1,1b # only on given range
addu t0,DCACHE_LINESIZE
.set reorder
2:
j ra
3:
li t0,K0BASE
addu t1,t0,t3
subu t1,DCACHE_LINESIZE
4:
.set noreorder
cache CACH_PD|C_IWBINV,0(t0) # If so, use index writeback invalidate
bltu t0,t1,4b # on entire cache
addu t0,DCACHE_LINESIZE
.set reorder
j ra
.set mips0
END(writebackDCache)
#*******<14 Initialize CPU cache>
# Invalidate I cache
LEAF(initICache)
.set mips3
.set reorder
la t0,K0BASE
addu t1,t0,ICACHE_SIZE
subu t1,ICACHE_LINESIZE
.set noreorder
mtc0 zero,C0_TAGLO
mtc0 zero,C0_TAGHI
1:
cache CACH_PI|C_IST,0(t0) # use index invalidate
bltu t0,t1,1b # on entire cache
addu t0,ICACHE_LINESIZE
jr ra
nop
.set reorder
.set mips0
END(initICache)
LEAF(initDCache)
.set mips3
la t0,K0BASE
addu t1,t0,DCACHE_SIZE
subu t1,DCACHE_LINESIZE
# Invalidate D cache
.set noreorder
2:
cache CACH_PD|C_IST,0(t0) # use index store tag to invalidate
bltu t0,t1,2b # cache.
addu t0,DCACHE_LINESIZE # some cache data for NMI case
jr ra
nop
.set reorder
.set mips0
END(initDCache)