root/arch/sh/kernel/relocate_kernel.S

/* [<][>][^][v][top][bottom][index][help] */
   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
  15 relocate_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 
 146 swap_pages:
 147         bra     1f
 148          mov    r4,r0     /* cmd = indirection_page */
 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 = addr  */
 158         tst     #1,r0
 159         bt      2f
 160         bra     0b
 161          mov    r2,r5
 162 
 163 2:      /* else if(cmd & IND_INDIRECTION) ind = addr  */
 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(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
 182 5:
 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
 219 10:
 220         .long   PAGE_SIZE
 221 11:
 222         .long   0
 223 12:
 224         .long   0x20000000 ! RB=1
 225 
 226 relocate_new_kernel_end:
 227 
 228         .globl relocate_new_kernel_size
 229 relocate_new_kernel_size:
 230         .long relocate_new_kernel_end - relocate_new_kernel

/* [<][>][^][v][top][bottom][index][help] */