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/blackfin.h> 32 33.text 34 35/* When you come here, it is assumed that 36 * R0 - Which way to be locked 37 */ 38 39ENTRY(_cache_grab_lock) 40 41 [--SP]=( R7:0,P5:0 ); 42 43 P1.H = HI(IMEM_CONTROL); 44 P1.L = LO(IMEM_CONTROL); 45 P5.H = HI(ICPLB_ADDR0); 46 P5.L = LO(ICPLB_ADDR0); 47 P4.H = HI(ICPLB_DATA0); 48 P4.L = LO(ICPLB_DATA0); 49 R7 = R0; 50 51 /* If the code of interest already resides in the cache 52 * invalidate the entire cache itself. 53 * invalidate_entire_icache; 54 */ 55 56 SP += -12; 57 [--SP] = RETS; 58 CALL _invalidate_entire_icache; 59 RETS = [SP++]; 60 SP += 12; 61 62 /* Disable the Interrupts*/ 63 64 CLI R3; 65 66.LLOCK_WAY: 67 68 /* Way0 - 0xFFA133E0 69 * Way1 - 0xFFA137E0 70 * Way2 - 0xFFA13BE0 Total Way Size = 4K 71 * Way3 - 0xFFA13FE0 72 */ 73 74 /* Procedure Ex. -Set the locks for other ways by setting ILOC[3:1] 75 * Only Way0 of the instruction cache can now be 76 * replaced by a new code 77 */ 78 79 R5 = R7; 80 CC = BITTST(R7,0); 81 IF CC JUMP .LCLEAR1; 82 R7 = 0; 83 BITSET(R7,0); 84 JUMP .LDONE1; 85 86.LCLEAR1: 87 R7 = 0; 88 BITCLR(R7,0); 89.LDONE1: R4 = R7 << 3; 90 R7 = [P1]; 91 R7 = R7 | R4; 92 SSYNC; /* SSYNC required writing to IMEM_CONTROL. */ 93 .align 8; 94 [P1] = R7; 95 SSYNC; 96 97 R7 = R5; 98 CC = BITTST(R7,1); 99 IF CC JUMP .LCLEAR2; 100 R7 = 0; 101 BITSET(R7,1); 102 JUMP .LDONE2; 103 104.LCLEAR2: 105 R7 = 0; 106 BITCLR(R7,1); 107.LDONE2: R4 = R7 << 3; 108 R7 = [P1]; 109 R7 = R7 | R4; 110 SSYNC; /* SSYNC required writing to IMEM_CONTROL. */ 111 .align 8; 112 [P1] = R7; 113 SSYNC; 114 115 R7 = R5; 116 CC = BITTST(R7,2); 117 IF CC JUMP .LCLEAR3; 118 R7 = 0; 119 BITSET(R7,2); 120 JUMP .LDONE3; 121.LCLEAR3: 122 R7 = 0; 123 BITCLR(R7,2); 124.LDONE3: R4 = R7 << 3; 125 R7 = [P1]; 126 R7 = R7 | R4; 127 SSYNC; /* SSYNC required writing to IMEM_CONTROL. */ 128 .align 8; 129 [P1] = R7; 130 SSYNC; 131 132 133 R7 = R5; 134 CC = BITTST(R7,3); 135 IF CC JUMP .LCLEAR4; 136 R7 = 0; 137 BITSET(R7,3); 138 JUMP .LDONE4; 139.LCLEAR4: 140 R7 = 0; 141 BITCLR(R7,3); 142.LDONE4: R4 = R7 << 3; 143 R7 = [P1]; 144 R7 = R7 | R4; 145 SSYNC; /* SSYNC required writing to IMEM_CONTROL. */ 146 .align 8; 147 [P1] = R7; 148 SSYNC; 149 150 STI R3; 151 152 ( R7:0,P5:0 ) = [SP++]; 153 154 RTS; 155ENDPROC(_cache_grab_lock) 156 157/* After the execution of critical code, the code is now locked into 158 * the cache way. Now we need to set ILOC. 159 * 160 * R0 - Which way to be locked 161 */ 162 163ENTRY(_bfin_cache_lock) 164 165 [--SP]=( R7:0,P5:0 ); 166 167 P1.H = HI(IMEM_CONTROL); 168 P1.L = LO(IMEM_CONTROL); 169 170 /* Disable the Interrupts*/ 171 CLI R3; 172 173 R7 = [P1]; 174 R2 = ~(0x78) (X); /* mask out ILOC */ 175 R7 = R7 & R2; 176 R0 = R0 << 3; 177 R7 = R0 | R7; 178 SSYNC; /* SSYNC required writing to IMEM_CONTROL. */ 179 .align 8; 180 [P1] = R7; 181 SSYNC; 182 /* Renable the Interrupts */ 183 STI R3; 184 185 ( R7:0,P5:0 ) = [SP++]; 186 RTS; 187ENDPROC(_bfin_cache_lock) 188 189/* Invalidate the Entire Instruction cache by 190 * disabling IMC bit 191 */ 192ENTRY(_invalidate_entire_icache) 193 [--SP] = ( R7:5); 194 195 P0.L = LO(IMEM_CONTROL); 196 P0.H = HI(IMEM_CONTROL); 197 R7 = [P0]; 198 199 /* Clear the IMC bit , All valid bits in the instruction 200 * cache are set to the invalid state 201 */ 202 BITCLR(R7,IMC_P); 203 CLI R6; 204 SSYNC; /* SSYNC required before invalidating cache. */ 205 .align 8; 206 [P0] = R7; 207 SSYNC; 208 STI R6; 209 210 /* Configures the instruction cache agian */ 211 R6 = (IMC | ENICPLB); 212 R7 = R7 | R6; 213 214 CLI R6; 215 SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */ 216 .align 8; 217 [P0] = R7; 218 SSYNC; 219 STI R6; 220 221 ( R7:5) = [SP++]; 222 RTS; 223ENDPROC(_invalidate_entire_icache) 224