1 /* SPDX-License-Identifier: GPL-2.0 */ 1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* << 3 * relocate_kernel.S - put the kernel image in << 4 */ << 5 << 6 #include <linux/linkage.h> 2 #include <linux/linkage.h> 7 #include <asm/assembler.h> !! 3 8 #include <asm/asm-offsets.h> 4 #include <asm/asm-offsets.h> 9 #include <asm/kexec.h> !! 5 #include <asm/page.h> >> 6 #include <asm/setup.h> >> 7 10 8 11 .align 3 /* not needed for this !! 9 #define MMU_BASE 8 /* MMU flags base in cpu_mmu_flags */ >> 10 >> 11 .text 12 12 13 ENTRY(relocate_new_kernel) 13 ENTRY(relocate_new_kernel) >> 14 movel %sp@(4),%a0 /* a0 = ptr */ >> 15 movel %sp@(8),%a1 /* a1 = start */ >> 16 movel %sp@(12),%d1 /* d1 = cpu_mmu_flags */ >> 17 movew #PAGE_MASK,%d2 /* d2 = PAGE_MASK */ >> 18 >> 19 /* Disable MMU */ >> 20 >> 21 btst #MMU_BASE + MMUB_68851,%d1 >> 22 jeq 3f >> 23 >> 24 1: /* 68851 or 68030 */ >> 25 >> 26 lea %pc@(.Lcopy),%a4 >> 27 2: addl #0x00000000,%a4 /* virt_to_phys() */ >> 28 >> 29 .section .m68k_fixup,"aw" >> 30 .long M68K_FIXUP_MEMOFFSET, 2b+2 >> 31 .previous >> 32 >> 33 .chip 68030 >> 34 pmove %tc,%d0 /* Disable MMU */ >> 35 bclr #7,%d0 >> 36 pmove %d0,%tc >> 37 jmp %a4@ /* Jump to physical .Lcopy */ >> 38 .chip 68k >> 39 >> 40 3: >> 41 btst #MMU_BASE + MMUB_68030,%d1 >> 42 jne 1b >> 43 >> 44 btst #MMU_BASE + MMUB_68040,%d1 >> 45 jeq 6f >> 46 >> 47 4: /* 68040 or 68060 */ >> 48 >> 49 lea %pc@(.Lcont040),%a4 >> 50 5: addl #0x00000000,%a4 /* virt_to_phys() */ >> 51 >> 52 .section .m68k_fixup,"aw" >> 53 .long M68K_FIXUP_MEMOFFSET, 5b+2 >> 54 .previous >> 55 >> 56 movel %a4,%d0 >> 57 andl #0xff000000,%d0 >> 58 orw #0xe020,%d0 /* Map 16 MiB, enable, cacheable */ >> 59 .chip 68040 >> 60 movec %d0,%itt0 >> 61 movec %d0,%dtt0 >> 62 .chip 68k >> 63 jmp %a4@ /* Jump to physical .Lcont040 */ >> 64 >> 65 .Lcont040: >> 66 moveq #0,%d0 >> 67 .chip 68040 >> 68 movec %d0,%tc /* Disable MMU */ >> 69 movec %d0,%itt0 >> 70 movec %d0,%itt1 >> 71 movec %d0,%dtt0 >> 72 movec %d0,%dtt1 >> 73 .chip 68k >> 74 jra .Lcopy >> 75 >> 76 6: >> 77 btst #MMU_BASE + MMUB_68060,%d1 >> 78 jne 4b >> 79 >> 80 .Lcopy: >> 81 movel %a0@+,%d0 /* d0 = entry = *ptr */ >> 82 jeq .Lflush >> 83 >> 84 btst #2,%d0 /* entry & IND_DONE? */ >> 85 jne .Lflush >> 86 >> 87 btst #1,%d0 /* entry & IND_INDIRECTION? */ >> 88 jeq 1f >> 89 andw %d2,%d0 >> 90 movel %d0,%a0 /* ptr = entry & PAGE_MASK */ >> 91 jra .Lcopy 14 92 15 adr r7, relocate_new_kernel_end << 16 ldr r0, [r7, #KEXEC_INDIR_PAGE] << 17 ldr r1, [r7, #KEXEC_START_ADDR] << 18 << 19 /* << 20 * If there is no indirection page (we << 21 * skip any relocation. << 22 */ << 23 cmp r0, #0 << 24 beq 2f << 25 << 26 0: /* top, read another word for the indi << 27 ldr r3, [r0],#4 << 28 << 29 /* Is it a destination page. Put desti << 30 tst r3,#1 << 31 beq 1f << 32 bic r4,r3,#1 << 33 b 0b << 34 1: << 35 /* Is it an indirection page */ << 36 tst r3,#2 << 37 beq 1f << 38 bic r0,r3,#2 << 39 b 0b << 40 1: 93 1: >> 94 btst #0,%d0 /* entry & IND_DESTINATION? */ >> 95 jeq 2f >> 96 andw %d2,%d0 >> 97 movel %d0,%a2 /* a2 = dst = entry & PAGE_MASK */ >> 98 jra .Lcopy 41 99 42 /* are we done ? */ !! 100 2: 43 tst r3,#4 !! 101 btst #3,%d0 /* entry & IND_SOURCE? */ 44 beq 1f !! 102 jeq .Lcopy 45 b 2f << 46 103 47 1: !! 104 andw %d2,%d0 48 /* is it source ? */ !! 105 movel %d0,%a3 /* a3 = src = entry & PAGE_MASK */ 49 tst r3,#8 !! 106 movew #PAGE_SIZE/32 - 1,%d0 /* d0 = PAGE_SIZE/32 - 1 */ 50 beq 0b !! 107 3: 51 bic r3,r3,#8 !! 108 movel %a3@+,%a2@+ /* *dst++ = *src++ */ 52 mov r6,#1024 !! 109 movel %a3@+,%a2@+ /* *dst++ = *src++ */ 53 9: !! 110 movel %a3@+,%a2@+ /* *dst++ = *src++ */ 54 ldr r5,[r3],#4 !! 111 movel %a3@+,%a2@+ /* *dst++ = *src++ */ 55 str r5,[r4],#4 !! 112 movel %a3@+,%a2@+ /* *dst++ = *src++ */ 56 subs r6,r6,#1 !! 113 movel %a3@+,%a2@+ /* *dst++ = *src++ */ 57 bne 9b !! 114 movel %a3@+,%a2@+ /* *dst++ = *src++ */ 58 b 0b !! 115 movel %a3@+,%a2@+ /* *dst++ = *src++ */ >> 116 dbf %d0, 3b >> 117 jra .Lcopy >> 118 >> 119 .Lflush: >> 120 /* Flush all caches */ >> 121 >> 122 btst #CPUB_68020,%d1 >> 123 jeq 2f >> 124 >> 125 1: /* 68020 or 68030 */ >> 126 .chip 68030 >> 127 movec %cacr,%d0 >> 128 orw #0x808,%d0 >> 129 movec %d0,%cacr >> 130 .chip 68k >> 131 jra .Lreincarnate 59 132 60 2: 133 2: 61 /* Jump to relocated kernel */ !! 134 btst #CPUB_68030,%d1 62 mov lr, r1 !! 135 jne 1b 63 mov r0, #0 << 64 ldr r1, [r7, #KEXEC_MACH_TYPE] << 65 ldr r2, [r7, #KEXEC_R2] << 66 ARM( ret lr ) << 67 THUMB( bx lr ) << 68 136 69 ENDPROC(relocate_new_kernel) !! 137 btst #CPUB_68040,%d1 >> 138 jeq 4f 70 139 71 .align 3 !! 140 3: /* 68040 or 68060 */ 72 relocate_new_kernel_end: !! 141 .chip 68040 >> 142 nop >> 143 cpusha %bc >> 144 nop >> 145 cinva %bc >> 146 nop >> 147 .chip 68k >> 148 jra .Lreincarnate >> 149 >> 150 4: >> 151 btst #CPUB_68060,%d1 >> 152 jne 3b 73 153 74 .globl relocate_new_kernel_size !! 154 .Lreincarnate: 75 relocate_new_kernel_size: !! 155 jmp %a1@ 76 .long relocate_new_kernel_end - reloca << 77 156 >> 157 relocate_new_kernel_end: 78 158 >> 159 ENTRY(relocate_new_kernel_size) >> 160 .long relocate_new_kernel_end - relocate_new_kernel
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.