1/* SPDX-License-Identifier: GPL-2.0 2 * 3 * relocate_kernel.S - put the kernel image in place to boot 4 * 2005.9.17 kogiidena@eggplant.ddo.jp 5 * 6 * LANDISK/sh4 is supported. Maybe, SH archtecture works well. 7 * 8 * 2009-03-18 Magnus Damm - Added Kexec Jump support 9 */ 10#include <linux/linkage.h> 11#include <asm/addrspace.h> 12#include <asm/page.h> 13 14 .globl relocate_new_kernel 15relocate_new_kernel: 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 stack at end of control page */ 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 indirection page again */ 73 74 bsr swap_pages /* swap pages before jumping to new kernel */ 75 nop 76 77 mova 11f, r0 78 mov.l r15, @r0 /* save pointer to stack */ 79 80 jsr @r6 /* hand over control to new kernel */ 81 nop 82 83 mov.l 11f, r15 /* get pointer to stack */ 84 mov.l @r15+, r4 /* restore r4 to get indirection page */ 85 86 bsr swap_pages /* swap pages back to previous state */ 87 nop 88 89 /* make sure bank0 is active and restore r0->r7 */ 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 146swap_pages: 147 bra 1f 148 mov r4,r0 /* cmd = indirection_page */ 1490: 150 mov.l @r4+,r0 /* cmd = *ind++ */ 151 1521: /* addr = cmd & 0xfffffff0 */ 153 mov r0,r2 154 mov #-16,r1 155 and r1,r2 156 157 /* if(cmd & IND_DESTINATION) dst = addr */ 158 tst #1,r0 159 bt 2f 160 bra 0b 161 mov r2,r5 162 1632: /* else if(cmd & IND_INDIRECTION) ind = addr */ 164 tst #2,r0 165 bt 3f 166 bra 0b 167 mov r2,r4 168 1693: /* else if(cmd & IND_DONE) return */ 170 tst #4,r0 171 bt 4f 172 rts 173 nop 174 1754: /* else if(cmd & IND_SOURCE) memcpy(dst,addr,PAGE_SIZE) */ 176 tst #8,r0 177 bt 0b 178 179 mov.l 10f,r3 /* PAGE_SIZE */ 180 shlr2 r3 181 shlr2 r3 1825: 183 dt r3 184 185 /* regular kexec just overwrites the destination page 186 * with the contents of the source page. 187 * for the kexec jump case we need to swap the contents 188 * of the pages. 189 * to keep it simple swap the contents for both cases. 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 21910: 220 .long PAGE_SIZE 22111: 222 .long 0 22312: 224 .long 0x20000000 ! RB=1 225 226relocate_new_kernel_end: 227 228 .globl relocate_new_kernel_size 229relocate_new_kernel_size: 230 .long relocate_new_kernel_end - relocate_new_kernel 231