VirtualBox

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

Last change on this file since 60009 was 60002, checked in by vboxsync, 9 years ago

bs3kit: got the weird v8086 w/ 16-bit tss and trap handlers working.

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