Merge master.kernel.org:/home/rmk/linux-2.6-arm
[linux-2.6] / arch / mips / kernel / relocate_kernel.S
1 /*
2  * relocate_kernel.S for kexec
3  * Created by <nschichan@corp.free.fr> on Thu Oct 12 17:49:57 2006
4  *
5  * This source code is licensed under the GNU General Public License,
6  * Version 2.  See the file COPYING for more details.
7  */
8
9 #include <asm/asm.h>
10 #include <asm/asmmacro.h>
11 #include <asm/regdef.h>
12 #include <asm/page.h>
13 #include <asm/mipsregs.h>
14 #include <asm/stackframe.h>
15 #include <asm/addrspace.h>
16
17 LEAF(relocate_new_kernel)
18         PTR_L           s0, kexec_indirection_page
19         PTR_L           s1, kexec_start_address
20
21 process_entry:
22         PTR_L           s2, (s0)
23         PTR_ADD         s0, s0, SZREG
24
25         /* destination page */
26         and             s3, s2, 0x1
27         beq             s3, zero, 1f
28         and             s4, s2, ~0x1    /* store destination addr in s4 */
29         move            a0, s4
30         b               process_entry
31
32 1:
33         /* indirection page, update s0  */
34         and             s3, s2, 0x2
35         beq             s3, zero, 1f
36         and             s0, s2, ~0x2
37         b               process_entry
38
39 1:
40         /* done page */
41         and             s3, s2, 0x4
42         beq             s3, zero, 1f
43         b               done
44 1:
45         /* source page */
46         and             s3, s2, 0x8
47         beq             s3, zero, process_entry
48         and             s2, s2, ~0x8
49         li              s6, (1 << PAGE_SHIFT) / SZREG
50
51 copy_word:
52         /* copy page word by word */
53         REG_L           s5, (s2)
54         REG_S           s5, (s4)
55         PTR_ADD         s4, s4, SZREG
56         PTR_ADD         s2, s2, SZREG
57         LONG_SUB        s6, s6, 1
58         beq             s6, zero, process_entry
59         b               copy_word
60         b               process_entry
61
62 done:
63         /* jump to kexec_start_address */
64         j               s1
65         END(relocate_new_kernel)
66
67 kexec_start_address:
68         EXPORT(kexec_start_address)
69         PTR             0x0
70         .size           kexec_start_address, PTRSIZE
71
72 kexec_indirection_page:
73         EXPORT(kexec_indirection_page)
74         PTR             0
75         .size           kexec_indirection_page, PTRSIZE
76
77 relocate_new_kernel_end:
78
79 relocate_new_kernel_size:
80         EXPORT(relocate_new_kernel_size)
81         PTR             relocate_new_kernel_end - relocate_new_kernel
82         .size           relocate_new_kernel_size, PTRSIZE