VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/bootsectors/bootsector2-cpu-xcpt-2-template.mac@ 103068

Last change on this file since 103068 was 98103, checked in by vboxsync, 23 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 13.9 KB
Line 
1; $Id: bootsector2-cpu-xcpt-2-template.mac 98103 2023-01-17 14:15:46Z vboxsync $
2;; @file
3; Bootsector test for debug exceptions - multi mode template.
4;
5
6;
7; Copyright (C) 2007-2023 Oracle and/or its affiliates.
8;
9; This file is part of VirtualBox base platform packages, as
10; available from https://www.virtualbox.org.
11;
12; This program is free software; you can redistribute it and/or
13; modify it under the terms of the GNU General Public License
14; as published by the Free Software Foundation, in version 3 of the
15; License.
16;
17; This program is distributed in the hope that it will be useful, but
18; WITHOUT ANY WARRANTY; without even the implied warranty of
19; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20; General Public License for more details.
21;
22; You should have received a copy of the GNU General Public License
23; along with this program; if not, see <https://www.gnu.org/licenses>.
24;
25; The contents of this file may alternatively be used under the terms
26; of the Common Development and Distribution License Version 1.0
27; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
28; in the VirtualBox distribution, in which case the provisions of the
29; CDDL are applicable instead of those of the GPL.
30;
31; You may elect to license modified versions of this file under the
32; terms and conditions of either the GPL or the CDDL or both.
33;
34; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
35;
36
37
38%include "bootsector2-template-header.mac"
39
40
41;*******************************************************************************
42;* Defined Constants And Macros *
43;*******************************************************************************
44;;
45; Some 32/64 macros.
46;
47%if TMPL_BITS == 32
48 %define bs2Idt_BP bs2Idt32bit_BP
49 %define MY_R0_CS BS2_SEL_CS32
50 %define MY_R1_CS BS2_SEL_R1_CS32
51 %define MY_R2_CS BS2_SEL_R2_CS32
52 %define MY_R3_CS BS2_SEL_R3_CS32
53
54 %define MY_R0_DS BS2_SEL_DS32
55 %define MY_R1_DS BS2_SEL_R1_DS32
56 %define MY_R2_DS BS2_SEL_R2_DS32
57 %define MY_R3_DS BS2_SEL_R3_DS32
58
59 %define MY_R0_SS BS2_SEL_SS32
60 %define MY_R1_SS BS2_SEL_R1_SS32
61 %define MY_R2_SS BS2_SEL_R2_SS32
62 %define MY_R3_SS BS2_SEL_R3_SS32
63
64%else
65 %define bs2Idt_BP bs2Idt64bit_BP
66 %define MY_R0_CS BS2_SEL_CS64
67 %define MY_R1_CS BS2_SEL_R1_CS64
68 %define MY_R2_CS BS2_SEL_R2_CS64
69 %define MY_R3_CS BS2_SEL_R3_CS64
70
71 %define MY_R0_DS BS2_SEL_DS64
72 %define MY_R1_DS BS2_SEL_R1_DS64
73 %define MY_R2_DS BS2_SEL_R2_DS64
74 %define MY_R3_DS BS2_SEL_R3_DS64
75
76 %define MY_R0_SS BS2_SEL_SS64
77 %define MY_R1_SS BS2_SEL_R1_SS64
78 %define MY_R2_SS BS2_SEL_R2_SS64
79 %define MY_R3_SS BS2_SEL_R3_SS64
80%endif
81
82%ifdef TMPL_64BIT
83 %assign MY_IS_64BIT 1
84%else
85 %assign MY_IS_64BIT 0
86%endif
87
88;; Uncomment this to do lots more iterations (takes time!).
89%define QUICK_TEST
90
91
92;*******************************************************************************
93;* Global Variables *
94;*******************************************************************************
95%ifndef CPU_XCPT_1_GLOBALS
96 %define CPU_XCPT_1_GLOBALS
97
98;;
99; Asserts a test.
100;
101; @param %1 First cmp operand.
102; @param %2 First cmp operand.
103; @param %3 Which kind of conditional jump to make
104; @param %4 The message to print (format string, no arguments please).
105;
106 %macro ASSERT_SIMPLE 4
107 cmp %1, %2
108 %3 %%.ok
109 cli ; raw-mode hack
110 push dword __LINE__
111 %ifdef TMPL_16BIT
112 push ds
113 %endif
114 push %%.s_szMsg
115 call TMPL_NM_CMN(TestFailedF)
116 add xSP, sCB*2
117 ;hlt
118 sti
119 jmp %%.ok
120 %%.s_szMsg: db %4, " (0x%RX32)", 0
121 %%.ok:
122 %endmacro
123
124%endif
125
126
127;;
128; Disable the breakpoints as well as check RA1 bits.
129;
130; @changes DRx
131;
132BEGINPROC TMPL_NM(DisableBps)
133 push sAX
134 push sBX
135 sPUSHF
136
137 xor eax, eax
138 mov dr7, sAX
139 mov dr6, sAX
140 mov dr0, sAX
141 mov dr1, sAX
142 mov dr2, sAX
143 mov dr3, sAX
144
145 mov sAX, dr6
146 mov ebx, X86_DR6_RA1_MASK
147 ASSERT_SIMPLE sAX, xBX, je, "Wrong DR6 value (RA1)."
148 mov sAX, dr7
149 mov ebx, X86_DR7_RA1_MASK
150 ASSERT_SIMPLE sAX, sBX, je, "Wrong DR7 value (RA1)."
151
152 sPOPF
153 pop sBX
154 pop sAX
155 ret
156ENDPROC TMPL_NM(DisableBps)
157
158
159;;
160; Checks different gate types.
161;
162BEGINPROC TMPL_NM(TestStepping)
163 push xBP
164 mov xBP, xSP
165 push sAX
166 push xBX
167 push xCX
168 push xDX
169 push xDI
170 push xSI
171
172 mov xAX, .s_szSubTestName
173 call TMPL_NM_CMN(TestSub)
174
175
176 ;
177 ; Step one instruction a lot of times to catch DR6 mismanagement.
178 ;
179%ifdef QUICK_TEST
180 mov ecx, 0x1000
181%else
182 mov ecx, 0x80000
183%endif
184.the_1st_loop:
185
186 mov eax, X86_DR6_INIT_VAL
187 mov dr6, sAX
188 mov eax, 0x12345678
189 mov ebx, 0xaabbccdd
190 sPUSHF
191 or word [xSP], X86_EFL_TF
192 sPOPF
193 xchg ebx, eax
194 BS2_TRAP_INSTR X86_XCPT_DB, 0, nop
195 ASSERT_SIMPLE eax, 0xaabbccdd, je, "xchg wasn't executed (eax)."
196 ASSERT_SIMPLE ebx, 0x12345678, je, "xchg wasn't executed (ebx)."
197 mov sAX, dr6
198 ASSERT_SIMPLE eax, (X86_DR6_INIT_VAL | X86_DR6_BS), je, "Wrong DR6 value."
199
200 dec ecx
201 jnz .the_1st_loop
202
203 ;
204 ; Check that certain bits in DR6 is preserved and others not.
205 ;
206%ifdef QUICK_TEST
207 mov ecx, 0x200
208%else
209 mov ecx, 0x20000
210%endif
211.the_2nd_loop:
212 mov eax, X86_DR6_INIT_VAL | X86_DR6_B0 | X86_DR6_B1 | X86_DR6_B2 | X86_DR6_B3 | X86_DR6_BT | X86_DR6_BD
213 mov dr6, sAX
214 mov eax, 0x12345678
215 mov ebx, 0xaabbccdd
216 sPUSHF
217 or word [xSP], X86_EFL_TF
218 sPOPF
219 xchg ebx, eax
220 BS2_TRAP_INSTR X86_XCPT_DB, 0, nop
221 ASSERT_SIMPLE eax, 0xaabbccdd, je, "xchg wasn't executed (eax)."
222 ASSERT_SIMPLE ebx, 0x12345678, je, "xchg wasn't executed (ebx)."
223 mov sAX, dr6
224 ASSERT_SIMPLE eax, (X86_DR6_BS | X86_DR6_INIT_VAL | X86_DR6_BT | X86_DR6_BD), je, "Wrong DR6 value."
225
226 dec ecx
227 jnz .the_2nd_loop
228
229 ;
230 ; Done.
231 ;
232 cli ; raw-mode hack
233 call TMPL_NM_CMN(TestSubDone)
234 sti
235
236 pop xSI
237 pop xDI
238 pop xDX
239 pop xCX
240 pop xBX
241 pop sAX
242 leave
243 ret
244
245.s_szSubTestName:
246 db TMPL_MODE_STR, ', EFLAGS.TF stepping', 0
247ENDPROC TMPL_NM(TestGateType)
248
249
250;;
251; Check execution breakpoint.
252;
253BEGINPROC TMPL_NM(TestBpExec)
254 push xBP
255 mov xBP, xSP
256 push sAX
257 push xBX
258 push xCX
259 push xDX
260 push xDI
261 push xSI
262
263 mov xAX, .s_szSubTestName
264 call TMPL_NM_CMN(TestSub)
265
266
267 ;
268 ; Arm all 4 breakpoints and check DR6 management.
269 ;
270%ifdef QUICK_TEST
271 mov ecx, 0x1000
272%else
273 mov ecx, 0x80000
274%endif
275 lea sAX, [.bp_dr0 xWrtRIP]
276 mov dr0, sAX
277 lea sAX, [.bp_dr1 xWrtRIP]
278 mov dr1, sAX
279 lea sAX, [.bp_dr2 xWrtRIP]
280 mov dr2, sAX
281 lea sAX, [.bp_dr3 xWrtRIP]
282 mov dr3, sAX
283 mov eax, X86_DR7_RA1_MASK | X86_DR7_G0 | X86_DR7_G1 | X86_DR7_G2 | X86_DR7_G3 | X86_DR7_GE
284 mov dr7, sAX
285
286.the_loop:
287 mov eax, X86_DR6_INIT_VAL | X86_DR6_BS | X86_DR6_BT | X86_DR6_BD
288 mov dr6, sAX
289
290 mov eax, 0x12345678
291 mov ebx, 0xaabbccdd
292.bp_dr0:
293 BS2_TRAP_INSTR X86_XCPT_DB, 0, xchg ebx, eax
294 ASSERT_SIMPLE eax, 0x12345678, je, "xchg was executed (eax)."
295 ASSERT_SIMPLE ebx, 0xaabbccdd, je, "xchg was executed (ebx)."
296 mov sAX, dr6
297 ASSERT_SIMPLE eax, (X86_DR6_INIT_VAL | X86_DR6_BS | X86_DR6_BT | X86_DR6_BD | X86_DR6_B0), je, "Wrong DR6 value (dr0)."
298
299 mov eax, 0x12345678
300 mov ebx, 0xaabbccdd
301.bp_dr1:
302 BS2_TRAP_INSTR X86_XCPT_DB, 0, xchg ebx, eax
303 ASSERT_SIMPLE eax, 0x12345678, je, "xchg was executed (eax)."
304 ASSERT_SIMPLE ebx, 0xaabbccdd, je, "xchg was executed (ebx)."
305 mov sAX, dr6
306 ASSERT_SIMPLE eax, (X86_DR6_INIT_VAL | X86_DR6_BS | X86_DR6_BT | X86_DR6_BD | X86_DR6_B1), je, "Wrong DR6 value (dr1)."
307
308 mov eax, 0x12345678
309 mov ebx, 0xaabbccdd
310.bp_dr2:
311 BS2_TRAP_INSTR X86_XCPT_DB, 0, xchg ebx, eax
312 ASSERT_SIMPLE eax, 0x12345678, je, "xchg was executed (eax)."
313 ASSERT_SIMPLE ebx, 0xaabbccdd, je, "xchg was executed (ebx)."
314 mov sAX, dr6
315 ASSERT_SIMPLE eax, (X86_DR6_INIT_VAL | X86_DR6_BS | X86_DR6_BT | X86_DR6_BD | X86_DR6_B2), je, "Wrong DR6 value (dr2)."
316
317 mov eax, 0x12345678
318 mov ebx, 0xaabbccdd
319.bp_dr3:
320 BS2_TRAP_INSTR X86_XCPT_DB, 0, xchg ebx, eax
321 ASSERT_SIMPLE eax, 0x12345678, je, "xchg was executed (eax)."
322 ASSERT_SIMPLE ebx, 0xaabbccdd, je, "xchg was executed (ebx)."
323 mov sAX, dr6
324 ASSERT_SIMPLE eax, (X86_DR6_INIT_VAL | X86_DR6_BS | X86_DR6_BT | X86_DR6_BD | X86_DR6_B3), je, "Wrong DR6 value (dr3)."
325
326 dec ecx
327 jnz .the_loop
328
329 ;
330 ; Touch the code, making sure the BPs don't trigger on data access.
331 ;
332 mov al, [.bp_dr0 xWrtRIP]
333 mov [.bp_dr0 xWrtRIP], al
334 mov al, [.bp_dr1 xWrtRIP]
335 mov [.bp_dr1 xWrtRIP], al
336 mov al, [.bp_dr2 xWrtRIP]
337 mov [.bp_dr2 xWrtRIP], al
338 mov al, [.bp_dr3 xWrtRIP]
339 mov [.bp_dr3 xWrtRIP], al
340
341 ;
342 ; Done.
343 ;
344 call TMPL_NM(DisableBps)
345 cli ; raw-mode hack
346 call TMPL_NM_CMN(TestSubDone)
347 sti
348
349 pop xSI
350 pop xDI
351 pop xDX
352 pop xCX
353 pop xBX
354 pop sAX
355 leave
356 ret
357
358.s_szSubTestName:
359 db TMPL_MODE_STR, ', Exec BP', 0
360ENDPROC TMPL_NM(TestBpExec)
361
362
363;;
364; Check I/O breakpoints.
365;
366BEGINPROC TMPL_NM(TestBpIo)
367 push xBP
368 mov xBP, xSP
369 push sAX
370 push xBX
371 push xCX
372 push xDX
373 push xDI
374 push xSI
375
376 mov xAX, .s_szSubTestName
377 call TMPL_NM_CMN(TestSub)
378
379
380 ;
381 ; Arm all 4 breakpoints and check range handling and such.
382 ;
383 mov sAX, cr4
384 or sAX, X86_CR4_DE
385 mov cr4, sAX
386
387%ifdef QUICK_TEST
388 mov ecx, 1000
389%else
390 mov ecx, 4096
391%endif
392 mov sAX, 84h
393 mov dr0, sAX
394 mov sAX, 85h
395 mov dr1, sAX
396 mov sAX, 86h
397 mov dr2, sAX
398 mov sAX, 8ch
399 mov dr3, sAX
400 mov eax, X86_DR7_RA1_MASK | X86_DR7_LE | X86_DR7_GE \
401 | X86_DR7_L0 | X86_DR7_G0 | X86_DR7_RW(0, X86_DR7_RW_IO) | X86_DR7_LEN(0, X86_DR7_LEN_BYTE) \
402 | X86_DR7_L1 | X86_DR7_G1 | X86_DR7_RW(1, X86_DR7_RW_IO) | X86_DR7_LEN(1, X86_DR7_LEN_WORD) \
403 | X86_DR7_L2 | X86_DR7_G2 | X86_DR7_RW(2, X86_DR7_RW_IO) | X86_DR7_LEN(2, X86_DR7_LEN_DWORD) \
404 | X86_DR7_L3 | X86_DR7_G3 | X86_DR7_RW(3, X86_DR7_RW_IO) | X86_DR7_LEN(3, X86_DR7_LEN_DWORD)
405 mov dr7, sAX
406
407.the_loop:
408 mov eax, X86_DR6_INIT_VAL
409 mov dr6, sAX
410
411 mov eax, 0x12345678
412 in eax, 84h
413 BS2_TRAP_INSTR X86_XCPT_DB, 0, nop
414 ASSERT_SIMPLE eax, 0x12345678, jne, "in was not executed."
415 mov sAX, dr6
416 ASSERT_SIMPLE eax, (X86_DR6_INIT_VAL | X86_DR6_B0), je, "Wrong DR6 value (dr0)."
417
418 mov ebx, 0x12345678
419 in eax, 85h
420 BS2_TRAP_INSTR X86_XCPT_DB, 0, nop
421 ASSERT_SIMPLE eax, 0x12345678, jne, "in was not executed."
422 mov sAX, dr6
423 ASSERT_SIMPLE eax, (X86_DR6_INIT_VAL | X86_DR6_B1), je, "Wrong DR6 value (dr1)."
424
425 mov eax, 0x12345678
426 in eax, 86h
427 BS2_TRAP_INSTR X86_XCPT_DB, 0, nop
428 ASSERT_SIMPLE eax, 0x12345678, jne, "in was not executed."
429 mov sAX, dr6
430 ASSERT_SIMPLE eax, (X86_DR6_INIT_VAL | X86_DR6_B2), je, "Wrong DR6 value (dr2)."
431
432 mov eax, 0x12345678
433 in eax, 8ch
434 BS2_TRAP_INSTR X86_XCPT_DB, 0, nop
435 ASSERT_SIMPLE eax, 0x12345678, jne, "in was not executed."
436 mov sAX, dr6
437 ASSERT_SIMPLE eax, (X86_DR6_INIT_VAL | X86_DR6_B3), je, "Wrong DR6 value (dr3)."
438
439 dec ecx
440 jnz .the_loop
441
442 ;
443 ; Done.
444 ;
445 call TMPL_NM(DisableBps)
446 cli ; raw-mode hack
447 call TMPL_NM_CMN(TestSubDone)
448 sti
449
450 pop xSI
451 pop xDI
452 pop xDX
453 pop xCX
454 pop xBX
455 pop sAX
456 leave
457 ret
458
459.s_szSubTestName:
460 db TMPL_MODE_STR, ', I/O BP', 0
461ENDPROC TMPL_NM(TestBpIo)
462
463
464;;
465; Do the tests for this mode.
466;
467; @uses nothing
468;
469BEGINCODELOW
470BITS 16
471BEGINPROC TMPL_NM(DoTestsForMode_rm)
472 push bp
473 mov bp, sp
474 push ax
475
476 ;
477 ; Check if the mode and NX is supported, do the switch.
478 ;
479 call TMPL_NM(Bs2IsModeSupported_rm)
480 jz .done
481 call TMPL_NM(Bs2EnterMode_rm)
482BITS TMPL_BITS
483 pushf
484 sti ; raw-mode hacks
485
486 ;
487 ; Do the testing.
488 ;
489
490 call TMPL_NM(TestStepping)
491 call TMPL_NM(TestBpExec)
492 call TMPL_NM(TestBpIo)
493
494 ;
495 ; Back to real mode.
496 ;
497 popf
498 call TMPL_NM(Bs2ExitMode)
499BITS 16
500 call Bs2DisableNX_r86
501
502.done:
503 pop ax
504 leave
505 ret
506ENDPROC TMPL_NM(DoTestsForMode_rm)
507TMPL_BEGINCODE
508BITS TMPL_BITS
509
510%include "bootsector2-template-footer.mac"
511
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