1/* SPDX-License-Identifier: GPL-2.0-only */ 2/* 3 * linux/arch/arm/boot/compressed/head.S 4 * 5 * Copyright (C) 1996-2002 Russell King 6 * Copyright (C) 2004 Hyok S. Choi (MPU support) 7 */ 8#include <linux/linkage.h> 9#include <asm/assembler.h> 10#include <asm/v7m.h> 11 12#include "efi-header.S" 13 14 AR_CLASS( .arch armv7-a ) 15 M_CLASS( .arch armv7-m ) 16 17/* 18 * Debugging stuff 19 * 20 * Note that these macros must not contain any code which is not 21 * 100% relocatable. Any attempt to do so will result in a crash. 22 * Please select one of the following when turning on debugging. 23 */ 24#ifdef DEBUG 25 26#if defined(CONFIG_DEBUG_ICEDCC) 27 28#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) || defined(CONFIG_CPU_V7) 29 .macro loadsp, rb, tmp1, tmp2 30 .endm 31 .macro writeb, ch, rb, tmp 32 mcr p14, 0, \ch, c0, c5, 0 33 .endm 34#elif defined(CONFIG_CPU_XSCALE) 35 .macro loadsp, rb, tmp1, tmp2 36 .endm 37 .macro writeb, ch, rb, tmp 38 mcr p14, 0, \ch, c8, c0, 0 39 .endm 40#else 41 .macro loadsp, rb, tmp1, tmp2 42 .endm 43 .macro writeb, ch, rb, tmp 44 mcr p14, 0, \ch, c1, c0, 0 45 .endm 46#endif 47 48#else 49 50#include CONFIG_DEBUG_LL_INCLUDE 51 52 .macro writeb, ch, rb, tmp 53#ifdef CONFIG_DEBUG_UART_FLOW_CONTROL 54 waituartcts \tmp, \rb 55#endif 56 waituarttxrdy \tmp, \rb 57 senduart \ch, \rb 58 busyuart \tmp, \rb 59 .endm 60 61#if defined(CONFIG_ARCH_SA1100) 62 .macro loadsp, rb, tmp1, tmp2 63 mov \rb, #0x80000000 @ physical base address 64#ifdef CONFIG_DEBUG_LL_SER3 65 add \rb, \rb, #0x00050000 @ Ser3 66#else 67 add \rb, \rb, #0x00010000 @ Ser1 68#endif 69 .endm 70#else 71 .macro loadsp, rb, tmp1, tmp2 72 addruart \rb, \tmp1, \tmp2 73 .endm 74#endif 75#endif 76#endif 77 78 .macro kputc,val 79 mov r0, \val 80 bl putc 81 .endm 82 83 .macro kphex,val,len 84 mov r0, \val 85 mov r1, #\len 86 bl phex 87 .endm 88 89 /* 90 * Debug kernel copy by printing the memory addresses involved 91 */ 92 .macro dbgkc, begin, end, cbegin, cend 93#ifdef DEBUG 94 kputc #'C' 95 kputc #':' 96 kputc #'0' 97 kputc #'x' 98 kphex \begin, 8 /* Start of compressed kernel */ 99 kputc #'-' 100 kputc #'0' 101 kputc #'x' 102 kphex \end, 8 /* End of compressed kernel */ 103 kputc #'-' 104 kputc #'>' 105 kputc #'0' 106 kputc #'x' 107 kphex \cbegin, 8 /* Start of kernel copy */ 108 kputc #'-' 109 kputc #'0' 110 kputc #'x' 111 kphex \cend, 8 /* End of kernel copy */ 112 kputc #'\n' 113#endif 114 .endm 115 116 .macro enable_cp15_barriers, reg 117 mrc p15, 0, \reg, c1, c0, 0 @ read SCTLR 118 tst \reg, #(1 << 5) @ CP15BEN bit set? 119 bne .L_\@ 120 orr \reg, \reg, #(1 << 5) @ CP15 barrier instructions 121 mcr p15, 0, \reg, c1, c0, 0 @ write SCTLR 122 ARM( .inst 0xf57ff06f @ v7+ isb ) 123 THUMB( isb ) 124.L_\@: 125 .endm 126 127 /* 128 * The kernel build system appends the size of the 129 * decompressed kernel at the end of the compressed data 130 * in little-endian form. 131 */ 132 .macro get_inflated_image_size, res:req, tmp1:req, tmp2:req 133 adr \res, .Linflated_image_size_offset 134 ldr \tmp1, [\res] 135 add \tmp1, \tmp1, \res @ address of inflated image size 136 137 ldrb \res, [\tmp1] @ get_unaligned_le32 138 ldrb \tmp2, [\tmp1, #1] 139 orr \res, \res, \tmp2, lsl #8 140 ldrb \tmp2, [\tmp1, #2] 141 ldrb \tmp1, [\tmp1, #3] 142 orr \res, \res, \tmp2, lsl #16 143 orr \res, \res, \tmp1, lsl #24 144 .endm 145 146 .section ".start", "ax" 147/* 148 * sort out different calling conventions 149 */ 150 .align 151 /* 152 * Always enter in ARM state for CPUs that support the ARM ISA. 153 * As of today (2014) that's exactly the members of the A and R 154 * classes. 155 */ 156 AR_CLASS( .arm ) 157start: 158 .type start,#function 159 /* 160 * These 7 nops along with the 1 nop immediately below for 161 * !THUMB2 form 8 nops that make the compressed kernel bootable 162 * on legacy ARM systems that were assuming the kernel in a.out 163 * binary format. The boot loaders on these systems would 164 * jump 32 bytes into the image to skip the a.out header. 165 * with these 8 nops filling exactly 32 bytes, things still 166 * work as expected on these legacy systems. Thumb2 mode keeps 167 * 7 of the nops as it turns out that some boot loaders 168 * were patching the initial instructions of the kernel, i.e 169 * had started to exploit this "patch area". 170 */ 171 .rept 7 172 __nop 173 .endr 174#ifndef CONFIG_THUMB2_KERNEL 175 __nop 176#else 177 AR_CLASS( sub pc, pc, #3 ) @ A/R: switch to Thumb2 mode 178 M_CLASS( nop.w ) @ M: already in Thumb2 mode 179 .thumb 180#endif 181 W(b) 1f 182 183 .word _magic_sig @ Magic numbers to help the loader 184 .word _magic_start @ absolute load/run zImage address 185 .word _magic_end @ zImage end address 186 .word 0x04030201 @ endianness flag 187 .word 0x45454545 @ another magic number to indicate 188 .word _magic_table @ additional data table 189 190 __EFI_HEADER 1911: 192 ARM_BE8( setend be ) @ go BE8 if compiled for BE8 193 AR_CLASS( mrs r9, cpsr ) 194#ifdef CONFIG_ARM_VIRT_EXT 195 bl __hyp_stub_install @ get into SVC mode, reversibly 196#endif 197 mov r7, r1 @ save architecture ID 198 mov r8, r2 @ save atags pointer 199 200#ifndef CONFIG_CPU_V7M 201 /* 202 * Booting from Angel - need to enter SVC mode and disable 203 * FIQs/IRQs (numeric definitions from angel arm.h source). 204 * We only do this if we were in user mode on entry. 205 */ 206 mrs r2, cpsr @ get current mode 207 tst r2, #3 @ not user? 208 bne not_angel 209 mov r0, #0x17 @ angel_SWIreason_EnterSVC 210 ARM( swi 0x123456 ) @ angel_SWI_ARM 211 THUMB( svc 0xab ) @ angel_SWI_THUMB 212not_angel: 213 safe_svcmode_maskall r0 214 msr spsr_cxsf, r9 @ Save the CPU boot mode in 215 @ SPSR 216#endif 217 /* 218 * Note that some cache flushing and other stuff may 219 * be needed here - is there an Angel SWI call for this? 220 */ 221 222 /* 223 * some architecture specific code can be inserted 224 * by the linker here, but it should preserve r7, r8, and r9. 225 */ 226 227 .text 228 229#ifdef CONFIG_AUTO_ZRELADDR 230 /* 231 * Find the start of physical memory. As we are executing 232 * without the MMU on, we are in the physical address space. 233 * We just need to get rid of any offset by aligning the 234 * address. 235 * 236 * This alignment is a balance between the requirements of 237 * different platforms - we have chosen 128MB to allow 238 * platforms which align the start of their physical memory 239 * to 128MB to use this feature, while allowing the zImage 240 * to be placed within the first 128MB of memory on other 241 * platforms. Increasing the alignment means we place 242 * stricter alignment requirements on the start of physical 243 * memory, but relaxing it means that we break people who 244 * are already placing their zImage in (eg) the top 64MB 245 * of this range. 246 */ 247 mov r4, pc 248 and r4, r4, #0xf8000000 249 /* Determine final kernel image address. */ 250 add r4, r4, #TEXT_OFFSET 251#else 252 ldr r4, =zreladdr 253#endif 254 255 /* 256 * Set up a page table only if it won't overwrite ourself. 257 * That means r4 < pc || r4 - 16k page directory > &_end. 258 * Given that r4 > &_end is most unfrequent, we add a rough 259 * additional 1MB of room for a possible appended DTB. 260 */ 261 mov r0, pc 262 cmp r0, r4 263 ldrcc r0, .Lheadroom 264 addcc r0, r0, pc 265 cmpcc r4, r0 266 orrcc r4, r4, #1 @ remember we skipped cache_on 267 blcs cache_on 268 269restart: adr r0, LC1 270 ldr sp, [r0] 271 ldr r6, [r0, #4] 272 add sp, sp, r0 273 add r6, r6, r0 274 275 get_inflated_image_size r9, r10, lr 276 277#ifndef CONFIG_ZBOOT_ROM 278 /* malloc space is above the relocated stack (64k max) */ 279 add r10, sp, #0x10000 280#else 281 /* 282 * With ZBOOT_ROM the bss/stack is non relocatable, 283 * but someone could still run this code from RAM, 284 * in which case our reference is _edata. 285 */ 286 mov r10, r6 287#endif 288 289 mov r5, #0 @ init dtb size to 0 290#ifdef CONFIG_ARM_APPENDED_DTB 291/* 292 * r4 = final kernel address (possibly with LSB set) 293 * r5 = appended dtb size (still unknown) 294 * r6 = _edata 295 * r7 = architecture ID 296 * r8 = atags/device tree pointer 297 * r9 = size of decompressed image 298 * r10 = end of this image, including bss/stack/malloc space if non XIP 299 * sp = stack pointer 300 * 301 * if there are device trees (dtb) appended to zImage, advance r10 so that the 302 * dtb data will get relocated along with the kernel if necessary. 303 */ 304 305 ldr lr, [r6, #0] 306#ifndef __ARMEB__ 307 ldr r1, =0xedfe0dd0 @ sig is 0xd00dfeed big endian 308#else 309 ldr r1, =0xd00dfeed 310#endif 311 cmp lr, r1 312 bne dtb_check_done @ not found 313 314#ifdef CONFIG_ARM_ATAG_DTB_COMPAT 315 /* 316 * OK... Let's do some funky business here. 317 * If we do have a DTB appended to zImage, and we do have 318 * an ATAG list around, we want the later to be translated 319 * and folded into the former here. No GOT fixup has occurred 320 * yet, but none of the code we're about to call uses any 321 * global variable. 322 */ 323 324 /* Get the initial DTB size */ 325 ldr r5, [r6, #4] 326#ifndef __ARMEB__ 327 /* convert to little endian */ 328 eor r1, r5, r5, ror #16 329 bic r1, r1, #0x00ff0000 330 mov r5, r5, ror #8 331 eor r5, r5, r1, lsr #8 332#endif 333 /* 50% DTB growth should be good enough */ 334 add r5, r5, r5, lsr #1 335 /* preserve 64-bit alignment */ 336 add r5, r5, #7 337 bic r5, r5, #7 338 /* clamp to 32KB min and 1MB max */ 339 cmp r5, #(1 << 15) 340 movlo r5, #(1 << 15) 341 cmp r5, #(1 << 20) 342 movhi r5, #(1 << 20) 343 /* temporarily relocate the stack past the DTB work space */ 344 add sp, sp, r5 345 346 mov r0, r8 347 mov r1, r6 348 mov r2, r5 349 bl atags_to_fdt 350 351 /* 352 * If returned value is 1, there is no ATAG at the location 353 * pointed by r8. Try the typical 0x100 offset from start 354 * of RAM and hope for the best. 355 */ 356 cmp r0, #1 357 sub r0, r4, #TEXT_OFFSET 358 bic r0, r0, #1 359 add r0, r0, #0x100 360 mov r1, r6 361 mov r2, r5 362 bleq atags_to_fdt 363 364 sub sp, sp, r5 365#endif 366 367 mov r8, r6 @ use the appended device tree 368 369 /* 370 * Make sure that the DTB doesn't end up in the final 371 * kernel's .bss area. To do so, we adjust the decompressed 372 * kernel size to compensate if that .bss size is larger 373 * than the relocated code. 374 */ 375 ldr r5, =_kernel_bss_size 376 adr r1, wont_overwrite 377 sub r1, r6, r1 378 subs r1, r5, r1 379 addhi r9, r9, r1 380 381 /* Get the current DTB size */ 382 ldr r5, [r6, #4] 383#ifndef __ARMEB__ 384 /* convert r5 (dtb size) to little endian */ 385 eor r1, r5, r5, ror #16 386 bic r1, r1, #0x00ff0000 387 mov r5, r5, ror #8 388 eor r5, r5, r1, lsr #8 389#endif 390 391 /* preserve 64-bit alignment */ 392 add r5, r5, #7 393 bic r5, r5, #7 394 395 /* relocate some pointers past the appended dtb */ 396 add r6, r6, r5 397 add r10, r10, r5 398 add sp, sp, r5 399dtb_check_done: 400#endif 401 402/* 403 * Check to see if we will overwrite ourselves. 404 * r4 = final kernel address (possibly with LSB set) 405 * r9 = size of decompressed image 406 * r10 = end of this image, including bss/stack/malloc space if non XIP 407 * We basically want: 408 * r4 - 16k page directory >= r10 -> OK 409 * r4 + image length <= address of wont_overwrite -> OK 410 * Note: the possible LSB in r4 is harmless here. 411 */ 412 add r10, r10, #16384 413 cmp r4, r10 414 bhs wont_overwrite 415 add r10, r4, r9 416 adr r9, wont_overwrite 417 cmp r10, r9 418 bls wont_overwrite 419 420/* 421 * Relocate ourselves past the end of the decompressed kernel. 422 * r6 = _edata 423 * r10 = end of the decompressed kernel 424 * Because we always copy ahead, we need to do it from the end and go 425 * backward in case the source and destination overlap. 426 */ 427 /* 428 * Bump to the next 256-byte boundary with the size of 429 * the relocation code added. This avoids overwriting 430 * ourself when the offset is small. 431 */ 432 add r10, r10, #((reloc_code_end - restart + 256) & ~255) 433 bic r10, r10, #255 434 435 /* Get start of code we want to copy and align it down. */ 436 adr r5, restart 437 bic r5, r5, #31 438 439/* Relocate the hyp vector base if necessary */ 440#ifdef CONFIG_ARM_VIRT_EXT 441 mrs r0, spsr 442 and r0, r0, #MODE_MASK 443 cmp r0, #HYP_MODE 444 bne 1f 445 446 /* 447 * Compute the address of the hyp vectors after relocation. 448 * This requires some arithmetic since we cannot directly 449 * reference __hyp_stub_vectors in a PC-relative way. 450 * Call __hyp_set_vectors with the new address so that we 451 * can HVC again after the copy. 452 */ 4530: adr r0, 0b 454 movw r1, #:lower16:__hyp_stub_vectors - 0b 455 movt r1, #:upper16:__hyp_stub_vectors - 0b 456 add r0, r0, r1 457 sub r0, r0, r5 458 add r0, r0, r10 459 bl __hyp_set_vectors 4601: 461#endif 462 463 sub r9, r6, r5 @ size to copy 464 add r9, r9, #31 @ rounded up to a multiple 465 bic r9, r9, #31 @ ... of 32 bytes 466 add r6, r9, r5 467 add r9, r9, r10 468 469#ifdef DEBUG 470 sub r10, r6, r5 471 sub r10, r9, r10 472 /* 473 * We are about to copy the kernel to a new memory area. 474 * The boundaries of the new memory area can be found in 475 * r10 and r9, whilst r5 and r6 contain the boundaries 476 * of the memory we are going to copy. 477 * Calling dbgkc will help with the printing of this 478 * information. 479 */ 480 dbgkc r5, r6, r10, r9 481#endif 482 4831: ldmdb r6!, {r0 - r3, r10 - r12, lr} 484 cmp r6, r5 485 stmdb r9!, {r0 - r3, r10 - r12, lr} 486 bhi 1b 487 488 /* Preserve offset to relocated code. */ 489 sub r6, r9, r6 490 491 mov r0, r9 @ start of relocated zImage 492 add r1, sp, r6 @ end of relocated zImage 493 bl cache_clean_flush 494 495 badr r0, restart 496 add r0, r0, r6 497 mov pc, r0 498 499wont_overwrite: 500 adr r0, LC0 501 ldmia r0, {r1, r2, r3, r11, r12} 502 sub r0, r0, r1 @ calculate the delta offset 503 504/* 505 * If delta is zero, we are running at the address we were linked at. 506 * r0 = delta 507 * r2 = BSS start 508 * r3 = BSS end 509 * r4 = kernel execution address (possibly with LSB set) 510 * r5 = appended dtb size (0 if not present) 511 * r7 = architecture ID 512 * r8 = atags pointer 513 * r11 = GOT start 514 * r12 = GOT end 515 * sp = stack pointer 516 */ 517 orrs r1, r0, r5 518 beq not_relocated 519 520 add r11, r11, r0 521 add r12, r12, r0 522 523#ifndef CONFIG_ZBOOT_ROM 524 /* 525 * If we're running fully PIC === CONFIG_ZBOOT_ROM = n, 526 * we need to fix up pointers into the BSS region. 527 * Note that the stack pointer has already been fixed up. 528 */ 529 add r2, r2, r0 530 add r3, r3, r0 531 532 /* 533 * Relocate all entries in the GOT table. 534 * Bump bss entries to _edata + dtb size 535 */ 5361: ldr r1, [r11, #0] @ relocate entries in the GOT 537 add r1, r1, r0 @ This fixes up C references 538 cmp r1, r2 @ if entry >= bss_start && 539 cmphs r3, r1 @ bss_end > entry 540 addhi r1, r1, r5 @ entry += dtb size 541 str r1, [r11], #4 @ next entry 542 cmp r11, r12 543 blo 1b 544 545 /* bump our bss pointers too */ 546 add r2, r2, r5 547 add r3, r3, r5 548 549#else 550 551 /* 552 * Relocate entries in the GOT table. We only relocate 553 * the entries that are outside the (relocated) BSS region. 554 */ 5551: ldr r1, [r11, #0] @ relocate entries in the GOT 556 cmp r1, r2 @ entry < bss_start || 557 cmphs r3, r1 @ _end < entry 558 addlo r1, r1, r0 @ table. This fixes up the 559 str r1, [r11], #4 @ C references. 560 cmp r11, r12 561 blo 1b 562#endif 563 564not_relocated: mov r0, #0 5651: str r0, [r2], #4 @ clear bss 566 str r0, [r2], #4 567 str r0, [r2], #4 568 str r0, [r2], #4 569 cmp r2, r3 570 blo 1b 571 572 /* 573 * Did we skip the cache setup earlier? 574 * That is indicated by the LSB in r4. 575 * Do it now if so. 576 */ 577 tst r4, #1 578 bic r4, r4, #1 579 blne cache_on 580 581/* 582 * The C runtime environment should now be setup sufficiently. 583 * Set up some pointers, and start decompressing. 584 * r4 = kernel execution address 585 * r7 = architecture ID 586 * r8 = atags pointer 587 */ 588 mov r0, r4 589 mov r1, sp @ malloc space above stack 590 add r2, sp, #0x10000 @ 64k max 591 mov r3, r7 592 bl decompress_kernel 593 594 get_inflated_image_size r1, r2, r3 595 596 mov r0, r4 @ start of inflated image 597 add r1, r1, r0 @ end of inflated image 598 bl cache_clean_flush 599 bl cache_off 600 601#ifdef CONFIG_ARM_VIRT_EXT 602 mrs r0, spsr @ Get saved CPU boot mode 603 and r0, r0, #MODE_MASK 604 cmp r0, #HYP_MODE @ if not booted in HYP mode... 605 bne __enter_kernel @ boot kernel directly 606 607 adr r12, .L__hyp_reentry_vectors_offset 608 ldr r0, [r12] 609 add r0, r0, r12 610 611 bl __hyp_set_vectors 612 __HVC(0) @ otherwise bounce to hyp mode 613 614 b . @ should never be reached 615 616 .align 2 617.L__hyp_reentry_vectors_offset: .long __hyp_reentry_vectors - . 618#else 619 b __enter_kernel 620#endif 621 622 .align 2 623 .type LC0, #object 624LC0: .word LC0 @ r1 625 .word __bss_start @ r2 626 .word _end @ r3 627 .word _got_start @ r11 628 .word _got_end @ ip 629 .size LC0, . - LC0 630 631 .type LC1, #object 632LC1: .word .L_user_stack_end - LC1 @ sp 633 .word _edata - LC1 @ r6 634 .size LC1, . - LC1 635 636.Lheadroom: 637 .word _end - restart + 16384 + 1024*1024 638 639.Linflated_image_size_offset: 640 .long (input_data_end - 4) - . 641 642#ifdef CONFIG_ARCH_RPC 643 .globl params 644params: ldr r0, =0x10000100 @ params_phys for RPC 645 mov pc, lr 646 .ltorg 647 .align 648#endif 649 650/* 651 * dcache_line_size - get the minimum D-cache line size from the CTR register 652 * on ARMv7. 653 */ 654 .macro dcache_line_size, reg, tmp 655#ifdef CONFIG_CPU_V7M 656 movw \tmp, #:lower16:BASEADDR_V7M_SCB + V7M_SCB_CTR 657 movt \tmp, #:upper16:BASEADDR_V7M_SCB + V7M_SCB_CTR 658 ldr \tmp, [\tmp] 659#else 660 mrc p15, 0, \tmp, c0, c0, 1 @ read ctr 661#endif 662 lsr \tmp, \tmp, #16 663 and \tmp, \tmp, #0xf @ cache line size encoding 664 mov \reg, #4 @ bytes per word 665 mov \reg, \reg, lsl \tmp @ actual cache line size 666 .endm 667 668/* 669 * Turn on the cache. We need to setup some page tables so that we 670 * can have both the I and D caches on. 671 * 672 * We place the page tables 16k down from the kernel execution address, 673 * and we hope that nothing else is using it. If we're using it, we 674 * will go pop! 675 * 676 * On entry, 677 * r4 = kernel execution address 678 * r7 = architecture number 679 * r8 = atags pointer 680 * On exit, 681 * r0, r1, r2, r3, r9, r10, r12 corrupted 682 * This routine must preserve: 683 * r4, r7, r8 684 */ 685 .align 5 686cache_on: mov r3, #8 @ cache_on function 687 b call_cache_fn 688 689/* 690 * Initialize the highest priority protection region, PR7 691 * to cover all 32bit address and cacheable and bufferable. 692 */ 693__armv4_mpu_cache_on: 694 mov r0, #0x3f @ 4G, the whole 695 mcr p15, 0, r0, c6, c7, 0 @ PR7 Area Setting 696 mcr p15, 0, r0, c6, c7, 1 697 698 mov r0, #0x80 @ PR7 699 mcr p15, 0, r0, c2, c0, 0 @ D-cache on 700 mcr p15, 0, r0, c2, c0, 1 @ I-cache on 701 mcr p15, 0, r0, c3, c0, 0 @ write-buffer on 702 703 mov r0, #0xc000 704 mcr p15, 0, r0, c5, c0, 1 @ I-access permission 705 mcr p15, 0, r0, c5, c0, 0 @ D-access permission 706 707 mov r0, #0 708 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer 709 mcr p15, 0, r0, c7, c5, 0 @ flush(inval) I-Cache 710 mcr p15, 0, r0, c7, c6, 0 @ flush(inval) D-Cache 711 mrc p15, 0, r0, c1, c0, 0 @ read control reg 712 @ ...I .... ..D. WC.M 713 orr r0, r0, #0x002d @ .... .... ..1. 11.1 714 orr r0, r0, #0x1000 @ ...1 .... .... .... 715 716 mcr p15, 0, r0, c1, c0, 0 @ write control reg 717 718 mov r0, #0 719 mcr p15, 0, r0, c7, c5, 0 @ flush(inval) I-Cache 720 mcr p15, 0, r0, c7, c6, 0 @ flush(inval) D-Cache 721 mov pc, lr 722 723__armv3_mpu_cache_on: 724 mov r0, #0x3f @ 4G, the whole 725 mcr p15, 0, r0, c6, c7, 0 @ PR7 Area Setting 726 727 mov r0, #0x80 @ PR7 728 mcr p15, 0, r0, c2, c0, 0 @ cache on 729 mcr p15, 0, r0, c3, c0, 0 @ write-buffer on 730 731 mov r0, #0xc000 732 mcr p15, 0, r0, c5, c0, 0 @ access permission 733 734 mov r0, #0 735 mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3 736 /* 737 * ?? ARMv3 MMU does not allow reading the control register, 738 * does this really work on ARMv3 MPU? 739 */ 740 mrc p15, 0, r0, c1, c0, 0 @ read control reg 741 @ .... .... .... WC.M 742 orr r0, r0, #0x000d @ .... .... .... 11.1 743 /* ?? this overwrites the value constructed above? */ 744 mov r0, #0 745 mcr p15, 0, r0, c1, c0, 0 @ write control reg 746 747 /* ?? invalidate for the second time? */ 748 mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3 749 mov pc, lr 750 751#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH 752#define CB_BITS 0x08 753#else 754#define CB_BITS 0x0c 755#endif 756 757__setup_mmu: sub r3, r4, #16384 @ Page directory size 758 bic r3, r3, #0xff @ Align the pointer 759 bic r3, r3, #0x3f00 760/* 761 * Initialise the page tables, turning on the cacheable and bufferable 762 * bits for the RAM area only. 763 */ 764 mov r0, r3 765 mov r9, r0, lsr #18 766 mov r9, r9, lsl #18 @ start of RAM 767 add r10, r9, #0x10000000 @ a reasonable RAM size 768 mov r1, #0x12 @ XN|U + section mapping 769 orr r1, r1, #3 << 10 @ AP=11 770 add r2, r3, #16384 7711: cmp r1, r9 @ if virt > start of RAM 772 cmphs r10, r1 @ && end of RAM > virt 773 bic r1, r1, #0x1c @ clear XN|U + C + B 774 orrlo r1, r1, #0x10 @ Set XN|U for non-RAM 775 orrhs r1, r1, r6 @ set RAM section settings 776 str r1, [r0], #4 @ 1:1 mapping 777 add r1, r1, #1048576 778 teq r0, r2 779 bne 1b 780/* 781 * If ever we are running from Flash, then we surely want the cache 782 * to be enabled also for our execution instance... We map 2MB of it 783 * so there is no map overlap problem for up to 1 MB compressed kernel. 784 * If the execution is in RAM then we would only be duplicating the above. 785 */ 786 orr r1, r6, #0x04 @ ensure B is set for this 787 orr r1, r1, #3 << 10 788 mov r2, pc 789 mov r2, r2, lsr #20 790 orr r1, r1, r2, lsl #20 791 add r0, r3, r2, lsl #2 792 str r1, [r0], #4 793 add r1, r1, #1048576 794 str r1, [r0] 795 mov pc, lr 796ENDPROC(__setup_mmu) 797 798@ Enable unaligned access on v6, to allow better code generation 799@ for the decompressor C code: 800__armv6_mmu_cache_on: 801 mrc p15, 0, r0, c1, c0, 0 @ read SCTLR 802 bic r0, r0, #2 @ A (no unaligned access fault) 803 orr r0, r0, #1 << 22 @ U (v6 unaligned access model) 804 mcr p15, 0, r0, c1, c0, 0 @ write SCTLR 805 b __armv4_mmu_cache_on 806 807__arm926ejs_mmu_cache_on: 808#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH 809 mov r0, #4 @ put dcache in WT mode 810 mcr p15, 7, r0, c15, c0, 0 811#endif 812 813__armv4_mmu_cache_on: 814 mov r12, lr 815#ifdef CONFIG_MMU 816 mov r6, #CB_BITS | 0x12 @ U 817 bl __setup_mmu 818 mov r0, #0 819 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer 820 mcr p15, 0, r0, c8, c7, 0 @ flush I,D TLBs 821 mrc p15, 0, r0, c1, c0, 0 @ read control reg 822 orr r0, r0, #0x5000 @ I-cache enable, RR cache replacement 823 orr r0, r0, #0x0030 824 ARM_BE8( orr r0, r0, #1 << 25 ) @ big-endian page tables 825 bl __common_mmu_cache_on 826 mov r0, #0 827 mcr p15, 0, r0, c8, c7, 0 @ flush I,D TLBs 828#endif 829 mov pc, r12 830 831__armv7_mmu_cache_on: 832 enable_cp15_barriers r11 833 mov r12, lr 834#ifdef CONFIG_MMU 835 mrc p15, 0, r11, c0, c1, 4 @ read ID_MMFR0 836 tst r11, #0xf @ VMSA 837 movne r6, #CB_BITS | 0x02 @ !XN 838 blne __setup_mmu 839 mov r0, #0 840 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer 841 tst r11, #0xf @ VMSA 842 mcrne p15, 0, r0, c8, c7, 0 @ flush I,D TLBs 843#endif 844 mrc p15, 0, r0, c1, c0, 0 @ read control reg 845 bic r0, r0, #1 << 28 @ clear SCTLR.TRE 846 orr r0, r0, #0x5000 @ I-cache enable, RR cache replacement 847 orr r0, r0, #0x003c @ write buffer 848 bic r0, r0, #2 @ A (no unaligned access fault) 849 orr r0, r0, #1 << 22 @ U (v6 unaligned access model) 850 @ (needed for ARM1176) 851#ifdef CONFIG_MMU 852 ARM_BE8( orr r0, r0, #1 << 25 ) @ big-endian page tables 853 mrcne p15, 0, r6, c2, c0, 2 @ read ttb control reg 854 orrne r0, r0, #1 @ MMU enabled 855 movne r1, #0xfffffffd @ domain 0 = client 856 bic r6, r6, #1 << 31 @ 32-bit translation system 857 bic r6, r6, #(7 << 0) | (1 << 4) @ use only ttbr0 858 mcrne p15, 0, r3, c2, c0, 0 @ load page table pointer 859 mcrne p15, 0, r1, c3, c0, 0 @ load domain access control 860 mcrne p15, 0, r6, c2, c0, 2 @ load ttb control 861#endif 862 mcr p15, 0, r0, c7, c5, 4 @ ISB 863 mcr p15, 0, r0, c1, c0, 0 @ load control register 864 mrc p15, 0, r0, c1, c0, 0 @ and read it back 865 mov r0, #0 866 mcr p15, 0, r0, c7, c5, 4 @ ISB 867 mov pc, r12 868 869__fa526_cache_on: 870 mov r12, lr 871 mov r6, #CB_BITS | 0x12 @ U 872 bl __setup_mmu 873 mov r0, #0 874 mcr p15, 0, r0, c7, c7, 0 @ Invalidate whole cache 875 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer 876 mcr p15, 0, r0, c8, c7, 0 @ flush UTLB 877 mrc p15, 0, r0, c1, c0, 0 @ read control reg 878 orr r0, r0, #0x1000 @ I-cache enable 879 bl __common_mmu_cache_on 880 mov r0, #0 881 mcr p15, 0, r0, c8, c7, 0 @ flush UTLB 882 mov pc, r12 883 884__common_mmu_cache_on: 885#ifndef CONFIG_THUMB2_KERNEL 886#ifndef DEBUG 887 orr r0, r0, #0x000d @ Write buffer, mmu 888#endif 889 mov r1, #-1 890 mcr p15, 0, r3, c2, c0, 0 @ load page table pointer 891 mcr p15, 0, r1, c3, c0, 0 @ load domain access control 892 b 1f 893 .align 5 @ cache line aligned 8941: mcr p15, 0, r0, c1, c0, 0 @ load control register 895 mrc p15, 0, r0, c1, c0, 0 @ and read it back to 896 sub pc, lr, r0, lsr #32 @ properly flush pipeline 897#endif 898 899#define PROC_ENTRY_SIZE (4*5) 900 901/* 902 * Here follow the relocatable cache support functions for the 903 * various processors. This is a generic hook for locating an 904 * entry and jumping to an instruction at the specified offset 905 * from the start of the block. Please note this is all position 906 * independent code. 907 * 908 * r1 = corrupted 909 * r2 = corrupted 910 * r3 = block offset 911 * r9 = corrupted 912 * r12 = corrupted 913 */ 914 915call_cache_fn: adr r12, proc_types 916#ifdef CONFIG_CPU_CP15 917 mrc p15, 0, r9, c0, c0 @ get processor ID 918#elif defined(CONFIG_CPU_V7M) 919 /* 920 * On v7-M the processor id is located in the V7M_SCB_CPUID 921 * register, but as cache handling is IMPLEMENTATION DEFINED on 922 * v7-M (if existant at all) we just return early here. 923 * If V7M_SCB_CPUID were used the cpu ID functions (i.e. 924 * __armv7_mmu_cache_{on,off,flush}) would be selected which 925 * use cp15 registers that are not implemented on v7-M. 926 */ 927 bx lr 928#else 929 ldr r9, =CONFIG_PROCESSOR_ID 930#endif 9311: ldr r1, [r12, #0] @ get value 932 ldr r2, [r12, #4] @ get mask 933 eor r1, r1, r9 @ (real ^ match) 934 tst r1, r2 @ & mask 935 ARM( addeq pc, r12, r3 ) @ call cache function 936 THUMB( addeq r12, r3 ) 937 THUMB( moveq pc, r12 ) @ call cache function 938 add r12, r12, #PROC_ENTRY_SIZE 939 b 1b 940 941/* 942 * Table for cache operations. This is basically: 943 * - CPU ID match 944 * - CPU ID mask 945 * - 'cache on' method instruction 946 * - 'cache off' method instruction 947 * - 'cache flush' method instruction 948 * 949 * We match an entry using: ((real_id ^ match) & mask) == 0 950 * 951 * Writethrough caches generally only need 'on' and 'off' 952 * methods. Writeback caches _must_ have the flush method 953 * defined. 954 */ 955 .align 2 956 .type proc_types,#object 957proc_types: 958 .word 0x41000000 @ old ARM ID 959 .word 0xff00f000 960 mov pc, lr 961 THUMB( nop ) 962 mov pc, lr 963 THUMB( nop ) 964 mov pc, lr 965 THUMB( nop ) 966 967 .word 0x41007000 @ ARM7/710 968 .word 0xfff8fe00 969 mov pc, lr 970 THUMB( nop ) 971 mov pc, lr 972 THUMB( nop ) 973 mov pc, lr 974 THUMB( nop ) 975 976 .word 0x41807200 @ ARM720T (writethrough) 977 .word 0xffffff00 978 W(b) __armv4_mmu_cache_on 979 W(b) __armv4_mmu_cache_off 980 mov pc, lr 981 THUMB( nop ) 982 983 .word 0x41007400 @ ARM74x 984 .word 0xff00ff00 985 W(b) __armv3_mpu_cache_on 986 W(b) __armv3_mpu_cache_off 987 W(b) __armv3_mpu_cache_flush 988 989 .word 0x41009400 @ ARM94x 990 .word 0xff00ff00 991 W(b) __armv4_mpu_cache_on 992 W(b) __armv4_mpu_cache_off 993 W(b) __armv4_mpu_cache_flush 994 995 .word 0x41069260 @ ARM926EJ-S (v5TEJ) 996 .word 0xff0ffff0 997 W(b) __arm926ejs_mmu_cache_on 998 W(b) __armv4_mmu_cache_off 999 W(b) __armv5tej_mmu_cache_flush 1000 1001 .word 0x00007000 @ ARM7 IDs 1002 .word 0x0000f000 1003 mov pc, lr 1004 THUMB( nop ) 1005 mov pc, lr 1006 THUMB( nop ) 1007 mov pc, lr 1008 THUMB( nop ) 1009 1010 @ Everything from here on will be the new ID system. 1011 1012 .word 0x4401a100 @ sa110 / sa1100 1013 .word 0xffffffe0 1014 W(b) __armv4_mmu_cache_on 1015 W(b) __armv4_mmu_cache_off 1016 W(b) __armv4_mmu_cache_flush 1017 1018 .word 0x6901b110 @ sa1110 1019 .word 0xfffffff0 1020 W(b) __armv4_mmu_cache_on 1021 W(b) __armv4_mmu_cache_off 1022 W(b) __armv4_mmu_cache_flush 1023 1024 .word 0x56056900 1025 .word 0xffffff00 @ PXA9xx 1026 W(b) __armv4_mmu_cache_on 1027 W(b) __armv4_mmu_cache_off 1028 W(b) __armv4_mmu_cache_flush 1029 1030 .word 0x56158000 @ PXA168 1031 .word 0xfffff000 1032 W(b) __armv4_mmu_cache_on 1033 W(b) __armv4_mmu_cache_off 1034 W(b) __armv5tej_mmu_cache_flush 1035 1036 .word 0x56050000 @ Feroceon 1037 .word 0xff0f0000 1038 W(b) __armv4_mmu_cache_on 1039 W(b) __armv4_mmu_cache_off 1040 W(b) __armv5tej_mmu_cache_flush 1041 1042#ifdef CONFIG_CPU_FEROCEON_OLD_ID 1043 /* this conflicts with the standard ARMv5TE entry */ 1044 .long 0x41009260 @ Old Feroceon 1045 .long 0xff00fff0 1046 b __armv4_mmu_cache_on 1047 b __armv4_mmu_cache_off 1048 b __armv5tej_mmu_cache_flush 1049#endif 1050 1051 .word 0x66015261 @ FA526 1052 .word 0xff01fff1 1053 W(b) __fa526_cache_on 1054 W(b) __armv4_mmu_cache_off 1055 W(b) __fa526_cache_flush 1056 1057 @ These match on the architecture ID 1058 1059 .word 0x00020000 @ ARMv4T 1060 .word 0x000f0000 1061 W(b) __armv4_mmu_cache_on 1062 W(b) __armv4_mmu_cache_off 1063 W(b) __armv4_mmu_cache_flush 1064 1065 .word 0x00050000 @ ARMv5TE 1066 .word 0x000f0000 1067 W(b) __armv4_mmu_cache_on 1068 W(b) __armv4_mmu_cache_off 1069 W(b) __armv4_mmu_cache_flush 1070 1071 .word 0x00060000 @ ARMv5TEJ 1072 .word 0x000f0000 1073 W(b) __armv4_mmu_cache_on 1074 W(b) __armv4_mmu_cache_off 1075 W(b) __armv5tej_mmu_cache_flush 1076 1077 .word 0x0007b000 @ ARMv6 1078 .word 0x000ff000 1079 W(b) __armv6_mmu_cache_on 1080 W(b) __armv4_mmu_cache_off 1081 W(b) __armv6_mmu_cache_flush 1082 1083 .word 0x000f0000 @ new CPU Id 1084 .word 0x000f0000 1085 W(b) __armv7_mmu_cache_on 1086 W(b) __armv7_mmu_cache_off 1087 W(b) __armv7_mmu_cache_flush 1088 1089 .word 0 @ unrecognised type 1090 .word 0 1091 mov pc, lr 1092 THUMB( nop ) 1093 mov pc, lr 1094 THUMB( nop ) 1095 mov pc, lr 1096 THUMB( nop ) 1097 1098 .size proc_types, . - proc_types 1099 1100 /* 1101 * If you get a "non-constant expression in ".if" statement" 1102 * error from the assembler on this line, check that you have 1103 * not accidentally written a "b" instruction where you should 1104 * have written W(b). 1105 */ 1106 .if (. - proc_types) % PROC_ENTRY_SIZE != 0 1107 .error "The size of one or more proc_types entries is wrong." 1108 .endif 1109 1110/* 1111 * Turn off the Cache and MMU. ARMv3 does not support 1112 * reading the control register, but ARMv4 does. 1113 * 1114 * On exit, 1115 * r0, r1, r2, r3, r9, r12 corrupted 1116 * This routine must preserve: 1117 * r4, r7, r8 1118 */ 1119 .align 5 1120cache_off: mov r3, #12 @ cache_off function 1121 b call_cache_fn 1122 1123__armv4_mpu_cache_off: 1124 mrc p15, 0, r0, c1, c0 1125 bic r0, r0, #0x000d 1126 mcr p15, 0, r0, c1, c0 @ turn MPU and cache off 1127 mov r0, #0 1128 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer 1129 mcr p15, 0, r0, c7, c6, 0 @ flush D-Cache 1130 mcr p15, 0, r0, c7, c5, 0 @ flush I-Cache 1131 mov pc, lr 1132 1133__armv3_mpu_cache_off: 1134 mrc p15, 0, r0, c1, c0 1135 bic r0, r0, #0x000d 1136 mcr p15, 0, r0, c1, c0, 0 @ turn MPU and cache off 1137 mov r0, #0 1138 mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3 1139 mov pc, lr 1140 1141__armv4_mmu_cache_off: 1142#ifdef CONFIG_MMU 1143 mrc p15, 0, r0, c1, c0 1144 bic r0, r0, #0x000d 1145 mcr p15, 0, r0, c1, c0 @ turn MMU and cache off 1146 mov r0, #0 1147 mcr p15, 0, r0, c7, c7 @ invalidate whole cache v4 1148 mcr p15, 0, r0, c8, c7 @ invalidate whole TLB v4 1149#endif 1150 mov pc, lr 1151 1152__armv7_mmu_cache_off: 1153 mrc p15, 0, r0, c1, c0 1154#ifdef CONFIG_MMU 1155 bic r0, r0, #0x000d 1156#else 1157 bic r0, r0, #0x000c 1158#endif 1159 mcr p15, 0, r0, c1, c0 @ turn MMU and cache off 1160 mov r0, #0 1161#ifdef CONFIG_MMU 1162 mcr p15, 0, r0, c8, c7, 0 @ invalidate whole TLB 1163#endif 1164 mcr p15, 0, r0, c7, c5, 6 @ invalidate BTC 1165 mcr p15, 0, r0, c7, c10, 4 @ DSB 1166 mcr p15, 0, r0, c7, c5, 4 @ ISB 1167 mov pc, lr 1168 1169/* 1170 * Clean and flush the cache to maintain consistency. 1171 * 1172 * On entry, 1173 * r0 = start address 1174 * r1 = end address (exclusive) 1175 * On exit, 1176 * r1, r2, r3, r9, r10, r11, r12 corrupted 1177 * This routine must preserve: 1178 * r4, r6, r7, r8 1179 */ 1180 .align 5 1181cache_clean_flush: 1182 mov r3, #16 1183 mov r11, r1 1184 b call_cache_fn 1185 1186__armv4_mpu_cache_flush: 1187 tst r4, #1 1188 movne pc, lr 1189 mov r2, #1 1190 mov r3, #0 1191 mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache 1192 mov r1, #7 << 5 @ 8 segments 11931: orr r3, r1, #63 << 26 @ 64 entries 11942: mcr p15, 0, r3, c7, c14, 2 @ clean & invalidate D index 1195 subs r3, r3, #1 << 26 1196 bcs 2b @ entries 63 to 0 1197 subs r1, r1, #1 << 5 1198 bcs 1b @ segments 7 to 0 1199 1200 teq r2, #0 1201 mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache 1202 mcr p15, 0, ip, c7, c10, 4 @ drain WB 1203 mov pc, lr 1204 1205__fa526_cache_flush: 1206 tst r4, #1 1207 movne pc, lr 1208 mov r1, #0 1209 mcr p15, 0, r1, c7, c14, 0 @ clean and invalidate D cache 1210 mcr p15, 0, r1, c7, c5, 0 @ flush I cache 1211 mcr p15, 0, r1, c7, c10, 4 @ drain WB 1212 mov pc, lr 1213 1214__armv6_mmu_cache_flush: 1215 mov r1, #0 1216 tst r4, #1 1217 mcreq p15, 0, r1, c7, c14, 0 @ clean+invalidate D 1218 mcr p15, 0, r1, c7, c5, 0 @ invalidate I+BTB 1219 mcreq p15, 0, r1, c7, c15, 0 @ clean+invalidate unified 1220 mcr p15, 0, r1, c7, c10, 4 @ drain WB 1221 mov pc, lr 1222 1223__armv7_mmu_cache_flush: 1224 enable_cp15_barriers r10 1225 tst r4, #1 1226 bne iflush 1227 mrc p15, 0, r10, c0, c1, 5 @ read ID_MMFR1 1228 tst r10, #0xf << 16 @ hierarchical cache (ARMv7) 1229 mov r10, #0 1230 beq hierarchical 1231 mcr p15, 0, r10, c7, c14, 0 @ clean+invalidate D 1232 b iflush 1233hierarchical: 1234 dcache_line_size r1, r2 @ r1 := dcache min line size 1235 sub r2, r1, #1 @ r2 := line size mask 1236 bic r0, r0, r2 @ round down start to line size 1237 sub r11, r11, #1 @ end address is exclusive 1238 bic r11, r11, r2 @ round down end to line size 12390: cmp r0, r11 @ finished? 1240 bgt iflush 1241 mcr p15, 0, r0, c7, c14, 1 @ Dcache clean/invalidate by VA 1242 add r0, r0, r1 1243 b 0b 1244iflush: 1245 mcr p15, 0, r10, c7, c10, 4 @ DSB 1246 mcr p15, 0, r10, c7, c5, 0 @ invalidate I+BTB 1247 mcr p15, 0, r10, c7, c10, 4 @ DSB 1248 mcr p15, 0, r10, c7, c5, 4 @ ISB 1249 mov pc, lr 1250 1251__armv5tej_mmu_cache_flush: 1252 tst r4, #1 1253 movne pc, lr 12541: mrc p15, 0, APSR_nzcv, c7, c14, 3 @ test,clean,invalidate D cache 1255 bne 1b 1256 mcr p15, 0, r0, c7, c5, 0 @ flush I cache 1257 mcr p15, 0, r0, c7, c10, 4 @ drain WB 1258 mov pc, lr 1259 1260__armv4_mmu_cache_flush: 1261 tst r4, #1 1262 movne pc, lr 1263 mov r2, #64*1024 @ default: 32K dcache size (*2) 1264 mov r11, #32 @ default: 32 byte line size 1265 mrc p15, 0, r3, c0, c0, 1 @ read cache type 1266 teq r3, r9 @ cache ID register present? 1267 beq no_cache_id 1268 mov r1, r3, lsr #18 1269 and r1, r1, #7 1270 mov r2, #1024 1271 mov r2, r2, lsl r1 @ base dcache size *2 1272 tst r3, #1 << 14 @ test M bit 1273 addne r2, r2, r2, lsr #1 @ +1/2 size if M == 1 1274 mov r3, r3, lsr #12 1275 and r3, r3, #3 1276 mov r11, #8 1277 mov r11, r11, lsl r3 @ cache line size in bytes 1278no_cache_id: 1279 mov r1, pc 1280 bic r1, r1, #63 @ align to longest cache line 1281 add r2, r1, r2 12821: 1283 ARM( ldr r3, [r1], r11 ) @ s/w flush D cache 1284 THUMB( ldr r3, [r1] ) @ s/w flush D cache 1285 THUMB( add r1, r1, r11 ) 1286 teq r1, r2 1287 bne 1b 1288 1289 mcr p15, 0, r1, c7, c5, 0 @ flush I cache 1290 mcr p15, 0, r1, c7, c6, 0 @ flush D cache 1291 mcr p15, 0, r1, c7, c10, 4 @ drain WB 1292 mov pc, lr 1293 1294__armv3_mmu_cache_flush: 1295__armv3_mpu_cache_flush: 1296 tst r4, #1 1297 movne pc, lr 1298 mov r1, #0 1299 mcr p15, 0, r1, c7, c0, 0 @ invalidate whole cache v3 1300 mov pc, lr 1301 1302/* 1303 * Various debugging routines for printing hex characters and 1304 * memory, which again must be relocatable. 1305 */ 1306#ifdef DEBUG 1307 .align 2 1308 .type phexbuf,#object 1309phexbuf: .space 12 1310 .size phexbuf, . - phexbuf 1311 1312@ phex corrupts {r0, r1, r2, r3} 1313phex: adr r3, phexbuf 1314 mov r2, #0 1315 strb r2, [r3, r1] 13161: subs r1, r1, #1 1317 movmi r0, r3 1318 bmi puts 1319 and r2, r0, #15 1320 mov r0, r0, lsr #4 1321 cmp r2, #10 1322 addge r2, r2, #7 1323 add r2, r2, #'0' 1324 strb r2, [r3, r1] 1325 b 1b 1326 1327@ puts corrupts {r0, r1, r2, r3} 1328puts: loadsp r3, r2, r1 13291: ldrb r2, [r0], #1 1330 teq r2, #0 1331 moveq pc, lr 13322: writeb r2, r3, r1 1333 mov r1, #0x00020000 13343: subs r1, r1, #1 1335 bne 3b 1336 teq r2, #'\n' 1337 moveq r2, #'\r' 1338 beq 2b 1339 teq r0, #0 1340 bne 1b 1341 mov pc, lr 1342@ putc corrupts {r0, r1, r2, r3} 1343putc: 1344 mov r2, r0 1345 loadsp r3, r1, r0 1346 mov r0, #0 1347 b 2b 1348 1349@ memdump corrupts {r0, r1, r2, r3, r10, r11, r12, lr} 1350memdump: mov r12, r0 1351 mov r10, lr 1352 mov r11, #0 13532: mov r0, r11, lsl #2 1354 add r0, r0, r12 1355 mov r1, #8 1356 bl phex 1357 mov r0, #':' 1358 bl putc 13591: mov r0, #' ' 1360 bl putc 1361 ldr r0, [r12, r11, lsl #2] 1362 mov r1, #8 1363 bl phex 1364 and r0, r11, #7 1365 teq r0, #3 1366 moveq r0, #' ' 1367 bleq putc 1368 and r0, r11, #7 1369 add r11, r11, #1 1370 teq r0, #7 1371 bne 1b 1372 mov r0, #'\n' 1373 bl putc 1374 cmp r11, #64 1375 blt 2b 1376 mov pc, r10 1377#endif 1378 1379 .ltorg 1380 1381#ifdef CONFIG_ARM_VIRT_EXT 1382.align 5 1383__hyp_reentry_vectors: 1384 W(b) . @ reset 1385 W(b) . @ undef 1386#ifdef CONFIG_EFI_STUB 1387 W(b) __enter_kernel_from_hyp @ hvc from HYP 1388#else 1389 W(b) . @ svc 1390#endif 1391 W(b) . @ pabort 1392 W(b) . @ dabort 1393 W(b) __enter_kernel @ hyp 1394 W(b) . @ irq 1395 W(b) . @ fiq 1396#endif /* CONFIG_ARM_VIRT_EXT */ 1397 1398__enter_kernel: 1399 mov r0, #0 @ must be 0 1400 mov r1, r7 @ restore architecture number 1401 mov r2, r8 @ restore atags pointer 1402 ARM( mov pc, r4 ) @ call kernel 1403 M_CLASS( add r4, r4, #1 ) @ enter in Thumb mode for M class 1404 THUMB( bx r4 ) @ entry point is always ARM for A/R classes 1405 1406reloc_code_end: 1407 1408#ifdef CONFIG_EFI_STUB 1409__enter_kernel_from_hyp: 1410 mrc p15, 4, r0, c1, c0, 0 @ read HSCTLR 1411 bic r0, r0, #0x5 @ disable MMU and caches 1412 mcr p15, 4, r0, c1, c0, 0 @ write HSCTLR 1413 isb 1414 b __enter_kernel 1415 1416ENTRY(efi_enter_kernel) 1417 mov r4, r0 @ preserve image base 1418 mov r8, r1 @ preserve DT pointer 1419 1420 ARM( adrl r0, call_cache_fn ) 1421 THUMB( adr r0, call_cache_fn ) 1422 adr r1, 0f @ clean the region of code we 1423 bl cache_clean_flush @ may run with the MMU off 1424 1425#ifdef CONFIG_ARM_VIRT_EXT 1426 @ 1427 @ The EFI spec does not support booting on ARM in HYP mode, 1428 @ since it mandates that the MMU and caches are on, with all 1429 @ 32-bit addressable DRAM mapped 1:1 using short descriptors. 1430 @ 1431 @ While the EDK2 reference implementation adheres to this, 1432 @ U-Boot might decide to enter the EFI stub in HYP mode 1433 @ anyway, with the MMU and caches either on or off. 1434 @ 1435 mrs r0, cpsr @ get the current mode 1436 msr spsr_cxsf, r0 @ record boot mode 1437 and r0, r0, #MODE_MASK @ are we running in HYP mode? 1438 cmp r0, #HYP_MODE 1439 bne .Lefi_svc 1440 1441 mrc p15, 4, r1, c1, c0, 0 @ read HSCTLR 1442 tst r1, #0x1 @ MMU enabled at HYP? 1443 beq 1f 1444 1445 @ 1446 @ When running in HYP mode with the caches on, we're better 1447 @ off just carrying on using the cached 1:1 mapping that the 1448 @ firmware provided. Set up the HYP vectors so HVC instructions 1449 @ issued from HYP mode take us to the correct handler code. We 1450 @ will disable the MMU before jumping to the kernel proper. 1451 @ 1452 adr r0, __hyp_reentry_vectors 1453 mcr p15, 4, r0, c12, c0, 0 @ set HYP vector base (HVBAR) 1454 isb 1455 b .Lefi_hyp 1456 1457 @ 1458 @ When running in HYP mode with the caches off, we need to drop 1459 @ into SVC mode now, and let the decompressor set up its cached 1460 @ 1:1 mapping as usual. 1461 @ 14621: mov r9, r4 @ preserve image base 1463 bl __hyp_stub_install @ install HYP stub vectors 1464 safe_svcmode_maskall r1 @ drop to SVC mode 1465 msr spsr_cxsf, r0 @ record boot mode 1466 orr r4, r9, #1 @ restore image base and set LSB 1467 b .Lefi_hyp 1468.Lefi_svc: 1469#endif 1470 mrc p15, 0, r0, c1, c0, 0 @ read SCTLR 1471 tst r0, #0x1 @ MMU enabled? 1472 orreq r4, r4, #1 @ set LSB if not 1473 1474.Lefi_hyp: 1475 mov r0, r8 @ DT start 1476 add r1, r8, r2 @ DT end 1477 bl cache_clean_flush 1478 1479 adr r0, 0f @ switch to our stack 1480 ldr sp, [r0] 1481 add sp, sp, r0 1482 1483 mov r5, #0 @ appended DTB size 1484 mov r7, #0xFFFFFFFF @ machine ID 1485 b wont_overwrite 1486ENDPROC(efi_enter_kernel) 14870: .long .L_user_stack_end - . 1488#endif 1489 1490 .align 1491 .section ".stack", "aw", %nobits 1492.L_user_stack: .space 4096 1493.L_user_stack_end: 1494