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