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#include <asm/assembler.h> 13 14 .arch armv7-a 15/* 16 * Debugging stuff 17 * 18 * Note that these macros must not contain any code which is not 19 * 100% relocatable. Any attempt to do so will result in a crash. 20 * Please select one of the following when turning on debugging. 21 */ 22#ifdef DEBUG 23 24#if defined(CONFIG_DEBUG_ICEDCC) 25 26#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) || defined(CONFIG_CPU_V7) 27 .macro loadsp, rb, tmp 28 .endm 29 .macro writeb, ch, rb 30 mcr p14, 0, \ch, c0, c5, 0 31 .endm 32#elif defined(CONFIG_CPU_XSCALE) 33 .macro loadsp, rb, tmp 34 .endm 35 .macro writeb, ch, rb 36 mcr p14, 0, \ch, c8, c0, 0 37 .endm 38#else 39 .macro loadsp, rb, tmp 40 .endm 41 .macro writeb, ch, rb 42 mcr p14, 0, \ch, c1, c0, 0 43 .endm 44#endif 45 46#else 47 48#include CONFIG_DEBUG_LL_INCLUDE 49 50 .macro writeb, ch, rb 51 senduart \ch, \rb 52 .endm 53 54#if defined(CONFIG_ARCH_SA1100) 55 .macro loadsp, rb, tmp 56 mov \rb, #0x80000000 @ physical base address 57#ifdef CONFIG_DEBUG_LL_SER3 58 add \rb, \rb, #0x00050000 @ Ser3 59#else 60 add \rb, \rb, #0x00010000 @ Ser1 61#endif 62 .endm 63#elif defined(CONFIG_ARCH_S3C24XX) 64 .macro loadsp, rb, tmp 65 mov \rb, #0x50000000 66 add \rb, \rb, #0x4000 * CONFIG_S3C_LOWLEVEL_UART_PORT 67 .endm 68#else 69 .macro loadsp, rb, tmp 70 addruart \rb, \tmp 71 .endm 72#endif 73#endif 74#endif 75 76 .macro kputc,val 77 mov r0, \val 78 bl putc 79 .endm 80 81 .macro kphex,val,len 82 mov r0, \val 83 mov r1, #\len 84 bl phex 85 .endm 86 87 .macro debug_reloc_start 88#ifdef DEBUG 89 kputc #'\n' 90 kphex r6, 8 /* processor id */ 91 kputc #':' 92 kphex r7, 8 /* architecture id */ 93#ifdef CONFIG_CPU_CP15 94 kputc #':' 95 mrc p15, 0, r0, c1, c0 96 kphex r0, 8 /* control reg */ 97#endif 98 kputc #'\n' 99 kphex r5, 8 /* decompressed kernel start */ 100 kputc #'-' 101 kphex r9, 8 /* decompressed kernel end */ 102 kputc #'>' 103 kphex r4, 8 /* kernel execution address */ 104 kputc #'\n' 105#endif 106 .endm 107 108 .macro debug_reloc_end 109#ifdef DEBUG 110 kphex r5, 8 /* end of kernel */ 111 kputc #'\n' 112 mov r0, r4 113 bl memdump /* dump 256 bytes at start of kernel */ 114#endif 115 .endm 116 117 .section ".start", #alloc, #execinstr 118/* 119 * sort out different calling conventions 120 */ 121 .align 122 .arm @ Always enter in ARM state 123start: 124 .type start,#function 125 .rept 7 126 mov r0, r0 127 .endr 128 ARM( mov r0, r0 ) 129 ARM( b 1f ) 130 THUMB( adr r12, BSYM(1f) ) 131 THUMB( bx r12 ) 132 133 .word 0x016f2818 @ Magic numbers to help the loader 134 .word start @ absolute load/run zImage address 135 .word _edata @ zImage end address 136 THUMB( .thumb ) 1371: 138 mrs r9, cpsr 139#ifdef CONFIG_ARM_VIRT_EXT 140 bl __hyp_stub_install @ get into SVC mode, reversibly 141#endif 142 mov r7, r1 @ save architecture ID 143 mov r8, r2 @ save atags pointer 144 145#ifndef __ARM_ARCH_2__ 146 /* 147 * Booting from Angel - need to enter SVC mode and disable 148 * FIQs/IRQs (numeric definitions from angel arm.h source). 149 * We only do this if we were in user mode on entry. 150 */ 151 mrs r2, cpsr @ get current mode 152 tst r2, #3 @ not user? 153 bne not_angel 154 mov r0, #0x17 @ angel_SWIreason_EnterSVC 155 ARM( swi 0x123456 ) @ angel_SWI_ARM 156 THUMB( svc 0xab ) @ angel_SWI_THUMB 157not_angel: 158 safe_svcmode_maskall r0 159 msr spsr_cxsf, r9 @ Save the CPU boot mode in 160 @ SPSR 161#else 162 teqp pc, #0x0c000003 @ turn off interrupts 163#endif 164 165 /* 166 * Note that some cache flushing and other stuff may 167 * be needed here - is there an Angel SWI call for this? 168 */ 169 170 /* 171 * some architecture specific code can be inserted 172 * by the linker here, but it should preserve r7, r8, and r9. 173 */ 174 175 .text 176 177#ifdef CONFIG_AUTO_ZRELADDR 178 @ determine final kernel image address 179 mov r4, pc 180 and r4, r4, #0xf8000000 181 add r4, r4, #TEXT_OFFSET 182#else 183 ldr r4, =zreladdr 184#endif 185 186 bl cache_on 187 188restart: adr r0, LC0 189 ldmia r0, {r1, r2, r3, r6, r10, r11, r12} 190 ldr sp, [r0, #28] 191 192 /* 193 * We might be running at a different address. We need 194 * to fix up various pointers. 195 */ 196 sub r0, r0, r1 @ calculate the delta offset 197 add r6, r6, r0 @ _edata 198 add r10, r10, r0 @ inflated kernel size location 199 200 /* 201 * The kernel build system appends the size of the 202 * decompressed kernel at the end of the compressed data 203 * in little-endian form. 204 */ 205 ldrb r9, [r10, #0] 206 ldrb lr, [r10, #1] 207 orr r9, r9, lr, lsl #8 208 ldrb lr, [r10, #2] 209 ldrb r10, [r10, #3] 210 orr r9, r9, lr, lsl #16 211 orr r9, r9, r10, lsl #24 212 213#ifndef CONFIG_ZBOOT_ROM 214 /* malloc space is above the relocated stack (64k max) */ 215 add sp, sp, r0 216 add r10, sp, #0x10000 217#else 218 /* 219 * With ZBOOT_ROM the bss/stack is non relocatable, 220 * but someone could still run this code from RAM, 221 * in which case our reference is _edata. 222 */ 223 mov r10, r6 224#endif 225 226 mov r5, #0 @ init dtb size to 0 227#ifdef CONFIG_ARM_APPENDED_DTB 228/* 229 * r0 = delta 230 * r2 = BSS start 231 * r3 = BSS end 232 * r4 = final kernel address 233 * r5 = appended dtb size (still unknown) 234 * r6 = _edata 235 * r7 = architecture ID 236 * r8 = atags/device tree pointer 237 * r9 = size of decompressed image 238 * r10 = end of this image, including bss/stack/malloc space if non XIP 239 * r11 = GOT start 240 * r12 = GOT end 241 * sp = stack pointer 242 * 243 * if there are device trees (dtb) appended to zImage, advance r10 so that the 244 * dtb data will get relocated along with the kernel if necessary. 245 */ 246 247 ldr lr, [r6, #0] 248#ifndef __ARMEB__ 249 ldr r1, =0xedfe0dd0 @ sig is 0xd00dfeed big endian 250#else 251 ldr r1, =0xd00dfeed 252#endif 253 cmp lr, r1 254 bne dtb_check_done @ not found 255 256#ifdef CONFIG_ARM_ATAG_DTB_COMPAT 257 /* 258 * OK... Let's do some funky business here. 259 * If we do have a DTB appended to zImage, and we do have 260 * an ATAG list around, we want the later to be translated 261 * and folded into the former here. To be on the safe side, 262 * let's temporarily move the stack away into the malloc 263 * area. No GOT fixup has occurred yet, but none of the 264 * code we're about to call uses any global variable. 265 */ 266 add sp, sp, #0x10000 267 stmfd sp!, {r0-r3, ip, lr} 268 mov r0, r8 269 mov r1, r6 270 sub r2, sp, r6 271 bl atags_to_fdt 272 273 /* 274 * If returned value is 1, there is no ATAG at the location 275 * pointed by r8. Try the typical 0x100 offset from start 276 * of RAM and hope for the best. 277 */ 278 cmp r0, #1 279 sub r0, r4, #TEXT_OFFSET 280 add r0, r0, #0x100 281 mov r1, r6 282 sub r2, sp, r6 283 bleq atags_to_fdt 284 285 ldmfd sp!, {r0-r3, ip, lr} 286 sub sp, sp, #0x10000 287#endif 288 289 mov r8, r6 @ use the appended device tree 290 291 /* 292 * Make sure that the DTB doesn't end up in the final 293 * kernel's .bss area. To do so, we adjust the decompressed 294 * kernel size to compensate if that .bss size is larger 295 * than the relocated code. 296 */ 297 ldr r5, =_kernel_bss_size 298 adr r1, wont_overwrite 299 sub r1, r6, r1 300 subs r1, r5, r1 301 addhi r9, r9, r1 302 303 /* Get the dtb's size */ 304 ldr r5, [r6, #4] 305#ifndef __ARMEB__ 306 /* convert r5 (dtb size) to little endian */ 307 eor r1, r5, r5, ror #16 308 bic r1, r1, #0x00ff0000 309 mov r5, r5, ror #8 310 eor r5, r5, r1, lsr #8 311#endif 312 313 /* preserve 64-bit alignment */ 314 add r5, r5, #7 315 bic r5, r5, #7 316 317 /* relocate some pointers past the appended dtb */ 318 add r6, r6, r5 319 add r10, r10, r5 320 add sp, sp, r5 321dtb_check_done: 322#endif 323 324/* 325 * Check to see if we will overwrite ourselves. 326 * r4 = final kernel address 327 * r9 = size of decompressed image 328 * r10 = end of this image, including bss/stack/malloc space if non XIP 329 * We basically want: 330 * r4 - 16k page directory >= r10 -> OK 331 * r4 + image length <= address of wont_overwrite -> OK 332 */ 333 add r10, r10, #16384 334 cmp r4, r10 335 bhs wont_overwrite 336 add r10, r4, r9 337 adr r9, wont_overwrite 338 cmp r10, r9 339 bls wont_overwrite 340 341/* 342 * Relocate ourselves past the end of the decompressed kernel. 343 * r6 = _edata 344 * r10 = end of the decompressed kernel 345 * Because we always copy ahead, we need to do it from the end and go 346 * backward in case the source and destination overlap. 347 */ 348 /* 349 * Bump to the next 256-byte boundary with the size of 350 * the relocation code added. This avoids overwriting 351 * ourself when the offset is small. 352 */ 353 add r10, r10, #((reloc_code_end - restart + 256) & ~255) 354 bic r10, r10, #255 355 356 /* Get start of code we want to copy and align it down. */ 357 adr r5, restart 358 bic r5, r5, #31 359 360/* Relocate the hyp vector base if necessary */ 361#ifdef CONFIG_ARM_VIRT_EXT 362 mrs r0, spsr 363 and r0, r0, #MODE_MASK 364 cmp r0, #HYP_MODE 365 bne 1f 366 367 bl __hyp_get_vectors 368 sub r0, r0, r5 369 add r0, r0, r10 370 bl __hyp_set_vectors 3711: 372#endif 373 374 sub r9, r6, r5 @ size to copy 375 add r9, r9, #31 @ rounded up to a multiple 376 bic r9, r9, #31 @ ... of 32 bytes 377 add r6, r9, r5 378 add r9, r9, r10 379 3801: ldmdb r6!, {r0 - r3, r10 - r12, lr} 381 cmp r6, r5 382 stmdb r9!, {r0 - r3, r10 - r12, lr} 383 bhi 1b 384 385 /* Preserve offset to relocated code. */ 386 sub r6, r9, r6 387 388#ifndef CONFIG_ZBOOT_ROM 389 /* cache_clean_flush may use the stack, so relocate it */ 390 add sp, sp, r6 391#endif 392 393 bl cache_clean_flush 394 395 adr r0, BSYM(restart) 396 add r0, r0, r6 397 mov pc, r0 398 399wont_overwrite: 400/* 401 * If delta is zero, we are running at the address we were linked at. 402 * r0 = delta 403 * r2 = BSS start 404 * r3 = BSS end 405 * r4 = kernel execution address 406 * r5 = appended dtb size (0 if not present) 407 * r7 = architecture ID 408 * r8 = atags pointer 409 * r11 = GOT start 410 * r12 = GOT end 411 * sp = stack pointer 412 */ 413 orrs r1, r0, r5 414 beq not_relocated 415 416 add r11, r11, r0 417 add r12, r12, r0 418 419#ifndef CONFIG_ZBOOT_ROM 420 /* 421 * If we're running fully PIC === CONFIG_ZBOOT_ROM = n, 422 * we need to fix up pointers into the BSS region. 423 * Note that the stack pointer has already been fixed up. 424 */ 425 add r2, r2, r0 426 add r3, r3, r0 427 428 /* 429 * Relocate all entries in the GOT table. 430 * Bump bss entries to _edata + dtb size 431 */ 4321: ldr r1, [r11, #0] @ relocate entries in the GOT 433 add r1, r1, r0 @ This fixes up C references 434 cmp r1, r2 @ if entry >= bss_start && 435 cmphs r3, r1 @ bss_end > entry 436 addhi r1, r1, r5 @ entry += dtb size 437 str r1, [r11], #4 @ next entry 438 cmp r11, r12 439 blo 1b 440 441 /* bump our bss pointers too */ 442 add r2, r2, r5 443 add r3, r3, r5 444 445#else 446 447 /* 448 * Relocate entries in the GOT table. We only relocate 449 * the entries that are outside the (relocated) BSS region. 450 */ 4511: ldr r1, [r11, #0] @ relocate entries in the GOT 452 cmp r1, r2 @ entry < bss_start || 453 cmphs r3, r1 @ _end < entry 454 addlo r1, r1, r0 @ table. This fixes up the 455 str r1, [r11], #4 @ C references. 456 cmp r11, r12 457 blo 1b 458#endif 459 460not_relocated: mov r0, #0 4611: str r0, [r2], #4 @ clear bss 462 str r0, [r2], #4 463 str r0, [r2], #4 464 str r0, [r2], #4 465 cmp r2, r3 466 blo 1b 467 468/* 469 * The C runtime environment should now be setup sufficiently. 470 * Set up some pointers, and start decompressing. 471 * r4 = kernel execution address 472 * r7 = architecture ID 473 * r8 = atags pointer 474 */ 475 mov r0, r4 476 mov r1, sp @ malloc space above stack 477 add r2, sp, #0x10000 @ 64k max 478 mov r3, r7 479 bl decompress_kernel 480 bl cache_clean_flush 481 bl cache_off 482 mov r1, r7 @ restore architecture number 483 mov r2, r8 @ restore atags pointer 484 485#ifdef CONFIG_ARM_VIRT_EXT 486 mrs r0, spsr @ Get saved CPU boot mode 487 and r0, r0, #MODE_MASK 488 cmp r0, #HYP_MODE @ if not booted in HYP mode... 489 bne __enter_kernel @ boot kernel directly 490 491 adr r12, .L__hyp_reentry_vectors_offset 492 ldr r0, [r12] 493 add r0, r0, r12 494 495 bl __hyp_set_vectors 496 __HVC(0) @ otherwise bounce to hyp mode 497 498 b . @ should never be reached 499 500 .align 2 501.L__hyp_reentry_vectors_offset: .long __hyp_reentry_vectors - . 502#else 503 b __enter_kernel 504#endif 505 506 .align 2 507 .type LC0, #object 508LC0: .word LC0 @ r1 509 .word __bss_start @ r2 510 .word _end @ r3 511 .word _edata @ r6 512 .word input_data_end - 4 @ r10 (inflated size location) 513 .word _got_start @ r11 514 .word _got_end @ ip 515 .word .L_user_stack_end @ sp 516 .size LC0, . - LC0 517 518#ifdef CONFIG_ARCH_RPC 519 .globl params 520params: ldr r0, =0x10000100 @ params_phys for RPC 521 mov pc, lr 522 .ltorg 523 .align 524#endif 525 526/* 527 * Turn on the cache. We need to setup some page tables so that we 528 * can have both the I and D caches on. 529 * 530 * We place the page tables 16k down from the kernel execution address, 531 * and we hope that nothing else is using it. If we're using it, we 532 * will go pop! 533 * 534 * On entry, 535 * r4 = kernel execution address 536 * r7 = architecture number 537 * r8 = atags pointer 538 * On exit, 539 * r0, r1, r2, r3, r9, r10, r12 corrupted 540 * This routine must preserve: 541 * r4, r7, r8 542 */ 543 .align 5 544cache_on: mov r3, #8 @ cache_on function 545 b call_cache_fn 546 547/* 548 * Initialize the highest priority protection region, PR7 549 * to cover all 32bit address and cacheable and bufferable. 550 */ 551__armv4_mpu_cache_on: 552 mov r0, #0x3f @ 4G, the whole 553 mcr p15, 0, r0, c6, c7, 0 @ PR7 Area Setting 554 mcr p15, 0, r0, c6, c7, 1 555 556 mov r0, #0x80 @ PR7 557 mcr p15, 0, r0, c2, c0, 0 @ D-cache on 558 mcr p15, 0, r0, c2, c0, 1 @ I-cache on 559 mcr p15, 0, r0, c3, c0, 0 @ write-buffer on 560 561 mov r0, #0xc000 562 mcr p15, 0, r0, c5, c0, 1 @ I-access permission 563 mcr p15, 0, r0, c5, c0, 0 @ D-access permission 564 565 mov r0, #0 566 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer 567 mcr p15, 0, r0, c7, c5, 0 @ flush(inval) I-Cache 568 mcr p15, 0, r0, c7, c6, 0 @ flush(inval) D-Cache 569 mrc p15, 0, r0, c1, c0, 0 @ read control reg 570 @ ...I .... ..D. WC.M 571 orr r0, r0, #0x002d @ .... .... ..1. 11.1 572 orr r0, r0, #0x1000 @ ...1 .... .... .... 573 574 mcr p15, 0, r0, c1, c0, 0 @ write control reg 575 576 mov r0, #0 577 mcr p15, 0, r0, c7, c5, 0 @ flush(inval) I-Cache 578 mcr p15, 0, r0, c7, c6, 0 @ flush(inval) D-Cache 579 mov pc, lr 580 581__armv3_mpu_cache_on: 582 mov r0, #0x3f @ 4G, the whole 583 mcr p15, 0, r0, c6, c7, 0 @ PR7 Area Setting 584 585 mov r0, #0x80 @ PR7 586 mcr p15, 0, r0, c2, c0, 0 @ cache on 587 mcr p15, 0, r0, c3, c0, 0 @ write-buffer on 588 589 mov r0, #0xc000 590 mcr p15, 0, r0, c5, c0, 0 @ access permission 591 592 mov r0, #0 593 mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3 594 /* 595 * ?? ARMv3 MMU does not allow reading the control register, 596 * does this really work on ARMv3 MPU? 597 */ 598 mrc p15, 0, r0, c1, c0, 0 @ read control reg 599 @ .... .... .... WC.M 600 orr r0, r0, #0x000d @ .... .... .... 11.1 601 /* ?? this overwrites the value constructed above? */ 602 mov r0, #0 603 mcr p15, 0, r0, c1, c0, 0 @ write control reg 604 605 /* ?? invalidate for the second time? */ 606 mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3 607 mov pc, lr 608 609#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH 610#define CB_BITS 0x08 611#else 612#define CB_BITS 0x0c 613#endif 614 615__setup_mmu: sub r3, r4, #16384 @ Page directory size 616 bic r3, r3, #0xff @ Align the pointer 617 bic r3, r3, #0x3f00 618/* 619 * Initialise the page tables, turning on the cacheable and bufferable 620 * bits for the RAM area only. 621 */ 622 mov r0, r3 623 mov r9, r0, lsr #18 624 mov r9, r9, lsl #18 @ start of RAM 625 add r10, r9, #0x10000000 @ a reasonable RAM size 626 mov r1, #0x12 @ XN|U + section mapping 627 orr r1, r1, #3 << 10 @ AP=11 628 add r2, r3, #16384 6291: cmp r1, r9 @ if virt > start of RAM 630 cmphs r10, r1 @ && end of RAM > virt 631 bic r1, r1, #0x1c @ clear XN|U + C + B 632 orrlo r1, r1, #0x10 @ Set XN|U for non-RAM 633 orrhs r1, r1, r6 @ set RAM section settings 634 str r1, [r0], #4 @ 1:1 mapping 635 add r1, r1, #1048576 636 teq r0, r2 637 bne 1b 638/* 639 * If ever we are running from Flash, then we surely want the cache 640 * to be enabled also for our execution instance... We map 2MB of it 641 * so there is no map overlap problem for up to 1 MB compressed kernel. 642 * If the execution is in RAM then we would only be duplicating the above. 643 */ 644 orr r1, r6, #0x04 @ ensure B is set for this 645 orr r1, r1, #3 << 10 646 mov r2, pc 647 mov r2, r2, lsr #20 648 orr r1, r1, r2, lsl #20 649 add r0, r3, r2, lsl #2 650 str r1, [r0], #4 651 add r1, r1, #1048576 652 str r1, [r0] 653 mov pc, lr 654ENDPROC(__setup_mmu) 655 656@ Enable unaligned access on v6, to allow better code generation 657@ for the decompressor C code: 658__armv6_mmu_cache_on: 659 mrc p15, 0, r0, c1, c0, 0 @ read SCTLR 660 bic r0, r0, #2 @ A (no unaligned access fault) 661 orr r0, r0, #1 << 22 @ U (v6 unaligned access model) 662 mcr p15, 0, r0, c1, c0, 0 @ write SCTLR 663 b __armv4_mmu_cache_on 664 665__arm926ejs_mmu_cache_on: 666#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH 667 mov r0, #4 @ put dcache in WT mode 668 mcr p15, 7, r0, c15, c0, 0 669#endif 670 671__armv4_mmu_cache_on: 672 mov r12, lr 673#ifdef CONFIG_MMU 674 mov r6, #CB_BITS | 0x12 @ U 675 bl __setup_mmu 676 mov r0, #0 677 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer 678 mcr p15, 0, r0, c8, c7, 0 @ flush I,D TLBs 679 mrc p15, 0, r0, c1, c0, 0 @ read control reg 680 orr r0, r0, #0x5000 @ I-cache enable, RR cache replacement 681 orr r0, r0, #0x0030 682#ifdef CONFIG_CPU_ENDIAN_BE8 683 orr r0, r0, #1 << 25 @ big-endian page tables 684#endif 685 bl __common_mmu_cache_on 686 mov r0, #0 687 mcr p15, 0, r0, c8, c7, 0 @ flush I,D TLBs 688#endif 689 mov pc, r12 690 691__armv7_mmu_cache_on: 692 mov r12, lr 693#ifdef CONFIG_MMU 694 mrc p15, 0, r11, c0, c1, 4 @ read ID_MMFR0 695 tst r11, #0xf @ VMSA 696 movne r6, #CB_BITS | 0x02 @ !XN 697 blne __setup_mmu 698 mov r0, #0 699 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer 700 tst r11, #0xf @ VMSA 701 mcrne p15, 0, r0, c8, c7, 0 @ flush I,D TLBs 702#endif 703 mrc p15, 0, r0, c1, c0, 0 @ read control reg 704 bic r0, r0, #1 << 28 @ clear SCTLR.TRE 705 orr r0, r0, #0x5000 @ I-cache enable, RR cache replacement 706 orr r0, r0, #0x003c @ write buffer 707 bic r0, r0, #2 @ A (no unaligned access fault) 708 orr r0, r0, #1 << 22 @ U (v6 unaligned access model) 709 @ (needed for ARM1176) 710#ifdef CONFIG_MMU 711#ifdef CONFIG_CPU_ENDIAN_BE8 712 orr r0, r0, #1 << 25 @ big-endian page tables 713#endif 714 mrcne p15, 0, r6, c2, c0, 2 @ read ttb control reg 715 orrne r0, r0, #1 @ MMU enabled 716 movne r1, #0xfffffffd @ domain 0 = client 717 bic r6, r6, #1 << 31 @ 32-bit translation system 718 bic r6, r6, #3 << 0 @ use only ttbr0 719 mcrne p15, 0, r3, c2, c0, 0 @ load page table pointer 720 mcrne p15, 0, r1, c3, c0, 0 @ load domain access control 721 mcrne p15, 0, r6, c2, c0, 2 @ load ttb control 722#endif 723 mcr p15, 0, r0, c7, c5, 4 @ ISB 724 mcr p15, 0, r0, c1, c0, 0 @ load control register 725 mrc p15, 0, r0, c1, c0, 0 @ and read it back 726 mov r0, #0 727 mcr p15, 0, r0, c7, c5, 4 @ ISB 728 mov pc, r12 729 730__fa526_cache_on: 731 mov r12, lr 732 mov r6, #CB_BITS | 0x12 @ U 733 bl __setup_mmu 734 mov r0, #0 735 mcr p15, 0, r0, c7, c7, 0 @ Invalidate whole cache 736 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer 737 mcr p15, 0, r0, c8, c7, 0 @ flush UTLB 738 mrc p15, 0, r0, c1, c0, 0 @ read control reg 739 orr r0, r0, #0x1000 @ I-cache enable 740 bl __common_mmu_cache_on 741 mov r0, #0 742 mcr p15, 0, r0, c8, c7, 0 @ flush UTLB 743 mov pc, r12 744 745__common_mmu_cache_on: 746#ifndef CONFIG_THUMB2_KERNEL 747#ifndef DEBUG 748 orr r0, r0, #0x000d @ Write buffer, mmu 749#endif 750 mov r1, #-1 751 mcr p15, 0, r3, c2, c0, 0 @ load page table pointer 752 mcr p15, 0, r1, c3, c0, 0 @ load domain access control 753 b 1f 754 .align 5 @ cache line aligned 7551: mcr p15, 0, r0, c1, c0, 0 @ load control register 756 mrc p15, 0, r0, c1, c0, 0 @ and read it back to 757 sub pc, lr, r0, lsr #32 @ properly flush pipeline 758#endif 759 760#define PROC_ENTRY_SIZE (4*5) 761 762/* 763 * Here follow the relocatable cache support functions for the 764 * various processors. This is a generic hook for locating an 765 * entry and jumping to an instruction at the specified offset 766 * from the start of the block. Please note this is all position 767 * independent code. 768 * 769 * r1 = corrupted 770 * r2 = corrupted 771 * r3 = block offset 772 * r9 = corrupted 773 * r12 = corrupted 774 */ 775 776call_cache_fn: adr r12, proc_types 777#ifdef CONFIG_CPU_CP15 778 mrc p15, 0, r9, c0, c0 @ get processor ID 779#else 780 ldr r9, =CONFIG_PROCESSOR_ID 781#endif 7821: ldr r1, [r12, #0] @ get value 783 ldr r2, [r12, #4] @ get mask 784 eor r1, r1, r9 @ (real ^ match) 785 tst r1, r2 @ & mask 786 ARM( addeq pc, r12, r3 ) @ call cache function 787 THUMB( addeq r12, r3 ) 788 THUMB( moveq pc, r12 ) @ call cache function 789 add r12, r12, #PROC_ENTRY_SIZE 790 b 1b 791 792/* 793 * Table for cache operations. This is basically: 794 * - CPU ID match 795 * - CPU ID mask 796 * - 'cache on' method instruction 797 * - 'cache off' method instruction 798 * - 'cache flush' method instruction 799 * 800 * We match an entry using: ((real_id ^ match) & mask) == 0 801 * 802 * Writethrough caches generally only need 'on' and 'off' 803 * methods. Writeback caches _must_ have the flush method 804 * defined. 805 */ 806 .align 2 807 .type proc_types,#object 808proc_types: 809 .word 0x00000000 @ old ARM ID 810 .word 0x0000f000 811 mov pc, lr 812 THUMB( nop ) 813 mov pc, lr 814 THUMB( nop ) 815 mov pc, lr 816 THUMB( nop ) 817 818 .word 0x41007000 @ ARM7/710 819 .word 0xfff8fe00 820 mov pc, lr 821 THUMB( nop ) 822 mov pc, lr 823 THUMB( nop ) 824 mov pc, lr 825 THUMB( nop ) 826 827 .word 0x41807200 @ ARM720T (writethrough) 828 .word 0xffffff00 829 W(b) __armv4_mmu_cache_on 830 W(b) __armv4_mmu_cache_off 831 mov pc, lr 832 THUMB( nop ) 833 834 .word 0x41007400 @ ARM74x 835 .word 0xff00ff00 836 W(b) __armv3_mpu_cache_on 837 W(b) __armv3_mpu_cache_off 838 W(b) __armv3_mpu_cache_flush 839 840 .word 0x41009400 @ ARM94x 841 .word 0xff00ff00 842 W(b) __armv4_mpu_cache_on 843 W(b) __armv4_mpu_cache_off 844 W(b) __armv4_mpu_cache_flush 845 846 .word 0x41069260 @ ARM926EJ-S (v5TEJ) 847 .word 0xff0ffff0 848 W(b) __arm926ejs_mmu_cache_on 849 W(b) __armv4_mmu_cache_off 850 W(b) __armv5tej_mmu_cache_flush 851 852 .word 0x00007000 @ ARM7 IDs 853 .word 0x0000f000 854 mov pc, lr 855 THUMB( nop ) 856 mov pc, lr 857 THUMB( nop ) 858 mov pc, lr 859 THUMB( nop ) 860 861 @ Everything from here on will be the new ID system. 862 863 .word 0x4401a100 @ sa110 / sa1100 864 .word 0xffffffe0 865 W(b) __armv4_mmu_cache_on 866 W(b) __armv4_mmu_cache_off 867 W(b) __armv4_mmu_cache_flush 868 869 .word 0x6901b110 @ sa1110 870 .word 0xfffffff0 871 W(b) __armv4_mmu_cache_on 872 W(b) __armv4_mmu_cache_off 873 W(b) __armv4_mmu_cache_flush 874 875 .word 0x56056900 876 .word 0xffffff00 @ PXA9xx 877 W(b) __armv4_mmu_cache_on 878 W(b) __armv4_mmu_cache_off 879 W(b) __armv4_mmu_cache_flush 880 881 .word 0x56158000 @ PXA168 882 .word 0xfffff000 883 W(b) __armv4_mmu_cache_on 884 W(b) __armv4_mmu_cache_off 885 W(b) __armv5tej_mmu_cache_flush 886 887 .word 0x56050000 @ Feroceon 888 .word 0xff0f0000 889 W(b) __armv4_mmu_cache_on 890 W(b) __armv4_mmu_cache_off 891 W(b) __armv5tej_mmu_cache_flush 892 893#ifdef CONFIG_CPU_FEROCEON_OLD_ID 894 /* this conflicts with the standard ARMv5TE entry */ 895 .long 0x41009260 @ Old Feroceon 896 .long 0xff00fff0 897 b __armv4_mmu_cache_on 898 b __armv4_mmu_cache_off 899 b __armv5tej_mmu_cache_flush 900#endif 901 902 .word 0x66015261 @ FA526 903 .word 0xff01fff1 904 W(b) __fa526_cache_on 905 W(b) __armv4_mmu_cache_off 906 W(b) __fa526_cache_flush 907 908 @ These match on the architecture ID 909 910 .word 0x00020000 @ ARMv4T 911 .word 0x000f0000 912 W(b) __armv4_mmu_cache_on 913 W(b) __armv4_mmu_cache_off 914 W(b) __armv4_mmu_cache_flush 915 916 .word 0x00050000 @ ARMv5TE 917 .word 0x000f0000 918 W(b) __armv4_mmu_cache_on 919 W(b) __armv4_mmu_cache_off 920 W(b) __armv4_mmu_cache_flush 921 922 .word 0x00060000 @ ARMv5TEJ 923 .word 0x000f0000 924 W(b) __armv4_mmu_cache_on 925 W(b) __armv4_mmu_cache_off 926 W(b) __armv5tej_mmu_cache_flush 927 928 .word 0x0007b000 @ ARMv6 929 .word 0x000ff000 930 W(b) __armv6_mmu_cache_on 931 W(b) __armv4_mmu_cache_off 932 W(b) __armv6_mmu_cache_flush 933 934 .word 0x000f0000 @ new CPU Id 935 .word 0x000f0000 936 W(b) __armv7_mmu_cache_on 937 W(b) __armv7_mmu_cache_off 938 W(b) __armv7_mmu_cache_flush 939 940 .word 0 @ unrecognised type 941 .word 0 942 mov pc, lr 943 THUMB( nop ) 944 mov pc, lr 945 THUMB( nop ) 946 mov pc, lr 947 THUMB( nop ) 948 949 .size proc_types, . - proc_types 950 951 /* 952 * If you get a "non-constant expression in ".if" statement" 953 * error from the assembler on this line, check that you have 954 * not accidentally written a "b" instruction where you should 955 * have written W(b). 956 */ 957 .if (. - proc_types) % PROC_ENTRY_SIZE != 0 958 .error "The size of one or more proc_types entries is wrong." 959 .endif 960 961/* 962 * Turn off the Cache and MMU. ARMv3 does not support 963 * reading the control register, but ARMv4 does. 964 * 965 * On exit, 966 * r0, r1, r2, r3, r9, r12 corrupted 967 * This routine must preserve: 968 * r4, r7, r8 969 */ 970 .align 5 971cache_off: mov r3, #12 @ cache_off function 972 b call_cache_fn 973 974__armv4_mpu_cache_off: 975 mrc p15, 0, r0, c1, c0 976 bic r0, r0, #0x000d 977 mcr p15, 0, r0, c1, c0 @ turn MPU and cache off 978 mov r0, #0 979 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer 980 mcr p15, 0, r0, c7, c6, 0 @ flush D-Cache 981 mcr p15, 0, r0, c7, c5, 0 @ flush I-Cache 982 mov pc, lr 983 984__armv3_mpu_cache_off: 985 mrc p15, 0, r0, c1, c0 986 bic r0, r0, #0x000d 987 mcr p15, 0, r0, c1, c0, 0 @ turn MPU and cache off 988 mov r0, #0 989 mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3 990 mov pc, lr 991 992__armv4_mmu_cache_off: 993#ifdef CONFIG_MMU 994 mrc p15, 0, r0, c1, c0 995 bic r0, r0, #0x000d 996 mcr p15, 0, r0, c1, c0 @ turn MMU and cache off 997 mov r0, #0 998 mcr p15, 0, r0, c7, c7 @ invalidate whole cache v4 999 mcr p15, 0, r0, c8, c7 @ invalidate whole TLB v4 1000#endif 1001 mov pc, lr 1002 1003__armv7_mmu_cache_off: 1004 mrc p15, 0, r0, c1, c0 1005#ifdef CONFIG_MMU 1006 bic r0, r0, #0x000d 1007#else 1008 bic r0, r0, #0x000c 1009#endif 1010 mcr p15, 0, r0, c1, c0 @ turn MMU and cache off 1011 mov r12, lr 1012 bl __armv7_mmu_cache_flush 1013 mov r0, #0 1014#ifdef CONFIG_MMU 1015 mcr p15, 0, r0, c8, c7, 0 @ invalidate whole TLB 1016#endif 1017 mcr p15, 0, r0, c7, c5, 6 @ invalidate BTC 1018 mcr p15, 0, r0, c7, c10, 4 @ DSB 1019 mcr p15, 0, r0, c7, c5, 4 @ ISB 1020 mov pc, r12 1021 1022/* 1023 * Clean and flush the cache to maintain consistency. 1024 * 1025 * On exit, 1026 * r1, r2, r3, r9, r10, r11, r12 corrupted 1027 * This routine must preserve: 1028 * r4, r6, r7, r8 1029 */ 1030 .align 5 1031cache_clean_flush: 1032 mov r3, #16 1033 b call_cache_fn 1034 1035__armv4_mpu_cache_flush: 1036 mov r2, #1 1037 mov r3, #0 1038 mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache 1039 mov r1, #7 << 5 @ 8 segments 10401: orr r3, r1, #63 << 26 @ 64 entries 10412: mcr p15, 0, r3, c7, c14, 2 @ clean & invalidate D index 1042 subs r3, r3, #1 << 26 1043 bcs 2b @ entries 63 to 0 1044 subs r1, r1, #1 << 5 1045 bcs 1b @ segments 7 to 0 1046 1047 teq r2, #0 1048 mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache 1049 mcr p15, 0, ip, c7, c10, 4 @ drain WB 1050 mov pc, lr 1051 1052__fa526_cache_flush: 1053 mov r1, #0 1054 mcr p15, 0, r1, c7, c14, 0 @ clean and invalidate D cache 1055 mcr p15, 0, r1, c7, c5, 0 @ flush I cache 1056 mcr p15, 0, r1, c7, c10, 4 @ drain WB 1057 mov pc, lr 1058 1059__armv6_mmu_cache_flush: 1060 mov r1, #0 1061 mcr p15, 0, r1, c7, c14, 0 @ clean+invalidate D 1062 mcr p15, 0, r1, c7, c5, 0 @ invalidate I+BTB 1063 mcr p15, 0, r1, c7, c15, 0 @ clean+invalidate unified 1064 mcr p15, 0, r1, c7, c10, 4 @ drain WB 1065 mov pc, lr 1066 1067__armv7_mmu_cache_flush: 1068 mrc p15, 0, r10, c0, c1, 5 @ read ID_MMFR1 1069 tst r10, #0xf << 16 @ hierarchical cache (ARMv7) 1070 mov r10, #0 1071 beq hierarchical 1072 mcr p15, 0, r10, c7, c14, 0 @ clean+invalidate D 1073 b iflush 1074hierarchical: 1075 mcr p15, 0, r10, c7, c10, 5 @ DMB 1076 stmfd sp!, {r0-r7, r9-r11} 1077 mrc p15, 1, r0, c0, c0, 1 @ read clidr 1078 ands r3, r0, #0x7000000 @ extract loc from clidr 1079 mov r3, r3, lsr #23 @ left align loc bit field 1080 beq finished @ if loc is 0, then no need to clean 1081 mov r10, #0 @ start clean at cache level 0 1082loop1: 1083 add r2, r10, r10, lsr #1 @ work out 3x current cache level 1084 mov r1, r0, lsr r2 @ extract cache type bits from clidr 1085 and r1, r1, #7 @ mask of the bits for current cache only 1086 cmp r1, #2 @ see what cache we have at this level 1087 blt skip @ skip if no cache, or just i-cache 1088 mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr 1089 mcr p15, 0, r10, c7, c5, 4 @ isb to sych the new cssr&csidr 1090 mrc p15, 1, r1, c0, c0, 0 @ read the new csidr 1091 and r2, r1, #7 @ extract the length of the cache lines 1092 add r2, r2, #4 @ add 4 (line length offset) 1093 ldr r4, =0x3ff 1094 ands r4, r4, r1, lsr #3 @ find maximum number on the way size 1095 clz r5, r4 @ find bit position of way size increment 1096 ldr r7, =0x7fff 1097 ands r7, r7, r1, lsr #13 @ extract max number of the index size 1098loop2: 1099 mov r9, r4 @ create working copy of max way size 1100loop3: 1101 ARM( orr r11, r10, r9, lsl r5 ) @ factor way and cache number into r11 1102 ARM( orr r11, r11, r7, lsl r2 ) @ factor index number into r11 1103 THUMB( lsl r6, r9, r5 ) 1104 THUMB( orr r11, r10, r6 ) @ factor way and cache number into r11 1105 THUMB( lsl r6, r7, r2 ) 1106 THUMB( orr r11, r11, r6 ) @ factor index number into r11 1107 mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way 1108 subs r9, r9, #1 @ decrement the way 1109 bge loop3 1110 subs r7, r7, #1 @ decrement the index 1111 bge loop2 1112skip: 1113 add r10, r10, #2 @ increment cache number 1114 cmp r3, r10 1115 bgt loop1 1116finished: 1117 ldmfd sp!, {r0-r7, r9-r11} 1118 mov r10, #0 @ swith back to cache level 0 1119 mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr 1120iflush: 1121 mcr p15, 0, r10, c7, c10, 4 @ DSB 1122 mcr p15, 0, r10, c7, c5, 0 @ invalidate I+BTB 1123 mcr p15, 0, r10, c7, c10, 4 @ DSB 1124 mcr p15, 0, r10, c7, c5, 4 @ ISB 1125 mov pc, lr 1126 1127__armv5tej_mmu_cache_flush: 11281: mrc p15, 0, r15, c7, c14, 3 @ test,clean,invalidate D cache 1129 bne 1b 1130 mcr p15, 0, r0, c7, c5, 0 @ flush I cache 1131 mcr p15, 0, r0, c7, c10, 4 @ drain WB 1132 mov pc, lr 1133 1134__armv4_mmu_cache_flush: 1135 mov r2, #64*1024 @ default: 32K dcache size (*2) 1136 mov r11, #32 @ default: 32 byte line size 1137 mrc p15, 0, r3, c0, c0, 1 @ read cache type 1138 teq r3, r9 @ cache ID register present? 1139 beq no_cache_id 1140 mov r1, r3, lsr #18 1141 and r1, r1, #7 1142 mov r2, #1024 1143 mov r2, r2, lsl r1 @ base dcache size *2 1144 tst r3, #1 << 14 @ test M bit 1145 addne r2, r2, r2, lsr #1 @ +1/2 size if M == 1 1146 mov r3, r3, lsr #12 1147 and r3, r3, #3 1148 mov r11, #8 1149 mov r11, r11, lsl r3 @ cache line size in bytes 1150no_cache_id: 1151 mov r1, pc 1152 bic r1, r1, #63 @ align to longest cache line 1153 add r2, r1, r2 11541: 1155 ARM( ldr r3, [r1], r11 ) @ s/w flush D cache 1156 THUMB( ldr r3, [r1] ) @ s/w flush D cache 1157 THUMB( add r1, r1, r11 ) 1158 teq r1, r2 1159 bne 1b 1160 1161 mcr p15, 0, r1, c7, c5, 0 @ flush I cache 1162 mcr p15, 0, r1, c7, c6, 0 @ flush D cache 1163 mcr p15, 0, r1, c7, c10, 4 @ drain WB 1164 mov pc, lr 1165 1166__armv3_mmu_cache_flush: 1167__armv3_mpu_cache_flush: 1168 mov r1, #0 1169 mcr p15, 0, r1, c7, c0, 0 @ invalidate whole cache v3 1170 mov pc, lr 1171 1172/* 1173 * Various debugging routines for printing hex characters and 1174 * memory, which again must be relocatable. 1175 */ 1176#ifdef DEBUG 1177 .align 2 1178 .type phexbuf,#object 1179phexbuf: .space 12 1180 .size phexbuf, . - phexbuf 1181 1182@ phex corrupts {r0, r1, r2, r3} 1183phex: adr r3, phexbuf 1184 mov r2, #0 1185 strb r2, [r3, r1] 11861: subs r1, r1, #1 1187 movmi r0, r3 1188 bmi puts 1189 and r2, r0, #15 1190 mov r0, r0, lsr #4 1191 cmp r2, #10 1192 addge r2, r2, #7 1193 add r2, r2, #'0' 1194 strb r2, [r3, r1] 1195 b 1b 1196 1197@ puts corrupts {r0, r1, r2, r3} 1198puts: loadsp r3, r1 11991: ldrb r2, [r0], #1 1200 teq r2, #0 1201 moveq pc, lr 12022: writeb r2, r3 1203 mov r1, #0x00020000 12043: subs r1, r1, #1 1205 bne 3b 1206 teq r2, #'\n' 1207 moveq r2, #'\r' 1208 beq 2b 1209 teq r0, #0 1210 bne 1b 1211 mov pc, lr 1212@ putc corrupts {r0, r1, r2, r3} 1213putc: 1214 mov r2, r0 1215 mov r0, #0 1216 loadsp r3, r1 1217 b 2b 1218 1219@ memdump corrupts {r0, r1, r2, r3, r10, r11, r12, lr} 1220memdump: mov r12, r0 1221 mov r10, lr 1222 mov r11, #0 12232: mov r0, r11, lsl #2 1224 add r0, r0, r12 1225 mov r1, #8 1226 bl phex 1227 mov r0, #':' 1228 bl putc 12291: mov r0, #' ' 1230 bl putc 1231 ldr r0, [r12, r11, lsl #2] 1232 mov r1, #8 1233 bl phex 1234 and r0, r11, #7 1235 teq r0, #3 1236 moveq r0, #' ' 1237 bleq putc 1238 and r0, r11, #7 1239 add r11, r11, #1 1240 teq r0, #7 1241 bne 1b 1242 mov r0, #'\n' 1243 bl putc 1244 cmp r11, #64 1245 blt 2b 1246 mov pc, r10 1247#endif 1248 1249 .ltorg 1250 1251#ifdef CONFIG_ARM_VIRT_EXT 1252.align 5 1253__hyp_reentry_vectors: 1254 W(b) . @ reset 1255 W(b) . @ undef 1256 W(b) . @ svc 1257 W(b) . @ pabort 1258 W(b) . @ dabort 1259 W(b) __enter_kernel @ hyp 1260 W(b) . @ irq 1261 W(b) . @ fiq 1262#endif /* CONFIG_ARM_VIRT_EXT */ 1263 1264__enter_kernel: 1265 mov r0, #0 @ must be 0 1266 ARM( mov pc, r4 ) @ call kernel 1267 THUMB( bx r4 ) @ entry point is always ARM 1268 1269reloc_code_end: 1270 1271 .align 1272 .section ".stack", "aw", %nobits 1273.L_user_stack: .space 4096 1274.L_user_stack_end: 1275