1/* 2 * File: arch/blackfin/mach-common/lock.S 3 * Based on: 4 * Author: LG Soft India 5 * 6 * Created: ? 7 * Description: kernel locks 8 * 9 * Modified: 10 * Copyright 2004-2006 Analog Devices Inc. 11 * 12 * Bugs: Enter bugs at http://blackfin.uclinux.org/ 13 * 14 * This program is free software; you can redistribute it and/or modify 15 * it under the terms of the GNU General Public License as published by 16 * the Free Software Foundation; either version 2 of the License, or 17 * (at your option) any later version. 18 * 19 * This program is distributed in the hope that it will be useful, 20 * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 * GNU General Public License for more details. 23 * 24 * You should have received a copy of the GNU General Public License 25 * along with this program; if not, see the file COPYING, or write 26 * to the Free Software Foundation, Inc., 27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 28 */ 29 30#include <linux/linkage.h> 31#include <asm/cplb.h> 32#include <asm/blackfin.h> 33 34.text 35 36#ifdef CONFIG_BLKFIN_CACHE_LOCK 37 38/* When you come here, it is assumed that 39 * R0 - Which way to be locked 40 */ 41 42ENTRY(_cache_grab_lock) 43 44 [--SP]=( R7:0,P5:0 ); 45 46 P1.H = (IMEM_CONTROL >> 16); 47 P1.L = (IMEM_CONTROL & 0xFFFF); 48 P5.H = (ICPLB_ADDR0 >> 16); 49 P5.L = (ICPLB_ADDR0 & 0xFFFF); 50 P4.H = (ICPLB_DATA0 >> 16); 51 P4.L = (ICPLB_DATA0 & 0xFFFF); 52 R7 = R0; 53 54 /* If the code of interest already resides in the cache 55 * invalidate the entire cache itself. 56 * invalidate_entire_icache; 57 */ 58 59 SP += -12; 60 [--SP] = RETS; 61 CALL _invalidate_entire_icache; 62 RETS = [SP++]; 63 SP += 12; 64 65 /* Disable the Interrupts*/ 66 67 CLI R3; 68 69.LLOCK_WAY: 70 71 /* Way0 - 0xFFA133E0 72 * Way1 - 0xFFA137E0 73 * Way2 - 0xFFA13BE0 Total Way Size = 4K 74 * Way3 - 0xFFA13FE0 75 */ 76 77 /* Procedure Ex. -Set the locks for other ways by setting ILOC[3:1] 78 * Only Way0 of the instruction cache can now be 79 * replaced by a new code 80 */ 81 82 R5 = R7; 83 CC = BITTST(R7,0); 84 IF CC JUMP .LCLEAR1; 85 R7 = 0; 86 BITSET(R7,0); 87 JUMP .LDONE1; 88 89.LCLEAR1: 90 R7 = 0; 91 BITCLR(R7,0); 92.LDONE1: R4 = R7 << 3; 93 R7 = [P1]; 94 R7 = R7 | R4; 95 SSYNC; /* SSYNC required writing to IMEM_CONTROL. */ 96 .align 8; 97 [P1] = R7; 98 SSYNC; 99 100 R7 = R5; 101 CC = BITTST(R7,1); 102 IF CC JUMP .LCLEAR2; 103 R7 = 0; 104 BITSET(R7,1); 105 JUMP .LDONE2; 106 107.LCLEAR2: 108 R7 = 0; 109 BITCLR(R7,1); 110.LDONE2: R4 = R7 << 3; 111 R7 = [P1]; 112 R7 = R7 | R4; 113 SSYNC; /* SSYNC required writing to IMEM_CONTROL. */ 114 .align 8; 115 [P1] = R7; 116 SSYNC; 117 118 R7 = R5; 119 CC = BITTST(R7,2); 120 IF CC JUMP .LCLEAR3; 121 R7 = 0; 122 BITSET(R7,2); 123 JUMP .LDONE3; 124.LCLEAR3: 125 R7 = 0; 126 BITCLR(R7,2); 127.LDONE3: R4 = R7 << 3; 128 R7 = [P1]; 129 R7 = R7 | R4; 130 SSYNC; /* SSYNC required writing to IMEM_CONTROL. */ 131 .align 8; 132 [P1] = R7; 133 SSYNC; 134 135 136 R7 = R5; 137 CC = BITTST(R7,3); 138 IF CC JUMP .LCLEAR4; 139 R7 = 0; 140 BITSET(R7,3); 141 JUMP .LDONE4; 142.LCLEAR4: 143 R7 = 0; 144 BITCLR(R7,3); 145.LDONE4: R4 = R7 << 3; 146 R7 = [P1]; 147 R7 = R7 | R4; 148 SSYNC; /* SSYNC required writing to IMEM_CONTROL. */ 149 .align 8; 150 [P1] = R7; 151 SSYNC; 152 153 STI R3; 154 155 ( R7:0,P5:0 ) = [SP++]; 156 157 RTS; 158ENDPROC(_cache_grab_lock) 159 160/* After the execution of critical code, the code is now locked into 161 * the cache way. Now we need to set ILOC. 162 * 163 * R0 - Which way to be locked 164 */ 165 166ENTRY(_cache_lock) 167 168 [--SP]=( R7:0,P5:0 ); 169 170 P1.H = (IMEM_CONTROL >> 16); 171 P1.L = (IMEM_CONTROL & 0xFFFF); 172 173 /* Disable the Interrupts*/ 174 CLI R3; 175 176 R7 = [P1]; 177 R2 = 0xFFFFFF87 (X); 178 R7 = R7 & R2; 179 R0 = R0 << 3; 180 R7 = R0 | R7; 181 SSYNC; /* SSYNC required writing to IMEM_CONTROL. */ 182 .align 8; 183 [P1] = R7; 184 SSYNC; 185 /* Renable the Interrupts */ 186 STI R3; 187 188 ( R7:0,P5:0 ) = [SP++]; 189 RTS; 190ENDPROC(_cache_lock) 191 192#endif /* BLKFIN_CACHE_LOCK */ 193 194/* Return the ILOC bits of IMEM_CONTROL 195 */ 196 197ENTRY(_read_iloc) 198 P1.H = (IMEM_CONTROL >> 16); 199 P1.L = (IMEM_CONTROL & 0xFFFF); 200 R1 = 0xF; 201 R0 = [P1]; 202 R0 = R0 >> 3; 203 R0 = R0 & R1; 204 205 RTS; 206ENDPROC(_read_iloc) 207