]> git.proxmox.com Git - mirror_edk2.git/blob - EdkModulePkg/Core/DxeIplX64Peim/x64/LongMode.S
273b3d5bc22305ca3033487f630bedf30d0a729d
[mirror_edk2.git] / EdkModulePkg / Core / DxeIplX64Peim / x64 / LongMode.S
1 #------------------------------------------------------------------------------
2 #*
3 #* Copyright (c) 2006, Intel Corporation
4 #* All rights reserved. This program and the accompanying materials
5 #* are licensed and made available under the terms and conditions of the BSD License
6 #* which accompanies this distribution. The full text of the license may be found at
7 #* http://opensource.org/licenses/bsd-license.php
8 #*
9 #* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 #* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11 #*
12 #* LongMode.S
13 #*
14 #* Abstract:
15 #*
16 #* Transition from 32-bit protected mode EFI environment into x64
17 #* 64-bit bit long mode.
18 #*
19 #* This file is not fully ported or operational.
20 #*
21 #------------------------------------------------------------------------------
22
23 .686p:
24 #.MODEL flat
25
26 #
27 # Create the exception handler code in IA32 C code
28 #
29
30 .code:
31 .stack:
32 .MMX:
33 .XMM:
34
35 .global _LoadGo64Gdt;
36 _LoadGo64Gdt:
37 pushl %ebp # C prolog
38 pushl %edi
39 movl %esp, %ebp
40 #
41 # Disable interrupts
42 #
43 cli
44 #
45 # Reload the selectors
46 # Note:
47 # Make the Selectors 64-bit ready
48 #
49 movl gdtr, %edi # Load GDT register
50 movw %cs, %ax # Get the selector data from our code image
51 mov %ax, %es
52 # FIXME MISMATCH: " lgdt FWORD PTR es:[edi] "
53
54 .byte 0x67
55 .byte 0xea # Far Jump Offset:Selector to reload CS
56 # FIXME MISMATCH: " dd OFFSET DataSelectorRld"
57 # FIXME MISMATCH: " dw LINEAR_CODE_SEL "
58 DataSelectorRld:
59 movw SYS_DATA_SEL, %ax # Update the Base for the new selectors, too
60 movw %ax, %ds
61 movw %ax, %es
62 movw %ax, %fs
63 movw %ax, %gs
64 movw %ax, %ss
65
66 popl %edi
67 popl %ebp
68 ret
69 #_LoadGo64Gdt ENDP
70
71
72 # VOID
73 # ActivateLongMode (
74 # IN EFI_PHYSICAL_ADDRESS PageTables,
75 # IN EFI_PHYSICAL_ADDRESS HobStart,
76 # IN EFI_PHYSICAL_ADDRESS Stack,
77 # IN EFI_PHYSICAL_ADDRESS PpisNeededByDxeIplEntryPoint,
78 # IN EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint
79 # )
80 #
81 # Input: [ebp][0h] = Original ebp
82 # [ebp][4h] = Return address
83 # [ebp][8h] = PageTables
84 # [ebp][10h] = HobStart
85 # [ebp][18h] = Stack
86 # [ebp][20h] = CodeEntryPoint1 <--- Call this first (for each call, pass HOB pointer)
87 # [ebp][28h] = CodeEntryPoint2 <--- Call this second
88 #
89 #
90 .global _ActivateLongMode;
91 _ActivateLongMode:
92 pushl %ebp # C prolog
93 movl %esp, %ebp
94
95 #
96 # Use CPUID to determine if the processor supports long mode.
97 #
98 movl $0x80000000, %eax # Extended-function code 8000000h.
99 cpuid # Is largest extended function
100 cmpl $0x80000000, %eax # any function > 80000000h?
101 jbe no_long_mode # If not, no long mode.
102 movl $0x80000001, %eax # Extended-function code 8000001h.
103 cpuid # Now EDX = extended-features flags.
104 btl $29, %edx # Test if long mode is supported.
105 jnc no_long_mode # Exit if not supported.
106
107 #
108 # Enable the 64-bit page-translation-table entries by
109 # setting CR4.PAE=1 (this is _required_ before activating
110 # long mode). Paging is not enabled until after long mode
111 # is enabled.
112 #
113 movl %cr4, %eax
114 btsl $5, %eax
115 movl %eax, %cr4
116
117 #
118 # Get the long-mode page tables, and initialize the
119 # 64-bit CR3 (page-table base address) to point to the base
120 # of the PML4 page table. The PML4 page table must be located
121 # below 4 Gbytes because only 32 bits of CR3 are loaded when
122 # the processor is not in 64-bit mode.
123 #
124 movl 0x8(%ebp), %eax # Get Page Tables
125 movl %eax, %cr3 # Initialize CR3 with PML4 base.
126
127 #
128 # Enable long mode (set EFER.LME=1).
129 #
130 movl $0xc0000080, %ecx # EFER MSR number.
131 rdmsr # Read EFER.
132 btsl $8, %eax # Set LME=1.
133 wrmsr # Write EFER.
134
135 #
136 # Enable paging to activate long mode (set CR0.PG=1)
137 #
138
139
140 movl %cr0, %eax # Read CR0.
141 btsl $31, %eax # Set PG=1.
142 movl %eax, %cr0 # Write CR0.
143 jmp go_to_long_mode
144 go_to_long_mode:
145
146 #
147 # This is the next instruction after enabling paging. Jump to long mode
148 #
149 .byte 0x67
150 .byte 0xea # Far Jump Offset:Selector to reload CS
151 #FIXME MISMATCH: " dd OFFSET in_long_mode"
152 #FIXME MISMATCH: " dw SYS_CODE64_SEL "
153 in_long_mode:
154 movw SYS_DATA64_SEL, %ax
155 movw %ax, %es
156 movw %ax, %ss
157 movw %ax, %ds
158 jmp .
159
160
161 #
162 # We're in long mode, so marshall the arguments to call the
163 # passed in function pointers
164 # Recall
165 # [ebp][10h] = HobStart
166 # [ebp][18h] = Stack
167 # [ebp][20h] = PpisNeededByDxeIplEntryPoint <--- Call this first (for each call, pass HOB pointer)
168 # [ebp][28h] = DxeCoreEntryPoint <--- Call this second
169 #
170 .byte 0x48
171 movl 0x18(%ebp), %ebx # Setup the stack
172 .byte 0x48
173 movl %ebx, %esp # On a new stack now
174
175
176 ## 00000905 FF D0 call rax
177
178 .byte 0x48
179 movl 0x10(%ebp), %ecx # Pass Hob Start in RCX
180 .byte 0x48
181 movl 0x28(%ebp), %eax # Get the function pointer for
182 # DxeCoreEntryPoint into EAX
183
184 ## 00000905 FF D0 call rax
185 .byte 0xff
186 .byte 0xd0
187
188 #
189 # WE SHOULD NEVER GET HERE!!!!!!!!!!!!!
190 #
191 no_long_mode:
192 jmp no_long_mode
193 #_ActivateLongMode ENDP
194
195 .align 16
196
197 gdtr: #FIXME MISMATCH: "gdtr dw _GDT_END - _GDT_BASE - 1 "
198 #FIXME MISMATCH: " dd OFFSET _GDT_BASE "
199
200 #-----------------------------------------------------------------------------;
201 # global descriptor table (GDT)
202 #-----------------------------------------------------------------------------;
203
204 .align 16
205
206 .global _GDT_BASE
207 _GDT_BASE:
208 # null descriptor
209 .equ NULL_SEL, .-_GDT_BASE # Selector [0]
210 .word 0 # limit 15:0
211 .word 0 # base 15:0
212 .byte 0 # base 23:16
213 .byte 0 # type
214 .byte 0 # limit 19:16, flags
215 .byte 0 # base 31:24
216
217 # linear data segment descriptor
218 .equ LINEAR_SEL, .-_GDT_BASE # Selector [0x8]
219 .word 0xFFFF # limit 0xFFFFF
220 .word 0 # base 0
221 .byte 0
222 .byte 0x92 # present, ring 0, data, expand-up, writable
223 .byte 0xCF # page-granular, 32-bit
224 .byte 0
225
226 # linear code segment descriptor
227 .equ LINEAR_CODE_SEL, .-_GDT_BASE # Selector [0x10]
228 .word 0xFFFF # limit 0xFFFFF
229 .word 0 # base 0
230 .byte 0
231 .byte 0x9F # present, ring 0, data, expand-up, writable
232 .byte 0xCF # page-granular, 32-bit
233 .byte 0
234
235 # system data segment descriptor
236 .equ SYS_DATA_SEL, .-_GDT_BASE # Selector [0x18]
237 .word 0xFFFF # limit 0xFFFFF
238 .word 0 # base 0
239 .byte 0
240 .byte 0x93 # present, ring 0, data, expand-up, writable
241 .byte 0xCF # page-granular, 32-bit
242 .byte 0
243
244 # system code segment descriptor
245 .equ SYS_CODE_SEL, .-_GDT_BASE # Selector [0x20]
246 .word 0xFFFF # limit 0xFFFFF
247 .word 0 # base 0
248 .byte 0
249 .byte 0x9A # present, ring 0, data, expand-up, writable
250 .byte 0xCF # page-granular, 32-bit
251 .byte 0
252
253 # spare segment descriptor
254 .equ SPARE3_SEL, .-_GDT_BASE # Selector [0x28]
255 .word 0 # limit 0xFFFFF
256 .word 0 # base 0
257 .byte 0
258 .byte 0 # present, ring 0, data, expand-up, writable
259 .byte 0 # page-granular, 32-bit
260 .byte 0
261
262 #
263 # system data segment descriptor
264 #
265 .equ SYS_DATA64_SEL, .-_GDT_BASE # Selector [0x30]
266 .word 0xFFFF # limit 0xFFFFF
267 .word 0 # base 0
268 .byte 0
269 .byte 0x92 # P | DPL [1..2] | 1 | 1 | C | R | A
270 .byte 0xCF # G | D | L | AVL | Segment [19..16]
271 .byte 0
272
273 #
274 # system code segment descriptor
275 #
276 .equ SYS_CODE64_SEL, .-_GDT_BASE # Selector [0x38]
277 .word 0xFFFF # limit 0xFFFFF
278 .word 0 # base 0
279 .byte 0
280 .byte 0x9A # P | DPL [1..2] | 1 | 1 | C | R | A
281 .byte 0xAF # G | D | L | AVL | Segment [19..16]
282 .byte 0
283
284 # spare segment descriptor
285 .equ SPARE4_SEL, .-_GDT_BASE # Selector [0x40]
286 .word 0 # limit 0xFFFFF
287 .word 0 # base 0
288 .byte 0
289 .byte 0 # present, ring 0, data, expand-up, writable
290 .byte 0 # page-granular, 32-bit
291 .byte 0
292
293 _GDT_END:
294
295
296