VirtualBox

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

Last change on this file since 77922 was 76553, checked in by vboxsync, 6 years ago

scm --update-copyright-year

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