blob: 30b887e67dd6776def5ef53238ebe3fead7a6bbd [file] [log] [blame]
Bryan Wu1394f032007-05-06 14:50:22 -07001/*
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
Robin Getz3bebca22007-10-10 23:55:26 +080036#ifdef CONFIG_BFIN_ICACHE_LOCK
Bryan Wu1394f032007-05-06 14:50:22 -070037
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
Mike Frysingere208f832007-07-25 10:11:42 +080046 P1.H = HI(IMEM_CONTROL);
47 P1.L = LO(IMEM_CONTROL);
48 P5.H = HI(ICPLB_ADDR0);
49 P5.L = LO(ICPLB_ADDR0);
50 P4.H = HI(ICPLB_DATA0);
51 P4.L = LO(ICPLB_DATA0);
Bryan Wu1394f032007-05-06 14:50:22 -070052 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;
Mike Frysinger51be24c2007-06-11 15:31:30 +0800158ENDPROC(_cache_grab_lock)
Bryan Wu1394f032007-05-06 14:50:22 -0700159
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
Mike Frysingere208f832007-07-25 10:11:42 +0800170 P1.H = HI(IMEM_CONTROL);
171 P1.L = LO(IMEM_CONTROL);
Bryan Wu1394f032007-05-06 14:50:22 -0700172
173 /* Disable the Interrupts*/
174 CLI R3;
175
176 R7 = [P1];
Mike Frysinger16428a42008-04-24 05:56:07 +0800177 R2 = ~(0x78) (X); /* mask out ILOC */
Bryan Wu1394f032007-05-06 14:50:22 -0700178 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;
Mike Frysinger51be24c2007-06-11 15:31:30 +0800190ENDPROC(_cache_lock)
Bryan Wu1394f032007-05-06 14:50:22 -0700191
Robin Getz3bebca22007-10-10 23:55:26 +0800192#endif /* BFIN_ICACHE_LOCK */
Bryan Wu1394f032007-05-06 14:50:22 -0700193
194/* Return the ILOC bits of IMEM_CONTROL
195 */
196
197ENTRY(_read_iloc)
Mike Frysingere208f832007-07-25 10:11:42 +0800198 P1.H = HI(IMEM_CONTROL);
199 P1.L = LO(IMEM_CONTROL);
Bryan Wu1394f032007-05-06 14:50:22 -0700200 R1 = 0xF;
201 R0 = [P1];
202 R0 = R0 >> 3;
203 R0 = R0 & R1;
204
205 RTS;
Mike Frysinger51be24c2007-06-11 15:31:30 +0800206ENDPROC(_read_iloc)