| 
									
										
										
										
											2011-03-18 16:54:30 +00:00
										 |  |  | /* MN10300 CPU cache invalidation routines, using automatic purge registers | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Copyright (C) 2011 Red Hat, Inc. All Rights Reserved. | 
					
						
							|  |  |  |  * Written by David Howells (dhowells@redhat.com)
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or
 | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public Licence | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version
 | 
					
						
							|  |  |  |  * 2 of the Licence, or (at your option) any later version. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | #include <linux/sys.h> | 
					
						
							|  |  |  | #include <linux/linkage.h> | 
					
						
							|  |  |  | #include <asm/smp.h> | 
					
						
							|  |  |  | #include <asm/page.h> | 
					
						
							|  |  |  | #include <asm/cache.h> | 
					
						
							|  |  |  | #include <asm/irqflags.h> | 
					
						
							|  |  |  | #include <asm/cacheflush.h> | 
					
						
							|  |  |  | #include "cache.inc" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	.am33_2 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ############################################################################### | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # void debugger_local_cache_flushinv(void) | 
					
						
							|  |  |  | # Flush the entire data cache back to RAM and invalidate the icache | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | ############################################################################### | 
					
						
							|  |  |  | 	ALIGN | 
					
						
							|  |  |  | 	.globl	debugger_local_cache_flushinv
 | 
					
						
							|  |  |  |         .type	debugger_local_cache_flushinv,@function
 | 
					
						
							|  |  |  | debugger_local_cache_flushinv: | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	# firstly flush the dcache | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	movhu	(CHCTR),d0 | 
					
						
							|  |  |  | 	btst	CHCTR_DCEN|CHCTR_ICEN,d0 | 
					
						
							|  |  |  | 	beq	debugger_local_cache_flushinv_end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mov	DCPGCR,a0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mov	epsw,d1 | 
					
						
							|  |  |  | 	and	~EPSW_IE,epsw | 
					
						
							|  |  |  | 	or	EPSW_NMID,epsw | 
					
						
							|  |  |  | 	nop | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	btst	CHCTR_DCEN,d0 | 
					
						
							|  |  |  | 	beq	debugger_local_cache_flushinv_no_dcache | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	# wait for busy bit of area purge | 
					
						
							|  |  |  | 	setlb | 
					
						
							|  |  |  | 	mov	(a0),d0 | 
					
						
							|  |  |  | 	btst	DCPGCR_DCPGBSY,d0 | 
					
						
							|  |  |  | 	lne | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	# set mask | 
					
						
							|  |  |  | 	clr	d0 | 
					
						
							|  |  |  | 	mov	d0,(DCPGMR) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	# area purge | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	# DCPGCR = DCPGCR_DCP | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	mov	DCPGCR_DCP,d0 | 
					
						
							|  |  |  | 	mov	d0,(a0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	# wait for busy bit of area purge | 
					
						
							|  |  |  | 	setlb | 
					
						
							|  |  |  | 	mov	(a0),d0 | 
					
						
							|  |  |  | 	btst	DCPGCR_DCPGBSY,d0 | 
					
						
							|  |  |  | 	lne | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | debugger_local_cache_flushinv_no_dcache: | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	# secondly, invalidate the icache if it is enabled | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	mov	CHCTR,a0 | 
					
						
							|  |  |  | 	movhu	(a0),d0 | 
					
						
							|  |  |  | 	btst	CHCTR_ICEN,d0 | 
					
						
							|  |  |  | 	beq	debugger_local_cache_flushinv_done | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	invalidate_icache 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | debugger_local_cache_flushinv_done: | 
					
						
							|  |  |  | 	mov	d1,epsw | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | debugger_local_cache_flushinv_end: | 
					
						
							|  |  |  | 	ret	[],0 | 
					
						
							|  |  |  | 	.size	debugger_local_cache_flushinv,.-debugger_local_cache_flushinv | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ############################################################################### | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # void debugger_local_cache_flushinv_one(u8 *addr) | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # Invalidate one particular cacheline if it's in the icache | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | ############################################################################### | 
					
						
							|  |  |  | 	ALIGN | 
					
						
							|  |  |  | 	.globl	debugger_local_cache_flushinv_one
 | 
					
						
							|  |  |  | 	.type	debugger_local_cache_flushinv_one,@function
 | 
					
						
							|  |  |  | debugger_local_cache_flushinv_one: | 
					
						
							|  |  |  | 	movhu	(CHCTR),d1 | 
					
						
							|  |  |  | 	btst	CHCTR_DCEN|CHCTR_ICEN,d1 | 
					
						
							|  |  |  | 	beq	debugger_local_cache_flushinv_one_end | 
					
						
							|  |  |  | 	btst	CHCTR_DCEN,d1 | 
					
						
							|  |  |  | 	beq	debugger_local_cache_flushinv_one_no_dcache | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	# round cacheline addr down | 
					
						
							|  |  |  | 	and	L1_CACHE_TAG_MASK,d0 | 
					
						
							|  |  |  | 	mov	d0,a1 | 
					
						
							|  |  |  | 	mov	d0,d1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	# determine the dcache purge control reg address | 
					
						
							|  |  |  | 	mov	DCACHE_PURGE(0,0),a0 | 
					
						
							|  |  |  | 	and	L1_CACHE_TAG_ENTRY,d0 | 
					
						
							|  |  |  | 	add	d0,a0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	# retain valid entries in the cache | 
					
						
							|  |  |  | 	or	L1_CACHE_TAG_VALID,d1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	# conditionally purge this line in all ways | 
					
						
							|  |  |  | 	mov	d1,(L1_CACHE_WAYDISP*0,a0) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-06-06 15:47:05 +01:00
										 |  |  | debugger_local_cache_flushinv_one_no_dcache: | 
					
						
							| 
									
										
										
										
											2011-03-18 16:54:30 +00:00
										 |  |  | 	# | 
					
						
							|  |  |  | 	# now try to flush the icache | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	mov	CHCTR,a0 | 
					
						
							|  |  |  | 	movhu	(a0),d0 | 
					
						
							|  |  |  | 	btst	CHCTR_ICEN,d0 | 
					
						
							| 
									
										
										
										
											2011-06-06 15:47:05 +01:00
										 |  |  | 	beq	debugger_local_cache_flushinv_one_end | 
					
						
							| 
									
										
										
										
											2011-03-18 16:54:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	LOCAL_CLI_SAVE(d1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mov	ICIVCR,a0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	# wait for the invalidator to quiesce | 
					
						
							|  |  |  | 	setlb | 
					
						
							|  |  |  | 	mov	(a0),d0 | 
					
						
							|  |  |  | 	btst	ICIVCR_ICIVBSY,d0 | 
					
						
							|  |  |  | 	lne | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	# set the mask | 
					
						
							|  |  |  | 	mov	L1_CACHE_TAG_MASK,d0 | 
					
						
							|  |  |  | 	mov	d0,(ICIVMR) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	# invalidate the cache line at the given address | 
					
						
							|  |  |  | 	or	ICIVCR_ICI,a1 | 
					
						
							|  |  |  | 	mov	a1,(a0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	# wait for the invalidator to quiesce again | 
					
						
							|  |  |  | 	setlb | 
					
						
							|  |  |  | 	mov	(a0),d0 | 
					
						
							|  |  |  | 	btst	ICIVCR_ICIVBSY,d0 | 
					
						
							|  |  |  | 	lne | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	LOCAL_IRQ_RESTORE(d1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | debugger_local_cache_flushinv_one_end: | 
					
						
							|  |  |  | 	ret	[],0 | 
					
						
							|  |  |  | 	.size	debugger_local_cache_flushinv_one,.-debugger_local_cache_flushinv_one |