VirtualBox

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

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