1/*
2 *  linux/arch/arm/boot/compressed/head.S
3 *
4 *  Copyright (C) 1996-1999 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#include <linux/config.h>
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#if defined(CONFIG_DEBUG_DC21285_PORT)
22		.macro	loadsp,	rb
23		mov	\rb, #0x7c000000
24		.endm
25		.macro	writeb,	rb
26		strb	\rb, [r3, #0x3f8]
27		.endm
28#elif defined(CONFIG_ARCH_RPC)
29		.macro	loadsp,	rb
30		mov	\rb, #0x03000000
31		orr	\rb, \rb, #0x00010000
32		.endm
33		.macro	writeb,	rb
34		strb	\rb, [r3, #0x3f8 << 2]
35		.endm
36#elif defined(CONFIG_ARCH_INTEGRATOR)
37		.macro	loadsp, rb
38		mov	\rb, #0x16000000
39		.endm
40		.macro	writeb, rb
41		strb	\rb, [r3, #0]
42		.endm
43#elif defined(CONFIG_ARCH_SA1100)
44		.macro	loadsp, rb
45		mov	\rb, #0x80000000	@ physical base address
46#  if defined(CONFIG_DEBUG_LL_SER3)
47		add	\rb, \rb, #0x00050000	@ Ser3
48#  else
49		add	\rb, \rb, #0x00010000	@ Ser1
50#  endif
51		.endm
52		.macro	writeb, rb
53		str	\rb, [r3, #0x14]	@ UTDR
54		.endm
55#else
56#error no serial architecture defined
57#endif
58#endif
59
60		.macro	kputc,val
61		mov	r0, \val
62		bl	putc
63		.endm
64
65		.macro	kphex,val,len
66		mov	r0, \val
67		mov	r1, #\len
68		bl	phex
69		.endm
70
71		.macro	debug_reloc_start
72#ifdef DEBUG
73		kputc	#'\n'
74		kphex	r6, 8		/* processor id */
75		kputc	#':'
76		kphex	r7, 8		/* architecture id */
77		kputc	#':'
78		mrc	p15, 0, r0, c1, c0
79		kphex	r0, 8		/* control reg */
80		kputc	#'\n'
81		kphex	r5, 8		/* decompressed kernel start */
82		kputc	#'-'
83		kphex	r8, 8		/* decompressed kernel end  */
84		kputc	#'>'
85		kphex	r4, 8		/* kernel execution address */
86		kputc	#'\n'
87#endif
88		.endm
89
90		.macro	debug_reloc_end
91#ifdef DEBUG
92		kphex	r5, 8		/* end of kernel */
93		kputc	#'\n'
94		mov	r0, r4
95		bl	memdump		/* dump 256 bytes at start of kernel */
96#endif
97		.endm
98
99		.section ".start", #alloc, #execinstr
100/*
101 * sort out different calling conventions
102 */
103		.align
104start:
105		.type	start,#function
106		.rept	8
107		mov	r0, r0
108		.endr
109
110		b	1f
111		.word	0x016f2818		@ Magic numbers to help the loader
112		.word	start			@ absolute load/run zImage address
113		.word	_edata			@ zImage end address
1141:		mov	r7, r1			@ save architecture ID
115		mov	r8, #0			@ save r0
116
117#ifndef __ARM_ARCH_2__
118		/*
119		 * Booting from Angel - need to enter SVC mode and disable
120		 * FIQs/IRQs (numeric definitions from angel arm.h source).
121		 * We only do this if we were in user mode on entry.
122		 */
123		mrs	r2, cpsr		@ get current mode
124		tst	r2, #3			@ not user?
125		bne	not_angel
126		mov	r0, #0x17		@ angel_SWIreason_EnterSVC
127		swi	0x123456		@ angel_SWI_ARM
128not_angel:
129		mrs	r2, cpsr		@ turn off interrupts to
130		orr	r2, r2, #0xc0		@ prevent angel from running
131		msr	cpsr_c, r2
132#else
133		teqp	pc, #0x0c000003		@ turn off interrupts
134#endif
135
136		/*
137		 * Note that some cache flushing and other stuff may
138		 * be needed here - is there an Angel SWI call for this?
139		 */
140
141		/*
142		 * some architecture specific code can be inserted
143		 * by the linker here, but it should preserve r7 and r8.
144		 */
145
146		.text
1471:		adr	r2, LC0
148		ldmia	r2, {r2, r3, r4, r5, sp}
149
150		mov	r0, #0
1511:		str	r0, [r2], #4		@ clear bss
152		str	r0, [r2], #4
153		str	r0, [r2], #4
154		str	r0, [r2], #4
155		cmp	r2, r3
156		blt	1b
157
158		mrc	p15, 0, r6, c0, c0	@ get processor ID
159		bl	cache_on
160
161		mov	r1, sp			@ malloc space above stack
162		add	r2, sp, #0x10000	@ 64k max
163
164		teq	r4, r5			@ will we overwrite ourselves?
165		moveq	r5, r2			@ decompress after image
166		movne	r5, r4			@ decompress to final location
167
168		mov	r0, r5
169		mov	r3, r7
170		bl	SYMBOL_NAME(decompress_kernel)
171
172		teq	r4, r5			@ do we need to relocate
173		beq	call_kernel		@ the kernel?
174
175		add	r0, r0, #127
176		bic	r0, r0, #127		@ align the kernel length
177/*
178 * r0     = decompressed kernel length
179 * r1-r3  = unused
180 * r4     = kernel execution address
181 * r5     = decompressed kernel start
182 * r6     = processor ID
183 * r7     = architecture ID
184 * r8-r14 = unused
185 */
186		add	r1, r5, r0		@ end of decompressed kernel
187		adr	r2, reloc_start
188		adr	r3, reloc_end
1891:		ldmia	r2!, {r8 - r13}		@ copy relocation code
190		stmia	r1!, {r8 - r13}
191		ldmia	r2!, {r8 - r13}
192		stmia	r1!, {r8 - r13}
193		cmp	r2, r3
194		blt	1b
195
196		bl	cache_clean_flush
197		add	pc, r5, r0		@ call relocation code
198
199		.type	LC0, #object
200LC0:		.word	__bss_start
201		.word	_end
202		.word	_load_addr
203		.word	_start
204		.word	user_stack+4096
205		.size	LC0, . - LC0
206
207/*
208 * Turn on the cache.  We need to setup some page tables so that we
209 * can have both the I and D caches on.
210 *
211 * We place the page tables 16k down from the kernel execution address,
212 * and we hope that nothing else is using it.  If we're using it, we
213 * will go pop!
214 *
215 * On entry,
216 *  r4 = kernel execution address
217 *  r6 = processor ID
218 *  r7 = architecture number
219 *  r8 = run-time address of "start"
220 * On exit,
221 *  r0, r1, r2, r3, r8, r9 corrupted
222 * This routine must preserve:
223 *  r4, r5, r6, r7
224 */
225		.align	5
226cache_on:	ldr	r1, proc_sa110_type
227		eor	r1, r1, r6
228		movs	r1, r1, lsr #5		@ catch SA110 and SA1100
229		beq	1f
230		ldr     r1, proc_sa1110_type
231		eor	r1, r1, r6
232		movs	r1, r1, lsr #4
233@		movne	pc, lr
234		bne	cache_off
2351:
236		sub	r3, r4, #16384		@ Page directory size
237		bic	r3, r3, #0xff		@ Align the pointer
238		bic	r3, r3, #0x3f00
239/*
240 * Initialise the page tables, turning on the cacheable and bufferable
241 * bits for the RAM area only.
242 */
243		mov	r0, r3
244		mov	r8, r0, lsr #18
245		mov	r8, r8, lsl #18		@ start of RAM
246		add	r9, r8, #0x10000000	@ a reasonable RAM size
247		mov	r1, #0x12
248		orr	r1, r1, #3 << 10
249		add	r2, r3, #16384
2501:		cmp	r1, r8			@ if virt > start of RAM
251		orrge	r1, r1, #0x0c		@ set cacheable, bufferable
252		cmp	r1, r9			@ if virt > end of RAM
253		bicge	r1, r1, #0x0c		@ clear cacheable, bufferable
254		str	r1, [r0], #4		@ 1:1 mapping
255		add	r1, r1, #1048576
256		teq	r0, r2
257		bne	1b
258/*
259 * If ever we are running from Flash, then we surely want the cache
260 * to be enabled also for our execution instance...  We map 2MB of it
261 * so there is no map overlap problem for up to 1 MB compressed kernel.
262 * If the execution is in RAM then we would only be duplicating the above.
263 */
264		mov	r1, #0x1e
265		orr	r1, r1, #3 << 10
266		mov	r2, pc, lsr #20
267		orr	r1, r1, r2, lsl #20
268		add	r0, r3, r2, lsl #2
269		str	r1, [r0], #4
270		add	r1, r1, #1048576
271		str	r1, [r0]
272
273		mov	r0, #0
274		mcr	p15, 0, r0, c7, c10, 4	@ drain write buffer
275		mcr	p15, 0, r0, c8, c7	@ flush I,D TLBs
276		mcr	p15, 0, r3, c2, c0	@ load page table pointer
277		mov	r0, #-1
278		mcr	p15, 0, r0, c3, c0	@ load domain access register
279		mrc	p15, 0, r0, c1, c0
280		orr	r0, r0, #0x1000		@ I-cache enable
281#ifndef DEBUG
282		orr	r0, r0, #0x003d		@ Write buffer, mmu
283#endif
284		mcr	p15, 0, r0, c1, c0
285		mov	pc, lr
286
287/*
288 * This code is relocatable.  It is relocated by the above code to the end
289 * of the kernel and executed there.  During this time, we have no stacks.
290 *
291 * r0     = decompressed kernel length
292 * r1-r3  = unused
293 * r4     = kernel execution address
294 * r5     = decompressed kernel start
295 * r6     = processor ID
296 * r7     = architecture ID
297 * r8-r14 = unused
298 */
299		.align	5
300reloc_start:	add	r8, r5, r0
301		debug_reloc_start
302		mov	r1, r4
3031:
304		.rept	4
305		ldmia	r5!, {r0, r2, r3, r9 - r13}	@ relocate kernel
306		stmia	r1!, {r0, r2, r3, r9 - r13}
307		.endr
308
309		cmp	r5, r8
310		blt	1b
311		debug_reloc_end
312
313call_kernel:	bl	cache_clean_flush
314		bl	cache_off
315		mov	r0, #0
316		mov	r1, r7			@ restore architecture number
317		mov	pc, r4			@ call kernel
318
319/*
320 * Here follow the relocatable cache support functions for
321 * the various processors.
322 */
323
324		.type	proc_sa110_type,#object
325proc_sa110_type:
326		.word	0x4401a100
327		.size	proc_sa110_type, . - proc_sa110_type
328
329		.type	proc_sa1110_type,#object
330proc_sa1110_type:
331		.word	0x6901b110
332		.size	proc_sa1110_type, . - proc_sa1110_type
333
334/*
335 * Turn off the Cache and MMU.  ARMv3 does not support
336 * reading the control register, but ARMv4 does.
337 *
338 * On entry,  r6 = processor ID
339 * On exit,   r0, r1 corrupted
340 * This routine must preserve: r4, r6, r7
341 */
342		.align	5
343cache_off:
344#ifdef CONFIG_CPU_ARM610
345		eor	r1, r6, #0x41000000
346		eor	r1, r1, #0x00560000
347		bic	r1, r1, #0x0000001f
348		teq	r1, #0x00000600
349		mov	r0, #0x00000060		@ ARM6 control reg.
350		beq	__armv3_cache_off
351#endif
352#ifdef CONFIG_CPU_ARM710
353		eor	r1, r6, #0x41000000
354		bic	r1, r1, #0x00070000
355		bic	r1, r1, #0x000000ff
356		teq	r1, #0x00007000		@ ARM7
357		teqne	r1, #0x00007100		@ ARM710
358		mov	r0, #0x00000070		@ ARM7 control reg.
359		beq	__armv3_cache_off
360#endif
361		mrc	p15, 0, r0, c1, c0
362		bic	r0, r0, #0x000d
363		mcr	p15, 0, r0, c1, c0	@ turn MMU and cache off
364		mov	r0, #0
365		mcr	p15, 0, r0, c7, c7	@ invalidate whole cache v4
366		mcr	p15, 0, r0, c8, c7	@ invalidate whole TLB v4
367		mov	pc, lr
368
369__armv3_cache_off:
370		mcr	p15, 0, r0, c1, c0	@ turn MMU and cache off
371		mov	r0, #0
372		mcr	p15, 0, r0, c7, c0	@ invalidate whole cache v3
373		mcr	p15, 0, r0, c5, c0	@ invalidate whole TLB v3
374		mov	pc, lr
375
376/*
377 * Clean and flush the cache to maintain consistency.
378 *
379 * On entry,
380 *  r6 = processor ID
381 * On exit,
382 *  r1, r2, r12 corrupted
383 * This routine must preserve:
384 *  r4, r6, r7
385 */
386		.align	5
387cache_clean_flush:
388		ldr	r1, proc_sa110_type
389		eor	r1, r1, r6
390		movs	r1, r1, lsr #5		@ catch SA110 and SA1100
391		beq	1f
392		ldr	r1, proc_sa1110_type
393		eor	r1, r1, r6
394		movs	r1, r1, lsr #4
395		movne	pc, lr
3961:
397		bic	r1, pc, #31
398		add	r2, r1, #32768
3991:		ldr	r12, [r1], #32		@ s/w flush D cache
400		teq	r1, r2
401		bne	1b
402
403		mcr	p15, 0, r1, c7, c7, 0	@ flush I cache
404		mcr	p15, 0, r1, c7, c10, 4	@ drain WB
405		mov	pc, lr
406
407/*
408 * Various debugging routines for printing hex characters and
409 * memory, which again must be relocatable.
410 */
411#ifdef DEBUG
412		.type	phexbuf,#object
413phexbuf:	.space	12
414		.size	phexbuf, . - phexbuf
415
416phex:		adr	r3, phexbuf
417		mov	r2, #0
418		strb	r2, [r3, r1]
4191:		subs	r1, r1, #1
420		movmi	r0, r3
421		bmi	puts
422		and	r2, r0, #15
423		mov	r0, r0, lsr #4
424		cmp	r2, #10
425		addge	r2, r2, #7
426		add	r2, r2, #'0'
427		strb	r2, [r3, r1]
428		b	1b
429
430puts:		loadsp	r3
4311:		ldrb	r2, [r0], #1
432		teq	r2, #0
433		moveq	pc, lr
4342:		writeb	r2
435		mov	r1, #0x00020000
4363:		subs	r1, r1, #1
437		bne	3b
438		teq	r2, #'\n'
439		moveq	r2, #'\r'
440		beq	2b
441		teq	r0, #0
442		bne	1b
443		mov	pc, lr
444putc:
445		mov	r2, r0
446		mov	r0, #0
447		loadsp	r3
448		b	2b
449
450memdump:	mov	r12, r0
451		mov	r10, lr
452		mov	r11, #0
4532:		mov	r0, r11, lsl #2
454		add	r0, r0, r12
455		mov	r1, #8
456		bl	phex
457		mov	r0, #':'
458		bl	putc
4591:		mov	r0, #' '
460		bl	putc
461		ldr	r0, [r12, r11, lsl #2]
462		mov	r1, #8
463		bl	phex
464		and	r0, r11, #7
465		teq	r0, #3
466		moveq	r0, #' '
467		bleq	putc
468		and	r0, r11, #7
469		add	r11, r11, #1
470		teq	r0, #7
471		bne	1b
472		mov	r0, #'\n'
473		bl	putc
474		cmp	r11, #64
475		blt	2b
476		mov	pc, r10
477#endif
478
479reloc_end:
480
481		.align
482		.section	".stack"
483user_stack:	.space	4096
484