diff options
Diffstat (limited to 'arch/mn10300/mm/cache-flush-by-tag.S')
-rw-r--r-- | arch/mn10300/mm/cache-flush-by-tag.S | 143 |
1 files changed, 101 insertions, 42 deletions
diff --git a/arch/mn10300/mm/cache-flush-by-tag.S b/arch/mn10300/mm/cache-flush-by-tag.S index 8fe90e49b96c..5cd6a27dd63e 100644 --- a/arch/mn10300/mm/cache-flush-by-tag.S +++ b/arch/mn10300/mm/cache-flush-by-tag.S @@ -1,4 +1,4 @@ -/* MN10300 CPU core caching routines +/* MN10300 CPU core caching routines, using direct tag flushing * * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. * Written by David Howells (dhowells@redhat.com) @@ -14,8 +14,11 @@ #include <asm/smp.h> #include <asm/page.h> #include <asm/cache.h> +#include <asm/irqflags.h> .am33_2 + +#ifndef CONFIG_SMP .globl mn10300_dcache_flush .globl mn10300_dcache_flush_page .globl mn10300_dcache_flush_range @@ -25,17 +28,30 @@ .globl mn10300_dcache_flush_inv_range .globl mn10300_dcache_flush_inv_range2 +mn10300_dcache_flush = mn10300_local_dcache_flush +mn10300_dcache_flush_page = mn10300_local_dcache_flush_page +mn10300_dcache_flush_range = mn10300_local_dcache_flush_range +mn10300_dcache_flush_range2 = mn10300_local_dcache_flush_range2 +mn10300_dcache_flush_inv = mn10300_local_dcache_flush_inv +mn10300_dcache_flush_inv_page = mn10300_local_dcache_flush_inv_page +mn10300_dcache_flush_inv_range = mn10300_local_dcache_flush_inv_range +mn10300_dcache_flush_inv_range2 = mn10300_local_dcache_flush_inv_range2 + +#endif /* !CONFIG_SMP */ + ############################################################################### # -# void mn10300_dcache_flush(void) +# void mn10300_local_dcache_flush(void) # Flush the entire data cache back to RAM # ############################################################################### ALIGN -mn10300_dcache_flush: + .globl mn10300_local_dcache_flush + .type mn10300_local_dcache_flush,@function +mn10300_local_dcache_flush: movhu (CHCTR),d0 btst CHCTR_DCEN,d0 - beq mn10300_dcache_flush_end + beq mn10300_local_dcache_flush_end # read the addresses tagged in the cache's tag RAM and attempt to flush # those addresses specifically @@ -44,41 +60,56 @@ mn10300_dcache_flush: mov DCACHE_PURGE(0,0),a1 # dcache purge request address mov L1_CACHE_NWAYS*L1_CACHE_NENTRIES,d1 # total number of entries -mn10300_dcache_flush_loop: +mn10300_local_dcache_flush_loop: mov (a0),d0 and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0 or L1_CACHE_TAG_VALID,d0 # retain valid entries in the # cache mov d0,(a1) # conditional purge -mn10300_dcache_flush_skip: add L1_CACHE_BYTES,a0 add L1_CACHE_BYTES,a1 add -1,d1 - bne mn10300_dcache_flush_loop + bne mn10300_local_dcache_flush_loop -mn10300_dcache_flush_end: +mn10300_local_dcache_flush_end: ret [],0 + .size mn10300_local_dcache_flush,.-mn10300_local_dcache_flush ############################################################################### # -# void mn10300_dcache_flush_page(unsigned long start) -# void mn10300_dcache_flush_range(unsigned long start, unsigned long end) -# void mn10300_dcache_flush_range2(unsigned long start, unsigned long size) +# void mn10300_local_dcache_flush_page(unsigned long start) +# void mn10300_local_dcache_flush_range(unsigned long start, unsigned long end) +# void mn10300_local_dcache_flush_range2(unsigned long start, unsigned long size) # Flush a range of addresses on a page in the dcache # ############################################################################### ALIGN -mn10300_dcache_flush_page: + .globl mn10300_local_dcache_flush_page + .globl mn10300_local_dcache_flush_range + .globl mn10300_local_dcache_flush_range2 + .type mn10300_local_dcache_flush_page,@function + .type mn10300_local_dcache_flush_range,@function + .type mn10300_local_dcache_flush_range2,@function +mn10300_local_dcache_flush_page: + and ~(PAGE_SIZE-1),d0 mov PAGE_SIZE,d1 -mn10300_dcache_flush_range2: +mn10300_local_dcache_flush_range2: add d0,d1 -mn10300_dcache_flush_range: - movm [d2,d3],(sp) +mn10300_local_dcache_flush_range: + movm [d2],(sp) movhu (CHCTR),d2 btst CHCTR_DCEN,d2 - beq mn10300_dcache_flush_range_end + beq mn10300_local_dcache_flush_range_end + + sub d0,d1,a0 + cmp MN10300_DCACHE_FLUSH_BORDER,a0 + ble 1f + + movm (sp),[d2] + bra mn10300_local_dcache_flush +1: # round start addr down and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0 @@ -101,7 +132,7 @@ mn10300_dcache_flush_range: or L1_CACHE_TAG_VALID,a1 # retain valid entries in the # cache -mn10300_dcache_flush_range_loop: +mn10300_local_dcache_flush_range_loop: mov a1,(L1_CACHE_WAYDISP*0,a0) # conditionally purge this line # all ways @@ -109,55 +140,80 @@ mn10300_dcache_flush_range_loop: add L1_CACHE_BYTES,a1 and ~L1_CACHE_WAYDISP,a0 # make sure way stay on way 0 add -1,d1 - bne mn10300_dcache_flush_range_loop + bne mn10300_local_dcache_flush_range_loop + +mn10300_local_dcache_flush_range_end: + ret [d2],4 -mn10300_dcache_flush_range_end: - ret [d2,d3],8 + .size mn10300_local_dcache_flush_page,.-mn10300_local_dcache_flush_page + .size mn10300_local_dcache_flush_range,.-mn10300_local_dcache_flush_range + .size mn10300_local_dcache_flush_range2,.-mn10300_local_dcache_flush_range2 ############################################################################### # -# void mn10300_dcache_flush_inv(void) +# void mn10300_local_dcache_flush_inv(void) # Flush the entire data cache and invalidate all entries # ############################################################################### ALIGN -mn10300_dcache_flush_inv: + .globl mn10300_local_dcache_flush_inv + .type mn10300_local_dcache_flush_inv,@function +mn10300_local_dcache_flush_inv: movhu (CHCTR),d0 btst CHCTR_DCEN,d0 - beq mn10300_dcache_flush_inv_end + beq mn10300_local_dcache_flush_inv_end - # hit each line in the dcache with an unconditional purge - mov DCACHE_PURGE(0,0),a1 # dcache purge request address - mov L1_CACHE_NWAYS*L1_CACHE_NENTRIES,d1 # total number of entries + mov L1_CACHE_NENTRIES,d1 + clr a1 -mn10300_dcache_flush_inv_loop: - mov (a1),d0 # unconditional purge +mn10300_local_dcache_flush_inv_loop: + mov (DCACHE_PURGE_WAY0(0),a1),d0 # unconditional purge + mov (DCACHE_PURGE_WAY1(0),a1),d0 # unconditional purge + mov (DCACHE_PURGE_WAY2(0),a1),d0 # unconditional purge + mov (DCACHE_PURGE_WAY3(0),a1),d0 # unconditional purge add L1_CACHE_BYTES,a1 add -1,d1 - bne mn10300_dcache_flush_inv_loop + bne mn10300_local_dcache_flush_inv_loop -mn10300_dcache_flush_inv_end: +mn10300_local_dcache_flush_inv_end: ret [],0 + .size mn10300_local_dcache_flush_inv,.-mn10300_local_dcache_flush_inv ############################################################################### # -# void mn10300_dcache_flush_inv_page(unsigned long start) -# void mn10300_dcache_flush_inv_range(unsigned long start, unsigned long end) -# void mn10300_dcache_flush_inv_range2(unsigned long start, unsigned long size) +# void mn10300_local_dcache_flush_inv_page(unsigned long start) +# void mn10300_local_dcache_flush_inv_range(unsigned long start, unsigned long end) +# void mn10300_local_dcache_flush_inv_range2(unsigned long start, unsigned long size) # Flush and invalidate a range of addresses on a page in the dcache # ############################################################################### ALIGN -mn10300_dcache_flush_inv_page: + .globl mn10300_local_dcache_flush_inv_page + .globl mn10300_local_dcache_flush_inv_range + .globl mn10300_local_dcache_flush_inv_range2 + .type mn10300_local_dcache_flush_inv_page,@function + .type mn10300_local_dcache_flush_inv_range,@function + .type mn10300_local_dcache_flush_inv_range2,@function +mn10300_local_dcache_flush_inv_page: + and ~(PAGE_SIZE-1),d0 mov PAGE_SIZE,d1 -mn10300_dcache_flush_inv_range2: +mn10300_local_dcache_flush_inv_range2: add d0,d1 -mn10300_dcache_flush_inv_range: - movm [d2,d3],(sp) +mn10300_local_dcache_flush_inv_range: + movm [d2],(sp) + movhu (CHCTR),d2 btst CHCTR_DCEN,d2 - beq mn10300_dcache_flush_inv_range_end + beq mn10300_local_dcache_flush_inv_range_end + + sub d0,d1,a0 + cmp MN10300_DCACHE_FLUSH_INV_BORDER,a0 + ble 1f + + movm (sp),[d2] + bra mn10300_local_dcache_flush_inv +1: and L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_ENTRY,d0 # round start # addr down @@ -178,7 +234,7 @@ mn10300_dcache_flush_inv_range: lsr L1_CACHE_SHIFT,d1 # total number of entries to # examine -mn10300_dcache_flush_inv_range_loop: +mn10300_local_dcache_flush_inv_range_loop: mov a1,(L1_CACHE_WAYDISP*0,a0) # conditionally purge this line # in all ways @@ -186,7 +242,10 @@ mn10300_dcache_flush_inv_range_loop: add L1_CACHE_BYTES,a1 and ~L1_CACHE_WAYDISP,a0 # make sure way stay on way 0 add -1,d1 - bne mn10300_dcache_flush_inv_range_loop + bne mn10300_local_dcache_flush_inv_range_loop -mn10300_dcache_flush_inv_range_end: - ret [d2,d3],8 +mn10300_local_dcache_flush_inv_range_end: + ret [d2],4 + .size mn10300_local_dcache_flush_inv_page,.-mn10300_local_dcache_flush_inv_page + .size mn10300_local_dcache_flush_inv_range,.-mn10300_local_dcache_flush_inv_range + .size mn10300_local_dcache_flush_inv_range2,.-mn10300_local_dcache_flush_inv_range2 |