VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-c32-Trap32Generic.asm@ 59866

Last change on this file since 59866 was 59287, checked in by vboxsync, 9 years ago

bs3kit: Working 16 and 64 bit PrintChr system call, fixed/documented 64-bit calls.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 17.4 KB
Line 
1; $Id: bs3-c32-Trap32Generic.asm 59287 2016-01-08 10:08:40Z vboxsync $
2;; @file
3; BS3Kit - Trap, 32-bit assembly handlers.
4;
5
6;
7; Copyright (C) 2007-2016 Oracle Corporation
8;
9; This file is part of VirtualBox Open Source Edition (OSE), as
10; available from http://www.virtualbox.org. This file is free software;
11; you can redistribute it and/or modify it under the terms of the GNU
12; General Public License (GPL) as published by the Free Software
13; Foundation, in version 2 as it comes in the "COPYING" file of the
14; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16;
17; The contents of this file may alternatively be used under the terms
18; of the Common Development and Distribution License Version 1.0
19; (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20; VirtualBox OSE distribution, in which case the provisions of the
21; CDDL are applicable instead of those of the GPL.
22;
23; You may elect to license modified versions of this file under the
24; terms and conditions of either the GPL or the CDDL or both.
25;
26
27%include "bs3kit-template-header.mac"
28
29%ifndef TMPL_32BIT
30 %error "32-bit only template"
31%endif
32
33BS3_BEGIN_DATA16
34;; Easy to access flat address of Bs3Trap32GenericEntries.
35BS3_GLOBAL_DATA g_Bs3Trap32GenericEntriesFlatAddr, 4
36 dd Bs3Trap32GenericEntries wrt FLAT
37;; Easy to access flat address of Bs3Trap32DoubleFaultHandler.
38BS3_GLOBAL_DATA g_Bs3Trap32DoubleFaultHandlerFlatAddr, 4
39 dd Bs3Trap32DoubleFaultHandler wrt FLAT
40
41BS3_BEGIN_DATA32
42;; Pointer C trap handlers.
43BS3_GLOBAL_DATA g_apfnBs3TrapHandlers_c32, 1024
44 resd 256
45
46
47TMPL_BEGIN_TEXT
48BS3_EXTERN_CMN Bs3TrapDefaultHandler
49BS3_EXTERN_CMN Bs3Trap32ResumeFrame
50
51
52;;
53; Generic entry points for IDT handlers, 8 byte spacing.
54;
55BS3_PROC_BEGIN Bs3Trap32GenericEntries
56%macro Bs3Trap32GenericEntry 1
57 db 06ah, i ; push imm8 - note that this is a signextended value.
58 jmp %1
59 ALIGNCODE(8)
60%assign i i+1
61%endmacro
62
63%assign i 0 ; start counter.
64 Bs3Trap32GenericEntry bs3Trap32GenericTrapOrInt ; 0
65 Bs3Trap32GenericEntry bs3Trap32GenericTrapOrInt ; 1
66 Bs3Trap32GenericEntry bs3Trap32GenericTrapOrInt ; 2
67 Bs3Trap32GenericEntry bs3Trap32GenericTrapOrInt ; 3
68 Bs3Trap32GenericEntry bs3Trap32GenericTrapOrInt ; 4
69 Bs3Trap32GenericEntry bs3Trap32GenericTrapOrInt ; 5
70 Bs3Trap32GenericEntry bs3Trap32GenericTrapOrInt ; 6
71 Bs3Trap32GenericEntry bs3Trap32GenericTrapOrInt ; 7
72 Bs3Trap32GenericEntry bs3Trap32GenericTrapErrCode ; 8
73 Bs3Trap32GenericEntry bs3Trap32GenericTrapOrInt ; 9
74 Bs3Trap32GenericEntry bs3Trap32GenericTrapErrCode ; a
75 Bs3Trap32GenericEntry bs3Trap32GenericTrapErrCode ; b
76 Bs3Trap32GenericEntry bs3Trap32GenericTrapErrCode ; c
77 Bs3Trap32GenericEntry bs3Trap32GenericTrapErrCode ; d
78 Bs3Trap32GenericEntry bs3Trap32GenericTrapErrCode ; e
79 Bs3Trap32GenericEntry bs3Trap32GenericTrapOrInt ; f (reserved)
80 Bs3Trap32GenericEntry bs3Trap32GenericTrapOrInt ; 10
81 Bs3Trap32GenericEntry bs3Trap32GenericTrapErrCode ; 11
82 Bs3Trap32GenericEntry bs3Trap32GenericTrapOrInt ; 12
83 Bs3Trap32GenericEntry bs3Trap32GenericTrapOrInt ; 13
84 Bs3Trap32GenericEntry bs3Trap32GenericTrapOrInt ; 14
85 Bs3Trap32GenericEntry bs3Trap32GenericTrapOrInt ; 15 (reserved)
86 Bs3Trap32GenericEntry bs3Trap32GenericTrapOrInt ; 16 (reserved)
87 Bs3Trap32GenericEntry bs3Trap32GenericTrapOrInt ; 17 (reserved)
88 Bs3Trap32GenericEntry bs3Trap32GenericTrapOrInt ; 18 (reserved)
89 Bs3Trap32GenericEntry bs3Trap32GenericTrapOrInt ; 19 (reserved)
90 Bs3Trap32GenericEntry bs3Trap32GenericTrapOrInt ; 1a (reserved)
91 Bs3Trap32GenericEntry bs3Trap32GenericTrapOrInt ; 1b (reserved)
92 Bs3Trap32GenericEntry bs3Trap32GenericTrapOrInt ; 1c (reserved)
93 Bs3Trap32GenericEntry bs3Trap32GenericTrapOrInt ; 1d (reserved)
94 Bs3Trap32GenericEntry bs3Trap32GenericTrapErrCode ; 1e
95 Bs3Trap32GenericEntry bs3Trap32GenericTrapOrInt ; 1f (reserved)
96%rep 224
97 Bs3Trap32GenericEntry bs3Trap32GenericTrapOrInt
98%endrep
99BS3_PROC_END Bs3Trap32GenericEntries
100
101
102
103
104;;
105; Trap or interrupt (no error code).
106;
107BS3_PROC_BEGIN bs3Trap32GenericTrapOrInt
108 pushfd
109 cli
110 cld
111
112 sub esp, BS3TRAPFRAME_size
113 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.rax], eax
114 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.rbp], ebp
115 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.rdx], edx
116 lea ebp, [esp + BS3TRAPFRAME_size + 4] ; iret - 4 (i.e. ebp frame chain location)
117
118 mov edx, [esp + BS3TRAPFRAME_size]
119 mov [esp + BS3TRAPFRAME.fHandlerRfl], edx
120
121 movzx edx, byte [esp + BS3TRAPFRAME_size + 4]
122 mov [esp + BS3TRAPFRAME.bXcpt], edx
123
124 xor edx, edx
125 mov [esp + BS3TRAPFRAME.uErrCd], edx
126 mov [esp + BS3TRAPFRAME.uErrCd + 4], edx
127 jmp bs3Trap32GenericCommon
128BS3_PROC_END bs3Trap32GenericTrapOrInt
129
130
131;;
132; Trap with error code.
133;
134BS3_PROC_BEGIN bs3Trap32GenericTrapErrCode
135 pushfd
136 cli
137 cld
138
139 sub esp, BS3TRAPFRAME_size
140 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.rax], eax
141 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.rbp], ebp
142 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.rdx], edx
143 lea ebp, [esp + BS3TRAPFRAME_size + 8] ; iret - 4 (i.e. ebp frame chain location)
144
145 mov edx, [esp + BS3TRAPFRAME_size]
146 mov [esp + BS3TRAPFRAME.fHandlerRfl], edx
147
148 movzx edx, byte [esp + BS3TRAPFRAME_size + 4]
149 mov [esp + BS3TRAPFRAME.bXcpt], edx
150
151 mov edx, [esp + BS3TRAPFRAME_size + 8]
152;; @todo Do voodoo checks for 'int xx' or misguided hardware interrupts.
153 mov [esp + BS3TRAPFRAME.uErrCd], edx
154 xor edx, edx
155 mov [esp + BS3TRAPFRAME.uErrCd + 4], edx
156 jmp bs3Trap32GenericCommon
157BS3_PROC_END bs3Trap32GenericTrapErrCode
158
159
160;;
161; Common context saving code and dispatching.
162;
163; @param esp Pointer to the trap frame. The following members have been
164; filled in by the previous code:
165; - bXcpt
166; - uErrCd
167; - fHandlerRFL
168; - Ctx.eax (except upper dword)
169; - Ctx.edx (except upper dword)
170; - Ctx.ebp (except upper dword)
171;
172; @param ebp Pointer to the dword before the iret frame, i.e. where ebp
173; would be saved if this was a normal call.
174; @param edx Zero (0).
175;
176BS3_PROC_BEGIN bs3Trap32GenericCommon
177 ;
178 ; Fake EBP frame.
179 ;
180 mov eax, [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.rbp]
181 mov [ebp], eax
182
183 ;
184 ; Save the remaining GPRs and segment registers.
185 ;
186 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.rcx], ecx
187 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.rbx], ebx
188 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.rdi], edi
189 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.rsi], esi
190 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.ds], ds
191 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.es], es
192 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.fs], fs
193 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.gs], gs
194
195 ;
196 ; Load 32-bit data selector for the DPL we're executing at into DS and ES.
197 ; Save the handler SS and CS values first.
198 ;
199 mov ax, cs
200 mov [esp + BS3TRAPFRAME.uHandlerCs], ax
201 mov ax, ss
202 mov [esp + BS3TRAPFRAME.uHandlerSs], ax
203 and ax, 3
204 mov cx, ax
205 shl ax, BS3_SEL_RING_SHIFT
206 or ax, cx
207 add ax, BS3_SEL_R0_DS32
208 mov ds, ax
209 mov es, ax
210
211 ;
212 ; Copy iret info.
213 ;
214 mov ecx, [ebp + 4]
215 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.rip], ecx
216 mov ecx, [ebp + 12]
217 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.rflags], ecx
218 mov cx, [ebp + 8]
219 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.cs], cx
220 test dword [ebp + 12], X86_EFL_VM
221 jnz .iret_frame_v8086
222 mov ax, ss
223 and ax, 3
224 and cx, 3
225 cmp ax, ax
226 je .iret_frame_same_cpl
227
228 mov ecx, [ebp + 16]
229 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.rsp], ecx
230 mov cx, [ebp + 20]
231 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.ss], cx
232 lea eax, [ebp + 24]
233 mov [esp + BS3TRAPFRAME.uHandlerRsp], eax
234 jmp .iret_frame_done
235
236.iret_frame_same_cpl:
237 lea ecx, [ebp + 12]
238 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.rsp], ecx
239 mov cx, ss
240 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.ss], cx
241 lea eax, [ebp + 16]
242 mov [esp + BS3TRAPFRAME.uHandlerRsp], eax
243 jmp .iret_frame_done
244
245.iret_frame_v8086:
246 lea ecx, [ebp + 12]
247 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.rsp], ecx
248 mov cx, [ebp + 20]
249 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.ss], cx
250 mov cx, [ebp + 24]
251 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.es], cx
252 mov cx, [ebp + 28]
253 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.ds], cx
254 mov cx, [ebp + 32]
255 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.fs], cx
256 mov cx, [ebp + 36]
257 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.gs], cx
258 lea eax, [ebp + 40]
259 mov [esp + BS3TRAPFRAME.uHandlerRsp], eax
260 jmp .iret_frame_done
261
262.iret_frame_done:
263 ;
264 ; Control registers.
265 ;
266 mov eax, cr0
267 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.cr0], eax
268 mov eax, cr2
269 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.cr2], eax
270 mov eax, cr3
271 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.cr3], eax
272 mov eax, cr4
273 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.cr4], eax
274 str ax
275 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.tr], ax
276 sldt ax
277 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.ldtr], ax
278
279 ;
280 ; Set context bit width and clear all upper dwords and unused register members.
281 ;
282.clear_and_dispatch_to_handler: ; The double fault code joins us here.
283 xor edx, edx
284 mov dword [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.cBits], 32
285 mov dword [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.abPadding + 3], edx
286 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.rax + 4], edx
287 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.rcx + 4], edx
288 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.rdx + 4], edx
289 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.rbx + 4], edx
290 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.rsp + 4], edx
291 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.rbp + 4], edx
292 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.rsi + 4], edx
293 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.rdi + 4], edx
294 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.r8 + 4], edx
295 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.r9 + 4], edx
296 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.r10 + 4], edx
297 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.r11 + 4], edx
298 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.r12 + 4], edx
299 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.r13 + 4], edx
300 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.r14 + 4], edx
301 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.r15 + 4], edx
302 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.rflags + 4], edx
303 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.rip + 4], edx
304 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.cr0 + 4], edx
305 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.cr2 + 4], edx
306 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.cr3 + 4], edx
307 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.cr4 + 4], edx
308
309 ;
310 ; Dispatch it to C code.
311 ;
312 movzx ebx, byte [esp + BS3TRAPFRAME.bXcpt]
313 mov eax, [BS3_DATA_NM(g_apfnBs3TrapHandlers_c32) + ebx * 4]
314 or eax, eax
315 jnz .call_handler
316 mov eax, Bs3TrapDefaultHandler
317.call_handler:
318 mov edi, esp
319 push edi
320 call eax
321
322 ;
323 ; Resume execution using trap frame.
324 ;
325 push 0
326 push edi
327 call Bs3Trap32ResumeFrame
328.panic:
329 int3
330 hlt
331 jmp .panic
332BS3_PROC_END bs3Trap32GenericCommon
333
334
335;;
336; Helper.
337;
338; @retruns Flat address in eax.
339; @param ax
340; @uses eax
341;
342bs3Trap32TssInAxToFlatInEax:
343 ; Get the GDT base address and find the descriptor address (EAX)
344 sub esp, 16h
345 sgdt [esp + 2] ; +2 for correct alignment.
346 and eax, 0fff8h
347 add eax, [esp + 4] ; GDT base address.
348 add esp, 16h
349
350 ; Get the flat TSS address from the descriptor.
351 push ecx
352 mov ecx, [eax + 4]
353 and eax, 0ffff0000h
354 movzx eax, word [eax]
355 or eax, ecx
356 pop ecx
357
358 ret
359
360;;
361; Double fault handler.
362;
363; We don't have to load any selectors or clear anything in EFLAGS because the
364; TSS specified sane values which got loaded during the task switch.
365;
366BS3_PROC_BEGIN Bs3Trap32DoubleFaultHandler
367 push 0 ; We'll copy the rip from the other TSS here later to create a more sensible call chain.
368 push ebp
369 mov ebp, esp
370
371 ;
372 ; Fill in the non-context trap frame bits.
373 ;
374 pushfd ; Get handler flags.
375 pop ecx
376 xor edx, edx ; NULL register.
377
378 sub esp, BS3TRAPFRAME_size ; Allocate trap frame.
379 mov [esp + BS3TRAPFRAME.fHandlerRfl], ecx
380 mov word [esp + BS3TRAPFRAME.bXcpt], X86_XCPT_DF
381 mov [esp + BS3TRAPFRAME.uHandlerCs], cs
382 mov [esp + BS3TRAPFRAME.uHandlerSs], ss
383 lea ecx, [ebp + 12]
384 mov [esp + BS3TRAPFRAME.uHandlerRsp], ecx
385 mov [esp + BS3TRAPFRAME.uHandlerRsp + 4], edx
386 mov ecx, [ebp + 8]
387 mov [esp + BS3TRAPFRAME.uErrCd], ecx
388 mov [esp + BS3TRAPFRAME.uErrCd + 4], edx
389
390 ;
391 ; Copy the register state from the previous task segment.
392 ;
393
394 ; Find our TSS.
395 str ax
396 call bs3Trap32TssInAxToFlatInEax
397
398 ; Find the previous TSS.
399 mov ax, [eax + X86TSS32.selPrev]
400 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.tr], ax
401 call bs3Trap32TssInAxToFlatInEax
402
403 ; Do the copying.
404 mov ecx, [eax + X86TSS32.eax]
405 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.rax], ecx
406 mov ecx, [eax + X86TSS32.ecx]
407 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.rcx], ecx
408 mov ecx, [eax + X86TSS32.edx]
409 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.rdx], ecx
410 mov ecx, [eax + X86TSS32.ebx]
411 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.rbx], ecx
412 mov ecx, [eax + X86TSS32.esp]
413 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.rsp], ecx
414 mov ecx, [eax + X86TSS32.ebp]
415 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.rbp], ecx
416 mov [ebp], ecx ; For better call stacks.
417 mov ecx, [eax + X86TSS32.esi]
418 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.rsi], ecx
419 mov ecx, [eax + X86TSS32.edi]
420 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.rdi], ecx
421 mov ecx, [eax + X86TSS32.esi]
422 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.rsi], ecx
423 mov ecx, [eax + X86TSS32.eflags]
424 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.rflags], ecx
425 mov ecx, [eax + X86TSS32.eip]
426 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.rip], ecx
427 mov [ebp + 4], ecx ; For better call stacks.
428 mov cx, [eax + X86TSS32.cs]
429 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.cs], cx
430 mov cx, [eax + X86TSS32.ds]
431 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.ds], cx
432 mov cx, [eax + X86TSS32.es]
433 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.es], cx
434 mov cx, [eax + X86TSS32.fs]
435 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.fs], cx
436 mov cx, [eax + X86TSS32.gs]
437 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.gs], cx
438 mov cx, [eax + X86TSS32.ss]
439 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.ss], cx
440 mov cx, [eax + X86TSS32.selLdt] ; Note! This isn't necessarily the ldtr at the time of the fault.
441 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.ldtr], cx
442 mov cx, [eax + X86TSS32.cr3] ; Note! This isn't necessarily the cr3 at the time of the fault.
443 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.cr3], ecx
444
445 mov dword [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.cBits], 32
446
447 ;
448 ; Control registers.
449 ;
450 mov ecx, cr0
451 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.cr0], ecx
452 mov ecx, cr2
453 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.cr2], ecx
454 mov ecx, cr4
455 mov [esp + BS3TRAPFRAME.Ctx + BS3REGCTX.cr4], ecx
456
457 ;
458 ; Join code paths with the generic handler code.
459 ;
460 jmp bs3Trap32GenericCommon.clear_and_dispatch_to_handler
461BS3_PROC_END Bs3Trap32DoubleFaultHandler
462
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