VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-c16-Trap16Generic.asm@ 60600

Last change on this file since 60600 was 60585, checked in by vboxsync, 9 years ago

bs3kit: updates

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 26.0 KB
Line 
1; $Id: bs3-c16-Trap16Generic.asm 60585 2016-04-20 09:48:09Z vboxsync $
2;; @file
3; BS3Kit - Trap, 16-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;*********************************************************************************************************************************
28;* Header Files *
29;*********************************************************************************************************************************
30%include "bs3kit-template-header.mac"
31
32%ifndef TMPL_16BIT
33 %error "16-bit only template"
34%endif
35
36
37;*********************************************************************************************************************************
38;* External Symbols *
39;*********************************************************************************************************************************
40BS3_EXTERN_DATA16 g_bBs3CurrentMode
41BS3_EXTERN_DATA16 g_uBs3TrapEipHint
42BS3_EXTERN_DATA16 g_uBs3CpuDetected
43BS3_EXTERN_DATA16 g_apfnBs3TrapHandlers_c16
44BS3_EXTERN_SYSTEM16 Bs3Gdt
45TMPL_BEGIN_TEXT
46BS3_EXTERN_CMN Bs3TrapDefaultHandler
47BS3_EXTERN_CMN Bs3RegCtxRestore
48TMPL_BEGIN_TEXT
49
50
51;;
52; Generic entry points for IDT handlers, 8 byte spacing.
53;
54BS3_PROC_BEGIN _Bs3Trap16GenericEntries
55BS3_PROC_BEGIN Bs3Trap16GenericEntries
56%macro Bs3Trap16GenericEntryNoErr 1
57 push byte 0 ; 2 byte: fake error code
58 db 06ah, i ; 2 byte: push imm8 - note that this is a signextended value.
59 jmp %1 ; 3 byte
60 ALIGNCODE(8)
61%assign i i+1
62%endmacro
63
64%macro Bs3Trap16GenericEntryErrCd 1
65 db 06ah, i ; 2 byte: push imm8 - note that this is a signextended value.
66 jmp %1 ; 3 byte
67 ALIGNCODE(8)
68%assign i i+1
69%endmacro
70
71%assign i 0 ; start counter.
72 Bs3Trap16GenericEntryNoErr bs3Trap16GenericTrapOrInt ; 0
73 Bs3Trap16GenericEntryNoErr bs3Trap16GenericTrapOrInt ; 1
74 Bs3Trap16GenericEntryNoErr bs3Trap16GenericTrapOrInt ; 2
75 Bs3Trap16GenericEntryNoErr bs3Trap16GenericTrapOrInt ; 3
76 Bs3Trap16GenericEntryNoErr bs3Trap16GenericTrapOrInt ; 4
77 Bs3Trap16GenericEntryNoErr bs3Trap16GenericTrapOrInt ; 5
78 Bs3Trap16GenericEntryNoErr bs3Trap16GenericTrapOrInt ; 6
79 Bs3Trap16GenericEntryNoErr bs3Trap16GenericTrapOrInt ; 7
80 Bs3Trap16GenericEntryErrCd bs3Trap16GenericTrapOrInt ; 8
81 Bs3Trap16GenericEntryNoErr bs3Trap16GenericTrapOrInt ; 9
82 Bs3Trap16GenericEntryErrCd bs3Trap16GenericTrapOrInt ; a
83 Bs3Trap16GenericEntryErrCd bs3Trap16GenericTrapOrInt ; b
84 Bs3Trap16GenericEntryErrCd bs3Trap16GenericTrapOrInt ; c
85 Bs3Trap16GenericEntryErrCd bs3Trap16GenericTrapOrInt ; d
86 Bs3Trap16GenericEntryErrCd bs3Trap16GenericTrapOrInt ; e
87 Bs3Trap16GenericEntryNoErr bs3Trap16GenericTrapOrInt ; f (reserved)
88 Bs3Trap16GenericEntryNoErr bs3Trap16GenericTrapOrInt ; 10
89 Bs3Trap16GenericEntryErrCd bs3Trap16GenericTrapOrInt ; 11
90 Bs3Trap16GenericEntryNoErr bs3Trap16GenericTrapOrInt ; 12
91 Bs3Trap16GenericEntryNoErr bs3Trap16GenericTrapOrInt ; 13
92 Bs3Trap16GenericEntryNoErr bs3Trap16GenericTrapOrInt ; 14
93 Bs3Trap16GenericEntryNoErr bs3Trap16GenericTrapOrInt ; 15 (reserved)
94 Bs3Trap16GenericEntryNoErr bs3Trap16GenericTrapOrInt ; 16 (reserved)
95 Bs3Trap16GenericEntryNoErr bs3Trap16GenericTrapOrInt ; 17 (reserved)
96 Bs3Trap16GenericEntryNoErr bs3Trap16GenericTrapOrInt ; 18 (reserved)
97 Bs3Trap16GenericEntryNoErr bs3Trap16GenericTrapOrInt ; 19 (reserved)
98 Bs3Trap16GenericEntryNoErr bs3Trap16GenericTrapOrInt ; 1a (reserved)
99 Bs3Trap16GenericEntryNoErr bs3Trap16GenericTrapOrInt ; 1b (reserved)
100 Bs3Trap16GenericEntryNoErr bs3Trap16GenericTrapOrInt ; 1c (reserved)
101 Bs3Trap16GenericEntryNoErr bs3Trap16GenericTrapOrInt ; 1d (reserved)
102 Bs3Trap16GenericEntryErrCd bs3Trap16GenericTrapOrInt ; 1e
103 Bs3Trap16GenericEntryNoErr bs3Trap16GenericTrapOrInt ; 1f (reserved)
104%rep 224
105 Bs3Trap16GenericEntryNoErr bs3Trap16GenericTrapOrInt
106%endrep
107BS3_PROC_END Bs3Trap16GenericEntries
108AssertCompile(Bs3Trap16GenericEntries_EndProc - Bs3Trap16GenericEntries == 8*256)
109
110
111;;
112; Trap or interrupt with error code, faked if necessary.
113;
114; Note! This code is going to "misbehave" if the high word of ESP is not cleared.
115;
116BS3_PROC_BEGIN _bs3Trap16GenericTrapOrInt
117BS3_PROC_BEGIN bs3Trap16GenericTrapOrInt
118CPU 386
119 jmp near bs3Trap16GenericTrapErrCode80286 ; Bs3Trap16Init adjusts this on 80386+
120 push ebp
121 movzx ebp, sp
122 push ebx ; BP - 04h
123 pushfd ; BP - 08h
124 cld
125 push edx ; BP - 0ch
126 push ss ; BP - 0eh
127 push esp ; BP - 12h
128
129 ;
130 ; We may be comming from 32-bit code where SS is flat and ESP has a non-
131 ; zero high word. We need to thunk it for C code to work correctly with
132 ; [BP+xx] and [SS:BX+xx] style addressing that leaves out the high word.
133 ;
134 ; Note! Require ring-0 handler for non-standard stacks (SS.DPL must equal CPL).
135 ;
136 mov bx, ss
137 lar ebx, bx
138 test ebx, X86LAR_F_D
139 jz .stack_fine
140 test esp, 0ffff0000h
141 jnz .stack_thunk
142.stack_load_r0_ss16:
143 mov bx, ss
144 and bl, 3
145 AssertCompile(BS3_SEL_RING_SHIFT == 8)
146 mov bh, bl
147 add bx, BS3_SEL_R0_SS16
148 jmp .stack_load_bx_into_ss
149.stack_thunk:
150 mov ebx, esp
151 shr ebx, 16
152 shl ebx, X86_SEL_SHIFT
153 add ebx, BS3_SEL_TILED_R0
154 cmp ebx, BS3_SEL_TILED_R0_LAST
155 ja .stack_esp_out_of_bounds
156.stack_load_bx_into_ss:
157 mov ss, bx
158.stack_fine:
159 movzx esp, sp
160
161 ; Reserve space for the the register and trap frame.
162 mov bx, (BS3TRAPFRAME_size + 7) / 8
163.more_zeroed_space:
164 push 0
165 push 0
166 push 0
167 push 0
168 dec bx
169 jnz .more_zeroed_space
170 movzx ebx, sp
171
172 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rax], eax
173 mov edx, [bp - 12h] ; This isn't quite right for wrap arounds, but close enough for now
174 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rsp], edx ; high bits
175 mov [ss:bx + BS3TRAPFRAME.uHandlerRsp], edx ; high bits
176 mov dx, [bp - 0eh]
177 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.ss], dx
178 mov [ss:bx + BS3TRAPFRAME.uHandlerSs], dx
179 mov edx, [bp - 0ch]
180 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rdx], edx
181 mov edx, [bp - 8]
182 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rflags], edx ; high bits
183 mov [ss:bx + BS3TRAPFRAME.fHandlerRfl], edx
184 mov edx, [bp - 4]
185 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rbx], edx
186 mov edx, [bp]
187 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rbp], edx
188
189 mov dl, [bp + 4]
190 mov [ss:bx + BS3TRAPFRAME.bXcpt], dl
191
192 mov dx, [bp + 6]
193;; @todo Do voodoo checks for 'int xx' or misguided hardware interrupts.
194 mov [ss:bx + BS3TRAPFRAME.uErrCd], dx
195
196 add bp, 6 ; adjust so it points to the word before the iret frame.
197 xor dx, dx
198 jmp bs3Trap16GenericCommon
199
200.stack_esp_out_of_bounds:
201%ifdef BS3_STRICT
202 int3
203%endif
204 jmp .stack_esp_out_of_bounds
205BS3_PROC_END bs3Trap16GenericTrapErrCode
206
207;;
208; Trap with error code - 80286 code variant.
209;
210BS3_PROC_BEGIN bs3Trap16GenericTrapErrCode80286
211CPU 286
212 push bp
213 mov bp, sp
214 push bx
215 pushf
216 cld
217
218 ; Reserve space for the the register and trap frame.
219 mov bx, (BS3TRAPFRAME_size + 7) / 8
220.more_zeroed_space:
221 push 0
222 push 0
223 push 0
224 push 0
225 dec bx
226 jnz .more_zeroed_space
227 mov bx, sp
228
229 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rax], ax
230 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.ss], ss
231 mov [ss:bx + BS3TRAPFRAME.uHandlerSs], ss
232 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rdx], dx
233 mov dx, [bp - 4]
234 mov [ss:bx + BS3TRAPFRAME.fHandlerRfl], dx
235 mov dx, [bp - 2]
236 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rbx], dx
237 mov dx, [bp]
238 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rbp], dx
239
240 mov dl, [bp + 2]
241 mov [ss:bx + BS3TRAPFRAME.bXcpt], dl
242
243 mov dx, [bp + 4]
244;; @todo Do voodoo checks for 'int xx' or misguided hardware interrupts.
245 mov [ss:bx + BS3TRAPFRAME.uErrCd], dx
246
247 add bp, 4 ; adjust so it points to the word before the iret frame.
248 mov dl, 1
249 jmp bs3Trap16GenericCommon
250BS3_PROC_END bs3Trap16GenericTrapErrCode80286
251
252
253;;
254; Common context saving code and dispatching.
255;
256; @param bx Pointer to the trap frame, zero filled. The following members
257; have been filled in by the previous code:
258; - bXcpt
259; - uErrCd
260; - fHandlerRFL
261; - Ctx.eax
262; - Ctx.edx
263; - Ctx.ebx
264; - Ctx.ebp
265; - Ctx.rflags - high bits only.
266; - Ctx.esp - high bits only.
267; - Ctx.ss - for same cpl frames
268; - All other bytes are zeroed.
269;
270; @param bp Pointer to the word before the iret frame, i.e. where bp
271; would be saved if this was a normal near call.
272; @param dx One (1) if 286, zero (0) if 386+.
273;
274BS3_PROC_BEGIN bs3Trap16GenericCommon
275CPU 286
276 ;
277 ; Fake EBP frame.
278 ;
279 mov ax, [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rbp]
280 mov [bp], ax
281
282 ;
283 ; Save the remaining GPRs and segment registers.
284 ;
285 test dx, dx
286 jnz .save_word_grps
287CPU 386
288 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rcx], ecx
289 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rdi], edi
290 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rsi], esi
291 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.fs], fs
292 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.gs], gs
293 jmp .save_segment_registers
294.save_word_grps:
295CPU 286
296 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rcx], cx
297 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rdi], di
298 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rsi], si
299.save_segment_registers:
300 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.ds], ds
301 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.es], es
302 mov [ss:bx + BS3TRAPFRAME.uHandlerCs], cs
303
304 ;
305 ; Load 16-bit data selector for the DPL we're executing at into DS and ES.
306 ;
307 mov ax, ss
308 and ax, 3
309 mov cx, ax
310 shl ax, BS3_SEL_RING_SHIFT
311 or ax, cx
312 add ax, BS3_SEL_R0_DS16
313 mov ds, ax
314 mov es, ax
315
316 ;
317 ; Copy and update the mode now that we've got a flat DS.
318 ;
319 mov al, [BS3_DATA16_WRT(g_bBs3CurrentMode)]
320 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.bMode], al
321 mov cl, al
322 and cl, ~BS3_MODE_CODE_MASK
323 or cl, BS3_MODE_CODE_16
324 mov [BS3_DATA16_WRT(g_bBs3CurrentMode)], cl
325
326 ;
327 ; Copy iret info.
328 ;
329 lea cx, [bp + 2]
330 mov [ss:bx + BS3TRAPFRAME.uHandlerRsp], cx
331 mov cx, [bp + 2]
332 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rip], cx
333 mov cx, [bp + 6]
334 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rflags], cx
335 mov cx, [bp + 4]
336 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.cs], cx
337
338 test al, BS3_MODE_CODE_V86
339 jnz .iret_frame_v8086
340
341 mov ax, ss
342 and al, 3
343 and cl, 3
344 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.bCpl], cl
345 cmp cl, al
346 je .iret_frame_same_cpl
347
348.ret_frame_different_cpl:
349 mov cx, [bp + 10]
350 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.ss], cx
351 mov cx, [bp + 8]
352 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rsp], cx
353 mov byte [ss:bx + BS3TRAPFRAME.cbIretFrame], 5*2
354 test dx, dx
355 jnz .iret_frame_done
356 jmp .iret_frame_seed_high_eip_word
357
358.iret_frame_same_cpl: ; (ss and high bits was saved by CPU specific part)
359 lea cx, [bp + 8]
360 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rsp], cx
361 mov byte [ss:bx + BS3TRAPFRAME.cbIretFrame], 3*2
362 test dx, dx
363 jnz .iret_frame_done
364 jmp .iret_frame_seed_high_eip_word
365
366.iret_frame_v8086:
367CPU 386
368 or dword [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rflags], X86_EFL_VM
369 mov byte [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.bCpl], 3
370 or byte [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.bMode], BS3_MODE_CODE_V86 ; paranoia ^ 2
371%if 0 ;; @todo testcase: high ESP word from V86 mode, 16-bit TSS.
372 movzx ecx, word [bp + 8]
373 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rsp], ecx
374%else
375 mov cx, word [bp + 8]
376 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rsp], cx
377%endif
378 mov cx, [bp + 10]
379 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.ss], cx
380 mov cx, [bp + 12]
381 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.es], cx
382 mov cx, [bp + 14]
383 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.ds], cx
384 mov cx, [bp + 16]
385 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.fs], cx
386 mov cx, [bp + 18]
387 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.gs], cx
388 mov byte [ss:bx + BS3TRAPFRAME.cbIretFrame], 9*2
389 jmp .iret_frame_done
390
391 ;
392 ; For 386 we do special tricks to supply the high word of EIP when
393 ; arriving here from 32-bit code. (ESP was seeded earlier.)
394 ;
395.iret_frame_seed_high_eip_word:
396 lar eax, [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.cs]
397 jnz .iret_frame_done
398 test eax, X86LAR_F_D
399 jz .iret_frame_done
400 mov ax, [g_uBs3TrapEipHint+2]
401 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rip + 2], ax
402
403.iret_frame_done:
404 ;
405 ; Control registers.
406 ;
407 str [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.tr]
408 sldt [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.ldtr]
409 test dx, dx
410 jnz .save_286_control_registers
411.save_386_control_registers:
412CPU 386
413 mov ax, ss
414 test al, 3
415 jnz .skip_crX_because_cpl_not_0
416 mov eax, cr0
417 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.cr0], eax
418 mov eax, cr2
419 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.cr2], eax
420 mov eax, cr3
421 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.cr3], eax
422
423 test byte [1 + BS3_DATA16_WRT(g_uBs3CpuDetected)], (BS3CPU_F_CPUID >> 8) ; CR4 first appeared in later 486es.
424 jz .skip_cr4_because_not_there
425 mov eax, cr4
426 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.cr4], eax
427 jmp .set_flags
428
429.skip_cr4_because_not_there:
430 mov byte [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.fbFlags], BS3REG_CTX_F_NO_CR4
431 jmp .set_flags
432
433.skip_crX_because_cpl_not_0:
434 or byte [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.fbFlags], BS3REG_CTX_F_NO_CR
435 jmp .set_flags
436
437CPU 286
438.save_286_control_registers:
439 smsw [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.cr0]
440
441.set_flags: ; The double fault code joins us here.
442 or byte [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.fbFlags], BS3REG_CTX_F_NO_AMD64
443
444 ;
445 ; Dispatch it to C code.
446 ;
447.dispatch_to_handler:
448 mov di, bx
449 mov bl, byte [ss:bx + BS3TRAPFRAME.bXcpt]
450 mov bh, 0
451 shl bx, 1
452 mov bx, [bx + BS3_DATA16_WRT(_g_apfnBs3TrapHandlers_c16)]
453 or bx, bx
454 jnz .call_handler
455 mov bx, Bs3TrapDefaultHandler
456.call_handler:
457 push ss
458 push di
459 call bx
460
461 ;
462 ; Resume execution using trap frame.
463 ;
464 push 0
465 push ss
466 add di, BS3TRAPFRAME.Ctx
467 push di
468 call Bs3RegCtxRestore
469.panic:
470 hlt
471 jmp .panic
472BS3_PROC_END bs3Trap16GenericCommon
473
474
475;;
476; Helper.
477;
478; @retruns Flat address in es:di.
479; @param di
480; @uses eax
481;
482bs3Trap16TssInDiToFar1616InEsDi:
483CPU 286
484 push ax
485
486 ; ASSUME Bs3Gdt is being used.
487 push BS3_SEL_SYSTEM16
488 pop es
489 and di, 0fff8h
490 add di, Bs3Gdt wrt BS3SYSTEM16
491
492 ; Load the TSS base into ax:di (di is low, ax high)
493 mov al, [es:di + (X86DESCGENERIC_BIT_OFF_BASE_HIGH1 / 8)]
494 mov ah, [es:di + (X86DESCGENERIC_BIT_OFF_BASE_HIGH2 / 8)]
495 mov di, [es:di + (X86DESCGENERIC_BIT_OFF_BASE_LOW / 8)]
496
497 ; Convert ax to tiled selector, if not within the tiling area we read
498 ; random BS3SYSTEM16 bits as that's preferable to #GP'ing.
499 shl ax, X86_SEL_SHIFT
500 cmp ax, BS3_SEL_TILED_LAST - BS3_SEL_TILED
501%ifdef BS3_STRICT
502 jbe .tiled
503 int3
504%endif
505 ja .return ; don't crash again.
506.tiled:
507 add ax, BS3_SEL_TILED
508 mov es, ax
509.return:
510 pop ax
511 ret
512
513
514;;
515; Double fault handler.
516;
517; We don't have to load any selectors or clear anything in EFLAGS because the
518; TSS specified sane values which got loaded during the task switch.
519;
520; @param dx Zero (0) for indicating 386+ to the common code.
521;
522BS3_PROC_BEGIN _Bs3Trap16DoubleFaultHandler80386
523BS3_PROC_BEGIN Bs3Trap16DoubleFaultHandler80386
524CPU 386
525 push 0 ; We'll copy the rip from the other TSS here later to create a more sensible call chain.
526 push ebp
527 mov bp, sp
528 pushfd ; Handler flags.
529
530 ; Reserve space for the the register and trap frame.
531 mov bx, (BS3TRAPFRAME_size + 15) / 16
532.more_zeroed_space:
533 push dword 0
534 push dword 0
535 push dword 0
536 push dword 0
537 dec bx
538 jz .more_zeroed_space
539 mov bx, sp
540
541 ;
542 ; Fill in the high GRP register words before we mess them up.
543 ;
544 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rax], eax
545 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rbx], ebx
546 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rcx], ecx
547 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rdx], edx
548 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rsi], esi
549 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rdi], edi
550 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rbp], ebp
551 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rsp], esp
552
553 ;
554 ; FS and GS are not part of the 16-bit TSS because they are 386+ specfic.
555 ;
556 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.fs], fs
557 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.gs], gs
558
559 ;
560 ; Fill in the non-context trap frame bits.
561 ;
562 mov ecx, [bp - 4]
563 mov [ss:bx + BS3TRAPFRAME.fHandlerRfl], ecx
564 mov byte [ss:bx + BS3TRAPFRAME.bXcpt], X86_XCPT_DF
565 mov [ss:bx + BS3TRAPFRAME.uHandlerCs], cs
566 mov [ss:bx + BS3TRAPFRAME.uHandlerSs], ss
567 mov ecx, esp
568 lea cx, [bp + 8]
569 mov [ss:bx + BS3TRAPFRAME.uHandlerRsp], ecx
570 mov cx, [bp + 6]
571 mov [ss:bx + BS3TRAPFRAME.uErrCd], cx
572
573 ;
574 ; Copy 80386+ control registers.
575 ;
576 mov ecx, cr0
577 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.cr0], ecx
578 mov ecx, cr2
579 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.cr2], ecx
580 mov ecx, cr3
581 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.cr3], ecx
582
583 test byte [1 + BS3_DATA16_WRT(g_uBs3CpuDetected)], (BS3CPU_F_CPUID >> 8) ; CR4 first appeared in later 486es.
584 jz .skip_cr4_because_not_there
585 mov ecx, cr4
586 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.cr4], ecx
587 jmp .common
588
589.skip_cr4_because_not_there:
590 mov byte [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.fbFlags], BS3REG_CTX_F_NO_CR4
591
592 ;
593 ; Copy the register state from the previous task segment.
594 ; The 80286 code with join us here.
595 ;
596.common:
597CPU 286
598 ; Find our TSS.
599 str di
600 call bs3Trap16TssInDiToFar1616InEsDi
601
602 ; Find the previous TSS.
603 mov di, [es:di + X86TSS32.selPrev]
604 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.tr], ax
605 call bs3Trap16TssInDiToFar1616InEsDi
606
607 ; Do the copying.
608 mov cx, [es:di + X86TSS16.ax]
609 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rax], cx
610 mov cx, [es:di + X86TSS16.cx]
611 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rcx], cx
612 mov cx, [es:di + X86TSS16.dx]
613 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rdx], cx
614 mov cx, [es:di + X86TSS16.bx]
615 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rbx], cx
616 mov cx, [es:di + X86TSS16.sp]
617 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rsp], cx
618 mov cx, [es:di + X86TSS16.bp]
619 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rbp], cx
620 mov [bp], cx ; For better call stacks.
621 mov cx, [es:di + X86TSS16.si]
622 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rsi], cx
623 mov cx, [es:di + X86TSS16.di]
624 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rdi], cx
625 mov cx, [es:di + X86TSS16.si]
626 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rsi], cx
627 mov cx, [es:di + X86TSS16.flags]
628 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rflags], cx
629 mov cx, [es:di + X86TSS16.ip]
630 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rip], cx
631 mov [bp + 2], cx ; For better call stacks.
632 mov cx, [es:di + X86TSS16.cs]
633 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.cs], cx
634 mov cx, [es:di + X86TSS16.ds]
635 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.ds], cx
636 mov cx, [es:di + X86TSS16.es]
637 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.es], cx
638 mov cx, [es:di + X86TSS16.ss]
639 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.ss], cx
640 mov cx, [es:di + X86TSS16.selLdt] ; Note! This isn't necessarily the ldtr at the time of the fault.
641 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.ldtr], cx
642
643 ;
644 ; Set CPL; copy and update mode.
645 ;
646 mov cl, [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.ss]
647 and cl, 3
648 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.bCpl], cl
649
650 mov cl, [BS3_DATA16_WRT(g_bBs3CurrentMode)]
651 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.bMode], cl
652 and cl, ~BS3_MODE_CODE_MASK
653 or cl, BS3_MODE_CODE_16
654 mov [BS3_DATA16_WRT(g_bBs3CurrentMode)], cl
655
656 ;
657 ; Join code paths with the generic handler code.
658 ;
659 jmp bs3Trap16GenericCommon.set_flags
660BS3_PROC_END Bs3Trap16DoubleFaultHandler
661
662
663;;
664; Double fault handler.
665;
666; We don't have to load any selectors or clear anything in EFLAGS because the
667; TSS specified sane values which got loaded during the task switch.
668;
669; @param dx One (1) for indicating 386+ to the common code.
670;
671BS3_PROC_BEGIN _Bs3Trap16DoubleFaultHandler80286
672BS3_PROC_BEGIN Bs3Trap16DoubleFaultHandler80286
673CPU 286
674 push 0 ; We'll copy the rip from the other TSS here later to create a more sensible call chain.
675 push bp
676 mov bp, sp
677 pushf ; Handler flags.
678
679 ; Reserve space for the the register and trap frame.
680 mov bx, (BS3TRAPFRAME_size + 7) / 8
681.more_zeroed_space:
682 push 0
683 push 0
684 push 0
685 push 0
686 dec bx
687 jz .more_zeroed_space
688 mov bx, sp
689
690 ;
691 ; Fill in the non-context trap frame bits.
692 ;
693 mov cx, [bp - 2]
694 mov [ss:bx + BS3TRAPFRAME.fHandlerRfl], cx
695 mov byte [ss:bx + BS3TRAPFRAME.bXcpt], X86_XCPT_DF
696 mov [ss:bx + BS3TRAPFRAME.uHandlerCs], cs
697 mov [ss:bx + BS3TRAPFRAME.uHandlerSs], ss
698 lea cx, [bp + 8]
699 mov [ss:bx + BS3TRAPFRAME.uHandlerRsp], cx
700 mov cx, [bp + 6]
701 mov [ss:bx + BS3TRAPFRAME.uErrCd], cx
702
703 ;
704 ; Copy 80286 specific control register.
705 ;
706 smsw [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.cr0]
707
708 jmp Bs3Trap16DoubleFaultHandler80386.common
709BS3_PROC_END Bs3Trap16DoubleFaultHandler80286
710
711
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