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 * 2005.9.17 kogiidena@eggplant.ddo.jp << 5 * << 6 * LANDISK/sh4 is supported. Maybe, SH archtec << 7 * << 8 * 2009-03-18 Magnus Damm - Added Kexec Jump s << 9 */ << 10 #include <linux/linkage.h> 2 #include <linux/linkage.h> 11 #include <asm/addrspace.h> !! 3 >> 4 #include <asm/asm-offsets.h> 12 #include <asm/page.h> 5 #include <asm/page.h> >> 6 #include <asm/setup.h> >> 7 >> 8 >> 9 #define MMU_BASE 8 /* MMU flags base in cpu_mmu_flags */ >> 10 >> 11 .text >> 12 >> 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 >> 92 >> 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 >> 99 >> 100 2: >> 101 btst #3,%d0 /* entry & IND_SOURCE? */ >> 102 jeq .Lcopy >> 103 >> 104 andw %d2,%d0 >> 105 movel %d0,%a3 /* a3 = src = entry & PAGE_MASK */ >> 106 movew #PAGE_SIZE/32 - 1,%d0 /* d0 = PAGE_SIZE/32 - 1 */ >> 107 3: >> 108 movel %a3@+,%a2@+ /* *dst++ = *src++ */ >> 109 movel %a3@+,%a2@+ /* *dst++ = *src++ */ >> 110 movel %a3@+,%a2@+ /* *dst++ = *src++ */ >> 111 movel %a3@+,%a2@+ /* *dst++ = *src++ */ >> 112 movel %a3@+,%a2@+ /* *dst++ = *src++ */ >> 113 movel %a3@+,%a2@+ /* *dst++ = *src++ */ >> 114 movel %a3@+,%a2@+ /* *dst++ = *src++ */ >> 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 >> 132 >> 133 2: >> 134 btst #CPUB_68030,%d1 >> 135 jne 1b >> 136 >> 137 btst #CPUB_68040,%d1 >> 138 jeq 4f >> 139 >> 140 3: /* 68040 or 68060 */ >> 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 13 153 14 .globl relocate_new_kernel !! 154 .Lreincarnate: 15 relocate_new_kernel: !! 155 jmp %a1@ 16 /* r4 = indirection_page */ << 17 /* r5 = reboot_code_buffer */ << 18 /* r6 = start_address */ << 19 << 20 mov.l 10f, r0 /* PAGE_SIZE * << 21 add r5, r0 /* setup new s << 22 << 23 /* save r15->r8 to new stack */ << 24 mov.l r15, @-r0 << 25 mov r0, r15 << 26 mov.l r14, @-r15 << 27 mov.l r13, @-r15 << 28 mov.l r12, @-r15 << 29 mov.l r11, @-r15 << 30 mov.l r10, @-r15 << 31 mov.l r9, @-r15 << 32 mov.l r8, @-r15 << 33 << 34 /* save other random registers */ << 35 sts.l macl, @-r15 << 36 sts.l mach, @-r15 << 37 stc.l gbr, @-r15 << 38 stc.l ssr, @-r15 << 39 stc.l sr, @-r15 << 40 sts.l pr, @-r15 << 41 stc.l spc, @-r15 << 42 << 43 /* switch to bank1 and save r7->r0 */ << 44 mov.l 12f, r9 << 45 stc sr, r8 << 46 or r9, r8 << 47 ldc r8, sr << 48 mov.l r7, @-r15 << 49 mov.l r6, @-r15 << 50 mov.l r5, @-r15 << 51 mov.l r4, @-r15 << 52 mov.l r3, @-r15 << 53 mov.l r2, @-r15 << 54 mov.l r1, @-r15 << 55 mov.l r0, @-r15 << 56 << 57 /* switch to bank0 and save r7->r0 */ << 58 mov.l 12f, r9 << 59 not r9, r9 << 60 stc sr, r8 << 61 and r9, r8 << 62 ldc r8, sr << 63 mov.l r7, @-r15 << 64 mov.l r6, @-r15 << 65 mov.l r5, @-r15 << 66 mov.l r4, @-r15 << 67 mov.l r3, @-r15 << 68 mov.l r2, @-r15 << 69 mov.l r1, @-r15 << 70 mov.l r0, @-r15 << 71 << 72 mov.l r4, @-r15 /* save indire << 73 << 74 bsr swap_pages /* swap pages << 75 nop << 76 << 77 mova 11f, r0 << 78 mov.l r15, @r0 /* save pointe << 79 << 80 jsr @r6 /* hand over c << 81 nop << 82 << 83 mov.l 11f, r15 /* get pointer << 84 mov.l @r15+, r4 /* restore r4 << 85 << 86 bsr swap_pages /* swap pages << 87 nop << 88 << 89 /* make sure bank0 is active and resto << 90 mov.l 12f, r9 << 91 not r9, r9 << 92 stc sr, r8 << 93 and r9, r8 << 94 ldc r8, sr << 95 mov.l @r15+, r0 << 96 mov.l @r15+, r1 << 97 mov.l @r15+, r2 << 98 mov.l @r15+, r3 << 99 mov.l @r15+, r4 << 100 mov.l @r15+, r5 << 101 mov.l @r15+, r6 << 102 mov.l @r15+, r7 << 103 << 104 /* switch to bank1 and restore r0->r7 << 105 mov.l 12f, r9 << 106 stc sr, r8 << 107 or r9, r8 << 108 ldc r8, sr << 109 mov.l @r15+, r0 << 110 mov.l @r15+, r1 << 111 mov.l @r15+, r2 << 112 mov.l @r15+, r3 << 113 mov.l @r15+, r4 << 114 mov.l @r15+, r5 << 115 mov.l @r15+, r6 << 116 mov.l @r15+, r7 << 117 << 118 /* switch back to bank0 */ << 119 mov.l 12f, r9 << 120 not r9, r9 << 121 stc sr, r8 << 122 and r9, r8 << 123 ldc r8, sr << 124 << 125 /* restore other random registers */ << 126 ldc.l @r15+, spc << 127 lds.l @r15+, pr << 128 ldc.l @r15+, sr << 129 ldc.l @r15+, ssr << 130 ldc.l @r15+, gbr << 131 lds.l @r15+, mach << 132 lds.l @r15+, macl << 133 << 134 /* restore r8->r15 */ << 135 mov.l @r15+, r8 << 136 mov.l @r15+, r9 << 137 mov.l @r15+, r10 << 138 mov.l @r15+, r11 << 139 mov.l @r15+, r12 << 140 mov.l @r15+, r13 << 141 mov.l @r15+, r14 << 142 mov.l @r15+, r15 << 143 rts << 144 nop << 145 << 146 swap_pages: << 147 bra 1f << 148 mov r4,r0 /* cmd = indirection << 149 0: << 150 mov.l @r4+,r0 /* cmd = *ind++ */ << 151 << 152 1: /* addr = cmd & 0xfffffff0 */ << 153 mov r0,r2 << 154 mov #-16,r1 << 155 and r1,r2 << 156 << 157 /* if(cmd & IND_DESTINATION) dst = add << 158 tst #1,r0 << 159 bt 2f << 160 bra 0b << 161 mov r2,r5 << 162 << 163 2: /* else if(cmd & IND_INDIRECTION) ind << 164 tst #2,r0 << 165 bt 3f << 166 bra 0b << 167 mov r2,r4 << 168 << 169 3: /* else if(cmd & IND_DONE) return */ << 170 tst #4,r0 << 171 bt 4f << 172 rts << 173 nop << 174 << 175 4: /* else if(cmd & IND_SOURCE) memcpy(ds << 176 tst #8,r0 << 177 bt 0b << 178 << 179 mov.l 10f,r3 /* PAGE_SIZE */ << 180 shlr2 r3 << 181 shlr2 r3 << 182 5: << 183 dt r3 << 184 << 185 /* regular kexec just overwrites the d << 186 * with the contents of the source pag << 187 * for the kexec jump case we need to << 188 * of the pages. << 189 * to keep it simple swap the contents << 190 */ << 191 mov.l @(0, r2), r8 << 192 mov.l @(0, r5), r1 << 193 mov.l r8, @(0, r5) << 194 mov.l r1, @(0, r2) << 195 << 196 mov.l @(4, r2), r8 << 197 mov.l @(4, r5), r1 << 198 mov.l r8, @(4, r5) << 199 mov.l r1, @(4, r2) << 200 << 201 mov.l @(8, r2), r8 << 202 mov.l @(8, r5), r1 << 203 mov.l r8, @(8, r5) << 204 mov.l r1, @(8, r2) << 205 << 206 mov.l @(12, r2), r8 << 207 mov.l @(12, r5), r1 << 208 mov.l r8, @(12, r5) << 209 mov.l r1, @(12, r2) << 210 << 211 add #16,r5 << 212 add #16,r2 << 213 bf 5b << 214 << 215 bra 0b << 216 nop << 217 << 218 .align 2 << 219 10: << 220 .long PAGE_SIZE << 221 11: << 222 .long 0 << 223 12: << 224 .long 0x20000000 ! RB=1 << 225 156 226 relocate_new_kernel_end: 157 relocate_new_kernel_end: 227 158 228 .globl relocate_new_kernel_size !! 159 ENTRY(relocate_new_kernel_size) 229 relocate_new_kernel_size: << 230 .long relocate_new_kernel_end - reloca 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.