9652 loader.efi: use explicit lea in multiboot_tramp.S
[unleashed.git] / usr / src / boot / sys / boot / efi / loader / arch / amd64 / multiboot_tramp.S
blob061c638b59d7dc45ef9b3a70253b2fec02bbd67d
1 /*
2  * This file and its contents are supplied under the terms of the
3  * Common Development and Distribution License ("CDDL"), version 1.0.
4  * You may only use this file in accordance with the terms of version
5  * 1.0 of the CDDL.
6  *
7  * A full copy of the text of the CDDL should have accompanied this
8  * source.  A copy of the CDDL is also available via the Internet at
9  * http://www.illumos.org/license/CDDL.
10  */
13  * Copyright 2016 Toomas Soome <tsoome@me.com>
14  */
16 #include <x86/specialreg.h>
18         .file   "multiboot_tramp.s"
21  * The current dboot in illumos kernel is running in 32bit mode
22  * and expecting following 32-bit multiboot execution environment:
23  *
24  * EAX: MB magic
25  * EBX: 32-bit physical address of MBI
26  * CS: 32-bit read/execute code segment with offset 0 and limit 0xFFFFFFFF
27  * DS: 32-bit read/write code segment with offset 0 and limit 0xFFFFFFFF
28  * ES: 32-bit read/write code segment with offset 0 and limit 0xFFFFFFFF
29  * FS: 32-bit read/write code segment with offset 0 and limit 0xFFFFFFFF
30  * GS: 32-bit read/write code segment with offset 0 and limit 0xFFFFFFFF
31  * SS: 32-bit read/write data segment with offset 0 and limit 0xFFFFFFFF
32  * A20 enabled
33  * CR0: PG cleared, PE set
34  * EFLAGS: VM cleared, IF cleared
35  * interrupts disabled
36  */
38                 .set    SEL_SCODE,0x8
39                 .set    SEL_SDATA,0x10
41                 .text
42                 .p2align 4
43                 .globl  multiboot_tramp
44                 .type   multiboot_tramp, STT_FUNC
47  * void multiboot_tramp(uint32_t magic, struct relocator *relocator,
48  *    uint64_t entry)
49  */
50 multiboot_tramp:
51                 cli
52                 movq    (%rsi), %rax
53                 movq    %rax, %rsp              /* Switch to temporary stack. */
54                 movq    0x8(%rsi), %rax         /* relocator->copy */
55                 pushq   %rdi                    /* save magic */
56                 pushq   %rdx                    /* save entry */
57                 movq    %rsi, %rdi
58                 callq   *%rax
59                 movq    %rax, %rbx              /* MBI */
60                 popq    %rsi                    /* entry to rsi */
61                 popq    %rdi                    /* restore magic */
62                 lea     gdt(%rip), %rax
63                 lea     gdtaddr(%rip), %rdx
64                 movq    %rax, (%rdx)
65                 lea     gdtdesc(%rip), %rax
66                 lgdt    (%rax)
68                 /* record the address */
69                 lea     multiboot_tramp_2(%rip), %rcx
70                 movq    %rsp, %rax
71                 pushq   $SEL_SDATA
72                 pushq   %rax
73                 pushf
74                 pushq   $SEL_SCODE
75                 lea     multiboot_tramp_1(%rip), %rax
76                 pushq   %rax
77                 iretq
79                 .code32
80 multiboot_tramp_1:
81                 movl    $SEL_SDATA, %eax
82                 movw    %ax, %ss
83                 movw    %ax, %ds
84                 movw    %ax, %es
85                 movw    %ax, %fs
86                 movw    %ax, %gs
88                 movl    %cr0, %eax              /* disable paging */
89                 btrl    $31, %eax
90                 movl    %eax, %cr0
91                 jmp     *%ecx
92 multiboot_tramp_2:
93                 movl    %cr4, %eax              /* disable PAE, PGE, PSE */
94                 andl    $~(CR4_PGE | CR4_PAE | CR4_PSE), %eax
95                 movl    %eax, %cr4
96                 movl    $MSR_EFER, %ecx
97                 rdmsr                           /* updates %edx:%eax */
98                 btcl    $8, %eax                /* clear long mode */
99                 wrmsr
100                 movl    %edi, %eax              /* magic */
101                 jmp     *%esi                   /* jump to kernel */
103 /* GDT record */
104                 .p2align 4
105 gdt:
106                 .word   0x0, 0x0                /* NULL entry */
107                 .byte   0x0, 0x0, 0x0, 0x0
108                 .word   0xffff, 0x0             /* code segment */
109                 .byte   0x0, 0x9a, 0xcf, 0x0
110                 .word   0xffff, 0x0             /* data segment */
111                 .byte   0x0, 0x92, 0xcf, 0x0
112 gdt_end:
114                 .p2align 4
115 gdtdesc:        .word   gdt_end - gdt - 1       /* limit */
116 gdtaddr:        .long   0                       /* base */
117                 .long   0
119 multiboot_tramp_end: