• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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