cache-flush-by-tag.S revision 518d4bb7464dd3c04aeb23874dc360b54058c01e
1/* MN10300 CPU core caching routines 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 18 .am33_2 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 27 28############################################################################### 29# 30# void mn10300_dcache_flush(void) 31# Flush the entire data cache back to RAM 32# 33############################################################################### 34 ALIGN 35mn10300_dcache_flush: 36 movhu (CHCTR),d0 37 btst CHCTR_DCEN,d0 38 beq mn10300_dcache_flush_end 39 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 46 47mn10300_dcache_flush_loop: 48 mov (a0),d0 49 and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0 50 or L1_CACHE_TAG_VALID,d0 # retain valid entries in the 51 # cache 52 mov d0,(a1) # conditional purge 53 54mn10300_dcache_flush_skip: 55 add L1_CACHE_BYTES,a0 56 add L1_CACHE_BYTES,a1 57 add -1,d1 58 bne mn10300_dcache_flush_loop 59 60mn10300_dcache_flush_end: 61 ret [],0 62 63############################################################################### 64# 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 69# 70############################################################################### 71 ALIGN 72mn10300_dcache_flush_page: 73 mov PAGE_SIZE,d1 74mn10300_dcache_flush_range2: 75 add d0,d1 76mn10300_dcache_flush_range: 77 movm [d2,d3],(sp) 78 79 movhu (CHCTR),d2 80 btst CHCTR_DCEN,d2 81 beq mn10300_dcache_flush_range_end 82 83 # round start addr down 84 and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0 85 mov d0,a1 86 87 add L1_CACHE_BYTES,d1 # round end addr up 88 and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d1 89 90 # write a request to flush all instances of an address from the cache 91 mov DCACHE_PURGE(0,0),a0 92 mov a1,d0 93 and L1_CACHE_TAG_ENTRY,d0 94 add d0,a0 # starting dcache purge control 95 # reg address 96 97 sub a1,d1 98 lsr L1_CACHE_SHIFT,d1 # total number of entries to 99 # examine 100 101 or L1_CACHE_TAG_VALID,a1 # retain valid entries in the 102 # cache 103 104mn10300_dcache_flush_range_loop: 105 mov a1,(L1_CACHE_WAYDISP*0,a0) # conditionally purge this line 106 # all ways 107 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 111 add -1,d1 112 bne mn10300_dcache_flush_range_loop 113 114mn10300_dcache_flush_range_end: 115 ret [d2,d3],8 116 117############################################################################### 118# 119# void mn10300_dcache_flush_inv(void) 120# Flush the entire data cache and invalidate all entries 121# 122############################################################################### 123 ALIGN 124mn10300_dcache_flush_inv: 125 movhu (CHCTR),d0 126 btst CHCTR_DCEN,d0 127 beq mn10300_dcache_flush_inv_end 128 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 132 133mn10300_dcache_flush_inv_loop: 134 mov (a1),d0 # unconditional purge 135 136 add L1_CACHE_BYTES,a1 137 add -1,d1 138 bne mn10300_dcache_flush_inv_loop 139 140mn10300_dcache_flush_inv_end: 141 ret [],0 142 143############################################################################### 144# 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 149# 150############################################################################### 151 ALIGN 152mn10300_dcache_flush_inv_page: 153 mov PAGE_SIZE,d1 154mn10300_dcache_flush_inv_range2: 155 add d0,d1 156mn10300_dcache_flush_inv_range: 157 movm [d2,d3],(sp) 158 movhu (CHCTR),d2 159 btst CHCTR_DCEN,d2 160 beq mn10300_dcache_flush_inv_range_end 161 162 and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0 # round start 163 # addr down 164 mov d0,a1 165 166 add L1_CACHE_BYTES,d1 # round end addr up 167 and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d1 168 169 # write a request to flush and invalidate all instances of an address 170 # from the cache 171 mov DCACHE_PURGE(0,0),a0 172 mov a1,d0 173 and L1_CACHE_TAG_ENTRY,d0 174 add d0,a0 # starting dcache purge control 175 # reg address 176 177 sub a1,d1 178 lsr L1_CACHE_SHIFT,d1 # total number of entries to 179 # examine 180 181mn10300_dcache_flush_inv_range_loop: 182 mov a1,(L1_CACHE_WAYDISP*0,a0) # conditionally purge this line 183 # in all ways 184 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 188 add -1,d1 189 bne mn10300_dcache_flush_inv_range_loop 190 191mn10300_dcache_flush_inv_range_end: 192 ret [d2,d3],8 193