xref: /linux/arch/arm/boot/compressed/head.S (revision c537b994505099b7197e7d3125b942ecbcc51eb6)
1/*
2 *  linux/arch/arm/boot/compressed/head.S
3 *
4 *  Copyright (C) 1996-2002 Russell King
5 *  Copyright (C) 2004 Hyok S. Choi (MPU support)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/linkage.h>
12
13/*
14 * Debugging stuff
15 *
16 * Note that these macros must not contain any code which is not
17 * 100% relocatable.  Any attempt to do so will result in a crash.
18 * Please select one of the following when turning on debugging.
19 */
20#ifdef DEBUG
21
22#if defined(CONFIG_DEBUG_ICEDCC)
23
24#ifdef CONFIG_CPU_V6
25		.macro	loadsp, rb
26		.endm
27		.macro	writeb, ch, rb
28		mcr	p14, 0, \ch, c0, c5, 0
29		.endm
30#else
31		.macro	loadsp, rb
32		.endm
33		.macro	writeb, ch, rb
34		mcr	p14, 0, \ch, c0, c1, 0
35		.endm
36#endif
37
38#else
39
40#include <asm/arch/debug-macro.S>
41
42		.macro	writeb,	ch, rb
43		senduart \ch, \rb
44		.endm
45
46#if defined(CONFIG_ARCH_SA1100)
47		.macro	loadsp, rb
48		mov	\rb, #0x80000000	@ physical base address
49#ifdef CONFIG_DEBUG_LL_SER3
50		add	\rb, \rb, #0x00050000	@ Ser3
51#else
52		add	\rb, \rb, #0x00010000	@ Ser1
53#endif
54		.endm
55#elif defined(CONFIG_ARCH_S3C2410)
56		.macro loadsp, rb
57		mov	\rb, #0x50000000
58		add	\rb, \rb, #0x4000 * CONFIG_S3C2410_LOWLEVEL_UART_PORT
59		.endm
60#else
61		.macro	loadsp,	rb
62		addruart \rb
63		.endm
64#endif
65#endif
66#endif
67
68		.macro	kputc,val
69		mov	r0, \val
70		bl	putc
71		.endm
72
73		.macro	kphex,val,len
74		mov	r0, \val
75		mov	r1, #\len
76		bl	phex
77		.endm
78
79		.macro	debug_reloc_start
80#ifdef DEBUG
81		kputc	#'\n'
82		kphex	r6, 8		/* processor id */
83		kputc	#':'
84		kphex	r7, 8		/* architecture id */
85#ifdef CONFIG_CPU_CP15
86		kputc	#':'
87		mrc	p15, 0, r0, c1, c0
88		kphex	r0, 8		/* control reg */
89#endif
90		kputc	#'\n'
91		kphex	r5, 8		/* decompressed kernel start */
92		kputc	#'-'
93		kphex	r9, 8		/* decompressed kernel end  */
94		kputc	#'>'
95		kphex	r4, 8		/* kernel execution address */
96		kputc	#'\n'
97#endif
98		.endm
99
100		.macro	debug_reloc_end
101#ifdef DEBUG
102		kphex	r5, 8		/* end of kernel */
103		kputc	#'\n'
104		mov	r0, r4
105		bl	memdump		/* dump 256 bytes at start of kernel */
106#endif
107		.endm
108
109		.section ".start", #alloc, #execinstr
110/*
111 * sort out different calling conventions
112 */
113		.align
114start:
115		.type	start,#function
116		.rept	8
117		mov	r0, r0
118		.endr
119
120		b	1f
121		.word	0x016f2818		@ Magic numbers to help the loader
122		.word	start			@ absolute load/run zImage address
123		.word	_edata			@ zImage end address
1241:		mov	r7, r1			@ save architecture ID
125		mov	r8, r2			@ save atags pointer
126
127#ifndef __ARM_ARCH_2__
128		/*
129		 * Booting from Angel - need to enter SVC mode and disable
130		 * FIQs/IRQs (numeric definitions from angel arm.h source).
131		 * We only do this if we were in user mode on entry.
132		 */
133		mrs	r2, cpsr		@ get current mode
134		tst	r2, #3			@ not user?
135		bne	not_angel
136		mov	r0, #0x17		@ angel_SWIreason_EnterSVC
137		swi	0x123456		@ angel_SWI_ARM
138not_angel:
139		mrs	r2, cpsr		@ turn off interrupts to
140		orr	r2, r2, #0xc0		@ prevent angel from running
141		msr	cpsr_c, r2
142#else
143		teqp	pc, #0x0c000003		@ turn off interrupts
144#endif
145
146		/*
147		 * Note that some cache flushing and other stuff may
148		 * be needed here - is there an Angel SWI call for this?
149		 */
150
151		/*
152		 * some architecture specific code can be inserted
153		 * by the linker here, but it should preserve r7, r8, and r9.
154		 */
155
156		.text
157		adr	r0, LC0
158		ldmia	r0, {r1, r2, r3, r4, r5, r6, ip, sp}
159		subs	r0, r0, r1		@ calculate the delta offset
160
161						@ if delta is zero, we are
162		beq	not_relocated		@ running at the address we
163						@ were linked at.
164
165		/*
166		 * We're running at a different address.  We need to fix
167		 * up various pointers:
168		 *   r5 - zImage base address
169		 *   r6 - GOT start
170		 *   ip - GOT end
171		 */
172		add	r5, r5, r0
173		add	r6, r6, r0
174		add	ip, ip, r0
175
176#ifndef CONFIG_ZBOOT_ROM
177		/*
178		 * If we're running fully PIC === CONFIG_ZBOOT_ROM = n,
179		 * we need to fix up pointers into the BSS region.
180		 *   r2 - BSS start
181		 *   r3 - BSS end
182		 *   sp - stack pointer
183		 */
184		add	r2, r2, r0
185		add	r3, r3, r0
186		add	sp, sp, r0
187
188		/*
189		 * Relocate all entries in the GOT table.
190		 */
1911:		ldr	r1, [r6, #0]		@ relocate entries in the GOT
192		add	r1, r1, r0		@ table.  This fixes up the
193		str	r1, [r6], #4		@ C references.
194		cmp	r6, ip
195		blo	1b
196#else
197
198		/*
199		 * Relocate entries in the GOT table.  We only relocate
200		 * the entries that are outside the (relocated) BSS region.
201		 */
2021:		ldr	r1, [r6, #0]		@ relocate entries in the GOT
203		cmp	r1, r2			@ entry < bss_start ||
204		cmphs	r3, r1			@ _end < entry
205		addlo	r1, r1, r0		@ table.  This fixes up the
206		str	r1, [r6], #4		@ C references.
207		cmp	r6, ip
208		blo	1b
209#endif
210
211not_relocated:	mov	r0, #0
2121:		str	r0, [r2], #4		@ clear bss
213		str	r0, [r2], #4
214		str	r0, [r2], #4
215		str	r0, [r2], #4
216		cmp	r2, r3
217		blo	1b
218
219		/*
220		 * The C runtime environment should now be setup
221		 * sufficiently.  Turn the cache on, set up some
222		 * pointers, and start decompressing.
223		 */
224		bl	cache_on
225
226		mov	r1, sp			@ malloc space above stack
227		add	r2, sp, #0x10000	@ 64k max
228
229/*
230 * Check to see if we will overwrite ourselves.
231 *   r4 = final kernel address
232 *   r5 = start of this image
233 *   r2 = end of malloc space (and therefore this image)
234 * We basically want:
235 *   r4 >= r2 -> OK
236 *   r4 + image length <= r5 -> OK
237 */
238		cmp	r4, r2
239		bhs	wont_overwrite
240		sub	r3, sp, r5		@ > compressed kernel size
241		add	r0, r4, r3, lsl #2	@ allow for 4x expansion
242		cmp	r0, r5
243		bls	wont_overwrite
244
245		mov	r5, r2			@ decompress after malloc space
246		mov	r0, r5
247		mov	r3, r7
248		bl	decompress_kernel
249
250		add	r0, r0, #127
251		bic	r0, r0, #127		@ align the kernel length
252/*
253 * r0     = decompressed kernel length
254 * r1-r3  = unused
255 * r4     = kernel execution address
256 * r5     = decompressed kernel start
257 * r6     = processor ID
258 * r7     = architecture ID
259 * r8     = atags pointer
260 * r9-r14 = corrupted
261 */
262		add	r1, r5, r0		@ end of decompressed kernel
263		adr	r2, reloc_start
264		ldr	r3, LC1
265		add	r3, r2, r3
2661:		ldmia	r2!, {r9 - r14}		@ copy relocation code
267		stmia	r1!, {r9 - r14}
268		ldmia	r2!, {r9 - r14}
269		stmia	r1!, {r9 - r14}
270		cmp	r2, r3
271		blo	1b
272
273		bl	cache_clean_flush
274		add	pc, r5, r0		@ call relocation code
275
276/*
277 * We're not in danger of overwriting ourselves.  Do this the simple way.
278 *
279 * r4     = kernel execution address
280 * r7     = architecture ID
281 */
282wont_overwrite:	mov	r0, r4
283		mov	r3, r7
284		bl	decompress_kernel
285		b	call_kernel
286
287		.type	LC0, #object
288LC0:		.word	LC0			@ r1
289		.word	__bss_start		@ r2
290		.word	_end			@ r3
291		.word	zreladdr		@ r4
292		.word	_start			@ r5
293		.word	_got_start		@ r6
294		.word	_got_end		@ ip
295		.word	user_stack+4096		@ sp
296LC1:		.word	reloc_end - reloc_start
297		.size	LC0, . - LC0
298
299#ifdef CONFIG_ARCH_RPC
300		.globl	params
301params:		ldr	r0, =params_phys
302		mov	pc, lr
303		.ltorg
304		.align
305#endif
306
307/*
308 * Turn on the cache.  We need to setup some page tables so that we
309 * can have both the I and D caches on.
310 *
311 * We place the page tables 16k down from the kernel execution address,
312 * and we hope that nothing else is using it.  If we're using it, we
313 * will go pop!
314 *
315 * On entry,
316 *  r4 = kernel execution address
317 *  r6 = processor ID
318 *  r7 = architecture number
319 *  r8 = atags pointer
320 *  r9 = run-time address of "start"  (???)
321 * On exit,
322 *  r1, r2, r3, r9, r10, r12 corrupted
323 * This routine must preserve:
324 *  r4, r5, r6, r7, r8
325 */
326		.align	5
327cache_on:	mov	r3, #8			@ cache_on function
328		b	call_cache_fn
329
330/*
331 * Initialize the highest priority protection region, PR7
332 * to cover all 32bit address and cacheable and bufferable.
333 */
334__armv4_mpu_cache_on:
335		mov	r0, #0x3f		@ 4G, the whole
336		mcr	p15, 0, r0, c6, c7, 0	@ PR7 Area Setting
337		mcr 	p15, 0, r0, c6, c7, 1
338
339		mov	r0, #0x80		@ PR7
340		mcr	p15, 0, r0, c2, c0, 0	@ D-cache on
341		mcr	p15, 0, r0, c2, c0, 1	@ I-cache on
342		mcr	p15, 0, r0, c3, c0, 0	@ write-buffer on
343
344		mov	r0, #0xc000
345		mcr	p15, 0, r0, c5, c0, 1	@ I-access permission
346		mcr	p15, 0, r0, c5, c0, 0	@ D-access permission
347
348		mov	r0, #0
349		mcr	p15, 0, r0, c7, c10, 4	@ drain write buffer
350		mcr	p15, 0, r0, c7, c5, 0	@ flush(inval) I-Cache
351		mcr	p15, 0, r0, c7, c6, 0	@ flush(inval) D-Cache
352		mrc	p15, 0, r0, c1, c0, 0	@ read control reg
353						@ ...I .... ..D. WC.M
354		orr	r0, r0, #0x002d		@ .... .... ..1. 11.1
355		orr	r0, r0, #0x1000		@ ...1 .... .... ....
356
357		mcr	p15, 0, r0, c1, c0, 0	@ write control reg
358
359		mov	r0, #0
360		mcr	p15, 0, r0, c7, c5, 0	@ flush(inval) I-Cache
361		mcr	p15, 0, r0, c7, c6, 0	@ flush(inval) D-Cache
362		mov	pc, lr
363
364__armv3_mpu_cache_on:
365		mov	r0, #0x3f		@ 4G, the whole
366		mcr	p15, 0, r0, c6, c7, 0	@ PR7 Area Setting
367
368		mov	r0, #0x80		@ PR7
369		mcr	p15, 0, r0, c2, c0, 0	@ cache on
370		mcr	p15, 0, r0, c3, c0, 0	@ write-buffer on
371
372		mov	r0, #0xc000
373		mcr	p15, 0, r0, c5, c0, 0	@ access permission
374
375		mov	r0, #0
376		mcr	p15, 0, r0, c7, c0, 0	@ invalidate whole cache v3
377		mrc	p15, 0, r0, c1, c0, 0	@ read control reg
378						@ .... .... .... WC.M
379		orr	r0, r0, #0x000d		@ .... .... .... 11.1
380		mov	r0, #0
381		mcr	p15, 0, r0, c1, c0, 0	@ write control reg
382
383		mcr	p15, 0, r0, c7, c0, 0	@ invalidate whole cache v3
384		mov	pc, lr
385
386__setup_mmu:	sub	r3, r4, #16384		@ Page directory size
387		bic	r3, r3, #0xff		@ Align the pointer
388		bic	r3, r3, #0x3f00
389/*
390 * Initialise the page tables, turning on the cacheable and bufferable
391 * bits for the RAM area only.
392 */
393		mov	r0, r3
394		mov	r9, r0, lsr #18
395		mov	r9, r9, lsl #18		@ start of RAM
396		add	r10, r9, #0x10000000	@ a reasonable RAM size
397		mov	r1, #0x12
398		orr	r1, r1, #3 << 10
399		add	r2, r3, #16384
4001:		cmp	r1, r9			@ if virt > start of RAM
401		orrhs	r1, r1, #0x0c		@ set cacheable, bufferable
402		cmp	r1, r10			@ if virt > end of RAM
403		bichs	r1, r1, #0x0c		@ clear cacheable, bufferable
404		str	r1, [r0], #4		@ 1:1 mapping
405		add	r1, r1, #1048576
406		teq	r0, r2
407		bne	1b
408/*
409 * If ever we are running from Flash, then we surely want the cache
410 * to be enabled also for our execution instance...  We map 2MB of it
411 * so there is no map overlap problem for up to 1 MB compressed kernel.
412 * If the execution is in RAM then we would only be duplicating the above.
413 */
414		mov	r1, #0x1e
415		orr	r1, r1, #3 << 10
416		mov	r2, pc, lsr #20
417		orr	r1, r1, r2, lsl #20
418		add	r0, r3, r2, lsl #2
419		str	r1, [r0], #4
420		add	r1, r1, #1048576
421		str	r1, [r0]
422		mov	pc, lr
423
424__armv4_mmu_cache_on:
425		mov	r12, lr
426		bl	__setup_mmu
427		mov	r0, #0
428		mcr	p15, 0, r0, c7, c10, 4	@ drain write buffer
429		mcr	p15, 0, r0, c8, c7, 0	@ flush I,D TLBs
430		mrc	p15, 0, r0, c1, c0, 0	@ read control reg
431		orr	r0, r0, #0x5000		@ I-cache enable, RR cache replacement
432		orr	r0, r0, #0x0030
433		bl	__common_mmu_cache_on
434		mov	r0, #0
435		mcr	p15, 0, r0, c8, c7, 0	@ flush I,D TLBs
436		mov	pc, r12
437
438__arm6_mmu_cache_on:
439		mov	r12, lr
440		bl	__setup_mmu
441		mov	r0, #0
442		mcr	p15, 0, r0, c7, c0, 0	@ invalidate whole cache v3
443		mcr	p15, 0, r0, c5, c0, 0	@ invalidate whole TLB v3
444		mov	r0, #0x30
445		bl	__common_mmu_cache_on
446		mov	r0, #0
447		mcr	p15, 0, r0, c5, c0, 0	@ invalidate whole TLB v3
448		mov	pc, r12
449
450__common_mmu_cache_on:
451#ifndef DEBUG
452		orr	r0, r0, #0x000d		@ Write buffer, mmu
453#endif
454		mov	r1, #-1
455		mcr	p15, 0, r3, c2, c0, 0	@ load page table pointer
456		mcr	p15, 0, r1, c3, c0, 0	@ load domain access control
457		b	1f
458		.align	5			@ cache line aligned
4591:		mcr	p15, 0, r0, c1, c0, 0	@ load control register
460		mrc	p15, 0, r0, c1, c0, 0	@ and read it back to
461		sub	pc, lr, r0, lsr #32	@ properly flush pipeline
462
463/*
464 * All code following this line is relocatable.  It is relocated by
465 * the above code to the end of the decompressed kernel image and
466 * executed there.  During this time, we have no stacks.
467 *
468 * r0     = decompressed kernel length
469 * r1-r3  = unused
470 * r4     = kernel execution address
471 * r5     = decompressed kernel start
472 * r6     = processor ID
473 * r7     = architecture ID
474 * r8     = atags pointer
475 * r9-r14 = corrupted
476 */
477		.align	5
478reloc_start:	add	r9, r5, r0
479		debug_reloc_start
480		mov	r1, r4
4811:
482		.rept	4
483		ldmia	r5!, {r0, r2, r3, r10 - r14}	@ relocate kernel
484		stmia	r1!, {r0, r2, r3, r10 - r14}
485		.endr
486
487		cmp	r5, r9
488		blo	1b
489		debug_reloc_end
490
491call_kernel:	bl	cache_clean_flush
492		bl	cache_off
493		mov	r0, #0			@ must be zero
494		mov	r1, r7			@ restore architecture number
495		mov	r2, r8			@ restore atags pointer
496		mov	pc, r4			@ call kernel
497
498/*
499 * Here follow the relocatable cache support functions for the
500 * various processors.  This is a generic hook for locating an
501 * entry and jumping to an instruction at the specified offset
502 * from the start of the block.  Please note this is all position
503 * independent code.
504 *
505 *  r1  = corrupted
506 *  r2  = corrupted
507 *  r3  = block offset
508 *  r6  = corrupted
509 *  r12 = corrupted
510 */
511
512call_cache_fn:	adr	r12, proc_types
513#ifdef CONFIG_CPU_CP15
514		mrc	p15, 0, r6, c0, c0	@ get processor ID
515#else
516		ldr	r6, =CONFIG_PROCESSOR_ID
517#endif
5181:		ldr	r1, [r12, #0]		@ get value
519		ldr	r2, [r12, #4]		@ get mask
520		eor	r1, r1, r6		@ (real ^ match)
521		tst	r1, r2			@       & mask
522		addeq	pc, r12, r3		@ call cache function
523		add	r12, r12, #4*5
524		b	1b
525
526/*
527 * Table for cache operations.  This is basically:
528 *   - CPU ID match
529 *   - CPU ID mask
530 *   - 'cache on' method instruction
531 *   - 'cache off' method instruction
532 *   - 'cache flush' method instruction
533 *
534 * We match an entry using: ((real_id ^ match) & mask) == 0
535 *
536 * Writethrough caches generally only need 'on' and 'off'
537 * methods.  Writeback caches _must_ have the flush method
538 * defined.
539 */
540		.type	proc_types,#object
541proc_types:
542		.word	0x41560600		@ ARM6/610
543		.word	0xffffffe0
544		b	__arm6_mmu_cache_off	@ works, but slow
545		b	__arm6_mmu_cache_off
546		mov	pc, lr
547@		b	__arm6_mmu_cache_on		@ untested
548@		b	__arm6_mmu_cache_off
549@		b	__armv3_mmu_cache_flush
550
551		.word	0x00000000		@ old ARM ID
552		.word	0x0000f000
553		mov	pc, lr
554		mov	pc, lr
555		mov	pc, lr
556
557		.word	0x41007000		@ ARM7/710
558		.word	0xfff8fe00
559		b	__arm7_mmu_cache_off
560		b	__arm7_mmu_cache_off
561		mov	pc, lr
562
563		.word	0x41807200		@ ARM720T (writethrough)
564		.word	0xffffff00
565		b	__armv4_mmu_cache_on
566		b	__armv4_mmu_cache_off
567		mov	pc, lr
568
569		.word	0x41007400		@ ARM74x
570		.word	0xff00ff00
571		b	__armv3_mpu_cache_on
572		b	__armv3_mpu_cache_off
573		b	__armv3_mpu_cache_flush
574
575		.word	0x41009400		@ ARM94x
576		.word	0xff00ff00
577		b	__armv4_mpu_cache_on
578		b	__armv4_mpu_cache_off
579		b	__armv4_mpu_cache_flush
580
581		.word	0x00007000		@ ARM7 IDs
582		.word	0x0000f000
583		mov	pc, lr
584		mov	pc, lr
585		mov	pc, lr
586
587		@ Everything from here on will be the new ID system.
588
589		.word	0x4401a100		@ sa110 / sa1100
590		.word	0xffffffe0
591		b	__armv4_mmu_cache_on
592		b	__armv4_mmu_cache_off
593		b	__armv4_mmu_cache_flush
594
595		.word	0x6901b110		@ sa1110
596		.word	0xfffffff0
597		b	__armv4_mmu_cache_on
598		b	__armv4_mmu_cache_off
599		b	__armv4_mmu_cache_flush
600
601		@ These match on the architecture ID
602
603		.word	0x00020000		@ ARMv4T
604		.word	0x000f0000
605		b	__armv4_mmu_cache_on
606		b	__armv4_mmu_cache_off
607		b	__armv4_mmu_cache_flush
608
609		.word	0x00050000		@ ARMv5TE
610		.word	0x000f0000
611		b	__armv4_mmu_cache_on
612		b	__armv4_mmu_cache_off
613		b	__armv4_mmu_cache_flush
614
615		.word	0x00060000		@ ARMv5TEJ
616		.word	0x000f0000
617		b	__armv4_mmu_cache_on
618		b	__armv4_mmu_cache_off
619		b	__armv4_mmu_cache_flush
620
621		.word	0x0007b000		@ ARMv6
622		.word	0x0007f000
623		b	__armv4_mmu_cache_on
624		b	__armv4_mmu_cache_off
625		b	__armv6_mmu_cache_flush
626
627		.word	0			@ unrecognised type
628		.word	0
629		mov	pc, lr
630		mov	pc, lr
631		mov	pc, lr
632
633		.size	proc_types, . - proc_types
634
635/*
636 * Turn off the Cache and MMU.  ARMv3 does not support
637 * reading the control register, but ARMv4 does.
638 *
639 * On entry,  r6 = processor ID
640 * On exit,   r0, r1, r2, r3, r12 corrupted
641 * This routine must preserve: r4, r6, r7
642 */
643		.align	5
644cache_off:	mov	r3, #12			@ cache_off function
645		b	call_cache_fn
646
647__armv4_mpu_cache_off:
648		mrc	p15, 0, r0, c1, c0
649		bic	r0, r0, #0x000d
650		mcr	p15, 0, r0, c1, c0	@ turn MPU and cache off
651		mov	r0, #0
652		mcr	p15, 0, r0, c7, c10, 4	@ drain write buffer
653		mcr	p15, 0, r0, c7, c6, 0	@ flush D-Cache
654		mcr	p15, 0, r0, c7, c5, 0	@ flush I-Cache
655		mov	pc, lr
656
657__armv3_mpu_cache_off:
658		mrc	p15, 0, r0, c1, c0
659		bic	r0, r0, #0x000d
660		mcr	p15, 0, r0, c1, c0, 0	@ turn MPU and cache off
661		mov	r0, #0
662		mcr	p15, 0, r0, c7, c0, 0	@ invalidate whole cache v3
663		mov	pc, lr
664
665__armv4_mmu_cache_off:
666		mrc	p15, 0, r0, c1, c0
667		bic	r0, r0, #0x000d
668		mcr	p15, 0, r0, c1, c0	@ turn MMU and cache off
669		mov	r0, #0
670		mcr	p15, 0, r0, c7, c7	@ invalidate whole cache v4
671		mcr	p15, 0, r0, c8, c7	@ invalidate whole TLB v4
672		mov	pc, lr
673
674__arm6_mmu_cache_off:
675		mov	r0, #0x00000030		@ ARM6 control reg.
676		b	__armv3_mmu_cache_off
677
678__arm7_mmu_cache_off:
679		mov	r0, #0x00000070		@ ARM7 control reg.
680		b	__armv3_mmu_cache_off
681
682__armv3_mmu_cache_off:
683		mcr	p15, 0, r0, c1, c0, 0	@ turn MMU and cache off
684		mov	r0, #0
685		mcr	p15, 0, r0, c7, c0, 0	@ invalidate whole cache v3
686		mcr	p15, 0, r0, c5, c0, 0	@ invalidate whole TLB v3
687		mov	pc, lr
688
689/*
690 * Clean and flush the cache to maintain consistency.
691 *
692 * On entry,
693 *  r6 = processor ID
694 * On exit,
695 *  r1, r2, r3, r11, r12 corrupted
696 * This routine must preserve:
697 *  r0, r4, r5, r6, r7
698 */
699		.align	5
700cache_clean_flush:
701		mov	r3, #16
702		b	call_cache_fn
703
704__armv4_mpu_cache_flush:
705		mov	r2, #1
706		mov	r3, #0
707		mcr	p15, 0, ip, c7, c6, 0	@ invalidate D cache
708		mov	r1, #7 << 5		@ 8 segments
7091:		orr	r3, r1, #63 << 26	@ 64 entries
7102:		mcr	p15, 0, r3, c7, c14, 2	@ clean & invalidate D index
711		subs	r3, r3, #1 << 26
712		bcs	2b			@ entries 63 to 0
713		subs 	r1, r1, #1 << 5
714		bcs	1b			@ segments 7 to 0
715
716		teq	r2, #0
717		mcrne	p15, 0, ip, c7, c5, 0	@ invalidate I cache
718		mcr	p15, 0, ip, c7, c10, 4	@ drain WB
719		mov	pc, lr
720
721
722__armv6_mmu_cache_flush:
723		mov	r1, #0
724		mcr	p15, 0, r1, c7, c14, 0	@ clean+invalidate D
725		mcr	p15, 0, r1, c7, c5, 0	@ invalidate I+BTB
726		mcr	p15, 0, r1, c7, c15, 0	@ clean+invalidate unified
727		mcr	p15, 0, r1, c7, c10, 4	@ drain WB
728		mov	pc, lr
729
730__armv4_mmu_cache_flush:
731		mov	r2, #64*1024		@ default: 32K dcache size (*2)
732		mov	r11, #32		@ default: 32 byte line size
733		mrc	p15, 0, r3, c0, c0, 1	@ read cache type
734		teq	r3, r6			@ cache ID register present?
735		beq	no_cache_id
736		mov	r1, r3, lsr #18
737		and	r1, r1, #7
738		mov	r2, #1024
739		mov	r2, r2, lsl r1		@ base dcache size *2
740		tst	r3, #1 << 14		@ test M bit
741		addne	r2, r2, r2, lsr #1	@ +1/2 size if M == 1
742		mov	r3, r3, lsr #12
743		and	r3, r3, #3
744		mov	r11, #8
745		mov	r11, r11, lsl r3	@ cache line size in bytes
746no_cache_id:
747		bic	r1, pc, #63		@ align to longest cache line
748		add	r2, r1, r2
7491:		ldr	r3, [r1], r11		@ s/w flush D cache
750		teq	r1, r2
751		bne	1b
752
753		mcr	p15, 0, r1, c7, c5, 0	@ flush I cache
754		mcr	p15, 0, r1, c7, c6, 0	@ flush D cache
755		mcr	p15, 0, r1, c7, c10, 4	@ drain WB
756		mov	pc, lr
757
758__armv3_mmu_cache_flush:
759__armv3_mpu_cache_flush:
760		mov	r1, #0
761		mcr	p15, 0, r0, c7, c0, 0	@ invalidate whole cache v3
762		mov	pc, lr
763
764/*
765 * Various debugging routines for printing hex characters and
766 * memory, which again must be relocatable.
767 */
768#ifdef DEBUG
769		.type	phexbuf,#object
770phexbuf:	.space	12
771		.size	phexbuf, . - phexbuf
772
773phex:		adr	r3, phexbuf
774		mov	r2, #0
775		strb	r2, [r3, r1]
7761:		subs	r1, r1, #1
777		movmi	r0, r3
778		bmi	puts
779		and	r2, r0, #15
780		mov	r0, r0, lsr #4
781		cmp	r2, #10
782		addge	r2, r2, #7
783		add	r2, r2, #'0'
784		strb	r2, [r3, r1]
785		b	1b
786
787puts:		loadsp	r3
7881:		ldrb	r2, [r0], #1
789		teq	r2, #0
790		moveq	pc, lr
7912:		writeb	r2, r3
792		mov	r1, #0x00020000
7933:		subs	r1, r1, #1
794		bne	3b
795		teq	r2, #'\n'
796		moveq	r2, #'\r'
797		beq	2b
798		teq	r0, #0
799		bne	1b
800		mov	pc, lr
801putc:
802		mov	r2, r0
803		mov	r0, #0
804		loadsp	r3
805		b	2b
806
807memdump:	mov	r12, r0
808		mov	r10, lr
809		mov	r11, #0
8102:		mov	r0, r11, lsl #2
811		add	r0, r0, r12
812		mov	r1, #8
813		bl	phex
814		mov	r0, #':'
815		bl	putc
8161:		mov	r0, #' '
817		bl	putc
818		ldr	r0, [r12, r11, lsl #2]
819		mov	r1, #8
820		bl	phex
821		and	r0, r11, #7
822		teq	r0, #3
823		moveq	r0, #' '
824		bleq	putc
825		and	r0, r11, #7
826		add	r11, r11, #1
827		teq	r0, #7
828		bne	1b
829		mov	r0, #'\n'
830		bl	putc
831		cmp	r11, #64
832		blt	2b
833		mov	pc, r10
834#endif
835
836reloc_end:
837
838		.align
839		.section ".stack", "w"
840user_stack:	.space	4096
841