1 /* MN10300 CPU core caching routines
3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
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.
12 #include <linux/sys.h>
13 #include <linux/linkage.h>
16 #include <asm/cache.h>
19 .globl mn10300_dcache_flush
20 .globl mn10300_dcache_flush_page
21 .globl mn10300_dcache_flush_range
22 .globl mn10300_dcache_flush_range2
23 .globl mn10300_dcache_flush_inv
24 .globl mn10300_dcache_flush_inv_page
25 .globl mn10300_dcache_flush_inv_range
26 .globl mn10300_dcache_flush_inv_range2
28 ###############################################################################
30 # void mn10300_dcache_flush(void)
31 # Flush the entire data cache back to RAM
33 ###############################################################################
38 beq mn10300_dcache_flush_end
40 # read the addresses tagged in the cache's tag RAM and attempt to flush
41 # those addresses specifically
42 # - we rely on the hardware to filter out invalid tag entry addresses
43 mov DCACHE_TAG(0,0),a0 # dcache tag RAM access address
44 mov DCACHE_PURGE(0,0),a1 # dcache purge request address
45 mov L1_CACHE_NWAYS*L1_CACHE_NENTRIES,d1 # total number of entries
47 mn10300_dcache_flush_loop:
49 and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0
50 or L1_CACHE_TAG_VALID,d0 # retain valid entries in the
52 mov d0,(a1) # conditional purge
54 mn10300_dcache_flush_skip:
58 bne mn10300_dcache_flush_loop
60 mn10300_dcache_flush_end:
63 ###############################################################################
65 # void mn10300_dcache_flush_page(unsigned start)
66 # void mn10300_dcache_flush_range(unsigned start, unsigned end)
67 # void mn10300_dcache_flush_range2(unsigned start, unsigned size)
68 # Flush a range of addresses on a page in the dcache
70 ###############################################################################
72 mn10300_dcache_flush_page:
74 mn10300_dcache_flush_range2:
76 mn10300_dcache_flush_range:
81 beq mn10300_dcache_flush_range_end
83 # round start addr down
84 and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0
87 add L1_CACHE_BYTES,d1 # round end addr up
88 and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d1
90 # write a request to flush all instances of an address from the cache
91 mov DCACHE_PURGE(0,0),a0
93 and L1_CACHE_TAG_ENTRY,d0
94 add d0,a0 # starting dcache purge control
98 lsr L1_CACHE_SHIFT,d1 # total number of entries to
101 or L1_CACHE_TAG_VALID,a1 # retain valid entries in the
104 mn10300_dcache_flush_range_loop:
105 mov a1,(L1_CACHE_WAYDISP*0,a0) # conditionally purge this line
108 add L1_CACHE_BYTES,a0
109 add L1_CACHE_BYTES,a1
110 and ~L1_CACHE_WAYDISP,a0 # make sure way stay on way 0
112 bne mn10300_dcache_flush_range_loop
114 mn10300_dcache_flush_range_end:
117 ###############################################################################
119 # void mn10300_dcache_flush_inv(void)
120 # Flush the entire data cache and invalidate all entries
122 ###############################################################################
124 mn10300_dcache_flush_inv:
127 beq mn10300_dcache_flush_inv_end
129 # hit each line in the dcache with an unconditional purge
130 mov DCACHE_PURGE(0,0),a1 # dcache purge request address
131 mov L1_CACHE_NWAYS*L1_CACHE_NENTRIES,d1 # total number of entries
133 mn10300_dcache_flush_inv_loop:
134 mov (a1),d0 # unconditional purge
136 add L1_CACHE_BYTES,a1
138 bne mn10300_dcache_flush_inv_loop
140 mn10300_dcache_flush_inv_end:
143 ###############################################################################
145 # void mn10300_dcache_flush_inv_page(unsigned start)
146 # void mn10300_dcache_flush_inv_range(unsigned start, unsigned end)
147 # void mn10300_dcache_flush_inv_range2(unsigned start, unsigned size)
148 # Flush and invalidate a range of addresses on a page in the dcache
150 ###############################################################################
152 mn10300_dcache_flush_inv_page:
154 mn10300_dcache_flush_inv_range2:
156 mn10300_dcache_flush_inv_range:
160 beq mn10300_dcache_flush_inv_range_end
162 and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0 # round start
166 add L1_CACHE_BYTES,d1 # round end addr up
167 and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d1
169 # write a request to flush and invalidate all instances of an address
171 mov DCACHE_PURGE(0,0),a0
173 and L1_CACHE_TAG_ENTRY,d0
174 add d0,a0 # starting dcache purge control
178 lsr L1_CACHE_SHIFT,d1 # total number of entries to
181 mn10300_dcache_flush_inv_range_loop:
182 mov a1,(L1_CACHE_WAYDISP*0,a0) # conditionally purge this line
185 add L1_CACHE_BYTES,a0
186 add L1_CACHE_BYTES,a1
187 and ~L1_CACHE_WAYDISP,a0 # make sure way stay on way 0
189 bne mn10300_dcache_flush_inv_range_loop
191 mn10300_dcache_flush_inv_range_end: