.. | .. |
---|
10 | 10 | * needs to be able to service interrupts. |
---|
11 | 11 | * |
---|
12 | 12 | * On the plus side, we don't have to worry about mangling 64-bit |
---|
13 | | - * addresses into 32-bits because we're executing with an identify |
---|
| 13 | + * addresses into 32-bits because we're executing with an identity |
---|
14 | 14 | * mapped pagetable and haven't transitioned to 64-bit virtual addresses |
---|
15 | 15 | * yet. |
---|
16 | 16 | */ |
---|
.. | .. |
---|
23 | 23 | |
---|
24 | 24 | .code64 |
---|
25 | 25 | .text |
---|
26 | | -ENTRY(efi64_thunk) |
---|
| 26 | +SYM_FUNC_START(__efi64_thunk) |
---|
27 | 27 | push %rbp |
---|
28 | 28 | push %rbx |
---|
29 | 29 | |
---|
30 | | - subq $8, %rsp |
---|
31 | | - leaq efi_exit32(%rip), %rax |
---|
32 | | - movl %eax, 4(%rsp) |
---|
33 | | - leaq efi_gdt64(%rip), %rax |
---|
34 | | - movl %eax, (%rsp) |
---|
35 | | - movl %eax, 2(%rax) /* Fixup the gdt base address */ |
---|
| 30 | + leaq 1f(%rip), %rbp |
---|
36 | 31 | |
---|
37 | 32 | movl %ds, %eax |
---|
38 | 33 | push %rax |
---|
.. | .. |
---|
48 | 43 | movl %esi, 0x0(%rsp) |
---|
49 | 44 | movl %edx, 0x4(%rsp) |
---|
50 | 45 | movl %ecx, 0x8(%rsp) |
---|
51 | | - movq %r8, %rsi |
---|
52 | | - movl %esi, 0xc(%rsp) |
---|
53 | | - movq %r9, %rsi |
---|
54 | | - movl %esi, 0x10(%rsp) |
---|
| 46 | + movl %r8d, 0xc(%rsp) |
---|
| 47 | + movl %r9d, 0x10(%rsp) |
---|
55 | 48 | |
---|
56 | | - sgdt save_gdt(%rip) |
---|
57 | | - |
---|
58 | | - leaq 1f(%rip), %rbx |
---|
59 | | - movq %rbx, func_rt_ptr(%rip) |
---|
| 49 | + leaq 0x14(%rsp), %rbx |
---|
| 50 | + sgdt (%rbx) |
---|
60 | 51 | |
---|
61 | 52 | /* |
---|
62 | 53 | * Switch to gdt with 32-bit segments. This is the firmware GDT |
---|
63 | 54 | * that was installed when the kernel started executing. This |
---|
64 | 55 | * pointer was saved at the EFI stub entry point in head_64.S. |
---|
| 56 | + * |
---|
| 57 | + * Pass the saved DS selector to the 32-bit code, and use far return to |
---|
| 58 | + * restore the saved CS selector. |
---|
65 | 59 | */ |
---|
66 | 60 | leaq efi32_boot_gdt(%rip), %rax |
---|
67 | 61 | lgdt (%rax) |
---|
68 | 62 | |
---|
69 | | - pushq $__KERNEL_CS |
---|
| 63 | + movzwl efi32_boot_ds(%rip), %edx |
---|
| 64 | + movzwq efi32_boot_cs(%rip), %rax |
---|
| 65 | + pushq %rax |
---|
70 | 66 | leaq efi_enter32(%rip), %rax |
---|
71 | 67 | pushq %rax |
---|
72 | 68 | lretq |
---|
73 | 69 | |
---|
74 | 70 | 1: addq $32, %rsp |
---|
75 | | - |
---|
76 | | - lgdt save_gdt(%rip) |
---|
| 71 | + movq %rdi, %rax |
---|
77 | 72 | |
---|
78 | 73 | pop %rbx |
---|
79 | 74 | movl %ebx, %ss |
---|
.. | .. |
---|
81 | 76 | movl %ebx, %es |
---|
82 | 77 | pop %rbx |
---|
83 | 78 | movl %ebx, %ds |
---|
| 79 | + /* Clear out 32-bit selector from FS and GS */ |
---|
| 80 | + xorl %ebx, %ebx |
---|
| 81 | + movl %ebx, %fs |
---|
| 82 | + movl %ebx, %gs |
---|
84 | 83 | |
---|
85 | 84 | /* |
---|
86 | 85 | * Convert 32-bit status code into 64-bit. |
---|
87 | 86 | */ |
---|
88 | | - test %rax, %rax |
---|
89 | | - jz 1f |
---|
90 | | - movl %eax, %ecx |
---|
91 | | - andl $0x0fffffff, %ecx |
---|
92 | | - andl $0xf0000000, %eax |
---|
93 | | - shl $32, %rax |
---|
94 | | - or %rcx, %rax |
---|
95 | | -1: |
---|
96 | | - addq $8, %rsp |
---|
| 87 | + roll $1, %eax |
---|
| 88 | + rorq $1, %rax |
---|
| 89 | + |
---|
97 | 90 | pop %rbx |
---|
98 | 91 | pop %rbp |
---|
99 | | - ret |
---|
100 | | -ENDPROC(efi64_thunk) |
---|
101 | | - |
---|
102 | | -ENTRY(efi_exit32) |
---|
103 | | - movq func_rt_ptr(%rip), %rax |
---|
104 | | - push %rax |
---|
105 | | - mov %rdi, %rax |
---|
106 | | - ret |
---|
107 | | -ENDPROC(efi_exit32) |
---|
| 92 | + RET |
---|
| 93 | +SYM_FUNC_END(__efi64_thunk) |
---|
108 | 94 | |
---|
109 | 95 | .code32 |
---|
110 | 96 | /* |
---|
.. | .. |
---|
112 | 98 | * |
---|
113 | 99 | * The stack should represent the 32-bit calling convention. |
---|
114 | 100 | */ |
---|
115 | | -ENTRY(efi_enter32) |
---|
116 | | - movl $__KERNEL_DS, %eax |
---|
117 | | - movl %eax, %ds |
---|
118 | | - movl %eax, %es |
---|
119 | | - movl %eax, %ss |
---|
| 101 | +SYM_FUNC_START_LOCAL(efi_enter32) |
---|
| 102 | + /* Load firmware selector into data and stack segment registers */ |
---|
| 103 | + movl %edx, %ds |
---|
| 104 | + movl %edx, %es |
---|
| 105 | + movl %edx, %fs |
---|
| 106 | + movl %edx, %gs |
---|
| 107 | + movl %edx, %ss |
---|
120 | 108 | |
---|
121 | 109 | /* Reload pgtables */ |
---|
122 | 110 | movl %cr3, %eax |
---|
.. | .. |
---|
144 | 132 | */ |
---|
145 | 133 | cli |
---|
146 | 134 | |
---|
147 | | - movl 56(%esp), %eax |
---|
148 | | - movl %eax, 2(%eax) |
---|
149 | | - lgdtl (%eax) |
---|
| 135 | + lgdtl (%ebx) |
---|
150 | 136 | |
---|
151 | 137 | movl %cr4, %eax |
---|
152 | 138 | btsl $(X86_CR4_PAE_BIT), %eax |
---|
.. | .. |
---|
163 | 149 | xorl %eax, %eax |
---|
164 | 150 | lldt %ax |
---|
165 | 151 | |
---|
166 | | - movl 60(%esp), %eax |
---|
167 | 152 | pushl $__KERNEL_CS |
---|
168 | | - pushl %eax |
---|
| 153 | + pushl %ebp |
---|
169 | 154 | |
---|
170 | 155 | /* Enable paging */ |
---|
171 | 156 | movl %cr0, %eax |
---|
172 | 157 | btsl $X86_CR0_PG_BIT, %eax |
---|
173 | 158 | movl %eax, %cr0 |
---|
174 | 159 | lret |
---|
175 | | -ENDPROC(efi_enter32) |
---|
| 160 | +SYM_FUNC_END(efi_enter32) |
---|
176 | 161 | |
---|
177 | 162 | .data |
---|
178 | 163 | .balign 8 |
---|
179 | | - .global efi32_boot_gdt |
---|
180 | | -efi32_boot_gdt: .word 0 |
---|
181 | | - .quad 0 |
---|
182 | | - |
---|
183 | | -save_gdt: .word 0 |
---|
184 | | - .quad 0 |
---|
185 | | -func_rt_ptr: .quad 0 |
---|
186 | | - |
---|
187 | | - .global efi_gdt64 |
---|
188 | | -efi_gdt64: |
---|
189 | | - .word efi_gdt64_end - efi_gdt64 |
---|
190 | | - .long 0 /* Filled out by user */ |
---|
| 164 | +SYM_DATA_START(efi32_boot_gdt) |
---|
191 | 165 | .word 0 |
---|
192 | | - .quad 0x0000000000000000 /* NULL descriptor */ |
---|
193 | | - .quad 0x00af9a000000ffff /* __KERNEL_CS */ |
---|
194 | | - .quad 0x00cf92000000ffff /* __KERNEL_DS */ |
---|
195 | | - .quad 0x0080890000000000 /* TS descriptor */ |
---|
196 | | - .quad 0x0000000000000000 /* TS continued */ |
---|
197 | | -efi_gdt64_end: |
---|
| 166 | + .quad 0 |
---|
| 167 | +SYM_DATA_END(efi32_boot_gdt) |
---|
| 168 | + |
---|
| 169 | +SYM_DATA_START(efi32_boot_cs) |
---|
| 170 | + .word 0 |
---|
| 171 | +SYM_DATA_END(efi32_boot_cs) |
---|
| 172 | + |
---|
| 173 | +SYM_DATA_START(efi32_boot_ds) |
---|
| 174 | + .word 0 |
---|
| 175 | +SYM_DATA_END(efi32_boot_ds) |
---|