]> bbs.cooldavid.org Git - net-next-2.6.git/blob - arch/x86/kernel/relocate_kernel_64.S
x86, kexec: fix kexec x86 coding style
[net-next-2.6.git] / arch / x86 / kernel / relocate_kernel_64.S
1 /*
2  * relocate_kernel.S - put the kernel image in place to boot
3  * Copyright (C) 2002-2005 Eric Biederman  <ebiederm@xmission.com>
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 <linux/linkage.h>
10 #include <asm/page_types.h>
11 #include <asm/kexec.h>
12 #include <asm/processor-flags.h>
13 #include <asm/pgtable_types.h>
14
15 /*
16  * Must be relocatable PIC code callable as a C function
17  */
18
19 #define PTR(x) (x << 3)
20 #define PAGE_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
21
22         .text
23         .align PAGE_SIZE
24         .code64
25         .globl relocate_kernel
26 relocate_kernel:
27         /*
28          * %rdi indirection_page
29          * %rsi page_list
30          * %rdx start address
31          */
32
33         /* zero out flags, and disable interrupts */
34         pushq $0
35         popfq
36
37         /*
38          * get physical address of control page now
39          * this is impossible after page table switch
40          */
41         movq    PTR(PA_CONTROL_PAGE)(%rsi), %r8
42
43         /* get physical address of page table now too */
44         movq    PTR(PA_TABLE_PAGE)(%rsi), %rcx
45
46         /* Switch to the identity mapped page tables */
47         movq    %rcx, %cr3
48
49         /* setup a new stack at the end of the physical control page */
50         lea     PAGE_SIZE(%r8), %rsp
51
52         /* jump to identity mapped page */
53         addq    $(identity_mapped - relocate_kernel), %r8
54         pushq   %r8
55         ret
56
57 identity_mapped:
58         /* store the start address on the stack */
59         pushq   %rdx
60
61         /*
62          * Set cr0 to a known state:
63          *  - Paging enabled
64          *  - Alignment check disabled
65          *  - Write protect disabled
66          *  - No task switch
67          *  - Don't do FP software emulation.
68          *  - Proctected mode enabled
69          */
70         movq    %cr0, %rax
71         andq    $~(X86_CR0_AM | X86_CR0_WP | X86_CR0_TS | X86_CR0_EM), %rax
72         orl     $(X86_CR0_PG | X86_CR0_PE), %eax
73         movq    %rax, %cr0
74
75         /*
76          * Set cr4 to a known state:
77          *  - physical address extension enabled
78          */
79         movq    $X86_CR4_PAE, %rax
80         movq    %rax, %cr4
81
82         jmp 1f
83 1:
84
85         /* Flush the TLB (needed?) */
86         movq    %rcx, %cr3
87
88         /* Do the copies */
89         movq    %rdi, %rcx      /* Put the page_list in %rcx */
90         xorq    %rdi, %rdi
91         xorq    %rsi, %rsi
92         jmp     1f
93
94 0:      /* top, read another word for the indirection page */
95
96         movq    (%rbx), %rcx
97         addq    $8,     %rbx
98 1:
99         testq   $0x1,   %rcx  /* is it a destination page? */
100         jz      2f
101         movq    %rcx,   %rdi
102         andq    $0xfffffffffffff000, %rdi
103         jmp     0b
104 2:
105         testq   $0x2,   %rcx  /* is it an indirection page? */
106         jz      2f
107         movq    %rcx,   %rbx
108         andq    $0xfffffffffffff000, %rbx
109         jmp     0b
110 2:
111         testq   $0x4,   %rcx  /* is it the done indicator? */
112         jz      2f
113         jmp     3f
114 2:
115         testq   $0x8,   %rcx  /* is it the source indicator? */
116         jz      0b            /* Ignore it otherwise */
117         movq    %rcx,   %rsi  /* For ever source page do a copy */
118         andq    $0xfffffffffffff000, %rsi
119
120         movq    $512,   %rcx
121         rep ; movsq
122         jmp     0b
123 3:
124
125         /*
126          * To be certain of avoiding problems with self-modifying code
127          * I need to execute a serializing instruction here.
128          * So I flush the TLB by reloading %cr3 here, it's handy,
129          * and not processor dependent.
130          */
131         movq    %cr3, %rax
132         movq    %rax, %cr3
133
134         /*
135          * set all of the registers to known values
136          * leave %rsp alone
137          */
138
139         xorq    %rax, %rax
140         xorq    %rbx, %rbx
141         xorq    %rcx, %rcx
142         xorq    %rdx, %rdx
143         xorq    %rsi, %rsi
144         xorq    %rdi, %rdi
145         xorq    %rbp, %rbp
146         xorq    %r8,  %r8
147         xorq    %r9,  %r9
148         xorq    %r10, %r9
149         xorq    %r11, %r11
150         xorq    %r12, %r12
151         xorq    %r13, %r13
152         xorq    %r14, %r14
153         xorq    %r15, %r15
154
155         ret