1/* 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_one_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	debugger_local_cache_flushinv_one_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
161