GNU Linux-libre 4.9.315-gnu1
[releases.git] / arch / x86 / boot / compressed / head_64.S
1 /*
2  *  linux/boot/head.S
3  *
4  *  Copyright (C) 1991, 1992, 1993  Linus Torvalds
5  */
6
7 /*
8  *  head.S contains the 32-bit startup code.
9  *
10  * NOTE!!! Startup happens at absolute address 0x00001000, which is also where
11  * the page directory will exist. The startup code will be overwritten by
12  * the page directory. [According to comments etc elsewhere on a compressed
13  * kernel it will end up at 0x1000 + 1Mb I hope so as I assume this. - AC]
14  *
15  * Page 0 is deliberately kept safe, since System Management Mode code in 
16  * laptops may need to access the BIOS data stored there.  This is also
17  * useful for future device drivers that either access the BIOS via VM86 
18  * mode.
19  */
20
21 /*
22  * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
23  */
24         .code32
25         .text
26
27 #include <linux/init.h>
28 #include <linux/linkage.h>
29 #include <asm/segment.h>
30 #include <asm/boot.h>
31 #include <asm/msr.h>
32 #include <asm/processor-flags.h>
33 #include <asm/asm-offsets.h>
34 #include <asm/bootparam.h>
35
36 /*
37  * Locally defined symbols should be marked hidden:
38  */
39         .hidden _bss
40         .hidden _ebss
41         .hidden _got
42         .hidden _egot
43         .hidden _end
44
45         __HEAD
46         .code32
47 ENTRY(startup_32)
48         /*
49          * 32bit entry is 0 and it is ABI so immutable!
50          * If we come here directly from a bootloader,
51          * kernel(text+data+bss+brk) ramdisk, zero_page, command line
52          * all need to be under the 4G limit.
53          */
54         cld
55         /*
56          * Test KEEP_SEGMENTS flag to see if the bootloader is asking
57          * us to not reload segments
58          */
59         testb $KEEP_SEGMENTS, BP_loadflags(%esi)
60         jnz 1f
61
62         cli
63         movl    $(__BOOT_DS), %eax
64         movl    %eax, %ds
65         movl    %eax, %es
66         movl    %eax, %ss
67 1:
68
69 /*
70  * Calculate the delta between where we were compiled to run
71  * at and where we were actually loaded at.  This can only be done
72  * with a short local call on x86.  Nothing  else will tell us what
73  * address we are running at.  The reserved chunk of the real-mode
74  * data at 0x1e4 (defined as a scratch field) are used as the stack
75  * for this calculation. Only 4 bytes are needed.
76  */
77         leal    (BP_scratch+4)(%esi), %esp
78         call    1f
79 1:      popl    %ebp
80         subl    $1b, %ebp
81
82 /* setup a stack and make sure cpu supports long mode. */
83         movl    $boot_stack_end, %eax
84         addl    %ebp, %eax
85         movl    %eax, %esp
86
87         call    verify_cpu
88         testl   %eax, %eax
89         jnz     no_longmode
90
91 /*
92  * Compute the delta between where we were compiled to run at
93  * and where the code will actually run at.
94  *
95  * %ebp contains the address we are loaded at by the boot loader and %ebx
96  * contains the address where we should move the kernel image temporarily
97  * for safe in-place decompression.
98  */
99
100 #ifdef CONFIG_RELOCATABLE
101         movl    %ebp, %ebx
102         movl    BP_kernel_alignment(%esi), %eax
103         decl    %eax
104         addl    %eax, %ebx
105         notl    %eax
106         andl    %eax, %ebx
107         cmpl    $LOAD_PHYSICAL_ADDR, %ebx
108         jae     1f
109 #endif
110         movl    $LOAD_PHYSICAL_ADDR, %ebx
111 1:
112
113         /* Target address to relocate to for decompression */
114         movl    BP_init_size(%esi), %eax
115         subl    $_end, %eax
116         addl    %eax, %ebx
117
118 /*
119  * Prepare for entering 64 bit mode
120  */
121
122         /* Load new GDT with the 64bit segments using 32bit descriptor */
123         leal    gdt(%ebp), %eax
124         movl    %eax, gdt+2(%ebp)
125         lgdt    gdt(%ebp)
126
127         /* Enable PAE mode */
128         movl    %cr4, %eax
129         orl     $X86_CR4_PAE, %eax
130         movl    %eax, %cr4
131
132  /*
133   * Build early 4G boot pagetable
134   */
135         /* Initialize Page tables to 0 */
136         leal    pgtable(%ebx), %edi
137         xorl    %eax, %eax
138         movl    $(BOOT_INIT_PGT_SIZE/4), %ecx
139         rep     stosl
140
141         /* Build Level 4 */
142         leal    pgtable + 0(%ebx), %edi
143         leal    0x1007 (%edi), %eax
144         movl    %eax, 0(%edi)
145
146         /* Build Level 3 */
147         leal    pgtable + 0x1000(%ebx), %edi
148         leal    0x1007(%edi), %eax
149         movl    $4, %ecx
150 1:      movl    %eax, 0x00(%edi)
151         addl    $0x00001000, %eax
152         addl    $8, %edi
153         decl    %ecx
154         jnz     1b
155
156         /* Build Level 2 */
157         leal    pgtable + 0x2000(%ebx), %edi
158         movl    $0x00000183, %eax
159         movl    $2048, %ecx
160 1:      movl    %eax, 0(%edi)
161         addl    $0x00200000, %eax
162         addl    $8, %edi
163         decl    %ecx
164         jnz     1b
165
166         /* Enable the boot page tables */
167         leal    pgtable(%ebx), %eax
168         movl    %eax, %cr3
169
170         /* Enable Long mode in EFER (Extended Feature Enable Register) */
171         movl    $MSR_EFER, %ecx
172         rdmsr
173         btsl    $_EFER_LME, %eax
174         wrmsr
175
176         /* After gdt is loaded */
177         xorl    %eax, %eax
178         lldt    %ax
179         movl    $__BOOT_TSS, %eax
180         ltr     %ax
181
182         /*
183          * Setup for the jump to 64bit mode
184          *
185          * When the jump is performend we will be in long mode but
186          * in 32bit compatibility mode with EFER.LME = 1, CS.L = 0, CS.D = 1
187          * (and in turn EFER.LMA = 1).  To jump into 64bit mode we use
188          * the new gdt/idt that has __KERNEL_CS with CS.L = 1.
189          * We place all of the values on our mini stack so lret can
190          * used to perform that far jump.
191          */
192         pushl   $__KERNEL_CS
193         leal    startup_64(%ebp), %eax
194 #ifdef CONFIG_EFI_MIXED
195         movl    efi32_config(%ebp), %ebx
196         cmp     $0, %ebx
197         jz      1f
198         leal    handover_entry(%ebp), %eax
199 1:
200 #endif
201         pushl   %eax
202
203         /* Enter paged protected Mode, activating Long Mode */
204         movl    $(X86_CR0_PG | X86_CR0_PE), %eax /* Enable Paging and Protected mode */
205         movl    %eax, %cr0
206
207         /* Jump from 32bit compatibility mode into 64bit mode. */
208         lret
209 ENDPROC(startup_32)
210
211 #ifdef CONFIG_EFI_MIXED
212         .org 0x190
213 ENTRY(efi32_stub_entry)
214         add     $0x4, %esp              /* Discard return address */
215         popl    %ecx
216         popl    %edx
217         popl    %esi
218
219         leal    (BP_scratch+4)(%esi), %esp
220         call    1f
221 1:      pop     %ebp
222         subl    $1b, %ebp
223
224         movl    %ecx, efi32_config(%ebp)
225         movl    %edx, efi32_config+8(%ebp)
226         sgdtl   efi32_boot_gdt(%ebp)
227
228         leal    efi32_config(%ebp), %eax
229         movl    %eax, efi_config(%ebp)
230
231         /* Disable paging */
232         movl    %cr0, %eax
233         btrl    $X86_CR0_PG_BIT, %eax
234         movl    %eax, %cr0
235
236         jmp     startup_32
237 ENDPROC(efi32_stub_entry)
238 #endif
239
240         .code64
241         .org 0x200
242 ENTRY(startup_64)
243         /*
244          * 64bit entry is 0x200 and it is ABI so immutable!
245          * We come here either from startup_32 or directly from a
246          * 64bit bootloader.
247          * If we come here from a bootloader, kernel(text+data+bss+brk),
248          * ramdisk, zero_page, command line could be above 4G.
249          * We depend on an identity mapped page table being provided
250          * that maps our entire kernel(text+data+bss+brk), zero page
251          * and command line.
252          */
253 #ifdef CONFIG_EFI_STUB
254         /*
255          * The entry point for the PE/COFF executable is efi_pe_entry, so
256          * only legacy boot loaders will execute this jmp.
257          */
258         jmp     preferred_addr
259
260 ENTRY(efi_pe_entry)
261         movq    %rcx, efi64_config(%rip)        /* Handle */
262         movq    %rdx, efi64_config+8(%rip) /* EFI System table pointer */
263
264         leaq    efi64_config(%rip), %rax
265         movq    %rax, efi_config(%rip)
266
267         call    1f
268 1:      popq    %rbp
269         subq    $1b, %rbp
270
271         /*
272          * Relocate efi_config->call().
273          */
274         addq    %rbp, efi64_config+32(%rip)
275
276         movq    %rax, %rdi
277         call    make_boot_params
278         cmpq    $0,%rax
279         je      fail
280         mov     %rax, %rsi
281         leaq    startup_32(%rip), %rax
282         movl    %eax, BP_code32_start(%rsi)
283         jmp     2f              /* Skip the relocation */
284
285 handover_entry:
286         call    1f
287 1:      popq    %rbp
288         subq    $1b, %rbp
289
290         /*
291          * Relocate efi_config->call().
292          */
293         movq    efi_config(%rip), %rax
294         addq    %rbp, 32(%rax)
295 2:
296         movq    efi_config(%rip), %rdi
297         call    efi_main
298         movq    %rax,%rsi
299         cmpq    $0,%rax
300         jne     2f
301 fail:
302         /* EFI init failed, so hang. */
303         hlt
304         jmp     fail
305 2:
306         movl    BP_code32_start(%esi), %eax
307         leaq    preferred_addr(%rax), %rax
308         jmp     *%rax
309
310 preferred_addr:
311 #endif
312
313         /* Setup data segments. */
314         xorl    %eax, %eax
315         movl    %eax, %ds
316         movl    %eax, %es
317         movl    %eax, %ss
318         movl    %eax, %fs
319         movl    %eax, %gs
320
321         /*
322          * Compute the decompressed kernel start address.  It is where
323          * we were loaded at aligned to a 2M boundary. %rbp contains the
324          * decompressed kernel start address.
325          *
326          * If it is a relocatable kernel then decompress and run the kernel
327          * from load address aligned to 2MB addr, otherwise decompress and
328          * run the kernel from LOAD_PHYSICAL_ADDR
329          *
330          * We cannot rely on the calculation done in 32-bit mode, since we
331          * may have been invoked via the 64-bit entry point.
332          */
333
334         /* Start with the delta to where the kernel will run at. */
335 #ifdef CONFIG_RELOCATABLE
336         leaq    startup_32(%rip) /* - $startup_32 */, %rbp
337         movl    BP_kernel_alignment(%rsi), %eax
338         decl    %eax
339         addq    %rax, %rbp
340         notq    %rax
341         andq    %rax, %rbp
342         cmpq    $LOAD_PHYSICAL_ADDR, %rbp
343         jae     1f
344 #endif
345         movq    $LOAD_PHYSICAL_ADDR, %rbp
346 1:
347
348         /* Target address to relocate to for decompression */
349         movl    BP_init_size(%rsi), %ebx
350         subl    $_end, %ebx
351         addq    %rbp, %rbx
352
353         /* Set up the stack */
354         leaq    boot_stack_end(%rbx), %rsp
355
356         /* Zero EFLAGS */
357         pushq   $0
358         popfq
359
360 /*
361  * Copy the compressed kernel to the end of our buffer
362  * where decompression in place becomes safe.
363  */
364         pushq   %rsi
365         leaq    (_bss-8)(%rip), %rsi
366         leaq    (_bss-8)(%rbx), %rdi
367         movq    $_bss /* - $startup_32 */, %rcx
368         shrq    $3, %rcx
369         std
370         rep     movsq
371         cld
372         popq    %rsi
373
374 /*
375  * Jump to the relocated address.
376  */
377         leaq    relocated(%rbx), %rax
378         jmp     *%rax
379
380 #ifdef CONFIG_EFI_STUB
381         .org 0x390
382 ENTRY(efi64_stub_entry)
383         movq    %rdi, efi64_config(%rip)        /* Handle */
384         movq    %rsi, efi64_config+8(%rip) /* EFI System table pointer */
385
386         leaq    efi64_config(%rip), %rax
387         movq    %rax, efi_config(%rip)
388
389         movq    %rdx, %rsi
390         jmp     handover_entry
391 ENDPROC(efi64_stub_entry)
392 #endif
393
394         .text
395 relocated:
396
397 /*
398  * Clear BSS (stack is currently empty)
399  */
400         xorl    %eax, %eax
401         leaq    _bss(%rip), %rdi
402         leaq    _ebss(%rip), %rcx
403         subq    %rdi, %rcx
404         shrq    $3, %rcx
405         rep     stosq
406
407 /*
408  * Adjust our own GOT
409  */
410         leaq    _got(%rip), %rdx
411         leaq    _egot(%rip), %rcx
412 1:
413         cmpq    %rcx, %rdx
414         jae     2f
415         addq    %rbx, (%rdx)
416         addq    $8, %rdx
417         jmp     1b
418 2:
419         
420 /*
421  * Do the extraction, and jump to the new kernel..
422  */
423         pushq   %rsi                    /* Save the real mode argument */
424         movq    %rsi, %rdi              /* real mode address */
425         leaq    boot_heap(%rip), %rsi   /* malloc area for uncompression */
426         leaq    input_data(%rip), %rdx  /* input_data */
427         movl    $z_input_len, %ecx      /* input_len */
428         movq    %rbp, %r8               /* output target address */
429         movq    $z_output_len, %r9      /* decompressed length, end of relocs */
430         call    extract_kernel          /* returns kernel location in %rax */
431         popq    %rsi
432
433 /*
434  * Jump to the decompressed kernel.
435  */
436         jmp     *%rax
437
438         .code32
439 no_longmode:
440         /* This isn't an x86-64 CPU so hang */
441 1:
442         hlt
443         jmp     1b
444
445 #include "../../kernel/verify_cpu.S"
446
447         .data
448 gdt:
449         .word   gdt_end - gdt
450         .long   gdt
451         .word   0
452         .quad   0x0000000000000000      /* NULL descriptor */
453         .quad   0x00af9a000000ffff      /* __KERNEL_CS */
454         .quad   0x00cf92000000ffff      /* __KERNEL_DS */
455         .quad   0x0080890000000000      /* TS descriptor */
456         .quad   0x0000000000000000      /* TS continued */
457 gdt_end:
458
459 #ifdef CONFIG_EFI_STUB
460 efi_config:
461         .quad   0
462
463 #ifdef CONFIG_EFI_MIXED
464         .global efi32_config
465 efi32_config:
466         .fill   4,8,0
467         .quad   efi64_thunk
468         .byte   0
469 #endif
470
471         .global efi64_config
472 efi64_config:
473         .fill   4,8,0
474         .quad   efi_call
475         .byte   1
476 #endif /* CONFIG_EFI_STUB */
477
478 /*
479  * Stack and heap for uncompression
480  */
481         .bss
482         .balign 4
483 boot_heap:
484         .fill BOOT_HEAP_SIZE, 1, 0
485 boot_stack:
486         .fill BOOT_STACK_SIZE, 1, 0
487 boot_stack_end:
488
489 /*
490  * Space for page tables (not in .bss so not zeroed)
491  */
492         .section ".pgtable","a",@nobits
493         .balign 4096
494 pgtable:
495         .fill BOOT_PGT_SIZE, 1, 0