1/*
2 *  linux/arch/arm/mm/proc-sa110.S
3 *
4 *  Copyright (C) 1997-2000 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 *  MMU functions for SA110
11 *
12 *  These are the low level assembler for performing cache and TLB
13 *  functions on the StrongARM-110, StrongARM-1100 and StrongARM-1110.
14 *
15 *  Note that SA1100 and SA1110 share everything but their name and CPU ID.
16 *
17 *  12-jun-2000, Erik Mouw (J.A.K.Mouw@its.tudelft.nl):
18 *    Flush the read buffer at context switches
19 */
20#include <linux/linkage.h>
21#include <asm/assembler.h>
22#include <asm/constants.h>
23#include <asm/procinfo.h>
24#include <asm/hardware.h>
25
26/* This is the maximum size of an area which will be flushed.  If the area
27 * is larger than this, then we flush the whole cache
28 */
29#define MAX_AREA_SIZE	32768
30
31/*
32 * the cache line size of the I and D cache
33 */
34#define DCACHELINESIZE	32
35
36/*
37 * and the page size
38 */
39#define PAGESIZE	4096
40
41#define FLUSH_OFFSET	32768
42
43		.macro flush_110_dcache	rd, ra, re
44		add	\re, \ra, #16384		@ only necessary for 16k
451001:		ldr	\rd, [\ra], #DCACHELINESIZE
46		teq	\re, \ra
47		bne	1001b
48		.endm
49
50		.macro flush_1100_dcache	rd, ra, re
51		add	\re, \ra, #8192			@ only necessary for 8k
521001:		ldr	\rd, [\ra], #DCACHELINESIZE
53		teq	\re, \ra
54		bne	1001b
55#ifdef FLUSH_BASE_MINICACHE
56		add	\ra, \ra, #FLUSH_BASE_MINICACHE - FLUSH_BASE
57		add	\re, \ra, #512			@ only 512 bytes
581002:		ldr	\rd, [\ra], #DCACHELINESIZE
59		teq	\re, \ra
60		bne	1002b
61#endif
62		.endm
63
64		.data
65Lclean_switch:	.long	0
66		.text
67
68
69/*
70 * cpu_sa110_data_abort()
71 *
72 * obtain information about current aborted instruction.
73 * Note: we read user space.  This means we might cause a data
74 * abort here if the I-TLB and D-TLB aren't seeing the same
75 * picture.  Unfortunately, this does happen.  We live with it.
76 *
77 *  r2 = address of aborted instruction
78 *  r3 = cpsr
79 *
80 * Returns:
81 *  r0 = address of abort
82 *  r1 != 0 if writing
83 *  r3 = FSR
84 *  r4 = corrupted
85 */
86	.align	5
87ENTRY(cpu_sa110_data_abort)
88ENTRY(cpu_sa1100_data_abort)
89	mrc	p15, 0, r3, c5, c0, 0		@ get FSR
90	mrc	p15, 0, r0, c6, c0, 0		@ get FAR
91	ldr	r1, [r2]			@ read aborted instruction
92	and	r3, r3, #255
93	tst	r1, r1, lsr #21			@ C = bit 20
94	sbc	r1, r1, r1			@ r1 = C - 1
95	mov	pc, lr
96
97/*
98 * cpu_sa110_check_bugs()
99 */
100ENTRY(cpu_sa110_check_bugs)
101ENTRY(cpu_sa1100_check_bugs)
102	mrs	ip, cpsr
103	bic	ip, ip, #F_BIT
104	msr	cpsr, ip
105	mov	pc, lr
106
107/*
108 * cpu_sa110_proc_init()
109 */
110ENTRY(cpu_sa110_proc_init)
111ENTRY(cpu_sa1100_proc_init)
112	mov	r0, #0
113	mcr	p15, 0, r0, c15, c1, 2		@ Enable clock switching
114	mov	pc, lr
115
116/*
117 * cpu_sa110_proc_fin()
118 */
119ENTRY(cpu_sa110_proc_fin)
120	stmfd	sp!, {lr}
121	mov	ip, #F_BIT | I_BIT | SVC_MODE
122	msr	cpsr_c, ip
123	bl	cpu_sa110_cache_clean_invalidate_all	@ clean caches
1241:	mov	r0, #0
125	mcr	p15, 0, r0, c15, c2, 2		@ Disable clock switching
126	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
127	bic	r0, r0, #0x1000			@ ...i............
128	bic	r0, r0, #0x000e			@ ............wca.
129	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
130	ldmfd	sp!, {pc}
131
132ENTRY(cpu_sa1100_proc_fin)
133	stmfd	sp!, {lr}
134	mov	ip, #F_BIT | I_BIT | SVC_MODE
135	msr	cpsr_c, ip
136	bl	cpu_sa1100_cache_clean_invalidate_all	@ clean caches
137	b	1b
138
139/*
140 * cpu_sa110_reset(loc)
141 *
142 * Perform a soft reset of the system.  Put the CPU into the
143 * same state as it would be if it had been reset, and branch
144 * to what would be the reset vector.
145 *
146 * loc: location to jump to for soft reset
147 */
148	.align	5
149ENTRY(cpu_sa110_reset)
150ENTRY(cpu_sa1100_reset)
151	mov	ip, #0
152	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I,D caches
153	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
154	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
155	mrc	p15, 0, ip, c1, c0, 0		@ ctrl register
156	bic	ip, ip, #0x000f			@ ............wcam
157	bic	ip, ip, #0x1100			@ ...i...s........
158	mcr	p15, 0, ip, c1, c0, 0		@ ctrl register
159	mov	pc, r0
160
161/*
162 * cpu_sa110_do_idle(type)
163 *
164 * Cause the processor to idle
165 *
166 * type: call type:
167 *   0 = slow idle
168 *   1 = fast idle
169 *   2 = switch to slow processor clock
170 *   3 = switch to fast processor clock
171 */
172	.align	5
173idle:	mcr	p15, 0, r0, c15, c8, 2		@ Wait for interrupt, cache aligned
174	mov	r0, r0				@ safety
175	mov	pc, lr
176
177ENTRY(cpu_sa110_do_idle)
178	mov	ip, #0
179	cmp	r0, #4
180	addcc	pc, pc, r0, lsl #2
181	mov	pc, lr
182
183	b	idle
184	b	idle
185	b	slow_clock
186	b	fast_clock
187
188fast_clock:
189	mcr	p15, 0, ip, c15, c1, 2		@ enable clock switching
190	mov	pc, lr
191
192slow_clock:
193	mcr	p15, 0, ip, c15, c2, 2		@ disable clock switching
194	ldr	r1, =UNCACHEABLE_ADDR		@ load from uncacheable loc
195	ldr	r1, [r1, #0]			@ force switch to MCLK
196	mov	pc, lr
197
198	.align	5
199ENTRY(cpu_sa1100_do_idle)
200	mov	r0, r0				@ 4 nop padding
201	mov	r0, r0
202	mov	r0, r0
203	mov	r0, #0
204	ldr	r1, =UNCACHEABLE_ADDR		@ ptr to uncacheable address
205	mrs	r2, cpsr
206	orr	r3, r2, #192			@ disallow interrupts
207	msr	cpsr_c, r3
208	@ --- aligned to a cache line
209	mcr	p15, 0, r0, c15, c2, 2		@ disable clock switching
210	ldr	r1, [r1, #0]			@ force switch to MCLK
211	mcr	p15, 0, r0, c15, c8, 2		@ wait for interrupt
212	mov	r0, r0				@ safety
213	mcr	p15, 0, r0, c15, c1, 2		@ enable clock switching
214	msr	cpsr_c, r2			@ allow interrupts
215	mov	pc, lr
216
217/* ================================= CACHE ================================ */
218
219
220/*
221 * cpu_sa110_cache_clean_invalidate_all (void)
222 *
223 * clean and invalidate all cache lines
224 *
225 * Note:
226 *  1. we should preserve r0 at all times
227 */
228	.align	5
229ENTRY(cpu_sa110_cache_clean_invalidate_all)
230	mov	r2, #1
231cpu_sa110_cache_clean_invalidate_all_r2:
232	ldr	r3, =Lclean_switch
233	ldr	ip, =FLUSH_BASE
234	ldr	r1, [r3]
235	ands	r1, r1, #1
236	eor	r1, r1, #1
237	str	r1, [r3]
238	addne	ip, ip, #FLUSH_OFFSET
239	flush_110_dcache	r3, ip, r1
240	mov	ip, #0
241	teq	r2, #0
242	mcrne	p15, 0, ip, c7, c5, 0		@ invalidate I cache
243	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
244	mov	pc, lr
245
246	.align	5
247ENTRY(cpu_sa1100_cache_clean_invalidate_all)
248	mov	r2, #1
249cpu_sa1100_cache_clean_invalidate_all_r2:
250	ldr	r3, =Lclean_switch
251	ldr	ip, =FLUSH_BASE
252	ldr	r1, [r3]
253	ands	r1, r1, #1
254	eor	r1, r1, #1
255	str	r1, [r3]
256	addne	ip, ip, #FLUSH_OFFSET
257	flush_1100_dcache	r3, ip, r1
258	mov	ip, #0
259	teq	r2, #0
260	mcrne	p15, 0, ip, c7, c5, 0		@ invalidate I cache
261	mcr	p15, 0, r1, c9, c0, 0		@ invalidate RB
262	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
263	mov	pc, lr
264
265/*
266 * cpu_sa110_cache_clean_invalidate_range(start, end, flags)
267 *
268 * clean and invalidate all cache lines associated with this area of memory
269 *
270 * start: Area start address
271 * end:   Area end address
272 * flags: nonzero for I cache as well
273 */
274	.align	5
275ENTRY(cpu_sa110_cache_clean_invalidate_range)
276	bic	r0, r0, #DCACHELINESIZE - 1
277	sub	r3, r1, r0
278	cmp	r3, #MAX_AREA_SIZE
279	bhi	cpu_sa110_cache_clean_invalidate_all_r2
2801:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
281	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
282	add	r0, r0, #DCACHELINESIZE
283	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
284	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
285	add	r0, r0, #DCACHELINESIZE
286	cmp	r0, r1
287	blo	1b
288	teq	r2, #0
289	movne	r0, #0
290	mcrne	p15, 0, r0, c7, c5, 0		@ invalidate I cache
291	mov	pc, lr
292
293ENTRY(cpu_sa1100_cache_clean_invalidate_range)
294	sub	r3, r1, r0
295	cmp	r3, #MAX_AREA_SIZE
296	bhi	cpu_sa1100_cache_clean_invalidate_all_r2
297	b	1b
298
299/*
300 * cpu_sa110_flush_ram_page(page)
301 *
302 * clean and invalidate all cache lines associated with this area of memory
303 *
304 * page: page to clean and invalidate
305 */
306	.align	5
307ENTRY(cpu_sa110_flush_ram_page)
308ENTRY(cpu_sa1100_flush_ram_page)
309	mov	r1, #PAGESIZE
3101:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
311	add	r0, r0, #DCACHELINESIZE
312	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
313	add	r0, r0, #DCACHELINESIZE
314	subs	r1, r1, #2 * DCACHELINESIZE
315	bne	1b
316	mcr	p15, 0, r1, c7, c10, 4		@ drain WB
317	mov	pc, lr
318
319/* ================================ D-CACHE =============================== */
320
321/*
322 * cpu_sa110_dcache_invalidate_range(start, end)
323 *
324 * throw away all D-cached data in specified region without an obligation
325 * to write them back.  Note however that we must clean the D-cached entries
326 * around the boundaries if the start and/or end address are not cache
327 * aligned.
328 *
329 * start: virtual start address
330 * end:   virtual end address
331 */
332	.align	5
333ENTRY(cpu_sa110_dcache_invalidate_range)
334ENTRY(cpu_sa1100_dcache_invalidate_range)
335	tst	r0, #DCACHELINESIZE - 1
336	bic	r0, r0, #DCACHELINESIZE - 1
337	mcrne	p15, 0, r0, c7, c10, 1		@ clean D entry
338	tst	r1, #DCACHELINESIZE - 1
339	mcrne	p15, 0, r1, c7, c10, 1		@ clean D entry
3401:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
341	add	r0, r0, #DCACHELINESIZE
342	cmp	r0, r1
343	blo	1b
344	mov	pc, lr
345
346/*
347 * cpu_sa110_dcache_clean_range(start, end)
348 *
349 * For the specified virtual address range, ensure that all caches contain
350 * clean data, such that peripheral accesses to the physical RAM fetch
351 * correct data.
352 *
353 * start: virtual start address
354 * end:   virtual end address
355 */
356	.align	5
357ENTRY(cpu_sa110_dcache_clean_range)
358	bic	r0, r0, #DCACHELINESIZE - 1
359	sub	r1, r1, r0
360	cmp	r1, #MAX_AREA_SIZE
361	mov	r2, #0
362	bhi	cpu_sa110_cache_clean_invalidate_all_r2
3631:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
364	add	r0, r0, #DCACHELINESIZE
365	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
366	add	r0, r0, #DCACHELINESIZE
367	subs	r1, r1, #2 * DCACHELINESIZE
368	bpl	1b
369	mcr	p15, 0, r2, c7, c10, 4		@ drain WB
370	mov	pc, lr
371
372ENTRY(cpu_sa1100_dcache_clean_range)
373	bic	r0, r0, #DCACHELINESIZE - 1
374	sub	r1, r1, r0
375	cmp	r1, #MAX_AREA_SIZE
376	mov	r2, #0
377	bhi	cpu_sa1100_cache_clean_invalidate_all_r2
378	b	1b
379
380/*
381 * cpu_sa110_clean_dcache_page(page)
382 *
383 * Cleans a single page of dcache so that if we have any future aliased
384 * mappings, they will be consistent at the time that they are created.
385 *
386 * Note:
387 *  1. we don't need to flush the write buffer in this case.
388 *  2. we don't invalidate the entries since when we write the page
389 *     out to disk, the entries may get reloaded into the cache.
390 */
391	.align	5
392ENTRY(cpu_sa110_dcache_clean_page)
393ENTRY(cpu_sa1100_dcache_clean_page)
394	mov	r1, #PAGESIZE
3951:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
396	add	r0, r0, #DCACHELINESIZE
397	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
398	add	r0, r0, #DCACHELINESIZE
399	subs	r1, r1, #2 * DCACHELINESIZE
400	bne	1b
401	mov	pc, lr
402
403/*
404 * cpu_sa110_dcache_clean_entry(addr)
405 *
406 * Clean the specified entry of any caches such that the MMU
407 * translation fetches will obtain correct data.
408 *
409 * addr: cache-unaligned virtual address
410 */
411	.align	5
412ENTRY(cpu_sa110_dcache_clean_entry)
413ENTRY(cpu_sa1100_dcache_clean_entry)
414	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
415	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
416	mov	pc, lr
417
418/* ================================ I-CACHE =============================== */
419
420/*
421 * cpu_sa110_icache_invalidate_range(start, end)
422 *
423 * invalidate a range of virtual addresses from the Icache
424 *
425 * start: virtual start address
426 * end:   virtual end address
427 */
428	.align	5
429ENTRY(cpu_sa110_icache_invalidate_range)
430ENTRY(cpu_sa1100_icache_invalidate_range)
431	bic	r0, r0, #DCACHELINESIZE - 1
4321:	mcr	p15, 0, r0, c7, c10, 1		@ Clean D entry
433	add	r0, r0, #DCACHELINESIZE
434	cmp	r0, r1
435	blo	1b
436	mov	r0, #0
437	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
438ENTRY(cpu_sa110_icache_invalidate_page)
439ENTRY(cpu_sa1100_icache_invalidate_page)
440	mcr	p15, 0, r0, c7, c5, 0		@ invalidate I cache
441	mov	pc, lr
442
443/* ================================== TLB ================================= */
444
445/*
446 * cpu_sa110_tlb_invalidate_all()
447 *
448 * Invalidate all TLB entries
449 */
450	.align	5
451ENTRY(cpu_sa110_tlb_invalidate_all)
452ENTRY(cpu_sa1100_tlb_invalidate_all)
453	mov	r0, #0
454	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
455	mcr	p15, 0, r0, c8, c7, 0		@ invalidate I & D TLBs
456	mov	pc, lr
457
458/*
459 * cpu_sa110_tlb_invalidate_range(start, end)
460 *
461 * invalidate TLB entries covering the specified range
462 *
463 * start: range start address
464 * end:   range end address
465 */
466	.align	5
467ENTRY(cpu_sa110_tlb_invalidate_range)
468ENTRY(cpu_sa1100_tlb_invalidate_range)
469	bic	r0, r0, #0x0ff
470	bic	r0, r0, #0xf00
471	mov	r3, #0
472	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
4731:	mcr	p15, 0, r0, c8, c6, 1		@ invalidate D TLB entry
474	add	r0, r0, #PAGESIZE
475	cmp	r0, r1
476	blo	1b
477	mcr	p15, 0, r3, c8, c5, 0		@ invalidate I TLB
478	mov	pc, lr
479
480/*
481 * cpu_sa110_tlb_invalidate_page(page, flags)
482 *
483 * invalidate the TLB entries for the specified page.
484 *
485 * page:  page to invalidate
486 * flags: non-zero if we include the I TLB
487 */
488	.align	5
489ENTRY(cpu_sa110_tlb_invalidate_page)
490ENTRY(cpu_sa1100_tlb_invalidate_page)
491	mov	r3, #0
492	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
493	teq	r1, #0
494	mcr	p15, 0, r0, c8, c6, 1		@ invalidate D TLB entry
495	mcrne	p15, 0, r3, c8, c5, 0		@ invalidate I TLB
496	mov	pc, lr
497
498/* =============================== PageTable ============================== */
499
500/*
501 * cpu_sa110_set_pgd(pgd)
502 *
503 * Set the translation base pointer to be as described by pgd.
504 *
505 * pgd: new page tables
506 */
507	.align	5
508ENTRY(cpu_sa110_set_pgd)
509	ldr	r3, =Lclean_switch
510	ldr	ip, =FLUSH_BASE
511	ldr	r2, [r3]
512	ands	r2, r2, #1
513	eor	r2, r2, #1
514	str	r2, [r3]
515	addne	ip, ip, #FLUSH_OFFSET
516	flush_110_dcache	r3, ip, r1
517	mov	r1, #0
518	mcr	p15, 0, r1, c7, c5, 0		@ invalidate I cache
519	mcr	p15, 0, r1, c7, c10, 4		@ drain WB
520	mcr	p15, 0, r0, c2, c0, 0		@ load page table pointer
521	mcr	p15, 0, r1, c8, c7, 0		@ invalidate I & D TLBs
522	mov	pc, lr
523
524/*
525 * cpu_sa1100_set_pgd(pgd)
526 *
527 * Set the translation base pointer to be as described by pgd.
528 *
529 * pgd: new page tables
530 */
531	.align	5
532ENTRY(cpu_sa1100_set_pgd)
533	ldr	r3, =Lclean_switch
534	ldr	ip, =FLUSH_BASE
535	ldr	r2, [r3]
536	ands	r2, r2, #1
537	eor	r2, r2, #1
538	str	r2, [r3]
539	addne	ip, ip, #FLUSH_OFFSET
540	flush_1100_dcache	r3, ip, r1
541	mov	ip, #0
542	mcr	p15, 0, ip, c7, c5, 0		@ invalidate I cache
543	mcr	p15, 0, ip, c9, c0, 0		@ invalidate RB
544	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
545	mcr	p15, 0, r0, c2, c0, 0		@ load page table pointer
546	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
547	mov	pc, lr
548
549/*
550 * cpu_sa110_set_pmd(pmdp, pmd)
551 *
552 * Set a level 1 translation table entry, and clean it out of
553 * any caches such that the MMUs can load it correctly.
554 *
555 * pmdp: pointer to PMD entry
556 * pmd:  PMD value to store
557 */
558	.align	5
559ENTRY(cpu_sa110_set_pmd)
560ENTRY(cpu_sa1100_set_pmd)
561	str	r1, [r0]
562	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
563	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
564	mov	pc, lr
565
566/*
567 * cpu_sa110_set_pte(ptep, pte)
568 *
569 * Set a PTE and flush it out
570 */
571	.align	5
572ENTRY(cpu_sa110_set_pte)
573ENTRY(cpu_sa1100_set_pte)
574	str	r1, [r0], #-1024		@ linux version
575
576	eor	r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
577
578	bic	r2, r1, #0xff0
579	bic	r2, r2, #3
580	orr	r2, r2, #HPTE_TYPE_SMALL
581
582	tst	r1, #LPTE_USER | LPTE_EXEC	@ User or Exec?
583	orrne	r2, r2, #HPTE_AP_READ
584
585	tst	r1, #LPTE_WRITE | LPTE_DIRTY	@ Write and Dirty?
586	orreq	r2, r2, #HPTE_AP_WRITE
587
588	tst	r1, #LPTE_PRESENT | LPTE_YOUNG	@ Present and Young?
589	movne	r2, #0
590
591	str	r2, [r0]			@ hardware version
592	mov	r0, r0
593	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
594	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
595	mov	pc, lr
596
597
598cpu_manu_name:
599	.asciz	"Intel"
600cpu_sa110_name:
601	.asciz	"StrongARM-110"
602cpu_sa1100_name:
603	.asciz	"StrongARM-1100"
604cpu_sa1110_name:
605	.asciz	"StrongARM-1110"
606	.align
607
608	.section ".text.init", #alloc, #execinstr
609
610__sa1100_setup:	@ Allow read-buffer operations from userland
611	mcr	p15, 0, r0, c9, c0, 5
612	mrc	p15, 0, r0, c1, c0		@ get control register v4
613	bic	r0, r0, #0x0e00			@ ..VI ZFRS BLDP WCAM
614	bic	r0, r0, #0x0002			@ .... 000. .... ..0.
615	orr	r0, r0, #0x003d
616	orr	r0, r0, #0x3100			@ ..11 ...1 ..11 11.1
617	b	__setup_common
618
619__sa110_setup:
620	mrc	p15, 0, r0, c1, c0		@ get control register v4
621	bic	r0, r0, #0x2e00			@ ..VI ZFRS BLDP WCAM
622	bic	r0, r0, #0x0002			@ ..0. 000. .... ..0.
623	orr	r0, r0, #0x003d
624	orr	r0, r0, #0x1100			@ ...1 ...1 ..11 11.1
625__setup_common:
626	mov	r10, #0
627	mcr	p15, 0, r10, c7, c7		@ invalidate I,D caches on v4
628	mcr	p15, 0, r10, c7, c10, 4		@ drain write buffer on v4
629	mcr	p15, 0, r10, c8, c7		@ invalidate I,D TLBs on v4
630	mcr	p15, 0, r4, c2, c0		@ load page table pointer
631	mov	r10, #0x1f			@ Domains 0, 1 = client
632	mcr	p15, 0, r10, c3, c0		@ load domain access register
633	mov	pc, lr
634
635	.text
636
637/*
638 * Purpose : Function pointers used to access above functions - all calls
639 *	     come through these
640 */
641
642	.type	sa110_processor_functions, #object
643ENTRY(sa110_processor_functions)
644	.word	cpu_sa110_data_abort
645	.word	cpu_sa110_check_bugs
646	.word	cpu_sa110_proc_init
647	.word	cpu_sa110_proc_fin
648	.word	cpu_sa110_reset
649	.word	cpu_sa110_do_idle
650
651	/* cache */
652	.word	cpu_sa110_cache_clean_invalidate_all
653	.word	cpu_sa110_cache_clean_invalidate_range
654	.word	cpu_sa110_flush_ram_page
655
656	/* dcache */
657	.word	cpu_sa110_dcache_invalidate_range
658	.word	cpu_sa110_dcache_clean_range
659	.word	cpu_sa110_dcache_clean_page
660	.word	cpu_sa110_dcache_clean_entry
661
662	/* icache */
663	.word	cpu_sa110_icache_invalidate_range
664	.word	cpu_sa110_icache_invalidate_page
665
666	/* tlb */
667	.word	cpu_sa110_tlb_invalidate_all
668	.word	cpu_sa110_tlb_invalidate_range
669	.word	cpu_sa110_tlb_invalidate_page
670
671	/* pgtable */
672	.word	cpu_sa110_set_pgd
673	.word	cpu_sa110_set_pmd
674	.word	cpu_sa110_set_pte
675	.size	sa110_processor_functions, . - sa110_processor_functions
676
677	.type	cpu_sa110_info, #object
678cpu_sa110_info:
679	.long	cpu_manu_name
680	.long	cpu_sa110_name
681	.size	cpu_sa110_info, . - cpu_sa110_info
682
683
684/*
685 * SA1100 and SA1110 share the same function calls
686 */
687	.type	sa1100_processor_functions, #object
688ENTRY(sa1100_processor_functions)
689	.word	cpu_sa1100_data_abort
690	.word	cpu_sa1100_check_bugs
691	.word	cpu_sa1100_proc_init
692	.word	cpu_sa1100_proc_fin
693	.word	cpu_sa1100_reset
694	.word	cpu_sa1100_do_idle
695
696	/* cache */
697	.word	cpu_sa1100_cache_clean_invalidate_all
698	.word	cpu_sa1100_cache_clean_invalidate_range
699	.word	cpu_sa1100_flush_ram_page
700
701	/* dcache */
702	.word	cpu_sa1100_dcache_invalidate_range
703	.word	cpu_sa1100_dcache_clean_range
704	.word	cpu_sa1100_dcache_clean_page
705	.word	cpu_sa1100_dcache_clean_entry
706
707	/* icache */
708	.word	cpu_sa1100_icache_invalidate_range
709	.word	cpu_sa1100_icache_invalidate_page
710
711	/* tlb */
712	.word	cpu_sa1100_tlb_invalidate_all
713	.word	cpu_sa1100_tlb_invalidate_range
714	.word	cpu_sa1100_tlb_invalidate_page
715
716	/* pgtable */
717	.word	cpu_sa1100_set_pgd
718	.word	cpu_sa1100_set_pmd
719	.word	cpu_sa1100_set_pte
720	.size	sa1100_processor_functions, . - sa1100_processor_functions
721
722cpu_sa1100_info:
723	.long	cpu_manu_name
724	.long	cpu_sa1100_name
725	.size	cpu_sa1100_info, . - cpu_sa1100_info
726
727cpu_sa1110_info:
728	.long	cpu_manu_name
729	.long	cpu_sa1110_name
730	.size	cpu_sa1110_info, . - cpu_sa1110_info
731
732	.type	cpu_arch_name, #object
733cpu_arch_name:
734	.asciz	"armv4"
735	.size	cpu_arch_name, . - cpu_arch_name
736
737	.type	cpu_elf_name, #object
738cpu_elf_name:
739	.asciz	"v4"
740	.size	cpu_elf_name, . - cpu_elf_name
741	.align
742
743	.section ".proc.info", #alloc, #execinstr
744
745	.type	__sa110_proc_info,#object
746__sa110_proc_info:
747	.long	0x4401a100
748	.long	0xfffffff0
749	.long	0x00000c0e
750	b	__sa110_setup
751	.long	cpu_arch_name
752	.long	cpu_elf_name
753	.long	HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT | HWCAP_FAST_MULT
754	.long	cpu_sa110_info
755	.long	sa110_processor_functions
756	.size	__sa110_proc_info, . - __sa110_proc_info
757
758	.type	__sa1100_proc_info,#object
759__sa1100_proc_info:
760	.long	0x4401a110
761	.long	0xfffffff0
762	.long	0x00000c0e
763	b	__sa1100_setup
764	.long	cpu_arch_name
765	.long	cpu_elf_name
766	.long	HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT | HWCAP_FAST_MULT
767	.long	cpu_sa1100_info
768	.long	sa1100_processor_functions
769	.size	__sa1100_proc_info, . - __sa1100_proc_info
770
771	.type	__sa1110_proc_info,#object
772__sa1110_proc_info:
773	.long	0x6901b110
774	.long	0xfffffff0
775	.long	0x00000c0e
776	b	__sa1100_setup
777	.long	cpu_arch_name
778	.long	cpu_elf_name
779	.long	HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT | HWCAP_FAST_MULT
780	.long	cpu_sa1110_info
781	.long	sa1100_processor_functions
782	.size	__sa1110_proc_info, . - __sa1110_proc_info
783