1 /* SPDX-License-Identifier: GPL-2.0
3 * relocate_kernel.S - put the kernel image in place to boot
4 * 2005.9.17 kogiidena@eggplant.ddo.jp
6 * LANDISK/sh4 is supported. Maybe, SH archtecture works well.
8 * 2009-03-18 Magnus Damm - Added Kexec Jump support
10 #include <linux/linkage.h>
11 #include <asm/addrspace.h>
14 .globl relocate_new_kernel
16 /* r4 = indirection_page */
17 /* r5 = reboot_code_buffer */
18 /* r6 = start_address */
20 mov.l 10f, r0 /* PAGE_SIZE */
21 add r5, r0 /* setup new stack at end of control page */
23 /* save r15->r8 to new stack */
34 /* save other random registers */
43 /* switch to bank1 and save r7->r0 */
57 /* switch to bank0 and save r7->r0 */
72 mov.l r4, @-r15 /* save indirection page again */
74 bsr swap_pages /* swap pages before jumping to new kernel */
78 mov.l r15, @r0 /* save pointer to stack */
80 jsr @r6 /* hand over control to new kernel */
83 mov.l 11f, r15 /* get pointer to stack */
84 mov.l @r15+, r4 /* restore r4 to get indirection page */
86 bsr swap_pages /* swap pages back to previous state */
89 /* make sure bank0 is active and restore r0->r7 */
104 /* switch to bank1 and restore r0->r7 */
118 /* switch back to bank0 */
125 /* restore other random registers */
134 /* restore r8->r15 */
148 mov r4,r0 /* cmd = indirection_page */
150 mov.l @r4+,r0 /* cmd = *ind++ */
152 1: /* addr = cmd & 0xfffffff0 */
157 /* if(cmd & IND_DESTINATION) dst = addr */
163 2: /* else if(cmd & IND_INDIRECTION) ind = addr */
169 3: /* else if(cmd & IND_DONE) return */
175 4: /* else if(cmd & IND_SOURCE) memcpy(dst,addr,PAGE_SIZE) */
179 mov.l 10f,r3 /* PAGE_SIZE */
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
189 * to keep it simple swap the contents for both cases.
224 .long 0x20000000 ! RB=1
226 relocate_new_kernel_end:
228 .globl relocate_new_kernel_size
229 relocate_new_kernel_size:
230 .long relocate_new_kernel_end - relocate_new_kernel