Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/mn10300/mm/cache-flush-by-reg.S
10817 views
1
/* MN10300 CPU core caching routines, using indirect regs on cache controller
2
*
3
* Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4
* Written by David Howells ([email protected])
5
*
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public Licence
8
* as published by the Free Software Foundation; either version
9
* 2 of the Licence, or (at your option) any later version.
10
*/
11
12
#include <linux/sys.h>
13
#include <linux/linkage.h>
14
#include <asm/smp.h>
15
#include <asm/page.h>
16
#include <asm/cache.h>
17
#include <asm/irqflags.h>
18
19
.am33_2
20
21
#ifndef CONFIG_SMP
22
.globl mn10300_dcache_flush
23
.globl mn10300_dcache_flush_page
24
.globl mn10300_dcache_flush_range
25
.globl mn10300_dcache_flush_range2
26
.globl mn10300_dcache_flush_inv
27
.globl mn10300_dcache_flush_inv_page
28
.globl mn10300_dcache_flush_inv_range
29
.globl mn10300_dcache_flush_inv_range2
30
31
mn10300_dcache_flush = mn10300_local_dcache_flush
32
mn10300_dcache_flush_page = mn10300_local_dcache_flush_page
33
mn10300_dcache_flush_range = mn10300_local_dcache_flush_range
34
mn10300_dcache_flush_range2 = mn10300_local_dcache_flush_range2
35
mn10300_dcache_flush_inv = mn10300_local_dcache_flush_inv
36
mn10300_dcache_flush_inv_page = mn10300_local_dcache_flush_inv_page
37
mn10300_dcache_flush_inv_range = mn10300_local_dcache_flush_inv_range
38
mn10300_dcache_flush_inv_range2 = mn10300_local_dcache_flush_inv_range2
39
40
#endif /* !CONFIG_SMP */
41
42
###############################################################################
43
#
44
# void mn10300_local_dcache_flush(void)
45
# Flush the entire data cache back to RAM
46
#
47
###############################################################################
48
ALIGN
49
.globl mn10300_local_dcache_flush
50
.type mn10300_local_dcache_flush,@function
51
mn10300_local_dcache_flush:
52
movhu (CHCTR),d0
53
btst CHCTR_DCEN,d0
54
beq mn10300_local_dcache_flush_end
55
56
mov DCPGCR,a0
57
58
LOCAL_CLI_SAVE(d1)
59
60
# wait for busy bit of area purge
61
setlb
62
mov (a0),d0
63
btst DCPGCR_DCPGBSY,d0
64
lne
65
66
# set mask
67
clr d0
68
mov d0,(DCPGMR)
69
70
# area purge
71
#
72
# DCPGCR = DCPGCR_DCP
73
#
74
mov DCPGCR_DCP,d0
75
mov d0,(a0)
76
77
# wait for busy bit of area purge
78
setlb
79
mov (a0),d0
80
btst DCPGCR_DCPGBSY,d0
81
lne
82
83
LOCAL_IRQ_RESTORE(d1)
84
85
mn10300_local_dcache_flush_end:
86
ret [],0
87
.size mn10300_local_dcache_flush,.-mn10300_local_dcache_flush
88
89
###############################################################################
90
#
91
# void mn10300_local_dcache_flush_page(unsigned long start)
92
# void mn10300_local_dcache_flush_range(unsigned long start, unsigned long end)
93
# void mn10300_local_dcache_flush_range2(unsigned long start, unsigned long size)
94
# Flush a range of addresses on a page in the dcache
95
#
96
###############################################################################
97
ALIGN
98
.globl mn10300_local_dcache_flush_page
99
.globl mn10300_local_dcache_flush_range
100
.globl mn10300_local_dcache_flush_range2
101
.type mn10300_local_dcache_flush_page,@function
102
.type mn10300_local_dcache_flush_range,@function
103
.type mn10300_local_dcache_flush_range2,@function
104
mn10300_local_dcache_flush_page:
105
and ~(PAGE_SIZE-1),d0
106
mov PAGE_SIZE,d1
107
mn10300_local_dcache_flush_range2:
108
add d0,d1
109
mn10300_local_dcache_flush_range:
110
movm [d2,d3,a2],(sp)
111
112
movhu (CHCTR),d2
113
btst CHCTR_DCEN,d2
114
beq mn10300_local_dcache_flush_range_end
115
116
# calculate alignsize
117
#
118
# alignsize = L1_CACHE_BYTES;
119
# for (i = (end - start - 1) / L1_CACHE_BYTES ; i > 0; i >>= 1)
120
# alignsize <<= 1;
121
# d2 = alignsize;
122
#
123
mov L1_CACHE_BYTES,d2
124
sub d0,d1,d3
125
add -1,d3
126
lsr L1_CACHE_SHIFT,d3
127
beq 2f
128
1:
129
add d2,d2
130
lsr 1,d3
131
bne 1b
132
2:
133
mov d1,a1 # a1 = end
134
135
LOCAL_CLI_SAVE(d3)
136
mov DCPGCR,a0
137
138
# wait for busy bit of area purge
139
setlb
140
mov (a0),d1
141
btst DCPGCR_DCPGBSY,d1
142
lne
143
144
# determine the mask
145
mov d2,d1
146
add -1,d1
147
not d1 # d1 = mask = ~(alignsize-1)
148
mov d1,(DCPGMR)
149
150
and d1,d0,a2 # a2 = mask & start
151
152
dcpgloop:
153
# area purge
154
mov a2,d0
155
or DCPGCR_DCP,d0
156
mov d0,(a0) # DCPGCR = (mask & start) | DCPGCR_DCP
157
158
# wait for busy bit of area purge
159
setlb
160
mov (a0),d1
161
btst DCPGCR_DCPGBSY,d1
162
lne
163
164
# check purge of end address
165
add d2,a2 # a2 += alignsize
166
cmp a1,a2 # if (a2 < end) goto dcpgloop
167
bns dcpgloop
168
169
LOCAL_IRQ_RESTORE(d3)
170
171
mn10300_local_dcache_flush_range_end:
172
ret [d2,d3,a2],12
173
174
.size mn10300_local_dcache_flush_page,.-mn10300_local_dcache_flush_page
175
.size mn10300_local_dcache_flush_range,.-mn10300_local_dcache_flush_range
176
.size mn10300_local_dcache_flush_range2,.-mn10300_local_dcache_flush_range2
177
178
###############################################################################
179
#
180
# void mn10300_local_dcache_flush_inv(void)
181
# Flush the entire data cache and invalidate all entries
182
#
183
###############################################################################
184
ALIGN
185
.globl mn10300_local_dcache_flush_inv
186
.type mn10300_local_dcache_flush_inv,@function
187
mn10300_local_dcache_flush_inv:
188
movhu (CHCTR),d0
189
btst CHCTR_DCEN,d0
190
beq mn10300_local_dcache_flush_inv_end
191
192
mov DCPGCR,a0
193
194
LOCAL_CLI_SAVE(d1)
195
196
# wait for busy bit of area purge & invalidate
197
setlb
198
mov (a0),d0
199
btst DCPGCR_DCPGBSY,d0
200
lne
201
202
# set the mask to cover everything
203
clr d0
204
mov d0,(DCPGMR)
205
206
# area purge & invalidate
207
mov DCPGCR_DCP|DCPGCR_DCI,d0
208
mov d0,(a0)
209
210
# wait for busy bit of area purge & invalidate
211
setlb
212
mov (a0),d0
213
btst DCPGCR_DCPGBSY,d0
214
lne
215
216
LOCAL_IRQ_RESTORE(d1)
217
218
mn10300_local_dcache_flush_inv_end:
219
ret [],0
220
.size mn10300_local_dcache_flush_inv,.-mn10300_local_dcache_flush_inv
221
222
###############################################################################
223
#
224
# void mn10300_local_dcache_flush_inv_page(unsigned long start)
225
# void mn10300_local_dcache_flush_inv_range(unsigned long start, unsigned long end)
226
# void mn10300_local_dcache_flush_inv_range2(unsigned long start, unsigned long size)
227
# Flush and invalidate a range of addresses on a page in the dcache
228
#
229
###############################################################################
230
ALIGN
231
.globl mn10300_local_dcache_flush_inv_page
232
.globl mn10300_local_dcache_flush_inv_range
233
.globl mn10300_local_dcache_flush_inv_range2
234
.type mn10300_local_dcache_flush_inv_page,@function
235
.type mn10300_local_dcache_flush_inv_range,@function
236
.type mn10300_local_dcache_flush_inv_range2,@function
237
mn10300_local_dcache_flush_inv_page:
238
and ~(PAGE_SIZE-1),d0
239
mov PAGE_SIZE,d1
240
mn10300_local_dcache_flush_inv_range2:
241
add d0,d1
242
mn10300_local_dcache_flush_inv_range:
243
movm [d2,d3,a2],(sp)
244
245
movhu (CHCTR),d2
246
btst CHCTR_DCEN,d2
247
beq mn10300_local_dcache_flush_inv_range_end
248
249
# calculate alignsize
250
#
251
# alignsize = L1_CACHE_BYTES;
252
# for (i = (end - start - 1) / L1_CACHE_BYTES; i > 0; i >>= 1)
253
# alignsize <<= 1;
254
# d2 = alignsize
255
#
256
mov L1_CACHE_BYTES,d2
257
sub d0,d1,d3
258
add -1,d3
259
lsr L1_CACHE_SHIFT,d3
260
beq 2f
261
1:
262
add d2,d2
263
lsr 1,d3
264
bne 1b
265
2:
266
mov d1,a1 # a1 = end
267
268
LOCAL_CLI_SAVE(d3)
269
mov DCPGCR,a0
270
271
# wait for busy bit of area purge & invalidate
272
setlb
273
mov (a0),d1
274
btst DCPGCR_DCPGBSY,d1
275
lne
276
277
# set the mask
278
mov d2,d1
279
add -1,d1
280
not d1 # d1 = mask = ~(alignsize-1)
281
mov d1,(DCPGMR)
282
283
and d1,d0,a2 # a2 = mask & start
284
285
dcpgivloop:
286
# area purge & invalidate
287
mov a2,d0
288
or DCPGCR_DCP|DCPGCR_DCI,d0
289
mov d0,(a0) # DCPGCR = (mask & start)|DCPGCR_DCP|DCPGCR_DCI
290
291
# wait for busy bit of area purge & invalidate
292
setlb
293
mov (a0),d1
294
btst DCPGCR_DCPGBSY,d1
295
lne
296
297
# check purge & invalidate of end address
298
add d2,a2 # a2 += alignsize
299
cmp a1,a2 # if (a2 < end) goto dcpgivloop
300
bns dcpgivloop
301
302
LOCAL_IRQ_RESTORE(d3)
303
304
mn10300_local_dcache_flush_inv_range_end:
305
ret [d2,d3,a2],12
306
.size mn10300_local_dcache_flush_inv_page,.-mn10300_local_dcache_flush_inv_page
307
.size mn10300_local_dcache_flush_inv_range,.-mn10300_local_dcache_flush_inv_range
308
.size mn10300_local_dcache_flush_inv_range2,.-mn10300_local_dcache_flush_inv_range2
309
310