1/* MN10300 CPU cache invalidation routines, using direct tag flushing 2 * 3 * Copyright (C) 2011 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#include <linux/sys.h> 12#include <linux/linkage.h> 13#include <asm/smp.h> 14#include <asm/page.h> 15#include <asm/cache.h> 16#include <asm/irqflags.h> 17#include <asm/cacheflush.h> 18#include "cache.inc" 19 20 .am33_2 21 22 .globl debugger_local_cache_flushinv_one_icache 23 24############################################################################### 25# 26# void debugger_local_cache_flushinv_one(u8 *addr) 27# 28# Invalidate one particular cacheline if it's in the icache 29# 30############################################################################### 31 ALIGN 32 .globl debugger_local_cache_flushinv_one_icache 33 .type debugger_local_cache_flushinv_one_icache,@function 34debugger_local_cache_flushinv_one_icache: 35 movm [d3,a2],(sp) 36 37 mov CHCTR,a2 38 movhu (a2),d0 39 btst CHCTR_ICEN,d0 40 beq debugger_local_cache_flushinv_one_icache_end 41 42 mov d0,a1 43 and L1_CACHE_TAG_MASK,a1 44 45 # read the tags from the tag RAM, and if they indicate a matching valid 46 # cache line then we invalidate that line 47 mov ICACHE_TAG(0,0),a0 48 mov a1,d0 49 and L1_CACHE_TAG_ENTRY,d0 50 add d0,a0 # starting icache tag RAM 51 # access address 52 53 and ~(L1_CACHE_DISPARITY-1),a1 # determine comparator base 54 or L1_CACHE_TAG_VALID,a1 55 mov L1_CACHE_TAG_ADDRESS|L1_CACHE_TAG_VALID,d1 56 57 LOCAL_CLI_SAVE(d3) 58 59 # disable the icache 60 movhu (a2),d0 61 and ~CHCTR_ICEN,d0 62 movhu d0,(a2) 63 64 # and wait for it to calm down 65 setlb 66 movhu (a2),d0 67 btst CHCTR_ICBUSY,d0 68 lne 69 70 # check all the way tags for this cache entry 71 mov (a0),d0 # read the tag in the way 0 slot 72 xor a1,d0 73 and d1,d0 74 beq debugger_local_icache_kill # jump if matched 75 76 add L1_CACHE_WAYDISP,a0 77 mov (a0),d0 # read the tag in the way 1 slot 78 xor a1,d0 79 and d1,d0 80 beq debugger_local_icache_kill # jump if matched 81 82 add L1_CACHE_WAYDISP,a0 83 mov (a0),d0 # read the tag in the way 2 slot 84 xor a1,d0 85 and d1,d0 86 beq debugger_local_icache_kill # jump if matched 87 88 add L1_CACHE_WAYDISP,a0 89 mov (a0),d0 # read the tag in the way 3 slot 90 xor a1,d0 91 and d1,d0 92 bne debugger_local_icache_finish # jump if not matched 93 94debugger_local_icache_kill: 95 mov d0,(a0) # kill the tag (D0 is 0 at this point) 96 97debugger_local_icache_finish: 98 # wait for the cache to finish what it's doing 99 setlb 100 movhu (a2),d0 101 btst CHCTR_ICBUSY,d0 102 lne 103 104 # and reenable it 105 or CHCTR_ICEN,d0 106 movhu d0,(a2) 107 movhu (a2),d0 108 109 # re-enable interrupts 110 LOCAL_IRQ_RESTORE(d3) 111 112debugger_local_cache_flushinv_one_icache_end: 113 ret [d3,a2],8 114 .size debugger_local_cache_flushinv_one_icache,.-debugger_local_cache_flushinv_one_icache 115 116#ifdef CONFIG_MN10300_DEBUGGER_CACHE_INV_BY_TAG 117 .globl debugger_local_cache_flushinv_one 118 .type debugger_local_cache_flushinv_one,@function 119debugger_local_cache_flushinv_one = debugger_local_cache_flushinv_one_icache 120#endif 121