VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Thunk/EfiThunk.asm@ 24951

Last change on this file since 24951 was 24839, checked in by vboxsync, 15 years ago

EFI: move initial stack closer to thunk location.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.1 KB
Line 
1; $Id: EfiThunk.asm 24839 2009-11-21 09:50:32Z vboxsync $
2;; @file
3; 16-bit EFI Thunk - 16-bit code executed immediately after CPU startup/reset,
4; performs minimal setup, switches CPU to 32-bit mode
5; and passes control to the 32-bit firmware entry point
6;
7;; @todo yasm 0.8.0 got binary sections which could simplify things in this file,
8; see: http://www.tortall.net/projects/yasm/manual/html/manual.html#objfmt-bin-section
9
10;
11; Copyright (C) 2009 Sun Microsystems, Inc.
12;
13; This file is part of VirtualBox Open Source Edition (OSE), as
14; available from http://www.virtualbox.org. This file is free software;
15; you can redistribute it and/or modify it under the terms of the GNU
16; General Public License (GPL) as published by the Free Software
17; Foundation, in version 2 as it comes in the "COPYING" file of the
18; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
19; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
20;
21; Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
22; Clara, CA 95054 USA or visit http://www.sun.com if you need
23; additional information or have any questions.
24;
25
26;*******************************************************************************
27;* Defined Constants And Macros *
28;*******************************************************************************
29;; we'll use no more than 128 vectors atm
30%define IDT_VECTORS 128
31;; keep in sync with actual GDT size
32%define GDT_SELECTORS 10
33
34
35;*******************************************************************************
36;* Header Files *
37;*******************************************************************************
38%include "VBox/asmdefs.mac"
39%include "VBox/x86.mac"
40%include "DevEFI.mac"
41
42;
43; 0xfffff000/0xf000 - Where we start.
44;
45 ORG 0xf000
46
47;
48; 0xfffff000/0xf000 - Parameters passed by DevEFI, DEVEFIINFO.
49;
50DevEfiParameters:
51 times DEVEFIINFO_size db 0
52
53;
54; The IDT.
55; The first 16 vectors have dedicated handlers to ease debugging.
56; The remaining uses a common handler.
57;
58align 16
59efi_thunk_IDT:
60%assign i 0
61%rep 16
62 dw Trap_ %+ i, 0x10, 0x8e00, 0xffff
63 %assign i i+1
64%endrep
65 times IDT_VECTORS-16 dw DefaultTrap, 0x10, 0x8e00, 0xffff
66
67
68;
69; The GDT.
70; Note! Keep this in sync with GDT_SELECTORS.
71;
72align 16
73efi_thunk_GDT:
74 dw 0, 0, 0, 0 ; null selector
75 dw 0, 0, 0, 0 ; ditto
76 dw 0xffff, 0, 0x9b00, 0x00cf ; 32 bit flat code segment (0x10)
77 dw 0xffff, 0, 0x9300, 0x00cf ; 32 bit flat data segment (0x18)
78 dw 0xffff, 0, 0x9b00, 0x0000 ; 16 bit code segment base=0xf0000 limit=0xffff - FIXME: the base is 0, not f0000 here.
79 dw 0xffff, 0, 0x9300, 0x0000 ; 16 bit data segment base=0x0 limit=0xffff - FIXME: ditto.
80 dw 0xffff, 0, 0x9300, 0x00cf ; 32 bit flat stack segment (0x30)
81 dw 0xffff, 0, 0x9a00, 0x00af ; 64 bit flat code segment (0x38)
82 dw 0, 0, 0, 0 ; ditto
83 dw 0, 0, 0, 0 ; ditto
84
85;; For lidt
86efi_thunk_idtr:
87 dw 8*IDT_VECTORS-1 ; limit 15:00
88 dw efi_thunk_IDT ; base 15:00
89 db 0x0f ; base 23:16
90 db 0x00 ; unused
91
92;; For lgdt
93efi_thunk_gdtr:
94 dw 8*GDT_SELECTORS-1 ; limit 15:00
95 dw efi_thunk_GDT ; base 15:00
96 db 0x0f ; base 23:16
97 db 0x00 ; unused
98
99BITS 32
100
101;;
102; The default trap/interrupt handler.
103;
104DefaultTrap:
105 push ebp
106 mov ebp, esp
107 mov eax, EFI_PANIC_CMD_THUNK_TRAP
108 mov edx, EFI_PANIC_PORT
109 out dx, al
110 jmp HaltForEver
111
112;;
113; Generate 16 Trap_N handlers that pushes trap number on the stack.
114%assign i 0
115%rep 16
116Trap_ %+ i:
117 push ebp ; Create a valid stackframe for the debugger. (not
118 push byte i ; quite true if there is an error value pushed)
119 jmp CommonTrap
120 %assign i i+1
121%endrep
122
123;;
124; Common trap handler for the 16 dedicated ones.
125;
126CommonTrap:
127 lea ebp, [esp + 4] ; stack frame part 2.
128 push edx
129 push eax
130 mov edx, EFI_PANIC_PORT
131 mov eax, EFI_PANIC_CMD_THUNK_TRAP
132 out dx, al
133
134HaltForEver:
135 cli
136 hlt
137 jmp short HaltForEver ; In case of NMI.
138
139BITS 16
140;;
141; This i the place where we jump immediately after boot and
142; switch the CPU into protected mode.
143;
144genesis:
145%ifdef DISABLED_CODE
146 ; Say 'Hi' to the granny!
147 mov al, 0x41
148 mov dx, EFI_DEBUG_PORT
149 out dx, al
150%endif
151 cli ; paranoia
152
153
154 ; enable a20
155 in al, 0x92
156 or al, 0x02
157 out 0x92, al
158
159 ; check that we loaded in the right place
160 cmp word [cs:efi_thunk_gdtr], 8*GDT_SELECTORS-1
161 je load_ok
162 ; panic if our offset is wrong, which most likely means invalid ORG
163 mov ax, EFI_PANIC_CMD_BAD_ORG
164 mov dx, EFI_PANIC_PORT
165 out dx, al
166load_ok:
167
168 ; load IDTR and GDTR.
169 cs lidt [efi_thunk_idtr]
170 cs lgdt [efi_thunk_gdtr]
171
172 ; set PE bit in CR0, not paged
173 mov eax, cr0
174 or al, X86_CR0_PE
175 mov cr0, eax
176
177 ; start protected mode code: ljmpl 0x10:code_32
178 db 0x66, 0xea
179 dw code_32 ; low offset word
180 dw 0xffff ; high offset word
181 dw 0x0010 ; protected mode CS selector
182
183 ;
184 ; At this point we're in 32-bit protected mode
185 ;
186BITS 32
187code_32:
188 ; load some segments
189 mov ax, 0x18 ; Flat 32-bit data segment
190 mov ds, ax
191 mov es, ax
192 mov ax, 0x30 ; Flat 32-bit stack segment
193 mov ss, ax
194 ; load the null selector into FS/GS (catches unwanted accesses)
195 xor ax, ax
196 mov gs, ax
197 mov fs, ax
198
199 ;
200 ; Switch stack, have it start at the last page before 2M
201 ;
202 mov esp, 0xfffff000;
203
204 ;
205 ; Jump to 32-bit entry point of the firmware, interrupts still disabled.
206 ;
207 ; It's up to the firmware init code to setup a working IDT (and optionally
208 ; GDT and TSS) before enabling interrupts. It may also switch the stack
209 ; around all it wants for all we care.
210 ;
211 mov eax,[0xfffff000 + DEVEFIINFO.fFlags]
212 and eax, DEVEFI_INFO_FLAGS_AMD64
213 jnz trampoline_64
214 mov ebp, [0xfffff000 + DEVEFIINFO.PhysFwVol]
215 mov esi, [0xfffff000 + DEVEFIINFO.pfnFirmwareEP]
216 mov edi, [0xfffff000 + DEVEFIINFO.pfnPeiEP]
217 jmp [0xfffff000 + DEVEFIINFO.pfnFirmwareEP]
218 jmp HaltForEver
219trampoline_64:
220%macro fill_pkt 1
221%%loop:
222 mov [ebx],eax
223 xor edx,edx
224 mov [ebx + 4], edx
225 add ebx, 8
226 add eax, %1
227 loop %%loop
228%endmacro
229
230%define base 0x800000;0xfffff000
231 mov ecx, 0x800 ; pde size
232 mov ebx, base - (6 << X86_PAGE_4K_SHIFT)
233 xor eax, eax
234 ;; or flags to eax
235 or eax, (X86_PDE_P|X86_PDE_A|X86_PDE_PS|X86_PDE_PCD|X86_PDE_RW|RT_BIT(6))
236 fill_pkt (1 << X86_PAGE_2M_SHIFT)
237
238 ;; pdpt (1st 4 entries describe 4Gb)
239 mov ebx, base - (2 << X86_PAGE_4K_SHIFT)
240 mov eax, base - (6 << X86_PAGE_4K_SHIFT) ;;
241 or eax, (X86_PDPE_P|X86_PDPE_RW|X86_PDPE_A|X86_PDPE_PCD)
242 mov [ebx],eax
243 xor edx,edx
244 mov [ebx + 4], edx
245 add ebx, 8
246
247 mov eax, base - 5 * (1 << X86_PAGE_4K_SHIFT) ;;
248 or eax, (X86_PDPE_P|X86_PDPE_RW|X86_PDPE_A|X86_PDPE_PCD)
249 mov [ebx],eax
250 xor edx,edx
251 mov [ebx + 4], edx
252 add ebx, 8
253
254 mov eax, base - 4 * (1 << X86_PAGE_4K_SHIFT) ;;
255 or eax, (X86_PDPE_P|X86_PDPE_RW|X86_PDPE_A|X86_PDPE_PCD)
256 mov [ebx],eax
257 xor edx,edx
258 mov [ebx + 4], edx
259 add ebx, 8
260
261 mov eax, base - 3 * (1 << X86_PAGE_4K_SHIFT) ;;
262 or eax, (X86_PDPE_P|X86_PDPE_RW|X86_PDPE_A|X86_PDPE_PCD)
263 mov [ebx],eax
264 xor edx,edx
265 mov [ebx + 4], edx
266 add ebx, 8
267
268 mov ecx, 0x1f7 ; pdte size
269 mov ebx, base - 2 * (1 << X86_PAGE_4K_SHIFT) + 4 * 8
270 mov eax, base - 6 * (1 << X86_PAGE_4K_SHIFT);;
271 or eax, (X86_PDPE_P|X86_PDPE_RW|X86_PDPE_A|X86_PDPE_PCD)
272 ;; or flags to eax
273 fill_pkt 3 * (1 << X86_PAGE_4K_SHIFT)
274
275 mov ecx, 0x200 ; pml4 size
276 mov ebx, base - (1 << X86_PAGE_4K_SHIFT)
277 mov eax, base - 2 * (1 << X86_PAGE_4K_SHIFT) ;;
278 or eax, (X86_PML4E_P|X86_PML4E_PCD|X86_PML4E_A|X86_PML4E_RW)
279 ;; or flags to eax
280 fill_pkt 0
281
282 mov eax, base - (1 << X86_PAGE_4K_SHIFT)
283 mov cr3, eax
284
285
286 mov eax,cr4
287 or eax, X86_CR4_PAE|X86_CR4_OSFSXR|X86_CR4_OSXMMEEXCPT
288 mov cr4,eax
289
290 mov ecx, MSR_K6_EFER
291 rdmsr
292 or eax, MSR_K6_EFER_LME
293 wrmsr
294
295 mov eax, cr0
296 or eax, X86_CR0_PG
297 mov cr0, eax
298 jmp compat
299compat:
300 jmp 0x38:0xffff0000 + efi_64
301BITS 64
302efi_64:
303 mov ebp, [0xff009] ; DEVEFIINFO.PhysFwVol
304 mov esi, [0xff000]; + DEVEFIINFO.pfnFirmwareEP]
305 mov edi, [0xff000 + 0x28]; + DEVEFIINFO.pfnPeiEP]
306 jmp [0xff000]; + DEVEFIINFO.pfnFirmwareEP]
307 jmp HaltForEver
308
309 ;
310 ; 0xfffffff0/0xfff0 - This is where the CPU starts executing.
311 ;
312 ;; @todo yasm 0.8.0: SECTION .text start=0fff0h vstart=0fff0h ?
313 times 0xff0-$+DevEfiParameters db 0cch ; Note! $ isn't moved by ORG (yasm v0.6.2).
314cpu_start:
315 BITS 16
316 jmp genesis
317 dw 0xdead
318 dw 0xbeaf
319 times (16 - 7) db 0cch
320end:
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette