linux/arch/sh/kernel/relocate_kernel.S
<<
>>
Prefs
   1/*
   2 * relocate_kernel.S - put the kernel image in place to boot
   3 * 2005.9.17 kogiidena@eggplant.ddo.jp
   4 *
   5 * LANDISK/sh4 is supported. Maybe, SH archtecture works well.
   6 *
   7 * 2009-03-18 Magnus Damm - Added Kexec Jump support
   8 *
   9 * This source code is licensed under the GNU General Public License,
  10 * Version 2.  See the file COPYING for more details.
  11 */
  12#include <linux/linkage.h>
  13#include <asm/addrspace.h>
  14#include <asm/page.h>
  15
  16                .globl relocate_new_kernel
  17relocate_new_kernel:
  18        /* r4 = indirection_page   */
  19        /* r5 = reboot_code_buffer */
  20        /* r6 = start_address      */
  21
  22        mov.l   10f, r0         /* PAGE_SIZE */
  23        add     r5, r0          /* setup new stack at end of control page */
  24
  25        /* save r15->r8 to new stack */
  26        mov.l   r15, @-r0
  27        mov     r0, r15
  28        mov.l   r14, @-r15
  29        mov.l   r13, @-r15
  30        mov.l   r12, @-r15
  31        mov.l   r11, @-r15
  32        mov.l   r10, @-r15
  33        mov.l   r9, @-r15
  34        mov.l   r8, @-r15
  35
  36        /* save other random registers */
  37        sts.l   macl, @-r15
  38        sts.l   mach, @-r15
  39        stc.l   gbr, @-r15
  40        stc.l   ssr, @-r15
  41        stc.l   sr, @-r15
  42        sts.l   pr, @-r15
  43        stc.l   spc, @-r15
  44
  45        /* switch to bank1 and save r7->r0 */
  46        mov.l   12f, r9
  47        stc     sr, r8
  48        or      r9, r8
  49        ldc     r8, sr
  50        mov.l   r7, @-r15
  51        mov.l   r6, @-r15
  52        mov.l   r5, @-r15
  53        mov.l   r4, @-r15
  54        mov.l   r3, @-r15
  55        mov.l   r2, @-r15
  56        mov.l   r1, @-r15
  57        mov.l   r0, @-r15
  58
  59        /* switch to bank0 and save r7->r0 */
  60        mov.l   12f, r9
  61        not     r9, r9
  62        stc     sr, r8
  63        and     r9, r8
  64        ldc     r8, sr
  65        mov.l   r7, @-r15
  66        mov.l   r6, @-r15
  67        mov.l   r5, @-r15
  68        mov.l   r4, @-r15
  69        mov.l   r3, @-r15
  70        mov.l   r2, @-r15
  71        mov.l   r1, @-r15
  72        mov.l   r0, @-r15
  73
  74        mov.l   r4, @-r15       /* save indirection page again */
  75
  76        bsr     swap_pages      /* swap pages before jumping to new kernel */
  77         nop
  78
  79        mova    11f, r0
  80        mov.l   r15, @r0        /* save pointer to stack */
  81
  82        jsr     @r6             /* hand over control to new kernel */
  83         nop
  84
  85        mov.l   11f, r15        /* get pointer to stack */
  86        mov.l   @r15+, r4       /* restore r4 to get indirection page */
  87
  88        bsr     swap_pages      /* swap pages back to previous state */
  89         nop
  90
  91        /* make sure bank0 is active and restore r0->r7 */
  92        mov.l   12f, r9
  93        not     r9, r9
  94        stc     sr, r8
  95        and     r9, r8
  96        ldc     r8, sr
  97        mov.l   @r15+, r0
  98        mov.l   @r15+, r1
  99        mov.l   @r15+, r2
 100        mov.l   @r15+, r3
 101        mov.l   @r15+, r4
 102        mov.l   @r15+, r5
 103        mov.l   @r15+, r6
 104        mov.l   @r15+, r7
 105
 106        /* switch to bank1 and restore r0->r7 */
 107        mov.l   12f, r9
 108        stc     sr, r8
 109        or      r9, r8
 110        ldc     r8, sr
 111        mov.l   @r15+, r0
 112        mov.l   @r15+, r1
 113        mov.l   @r15+, r2
 114        mov.l   @r15+, r3
 115        mov.l   @r15+, r4
 116        mov.l   @r15+, r5
 117        mov.l   @r15+, r6
 118        mov.l   @r15+, r7
 119
 120        /* switch back to bank0 */
 121        mov.l   12f, r9
 122        not     r9, r9
 123        stc     sr, r8
 124        and     r9, r8
 125        ldc     r8, sr
 126
 127        /* restore other random registers */
 128        ldc.l   @r15+, spc
 129        lds.l   @r15+, pr
 130        ldc.l   @r15+, sr
 131        ldc.l   @r15+, ssr
 132        ldc.l   @r15+, gbr
 133        lds.l   @r15+, mach
 134        lds.l   @r15+, macl
 135
 136        /* restore r8->r15 */
 137        mov.l   @r15+, r8
 138        mov.l   @r15+, r9
 139        mov.l   @r15+, r10
 140        mov.l   @r15+, r11
 141        mov.l   @r15+, r12
 142        mov.l   @r15+, r13
 143        mov.l   @r15+, r14
 144        mov.l   @r15+, r15
 145        rts
 146         nop
 147
 148swap_pages:
 149        bra     1f
 150         mov    r4,r0     /* cmd = indirection_page */
 1510:
 152        mov.l   @r4+,r0   /* cmd = *ind++ */
 153
 1541:      /* addr = cmd & 0xfffffff0 */
 155        mov     r0,r2
 156        mov     #-16,r1
 157        and     r1,r2
 158
 159        /* if(cmd & IND_DESTINATION) dst = addr  */
 160        tst     #1,r0
 161        bt      2f
 162        bra     0b
 163         mov    r2,r5
 164
 1652:      /* else if(cmd & IND_INDIRECTION) ind = addr  */
 166        tst     #2,r0
 167        bt      3f
 168        bra     0b
 169         mov    r2,r4
 170
 1713:      /* else if(cmd & IND_DONE) return */
 172        tst     #4,r0
 173        bt      4f
 174        rts
 175         nop
 176
 1774:      /* else if(cmd & IND_SOURCE) memcpy(dst,addr,PAGE_SIZE) */
 178        tst     #8,r0
 179        bt      0b
 180
 181        mov.l   10f,r3    /* PAGE_SIZE */
 182        shlr2   r3
 183        shlr2   r3
 1845:
 185        dt      r3
 186
 187        /* regular kexec just overwrites the destination page
 188         * with the contents of the source page.
 189         * for the kexec jump case we need to swap the contents
 190         * of the pages.
 191         * to keep it simple swap the contents for both cases.
 192         */
 193        mov.l   @(0, r2), r8
 194        mov.l   @(0, r5), r1
 195        mov.l   r8, @(0, r5)
 196        mov.l   r1, @(0, r2)
 197
 198        mov.l   @(4, r2), r8
 199        mov.l   @(4, r5), r1
 200        mov.l   r8, @(4, r5)
 201        mov.l   r1, @(4, r2)
 202
 203        mov.l   @(8, r2), r8
 204        mov.l   @(8, r5), r1
 205        mov.l   r8, @(8, r5)
 206        mov.l   r1, @(8, r2)
 207
 208        mov.l   @(12, r2), r8
 209        mov.l   @(12, r5), r1
 210        mov.l   r8, @(12, r5)
 211        mov.l   r1, @(12, r2)
 212
 213        add     #16,r5
 214        add     #16,r2
 215        bf      5b
 216
 217        bra     0b
 218         nop
 219
 220        .align 2
 22110:
 222        .long   PAGE_SIZE
 22311:
 224        .long   0
 22512:
 226        .long   0x20000000 ! RB=1
 227
 228relocate_new_kernel_end:
 229
 230        .globl relocate_new_kernel_size
 231relocate_new_kernel_size:
 232        .long relocate_new_kernel_end - relocate_new_kernel
 233