x86, 32-bit: trim memory not covered by wb mtrrs
[deliverable/linux.git] / arch / x86 / kernel / relocate_kernel_32.S
1 /*
2 * relocate_kernel.S - put the kernel image in place to boot
3 * Copyright (C) 2002-2004 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.h>
11 #include <asm/kexec.h>
12
13 /*
14 * Must be relocatable PIC code callable as a C function
15 */
16
17 #define PTR(x) (x << 2)
18 #define PAGE_ALIGNED (1 << PAGE_SHIFT)
19 #define PAGE_ATTR 0x63 /* _PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY */
20 #define PAE_PGD_ATTR 0x01 /* _PAGE_PRESENT */
21
22 .text
23 .align PAGE_ALIGNED
24 .globl relocate_kernel
25 relocate_kernel:
26 movl 8(%esp), %ebp /* list of pages */
27
28 #ifdef CONFIG_X86_PAE
29 /* map the control page at its virtual address */
30
31 movl PTR(VA_PGD)(%ebp), %edi
32 movl PTR(VA_CONTROL_PAGE)(%ebp), %eax
33 andl $0xc0000000, %eax
34 shrl $27, %eax
35 addl %edi, %eax
36
37 movl PTR(PA_PMD_0)(%ebp), %edx
38 orl $PAE_PGD_ATTR, %edx
39 movl %edx, (%eax)
40
41 movl PTR(VA_PMD_0)(%ebp), %edi
42 movl PTR(VA_CONTROL_PAGE)(%ebp), %eax
43 andl $0x3fe00000, %eax
44 shrl $18, %eax
45 addl %edi, %eax
46
47 movl PTR(PA_PTE_0)(%ebp), %edx
48 orl $PAGE_ATTR, %edx
49 movl %edx, (%eax)
50
51 movl PTR(VA_PTE_0)(%ebp), %edi
52 movl PTR(VA_CONTROL_PAGE)(%ebp), %eax
53 andl $0x001ff000, %eax
54 shrl $9, %eax
55 addl %edi, %eax
56
57 movl PTR(PA_CONTROL_PAGE)(%ebp), %edx
58 orl $PAGE_ATTR, %edx
59 movl %edx, (%eax)
60
61 /* identity map the control page at its physical address */
62
63 movl PTR(VA_PGD)(%ebp), %edi
64 movl PTR(PA_CONTROL_PAGE)(%ebp), %eax
65 andl $0xc0000000, %eax
66 shrl $27, %eax
67 addl %edi, %eax
68
69 movl PTR(PA_PMD_1)(%ebp), %edx
70 orl $PAE_PGD_ATTR, %edx
71 movl %edx, (%eax)
72
73 movl PTR(VA_PMD_1)(%ebp), %edi
74 movl PTR(PA_CONTROL_PAGE)(%ebp), %eax
75 andl $0x3fe00000, %eax
76 shrl $18, %eax
77 addl %edi, %eax
78
79 movl PTR(PA_PTE_1)(%ebp), %edx
80 orl $PAGE_ATTR, %edx
81 movl %edx, (%eax)
82
83 movl PTR(VA_PTE_1)(%ebp), %edi
84 movl PTR(PA_CONTROL_PAGE)(%ebp), %eax
85 andl $0x001ff000, %eax
86 shrl $9, %eax
87 addl %edi, %eax
88
89 movl PTR(PA_CONTROL_PAGE)(%ebp), %edx
90 orl $PAGE_ATTR, %edx
91 movl %edx, (%eax)
92 #else
93 /* map the control page at its virtual address */
94
95 movl PTR(VA_PGD)(%ebp), %edi
96 movl PTR(VA_CONTROL_PAGE)(%ebp), %eax
97 andl $0xffc00000, %eax
98 shrl $20, %eax
99 addl %edi, %eax
100
101 movl PTR(PA_PTE_0)(%ebp), %edx
102 orl $PAGE_ATTR, %edx
103 movl %edx, (%eax)
104
105 movl PTR(VA_PTE_0)(%ebp), %edi
106 movl PTR(VA_CONTROL_PAGE)(%ebp), %eax
107 andl $0x003ff000, %eax
108 shrl $10, %eax
109 addl %edi, %eax
110
111 movl PTR(PA_CONTROL_PAGE)(%ebp), %edx
112 orl $PAGE_ATTR, %edx
113 movl %edx, (%eax)
114
115 /* identity map the control page at its physical address */
116
117 movl PTR(VA_PGD)(%ebp), %edi
118 movl PTR(PA_CONTROL_PAGE)(%ebp), %eax
119 andl $0xffc00000, %eax
120 shrl $20, %eax
121 addl %edi, %eax
122
123 movl PTR(PA_PTE_1)(%ebp), %edx
124 orl $PAGE_ATTR, %edx
125 movl %edx, (%eax)
126
127 movl PTR(VA_PTE_1)(%ebp), %edi
128 movl PTR(PA_CONTROL_PAGE)(%ebp), %eax
129 andl $0x003ff000, %eax
130 shrl $10, %eax
131 addl %edi, %eax
132
133 movl PTR(PA_CONTROL_PAGE)(%ebp), %edx
134 orl $PAGE_ATTR, %edx
135 movl %edx, (%eax)
136 #endif
137
138 relocate_new_kernel:
139 /* read the arguments and say goodbye to the stack */
140 movl 4(%esp), %ebx /* page_list */
141 movl 8(%esp), %ebp /* list of pages */
142 movl 12(%esp), %edx /* start address */
143 movl 16(%esp), %ecx /* cpu_has_pae */
144
145 /* zero out flags, and disable interrupts */
146 pushl $0
147 popfl
148
149 /* get physical address of control page now */
150 /* this is impossible after page table switch */
151 movl PTR(PA_CONTROL_PAGE)(%ebp), %edi
152
153 /* switch to new set of page tables */
154 movl PTR(PA_PGD)(%ebp), %eax
155 movl %eax, %cr3
156
157 /* setup a new stack at the end of the physical control page */
158 lea 4096(%edi), %esp
159
160 /* jump to identity mapped page */
161 movl %edi, %eax
162 addl $(identity_mapped - relocate_kernel), %eax
163 pushl %eax
164 ret
165
166 identity_mapped:
167 /* store the start address on the stack */
168 pushl %edx
169
170 /* Set cr0 to a known state:
171 * 31 0 == Paging disabled
172 * 18 0 == Alignment check disabled
173 * 16 0 == Write protect disabled
174 * 3 0 == No task switch
175 * 2 0 == Don't do FP software emulation.
176 * 0 1 == Proctected mode enabled
177 */
178 movl %cr0, %eax
179 andl $~((1<<31)|(1<<18)|(1<<16)|(1<<3)|(1<<2)), %eax
180 orl $(1<<0), %eax
181 movl %eax, %cr0
182
183 /* clear cr4 if applicable */
184 testl %ecx, %ecx
185 jz 1f
186 /* Set cr4 to a known state:
187 * Setting everything to zero seems safe.
188 */
189 movl %cr4, %eax
190 andl $0, %eax
191 movl %eax, %cr4
192
193 jmp 1f
194 1:
195
196 /* Flush the TLB (needed?) */
197 xorl %eax, %eax
198 movl %eax, %cr3
199
200 /* Do the copies */
201 movl %ebx, %ecx
202 jmp 1f
203
204 0: /* top, read another word from the indirection page */
205 movl (%ebx), %ecx
206 addl $4, %ebx
207 1:
208 testl $0x1, %ecx /* is it a destination page */
209 jz 2f
210 movl %ecx, %edi
211 andl $0xfffff000, %edi
212 jmp 0b
213 2:
214 testl $0x2, %ecx /* is it an indirection page */
215 jz 2f
216 movl %ecx, %ebx
217 andl $0xfffff000, %ebx
218 jmp 0b
219 2:
220 testl $0x4, %ecx /* is it the done indicator */
221 jz 2f
222 jmp 3f
223 2:
224 testl $0x8, %ecx /* is it the source indicator */
225 jz 0b /* Ignore it otherwise */
226 movl %ecx, %esi /* For every source page do a copy */
227 andl $0xfffff000, %esi
228
229 movl $1024, %ecx
230 rep ; movsl
231 jmp 0b
232
233 3:
234
235 /* To be certain of avoiding problems with self-modifying code
236 * I need to execute a serializing instruction here.
237 * So I flush the TLB, it's handy, and not processor dependent.
238 */
239 xorl %eax, %eax
240 movl %eax, %cr3
241
242 /* set all of the registers to known values */
243 /* leave %esp alone */
244
245 xorl %eax, %eax
246 xorl %ebx, %ebx
247 xorl %ecx, %ecx
248 xorl %edx, %edx
249 xorl %esi, %esi
250 xorl %edi, %edi
251 xorl %ebp, %ebp
252 ret
This page took 0.043175 seconds and 5 git commands to generate.