1/* MN10300 CPU core caching routines, using direct tag flushing 2 * 3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. 4 * Written by David Howells (dhowells@redhat.com) 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 31mn10300_dcache_flush = mn10300_local_dcache_flush 32mn10300_dcache_flush_page = mn10300_local_dcache_flush_page 33mn10300_dcache_flush_range = mn10300_local_dcache_flush_range 34mn10300_dcache_flush_range2 = mn10300_local_dcache_flush_range2 35mn10300_dcache_flush_inv = mn10300_local_dcache_flush_inv 36mn10300_dcache_flush_inv_page = mn10300_local_dcache_flush_inv_page 37mn10300_dcache_flush_inv_range = mn10300_local_dcache_flush_inv_range 38mn10300_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 51mn10300_local_dcache_flush: 52 movhu (CHCTR),d0 53 btst CHCTR_DCEN,d0 54 beq mn10300_local_dcache_flush_end 55 56 # read the addresses tagged in the cache's tag RAM and attempt to flush 57 # those addresses specifically 58 # - we rely on the hardware to filter out invalid tag entry addresses 59 mov DCACHE_TAG(0,0),a0 # dcache tag RAM access address 60 mov DCACHE_PURGE(0,0),a1 # dcache purge request address 61 mov L1_CACHE_NWAYS*L1_CACHE_NENTRIES,d1 # total number of entries 62 63mn10300_local_dcache_flush_loop: 64 mov (a0),d0 65 and L1_CACHE_TAG_MASK,d0 66 or L1_CACHE_TAG_VALID,d0 # retain valid entries in the 67 # cache 68 mov d0,(a1) # conditional purge 69 70 add L1_CACHE_BYTES,a0 71 add L1_CACHE_BYTES,a1 72 add -1,d1 73 bne mn10300_local_dcache_flush_loop 74 75mn10300_local_dcache_flush_end: 76 ret [],0 77 .size mn10300_local_dcache_flush,.-mn10300_local_dcache_flush 78 79############################################################################### 80# 81# void mn10300_local_dcache_flush_page(unsigned long start) 82# void mn10300_local_dcache_flush_range(unsigned long start, unsigned long end) 83# void mn10300_local_dcache_flush_range2(unsigned long start, unsigned long size) 84# Flush a range of addresses on a page in the dcache 85# 86############################################################################### 87 ALIGN 88 .globl mn10300_local_dcache_flush_page 89 .globl mn10300_local_dcache_flush_range 90 .globl mn10300_local_dcache_flush_range2 91 .type mn10300_local_dcache_flush_page,@function 92 .type mn10300_local_dcache_flush_range,@function 93 .type mn10300_local_dcache_flush_range2,@function 94mn10300_local_dcache_flush_page: 95 and ~(PAGE_SIZE-1),d0 96 mov PAGE_SIZE,d1 97mn10300_local_dcache_flush_range2: 98 add d0,d1 99mn10300_local_dcache_flush_range: 100 movm [d2],(sp) 101 102 movhu (CHCTR),d2 103 btst CHCTR_DCEN,d2 104 beq mn10300_local_dcache_flush_range_end 105 106 sub d0,d1,a0 107 cmp MN10300_DCACHE_FLUSH_BORDER,a0 108 ble 1f 109 110 movm (sp),[d2] 111 bra mn10300_local_dcache_flush 1121: 113 114 # round start addr down 115 and L1_CACHE_TAG_MASK,d0 116 mov d0,a1 117 118 add L1_CACHE_BYTES,d1 # round end addr up 119 and L1_CACHE_TAG_MASK,d1 120 121 # write a request to flush all instances of an address from the cache 122 mov DCACHE_PURGE(0,0),a0 123 mov a1,d0 124 and L1_CACHE_TAG_ENTRY,d0 125 add d0,a0 # starting dcache purge control 126 # reg address 127 128 sub a1,d1 129 lsr L1_CACHE_SHIFT,d1 # total number of entries to 130 # examine 131 132 or L1_CACHE_TAG_VALID,a1 # retain valid entries in the 133 # cache 134 135mn10300_local_dcache_flush_range_loop: 136 mov a1,(L1_CACHE_WAYDISP*0,a0) # conditionally purge this line 137 # all ways 138 139 add L1_CACHE_BYTES,a0 140 add L1_CACHE_BYTES,a1 141 and ~L1_CACHE_WAYDISP,a0 # make sure way stay on way 0 142 add -1,d1 143 bne mn10300_local_dcache_flush_range_loop 144 145mn10300_local_dcache_flush_range_end: 146 ret [d2],4 147 148 .size mn10300_local_dcache_flush_page,.-mn10300_local_dcache_flush_page 149 .size mn10300_local_dcache_flush_range,.-mn10300_local_dcache_flush_range 150 .size mn10300_local_dcache_flush_range2,.-mn10300_local_dcache_flush_range2 151 152############################################################################### 153# 154# void mn10300_local_dcache_flush_inv(void) 155# Flush the entire data cache and invalidate all entries 156# 157############################################################################### 158 ALIGN 159 .globl mn10300_local_dcache_flush_inv 160 .type mn10300_local_dcache_flush_inv,@function 161mn10300_local_dcache_flush_inv: 162 movhu (CHCTR),d0 163 btst CHCTR_DCEN,d0 164 beq mn10300_local_dcache_flush_inv_end 165 166 mov L1_CACHE_NENTRIES,d1 167 clr a1 168 169mn10300_local_dcache_flush_inv_loop: 170 mov (DCACHE_PURGE_WAY0(0),a1),d0 # unconditional purge 171 mov (DCACHE_PURGE_WAY1(0),a1),d0 # unconditional purge 172 mov (DCACHE_PURGE_WAY2(0),a1),d0 # unconditional purge 173 mov (DCACHE_PURGE_WAY3(0),a1),d0 # unconditional purge 174 175 add L1_CACHE_BYTES,a1 176 add -1,d1 177 bne mn10300_local_dcache_flush_inv_loop 178 179mn10300_local_dcache_flush_inv_end: 180 ret [],0 181 .size mn10300_local_dcache_flush_inv,.-mn10300_local_dcache_flush_inv 182 183############################################################################### 184# 185# void mn10300_local_dcache_flush_inv_page(unsigned long start) 186# void mn10300_local_dcache_flush_inv_range(unsigned long start, unsigned long end) 187# void mn10300_local_dcache_flush_inv_range2(unsigned long start, unsigned long size) 188# Flush and invalidate a range of addresses on a page in the dcache 189# 190############################################################################### 191 ALIGN 192 .globl mn10300_local_dcache_flush_inv_page 193 .globl mn10300_local_dcache_flush_inv_range 194 .globl mn10300_local_dcache_flush_inv_range2 195 .type mn10300_local_dcache_flush_inv_page,@function 196 .type mn10300_local_dcache_flush_inv_range,@function 197 .type mn10300_local_dcache_flush_inv_range2,@function 198mn10300_local_dcache_flush_inv_page: 199 and ~(PAGE_SIZE-1),d0 200 mov PAGE_SIZE,d1 201mn10300_local_dcache_flush_inv_range2: 202 add d0,d1 203mn10300_local_dcache_flush_inv_range: 204 movm [d2],(sp) 205 206 movhu (CHCTR),d2 207 btst CHCTR_DCEN,d2 208 beq mn10300_local_dcache_flush_inv_range_end 209 210 sub d0,d1,a0 211 cmp MN10300_DCACHE_FLUSH_INV_BORDER,a0 212 ble 1f 213 214 movm (sp),[d2] 215 bra mn10300_local_dcache_flush_inv 2161: 217 218 and L1_CACHE_TAG_MASK,d0 # round start addr down 219 mov d0,a1 220 221 add L1_CACHE_BYTES,d1 # round end addr up 222 and L1_CACHE_TAG_MASK,d1 223 224 # write a request to flush and invalidate all instances of an address 225 # from the cache 226 mov DCACHE_PURGE(0,0),a0 227 mov a1,d0 228 and L1_CACHE_TAG_ENTRY,d0 229 add d0,a0 # starting dcache purge control 230 # reg address 231 232 sub a1,d1 233 lsr L1_CACHE_SHIFT,d1 # total number of entries to 234 # examine 235 236mn10300_local_dcache_flush_inv_range_loop: 237 mov a1,(L1_CACHE_WAYDISP*0,a0) # conditionally purge this line 238 # in all ways 239 240 add L1_CACHE_BYTES,a0 241 add L1_CACHE_BYTES,a1 242 and ~L1_CACHE_WAYDISP,a0 # make sure way stay on way 0 243 add -1,d1 244 bne mn10300_local_dcache_flush_inv_range_loop 245 246mn10300_local_dcache_flush_inv_range_end: 247 ret [d2],4 248 .size mn10300_local_dcache_flush_inv_page,.-mn10300_local_dcache_flush_inv_page 249 .size mn10300_local_dcache_flush_inv_range,.-mn10300_local_dcache_flush_inv_range 250 .size mn10300_local_dcache_flush_inv_range2,.-mn10300_local_dcache_flush_inv_range2 251