1/*
2 *  linux/arch/arm/mm/arm925.S: MMU functions for ARM925
3 *
4 *  Copyright (C) 1999-2001 ARM Limited
5 *  Copyright (C) 2000 Deep Blue Solutions Ltd.
6 *  Copyright (C) 2002 RidgeRun, Inc.
7 *  Copyright (C) 2002 MontaVista Software, Inc.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22 *
23 *
24 * These are the low level assembler for performing cache and TLB
25 * functions on the arm925.
26 */
27#include <linux/linkage.h>
28#include <linux/config.h>
29#include <asm/assembler.h>
30#include <asm/constants.h>
31#include <asm/procinfo.h>
32#include <asm/hardware.h>
33
34
35/*
36 * This is the maximum size of an area which will be invalidated
37 * using the single invalidate entry instructions.  Anything larger
38 * than this, and we go for the whole cache.
39 *
40 * This value should be chosen such that we choose the cheapest
41 * alternative.
42 */
43#define MAX_AREA_SIZE	(2 * 1024)
44
45/*
46 * the cache line size of the I and D cache
47 */
48#define DCACHELINESIZE	16
49#define ICACHELINESIZE	16
50
51/*
52 * and the page size
53 */
54#define PAGESIZE	4096
55
56	.text
57
58/*
59 * cpu_arm925_data_abort()
60 *
61 * obtain information about current aborted instruction
62 * Note: we read user space.  This means we might cause a data
63 * abort here if the I-TLB and D-TLB aren't seeing the same
64 * picture.  Unfortunately, this does happen.  We live with it.
65 *
66 * Inputs:
67 *  r2 = address of abort
68 *  r3 = cpsr of abort
69 *
70 * Returns:
71 *  r0 = address of abort
72 *  r1 != 0 if writing
73 *  r3 = FSR
74 *  r4 = corrupted
75 */
76	.align	5
77ENTRY(cpu_arm925_data_abort)
78	mrc	p15, 0, r0, c6, c0, 0		@ get FAR
79	mrc	p15, 0, r4, c5, c0, 0		@ get FSR
80
81	tst	r3, #1<<5			@ Check for Thumb-bit (NE -> found)
82	ldrneh	r1, [r2]			@ Read aborted Thumb instruction
83	tstne	r1, r1, lsr #12 		@ C = bit 11
84
85	ldreq	r1, [r2]			@ Read aborted ARM instruction
86	tsteq	r1, r1, lsr #21 		@ C = bit 20
87
88	sbc	r1, r1, r1			@ r1 = C - 1
89	and	r3, r4, #255
90	mov	pc, lr
91
92/*
93 * cpu_arm925_check_bugs()
94 */
95ENTRY(cpu_arm925_check_bugs)
96	mrs	ip, cpsr
97	bic	ip, ip, #F_BIT
98	msr	cpsr, ip
99	mov	pc, lr
100
101/*
102 * cpu_arm925_proc_init()
103 */
104ENTRY(cpu_arm925_proc_init)
105	mov	pc, lr
106
107/*
108 * cpu_arm925_proc_fin()
109 */
110ENTRY(cpu_arm925_proc_fin)
111	stmfd	sp!, {lr}
112	mov	ip, #F_BIT | I_BIT | SVC_MODE
113	msr	cpsr_c, ip
114	bl	cpu_arm925_cache_clean_invalidate_all
115	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
116	bic	r0, r0, #0x1000			@ ...i............
117	bic	r0, r0, #0x000e			@ ............wca.
118	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
119	ldmfd	sp!, {pc}
120
121/*
122 * cpu_arm925_reset(loc)
123 *
124 * Perform a soft reset of the system.  Put the CPU into the
125 * same state as it would be if it had been reset, and branch
126 * to what would be the reset vector.
127 *
128 * loc: location to jump to for soft reset
129 */
130	.align	5
131ENTRY(cpu_arm925_reset)
132	mov	ip, #0
133	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I,D caches
134	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
135	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
136	mrc	p15, 0, ip, c1, c0, 0		@ ctrl register
137	bic	ip, ip, #0x000f			@ ............wcam
138	bic	ip, ip, #0x1100			@ ...i...s........
139	mcr	p15, 0, ip, c1, c0, 0		@ ctrl register
140	mov	pc, r0
141
142/*
143 * cpu_arm925_do_idle()
144 */
145	.align	5
146ENTRY(cpu_arm925_do_idle)
147#if defined(CONFIG_CPU_ARM925_CPU_IDLE)
148	mcr	p15, 0, r0, c7, c0, 4		@ Wait for interrupt
149#endif
150	mov	pc, lr
151
152/* ================================= CACHE ================================ */
153
154
155/*
156 * cpu_arm925_cache_clean_invalidate_all()
157 *
158 * clean and invalidate all cache lines
159 *
160 * Note:
161 *  1. we should preserve r0 at all times
162 */
163	.align	5
164ENTRY(cpu_arm925_cache_clean_invalidate_all)
165	mov	r2, #1
166cpu_arm925_cache_clean_invalidate_all_r2:
167	mov	ip, #0
168#ifdef CONFIG_CPU_ARM925_WRITETHROUGH
169	mcr	p15, 0, ip, c7, c6, 0		@ invalidate D cache
170#else
171/*
172 * 'Clean & Invalidate whole DCache'
173 * Re-written to use Index Ops.
174 * NOTE: Requires TI925T Configuration Register C bit <- 0
175 *       for clean and invalidate of both D-Cache sets.
176 */
177	mov	r3, #255 << 4		@ 256 entries/set
178					@ ((NSETS - 1) << (CIR[13-12] + 3))
1792:	mcr	p15, 0, r3, c7, c14, 2	@ clean & invalidate D index
180	subs	r3, r3, #1 << 4
181	bcs	2b			@ entries 255 to 0
182#endif
183	teq	r2, #0
184	mcrne	p15, 0, ip, c7, c5, 0		@ invalidate I cache
185	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
186	mov	pc, lr
187
188/*
189 * cpu_arm925_cache_clean_invalidate_range(start, end, flags)
190 *
191 * clean and invalidate all cache lines associated with this area of memory
192 *
193 * This is a little misleading, it is not intended to clean out
194 * the i-cache but to make sure that any data written to the
195 * range is made consistant.  This means that when we execute code
196 * in that region, everything works as we expect.
197 *
198 * This generally means writing back data in the Dcache and
199 * write buffer and flushing the Icache over that region
200 * start: Area start address
201 * end:   Area end address
202 * flags: nonzero for I cache as well
203 */
204		.align	5
205ENTRY(cpu_arm925_cache_clean_invalidate_range)
206	bic	r0, r0, #DCACHELINESIZE - 1	@ && added by PGM
207	bic	r1, r1, #DCACHELINESIZE - 1     @ && added by DHM
208	sub	r3, r1, r0
209	cmp	r3, #MAX_AREA_SIZE
210	bgt	cpu_arm925_cache_clean_invalidate_all_r2
2111:	teq	r2, #0
212#ifdef CONFIG_CPU_ARM925_WRITETHROUGH
213	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
214	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
215	add	r0, r0, #DCACHELINESIZE
216	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
217	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
218	add	r0, r0, #DCACHELINESIZE
219#else
220	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
221	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
222	add	r0, r0, #DCACHELINESIZE
223	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
224	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
225	add	r0, r0, #DCACHELINESIZE
226#endif
227	cmp	r0, r1
228	blt	1b
229
230	mcr	p15, 0, r1, c7, c10, 4		@ drain WB
231	mov	pc, lr
232
233/*
234 * cpu_arm925_flush_ram_page(page)
235 *
236 * clean and invalidate all cache lines associated with this area of memory
237 *
238 * page: page to clean and invalidate
239 */
240	.align	5
241ENTRY(cpu_arm925_flush_ram_page)
242	mov	r1, #PAGESIZE
243#ifdef CONFIG_CPU_ARM925_WRITETHROUGH
2441:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
245	add	r0, r0, #DCACHELINESIZE
246	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
247	add	r0, r0, #DCACHELINESIZE
248#else
2491:	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
250	add	r0, r0, #DCACHELINESIZE
251	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
252	add	r0, r0, #DCACHELINESIZE
253#endif
254	subs	r1, r1, #2 * DCACHELINESIZE
255	bne	1b
256	mcr	p15, 0, r1, c7, c10, 4		@ drain WB
257	mov	pc, lr
258
259/* ================================ D-CACHE =============================== */
260
261/*
262 * cpu_arm925_dcache_invalidate_range(start, end)
263 *
264 * throw away all D-cached data in specified region without an obligation
265 * to write them back.  Note however that we must clean the D-cached entries
266 * around the boundaries if the start and/or end address are not cache
267 * aligned.
268 *
269 * start: virtual start address
270 * end:   virtual end address
271 */
272	.align	5
273ENTRY(cpu_arm925_dcache_invalidate_range)
274#ifndef CONFIG_CPU_ARM925_WRITETHROUGH
275	tst	r0, #DCACHELINESIZE - 1
276	mcrne	p15, 0, r0, c7, c10, 1		@ clean D entry
277	tst	r1, #DCACHELINESIZE - 1
278	mcrne	p15, 0, r1, c7, c10, 1		@ clean D entry
279#endif
280	bic	r0, r0, #DCACHELINESIZE - 1
281	bic	r1, r1, #DCACHELINESIZE - 1
2821:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
283	add	r0, r0, #DCACHELINESIZE
284	cmp	r0, r1
285	blt	1b
286	mov	pc, lr
287
288/*
289 * cpu_arm925_dcache_clean_range(start, end)
290 *
291 * For the specified virtual address range, ensure that all caches contain
292 * clean data, such that peripheral accesses to the physical RAM fetch
293 * correct data.
294 *
295 * start: virtual start address
296 * end:   virtual end address
297 */
298	.align	5
299ENTRY(cpu_arm925_dcache_clean_range)
300#ifndef CONFIG_CPU_ARM925_WRITETHROUGH
301	bic	r0, r0, #DCACHELINESIZE - 1
302	sub	r1, r1, r0
303	cmp	r1, #MAX_AREA_SIZE
304	mov	r2, #0
305	bgt	cpu_arm925_cache_clean_invalidate_all_r2
306
307	bic	r1, r1, #DCACHELINESIZE -1
308	add	r1, r1, #DCACHELINESIZE
309
3101:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
311	add	r0, r0, #DCACHELINESIZE
312	subs	r1, r1, #DCACHELINESIZE
313	bpl	1b
314#endif
315	mcr	p15, 0, r2, c7, c10, 4		@ drain WB
316	mov	pc, lr
317
318/*
319 * cpu_arm925_dcache_clean_page(page)
320 *
321 * Cleans a single page of dcache so that if we have any future aliased
322 * mappings, they will be consistent at the time that they are created.
323 *
324 * page: virtual address of page to clean from dcache
325 *
326 * Note:
327 *  1. we don't need to flush the write buffer in this case.
328 *  2. we don't invalidate the entries since when we write the page
329 *     out to disk, the entries may get reloaded into the cache.
330 */
331	.align	5
332ENTRY(cpu_arm925_dcache_clean_page)
333#ifndef CONFIG_CPU_ARM925_WRITETHROUGH
334	mov	r1, #PAGESIZE
3351:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
336	add	r0, r0, #DCACHELINESIZE
337	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
338	add	r0, r0, #DCACHELINESIZE
339	subs	r1, r1, #2 * DCACHELINESIZE
340	bne	1b
341#endif
342	mov	pc, lr
343
344/*
345 * cpu_arm925_dcache_clean_entry(addr)
346 *
347 * Clean the specified entry of any caches such that the MMU
348 * translation fetches will obtain correct data.
349 *
350 * addr: cache-unaligned virtual address
351 */
352	.align	5
353ENTRY(cpu_arm925_dcache_clean_entry)
354#ifndef CONFIG_CPU_ARM925_WRITETHROUGH
355	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
356#endif
357	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
358	mov	pc, lr
359
360/* ================================ I-CACHE =============================== */
361
362/*
363 * cpu_arm925_icache_invalidate_range(start, end)
364 *
365 * invalidate a range of virtual addresses from the Icache
366 *
367 * This is a little misleading, it is not intended to clean out
368 * the i-cache but to make sure that any data written to the
369 * range is made consistant.  This means that when we execute code
370 * in that region, everything works as we expect.
371 *
372 * This generally means writing back data in the Dcache and
373 * write buffer and flushing the Icache over that region
374 *
375 * start: virtual start address
376 * end:   virtual end address
377 *
378 * NOTE: ICACHELINESIZE == DCACHELINESIZE (so we don't need to
379 * loop twice, once for i-cache, once for d-cache)
380 */
381	.align	5
382ENTRY(cpu_arm925_icache_invalidate_range)
383	bic	r0, r0, #ICACHELINESIZE - 1	@ Safety check
384	sub	r1, r1, r0
385	cmp	r1, #MAX_AREA_SIZE
386	bgt	cpu_arm925_cache_clean_invalidate_all_r2
387
388	bic	r1, r1, #ICACHELINESIZE - 1
389	add	r1, r1, #ICACHELINESIZE
390
3911:	mcr	p15, 0, r0, c7, c5, 1		@ Clean I entry
392	mcr	p15, 0, r0, c7, c10, 1		@ Clean D entry
393	add	r0, r0, #ICACHELINESIZE
394	subs	r1, r1, #ICACHELINESIZE
395	bne	1b
396
397	mov	r0, #0
398	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
399	mov	pc, lr
400
401
402ENTRY(cpu_arm925_icache_invalidate_page)
403	mcr	p15, 0, r0, c7, c5, 0		@ invalidate I cache
404        nop
405        nop
406        nop
407        nop
408	mov	pc, lr
409
410/* ================================== TLB ================================= */
411
412/*
413 * cpu_arm925_tlb_invalidate_all()
414 *
415 * Invalidate all TLB entries
416 */
417	.align	5
418ENTRY(cpu_arm925_tlb_invalidate_all)
419	mov	r0, #0
420	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
421	mcr	p15, 0, r0, c8, c7, 0		@ invalidate I & D TLBs
422	mov	pc, lr
423
424/*
425 * cpu_arm925_tlb_invalidate_range(start, end)
426 *
427 * invalidate TLB entries covering the specified range
428 *
429 * start: range start address
430 * end:   range end address
431 */
432	.align	5
433ENTRY(cpu_arm925_tlb_invalidate_range)
434	mov	r3, #0
435	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
436
437	mov	r3, #PAGESIZE
438	sub	r3, r3, #1
439	bic 	r0, r0, r3
440	bic	r1, r1, r3
441
4421:	mcr	p15, 0, r0, c8, c6, 1		@ invalidate D TLB entry
443	mcr	p15, 0, r0, c8, c5, 1		@ invalidate I TLB entry
444	add	r0, r0, #PAGESIZE
445	cmp	r0, r1
446	blt	1b
447	mov	pc, lr
448
449/*
450 * cpu_arm925_tlb_invalidate_page(page, flags)
451 *
452 * invalidate the TLB entries for the specified page.
453 *
454 * page:  page to invalidate
455 * flags: non-zero if we include the I TLB
456 */
457	.align	5
458ENTRY(cpu_arm925_tlb_invalidate_page)
459	mov	r3, #0
460	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
461	teq	r1, #0
462	mcr	p15, 0, r0, c8, c6, 1		@ invalidate D TLB entry
463	mcrne	p15, 0, r0, c8, c5, 1		@ invalidate I TLB entry
464	mov	pc, lr
465
466/* =============================== PageTable ============================== */
467
468/*
469 * cpu_arm925_set_pgd(pgd)
470 *
471 * Set the translation base pointer to be as described by pgd.
472 *
473 * pgd: new page tables
474 */
475	.align	5
476ENTRY(cpu_arm925_set_pgd)
477	mov	ip, #0
478#ifdef CONFIG_CPU_ARM925_WRITETHROUGH
479	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I & D cache
480#else
481/*
482 * 'Clean & Invalidate whole DCache'
483 * Re-written to use Index Ops.
484 * NOTE: Requires TI925T Configuration Register C bit <- 0
485 *       for clean and invalidate of both D-Cache sets.
486 */
487	mov	r3, #255 << 4		@ 256 entries/set
488					@ ((NSETS - 1) << (CIR[13-12] + 3))
4892:	mcr	p15, 0, r3, c7, c14, 2	@ clean & invalidate D index
490	subs	r3, r3, #1 << 4
491	bcs	2b			@ entries 255 to 0
492#endif
493	mcr	p15, 0, ip, c7, c5, 0		@ invalidate I cache
494	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
495	mcr	p15, 0, r0, c2, c0, 0		@ load page table pointer
496	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
497	mov	pc, lr
498
499/*
500 * cpu_arm925_set_pmd(pmdp, pmd)
501 *
502 * Set a level 1 translation table entry, and clean it out of
503 * any caches such that the MMUs can load it correctly.
504 *
505 * pmdp: pointer to PMD entry
506 * pmd:  PMD value to store
507 */
508	.align	5
509ENTRY(cpu_arm925_set_pmd)
510#ifdef CONFIG_CPU_ARM925_WRITETHROUGH
511	eor	r2, r1, #0x0a			@ C & Section
512	tst	r2, #0x0b
513	biceq	r1, r1, #4			@ clear bufferable bit
514#endif
515	str	r1, [r0]
516	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
517	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
518	mov	pc, lr
519
520/*
521 * cpu_arm925_set_pte(ptep, pte)
522 *
523 * Set a PTE and flush it out
524 */
525	.align	5
526ENTRY(cpu_arm925_set_pte)
527	str	r1, [r0], #-1024		@ linux version
528
529	eor	r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
530
531	bic	r2, r1, #0xff0
532	bic	r2, r2, #3
533	orr	r2, r2, #HPTE_TYPE_SMALL
534
535	tst	r1, #LPTE_USER | LPTE_EXEC	@ User or Exec?
536	orrne	r2, r2, #HPTE_AP_READ
537
538	tst	r1, #LPTE_WRITE | LPTE_DIRTY	@ Write and Dirty?
539	orreq	r2, r2, #HPTE_AP_WRITE
540
541	tst	r1, #LPTE_PRESENT | LPTE_YOUNG	@ Present and Young?
542	movne	r2, #0
543
544#ifdef CONFIG_CPU_ARM925_WRITETHROUGH
545	eor	r3, r2, #0x0a			@ C & small page?
546	tst	r3, #0x0b
547	biceq	r2, r2, #4
548#endif
549	str	r2, [r0]			@ hardware version
550	mov	r0, r0
551	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
552	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
553	mov	pc, lr
554
555
556ENTRY(cpu_arm925_name)
557	.ascii	"Arm925T"
558#if defined(CONFIG_CPU_ARM925_CPU_IDLE)
559	.ascii	"s"
560#endif
561#if defined(CONFIG_CPU_ARM925_I_CACHE_ON)
562	.ascii	"i"
563#endif
564#if defined(CONFIG_CPU_ARM925_D_CACHE_ON)
565	.ascii	"d"
566#if defined(CONFIG_CPU_ARM925_WRITETHROUGH)
567	.ascii	"(wt)"
568#else
569	.ascii	"(wb)"
570#endif
571#endif
572	.ascii	"\0"
573
574ENTRY(cpu_arm915_name)
575	.ascii	"Arm915T"
576#if defined(CONFIG_CPU_ARM925_CPU_IDLE)
577	.ascii	"s"
578#endif
579#if defined(CONFIG_CPU_ARM925_I_CACHE_ON)
580	.ascii	"i"
581#endif
582#if defined(CONFIG_CPU_ARM925_D_CACHE_ON)
583	.ascii	"d"
584#if defined(CONFIG_CPU_ARM925_WRITETHROUGH)
585	.ascii	"(wt)"
586#else
587	.ascii	"(wb)"
588#endif
589#endif
590	.ascii	"\0"
591	.align
592
593	.section ".text.init", #alloc, #execinstr
594
595__arm925_setup:
596	mov	r0, #0
597#if defined(CONFIG_CPU_ARM925_NON_STREAMING_ON)
598        orr     r0,r0,#0x80
599#endif
600#if defined(CONFIG_CPU_ARM925_TRANSPARENT_ON)
601        orr     r0,r0,#0x2
602#endif
603	mcr	p15, 0, r0, c15, c1, 0		@ write TI config register
604	mov	r0, #0
605	mcr	p15, 0, r0, c7, c7		@ invalidate I,D caches on v4
606	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer on v4
607	mcr	p15, 0, r0, c8, c7		@ invalidate I,D TLBs on v4
608	mcr	p15, 0, r4, c2, c0		@ load page table pointer
609	mov	r0, #0x1f			@ Domains 0, 1 = client
610	mcr	p15, 0, r0, c3, c0		@ load domain access register
611	mrc	p15, 0, r0, c1, c0		@ get control register v4
612/*
613 * Clear out 'unwanted' bits (then put them in if we need them)
614 */
615						@   VI ZFRS BLDP WCAM
616	bic	r0, r0, #0x0e00
617	bic	r0, r0, #0x0002
618	bic	r0, r0, #0x000c
619	bic	r0, r0, #0x1000			@ ...0 000. .... 000.
620/*
621 * Turn on what we want
622 */
623	orr	r0, r0, #0x0031
624	orr	r0, r0, #0x2100			@ ..1. ...1 ..11 ...1
625
626#ifdef CONFIG_CPU_ARM925_WRITEBUFFER_ON
627	orr	r0, r0, #0x0008			@ .... .... .... 1...
628#endif
629#ifdef CONFIG_CPU_ARM925_D_CACHE_ON
630	orr	r0, r0, #0x0004			@ .... .... .... .1..
631#endif
632#ifdef CONFIG_CPU_ARM925_I_CACHE_ON
633	orr	r0, r0, #0x1000			@ ...1 .... .... ....
634#endif
635	mov	pc, lr
636
637	.text
638
639/*
640 * Purpose : Function pointers used to access above functions - all calls
641 *	     come through these
642 */
643	.type	arm925_processor_functions, #object
644arm925_processor_functions:
645	.word	cpu_arm925_data_abort
646	.word	cpu_arm925_check_bugs
647	.word	cpu_arm925_proc_init
648	.word	cpu_arm925_proc_fin
649	.word	cpu_arm925_reset
650	.word   cpu_arm925_do_idle
651
652	/* cache */
653	.word	cpu_arm925_cache_clean_invalidate_all
654	.word	cpu_arm925_cache_clean_invalidate_range
655	.word	cpu_arm925_flush_ram_page
656
657	/* dcache */
658	.word	cpu_arm925_dcache_invalidate_range
659	.word	cpu_arm925_dcache_clean_range
660	.word	cpu_arm925_dcache_clean_page
661	.word	cpu_arm925_dcache_clean_entry
662
663	/* icache */
664	.word	cpu_arm925_icache_invalidate_range
665	.word	cpu_arm925_icache_invalidate_page
666
667	/* tlb */
668	.word	cpu_arm925_tlb_invalidate_all
669	.word	cpu_arm925_tlb_invalidate_range
670	.word	cpu_arm925_tlb_invalidate_page
671
672	/* pgtable */
673	.word	cpu_arm925_set_pgd
674	.word	cpu_arm925_set_pmd
675	.word	cpu_arm925_set_pte
676	.size	arm925_processor_functions, . - arm925_processor_functions
677
678	.type	cpu_arm925_info, #object
679cpu_arm925_info:
680	.long	0
681	.long	cpu_arm925_name
682	.size	cpu_arm925_info, . - cpu_arm925_info
683
684	.type	cpu_arm915_info, #object
685cpu_arm915_info:
686	.long	cpu_manu_name
687	.long	cpu_arm915_name
688	.size	cpu_arm915_info, . - cpu_arm915_info
689
690	.type	cpu_arch_name, #object
691cpu_arch_name:
692	.asciz	"armv4"
693	.size	cpu_arch_name, . - cpu_arch_name
694
695	.type	cpu_elf_name, #object
696cpu_elf_name:
697	.asciz	"v4"
698	.size	cpu_elf_name, . - cpu_elf_name
699	.align
700
701#if	defined(CONFIG_CPU_ARM925_WRITETHROUGH)
702#  define	MMU_FLAGS	0x00000c1a
703#else
704#  define	MMU_FLAGS	0x00000c1e
705#endif
706	.section ".proc.info", #alloc, #execinstr
707
708	.type	__arm925_proc_info,#object
709__arm925_proc_info:
710	.long	0x54029252
711	.long	0xffffffff
712	.long	MMU_FLAGS
713	b	__arm925_setup
714	.long	cpu_arch_name
715	.long	cpu_elf_name
716	.long	HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB
717	.long	cpu_arm925_info
718	.long	arm925_processor_functions
719	.size	__arm925_proc_info, . - __arm925_proc_info
720
721	.type	__arm915_proc_info,#object
722__arm915_proc_info:
723	.long	0x54029152
724	.long	0xffffffff
725	.long	MMU_FLAGS
726	b	__arm925_setup
727	.long	cpu_arch_name
728	.long	cpu_elf_name
729	.long	HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB
730	.long	cpu_arm915_info
731	.long	arm925_processor_functions
732	.size	__arm925_proc_info, . - __arm925_proc_info
733