VirtualBox

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

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

bs3kit: fixes.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 15.3 KB
Line 
1; $Id: bs3-c16-TrapRmV86Generic.asm 60661 2016-04-22 16:46:15Z vboxsync $
2;; @file
3; BS3Kit - Trap, 16-bit assembly handlers for real mode and v8086.
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
44TMPL_BEGIN_TEXT
45BS3_EXTERN_CMN Bs3TrapDefaultHandler
46BS3_EXTERN_CMN Bs3RegCtxRestore
47TMPL_BEGIN_TEXT
48
49
50;;
51; Generic entry points for IDT handlers, 8 byte spacing.
52;
53BS3_PROC_BEGIN _Bs3TrapRmV86GenericEntries
54BS3_PROC_BEGIN Bs3TrapRmV86GenericEntries
55%macro Bs3TrapRmV86GenericEntryNoErr 1
56 push ax ; 1 byte: Reserve space for fake error cd. (BP(+2) + 4)
57 push ax ; 1 byte: Save AX (BP(+2) + 2)
58 mov ax, i | 00000h ; 2 bytes: AL = trap/interrupt number; AH=indicate no error code
59 jmp %1 ; 3 bytes: Jump to handler code
60 ALIGNCODE(8)
61%assign i i+1
62%endmacro
63
64%macro Bs3TrapRmV86GenericEntryErrCd 1
65 push ax ; 1 byte: Save AX (BP(+2) + 2)
66 mov ax, i | 0ff00h ; 2 bytes: AL = trap/interrupt number; AH=indicate have error code.
67 jmp %1 ; 3 bytes: Jump to handler code
68 ALIGNCODE(8)
69%assign i i+1
70%endmacro
71
72%assign i 0 ; start counter.
73 Bs3TrapRmV86GenericEntryNoErr bs3TrapRmV86GenericTrapOrInt ; 0
74 Bs3TrapRmV86GenericEntryNoErr bs3TrapRmV86GenericTrapOrInt ; 1
75 Bs3TrapRmV86GenericEntryNoErr bs3TrapRmV86GenericTrapOrInt ; 2
76 Bs3TrapRmV86GenericEntryNoErr bs3TrapRmV86GenericTrapOrInt ; 3
77 Bs3TrapRmV86GenericEntryNoErr bs3TrapRmV86GenericTrapOrInt ; 4
78 Bs3TrapRmV86GenericEntryNoErr bs3TrapRmV86GenericTrapOrInt ; 5
79 Bs3TrapRmV86GenericEntryNoErr bs3TrapRmV86GenericTrapOrInt ; 6
80 Bs3TrapRmV86GenericEntryNoErr bs3TrapRmV86GenericTrapOrInt ; 7
81 Bs3TrapRmV86GenericEntryErrCd bs3TrapRmV86GenericTrapOrInt ; 8
82 Bs3TrapRmV86GenericEntryNoErr bs3TrapRmV86GenericTrapOrInt ; 9
83 Bs3TrapRmV86GenericEntryErrCd bs3TrapRmV86GenericTrapOrInt ; a
84 Bs3TrapRmV86GenericEntryErrCd bs3TrapRmV86GenericTrapOrInt ; b
85 Bs3TrapRmV86GenericEntryErrCd bs3TrapRmV86GenericTrapOrInt ; c
86 Bs3TrapRmV86GenericEntryErrCd bs3TrapRmV86GenericTrapOrInt ; d
87 Bs3TrapRmV86GenericEntryErrCd bs3TrapRmV86GenericTrapOrInt ; e
88 Bs3TrapRmV86GenericEntryNoErr bs3TrapRmV86GenericTrapOrInt ; f (reserved)
89 Bs3TrapRmV86GenericEntryNoErr bs3TrapRmV86GenericTrapOrInt ; 10
90 Bs3TrapRmV86GenericEntryErrCd bs3TrapRmV86GenericTrapOrInt ; 11
91 Bs3TrapRmV86GenericEntryNoErr bs3TrapRmV86GenericTrapOrInt ; 12
92 Bs3TrapRmV86GenericEntryNoErr bs3TrapRmV86GenericTrapOrInt ; 13
93 Bs3TrapRmV86GenericEntryNoErr bs3TrapRmV86GenericTrapOrInt ; 14
94 Bs3TrapRmV86GenericEntryNoErr bs3TrapRmV86GenericTrapOrInt ; 15 (reserved)
95 Bs3TrapRmV86GenericEntryNoErr bs3TrapRmV86GenericTrapOrInt ; 16 (reserved)
96 Bs3TrapRmV86GenericEntryNoErr bs3TrapRmV86GenericTrapOrInt ; 17 (reserved)
97 Bs3TrapRmV86GenericEntryNoErr bs3TrapRmV86GenericTrapOrInt ; 18 (reserved)
98 Bs3TrapRmV86GenericEntryNoErr bs3TrapRmV86GenericTrapOrInt ; 19 (reserved)
99 Bs3TrapRmV86GenericEntryNoErr bs3TrapRmV86GenericTrapOrInt ; 1a (reserved)
100 Bs3TrapRmV86GenericEntryNoErr bs3TrapRmV86GenericTrapOrInt ; 1b (reserved)
101 Bs3TrapRmV86GenericEntryNoErr bs3TrapRmV86GenericTrapOrInt ; 1c (reserved)
102 Bs3TrapRmV86GenericEntryNoErr bs3TrapRmV86GenericTrapOrInt ; 1d (reserved)
103 Bs3TrapRmV86GenericEntryErrCd bs3TrapRmV86GenericTrapOrInt ; 1e
104 Bs3TrapRmV86GenericEntryNoErr bs3TrapRmV86GenericTrapOrInt ; 1f (reserved)
105%rep 224
106 Bs3TrapRmV86GenericEntryNoErr bs3TrapRmV86GenericTrapOrInt
107%endrep
108BS3_PROC_END Bs3TrapRmV86GenericEntries
109AssertCompile(Bs3TrapRmV86GenericEntries_EndProc - Bs3TrapRmV86GenericEntries == 8*256)
110
111
112;;
113; Trap or interrupt with error code, faked if necessary.
114;
115BS3_PROC_BEGIN _bs3TrapRmV86GenericTrapOrInt
116BS3_PROC_BEGIN bs3TrapRmV86GenericTrapOrInt
117CPU 386
118 jmp near bs3TrapRmV86GenericTrapErrCode8086 ; Bs3TrapRmV86Init adjusts this on 80386+
119 push ebp
120 movzx ebp, sp
121 push ebx ; BP - 04h
122 pushfd ; BP - 08h
123 cld
124 push edx ; BP - 0ch
125 push ss ; BP - 0eh
126 push esp ; BP - 12h
127
128 ; Reserve space for the the register and trap frame.
129 mov bx, (BS3TRAPFRAME_size + 7) / 8
130.more_zeroed_space:
131 push 0
132 push 0
133 push 0
134 push 0
135 dec bx
136 jnz .more_zeroed_space
137 movzx ebx, sp
138
139
140 mov edx, [bp - 12h]
141 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rsp], edx ; high bits
142 mov [ss:bx + BS3TRAPFRAME.uHandlerRsp], edx ; high bits
143 mov dx, [bp - 0eh]
144 mov [ss:bx + BS3TRAPFRAME.uHandlerSs], dx
145 mov edx, [bp - 0ch]
146 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rdx], edx
147 mov edx, [bp - 8]
148 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rflags], edx ; high bits
149 mov [ss:bx + BS3TRAPFRAME.fHandlerRfl], edx
150 mov edx, [bp - 4]
151 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rbx], edx
152 mov edx, [bp]
153 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rbp], edx
154 mov edx, eax ; high bits
155 mov dx, [bp + 4]
156 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rax], edx
157
158 mov [ss:bx + BS3TRAPFRAME.bXcpt], al
159
160 test ah, 0ffh
161 jz .no_error_code
162;; @todo Do voodoo checks for 'int xx' or misguided hardware interrupts.
163 mov dx, [bp + 6]
164 mov [ss:bx + BS3TRAPFRAME.uErrCd], dx
165.no_error_code:
166
167 add bp, 6 ; adjust so it points to the word before the iret frame.
168 xor dx, dx
169 jmp bs3TrapRmV86GenericCommon
170BS3_PROC_END bs3TrapRmV86GenericTrapErrCode
171
172;;
173; Trap with error code - 8086/V20/80186/80286 code variant.
174;
175BS3_PROC_BEGIN bs3TrapRmV86GenericTrapErrCode8086
176CPU 8086
177 push bp
178 mov bp, sp
179 push bx ; BP - 2
180 pushf ; BP - 4
181 push ax ; BP - 6
182 cld
183
184 ; Reserve space for the the register and trap frame.
185 mov bx, (BS3TRAPFRAME_size + 7) / 8
186 xor ax, ax
187.more_zeroed_space:
188 push ax
189 push ax
190 push ax
191 push ax
192 dec bx
193 jnz .more_zeroed_space
194 mov bx, sp
195
196 mov [ss:bx + BS3TRAPFRAME.uHandlerSs], ss
197 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rdx], dx
198 mov dx, [bp - 4]
199 mov [ss:bx + BS3TRAPFRAME.fHandlerRfl], dx
200 mov dx, [bp - 2]
201 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rbx], dx
202 mov dx, [bp]
203 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rbp], dx
204
205 mov dx, [bp + 2]
206 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rax], dx
207
208 mov ax, [bp - 6]
209 mov [ss:bx + BS3TRAPFRAME.bXcpt], al
210
211 test ah, 0ffh
212 jz .no_error_code
213;; @todo Do voodoo checks for 'int xx' or misguided hardware interrupts.
214 mov dx, [bp + 4]
215 mov [ss:bx + BS3TRAPFRAME.uErrCd], dx
216.no_error_code:
217
218 add bp, 4 ; adjust so it points to the word before the iret frame.
219 mov dl, 1
220 jmp bs3TrapRmV86GenericCommon
221BS3_PROC_END bs3TrapRmV86GenericTrapErrCode8086
222
223
224;;
225; Common context saving code and dispatching.
226;
227; @param ss:bx Pointer to the trap frame, zero filled. The following members
228; have been filled in by the previous code:
229; - bXcpt
230; - uErrCd
231; - fHandlerRFL
232; - Ctx.eax
233; - Ctx.edx
234; - Ctx.ebx
235; - Ctx.ebp
236; - Ctx.rflags - high bits only.
237; - Ctx.esp - high bits only.
238; - All other bytes are zeroed.
239;
240; @param bp Pointer to the word before the iret frame, i.e. where bp
241; would be saved if this was a normal near call.
242; @param dx One (1) if 286, zero (0) if 386+.
243;
244BS3_PROC_BEGIN bs3TrapRmV86GenericCommon
245CPU 8086
246 ;
247 ; Fake EBP frame.
248 ;
249 mov ax, [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rbp]
250 mov [bp], ax
251
252 ;
253 ; Save the remaining GPRs and segment registers.
254 ;
255 test dx, dx
256 jnz .save_word_grps
257CPU 386
258 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rcx], ecx
259 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rdi], edi
260 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rsi], esi
261 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.fs], fs
262 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.gs], gs
263 jmp .save_segment_registers
264.save_word_grps:
265CPU 8086
266 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rcx], cx
267 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rdi], di
268 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rsi], si
269.save_segment_registers:
270 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.ds], ds
271 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.es], es
272 mov [ss:bx + BS3TRAPFRAME.uHandlerCs], cs
273
274 ;
275 ; Load 16-bit BS3KIT_GRPNM_DATA16 into DS and ES so we can access globals.
276 ;
277 mov ax, BS3KIT_GRPNM_DATA16
278 mov ds, ax
279 mov es, ax
280
281 ;
282 ; Copy the mode now that we've got a flat DS. We don't need to update
283 ; it as it didn't change.
284 ;
285 mov al, [BS3_DATA16_WRT(g_bBs3CurrentMode)]
286 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.bMode], al
287
288 ;
289 ; Copy iret info.
290 ;
291 lea cx, [bp + 2]
292 mov [ss:bx + BS3TRAPFRAME.uHandlerRsp], cx
293 mov cx, [bp + 2]
294 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rip], cx
295 mov cx, [bp + 6]
296 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rflags], cx
297 mov cx, [bp + 4]
298 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.cs], cx
299 mov cx, ss
300 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.ss], cx
301 lea cx, [bp + 8]
302 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rsp], cx
303 mov byte [ss:bx + BS3TRAPFRAME.cbIretFrame], 3*2
304
305 ; The VM flag and CPL.
306 test al, BS3_MODE_CODE_V86
307 jz .dont_set_vm
308 or byte [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.rflags + 2], X86_EFL_VM >> 16
309 mov byte [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.bCpl], 3
310.dont_set_vm:
311
312
313 ;
314 ; Control registers.
315 ;
316 ; Since we're in real or v8086 here, we cannot save TR and LDTR.
317 ; But get MSW (CR0) first since that's always accessible and we
318 ; need it even on a 386 to check whether we're in v8086 mode or not.
319 ;
320 cmp byte [BS3_DATA16_WRT(g_uBs3CpuDetected)], BS3CPU_80286
321 jb .skip_control_registers_because_80186_or_older
322CPU 286
323 smsw ax
324 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.cr0], ax
325
326 test dx, dx
327 jnz .set_flags
328.save_386_control_registers:
329CPU 386
330 ; 386 control registers are not accessible from virtual 8086 mode.
331 test al, X86_CR0_PE
332 jnz .skip_crX_because_v8086
333 mov eax, cr0
334 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.cr0], eax
335 mov eax, cr2
336 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.cr2], eax
337 mov eax, cr3
338 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.cr3], eax
339
340 test byte [1 + BS3_DATA16_WRT(g_uBs3CpuDetected)], (BS3CPU_F_CPUID >> 8) ; CR4 first appeared in later 486es.
341 jz .skip_cr4_because_not_there
342 mov eax, cr4
343 mov [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.cr4], eax
344 jmp .set_flags
345
346.skip_cr4_because_not_there:
347 mov byte [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.fbFlags], BS3REG_CTX_F_NO_CR4
348 jmp .set_flags
349
350CPU 8086
351.skip_control_registers_because_80186_or_older:
352.skip_crX_because_v8086:
353 or byte [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.fbFlags], \
354 BS3REG_CTX_F_NO_CR0_IS_MSW | BS3REG_CTX_F_NO_CR2_CR3 | BS3REG_CTX_F_NO_CR4
355.set_flags: ; The double fault code joins us here.
356 or byte [ss:bx + BS3TRAPFRAME.Ctx + BS3REGCTX.fbFlags], BS3REG_CTX_F_NO_AMD64 | BS3REG_CTX_F_NO_TR_LDTR
357
358 ;
359 ; Dispatch it to C code.
360 ;
361.dispatch_to_handler:
362 mov di, bx
363 mov bl, byte [ss:bx + BS3TRAPFRAME.bXcpt]
364 mov bh, 0
365 shl bx, 1
366 mov bx, [bx + BS3_DATA16_WRT(_g_apfnBs3TrapHandlers_c16)]
367 or bx, bx
368 jnz .call_handler
369 mov bx, Bs3TrapDefaultHandler
370.call_handler:
371 push ss
372 push di
373 call bx
374
375 ;
376 ; Resume execution using trap frame.
377 ;
378 xor ax, ax
379 push ax
380 push ss
381 add di, BS3TRAPFRAME.Ctx
382 push di
383 call Bs3RegCtxRestore
384.panic:
385 hlt
386 jmp .panic
387BS3_PROC_END bs3TrapRmV86GenericCommon
388
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