x86/boot/compressed/64: Call set_sev_encryption_mask() earlier
[linux-2.6-microblaze.git] / arch / x86 / boot / compressed / head_64.S
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  *  linux/boot/head.S
4  *
5  *  Copyright (C) 1991, 1992, 1993  Linus Torvalds
6  */
7
8 /*
9  *  head.S contains the 32-bit startup code.
10  *
11  * NOTE!!! Startup happens at absolute address 0x00001000, which is also where
12  * the page directory will exist. The startup code will be overwritten by
13  * the page directory. [According to comments etc elsewhere on a compressed
14  * kernel it will end up at 0x1000 + 1Mb I hope so as I assume this. - AC]
15  *
16  * Page 0 is deliberately kept safe, since System Management Mode code in 
17  * laptops may need to access the BIOS data stored there.  This is also
18  * useful for future device drivers that either access the BIOS via VM86 
19  * mode.
20  */
21
22 /*
23  * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
24  */
25         .code32
26         .text
27
28 #include <linux/init.h>
29 #include <linux/linkage.h>
30 #include <asm/segment.h>
31 #include <asm/boot.h>
32 #include <asm/msr.h>
33 #include <asm/processor-flags.h>
34 #include <asm/asm-offsets.h>
35 #include <asm/bootparam.h>
36 #include <asm/desc_defs.h>
37 #include "pgtable.h"
38
39 /*
40  * Locally defined symbols should be marked hidden:
41  */
42         .hidden _bss
43         .hidden _ebss
44         .hidden _got
45         .hidden _egot
46         .hidden _end
47
48         __HEAD
49         .code32
50 SYM_FUNC_START(startup_32)
51         /*
52          * 32bit entry is 0 and it is ABI so immutable!
53          * If we come here directly from a bootloader,
54          * kernel(text+data+bss+brk) ramdisk, zero_page, command line
55          * all need to be under the 4G limit.
56          */
57         cld
58         cli
59
60 /*
61  * Calculate the delta between where we were compiled to run
62  * at and where we were actually loaded at.  This can only be done
63  * with a short local call on x86.  Nothing  else will tell us what
64  * address we are running at.  The reserved chunk of the real-mode
65  * data at 0x1e4 (defined as a scratch field) are used as the stack
66  * for this calculation. Only 4 bytes are needed.
67  */
68         leal    (BP_scratch+4)(%esi), %esp
69         call    1f
70 1:      popl    %ebp
71         subl    $1b, %ebp
72
73         /* Load new GDT with the 64bit segments using 32bit descriptor */
74         leal    gdt(%ebp), %eax
75         movl    %eax, 2(%eax)
76         lgdt    (%eax)
77
78         /* Load segment registers with our descriptors */
79         movl    $__BOOT_DS, %eax
80         movl    %eax, %ds
81         movl    %eax, %es
82         movl    %eax, %fs
83         movl    %eax, %gs
84         movl    %eax, %ss
85
86 /* setup a stack and make sure cpu supports long mode. */
87         leal    boot_stack_end(%ebp), %esp
88
89         call    verify_cpu
90         testl   %eax, %eax
91         jnz     .Lno_longmode
92
93 /*
94  * Compute the delta between where we were compiled to run at
95  * and where the code will actually run at.
96  *
97  * %ebp contains the address we are loaded at by the boot loader and %ebx
98  * contains the address where we should move the kernel image temporarily
99  * for safe in-place decompression.
100  */
101
102 #ifdef CONFIG_RELOCATABLE
103         movl    %ebp, %ebx
104
105 #ifdef CONFIG_EFI_STUB
106 /*
107  * If we were loaded via the EFI LoadImage service, startup_32 will be at an
108  * offset to the start of the space allocated for the image. efi_pe_entry will
109  * set up image_offset to tell us where the image actually starts, so that we
110  * can use the full available buffer.
111  *      image_offset = startup_32 - image_base
112  * Otherwise image_offset will be zero and has no effect on the calculations.
113  */
114         subl    image_offset(%ebp), %ebx
115 #endif
116
117         movl    BP_kernel_alignment(%esi), %eax
118         decl    %eax
119         addl    %eax, %ebx
120         notl    %eax
121         andl    %eax, %ebx
122         cmpl    $LOAD_PHYSICAL_ADDR, %ebx
123         jae     1f
124 #endif
125         movl    $LOAD_PHYSICAL_ADDR, %ebx
126 1:
127
128         /* Target address to relocate to for decompression */
129         addl    BP_init_size(%esi), %ebx
130         subl    $_end, %ebx
131
132 /*
133  * Prepare for entering 64 bit mode
134  */
135
136         /* Enable PAE mode */
137         movl    %cr4, %eax
138         orl     $X86_CR4_PAE, %eax
139         movl    %eax, %cr4
140
141  /*
142   * Build early 4G boot pagetable
143   */
144         /*
145          * If SEV is active then set the encryption mask in the page tables.
146          * This will insure that when the kernel is copied and decompressed
147          * it will be done so encrypted.
148          */
149         call    get_sev_encryption_bit
150         xorl    %edx, %edx
151         testl   %eax, %eax
152         jz      1f
153         subl    $32, %eax       /* Encryption bit is always above bit 31 */
154         bts     %eax, %edx      /* Set encryption mask for page tables */
155 1:
156
157         /* Initialize Page tables to 0 */
158         leal    pgtable(%ebx), %edi
159         xorl    %eax, %eax
160         movl    $(BOOT_INIT_PGT_SIZE/4), %ecx
161         rep     stosl
162
163         /* Build Level 4 */
164         leal    pgtable + 0(%ebx), %edi
165         leal    0x1007 (%edi), %eax
166         movl    %eax, 0(%edi)
167         addl    %edx, 4(%edi)
168
169         /* Build Level 3 */
170         leal    pgtable + 0x1000(%ebx), %edi
171         leal    0x1007(%edi), %eax
172         movl    $4, %ecx
173 1:      movl    %eax, 0x00(%edi)
174         addl    %edx, 0x04(%edi)
175         addl    $0x00001000, %eax
176         addl    $8, %edi
177         decl    %ecx
178         jnz     1b
179
180         /* Build Level 2 */
181         leal    pgtable + 0x2000(%ebx), %edi
182         movl    $0x00000183, %eax
183         movl    $2048, %ecx
184 1:      movl    %eax, 0(%edi)
185         addl    %edx, 4(%edi)
186         addl    $0x00200000, %eax
187         addl    $8, %edi
188         decl    %ecx
189         jnz     1b
190
191         /* Enable the boot page tables */
192         leal    pgtable(%ebx), %eax
193         movl    %eax, %cr3
194
195         /* Enable Long mode in EFER (Extended Feature Enable Register) */
196         movl    $MSR_EFER, %ecx
197         rdmsr
198         btsl    $_EFER_LME, %eax
199         wrmsr
200
201         /* After gdt is loaded */
202         xorl    %eax, %eax
203         lldt    %ax
204         movl    $__BOOT_TSS, %eax
205         ltr     %ax
206
207         /*
208          * Setup for the jump to 64bit mode
209          *
210          * When the jump is performend we will be in long mode but
211          * in 32bit compatibility mode with EFER.LME = 1, CS.L = 0, CS.D = 1
212          * (and in turn EFER.LMA = 1).  To jump into 64bit mode we use
213          * the new gdt/idt that has __KERNEL_CS with CS.L = 1.
214          * We place all of the values on our mini stack so lret can
215          * used to perform that far jump.
216          */
217         leal    startup_64(%ebp), %eax
218 #ifdef CONFIG_EFI_MIXED
219         movl    efi32_boot_args(%ebp), %edi
220         cmp     $0, %edi
221         jz      1f
222         leal    efi64_stub_entry(%ebp), %eax
223         movl    efi32_boot_args+4(%ebp), %esi
224         movl    efi32_boot_args+8(%ebp), %edx   // saved bootparams pointer
225         cmpl    $0, %edx
226         jnz     1f
227         /*
228          * efi_pe_entry uses MS calling convention, which requires 32 bytes of
229          * shadow space on the stack even if all arguments are passed in
230          * registers. We also need an additional 8 bytes for the space that
231          * would be occupied by the return address, and this also results in
232          * the correct stack alignment for entry.
233          */
234         subl    $40, %esp
235         leal    efi_pe_entry(%ebp), %eax
236         movl    %edi, %ecx                      // MS calling convention
237         movl    %esi, %edx
238 1:
239 #endif
240         pushl   $__KERNEL_CS
241         pushl   %eax
242
243         /* Enter paged protected Mode, activating Long Mode */
244         movl    $(X86_CR0_PG | X86_CR0_PE), %eax /* Enable Paging and Protected mode */
245         movl    %eax, %cr0
246
247         /* Jump from 32bit compatibility mode into 64bit mode. */
248         lret
249 SYM_FUNC_END(startup_32)
250
251 #ifdef CONFIG_EFI_MIXED
252         .org 0x190
253 SYM_FUNC_START(efi32_stub_entry)
254         add     $0x4, %esp              /* Discard return address */
255         popl    %ecx
256         popl    %edx
257         popl    %esi
258
259         call    1f
260 1:      pop     %ebp
261         subl    $1b, %ebp
262
263         movl    %esi, efi32_boot_args+8(%ebp)
264 SYM_INNER_LABEL(efi32_pe_stub_entry, SYM_L_LOCAL)
265         movl    %ecx, efi32_boot_args(%ebp)
266         movl    %edx, efi32_boot_args+4(%ebp)
267         movb    $0, efi_is64(%ebp)
268
269         /* Save firmware GDTR and code/data selectors */
270         sgdtl   efi32_boot_gdt(%ebp)
271         movw    %cs, efi32_boot_cs(%ebp)
272         movw    %ds, efi32_boot_ds(%ebp)
273
274         /* Disable paging */
275         movl    %cr0, %eax
276         btrl    $X86_CR0_PG_BIT, %eax
277         movl    %eax, %cr0
278
279         jmp     startup_32
280 SYM_FUNC_END(efi32_stub_entry)
281 #endif
282
283         .code64
284         .org 0x200
285 SYM_CODE_START(startup_64)
286         /*
287          * 64bit entry is 0x200 and it is ABI so immutable!
288          * We come here either from startup_32 or directly from a
289          * 64bit bootloader.
290          * If we come here from a bootloader, kernel(text+data+bss+brk),
291          * ramdisk, zero_page, command line could be above 4G.
292          * We depend on an identity mapped page table being provided
293          * that maps our entire kernel(text+data+bss+brk), zero page
294          * and command line.
295          */
296
297         cld
298         cli
299
300         /* Setup data segments. */
301         xorl    %eax, %eax
302         movl    %eax, %ds
303         movl    %eax, %es
304         movl    %eax, %ss
305         movl    %eax, %fs
306         movl    %eax, %gs
307
308         /*
309          * Compute the decompressed kernel start address.  It is where
310          * we were loaded at aligned to a 2M boundary. %rbp contains the
311          * decompressed kernel start address.
312          *
313          * If it is a relocatable kernel then decompress and run the kernel
314          * from load address aligned to 2MB addr, otherwise decompress and
315          * run the kernel from LOAD_PHYSICAL_ADDR
316          *
317          * We cannot rely on the calculation done in 32-bit mode, since we
318          * may have been invoked via the 64-bit entry point.
319          */
320
321         /* Start with the delta to where the kernel will run at. */
322 #ifdef CONFIG_RELOCATABLE
323         leaq    startup_32(%rip) /* - $startup_32 */, %rbp
324
325 #ifdef CONFIG_EFI_STUB
326 /*
327  * If we were loaded via the EFI LoadImage service, startup_32 will be at an
328  * offset to the start of the space allocated for the image. efi_pe_entry will
329  * set up image_offset to tell us where the image actually starts, so that we
330  * can use the full available buffer.
331  *      image_offset = startup_32 - image_base
332  * Otherwise image_offset will be zero and has no effect on the calculations.
333  */
334         movl    image_offset(%rip), %eax
335         subq    %rax, %rbp
336 #endif
337
338         movl    BP_kernel_alignment(%rsi), %eax
339         decl    %eax
340         addq    %rax, %rbp
341         notq    %rax
342         andq    %rax, %rbp
343         cmpq    $LOAD_PHYSICAL_ADDR, %rbp
344         jae     1f
345 #endif
346         movq    $LOAD_PHYSICAL_ADDR, %rbp
347 1:
348
349         /* Target address to relocate to for decompression */
350         movl    BP_init_size(%rsi), %ebx
351         subl    $_end, %ebx
352         addq    %rbp, %rbx
353
354         /* Set up the stack */
355         leaq    boot_stack_end(%rbx), %rsp
356
357         /*
358          * paging_prepare() and cleanup_trampoline() below can have GOT
359          * references. Adjust the table with address we are running at.
360          *
361          * Zero RAX for adjust_got: the GOT was not adjusted before;
362          * there's no adjustment to undo.
363          */
364         xorq    %rax, %rax
365
366         /*
367          * Calculate the address the binary is loaded at and use it as
368          * a GOT adjustment.
369          */
370         call    1f
371 1:      popq    %rdi
372         subq    $1b, %rdi
373
374         call    .Ladjust_got
375
376         /*
377          * At this point we are in long mode with 4-level paging enabled,
378          * but we might want to enable 5-level paging or vice versa.
379          *
380          * The problem is that we cannot do it directly. Setting or clearing
381          * CR4.LA57 in long mode would trigger #GP. So we need to switch off
382          * long mode and paging first.
383          *
384          * We also need a trampoline in lower memory to switch over from
385          * 4- to 5-level paging for cases when the bootloader puts the kernel
386          * above 4G, but didn't enable 5-level paging for us.
387          *
388          * The same trampoline can be used to switch from 5- to 4-level paging
389          * mode, like when starting 4-level paging kernel via kexec() when
390          * original kernel worked in 5-level paging mode.
391          *
392          * For the trampoline, we need the top page table to reside in lower
393          * memory as we don't have a way to load 64-bit values into CR3 in
394          * 32-bit mode.
395          *
396          * We go though the trampoline even if we don't have to: if we're
397          * already in a desired paging mode. This way the trampoline code gets
398          * tested on every boot.
399          */
400
401         /* Make sure we have GDT with 32-bit code segment */
402         leaq    gdt64(%rip), %rax
403         addq    %rax, 2(%rax)
404         lgdt    (%rax)
405
406         /* Reload CS so IRET returns to a CS actually in the GDT */
407         pushq   $__KERNEL_CS
408         leaq    .Lon_kernel_cs(%rip), %rax
409         pushq   %rax
410         lretq
411
412 .Lon_kernel_cs:
413
414         pushq   %rsi
415         call    load_stage1_idt
416         popq    %rsi
417
418         /*
419          * paging_prepare() sets up the trampoline and checks if we need to
420          * enable 5-level paging.
421          *
422          * paging_prepare() returns a two-quadword structure which lands
423          * into RDX:RAX:
424          *   - Address of the trampoline is returned in RAX.
425          *   - Non zero RDX means trampoline needs to enable 5-level
426          *     paging.
427          *
428          * RSI holds real mode data and needs to be preserved across
429          * this function call.
430          */
431         pushq   %rsi
432         movq    %rsi, %rdi              /* real mode address */
433         call    paging_prepare
434         popq    %rsi
435
436         /* Save the trampoline address in RCX */
437         movq    %rax, %rcx
438
439         /*
440          * Load the address of trampoline_return() into RDI.
441          * It will be used by the trampoline to return to the main code.
442          */
443         leaq    trampoline_return(%rip), %rdi
444
445         /* Switch to compatibility mode (CS.L = 0 CS.D = 1) via far return */
446         pushq   $__KERNEL32_CS
447         leaq    TRAMPOLINE_32BIT_CODE_OFFSET(%rax), %rax
448         pushq   %rax
449         lretq
450 trampoline_return:
451         /* Restore the stack, the 32-bit trampoline uses its own stack */
452         leaq    boot_stack_end(%rbx), %rsp
453
454         /*
455          * cleanup_trampoline() would restore trampoline memory.
456          *
457          * RDI is address of the page table to use instead of page table
458          * in trampoline memory (if required).
459          *
460          * RSI holds real mode data and needs to be preserved across
461          * this function call.
462          */
463         pushq   %rsi
464         leaq    top_pgtable(%rbx), %rdi
465         call    cleanup_trampoline
466         popq    %rsi
467
468         /* Zero EFLAGS */
469         pushq   $0
470         popfq
471
472         /*
473          * Previously we've adjusted the GOT with address the binary was
474          * loaded at. Now we need to re-adjust for relocation address.
475          *
476          * Calculate the address the binary is loaded at, so that we can
477          * undo the previous GOT adjustment.
478          */
479         call    1f
480 1:      popq    %rax
481         subq    $1b, %rax
482
483         /* The new adjustment is the relocation address */
484         movq    %rbx, %rdi
485         call    .Ladjust_got
486
487 /*
488  * Copy the compressed kernel to the end of our buffer
489  * where decompression in place becomes safe.
490  */
491         pushq   %rsi
492         leaq    (_bss-8)(%rip), %rsi
493         leaq    (_bss-8)(%rbx), %rdi
494         movq    $_bss /* - $startup_32 */, %rcx
495         shrq    $3, %rcx
496         std
497         rep     movsq
498         cld
499         popq    %rsi
500
501         /*
502          * The GDT may get overwritten either during the copy we just did or
503          * during extract_kernel below. To avoid any issues, repoint the GDTR
504          * to the new copy of the GDT.
505          */
506         leaq    gdt64(%rbx), %rax
507         leaq    gdt(%rbx), %rdx
508         movq    %rdx, 2(%rax)
509         lgdt    (%rax)
510
511 /*
512  * Jump to the relocated address.
513  */
514         leaq    .Lrelocated(%rbx), %rax
515         jmp     *%rax
516 SYM_CODE_END(startup_64)
517
518 #ifdef CONFIG_EFI_STUB
519         .org 0x390
520 SYM_FUNC_START(efi64_stub_entry)
521 SYM_FUNC_START_ALIAS(efi_stub_entry)
522         and     $~0xf, %rsp                     /* realign the stack */
523         movq    %rdx, %rbx                      /* save boot_params pointer */
524         call    efi_main
525         movq    %rbx,%rsi
526         leaq    startup_64(%rax), %rax
527         jmp     *%rax
528 SYM_FUNC_END(efi64_stub_entry)
529 SYM_FUNC_END_ALIAS(efi_stub_entry)
530 #endif
531
532         .text
533 SYM_FUNC_START_LOCAL_NOALIGN(.Lrelocated)
534
535 /*
536  * Clear BSS (stack is currently empty)
537  */
538         xorl    %eax, %eax
539         leaq    _bss(%rip), %rdi
540         leaq    _ebss(%rip), %rcx
541         subq    %rdi, %rcx
542         shrq    $3, %rcx
543         rep     stosq
544
545 /*
546  * If running as an SEV guest, the encryption mask is required in the
547  * page-table setup code below. When the guest also has SEV-ES enabled
548  * set_sev_encryption_mask() will cause #VC exceptions, but the stage2
549  * handler can't map its GHCB because the page-table is not set up yet.
550  * So set up the encryption mask here while still on the stage1 #VC
551  * handler. Then load stage2 IDT and switch to the kernel's own
552  * page-table.
553  */
554         pushq   %rsi
555         call    set_sev_encryption_mask
556         call    load_stage2_idt
557         call    initialize_identity_maps
558         popq    %rsi
559
560 /*
561  * Do the extraction, and jump to the new kernel..
562  */
563         pushq   %rsi                    /* Save the real mode argument */
564         movq    %rsi, %rdi              /* real mode address */
565         leaq    boot_heap(%rip), %rsi   /* malloc area for uncompression */
566         leaq    input_data(%rip), %rdx  /* input_data */
567         movl    $z_input_len, %ecx      /* input_len */
568         movq    %rbp, %r8               /* output target address */
569         movl    $z_output_len, %r9d     /* decompressed length, end of relocs */
570         call    extract_kernel          /* returns kernel location in %rax */
571         popq    %rsi
572
573 /*
574  * Jump to the decompressed kernel.
575  */
576         jmp     *%rax
577 SYM_FUNC_END(.Lrelocated)
578
579 /*
580  * Adjust the global offset table
581  *
582  * RAX is the previous adjustment of the table to undo (use 0 if it's the
583  * first time we touch GOT).
584  * RDI is the new adjustment to apply.
585  */
586 .Ladjust_got:
587         /* Walk through the GOT adding the address to the entries */
588         leaq    _got(%rip), %rdx
589         leaq    _egot(%rip), %rcx
590 1:
591         cmpq    %rcx, %rdx
592         jae     2f
593         subq    %rax, (%rdx)    /* Undo previous adjustment */
594         addq    %rdi, (%rdx)    /* Apply the new adjustment */
595         addq    $8, %rdx
596         jmp     1b
597 2:
598         ret
599
600         .code32
601 /*
602  * This is the 32-bit trampoline that will be copied over to low memory.
603  *
604  * RDI contains the return address (might be above 4G).
605  * ECX contains the base address of the trampoline memory.
606  * Non zero RDX means trampoline needs to enable 5-level paging.
607  */
608 SYM_CODE_START(trampoline_32bit_src)
609         /* Set up data and stack segments */
610         movl    $__KERNEL_DS, %eax
611         movl    %eax, %ds
612         movl    %eax, %ss
613
614         /* Set up new stack */
615         leal    TRAMPOLINE_32BIT_STACK_END(%ecx), %esp
616
617         /* Disable paging */
618         movl    %cr0, %eax
619         btrl    $X86_CR0_PG_BIT, %eax
620         movl    %eax, %cr0
621
622         /* Check what paging mode we want to be in after the trampoline */
623         cmpl    $0, %edx
624         jz      1f
625
626         /* We want 5-level paging: don't touch CR3 if it already points to 5-level page tables */
627         movl    %cr4, %eax
628         testl   $X86_CR4_LA57, %eax
629         jnz     3f
630         jmp     2f
631 1:
632         /* We want 4-level paging: don't touch CR3 if it already points to 4-level page tables */
633         movl    %cr4, %eax
634         testl   $X86_CR4_LA57, %eax
635         jz      3f
636 2:
637         /* Point CR3 to the trampoline's new top level page table */
638         leal    TRAMPOLINE_32BIT_PGTABLE_OFFSET(%ecx), %eax
639         movl    %eax, %cr3
640 3:
641         /* Set EFER.LME=1 as a precaution in case hypervsior pulls the rug */
642         pushl   %ecx
643         pushl   %edx
644         movl    $MSR_EFER, %ecx
645         rdmsr
646         btsl    $_EFER_LME, %eax
647         wrmsr
648         popl    %edx
649         popl    %ecx
650
651         /* Enable PAE and LA57 (if required) paging modes */
652         movl    $X86_CR4_PAE, %eax
653         cmpl    $0, %edx
654         jz      1f
655         orl     $X86_CR4_LA57, %eax
656 1:
657         movl    %eax, %cr4
658
659         /* Calculate address of paging_enabled() once we are executing in the trampoline */
660         leal    .Lpaging_enabled - trampoline_32bit_src + TRAMPOLINE_32BIT_CODE_OFFSET(%ecx), %eax
661
662         /* Prepare the stack for far return to Long Mode */
663         pushl   $__KERNEL_CS
664         pushl   %eax
665
666         /* Enable paging again */
667         movl    $(X86_CR0_PG | X86_CR0_PE), %eax
668         movl    %eax, %cr0
669
670         lret
671 SYM_CODE_END(trampoline_32bit_src)
672
673         .code64
674 SYM_FUNC_START_LOCAL_NOALIGN(.Lpaging_enabled)
675         /* Return from the trampoline */
676         jmp     *%rdi
677 SYM_FUNC_END(.Lpaging_enabled)
678
679         /*
680          * The trampoline code has a size limit.
681          * Make sure we fail to compile if the trampoline code grows
682          * beyond TRAMPOLINE_32BIT_CODE_SIZE bytes.
683          */
684         .org    trampoline_32bit_src + TRAMPOLINE_32BIT_CODE_SIZE
685
686         .code32
687 SYM_FUNC_START_LOCAL_NOALIGN(.Lno_longmode)
688         /* This isn't an x86-64 CPU, so hang intentionally, we cannot continue */
689 1:
690         hlt
691         jmp     1b
692 SYM_FUNC_END(.Lno_longmode)
693
694 #include "../../kernel/verify_cpu.S"
695
696         .data
697 SYM_DATA_START_LOCAL(gdt64)
698         .word   gdt_end - gdt - 1
699         .quad   gdt - gdt64
700 SYM_DATA_END(gdt64)
701         .balign 8
702 SYM_DATA_START_LOCAL(gdt)
703         .word   gdt_end - gdt - 1
704         .long   0
705         .word   0
706         .quad   0x00cf9a000000ffff      /* __KERNEL32_CS */
707         .quad   0x00af9a000000ffff      /* __KERNEL_CS */
708         .quad   0x00cf92000000ffff      /* __KERNEL_DS */
709         .quad   0x0080890000000000      /* TS descriptor */
710         .quad   0x0000000000000000      /* TS continued */
711 SYM_DATA_END_LABEL(gdt, SYM_L_LOCAL, gdt_end)
712
713 SYM_DATA_START(boot_idt_desc)
714         .word   boot_idt_end - boot_idt - 1
715         .quad   0
716 SYM_DATA_END(boot_idt_desc)
717         .balign 8
718 SYM_DATA_START(boot_idt)
719         .rept   BOOT_IDT_ENTRIES
720         .quad   0
721         .quad   0
722         .endr
723 SYM_DATA_END_LABEL(boot_idt, SYM_L_GLOBAL, boot_idt_end)
724
725 #ifdef CONFIG_EFI_STUB
726 SYM_DATA(image_offset, .long 0)
727 #endif
728 #ifdef CONFIG_EFI_MIXED
729 SYM_DATA_LOCAL(efi32_boot_args, .long 0, 0, 0)
730 SYM_DATA(efi_is64, .byte 1)
731
732 #define ST32_boottime           60 // offsetof(efi_system_table_32_t, boottime)
733 #define BS32_handle_protocol    88 // offsetof(efi_boot_services_32_t, handle_protocol)
734 #define LI32_image_base         32 // offsetof(efi_loaded_image_32_t, image_base)
735
736         .text
737         .code32
738 SYM_FUNC_START(efi32_pe_entry)
739 /*
740  * efi_status_t efi32_pe_entry(efi_handle_t image_handle,
741  *                             efi_system_table_32_t *sys_table)
742  */
743
744         pushl   %ebp
745         movl    %esp, %ebp
746         pushl   %eax                            // dummy push to allocate loaded_image
747
748         pushl   %ebx                            // save callee-save registers
749         pushl   %edi
750
751         call    verify_cpu                      // check for long mode support
752         testl   %eax, %eax
753         movl    $0x80000003, %eax               // EFI_UNSUPPORTED
754         jnz     2f
755
756         call    1f
757 1:      pop     %ebx
758         subl    $1b, %ebx
759
760         /* Get the loaded image protocol pointer from the image handle */
761         leal    -4(%ebp), %eax
762         pushl   %eax                            // &loaded_image
763         leal    loaded_image_proto(%ebx), %eax
764         pushl   %eax                            // pass the GUID address
765         pushl   8(%ebp)                         // pass the image handle
766
767         /*
768          * Note the alignment of the stack frame.
769          *   sys_table
770          *   handle             <-- 16-byte aligned on entry by ABI
771          *   return address
772          *   frame pointer
773          *   loaded_image       <-- local variable
774          *   saved %ebx         <-- 16-byte aligned here
775          *   saved %edi
776          *   &loaded_image
777          *   &loaded_image_proto
778          *   handle             <-- 16-byte aligned for call to handle_protocol
779          */
780
781         movl    12(%ebp), %eax                  // sys_table
782         movl    ST32_boottime(%eax), %eax       // sys_table->boottime
783         call    *BS32_handle_protocol(%eax)     // sys_table->boottime->handle_protocol
784         addl    $12, %esp                       // restore argument space
785         testl   %eax, %eax
786         jnz     2f
787
788         movl    8(%ebp), %ecx                   // image_handle
789         movl    12(%ebp), %edx                  // sys_table
790         movl    -4(%ebp), %esi                  // loaded_image
791         movl    LI32_image_base(%esi), %esi     // loaded_image->image_base
792         movl    %ebx, %ebp                      // startup_32 for efi32_pe_stub_entry
793         /*
794          * We need to set the image_offset variable here since startup_32() will
795          * use it before we get to the 64-bit efi_pe_entry() in C code.
796          */
797         subl    %esi, %ebx
798         movl    %ebx, image_offset(%ebp)        // save image_offset
799         jmp     efi32_pe_stub_entry
800
801 2:      popl    %edi                            // restore callee-save registers
802         popl    %ebx
803         leave
804         ret
805 SYM_FUNC_END(efi32_pe_entry)
806
807         .section ".rodata"
808         /* EFI loaded image protocol GUID */
809         .balign 4
810 SYM_DATA_START_LOCAL(loaded_image_proto)
811         .long   0x5b1b31a1
812         .word   0x9562, 0x11d2
813         .byte   0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b
814 SYM_DATA_END(loaded_image_proto)
815 #endif
816
817 /*
818  * Stack and heap for uncompression
819  */
820         .bss
821         .balign 4
822 SYM_DATA_LOCAL(boot_heap,       .fill BOOT_HEAP_SIZE, 1, 0)
823
824 SYM_DATA_START_LOCAL(boot_stack)
825         .fill BOOT_STACK_SIZE, 1, 0
826         .balign 16
827 SYM_DATA_END_LABEL(boot_stack, SYM_L_LOCAL, boot_stack_end)
828
829 /*
830  * Space for page tables (not in .bss so not zeroed)
831  */
832         .section ".pgtable","aw",@nobits
833         .balign 4096
834 SYM_DATA_LOCAL(pgtable,         .fill BOOT_PGT_SIZE, 1, 0)
835
836 /*
837  * The page table is going to be used instead of page table in the trampoline
838  * memory.
839  */
840 SYM_DATA_LOCAL(top_pgtable,     .fill PAGE_SIZE, 1, 0)