blob: 665919f2ab62ef3e8f43c4466f6f72fdd69988e9 [file] [log] [blame]
David Howells7f386ac2011-03-18 16:54:30 +00001/* MN10300 CPU cache invalidation routines, using automatic purge registers
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###############################################################################
23#
24# void debugger_local_cache_flushinv(void)
25# Flush the entire data cache back to RAM and invalidate the icache
26#
27###############################################################################
28 ALIGN
29 .globl debugger_local_cache_flushinv
30 .type debugger_local_cache_flushinv,@function
31debugger_local_cache_flushinv:
32 #
33 # firstly flush the dcache
34 #
35 movhu (CHCTR),d0
36 btst CHCTR_DCEN|CHCTR_ICEN,d0
37 beq debugger_local_cache_flushinv_end
38
39 mov DCPGCR,a0
40
41 mov epsw,d1
42 and ~EPSW_IE,epsw
43 or EPSW_NMID,epsw
44 nop
45
46 btst CHCTR_DCEN,d0
47 beq debugger_local_cache_flushinv_no_dcache
48
49 # wait for busy bit of area purge
50 setlb
51 mov (a0),d0
52 btst DCPGCR_DCPGBSY,d0
53 lne
54
55 # set mask
56 clr d0
57 mov d0,(DCPGMR)
58
59 # area purge
60 #
61 # DCPGCR = DCPGCR_DCP
62 #
63 mov DCPGCR_DCP,d0
64 mov d0,(a0)
65
66 # wait for busy bit of area purge
67 setlb
68 mov (a0),d0
69 btst DCPGCR_DCPGBSY,d0
70 lne
71
72debugger_local_cache_flushinv_no_dcache:
73 #
74 # secondly, invalidate the icache if it is enabled
75 #
76 mov CHCTR,a0
77 movhu (a0),d0
78 btst CHCTR_ICEN,d0
79 beq debugger_local_cache_flushinv_done
80
81 invalidate_icache 0
82
83debugger_local_cache_flushinv_done:
84 mov d1,epsw
85
86debugger_local_cache_flushinv_end:
87 ret [],0
88 .size debugger_local_cache_flushinv,.-debugger_local_cache_flushinv
89
90###############################################################################
91#
92# void debugger_local_cache_flushinv_one(u8 *addr)
93#
94# Invalidate one particular cacheline if it's in the icache
95#
96###############################################################################
97 ALIGN
98 .globl debugger_local_cache_flushinv_one
99 .type debugger_local_cache_flushinv_one,@function
100debugger_local_cache_flushinv_one:
101 movhu (CHCTR),d1
102 btst CHCTR_DCEN|CHCTR_ICEN,d1
103 beq debugger_local_cache_flushinv_one_end
104 btst CHCTR_DCEN,d1
105 beq debugger_local_cache_flushinv_one_no_dcache
106
107 # round cacheline addr down
108 and L1_CACHE_TAG_MASK,d0
109 mov d0,a1
110 mov d0,d1
111
112 # determine the dcache purge control reg address
113 mov DCACHE_PURGE(0,0),a0
114 and L1_CACHE_TAG_ENTRY,d0
115 add d0,a0
116
117 # retain valid entries in the cache
118 or L1_CACHE_TAG_VALID,d1
119
120 # conditionally purge this line in all ways
121 mov d1,(L1_CACHE_WAYDISP*0,a0)
122
123debugger_local_cache_flushinv_no_dcache:
124 #
125 # now try to flush the icache
126 #
127 mov CHCTR,a0
128 movhu (a0),d0
129 btst CHCTR_ICEN,d0
130 beq mn10300_local_icache_inv_range_reg_end
131
132 LOCAL_CLI_SAVE(d1)
133
134 mov ICIVCR,a0
135
136 # wait for the invalidator to quiesce
137 setlb
138 mov (a0),d0
139 btst ICIVCR_ICIVBSY,d0
140 lne
141
142 # set the mask
143 mov L1_CACHE_TAG_MASK,d0
144 mov d0,(ICIVMR)
145
146 # invalidate the cache line at the given address
147 or ICIVCR_ICI,a1
148 mov a1,(a0)
149
150 # wait for the invalidator to quiesce again
151 setlb
152 mov (a0),d0
153 btst ICIVCR_ICIVBSY,d0
154 lne
155
156 LOCAL_IRQ_RESTORE(d1)
157
158debugger_local_cache_flushinv_one_end:
159 ret [],0
160 .size debugger_local_cache_flushinv_one,.-debugger_local_cache_flushinv_one