diff options
Diffstat (limited to 'cpu/blackfin/flush.S')
| -rw-r--r-- | cpu/blackfin/flush.S | 230 | 
1 files changed, 0 insertions, 230 deletions
| diff --git a/cpu/blackfin/flush.S b/cpu/blackfin/flush.S deleted file mode 100644 index 417f798f8..000000000 --- a/cpu/blackfin/flush.S +++ /dev/null @@ -1,230 +0,0 @@ -/* flush.S - low level cache flushing routines - * Copyright (C) 2003-2007 Analog Devices Inc. - * Licensed under the GPL-2 or later. - */ - -#include <config.h> -#include <asm/blackfin.h> -#include <asm/cplb.h> -#include <asm/mach-common/bits/mpu.h> - -.text - -/* This is an external function being called by the user - * application through __flush_cache_all. Currently this function - * serves the purpose of flushing all the pending writes in - * in the data cache. - */ - -ENTRY(_flush_data_cache) -	[--SP] = ( R7:6, P5:4 ); -	LINK 12; -	SP += -12; -	P5.H = HI(DCPLB_ADDR0); -	P5.L = LO(DCPLB_ADDR0); -	P4.H = HI(DCPLB_DATA0); -	P4.L = LO(DCPLB_DATA0); -	R7 = CPLB_VALID | CPLB_L1_CHBL | CPLB_DIRTY (Z); -	R6 = 16; -.Lnext:	R0 = [P5++]; -	R1 = [P4++]; -	CC = BITTST(R1, 14);	/* Is it write-through?*/ -	IF CC JUMP .Lskip;	/* If so, ignore it.*/ -	R2 = R1 & R7;		/* Is it a dirty, cached page?*/ -	CC = R2; -	IF !CC JUMP .Lskip;	/* If not, ignore it.*/ -	[--SP] = RETS; -	CALL _dcplb_flush;	/* R0 = page, R1 = data*/ -	RETS = [SP++]; -.Lskip:	R6 += -1; -	CC = R6; -	IF CC JUMP .Lnext; -	SSYNC; -	SP += 12; -	UNLINK; -	( R7:6, P5:4 ) = [SP++]; -	RTS; -ENDPROC(_flush_data_cache) - -/* This is an internal function to flush all pending - * writes in the cache associated with a particular DCPLB. - * - * R0 -  page's start address - * R1 -  CPLB's data field. - */ - -.align 2 -ENTRY(_dcplb_flush) -	[--SP] = ( R7:0, P5:0 ); -	[--SP] = LC0; -	[--SP] = LT0; -	[--SP] = LB0; -	[--SP] = LC1; -	[--SP] = LT1; -	[--SP] = LB1; - -	/* If it's a 1K or 4K page, then it's quickest to -	 * just systematically flush all the addresses in -	 * the page, regardless of whether they're in the -	 * cache, or dirty. If it's a 1M or 4M page, there -	 * are too many addresses, and we have to search the -	 * cache for lines corresponding to the page. -	 */ - -	CC = BITTST(R1, 17);	/* 1MB or 4MB */ -	IF !CC JUMP .Ldflush_whole_page; - -	/* We're only interested in the page's size, so extract -	 * this from the CPLB (bits 17:16), and scale to give an -	 * offset into the page_size and page_prefix tables. -	 */ - -	R1 <<= 14; -	R1 >>= 30; -	R1 <<= 2; - -	/* The page could be mapped into Bank A or Bank B, depending -	 * on (a) whether both banks are configured as cache, and -	 * (b) on whether address bit A[x] is set. x is determined -	 * by DCBS in DMEM_CONTROL -	 */ - -	R2 = 0;			/* Default to Bank A (Bank B would be 1)*/ - -	P0.L = LO(DMEM_CONTROL); -	P0.H = HI(DMEM_CONTROL); - -	R3 = [P0];		/* If Bank B is not enabled as cache*/ -	CC = BITTST(R3, 2);	/* then Bank A is our only option.*/ -	IF CC JUMP .Lbank_chosen; - -	R4 = 1<<14;		/* If DCBS==0, use A[14].*/ -	R5 = R4 << 7;		/* If DCBS==1, use A[23];*/ -	CC = BITTST(R3, 4); -	IF CC R4 = R5;		/* R4 now has either bit 14 or bit 23 set.*/ -	R5 = R0 & R4;		/* Use it to test the Page address*/ -	CC = R5;		/* and if that bit is set, we use Bank B,*/ -	R2 = CC;		/* else we use Bank A.*/ -	R2 <<= 23;		/* The Bank selection's at posn 23.*/ - -.Lbank_chosen: - -	/* We can also determine the sub-bank used, because this is -	 * taken from bits 13:12 of the address. -	 */ - -	R3 = ((12<<8)|2);		/* Extraction pattern */ -	nop;				/*Anamoly 05000209*/ -	R4 = EXTRACT(R0, R3.L) (Z);	/* Extract bits*/ -	/* Save in extraction pattern for later deposit.*/ -	R3.H = R4.L << 0; - -	/* So: -	 * R0 = Page start -	 * R1 = Page length (actually, offset into size/prefix tables) -	 * R2 = Bank select mask -	 * R3 = sub-bank deposit values -	 * -	 * The cache has 2 Ways, and 64 sets, so we iterate through -	 * the sets, accessing the tag for each Way, for our Bank and -	 * sub-bank, looking for dirty, valid tags that match our -	 * address prefix. -	 */ - -	P5.L = LO(DTEST_COMMAND); -	P5.H = HI(DTEST_COMMAND); -	P4.L = LO(DTEST_DATA0); -	P4.H = HI(DTEST_DATA0); - -	P0.L = page_prefix_table; -	P0.H = page_prefix_table; -	P1 = R1; -	R5 = 0;			/* Set counter*/ -	P0 = P1 + P0; -	R4 = [P0];		/* This is the address prefix*/ - - -	/* We're reading (bit 1==0) the tag (bit 2==0), and we -	 * don't care about which double-word, since we're only -	 * fetching tags, so we only have to set Set, Bank, -	 * Sub-bank and Way. -	 */ - -	P2 = 2; -	LSETUP (.Lfs1, .Lfe1) LC1 = P2; -.Lfs1:	P0 = 64;		/* iterate over all sets*/ -	LSETUP (.Lfs0, .Lfe0) LC0 = P0; -.Lfs0:	R6 = R5 << 5;		/* Combine set*/ -	R6.H = R3.H << 0 ;	/* and sub-bank*/ -	R6 = R6 | R2;		/* and Bank. Leave Way==0 at first.*/ -	BITSET(R6,14); -	[P5] = R6;		/* Issue Command*/ -	SSYNC; -	R7 = [P4];		/* and read Tag.*/ -	CC = BITTST(R7, 0);	/* Check if valid*/ -	IF !CC JUMP .Lfskip;	/* and skip if not.*/ -	CC = BITTST(R7, 1);	/* Check if dirty*/ -	IF !CC JUMP .Lfskip;	/* and skip if not.*/ - -	/* Compare against the page address. First, plant bits 13:12 -	 * into the tag, since those aren't part of the returned data. -	 */ - -	R7 = DEPOSIT(R7, R3);	/* set 13:12*/ -	R1 = R7 & R4;		/* Mask off lower bits*/ -	CC = R1 == R0;		/* Compare against page start.*/ -	IF !CC JUMP .Lfskip;	/* Skip it if it doesn't match.*/ - -	/* Tag address matches against page, so this is an entry -	 * we must flush. -	 */ - -	R7 >>= 10;		/* Mask off the non-address bits*/ -	R7 <<= 10; -	P3 = R7; -	SSYNC; -	FLUSHINV [P3];		/* And flush the entry*/ -.Lfskip: -.Lfe0:	R5 += 1;		/* Advance to next Set*/ -.Lfe1:	BITSET(R2, 26);		/* Go to next Way.*/ - -.Ldfinished: -	SSYNC;			/* Ensure the data gets out to mem.*/ - -	/*Finished. Restore context.*/ -	LB1 = [SP++]; -	LT1 = [SP++]; -	LC1 = [SP++]; -	LB0 = [SP++]; -	LT0 = [SP++]; -	LC0 = [SP++]; -	( R7:0, P5:0 ) = [SP++]; -	RTS; - -.Ldflush_whole_page: - -	/* It's a 1K or 4K page, so quicker to just flush the -	 * entire page. -	 */ - -	P1 = 32;		/* For 1K pages*/ -	P2 = P1 << 2;		/* For 4K pages*/ -	P0 = R0;		/* Start of page*/ -	CC = BITTST(R1, 16);	/* Whether 1K or 4K*/ -	IF CC P1 = P2; -	P1 += -1;		/* Unroll one iteration*/ -	SSYNC; -	FLUSHINV [P0++];	/* because CSYNC can't end loops.*/ -	LSETUP (.Leall, .Leall) LC0 = P1; -.Leall:	FLUSHINV [P0++]; -	SSYNC; -	JUMP .Ldfinished; -ENDPROC(_dcplb_flush) - -.align 4; -page_prefix_table: -.byte4	0xFFFFFC00;	/* 1K */ -.byte4	0xFFFFF000;	/* 4K */ -.byte4	0xFFF00000;	/* 1M */ -.byte4	0xFFC00000;	/* 4M */ -.page_prefix_table.end: |