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