diff options
Diffstat (limited to 'arch/x86/boot/compressed/head_64.S')
-rw-r--r-- | arch/x86/boot/compressed/head_64.S | 111 |
1 files changed, 99 insertions, 12 deletions
diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S index c5c1ae0997e7..57e58a5fa210 100644 --- a/arch/x86/boot/compressed/head_64.S +++ b/arch/x86/boot/compressed/head_64.S | |||
@@ -113,7 +113,8 @@ ENTRY(startup_32) | |||
113 | lgdt gdt(%ebp) | 113 | lgdt gdt(%ebp) |
114 | 114 | ||
115 | /* Enable PAE mode */ | 115 | /* Enable PAE mode */ |
116 | movl $(X86_CR4_PAE), %eax | 116 | movl %cr4, %eax |
117 | orl $X86_CR4_PAE, %eax | ||
117 | movl %eax, %cr4 | 118 | movl %eax, %cr4 |
118 | 119 | ||
119 | /* | 120 | /* |
@@ -178,6 +179,13 @@ ENTRY(startup_32) | |||
178 | */ | 179 | */ |
179 | pushl $__KERNEL_CS | 180 | pushl $__KERNEL_CS |
180 | leal startup_64(%ebp), %eax | 181 | leal startup_64(%ebp), %eax |
182 | #ifdef CONFIG_EFI_MIXED | ||
183 | movl efi32_config(%ebp), %ebx | ||
184 | cmp $0, %ebx | ||
185 | jz 1f | ||
186 | leal handover_entry(%ebp), %eax | ||
187 | 1: | ||
188 | #endif | ||
181 | pushl %eax | 189 | pushl %eax |
182 | 190 | ||
183 | /* Enter paged protected Mode, activating Long Mode */ | 191 | /* Enter paged protected Mode, activating Long Mode */ |
@@ -188,6 +196,30 @@ ENTRY(startup_32) | |||
188 | lret | 196 | lret |
189 | ENDPROC(startup_32) | 197 | ENDPROC(startup_32) |
190 | 198 | ||
199 | #ifdef CONFIG_EFI_MIXED | ||
200 | .org 0x190 | ||
201 | ENTRY(efi32_stub_entry) | ||
202 | add $0x4, %esp /* Discard return address */ | ||
203 | popl %ecx | ||
204 | popl %edx | ||
205 | popl %esi | ||
206 | |||
207 | leal (BP_scratch+4)(%esi), %esp | ||
208 | call 1f | ||
209 | 1: pop %ebp | ||
210 | subl $1b, %ebp | ||
211 | |||
212 | movl %ecx, efi32_config(%ebp) | ||
213 | movl %edx, efi32_config+8(%ebp) | ||
214 | sgdtl efi32_boot_gdt(%ebp) | ||
215 | |||
216 | leal efi32_config(%ebp), %eax | ||
217 | movl %eax, efi_config(%ebp) | ||
218 | |||
219 | jmp startup_32 | ||
220 | ENDPROC(efi32_stub_entry) | ||
221 | #endif | ||
222 | |||
191 | .code64 | 223 | .code64 |
192 | .org 0x200 | 224 | .org 0x200 |
193 | ENTRY(startup_64) | 225 | ENTRY(startup_64) |
@@ -209,26 +241,48 @@ ENTRY(startup_64) | |||
209 | jmp preferred_addr | 241 | jmp preferred_addr |
210 | 242 | ||
211 | ENTRY(efi_pe_entry) | 243 | ENTRY(efi_pe_entry) |
212 | mov %rcx, %rdi | 244 | movq %rcx, efi64_config(%rip) /* Handle */ |
213 | mov %rdx, %rsi | 245 | movq %rdx, efi64_config+8(%rip) /* EFI System table pointer */ |
214 | pushq %rdi | 246 | |
215 | pushq %rsi | 247 | leaq efi64_config(%rip), %rax |
248 | movq %rax, efi_config(%rip) | ||
249 | |||
250 | call 1f | ||
251 | 1: popq %rbp | ||
252 | subq $1b, %rbp | ||
253 | |||
254 | /* | ||
255 | * Relocate efi_config->call(). | ||
256 | */ | ||
257 | addq %rbp, efi64_config+88(%rip) | ||
258 | |||
259 | movq %rax, %rdi | ||
216 | call make_boot_params | 260 | call make_boot_params |
217 | cmpq $0,%rax | 261 | cmpq $0,%rax |
218 | je 1f | 262 | je fail |
219 | mov %rax, %rdx | 263 | mov %rax, %rsi |
220 | popq %rsi | 264 | jmp 2f /* Skip the relocation */ |
221 | popq %rdi | ||
222 | 265 | ||
223 | ENTRY(efi_stub_entry) | 266 | handover_entry: |
267 | call 1f | ||
268 | 1: popq %rbp | ||
269 | subq $1b, %rbp | ||
270 | |||
271 | /* | ||
272 | * Relocate efi_config->call(). | ||
273 | */ | ||
274 | movq efi_config(%rip), %rax | ||
275 | addq %rbp, 88(%rax) | ||
276 | 2: | ||
277 | movq efi_config(%rip), %rdi | ||
224 | call efi_main | 278 | call efi_main |
225 | movq %rax,%rsi | 279 | movq %rax,%rsi |
226 | cmpq $0,%rax | 280 | cmpq $0,%rax |
227 | jne 2f | 281 | jne 2f |
228 | 1: | 282 | fail: |
229 | /* EFI init failed, so hang. */ | 283 | /* EFI init failed, so hang. */ |
230 | hlt | 284 | hlt |
231 | jmp 1b | 285 | jmp fail |
232 | 2: | 286 | 2: |
233 | call 3f | 287 | call 3f |
234 | 3: | 288 | 3: |
@@ -307,6 +361,20 @@ preferred_addr: | |||
307 | leaq relocated(%rbx), %rax | 361 | leaq relocated(%rbx), %rax |
308 | jmp *%rax | 362 | jmp *%rax |
309 | 363 | ||
364 | #ifdef CONFIG_EFI_STUB | ||
365 | .org 0x390 | ||
366 | ENTRY(efi64_stub_entry) | ||
367 | movq %rdi, efi64_config(%rip) /* Handle */ | ||
368 | movq %rsi, efi64_config+8(%rip) /* EFI System table pointer */ | ||
369 | |||
370 | leaq efi64_config(%rip), %rax | ||
371 | movq %rax, efi_config(%rip) | ||
372 | |||
373 | movq %rdx, %rsi | ||
374 | jmp handover_entry | ||
375 | ENDPROC(efi64_stub_entry) | ||
376 | #endif | ||
377 | |||
310 | .text | 378 | .text |
311 | relocated: | 379 | relocated: |
312 | 380 | ||
@@ -372,6 +440,25 @@ gdt: | |||
372 | .quad 0x0000000000000000 /* TS continued */ | 440 | .quad 0x0000000000000000 /* TS continued */ |
373 | gdt_end: | 441 | gdt_end: |
374 | 442 | ||
443 | #ifdef CONFIG_EFI_STUB | ||
444 | efi_config: | ||
445 | .quad 0 | ||
446 | |||
447 | #ifdef CONFIG_EFI_MIXED | ||
448 | .global efi32_config | ||
449 | efi32_config: | ||
450 | .fill 11,8,0 | ||
451 | .quad efi64_thunk | ||
452 | .byte 0 | ||
453 | #endif | ||
454 | |||
455 | .global efi64_config | ||
456 | efi64_config: | ||
457 | .fill 11,8,0 | ||
458 | .quad efi_call6 | ||
459 | .byte 1 | ||
460 | #endif /* CONFIG_EFI_STUB */ | ||
461 | |||
375 | /* | 462 | /* |
376 | * Stack and heap for uncompression | 463 | * Stack and heap for uncompression |
377 | */ | 464 | */ |