VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/bootsectors/bootsector2-cpu-a20-1.asm@ 72293

Last change on this file since 72293 was 69111, checked in by vboxsync, 7 years ago

(C) year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.9 KB
Line 
1; $Id: bootsector2-cpu-a20-1.asm 69111 2017-10-17 14:26:02Z vboxsync $
2;; @file
3; Bootsector that checks the A20 emulation.
4;
5
6;
7; Copyright (C) 2007-2017 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%include "iprt/asmdefs.mac"
29%include "iprt/x86.mac"
30%include "VBox/VMMDevTesting.mac"
31
32;
33; Include and execute the init code.
34;
35%define BS2_WITH_TRAPS
36%define BS2_INIT_RM
37%define BS2_INC_PE16
38%define BS2_INC_PE32
39%define BS2_INC_PP32
40%define BS2_INC_PAE32
41%define BS2_INC_LM64
42%include "bootsector2-common-init-code.mac"
43
44
45;
46; The benchmark driver
47;
48BEGINPROC main
49 ;
50 ; Test prologue.
51 ;
52 mov ax, .s_szTstName
53 call TestInit_r86
54
55 ;
56 ; The actual tests.
57 ;
58 call TestA20_1 ; must come first
59 call TestA20_rm_rm
60 ;call TestA20_rm_pe16
61 call TestA20_rm_pe32
62 call TestA20_rm_pp32
63 ;call TestA20_rm_pp16
64 call TestA20_rm_pae32
65 call TestA20_rm_lm64
66
67 ;
68 ; We're done.
69 ;
70 call TestTerm_r86
71 call Bs2Panic
72
73.s_szTstName:
74 db 'tstA20-1', 0
75.s_szInitialA20Status:
76 db 'Initial A20 state', 0
77ENDPROC main
78
79
80;
81; Do some initial tests.
82;
83BEGINPROC TestA20_1
84 push eax
85 push edx
86 push ecx
87 push ebx
88 push edi
89
90 ;
91 ; Check that the A20 gate is disabled when we come from the BIOS.
92 ;
93 mov ax, .s_szInitialA20Status
94 call TestSub_r86
95
96 call IsA20GateEnabled_rm
97 mov di, ax ; save A20 state in AX for bios test.
98 cmp al, 0
99 je .initial_state_done
100 mov ax, .s_szBadInitialA20Status
101 call TestFailed_r86
102 jmp .initial_state_done
103.s_szInitialA20Status:
104 db 'Initial A20 state', 0
105.s_szBadInitialA20Status:
106 db 'Initial A20 state is enabled, expected disabled', 10, 13, 0
107.initial_state_done:
108 call TestSubDone_r86
109
110 ;
111 ; Disable it via the BIOS interface and check.
112 ;
113 mov ax, .s_szBios
114 call TestSub_r86
115
116 ; query support
117 mov ax, 2403h
118 int 15h
119 jnc .bios_2403_ok
120 movzx edx, ax
121 mov ax, .s_szBios2403Error
122 mov cl, VMMDEV_TESTING_UNIT_NONE
123 call TestValueU32_r86
124 jmp .bios_2403_done
125.bios_2403_ok:
126 movzx edx, al
127 mov ax, .s_szBios2403Mask
128 mov cl, VMMDEV_TESTING_UNIT_NONE
129 call TestValueU32_r86
130.bios_2403_done:
131
132 ; Check what the bios thinks the state is.
133 call BiosIsA20GateEnabled_rm
134 cmp ax, di
135 je .bios_2402_done
136 push di
137 push ax
138 push word ds
139 push word .s_szBios2402Error
140 call TestFailedF_r86
141 add sp, 8
142.bios_2402_done:
143
144 ; Loop to make sure we get all transitions and ends up with A20 disabled.
145 mov cx, 10h
146.bios_loop:
147 ; enable it
148 mov ax, 2401h
149 push cx ; paranoia that seems necessary for at least one AMI bios.
150 int 15h
151 pop cx
152 jnc .bios_continue1
153 mov ax, .s_szBiosFailed2401
154 jmp .bios_failed
155.bios_continue1:
156
157 call IsA20GateEnabled_rm
158 cmp al, 1
159 je .bios_continue2
160 mov ax, .s_szBiosEnableFailed
161 jmp .bios_failed
162.bios_continue2:
163
164 ; disable
165 mov ax, 2400h
166 push cx ; paranoia that seems necessary for at least one AMI bios.
167 int 15h
168 pop cx
169 jnc .bios_continue3
170 mov ax, .s_szBiosFailed2400
171 jmp .bios_failed
172.bios_continue3:
173 call IsA20GateEnabled_rm
174 cmp al, 0
175 je .bios_continue4
176 mov ax, .s_szBiosDisableFailed
177 jmp .bios_failed
178.bios_continue4:
179
180 loop .bios_loop
181 jmp .bios_done
182.s_szBios:
183 db 'INT 15h AH=24 A20 Gate interface', 0
184.s_szBios2403Mask:
185 db 'AX=2403 return (AL)', 0
186.s_szBios2403Error:
187 db 'AX=2403 error (AX)', 10, 13, 0
188.s_szBios2402Error:
189 db '2402h -> AX=%RX16 expected %RX16', 10, 13, 0
190.s_szBiosFailed2400:
191 db '2400h interface failed', 10, 13, 0
192.s_szBiosFailed2401:
193 db '2401h interface failed', 10, 13, 0
194.s_szBiosDisableFailed:
195 db 'BIOS failed to disable A20 (or bad CPU)', 10, 13, 0
196.s_szBiosEnableFailed:
197 db 'BIOS failed to enable A20', 10, 13, 0
198.bios_failed:
199 call TestFailed_r86
200.bios_done:
201 call TestSubDone_r86
202 call Bs2DisableA20ViaPortA_r86
203 call Bs2DisableA20ViaKbd_r86
204
205 ;
206 ; Test the fast A20 gate interface.
207 ;
208 mov ax, .s_szFastA20
209 call TestSub_r86
210
211 mov cx, 10h
212.fast_loop:
213 call Bs2EnableA20ViaPortA_r86
214 call IsA20GateEnabled_rm
215 cmp al, 1
216 mov ax, .s_szFastEnableFailed
217 jne .fast_failed
218
219 call Bs2DisableA20ViaPortA_r86
220 call IsA20GateEnabled_rm
221 cmp al, 0
222 mov ax, .s_szFastDisableFailed
223 jne .fast_failed
224 loop .fast_loop
225
226 jmp .fast_done
227.s_szFastA20:
228 db 'Fast A20 Gate Interface', 0
229.s_szFastDisableFailed:
230 db 'Fast A20 gate disabling failed', 10, 13, 0
231.s_szFastEnableFailed:
232 db 'Fast A20 gate enabling failed', 10, 13, 0
233.fast_failed:
234 call TestFailed_r86
235.fast_done:
236 call TestSubDone_r86
237 call Bs2DisableA20ViaPortA_r86
238 call Bs2DisableA20ViaKbd_r86
239
240 ;
241 ; Test the keyboard interface.
242 ;
243 mov ax, .s_szKeyboardA20
244 call TestSub_r86
245
246 mov cx, 10h
247.kbd_loop:
248 call Bs2EnableA20ViaKbd_r86
249 call IsA20GateEnabled_rm
250 cmp al, 1
251 mov ax, .s_szKbdEnableFailed
252 jne .kbd_failed
253
254 call Bs2DisableA20ViaKbd_r86
255 call IsA20GateEnabled_rm
256 cmp al, 0
257 mov ax, .s_szKbdDisableFailed
258 jne .kbd_failed
259 loop .kbd_loop
260
261 jmp .kbd_done
262.s_szKeyboardA20:
263 db 'Keyboard A20 Gate Interface', 0
264.s_szKbdDisableFailed:
265 db 'Disabling the A20 gate via the keyboard controller failed', 10, 13, 0
266.s_szKbdEnableFailed:
267 db 'Enabling the A20 gate via the keyboard controller failed', 10, 13, 0
268.kbd_failed:
269 call TestFailed_r86
270.kbd_done:
271 call TestSubDone_r86
272 call Bs2DisableA20ViaPortA_r86
273 call Bs2DisableA20ViaKbd_r86
274
275 pop edi
276 pop ebx
277 pop ecx
278 pop edx
279 pop eax
280 ret
281ENDPROC TestA20_1
282
283
284;;
285; Checks if the A20 gate is enabled.
286;
287; This is do by temporarily changing a word at address 0000000h and see if this
288; is reflected at address 0100000h (1 MB). The word written is
289; ~*(word *)0x100000h to make sure it won't accidentally match.
290;
291; @returns ax 1 if enabled, 0 if disabled.
292;
293BEGINPROC IsA20GateEnabled_rm
294 push ds
295 push es
296 push dx
297 pushf
298 cli
299
300.once_again:
301 xor ax, ax
302 mov ds, ax
303 dec ax
304 mov es, ax
305
306 mov ax, [es:0010h] ; 0ffff:0010 => 0100000h (1 MB)
307 mov dx, [ds:0000h] ; 00000:0000 => 0000000h - save it
308 not ax
309 mov [ds:0000h], ax ; 0000000h - write ~[0100000h]
310 cmp [es:0010h], ax ; 0100000h - same as 0000000h if A20 is disabled.
311 mov [ds:0000h], dx ; 0000000h - restore original value
312 setne al
313 movzx ax, al
314
315 popf
316 pop dx
317 pop es
318 pop ds
319 ret
320ENDPROC IsA20GateEnabled_rm
321
322;;
323; Checks if the BIOS thinks the A20 gate is enabled.
324;
325; @returns ax 1 if enabled, 0 if disabled.
326;
327BEGINPROC BiosIsA20GateEnabled_rm
328 push ecx
329 push eax
330
331 mov ax, 2402h
332 int 15h
333 jnc .ok
334 mov al, 080h
335.ok:
336 mov cx, ax
337 pop eax
338 mov ax, cx
339 pop ecx
340 ret
341ENDPROC BiosIsA20GateEnabled_rm
342
343;
344; Instantiate the template code.
345;
346%include "bootsector2-template-footer.mac" ; reset the initial environemnt.
347
348%define TMPL_RM
349%include "bootsector2-cpu-a20-1-template.mac"
350;%define TMPL_CMN_V86
351;%include "bootsector2-cpu-a20-1-template.mac"
352%define TMPL_PE16
353%include "bootsector2-cpu-a20-1-template.mac"
354%define TMPL_PE32
355%include "bootsector2-cpu-a20-1-template.mac"
356;%define TMPL_PP16
357;%include "bootsector2-cpu-a20-1-template.mac"
358%define TMPL_PP32
359%include "bootsector2-cpu-a20-1-template.mac"
360;%define TMPL_PAE16
361;%include "bootsector2-cpu-a20-1-template.mac"
362%define TMPL_PAE32
363%include "bootsector2-cpu-a20-1-template.mac"
364;%define TMPL_LM16
365;%include "bootsector2-cpu-a20-1-template.mac"
366;%define TMPL_LM32
367;%include "bootsector2-cpu-a20-1-template.mac"
368%define TMPL_LM64
369%include "bootsector2-cpu-a20-1-template.mac"
370
371
372;
373; End sections and image.
374;
375%include "bootsector2-common-end.mac"
376
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