~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to arch/sh/kernel/relocate_kernel.S

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
17
relocate_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
 
 
148
swap_pages:
 
149
        bra     1f
 
150
         mov    r4,r0     /* cmd = indirection_page */
 
151
0:
 
152
        mov.l   @r4+,r0   /* cmd = *ind++ */
 
153
 
 
154
1:      /* 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
 
 
165
2:      /* else if(cmd & IND_INDIRECTION) ind = addr  */
 
166
        tst     #2,r0
 
167
        bt      3f
 
168
        bra     0b
 
169
         mov    r2,r4
 
170
 
 
171
3:      /* else if(cmd & IND_DONE) return */
 
172
        tst     #4,r0
 
173
        bt      4f
 
174
        rts
 
175
         nop
 
176
 
 
177
4:      /* 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
 
184
5:
 
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
 
221
10:
 
222
        .long   PAGE_SIZE
 
223
11:
 
224
        .long   0
 
225
12:
 
226
        .long   0x20000000 ! RB=1
 
227
 
 
228
relocate_new_kernel_end:
 
229
 
 
230
        .globl relocate_new_kernel_size
 
231
relocate_new_kernel_size:
 
232
        .long relocate_new_kernel_end - relocate_new_kernel