Merge git://git.infradead.org/hdrinstall-2.6
[linux-2.6] / arch / sh / kernel / relocate_kernel.S
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  * This source code is licensed under the GNU General Public License,
8  * Version 2.  See the file COPYING for more details.
9  */
10
11 #include <linux/linkage.h>
12
13 #define PAGE_SIZE      4096 /* must be same value as in <asm/page.h> */
14
15
16                 .globl relocate_new_kernel
17 relocate_new_kernel:
18         /* r4 = indirection_page   */
19         /* r5 = reboot_code_buffer */
20         /* r6 = start_address      */
21         /* r7 = vbr_reg            */
22
23         mov.l   10f,r8    /* 4096 */
24         mov.l   11f,r9    /* 0xa0000000 */
25
26         /*  stack setting */
27         add     r8,r5
28         mov     r5,r15
29
30         bra     1f
31         mov     r4,r0     /* cmd = indirection_page */
32 0:
33         mov.l   @r4+,r0   /* cmd = *ind++ */
34
35 1:      /* addr = (cmd | 0xa0000000) & 0xfffffff0 */
36         mov     r0,r2
37         or      r9,r2
38         mov     #-16,r1
39         and     r1,r2
40
41         /* if(cmd & IND_DESTINATION) dst = addr  */
42         tst     #1,r0
43         bt      2f
44         bra     0b
45         mov     r2,r5
46
47 2:      /* else if(cmd & IND_INDIRECTION) ind = addr  */
48         tst     #2,r0
49         bt      3f
50         bra     0b
51         mov     r2,r4
52
53 3:      /* else if(cmd & IND_DONE) goto 6  */
54         tst     #4,r0
55         bt      4f
56         bra     6f
57         nop
58
59 4:      /* else if(cmd & IND_SOURCE) memcpy(dst,addr,PAGE_SIZE) */
60         tst     #8,r0
61         bt      0b
62
63         mov     r8,r3
64         shlr2   r3
65         shlr2   r3
66 5:
67         dt      r3
68         mov.l   @r2+,r1   /*  16n+0 */
69         mov.l   r1,@r5
70         add     #4,r5
71         mov.l   @r2+,r1   /*  16n+4 */
72         mov.l   r1,@r5
73         add     #4,r5
74         mov.l   @r2+,r1   /*  16n+8 */
75         mov.l   r1,@r5
76         add     #4,r5
77         mov.l   @r2+,r1   /*  16n+12 */
78         mov.l   r1,@r5
79         add     #4,r5
80         bf      5b
81
82         bra     0b
83         nop
84 6:
85 #ifdef CONFIG_SH_STANDARD_BIOS
86         ldc   r7, vbr
87 #endif
88         jmp @r6
89         nop
90
91         .align 2
92 10:
93         .long   PAGE_SIZE
94 11:
95         .long   0xa0000000
96
97 relocate_new_kernel_end:
98
99         .globl relocate_new_kernel_size
100 relocate_new_kernel_size:
101         .long relocate_new_kernel_end - relocate_new_kernel