VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-basic-2-template.mac@ 103131

Last change on this file since 103131 was 102130, checked in by vboxsync, 11 months ago

ValKit/bs3-cpu-basic-2: Split out the LEA testing into bs3-cpu-basic-3 because there isn't enough room left under 640KB to test it all. bugref:10371

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 59.9 KB
Line 
1; $Id: bs3-cpu-basic-2-template.mac 102130 2023-11-16 23:51:25Z vboxsync $
2;; @file
3; BS3Kit - bs3-cpu-basic-2 assembly 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;*********************************************************************************************************************************
39;* Header Files *
40;*********************************************************************************************************************************
41%include "bs3kit-template-header.mac" ; setup environment
42
43
44;*********************************************************************************************************************************
45;* Defined Constants And Macros *
46;*********************************************************************************************************************************
47%ifnmacro BS3_CPUBAS2_UD_OFF
48%macro BS3_CPUBAS2_UD_OFF 1
49BS3_GLOBAL_NAME_EX BS3_CMN_NM(%1) %+ _offUD, , 1
50 db BS3_CMN_NM(%1).again - BS3_CMN_NM(%1)
51%endmacro
52%endif
53
54%undef BS3_CPUBAS2_REF_LABEL_VIA_CS
55%if TMPL_BITS == 16
56 %define BS3_CPUBAS2_REF_LABEL_VIA_CS(a_Label) cs:a_Label
57%elif TMPL_BITS == 32
58 %define BS3_CPUBAS2_REF_LABEL_VIA_CS(a_Label) cs:a_Label wrt FLAT
59%elif TMPL_BITS == 64
60 %define BS3_CPUBAS2_REF_LABEL_VIA_CS(a_Label) a_Label wrt FLAT
61%else
62 %error TMPL_BITS
63%endif
64
65;;
66; Macro for generating far jmp instruction w/o nasm adding REX.W prefixes.
67;
68; @param 1 The label of the memory pointer.
69; @param 2 Prefix: 0: none, 1: 066h, 2: REX.W, 3: 066h REX.W
70%ifnmacro BS3_CPUBAS2_JMP_FAR_MEM_LABEL
71%macro BS3_CPUBAS2_JMP_FAR_MEM_LABEL 2
72 %if (%2) == 1 || (%2) == 3
73 db 066h ; o16/o32
74 %endif
75 %if TMPL_BITS != 64
76 jmp far [BS3_CPUBAS2_REF_LABEL_VIA_CS(%1)]
77 %elif TMPL_BITS == 64
78 ; 48FF2C25[040C0000] <3> jmp far [BS3_CPUBAS2_REF_LABLE_VIA_CS(.fpfn)]
79 %if (%2) == 2 || (%2) == 3
80 db 048h ; REX.W
81 %endif
82 db 0ffh, 02ch, 025h
83 dd %1 wrt FLAT
84 %else
85 %error TMPL_BITS
86 %endif
87%endmacro
88%endif
89
90;;
91; Macro for generating far call instruction w/o nasm adding REX.W prefixes.
92;
93; @param 1 The label of the memory pointer.
94; @param 2 Prefix: 0: none, 1: 066h, 2: REX.W, 3: 066h REX.W
95%ifnmacro BS3_CPUBAS2_CALL_FAR_MEM_LABEL
96%macro BS3_CPUBAS2_CALL_FAR_MEM_LABEL 2
97 %if (%2) == 1 || (%2) == 3
98 db 066h ; o16/o32
99 %endif
100 %if TMPL_BITS != 64
101 call far [BS3_CPUBAS2_REF_LABEL_VIA_CS(%1)]
102 %elif TMPL_BITS == 64
103 %if (%2) == 2 || (%2) == 3
104 db 048h ; REX.W
105 %endif
106 db 0ffh, 01ch, 025h ; call far [mem]
107 dd %1 wrt FLAT
108 %else
109 %error TMPL_BITS
110 %endif
111%endmacro
112%endif
113
114
115;*********************************************************************************************************************************
116;* External Symbols *
117;*********************************************************************************************************************************
118TMPL_BEGIN_TEXT
119
120
121
122;
123; Test code snippets containing code which differs between 16-bit, 32-bit
124; and 64-bit CPUs modes.
125;
126%ifdef BS3_INSTANTIATING_CMN
127
128;
129; SIDT
130;
131BS3_CPUBAS2_UD_OFF bs3CpuBasic2_sidt_bx_ud2
132BS3_PROC_BEGIN_CMN bs3CpuBasic2_sidt_bx_ud2, BS3_PBC_NEAR
133 sidt [xBX]
134.again: ud2
135 jmp .again
136AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_sidt_bx_ud2) == 3)
137BS3_PROC_END_CMN bs3CpuBasic2_sidt_bx_ud2
138
139BS3_CPUBAS2_UD_OFF bs3CpuBasic2_sidt_opsize_bx_ud2
140BS3_PROC_BEGIN_CMN bs3CpuBasic2_sidt_opsize_bx_ud2, BS3_PBC_NEAR
141 db X86_OP_PRF_SIZE_OP
142 sidt [xBX]
143.again: ud2
144 jmp .again
145AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_sidt_opsize_bx_ud2) == 4)
146BS3_PROC_END_CMN bs3CpuBasic2_sidt_opsize_bx_ud2
147
148 %if TMPL_BITS == 64
149BS3_CPUBAS2_UD_OFF bs3CpuBasic2_sidt_rexw_bx_ud2
150BS3_PROC_BEGIN_CMN bs3CpuBasic2_sidt_rexw_bx_ud2, BS3_PBC_NEAR
151 db X86_OP_REX_W
152 sidt [xBX]
153.again: ud2
154 jmp .again
155AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_sidt_rexw_bx_ud2) == 4)
156BS3_PROC_END_CMN bs3CpuBasic2_sidt_rexw_bx_ud2
157
158BS3_CPUBAS2_UD_OFF bs3CpuBasic2_sidt_opsize_rexw_bx_ud2
159BS3_PROC_BEGIN_CMN bs3CpuBasic2_sidt_opsize_rexw_bx_ud2, BS3_PBC_NEAR
160 db X86_OP_PRF_SIZE_OP
161 db X86_OP_REX_W
162 sidt [xBX]
163.again: ud2
164 jmp .again
165AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_sidt_opsize_rexw_bx_ud2) == 5)
166BS3_PROC_END_CMN bs3CpuBasic2_sidt_opsize_rexw_bx_ud2
167 %endif
168
169 %if TMPL_BITS != 64
170BS3_CPUBAS2_UD_OFF bs3CpuBasic2_sidt_ss_bx_ud2
171BS3_PROC_BEGIN_CMN bs3CpuBasic2_sidt_ss_bx_ud2, BS3_PBC_NEAR
172 sidt [ss:xBX]
173.again: ud2
174 jmp .again
175AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_sidt_ss_bx_ud2) == 4)
176BS3_PROC_END_CMN bs3CpuBasic2_sidt_ss_bx_ud2
177
178BS3_CPUBAS2_UD_OFF bs3CpuBasic2_sidt_opsize_ss_bx_ud2
179BS3_PROC_BEGIN_CMN bs3CpuBasic2_sidt_opsize_ss_bx_ud2, BS3_PBC_NEAR
180 db X86_OP_PRF_SIZE_OP
181 sidt [ss:xBX]
182.again: ud2
183 jmp .again
184AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_sidt_opsize_ss_bx_ud2) == 5)
185BS3_PROC_END_CMN bs3CpuBasic2_sidt_opsize_ss_bx_ud2
186 %endif
187
188
189;
190; SGDT
191;
192BS3_CPUBAS2_UD_OFF bs3CpuBasic2_sgdt_bx_ud2
193BS3_PROC_BEGIN_CMN bs3CpuBasic2_sgdt_bx_ud2, BS3_PBC_NEAR
194 sgdt [xBX]
195.again: ud2
196 jmp .again
197AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_sgdt_bx_ud2) == 3)
198BS3_PROC_END_CMN bs3CpuBasic2_sgdt_bx_ud2
199
200BS3_CPUBAS2_UD_OFF bs3CpuBasic2_sgdt_opsize_bx_ud2
201BS3_PROC_BEGIN_CMN bs3CpuBasic2_sgdt_opsize_bx_ud2, BS3_PBC_NEAR
202 db X86_OP_PRF_SIZE_OP
203 sgdt [xBX]
204.again: ud2
205 jmp .again
206AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_sgdt_opsize_bx_ud2) == 4)
207BS3_PROC_END_CMN bs3CpuBasic2_sgdt_opsize_bx_ud2
208
209 %if TMPL_BITS == 64
210BS3_CPUBAS2_UD_OFF bs3CpuBasic2_sgdt_rexw_bx_ud2
211BS3_PROC_BEGIN_CMN bs3CpuBasic2_sgdt_rexw_bx_ud2, BS3_PBC_NEAR
212 db X86_OP_REX_W
213 sgdt [xBX]
214.again: ud2
215 jmp .again
216AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_sgdt_rexw_bx_ud2) == 4)
217BS3_PROC_END_CMN bs3CpuBasic2_sgdt_rexw_bx_ud2
218
219BS3_CPUBAS2_UD_OFF bs3CpuBasic2_sgdt_opsize_rexw_bx_ud2
220BS3_PROC_BEGIN_CMN bs3CpuBasic2_sgdt_opsize_rexw_bx_ud2, BS3_PBC_NEAR
221 db X86_OP_PRF_SIZE_OP
222 db X86_OP_REX_W
223 sgdt [xBX]
224.again: ud2
225 jmp .again
226AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_sgdt_opsize_rexw_bx_ud2) == 5)
227BS3_PROC_END_CMN bs3CpuBasic2_sgdt_opsize_rexw_bx_ud2
228 %endif
229
230 %if TMPL_BITS != 64
231BS3_CPUBAS2_UD_OFF bs3CpuBasic2_sgdt_ss_bx_ud2
232BS3_PROC_BEGIN_CMN bs3CpuBasic2_sgdt_ss_bx_ud2, BS3_PBC_NEAR
233 sgdt [ss:xBX]
234.again: ud2
235 jmp .again
236AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_sgdt_ss_bx_ud2) == 4)
237BS3_PROC_END_CMN bs3CpuBasic2_sgdt_ss_bx_ud2
238
239BS3_CPUBAS2_UD_OFF bs3CpuBasic2_sgdt_opsize_ss_bx_ud2
240BS3_PROC_BEGIN_CMN bs3CpuBasic2_sgdt_opsize_ss_bx_ud2, BS3_PBC_NEAR
241 db X86_OP_PRF_SIZE_OP
242 sgdt [ss:xBX]
243.again: ud2
244 jmp .again
245AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_sgdt_opsize_ss_bx_ud2) == 5)
246BS3_PROC_END_CMN bs3CpuBasic2_sgdt_opsize_ss_bx_ud2
247 %endif
248
249
250;
251; LIDT
252;
253BS3_CPUBAS2_UD_OFF bs3CpuBasic2_lidt_bx__sidt_es_di__lidt_es_si__ud2
254BS3_PROC_BEGIN_CMN bs3CpuBasic2_lidt_bx__sidt_es_di__lidt_es_si__ud2, BS3_PBC_NEAR
255 lidt [xBX]
256 sidt [BS3_NOT_64BIT(es:) xDI]
257 lidt [BS3_NOT_64BIT(es:) xSI]
258.again:
259 ud2
260 jmp .again
261AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_lidt_bx__sidt_es_di__lidt_es_si__ud2) == BS3_IF_64BIT_OTHERWISE(9,11))
262BS3_PROC_END_CMN bs3CpuBasic2_lidt_bx__sidt_es_di__lidt_es_si__ud2
263
264BS3_CPUBAS2_UD_OFF bs3CpuBasic2_lidt_opsize_bx__sidt_es_di__lidt_es_si__ud2
265BS3_PROC_BEGIN_CMN bs3CpuBasic2_lidt_opsize_bx__sidt_es_di__lidt_es_si__ud2, BS3_PBC_NEAR
266 db X86_OP_PRF_SIZE_OP
267 lidt [xBX]
268 sidt [BS3_NOT_64BIT(es:) xDI]
269 lidt [BS3_NOT_64BIT(es:) xSI]
270.again:
271 ud2
272 jmp .again
273AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_lidt_opsize_bx__sidt_es_di__lidt_es_si__ud2) == BS3_IF_64BIT_OTHERWISE(10,12))
274BS3_PROC_END_CMN bs3CpuBasic2_lidt_opsize_bx__sidt_es_di__lidt_es_si__ud2
275
276%if TMPL_BITS == 16
277BS3_CPUBAS2_UD_OFF bs3CpuBasic2_lidt_opsize_bx__sidt32_es_di__lidt_es_si__ud2
278BS3_PROC_BEGIN_CMN bs3CpuBasic2_lidt_opsize_bx__sidt32_es_di__lidt_es_si__ud2, BS3_PBC_NEAR
279 db X86_OP_PRF_SIZE_OP
280 lidt [xBX]
281 jmp dword BS3_SEL_R0_CS32:.in_32bit wrt FLAT
282 BS3_SET_BITS 32
283.in_32bit:
284 sidt [es:edi]
285 lidt [es:esi]
286 jmp dword BS3_SEL_R0_CS16:.again wrt CGROUP16
287 BS3_SET_BITS 16
288.again:
289 ud2
290 jmp .again
291AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_lidt_opsize_bx__sidt32_es_di__lidt_es_si__ud2) == 27)
292BS3_PROC_END_CMN bs3CpuBasic2_lidt_opsize_bx__sidt32_es_di__lidt_es_si__ud2
293%endif
294
295 %if TMPL_BITS == 64
296BS3_CPUBAS2_UD_OFF bs3CpuBasic2_lidt_rexw_bx__sidt_es_di__lidt_es_si__ud2
297BS3_PROC_BEGIN_CMN bs3CpuBasic2_lidt_rexw_bx__sidt_es_di__lidt_es_si__ud2, BS3_PBC_NEAR
298 db X86_OP_REX_W
299 lidt [xBX]
300 sidt [xDI]
301 lidt [xSI]
302.again:
303 ud2
304 jmp .again
305AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_lidt_rexw_bx__sidt_es_di__lidt_es_si__ud2) == 10)
306BS3_PROC_END_CMN bs3CpuBasic2_lidt_rexw_bx__sidt_es_di__lidt_es_si__ud2
307
308BS3_CPUBAS2_UD_OFF bs3CpuBasic2_lidt_opsize_rexw_bx__sidt_es_di__lidt_es_si__ud2
309BS3_PROC_BEGIN_CMN bs3CpuBasic2_lidt_opsize_rexw_bx__sidt_es_di__lidt_es_si__ud2, BS3_PBC_NEAR
310 db X86_OP_PRF_SIZE_OP
311 db X86_OP_REX_W
312 lidt [xBX]
313 sidt [xDI]
314 lidt [xSI]
315.again:
316 ud2
317 jmp .again
318AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_lidt_opsize_rexw_bx__sidt_es_di__lidt_es_si__ud2) == 11)
319BS3_PROC_END_CMN bs3CpuBasic2_lidt_opsize_rexw_bx__sidt_es_di__lidt_es_si__ud2
320 %endif
321
322 %if TMPL_BITS != 64
323BS3_CPUBAS2_UD_OFF bs3CpuBasic2_lidt_ss_bx__sidt_es_di__lidt_es_si__ud2
324BS3_PROC_BEGIN_CMN bs3CpuBasic2_lidt_ss_bx__sidt_es_di__lidt_es_si__ud2, BS3_PBC_NEAR
325 lidt [ss:xBX]
326 sidt [BS3_NOT_64BIT(es:) xDI]
327 lidt [BS3_NOT_64BIT(es:) xSI]
328.again:
329 ud2
330 jmp .again
331AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_lidt_ss_bx__sidt_es_di__lidt_es_si__ud2) == 12)
332BS3_PROC_END_CMN bs3CpuBasic2_lidt_ss_bx__sidt_es_di__lidt_es_si__ud2
333
334BS3_CPUBAS2_UD_OFF bs3CpuBasic2_lidt_opsize_ss_bx__sidt_es_di__lidt_es_si__ud2
335BS3_PROC_BEGIN_CMN bs3CpuBasic2_lidt_opsize_ss_bx__sidt_es_di__lidt_es_si__ud2, BS3_PBC_NEAR
336 db X86_OP_PRF_SIZE_OP
337 lidt [ss:xBX]
338 sidt [BS3_NOT_64BIT(es:) xDI]
339 lidt [BS3_NOT_64BIT(es:) xSI]
340.again:
341 ud2
342 jmp .again
343AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_lidt_opsize_ss_bx__sidt_es_di__lidt_es_si__ud2) == 13)
344BS3_PROC_END_CMN bs3CpuBasic2_lidt_opsize_ss_bx__sidt_es_di__lidt_es_si__ud2
345 %endif
346
347
348;
349; LGDT
350;
351BS3_CPUBAS2_UD_OFF bs3CpuBasic2_lgdt_bx__sgdt_es_di__lgdt_es_si__ud2
352BS3_PROC_BEGIN_CMN bs3CpuBasic2_lgdt_bx__sgdt_es_di__lgdt_es_si__ud2, BS3_PBC_NEAR
353 lgdt [xBX]
354 sgdt [BS3_NOT_64BIT(es:) xDI]
355 lgdt [BS3_NOT_64BIT(es:) xSI]
356.again:
357 ud2
358 jmp .again
359AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_lgdt_bx__sgdt_es_di__lgdt_es_si__ud2) == BS3_IF_64BIT_OTHERWISE(9,11))
360BS3_PROC_END_CMN bs3CpuBasic2_lgdt_bx__sgdt_es_di__lgdt_es_si__ud2
361
362BS3_CPUBAS2_UD_OFF bs3CpuBasic2_lgdt_opsize_bx__sgdt_es_di__lgdt_es_si__ud2
363BS3_PROC_BEGIN_CMN bs3CpuBasic2_lgdt_opsize_bx__sgdt_es_di__lgdt_es_si__ud2, BS3_PBC_NEAR
364 db X86_OP_PRF_SIZE_OP
365 lgdt [xBX]
366 sgdt [BS3_NOT_64BIT(es:) xDI]
367 lgdt [BS3_NOT_64BIT(es:) xSI]
368.again:
369 ud2
370 jmp .again
371AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_lgdt_opsize_bx__sgdt_es_di__lgdt_es_si__ud2) == BS3_IF_64BIT_OTHERWISE(10,12))
372BS3_PROC_END_CMN bs3CpuBasic2_lgdt_opsize_bx__sgdt_es_di__lgdt_es_si__ud2
373
374 %if TMPL_BITS == 64
375BS3_CPUBAS2_UD_OFF bs3CpuBasic2_lgdt_rexw_bx__sgdt_es_di__lgdt_es_si__ud2
376BS3_PROC_BEGIN_CMN bs3CpuBasic2_lgdt_rexw_bx__sgdt_es_di__lgdt_es_si__ud2, BS3_PBC_NEAR
377 db X86_OP_REX_W
378 lgdt [xBX]
379 sgdt [xDI]
380 lgdt [xSI]
381.again:
382 ud2
383 jmp .again
384AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_lgdt_rexw_bx__sgdt_es_di__lgdt_es_si__ud2) == 10)
385BS3_PROC_END_CMN bs3CpuBasic2_lgdt_rexw_bx__sgdt_es_di__lgdt_es_si__ud2
386
387BS3_CPUBAS2_UD_OFF bs3CpuBasic2_lgdt_opsize_rexw_bx__sgdt_es_di__lgdt_es_si__ud2
388BS3_PROC_BEGIN_CMN bs3CpuBasic2_lgdt_opsize_rexw_bx__sgdt_es_di__lgdt_es_si__ud2, BS3_PBC_NEAR
389 db X86_OP_PRF_SIZE_OP
390 db X86_OP_REX_W
391 lgdt [xBX]
392 sgdt [xDI]
393 lgdt [xSI]
394.again:
395 ud2
396 jmp .again
397AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_lgdt_opsize_rexw_bx__sgdt_es_di__lgdt_es_si__ud2) == 11)
398BS3_PROC_END_CMN bs3CpuBasic2_lgdt_opsize_rexw_bx__sgdt_es_di__lgdt_es_si__ud2
399 %endif
400
401 %if TMPL_BITS != 64
402BS3_CPUBAS2_UD_OFF bs3CpuBasic2_lgdt_ss_bx__sgdt_es_di__lgdt_es_si__ud2
403BS3_PROC_BEGIN_CMN bs3CpuBasic2_lgdt_ss_bx__sgdt_es_di__lgdt_es_si__ud2, BS3_PBC_NEAR
404 lgdt [ss:xBX]
405 sgdt [BS3_NOT_64BIT(es:) xDI]
406 lgdt [BS3_NOT_64BIT(es:) xSI]
407.again:
408 ud2
409 jmp .again
410AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_lgdt_ss_bx__sgdt_es_di__lgdt_es_si__ud2) == 12)
411BS3_PROC_END_CMN bs3CpuBasic2_lgdt_ss_bx__sgdt_es_di__lgdt_es_si__ud2
412
413BS3_CPUBAS2_UD_OFF bs3CpuBasic2_lgdt_opsize_ss_bx__sgdt_es_di__lgdt_es_si__ud2
414BS3_PROC_BEGIN_CMN bs3CpuBasic2_lgdt_opsize_ss_bx__sgdt_es_di__lgdt_es_si__ud2, BS3_PBC_NEAR
415 db X86_OP_PRF_SIZE_OP
416 lgdt [ss:xBX]
417 sgdt [BS3_NOT_64BIT(es:) xDI]
418 lgdt [BS3_NOT_64BIT(es:) xSI]
419.again:
420 ud2
421 jmp .again
422AssertCompile(.again - BS3_CMN_NM(bs3CpuBasic2_lgdt_opsize_ss_bx__sgdt_es_di__lgdt_es_si__ud2) == 13)
423BS3_PROC_END_CMN bs3CpuBasic2_lgdt_opsize_ss_bx__sgdt_es_di__lgdt_es_si__ud2
424 %endif ; TMPL_BITS != 64
425
426;
427; #PF & #AC
428;
429
430; For testing read access.
431BS3_CPUBAS2_UD_OFF bs3CpuBasic2_mov_ax_ds_bx__ud2
432BS3_PROC_BEGIN_CMN bs3CpuBasic2_mov_ax_ds_bx__ud2, BS3_PBC_NEAR
433 mov xAX, [xBX]
434.again: ud2
435 jmp .again
436AssertCompile(.again - BS3_LAST_LABEL == 2 + (TMPL_BITS == 64))
437BS3_PROC_END_CMN bs3CpuBasic2_mov_ax_ds_bx__ud2
438
439
440; For testing write access.
441BS3_CPUBAS2_UD_OFF bs3CpuBasic2_mov_ds_bx_ax__ud2
442BS3_PROC_BEGIN_CMN bs3CpuBasic2_mov_ds_bx_ax__ud2, BS3_PBC_NEAR
443 mov [xBX], xAX
444.again: ud2
445 jmp .again
446AssertCompile(.again - BS3_LAST_LABEL == 2 + (TMPL_BITS == 64))
447BS3_PROC_END_CMN bs3CpuBasic2_mov_ds_bx_ax__ud2
448
449
450; For testing read+write access.
451BS3_CPUBAS2_UD_OFF bs3CpuBasic2_xchg_ds_bx_ax__ud2
452BS3_PROC_BEGIN_CMN bs3CpuBasic2_xchg_ds_bx_ax__ud2, BS3_PBC_NEAR
453 xchg [xBX], xAX
454.again: ud2
455 jmp .again
456AssertCompile(.again - BS3_LAST_LABEL == 2 + (TMPL_BITS == 64))
457BS3_PROC_END_CMN bs3CpuBasic2_xchg_ds_bx_ax__ud2
458
459
460; Another read+write access test.
461BS3_CPUBAS2_UD_OFF bs3CpuBasic2_cmpxchg_ds_bx_cx__ud2
462BS3_PROC_BEGIN_CMN bs3CpuBasic2_cmpxchg_ds_bx_cx__ud2, BS3_PBC_NEAR
463 cmpxchg [xBX], xCX
464.again: ud2
465 jmp .again
466AssertCompile(.again - BS3_LAST_LABEL == 3 + (TMPL_BITS == 64))
467BS3_PROC_END_CMN bs3CpuBasic2_cmpxchg_ds_bx_cx__ud2
468
469
470; For testing read access from an aborted instruction: DIV by zero
471BS3_CPUBAS2_UD_OFF bs3CpuBasic2_div_ds_bx__ud2
472BS3_PROC_BEGIN_CMN bs3CpuBasic2_div_ds_bx__ud2, BS3_PBC_NEAR
473 div xPRE [xBX]
474.again: ud2
475 jmp .again
476AssertCompile(.again - BS3_LAST_LABEL == 2 + (TMPL_BITS == 64))
477BS3_PROC_END_CMN bs3CpuBasic2_div_ds_bx__ud2
478
479; For testing FLD m80 alignment (#AC).
480BS3_CPUBAS2_UD_OFF bs3CpuBasic2_fninit_fld_ds_bx__ud2
481BS3_PROC_BEGIN_CMN bs3CpuBasic2_fninit_fld_ds_bx__ud2, BS3_PBC_NEAR
482 fninit ; make sure to not trigger a stack overflow.
483.actual_test_instruction:
484 fld tword [xBX]
485.again: ud2
486 jmp .again
487AssertCompile(.actual_test_instruction - BS3_LAST_LABEL == 2)
488BS3_PROC_END_CMN bs3CpuBasic2_fninit_fld_ds_bx__ud2
489
490; For testing FBLD m80 alignment (#AC).
491BS3_CPUBAS2_UD_OFF bs3CpuBasic2_fninit_fbld_ds_bx__ud2
492BS3_PROC_BEGIN_CMN bs3CpuBasic2_fninit_fbld_ds_bx__ud2, BS3_PBC_NEAR
493 fninit ; make sure to not trigger a stack overflow.
494.actual_test_instruction:
495 fbld tword [xBX]
496.again: ud2
497 jmp .again
498AssertCompile(.actual_test_instruction - BS3_LAST_LABEL == 2)
499BS3_PROC_END_CMN bs3CpuBasic2_fninit_fbld_ds_bx__ud2
500
501; For testing FST m80 alignment (#AC).
502BS3_CPUBAS2_UD_OFF bs3CpuBasic2_fninit_fldz_fstp_ds_bx__ud2
503BS3_PROC_BEGIN_CMN bs3CpuBasic2_fninit_fldz_fstp_ds_bx__ud2, BS3_PBC_NEAR
504 fninit ; make sure to not trigger a stack overflow.
505 fldz ; make sure we've got something to store
506.actual_test_instruction:
507 fstp tword [xBX]
508.again: ud2
509 jmp .again
510AssertCompile(.actual_test_instruction - BS3_LAST_LABEL == 4)
511BS3_PROC_END_CMN bs3CpuBasic2_fninit_fldz_fstp_ds_bx__ud2
512
513; For testing FXSAVE alignment (#AC/#GP).
514BS3_CPUBAS2_UD_OFF bs3CpuBasic2_fxsave_ds_bx__ud2
515BS3_PROC_BEGIN_CMN bs3CpuBasic2_fxsave_ds_bx__ud2, BS3_PBC_NEAR
516 fxsave [xBX]
517.again: ud2
518 jmp .again
519BS3_PROC_END_CMN bs3CpuBasic2_fxsave_ds_bx__ud2
520
521
522; Two memory operands: push [mem]
523BS3_CPUBAS2_UD_OFF bs3CpuBasic2_push_ds_bx__ud2
524BS3_PROC_BEGIN_CMN bs3CpuBasic2_push_ds_bx__ud2, BS3_PBC_NEAR
525 push xPRE [xBX]
526.again: ud2
527 jmp .again
528AssertCompile(.again - BS3_LAST_LABEL == 2)
529BS3_PROC_END_CMN bs3CpuBasic2_push_ds_bx__ud2
530
531; Two memory operands: pop [mem]
532BS3_CPUBAS2_UD_OFF bs3CpuBasic2_push_ax__pop_ds_bx__ud2
533BS3_PROC_BEGIN_CMN bs3CpuBasic2_push_ax__pop_ds_bx__ud2, BS3_PBC_NEAR
534 push xAX
535 pop xPRE [xBX]
536.again: ud2
537 jmp .again
538AssertCompile(.again - BS3_LAST_LABEL == 3)
539BS3_PROC_END_CMN bs3CpuBasic2_push_ax__pop_ds_bx__ud2
540
541; Two memory operands: call [mem]
542BS3_CPUBAS2_UD_OFF bs3CpuBasic2_call_ds_bx__ud2
543BS3_PROC_BEGIN_CMN bs3CpuBasic2_call_ds_bx__ud2, BS3_PBC_NEAR
544 call xPRE [xBX]
545.again: ud2
546 jmp .again
547AssertCompile(.again - BS3_LAST_LABEL == 2)
548BS3_PROC_END_CMN bs3CpuBasic2_call_ds_bx__ud2
549
550; For testing #GP vs #PF write
551BS3_CPUBAS2_UD_OFF bs3CpuBasic2_insb__ud2
552BS3_PROC_BEGIN_CMN bs3CpuBasic2_insb__ud2, BS3_PBC_NEAR
553 insb
554.again: ud2
555 jmp .again
556AssertCompile(.again - BS3_LAST_LABEL == 1)
557BS3_PROC_END_CMN bs3CpuBasic2_insb__ud2
558
559
560;*********************************************************************************************************************************
561;* Non-far JMP & CALL Tests (simple ones). *
562;*********************************************************************************************************************************
563
564; jmp rel8 (forwards)
565BS3_CPUBAS2_UD_OFF bs3CpuBasic2_jmp_jb__ud2
566BS3_PROC_BEGIN_CMN bs3CpuBasic2_jmp_jb__ud2, BS3_PBC_NEAR
567 jmp short .again
568.post_jmp:
569 times 7 int3
570.again: ud2
571 int3
572 jmp .again
573AssertCompile(.post_jmp - BS3_LAST_LABEL == 2)
574BS3_PROC_END_CMN bs3CpuBasic2_jmp_jb__ud2
575
576
577; jmp rel8 (backwards)
578BS3_GLOBAL_NAME_EX RT_CONCAT(BS3_CMN_NM(bs3CpuBasic2_jmp_jb_back__ud2),.again), function, 2
579 ud2
580 times 7 int3
581BS3_CPUBAS2_UD_OFF bs3CpuBasic2_jmp_jb_back__ud2
582BS3_PROC_BEGIN_CMN bs3CpuBasic2_jmp_jb_back__ud2, BS3_PBC_NEAR
583 jmp short .again
584.post_jmp:
585 int3
586AssertCompile(.post_jmp - BS3_LAST_LABEL == 2)
587BS3_PROC_END_CMN bs3CpuBasic2_jmp_jb_back__ud2
588
589
590; jmp rel16 (forwards)
591BS3_CPUBAS2_UD_OFF bs3CpuBasic2_jmp_jv__ud2
592BS3_PROC_BEGIN_CMN bs3CpuBasic2_jmp_jv__ud2, BS3_PBC_NEAR
593 jmp near .again
594.post_jmp:
595 times 9 int3
596.again: ud2
597 int3
598 jmp .again
599 %if TMPL_BITS == 16
600AssertCompile(.post_jmp - BS3_LAST_LABEL == 3)
601 %else
602AssertCompile(.post_jmp - BS3_LAST_LABEL == 5)
603 %endif
604BS3_PROC_END_CMN bs3CpuBasic2_jmp_jv__ud2
605
606
607; jmp rel16 (backwards)
608BS3_GLOBAL_NAME_EX RT_CONCAT(BS3_CMN_NM(bs3CpuBasic2_jmp_jv_back__ud2),.again), function, 2
609 ud2
610 times 6 int3
611BS3_CPUBAS2_UD_OFF bs3CpuBasic2_jmp_jv_back__ud2
612BS3_PROC_BEGIN_CMN bs3CpuBasic2_jmp_jv_back__ud2, BS3_PBC_NEAR
613 jmp near .again
614.post_jmp:
615 int3
616 %if TMPL_BITS == 16
617AssertCompile(.post_jmp - BS3_LAST_LABEL == 3)
618 %else
619AssertCompile(.post_jmp - BS3_LAST_LABEL == 5)
620 %endif
621BS3_PROC_END_CMN bs3CpuBasic2_jmp_jv_back__ud2
622
623
624; jmp [indirect]
625BS3_CPUBAS2_UD_OFF bs3CpuBasic2_jmp_ind_mem__ud2
626BS3_PROC_BEGIN_CMN bs3CpuBasic2_jmp_ind_mem__ud2, BS3_PBC_NEAR
627%if TMPL_BITS == 16
628 jmp [word cs:.npAgain]
629%elif TMPL_BITS == 32
630 jmp [dword cs:.npAgain]
631%else
632 jmp [.npAgain]
633%endif
634.post_jmp:
635 times 9 int3
636.npAgain:
637 %if TMPL_BITS == 16
638 dw BS3_TEXT16_WRT(.again)
639 %else
640 dd .again wrt FLAT
641 %if TMPL_BITS == 64
642 dd 0
643 %endif
644 %endif
645.again: ud2
646 int3
647 jmp .again
648BS3_PROC_END_CMN bs3CpuBasic2_jmp_ind_mem__ud2
649
650; jmp [xAX]
651BS3_CPUBAS2_UD_OFF bs3CpuBasic2_jmp_ind_xAX__ud2
652BS3_PROC_BEGIN_CMN bs3CpuBasic2_jmp_ind_xAX__ud2, BS3_PBC_NEAR
653 jmp xAX
654.post_jmp:
655 times 17 int3
656.again: ud2
657 int3
658 jmp .again
659BS3_PROC_END_CMN bs3CpuBasic2_jmp_ind_xAX__ud2
660
661; jmp [xDI]
662BS3_CPUBAS2_UD_OFF bs3CpuBasic2_jmp_ind_xDI__ud2
663BS3_PROC_BEGIN_CMN bs3CpuBasic2_jmp_ind_xDI__ud2, BS3_PBC_NEAR
664 jmp xDI
665.post_jmp:
666 times 17 int3
667.again: ud2
668 int3
669 jmp .again
670BS3_PROC_END_CMN bs3CpuBasic2_jmp_ind_xDI__ud2
671
672 %if TMPL_BITS == 64
673; jmp [xAX]
674BS3_CPUBAS2_UD_OFF bs3CpuBasic2_jmp_ind_r9__ud2
675BS3_PROC_BEGIN_CMN bs3CpuBasic2_jmp_ind_r9__ud2, BS3_PBC_NEAR
676 jmp r9
677.post_jmp:
678 times 17 int3
679.again: ud2
680 int3
681 jmp .again
682BS3_PROC_END_CMN bs3CpuBasic2_jmp_ind_r9__ud2
683 %endif
684
685
686; call rel16/32 (forwards)
687BS3_CPUBAS2_UD_OFF bs3CpuBasic2_call_jv__ud2
688BS3_PROC_BEGIN_CMN bs3CpuBasic2_call_jv__ud2, BS3_PBC_NEAR
689 call near .again
690.post_call:
691 times 9 int3
692.again: ud2
693 int3
694 jmp .again
695 %if TMPL_BITS == 16
696AssertCompile(.post_call - BS3_LAST_LABEL == 3)
697 %else
698AssertCompile(.post_call - BS3_LAST_LABEL == 5)
699 %endif
700BS3_PROC_END_CMN bs3CpuBasic2_call_jv__ud2
701
702; call rel16/32 (backwards)
703BS3_GLOBAL_NAME_EX RT_CONCAT(BS3_CMN_NM(bs3CpuBasic2_call_jv_back__ud2),.again), function, 2
704 ud2
705 times 6 int3
706BS3_CPUBAS2_UD_OFF bs3CpuBasic2_call_jv_back__ud2
707BS3_PROC_BEGIN_CMN bs3CpuBasic2_call_jv_back__ud2, BS3_PBC_NEAR
708 call near .again
709.post_call:
710 int3
711 %if TMPL_BITS == 16
712AssertCompile(.post_call - BS3_LAST_LABEL == 3)
713 %else
714AssertCompile(.post_call - BS3_LAST_LABEL == 5)
715 %endif
716BS3_PROC_END_CMN bs3CpuBasic2_call_jv_back__ud2
717
718; call [indirect]
719BS3_CPUBAS2_UD_OFF bs3CpuBasic2_call_ind_mem__ud2
720BS3_PROC_BEGIN_CMN bs3CpuBasic2_call_ind_mem__ud2, BS3_PBC_NEAR
721%if TMPL_BITS == 16
722 call [word cs:.npAgain]
723%elif TMPL_BITS == 32
724 call [dword cs:.npAgain]
725%else
726 call [.npAgain]
727%endif
728.post_call:
729 times 9 int3
730.npAgain:
731 %if TMPL_BITS == 16
732 dw BS3_TEXT16_WRT(.again)
733 %else
734 dd .again wrt FLAT
735 %if TMPL_BITS == 64
736 dd 0
737 %endif
738 %endif
739.again: ud2
740 int3
741 jmp .again
742BS3_PROC_END_CMN bs3CpuBasic2_call_ind_mem__ud2
743
744; call [xAX]
745BS3_CPUBAS2_UD_OFF bs3CpuBasic2_call_ind_xAX__ud2
746BS3_PROC_BEGIN_CMN bs3CpuBasic2_call_ind_xAX__ud2, BS3_PBC_NEAR
747 call xAX
748.post_call:
749 times 17 int3
750.again: ud2
751 int3
752 jmp .again
753BS3_PROC_END_CMN bs3CpuBasic2_call_ind_xAX__ud2
754
755; call [xDI]
756BS3_CPUBAS2_UD_OFF bs3CpuBasic2_call_ind_xDI__ud2
757BS3_PROC_BEGIN_CMN bs3CpuBasic2_call_ind_xDI__ud2, BS3_PBC_NEAR
758 call xDI
759.post_call:
760 times 17 int3
761.again: ud2
762 int3
763 jmp .again
764BS3_PROC_END_CMN bs3CpuBasic2_call_ind_xDI__ud2
765
766 %if TMPL_BITS == 64
767; call [xAX]
768BS3_CPUBAS2_UD_OFF bs3CpuBasic2_call_ind_r9__ud2
769BS3_PROC_BEGIN_CMN bs3CpuBasic2_call_ind_r9__ud2, BS3_PBC_NEAR
770 call r9
771.post_call:
772 times 17 int3
773.again: ud2
774 int3
775 jmp .again
776BS3_PROC_END_CMN bs3CpuBasic2_call_ind_r9__ud2
777 %endif
778
779
780;
781; When applying opsize, we need to put this in the 16-bit text segment to
782; better control where we end up in 32-bit and 64-bit mode.
783;
784; Try keep the code out of the IVT and BIOS data area. We ASSUME that the
785; BS3TEXT16 segment portion in this object file will be at the start of the
786; image, so we won't waste much space padding up to offset 0x600.
787;
788BS3_BEGIN_TEXT16 TMPL_BITS
789%if TMPL_BITS == 32
790 %assign here ($ - $$)
791 %if here < 0x600
792 times (0x600 - here) int3
793 %endif
794%endif
795BS3_GLOBAL_NAME_EX BS3_CMN_NM(bs3CpuBasic2_jmp_opsize_begin), , 1
796
797
798; jmp rel8 (forwards) with opsize override.
799BS3_CPUBAS2_UD_OFF bs3CpuBasic2_jmp_jb_opsize__ud2
800BS3_PROC_BEGIN_CMN bs3CpuBasic2_jmp_jb_opsize__ud2, BS3_PBC_NEAR
801 db 66h
802 jmp short .again
803.post_jmp:
804 times 8 int3
805.again: ud2
806 int3
807 jmp .again
808AssertCompile(.post_jmp - BS3_LAST_LABEL == 3)
809BS3_PROC_END_CMN bs3CpuBasic2_jmp_jb_opsize__ud2
810
811
812; jmp rel8 (backwards) with opsize override.
813BS3_GLOBAL_NAME_EX RT_CONCAT(BS3_CMN_NM(bs3CpuBasic2_jmp_jb_opsize_back__ud2),.again), function, 2
814 ud2
815 times 19 int3
816BS3_CPUBAS2_UD_OFF bs3CpuBasic2_jmp_jb_opsize_back__ud2
817BS3_PROC_BEGIN_CMN bs3CpuBasic2_jmp_jb_opsize_back__ud2, BS3_PBC_NEAR
818 db 66h
819 jmp short .again
820.post_jmp:
821 int3
822AssertCompile(.post_jmp - BS3_LAST_LABEL == 3)
823BS3_PROC_END_CMN bs3CpuBasic2_jmp_jb_opsize_back__ud2
824
825
826; jmp rel16 (forwards) with opsize override.
827BS3_CPUBAS2_UD_OFF bs3CpuBasic2_jmp_jv_opsize__ud2
828BS3_PROC_BEGIN_CMN bs3CpuBasic2_jmp_jv_opsize__ud2, BS3_PBC_NEAR
829 db 66h, 0e9h ; o32 jmp near .again
830 %if TMPL_BITS != 32
831 dd 11
832 %else
833 dw 11
834 %endif
835.post_jmp:
836 times 11 int3
837.again: ud2
838 int3
839 jmp .again
840BS3_PROC_END_CMN bs3CpuBasic2_jmp_jv_opsize__ud2
841
842
843; jmp rel16 (backwards) with opsize override.
844BS3_GLOBAL_NAME_EX RT_CONCAT(BS3_CMN_NM(bs3CpuBasic2_jmp_jv_opsize_back__ud2),.again), function, 2
845 ud2
846 times 19 int3
847BS3_CPUBAS2_UD_OFF bs3CpuBasic2_jmp_jv_opsize_back__ud2
848BS3_PROC_BEGIN_CMN bs3CpuBasic2_jmp_jv_opsize_back__ud2, BS3_PBC_NEAR
849 %if TMPL_BITS != 32
850 db 66h, 0e9h ; o32 jmp near .again
851 dd RT_CONCAT(BS3_CMN_NM(bs3CpuBasic2_jmp_jv_opsize_back__ud2),.again) - .post_jmp
852 %else
853 db 66h, 0e9h ; o16 jmp near .again
854 dw RT_CONCAT(BS3_CMN_NM(bs3CpuBasic2_jmp_jv_opsize_back__ud2),.again) - .post_jmp
855 %endif
856.post_jmp:
857 int3
858BS3_PROC_END_CMN bs3CpuBasic2_jmp_jv_opsize_back__ud2
859
860
861; jmp [indirect]
862BS3_CPUBAS2_UD_OFF bs3CpuBasic2_jmp_ind_mem_opsize__ud2
863BS3_PROC_BEGIN_CMN bs3CpuBasic2_jmp_ind_mem_opsize__ud2, BS3_PBC_NEAR
864 db 66h
865 %if TMPL_BITS == 16
866 jmp [word cs:.npAgain]
867 %elif TMPL_BITS == 32
868 jmp [dword cs:.npAgain wrt FLAT]
869 %else
870 jmp [.npAgain wrt FLAT]
871 %endif
872.post_jmp:
873 times 9 int3
874.npAgain:
875 %if TMPL_BITS == 16
876 dw BS3_TEXT16_WRT(.again)
877 dw 0
878 %else
879 dw .again wrt CGROUP16
880 dw 0faceh, 0f00dh, 07777h ; non-canonical address
881 %endif
882.again: ud2
883 int3
884 jmp .again
885BS3_PROC_END_CMN bs3CpuBasic2_jmp_ind_mem_opsize__ud2
886
887 %if TMPL_BITS == 64
888; jmp [indirect] - 64-bit intel version
889BS3_CPUBAS2_UD_OFF bs3CpuBasic2_jmp_ind_mem_opsize__ud2__intel
890BS3_PROC_BEGIN_CMN bs3CpuBasic2_jmp_ind_mem_opsize__ud2__intel, BS3_PBC_NEAR
891 db 66h
892 jmp [.npAgain wrt FLAT]
893.post_jmp:
894 times 8 int3
895.npAgain:
896 dd .again wrt FLAT
897 dd 0
898.again: ud2
899 int3
900 jmp .again
901BS3_PROC_END_CMN bs3CpuBasic2_jmp_ind_mem_opsize__ud2__intel
902 %endif
903
904; jmp [xAX]
905BS3_CPUBAS2_UD_OFF bs3CpuBasic2_jmp_ind_xAX_opsize__ud2
906BS3_PROC_BEGIN_CMN bs3CpuBasic2_jmp_ind_xAX_opsize__ud2, BS3_PBC_NEAR
907 db 66h
908 jmp xAX
909.post_jmp:
910 times 8 int3
911.again: ud2
912 int3
913 jmp .again
914BS3_PROC_END_CMN bs3CpuBasic2_jmp_ind_xAX_opsize__ud2
915
916
917; call rel16/32 (forwards) with opsize override.
918BS3_CPUBAS2_UD_OFF bs3CpuBasic2_call_jv_opsize__ud2
919BS3_PROC_BEGIN_CMN bs3CpuBasic2_call_jv_opsize__ud2, BS3_PBC_NEAR
920 db 66h, 0e8h ; o32 jmp near .again
921 %if TMPL_BITS != 32
922 dd 12
923 %else
924 dw 12
925 %endif
926.post_call:
927 times 12 int3
928.again: ud2
929 int3
930 jmp .again
931BS3_PROC_END_CMN bs3CpuBasic2_call_jv_opsize__ud2
932
933
934; call rel16/32 (backwards) with opsize override.
935BS3_GLOBAL_NAME_EX RT_CONCAT(BS3_CMN_NM(bs3CpuBasic2_call_jv_opsize_back__ud2),.again), function, 2
936 ud2
937 times 19 int3
938BS3_CPUBAS2_UD_OFF bs3CpuBasic2_call_jv_opsize_back__ud2
939BS3_PROC_BEGIN_CMN bs3CpuBasic2_call_jv_opsize_back__ud2, BS3_PBC_NEAR
940 %if TMPL_BITS != 32
941 db 66h, 0e8h ; o32 call near .again
942 dd RT_CONCAT(BS3_CMN_NM(bs3CpuBasic2_call_jv_opsize_back__ud2),.again) - .post_call
943 %else
944 db 66h, 0e8h ; o16 call near .again
945 dw RT_CONCAT(BS3_CMN_NM(bs3CpuBasic2_call_jv_opsize_back__ud2),.again) - .post_call
946 %endif
947.post_call:
948 int3
949BS3_PROC_END_CMN bs3CpuBasic2_call_jv_opsize_back__ud2
950
951; call [indirect]
952BS3_CPUBAS2_UD_OFF bs3CpuBasic2_call_ind_mem_opsize__ud2
953BS3_PROC_BEGIN_CMN bs3CpuBasic2_call_ind_mem_opsize__ud2, BS3_PBC_NEAR
954 db 66h
955 %if TMPL_BITS == 16
956 call [word cs:.npAgain]
957 %elif TMPL_BITS == 32
958 call [dword cs:.npAgain wrt FLAT]
959 %else
960 call [.npAgain wrt FLAT]
961 %endif
962.post_call:
963 times 9 int3
964.npAgain:
965 %if TMPL_BITS == 16
966 dw BS3_TEXT16_WRT(.again)
967 dw 0
968 %else
969 dw .again wrt CGROUP16
970 dw 0faceh, 0f00dh, 07777h ; non-canonical address
971 %endif
972.again: ud2
973 int3
974 jmp .again
975BS3_PROC_END_CMN bs3CpuBasic2_call_ind_mem_opsize__ud2
976
977 %if TMPL_BITS == 64
978; call [indirect] - 64-bit intel version
979BS3_CPUBAS2_UD_OFF bs3CpuBasic2_call_ind_mem_opsize__ud2__intel
980BS3_PROC_BEGIN_CMN bs3CpuBasic2_call_ind_mem_opsize__ud2__intel, BS3_PBC_NEAR
981 db 66h
982 call [.npAgain wrt FLAT]
983.post_call:
984 times 8 int3
985.npAgain:
986 dd .again wrt FLAT
987 dd 0
988.again: ud2
989 int3
990 jmp .again
991BS3_PROC_END_CMN bs3CpuBasic2_call_ind_mem_opsize__ud2__intel
992 %endif
993
994; call [xAX]
995BS3_CPUBAS2_UD_OFF bs3CpuBasic2_call_ind_xAX_opsize__ud2
996BS3_PROC_BEGIN_CMN bs3CpuBasic2_call_ind_xAX_opsize__ud2, BS3_PBC_NEAR
997 db 66h
998 call xAX
999.post_call:
1000 times 8 int3
1001.again: ud2
1002 int3
1003 jmp .again
1004BS3_PROC_END_CMN bs3CpuBasic2_call_ind_xAX_opsize__ud2
1005
1006
1007;
1008; Mark the end of the opsize jmp section.
1009;
1010BS3_GLOBAL_NAME_EX BS3_CMN_NM(bs3CpuBasic2_jmp_opsize_end), , 1
1011 int3
1012TMPL_BEGIN_TEXT
1013
1014
1015;*********************************************************************************************************************************
1016;* FAR JMP ABS *
1017;*********************************************************************************************************************************
1018
1019;
1020; Mark the start of the opsize far jmp/call section.
1021;
1022; Here we also need to keep the 16-bit code out of the IVT and BIOS data area,
1023; not just the 32-bit and 64-bit code like for the above opsize cases.
1024;
1025BS3_BEGIN_TEXT16 TMPL_BITS
1026 %assign here $-$$
1027%if here < 0x600
1028 times (0x600 - here) int3
1029%endif
1030BS3_GLOBAL_NAME_EX BS3_CMN_NM(bs3CpuBasic2_far_jmp_call_opsize_begin), , 1
1031 int3
1032TMPL_BEGIN_TEXT
1033
1034 %if TMPL_BITS == 16
1035BS3_CPUBAS2_UD_OFF bs3CpuBasic2_jmpf_ptr_rm__ud2
1036BS3_PROC_BEGIN_CMN bs3CpuBasic2_jmpf_ptr_rm__ud2, BS3_PBC_NEAR
1037 db 0eah
1038 dw .again wrt CGROUP16
1039 dw BS3_SEL_TEXT16
1040.post_jmp:
1041 times 2 int3
1042.again: ud2
1043 int3
1044 jmp .again
1045BS3_PROC_END_CMN bs3CpuBasic2_jmpf_ptr_rm__ud2
1046 %endif
1047
1048 %if TMPL_BITS != 64
1049
1050BS3_CPUBAS2_UD_OFF bs3CpuBasic2_jmpf_ptr_same_r0__ud2
1051BS3_PROC_BEGIN_CMN bs3CpuBasic2_jmpf_ptr_same_r0__ud2, BS3_PBC_NEAR
1052 db 0eah
1053 %if TMPL_BITS == 16
1054 dw .again wrt CGROUP16
1055 dw BS3_SEL_R0_CS16
1056 %else
1057 dd .again wrt FLAT
1058 dw BS3_SEL_R0_CS32
1059 %endif
1060.post_jmp:
1061 times 7 int3
1062.again: ud2
1063 int3
1064 jmp .again
1065BS3_PROC_END_CMN bs3CpuBasic2_jmpf_ptr_same_r0__ud2
1066
1067BS3_CPUBAS2_UD_OFF bs3CpuBasic2_jmpf_ptr_same_r1__ud2
1068BS3_PROC_BEGIN_CMN bs3CpuBasic2_jmpf_ptr_same_r1__ud2, BS3_PBC_NEAR
1069 db 0eah ; inter privilege jmp -> #GP(dst-cs)
1070 %if TMPL_BITS == 16
1071 dw .again wrt CGROUP16
1072 dw BS3_SEL_R1_CS16 | 1
1073 %else
1074 dd .again wrt FLAT
1075 dw BS3_SEL_R1_CS32 | 1
1076 %endif
1077.again: ud2
1078 jmp .again
1079BS3_PROC_END_CMN bs3CpuBasic2_jmpf_ptr_same_r1__ud2
1080
1081BS3_CPUBAS2_UD_OFF bs3CpuBasic2_jmpf_ptr_same_r2__ud2
1082BS3_PROC_BEGIN_CMN bs3CpuBasic2_jmpf_ptr_same_r2__ud2, BS3_PBC_NEAR
1083 db 0eah ; inter privilege jmp -> #GP(dst-cs)
1084 %if TMPL_BITS == 16
1085 dw .again wrt CGROUP16
1086 dw BS3_SEL_R2_CS16 | 2
1087 %else
1088 dd .again wrt FLAT
1089 dw BS3_SEL_R2_CS32 | 2
1090 %endif
1091.again: ud2
1092 jmp .again
1093BS3_PROC_END_CMN bs3CpuBasic2_jmpf_ptr_same_r2__ud2
1094
1095BS3_CPUBAS2_UD_OFF bs3CpuBasic2_jmpf_ptr_same_r3__ud2
1096BS3_PROC_BEGIN_CMN bs3CpuBasic2_jmpf_ptr_same_r3__ud2, BS3_PBC_NEAR
1097 db 0eah ; inter privilege jmp -> #GP(dst-cs)
1098 %if TMPL_BITS == 16
1099 dw .again wrt CGROUP16
1100 dw BS3_SEL_R3_CS16 | 3
1101 %else
1102 dd .again wrt FLAT
1103 dw BS3_SEL_R3_CS32 | 3
1104 %endif
1105.again: ud2
1106 jmp .again
1107BS3_PROC_END_CMN bs3CpuBasic2_jmpf_ptr_same_r3__ud2
1108
1109BS3_BEGIN_TEXT16 TMPL_BITS
1110BS3_CPUBAS2_UD_OFF bs3CpuBasic2_jmpf_ptr_opsize_flipbit_r0__ud2
1111BS3_PROC_BEGIN_CMN bs3CpuBasic2_jmpf_ptr_opsize_flipbit_r0__ud2, BS3_PBC_NEAR
1112 db 066h, 0eah
1113 %if TMPL_BITS == 32
1114 dw .again wrt CGROUP16
1115 dw BS3_SEL_R0_CS16
1116 %else
1117 dd .again wrt FLAT
1118 dw BS3_SEL_R0_CS32
1119 %endif
1120 times 4 int3
1121.again: ud2
1122 jmp .again
1123BS3_PROC_END_CMN bs3CpuBasic2_jmpf_ptr_opsize_flipbit_r0__ud2
1124TMPL_BEGIN_TEXT
1125
1126; Do a jmp to BS3_SEL_R0_CS64. Except for when we're in long mode, this will
1127; result in a 16-bit CS with zero base and 4G limit.
1128BS3_CPUBAS2_UD_OFF bs3CpuBasic2_jmpf_ptr_r0_cs64__ud2
1129BS3_PROC_BEGIN_CMN bs3CpuBasic2_jmpf_ptr_r0_cs64__ud2, BS3_PBC_NEAR
1130 %if TMPL_BITS == 16
1131 db 066h
1132 %endif
1133 db 0eah
1134 dd .jmp_target wrt FLAT
1135 dw BS3_SEL_R0_CS64
1136 times 8 int3
1137.jmp_target:
1138 salc ; #UD in 64-bit mode
1139.again: ud2
1140 jmp .again
1141BS3_PROC_END_CMN bs3CpuBasic2_jmpf_ptr_r0_cs64__ud2
1142
1143BS3_BEGIN_TEXT16 TMPL_BITS
1144; Variation of the previous with a CS16 copy that has the L bit set, emulating
1145; pre-AMD64 software using the L bit for other stuff. (Don't run in long mode
1146; w/o copying the 3 bytes to the 0xxxxh memory range.)
1147BS3_CPUBAS2_UD_OFF bs3CpuBasic2_jmpf_ptr_r0_cs16l__ud2
1148BS3_PROC_BEGIN_CMN bs3CpuBasic2_jmpf_ptr_r0_cs16l__ud2, BS3_PBC_NEAR
1149 %if TMPL_BITS != 16
1150 db 066h
1151 %endif
1152 db 0eah
1153 dw .jmp_target wrt CGROUP16
1154 dw BS3_SEL_SPARE_00 ; ASSUMES this is set up as CGROUP16 but with L=1.
1155 times 3 int3
1156.jmp_target:
1157 salc ; #UD in 64-bit mode
1158.again: ud2
1159 jmp .again
1160BS3_PROC_END_CMN bs3CpuBasic2_jmpf_ptr_r0_cs16l__ud2
1161TMPL_BEGIN_TEXT
1162
1163 %endif ; TMPL_BITS != 64
1164
1165
1166
1167;*********************************************************************************************************************************
1168;* FAR CALL ABS *
1169;*********************************************************************************************************************************
1170
1171 %if TMPL_BITS == 16
1172BS3_CPUBAS2_UD_OFF bs3CpuBasic2_callf_ptr_rm__ud2
1173BS3_PROC_BEGIN_CMN bs3CpuBasic2_callf_ptr_rm__ud2, BS3_PBC_NEAR
1174 db 09ah
1175 dw .again wrt CGROUP16
1176 dw BS3_SEL_TEXT16
1177.post_call:
1178 times 2 int3
1179.again: ud2
1180 int3
1181 jmp .again
1182BS3_PROC_END_CMN bs3CpuBasic2_callf_ptr_rm__ud2
1183 %endif
1184
1185 %if TMPL_BITS != 64
1186
1187BS3_CPUBAS2_UD_OFF bs3CpuBasic2_callf_ptr_same_r0__ud2
1188BS3_PROC_BEGIN_CMN bs3CpuBasic2_callf_ptr_same_r0__ud2, BS3_PBC_NEAR
1189 db 09ah
1190 %if TMPL_BITS == 16
1191 dw .again wrt CGROUP16
1192 dw BS3_SEL_R0_CS16
1193 %else
1194 dd .again wrt FLAT
1195 dw BS3_SEL_R0_CS32
1196 %endif
1197.post_call:
1198 times 7 int3
1199.again: ud2
1200 int3
1201 jmp .again
1202BS3_PROC_END_CMN bs3CpuBasic2_callf_ptr_same_r0__ud2
1203
1204BS3_CPUBAS2_UD_OFF bs3CpuBasic2_callf_ptr_same_r1__ud2
1205BS3_PROC_BEGIN_CMN bs3CpuBasic2_callf_ptr_same_r1__ud2, BS3_PBC_NEAR
1206 db 09ah
1207 %if TMPL_BITS == 16
1208 dw .again wrt CGROUP16
1209 dw BS3_SEL_R1_CS16 | 1
1210 %else
1211 dd .again wrt FLAT
1212 dw BS3_SEL_R1_CS32 | 1
1213 %endif
1214.again: ud2
1215 jmp .again
1216BS3_PROC_END_CMN bs3CpuBasic2_callf_ptr_same_r1__ud2
1217
1218BS3_CPUBAS2_UD_OFF bs3CpuBasic2_callf_ptr_same_r2__ud2
1219BS3_PROC_BEGIN_CMN bs3CpuBasic2_callf_ptr_same_r2__ud2, BS3_PBC_NEAR
1220 db 09ah
1221 %if TMPL_BITS == 16
1222 dw .again wrt CGROUP16
1223 dw BS3_SEL_R2_CS16 | 2
1224 %else
1225 dd .again wrt FLAT
1226 dw BS3_SEL_R2_CS32 | 2
1227 %endif
1228.again: ud2
1229 jmp .again
1230BS3_PROC_END_CMN bs3CpuBasic2_callf_ptr_same_r2__ud2
1231
1232BS3_CPUBAS2_UD_OFF bs3CpuBasic2_callf_ptr_same_r3__ud2
1233BS3_PROC_BEGIN_CMN bs3CpuBasic2_callf_ptr_same_r3__ud2, BS3_PBC_NEAR
1234 db 09ah
1235 %if TMPL_BITS == 16
1236 dw .again wrt CGROUP16
1237 dw BS3_SEL_R3_CS16 | 3
1238 %else
1239 dd .again wrt FLAT
1240 dw BS3_SEL_R3_CS32 | 3
1241 %endif
1242.again: ud2
1243 jmp .again
1244BS3_PROC_END_CMN bs3CpuBasic2_callf_ptr_same_r3__ud2
1245
1246BS3_BEGIN_TEXT16 TMPL_BITS
1247BS3_CPUBAS2_UD_OFF bs3CpuBasic2_callf_ptr_opsize_flipbit_r0__ud2
1248BS3_PROC_BEGIN_CMN bs3CpuBasic2_callf_ptr_opsize_flipbit_r0__ud2, BS3_PBC_NEAR
1249 db 066h, 09ah
1250 %if TMPL_BITS == 32
1251 dw .again wrt CGROUP16
1252 dw BS3_SEL_R0_CS16
1253 %else
1254 dd .again wrt FLAT
1255 dw BS3_SEL_R0_CS32
1256 %endif
1257 times 4 int3
1258.again: ud2
1259 jmp .again
1260BS3_PROC_END_CMN bs3CpuBasic2_callf_ptr_opsize_flipbit_r0__ud2
1261TMPL_BEGIN_TEXT
1262
1263; Do a call to BS3_SEL_R0_CS64. Except for when we're in long mode, this will
1264; result in a 16-bit CS with zero base and 4G limit.
1265BS3_CPUBAS2_UD_OFF bs3CpuBasic2_callf_ptr_r0_cs64__ud2
1266BS3_PROC_BEGIN_CMN bs3CpuBasic2_callf_ptr_r0_cs64__ud2, BS3_PBC_NEAR
1267 %if TMPL_BITS == 16
1268 db 066h
1269 %endif
1270 db 09ah
1271 dd .call_target wrt FLAT
1272 dw BS3_SEL_R0_CS64
1273 times 8 int3
1274.call_target:
1275 salc ; #UD in 64-bit mode
1276.again: ud2
1277 jmp .again
1278BS3_PROC_END_CMN bs3CpuBasic2_callf_ptr_r0_cs64__ud2
1279
1280BS3_BEGIN_TEXT16 TMPL_BITS
1281; Variation of the previous with a CS16 copy that has the L bit set, emulating
1282; pre-AMD64 software using the L bit for other stuff. (Don't run in long mode
1283; w/o copying the 3 bytes to the 0xxxxh memory range.)
1284BS3_CPUBAS2_UD_OFF bs3CpuBasic2_callf_ptr_r0_cs16l__ud2
1285BS3_PROC_BEGIN_CMN bs3CpuBasic2_callf_ptr_r0_cs16l__ud2, BS3_PBC_NEAR
1286 %if TMPL_BITS != 16
1287 db 066h
1288 %endif
1289 db 09ah
1290 dw .call_target wrt CGROUP16
1291 dw BS3_SEL_SPARE_00 ; ASSUMES this is set up as CGROUP16 but with L=1.
1292 times 3 int3
1293.call_target:
1294 salc ; #UD in 64-bit mode
1295.again: ud2
1296 jmp .again
1297BS3_PROC_END_CMN bs3CpuBasic2_callf_ptr_r0_cs16l__ud2
1298TMPL_BEGIN_TEXT
1299
1300 %endif ; TMPL_BITS != 64
1301
1302
1303;*********************************************************************************************************************************
1304;* INDIRECT FAR JMP *
1305;*********************************************************************************************************************************
1306
1307 %if TMPL_BITS == 16
1308BS3_CPUBAS2_UD_OFF bs3CpuBasic2_jmpf_mem_rm__ud2
1309BS3_PROC_BEGIN_CMN bs3CpuBasic2_jmpf_mem_rm__ud2, BS3_PBC_NEAR
1310 jmp far [BS3_CPUBAS2_REF_LABEL_VIA_CS(.fpfn)]
1311 int3
1312.fpfn:
1313 dw .again wrt CGROUP16
1314 dw BS3_SEL_TEXT16
1315.post_jmp:
1316 times 2 int3
1317.again: ud2
1318 int3
1319 jmp .again
1320BS3_PROC_END_CMN bs3CpuBasic2_jmpf_mem_rm__ud2
1321 %endif
1322
1323;;
1324; Since AMD and Intel treat REX.W differently, we need two versions of the
1325; test functions here and use a macro to accomplish that.
1326;
1327; @param 1 Symbol suffix
1328; @param 2 0 for AMD, 1 for Intel.
1329;
1330%ifnmacro jmpf_macro
1331%macro jmpf_macro 2
1332
1333BS3_CPUBAS2_UD_OFF bs3CpuBasic2_jmpf_mem_same_r0__ud2 %+ %1
1334BS3_PROC_BEGIN_CMN bs3CpuBasic2_jmpf_mem_same_r0__ud2 %+ %1, BS3_PBC_NEAR
1335 BS3_CPUBAS2_JMP_FAR_MEM_LABEL .fpfn, 2
1336.fpfn:
1337 %if TMPL_BITS == 16
1338 dw .again wrt CGROUP16
1339 dw BS3_SEL_R0_CS16
1340 %elif TMPL_BITS == 32
1341 dd .again wrt FLAT
1342 dw BS3_SEL_R0_CS32
1343 %else
1344 dd .again wrt FLAT
1345 %if %2 != 0
1346 dd 0fffff000h
1347 %endif
1348 dw BS3_SEL_R0_CS64
1349 %endif
1350.post_jmp:
1351 times 7 int3
1352.again: ud2
1353 int3
1354 jmp .again
1355BS3_PROC_END_CMN bs3CpuBasic2_jmpf_mem_same_r0__ud2 %+ %1
1356
1357BS3_CPUBAS2_UD_OFF bs3CpuBasic2_jmpf_mem_same_r1__ud2 %+ %1
1358BS3_PROC_BEGIN_CMN bs3CpuBasic2_jmpf_mem_same_r1__ud2 %+ %1, BS3_PBC_NEAR
1359 BS3_CPUBAS2_JMP_FAR_MEM_LABEL .fpfn, 2
1360.fpfn:
1361 %if TMPL_BITS == 16
1362 dw .again wrt CGROUP16
1363 dw BS3_SEL_R1_CS16 | 1
1364 %elif TMPL_BITS == 32
1365 dd .again wrt FLAT
1366 dw BS3_SEL_R1_CS32 | 1
1367 %else
1368 dd .again wrt FLAT
1369 %if %2 != 0
1370 dd 0fffff000h
1371 %endif
1372 dw BS3_SEL_R1_CS64 | 1
1373 %endif
1374.again: ud2
1375 jmp .again
1376BS3_PROC_END_CMN bs3CpuBasic2_jmpf_mem_same_r1__ud2 %+ %1
1377
1378BS3_CPUBAS2_UD_OFF bs3CpuBasic2_jmpf_mem_same_r2__ud2 %+ %1
1379BS3_PROC_BEGIN_CMN bs3CpuBasic2_jmpf_mem_same_r2__ud2 %+ %1, BS3_PBC_NEAR
1380 BS3_CPUBAS2_JMP_FAR_MEM_LABEL .fpfn, 0
1381.fpfn:
1382 %if TMPL_BITS == 16
1383 dw .again wrt CGROUP16
1384 dw BS3_SEL_R2_CS16 | 2
1385 %elif TMPL_BITS == 32
1386 dd .again wrt FLAT
1387 dw BS3_SEL_R2_CS32 | 2
1388 %else
1389 dd .again wrt FLAT
1390 dw BS3_SEL_R2_CS64 | 2
1391 %endif
1392.again: ud2
1393 jmp .again
1394BS3_PROC_END_CMN bs3CpuBasic2_jmpf_mem_same_r2__ud2 %+ %1
1395
1396BS3_CPUBAS2_UD_OFF bs3CpuBasic2_jmpf_mem_same_r3__ud2 %+ %1
1397BS3_PROC_BEGIN_CMN bs3CpuBasic2_jmpf_mem_same_r3__ud2 %+ %1, BS3_PBC_NEAR
1398 BS3_CPUBAS2_JMP_FAR_MEM_LABEL .fpfn, 2
1399.fpfn:
1400 %if TMPL_BITS == 16
1401 dw .again wrt CGROUP16
1402 dw BS3_SEL_R3_CS16 | 3
1403 %elif TMPL_BITS == 32
1404 dd .again wrt FLAT
1405 dw BS3_SEL_R3_CS32 | 3
1406 %else
1407 dd .again wrt FLAT
1408 %if %2 != 0
1409 dd 0fffff000h
1410 %endif
1411 dw BS3_SEL_R3_CS64 | 3
1412 %endif
1413.again: ud2
1414 jmp .again
1415BS3_PROC_END_CMN bs3CpuBasic2_jmpf_mem_same_r3__ud2 %+ %1
1416
1417BS3_BEGIN_TEXT16 TMPL_BITS
1418BS3_CPUBAS2_UD_OFF bs3CpuBasic2_jmpf_mem_r0_cs16__ud2 %+ %1
1419BS3_PROC_BEGIN_CMN bs3CpuBasic2_jmpf_mem_r0_cs16__ud2 %+ %1, BS3_PBC_NEAR
1420 BS3_CPUBAS2_JMP_FAR_MEM_LABEL .fpfn, (TMPL_BITS != 16) ; TMPL_BITS != 16 ? 1 : 0
1421.fpfn:
1422 dw .again wrt CGROUP16
1423 dw BS3_SEL_R0_CS16
1424 times 4 int3
1425.again: ud2
1426 jmp .again
1427BS3_PROC_END_CMN bs3CpuBasic2_jmpf_mem_r0_cs16__ud2 %+ %1
1428TMPL_BEGIN_TEXT
1429
1430BS3_CPUBAS2_UD_OFF bs3CpuBasic2_jmpf_mem_r0_cs32__ud2 %+ %1
1431BS3_PROC_BEGIN_CMN bs3CpuBasic2_jmpf_mem_r0_cs32__ud2 %+ %1, BS3_PBC_NEAR
1432 BS3_CPUBAS2_JMP_FAR_MEM_LABEL .fpfn, (TMPL_BITS == 16) ; TMPL_BITS == 16 ? 1 : 0
1433.fpfn:
1434 dd .again wrt FLAT
1435 dw BS3_SEL_R0_CS32
1436 times 4 int3
1437.again: ud2
1438 jmp .again
1439BS3_PROC_END_CMN bs3CpuBasic2_jmpf_mem_r0_cs32__ud2 %+ %1
1440
1441; Do a jmp to BS3_SEL_R0_CS64. Except for when we're in long mode, this will
1442; result in a 16-bit CS with zero base and 4G limit.
1443BS3_CPUBAS2_UD_OFF bs3CpuBasic2_jmpf_mem_r0_cs64__ud2 %+ %1
1444BS3_PROC_BEGIN_CMN bs3CpuBasic2_jmpf_mem_r0_cs64__ud2 %+ %1, BS3_PBC_NEAR
1445 BS3_CPUBAS2_JMP_FAR_MEM_LABEL .fpfn, (2 - (TMPL_BITS == 16)) ; TMPL_BITS == 16 ? 1 : 2
1446.fpfn:
1447 dd .jmp_target wrt FLAT
1448 %if TMPL_BITS == 64 && %2 != 0
1449 dd 0fffff000h
1450 %endif
1451 dw BS3_SEL_R0_CS64
1452 times 8 int3
1453.jmp_target:
1454 %if TMPL_BITS != 64
1455 salc ; #UD in 64-bit mode
1456 %endif
1457.again: ud2
1458 jmp .again
1459BS3_PROC_END_CMN bs3CpuBasic2_jmpf_mem_r0_cs64__ud2 %+ %1
1460
1461BS3_BEGIN_TEXT16 TMPL_BITS
1462; Variation of the previous with a CS16 copy that has the L bit set, emulating
1463; pre-AMD64 software using the L bit for other stuff. (Don't run _c16/32 in
1464; long mode w/o copying the 3 bytes to the 0xxxxh memory range.)
1465; The _c64 version will test that the base is ignored.
1466BS3_CPUBAS2_UD_OFF bs3CpuBasic2_jmpf_mem_r0_cs16l__ud2 %+ %1
1467BS3_PROC_BEGIN_CMN bs3CpuBasic2_jmpf_mem_r0_cs16l__ud2 %+ %1, BS3_PBC_NEAR
1468 BS3_CPUBAS2_JMP_FAR_MEM_LABEL .fpfn, (TMPL_BITS == 32) ; TMPL_BITS == 32 ? 1 : 0
1469.fpfn:
1470 %if TMPL_BITS != 64
1471 dw .jmp_target wrt CGROUP16
1472 %else
1473 dd .jmp_target wrt FLAT
1474 %endif
1475 dw BS3_SEL_SPARE_00 ; ASSUMES this is set up as CGROUP16 but with L=1.
1476 times 3 int3
1477.jmp_target:
1478 %if TMPL_BITS != 64
1479 salc ; #UD in 64-bit mode
1480 %endif
1481.again: ud2
1482 jmp .again
1483BS3_PROC_END_CMN bs3CpuBasic2_jmpf_mem_r0_cs16l__ud2 %+ %1
1484TMPL_BEGIN_TEXT
1485
1486%endmacro
1487%endif
1488
1489; Instantiate the above code
1490jmpf_macro , 0
1491 %if TMPL_BITS == 64
1492jmpf_macro _intel, 1
1493 %endif
1494
1495
1496;*********************************************************************************************************************************
1497;* INDIRECT FAR CALL *
1498;*********************************************************************************************************************************
1499
1500 %if TMPL_BITS == 16
1501BS3_CPUBAS2_UD_OFF bs3CpuBasic2_callf_mem_rm__ud2
1502BS3_PROC_BEGIN_CMN bs3CpuBasic2_callf_mem_rm__ud2, BS3_PBC_NEAR
1503 call far [BS3_CPUBAS2_REF_LABEL_VIA_CS(.fpfn)]
1504 int3
1505.fpfn:
1506 dw .again wrt CGROUP16
1507 dw BS3_SEL_TEXT16
1508.post_jmp:
1509 times 2 int3
1510.again: ud2
1511 int3
1512 jmp .again
1513BS3_PROC_END_CMN bs3CpuBasic2_callf_mem_rm__ud2
1514 %endif
1515
1516
1517;;
1518; Since AMD and Intel treat REX.W differently, we need two versions of the
1519; test functions here and use a macro to accomplish that.
1520;
1521; @param 1 Symbol suffix
1522; @param 2 0 for AMD, 1 for Intel.
1523;
1524%ifnmacro callf_macro
1525%macro callf_macro 2
1526
1527BS3_CPUBAS2_UD_OFF bs3CpuBasic2_callf_mem_same_r0__ud2 %+ %1
1528BS3_PROC_BEGIN_CMN bs3CpuBasic2_callf_mem_same_r0__ud2 %+ %1, BS3_PBC_NEAR
1529 BS3_CPUBAS2_CALL_FAR_MEM_LABEL .fpfn, 2
1530.fpfn:
1531 %if TMPL_BITS == 16
1532 dw .again wrt CGROUP16
1533 dw BS3_SEL_R0_CS16
1534 %elif TMPL_BITS == 32
1535 dd .again wrt FLAT
1536 dw BS3_SEL_R0_CS32
1537 %else
1538 dd .again wrt FLAT
1539 %if %2 != 0
1540 dd 0fffff000h
1541 %endif
1542 dw BS3_SEL_R0_CS64
1543 %endif
1544.post_call:
1545 times 7 int3
1546.again: ud2
1547 int3
1548 jmp .again
1549BS3_PROC_END_CMN bs3CpuBasic2_callf_mem_same_r0__ud2 %+ %1
1550
1551BS3_CPUBAS2_UD_OFF bs3CpuBasic2_callf_mem_same_r1__ud2 %+ %1
1552BS3_PROC_BEGIN_CMN bs3CpuBasic2_callf_mem_same_r1__ud2 %+ %1, BS3_PBC_NEAR
1553 BS3_CPUBAS2_CALL_FAR_MEM_LABEL .fpfn, 2
1554.fpfn:
1555 %if TMPL_BITS == 16
1556 dw .again wrt CGROUP16
1557 dw BS3_SEL_R1_CS16 | 1
1558 %elif TMPL_BITS == 32
1559 dd .again wrt FLAT
1560 dw BS3_SEL_R1_CS32 | 1
1561 %else
1562 dd .again wrt FLAT
1563 %if %2 != 0
1564 dd 0fffff000h
1565 %endif
1566 dw BS3_SEL_R1_CS64 | 1
1567 %endif
1568.again: ud2
1569 jmp .again
1570BS3_PROC_END_CMN bs3CpuBasic2_callf_mem_same_r1__ud2 %+ %1
1571
1572BS3_CPUBAS2_UD_OFF bs3CpuBasic2_callf_mem_same_r2__ud2 %+ %1
1573BS3_PROC_BEGIN_CMN bs3CpuBasic2_callf_mem_same_r2__ud2 %+ %1, BS3_PBC_NEAR
1574 BS3_CPUBAS2_CALL_FAR_MEM_LABEL .fpfn, 0
1575.fpfn:
1576 %if TMPL_BITS == 16
1577 dw .again wrt CGROUP16
1578 dw BS3_SEL_R2_CS16 | 2
1579 %elif TMPL_BITS == 32
1580 dd .again wrt FLAT
1581 dw BS3_SEL_R2_CS32 | 2
1582 %else
1583 dd .again wrt FLAT
1584 dw BS3_SEL_R2_CS64 | 2
1585 %endif
1586.again: ud2
1587 jmp .again
1588BS3_PROC_END_CMN bs3CpuBasic2_callf_mem_same_r2__ud2 %+ %1
1589
1590BS3_CPUBAS2_UD_OFF bs3CpuBasic2_callf_mem_same_r3__ud2 %+ %1
1591BS3_PROC_BEGIN_CMN bs3CpuBasic2_callf_mem_same_r3__ud2 %+ %1, BS3_PBC_NEAR
1592 BS3_CPUBAS2_CALL_FAR_MEM_LABEL .fpfn, 2
1593.fpfn:
1594 %if TMPL_BITS == 16
1595 dw .again wrt CGROUP16
1596 dw BS3_SEL_R3_CS16 | 3
1597 %elif TMPL_BITS == 32
1598 dd .again wrt FLAT
1599 dw BS3_SEL_R3_CS32 | 3
1600 %else
1601 dd .again wrt FLAT
1602 %if %2 != 0
1603 dd 0fffff000h
1604 %endif
1605 dw BS3_SEL_R3_CS64 | 3
1606 %endif
1607.again: ud2
1608 jmp .again
1609BS3_PROC_END_CMN bs3CpuBasic2_callf_mem_same_r3__ud2 %+ %1
1610
1611BS3_BEGIN_TEXT16 TMPL_BITS
1612BS3_CPUBAS2_UD_OFF bs3CpuBasic2_callf_mem_r0_cs16__ud2 %+ %1
1613BS3_PROC_BEGIN_CMN bs3CpuBasic2_callf_mem_r0_cs16__ud2 %+ %1, BS3_PBC_NEAR
1614 BS3_CPUBAS2_CALL_FAR_MEM_LABEL .fpfn, (TMPL_BITS != 16) ; (TMPL_BITS == 16 ? 0 : 1)
1615.fpfn:
1616 dw .again wrt CGROUP16
1617 dw BS3_SEL_R0_CS16
1618 times 4 int3
1619.again: ud2
1620 jmp .again
1621BS3_PROC_END_CMN bs3CpuBasic2_callf_mem_r0_cs16__ud2 %+ %1
1622TMPL_BEGIN_TEXT
1623
1624BS3_CPUBAS2_UD_OFF bs3CpuBasic2_callf_mem_r0_cs32__ud2 %+ %1
1625BS3_PROC_BEGIN_CMN bs3CpuBasic2_callf_mem_r0_cs32__ud2 %+ %1, BS3_PBC_NEAR
1626 BS3_CPUBAS2_CALL_FAR_MEM_LABEL .fpfn, (TMPL_BITS == 16) ; (TMPL_BITS == 16 ? 1 : 0)
1627.fpfn:
1628 dd .again wrt FLAT
1629 dw BS3_SEL_R0_CS32
1630 times 4 int3
1631.again: ud2
1632 jmp .again
1633BS3_PROC_END_CMN bs3CpuBasic2_callf_mem_r0_cs32__ud2 %+ %1
1634
1635; Do a call to BS3_SEL_R0_CS64. Except for when we're in long mode, this will
1636; result in a 16-bit CS with zero base and 4G limit.
1637BS3_CPUBAS2_UD_OFF bs3CpuBasic2_callf_mem_r0_cs64__ud2 %+ %1
1638BS3_PROC_BEGIN_CMN bs3CpuBasic2_callf_mem_r0_cs64__ud2 %+ %1, BS3_PBC_NEAR
1639 BS3_CPUBAS2_CALL_FAR_MEM_LABEL .fpfn, (2 - (TMPL_BITS == 16)) ; (TMPL_BITS == 16 ? 1 : 2)
1640.fpfn:
1641 dd .call_target wrt FLAT
1642 %if TMPL_BITS == 64 && %2 != 0
1643 dd 0fffff000h
1644 %endif
1645 dw BS3_SEL_R0_CS64
1646 times 8 int3
1647.call_target:
1648 %if TMPL_BITS != 64
1649 salc ; #UD in 64-bit mode
1650 %endif
1651.again: ud2
1652 jmp .again
1653BS3_PROC_END_CMN bs3CpuBasic2_callf_mem_r0_cs64__ud2 %+ %1
1654
1655BS3_BEGIN_TEXT16 TMPL_BITS
1656; Variation of the previous with a CS16 copy that has the L bit set, emulating
1657; pre-AMD64 software using the L bit for other stuff. (Don't run _c16/32 in
1658; long mode w/o copying the 3 bytes to the 0xxxxh memory range.)
1659; The _c64 version will test that the base is ignored.
1660BS3_CPUBAS2_UD_OFF bs3CpuBasic2_callf_mem_r0_cs16l__ud2 %+ %1
1661BS3_PROC_BEGIN_CMN bs3CpuBasic2_callf_mem_r0_cs16l__ud2 %+ %1, BS3_PBC_NEAR
1662 BS3_CPUBAS2_CALL_FAR_MEM_LABEL .fpfn, (TMPL_BITS == 32) ; (TMPL_BITS == 32 ? 1 : 0)
1663.fpfn:
1664 %if TMPL_BITS != 64
1665 dw .call_target wrt CGROUP16
1666 %else
1667 dd .call_target wrt FLAT
1668 %endif
1669 dw BS3_SEL_SPARE_00 ; ASSUMES this is set up as CGROUP16 but with L=1.
1670 times 3 int3
1671.call_target:
1672 %if TMPL_BITS != 64
1673 salc ; #UD in 64-bit mode
1674 %endif
1675.again: ud2
1676 jmp .again
1677BS3_PROC_END_CMN bs3CpuBasic2_callf_mem_r0_cs16l__ud2 %+ %1
1678TMPL_BEGIN_TEXT
1679
1680%endmacro ; callf_macro
1681%endif
1682
1683; Instantiate the above code
1684callf_macro , 0
1685 %if TMPL_BITS == 64
1686callf_macro _intel, 1
1687 %endif
1688
1689;
1690; Mark the end of the opsize far jmp/call section.
1691;
1692BS3_BEGIN_TEXT16 TMPL_BITS
1693BS3_GLOBAL_NAME_EX BS3_CMN_NM(bs3CpuBasic2_far_jmp_call_opsize_end), , 1
1694 int3
1695TMPL_BEGIN_TEXT
1696
1697
1698;*********************************************************************************************************************************
1699;* Near RET *
1700;*********************************************************************************************************************************
1701BS3_CPUBAS2_UD_OFF bs3CpuBasic2_retn__ud2
1702BS3_PROC_BEGIN_CMN bs3CpuBasic2_retn__ud2, BS3_PBC_NEAR
1703 ret
1704.again: ud2
1705 jmp .again
1706BS3_PROC_END_CMN bs3CpuBasic2_retn__ud2
1707
1708BS3_CPUBAS2_UD_OFF bs3CpuBasic2_retn_i24__ud2
1709BS3_PROC_BEGIN_CMN bs3CpuBasic2_retn_i24__ud2, BS3_PBC_NEAR
1710 ret 24
1711.again: ud2
1712 jmp .again
1713AssertCompile(.again - BS3_LAST_LABEL == 3)
1714BS3_PROC_END_CMN bs3CpuBasic2_retn_i24__ud2
1715
1716BS3_CPUBAS2_UD_OFF bs3CpuBasic2_retn_i0__ud2
1717BS3_PROC_BEGIN_CMN bs3CpuBasic2_retn_i0__ud2, BS3_PBC_NEAR
1718 ret 0
1719.again: ud2
1720 jmp .again
1721AssertCompile(.again - BS3_LAST_LABEL == 3)
1722BS3_PROC_END_CMN bs3CpuBasic2_retn_i0__ud2
1723
1724BS3_CPUBAS2_UD_OFF bs3CpuBasic2_retn_i760__ud2
1725BS3_PROC_BEGIN_CMN bs3CpuBasic2_retn_i760__ud2, BS3_PBC_NEAR
1726 ret 760
1727.again: ud2
1728 jmp .again
1729AssertCompile(.again - BS3_LAST_LABEL == 3)
1730BS3_PROC_END_CMN bs3CpuBasic2_retn_i760__ud2
1731
1732 %if TMPL_BITS == 64
1733
1734BS3_CPUBAS2_UD_OFF bs3CpuBasic2_retn_rexw__ud2
1735BS3_PROC_BEGIN_CMN bs3CpuBasic2_retn_rexw__ud2, BS3_PBC_NEAR
1736 db 048h ; REX.W
1737 ret
1738.again: ud2
1739 jmp .again
1740BS3_PROC_END_CMN bs3CpuBasic2_retn_rexw__ud2
1741
1742BS3_CPUBAS2_UD_OFF bs3CpuBasic2_retn_i24_rexw__ud2
1743BS3_PROC_BEGIN_CMN bs3CpuBasic2_retn_i24_rexw__ud2, BS3_PBC_NEAR
1744 db 048h ; REX.W
1745 ret 24
1746.again: ud2
1747 jmp .again
1748AssertCompile(.again - BS3_LAST_LABEL == 4)
1749BS3_PROC_END_CMN bs3CpuBasic2_retn_i24_rexw__ud2
1750
1751BS3_CPUBAS2_UD_OFF bs3CpuBasic2_retn_opsize_rexw__ud2
1752BS3_PROC_BEGIN_CMN bs3CpuBasic2_retn_opsize_rexw__ud2, BS3_PBC_NEAR
1753 db 66h, 048h
1754 ret
1755.again: ud2
1756 jmp .again
1757BS3_PROC_END_CMN bs3CpuBasic2_retn_opsize_rexw__ud2
1758
1759BS3_CPUBAS2_UD_OFF bs3CpuBasic2_retn_i24_opsize_rexw__ud2
1760BS3_PROC_BEGIN_CMN bs3CpuBasic2_retn_i24_opsize_rexw__ud2, BS3_PBC_NEAR
1761 db 66h, 048h
1762 ret 24
1763.again: ud2
1764 jmp .again
1765AssertCompile(.again - BS3_LAST_LABEL == 5)
1766BS3_PROC_END_CMN bs3CpuBasic2_retn_i24_opsize_rexw__ud2
1767
1768 %endif
1769
1770; Mark the start of opsize tests as we end up below 64K in 32-bit and 64-bit when used.
1771BS3_BEGIN_TEXT16 TMPL_BITS
1772BS3_GLOBAL_NAME_EX BS3_CMN_NM(bs3CpuBasic2_retn_opsize_begin), , 1
1773 int3
1774
1775BS3_CPUBAS2_UD_OFF bs3CpuBasic2_retn_opsize__ud2
1776BS3_PROC_BEGIN_CMN bs3CpuBasic2_retn_opsize__ud2, BS3_PBC_NEAR
1777 db 66h
1778 ret
1779.again: ud2
1780 jmp .again
1781BS3_PROC_END_CMN bs3CpuBasic2_retn_opsize__ud2
1782
1783BS3_CPUBAS2_UD_OFF bs3CpuBasic2_retn_i24_opsize__ud2
1784BS3_PROC_BEGIN_CMN bs3CpuBasic2_retn_i24_opsize__ud2, BS3_PBC_NEAR
1785 db 66h
1786 ret 24
1787.again: ud2
1788 jmp .again
1789AssertCompile(.again - BS3_LAST_LABEL == 4)
1790BS3_PROC_END_CMN bs3CpuBasic2_retn_i24_opsize__ud2
1791
1792BS3_CPUBAS2_UD_OFF bs3CpuBasic2_retn_i0_opsize__ud2
1793BS3_PROC_BEGIN_CMN bs3CpuBasic2_retn_i0_opsize__ud2, BS3_PBC_NEAR
1794 db 66h
1795 ret 0
1796.again: ud2
1797 jmp .again
1798AssertCompile(.again - BS3_LAST_LABEL == 4)
1799BS3_PROC_END_CMN bs3CpuBasic2_retn_i0_opsize__ud2
1800
1801 %if TMPL_BITS == 64
1802BS3_CPUBAS2_UD_OFF bs3CpuBasic2_retn_rexw_opsize__ud2
1803BS3_PROC_BEGIN_CMN bs3CpuBasic2_retn_rexw_opsize__ud2, BS3_PBC_NEAR
1804 db 048h, 66h
1805 ret
1806.again: ud2
1807 jmp .again
1808BS3_PROC_END_CMN bs3CpuBasic2_retn_rexw_opsize__ud2
1809
1810BS3_CPUBAS2_UD_OFF bs3CpuBasic2_retn_i24_rexw_opsize__ud2
1811BS3_PROC_BEGIN_CMN bs3CpuBasic2_retn_i24_rexw_opsize__ud2, BS3_PBC_NEAR
1812 db 048h, 66h
1813 ret 24
1814.again: ud2
1815 jmp .again
1816AssertCompile(.again - BS3_LAST_LABEL == 5)
1817BS3_PROC_END_CMN bs3CpuBasic2_retn_i24_rexw_opsize__ud2
1818 %endif
1819
1820; End of opsize tests.
1821BS3_GLOBAL_NAME_EX BS3_CMN_NM(bs3CpuBasic2_retn_opsize_end), , 1
1822 int3
1823TMPL_BEGIN_TEXT
1824
1825
1826;*********************************************************************************************************************************
1827;* FAR RET *
1828;*********************************************************************************************************************************
1829BS3_PROC_BEGIN_CMN bs3CpuBasic2_retf, BS3_PBC_NEAR
1830 db 0cbh ; retf
1831BS3_PROC_END_CMN bs3CpuBasic2_retf
1832
1833BS3_PROC_BEGIN_CMN bs3CpuBasic2_retf_opsize, BS3_PBC_NEAR
1834 db 066h, 0cbh ; o32/o16 retf
1835BS3_PROC_END_CMN bs3CpuBasic2_retf_opsize
1836
1837BS3_PROC_BEGIN_CMN bs3CpuBasic2_retf_i32, BS3_PBC_NEAR
1838 db 0cah, 20h, 0 ; retf 32
1839BS3_PROC_END_CMN bs3CpuBasic2_retf_i32
1840
1841BS3_PROC_BEGIN_CMN bs3CpuBasic2_retf_i32_opsize, BS3_PBC_NEAR
1842 db 066h, 0cah, 20h, 0 ; o32/o16 retf 32
1843BS3_PROC_END_CMN bs3CpuBasic2_retf_i32_opsize
1844
1845BS3_PROC_BEGIN_CMN bs3CpuBasic2_retf_i888, BS3_PBC_NEAR
1846 db 0cah, 78h, 03h ; retf 888 (0x378)
1847BS3_PROC_END_CMN bs3CpuBasic2_retf_i888
1848
1849 %if TMPL_BITS == 64
1850BS3_PROC_BEGIN_CMN bs3CpuBasic2_retf_rexw, BS3_PBC_NEAR
1851 db 048h, 0cbh ; o64 retf
1852BS3_PROC_END_CMN bs3CpuBasic2_retf_rexw
1853
1854BS3_PROC_BEGIN_CMN bs3CpuBasic2_retf_opsize_rexw, BS3_PBC_NEAR
1855 db 066h, 048h, 0cbh ; o16 o64 retf
1856BS3_PROC_END_CMN bs3CpuBasic2_retf_opsize_rexw
1857
1858BS3_PROC_BEGIN_CMN bs3CpuBasic2_retf_rexw_opsize, BS3_PBC_NEAR
1859 db 048h, 066h, 0cbh ; o64 o16 retf
1860BS3_PROC_END_CMN bs3CpuBasic2_retf_rexw_opsize
1861
1862BS3_PROC_BEGIN_CMN bs3CpuBasic2_retf_i24_rexw, BS3_PBC_NEAR
1863 db 048h, 0cah, 24, 0 ; o64 retf 24
1864BS3_PROC_END_CMN bs3CpuBasic2_retf_i24_rexw
1865
1866BS3_PROC_BEGIN_CMN bs3CpuBasic2_retf_i24_opsize_rexw, BS3_PBC_NEAR
1867 db 066h, 048h, 0cah, 24, 0 ; o16 o64 retf 24
1868BS3_PROC_END_CMN bs3CpuBasic2_retf_i24_opsize_rexw
1869
1870BS3_PROC_BEGIN_CMN bs3CpuBasic2_retf_i24_rexw_opsize, BS3_PBC_NEAR
1871 db 048h, 066h, 0cah, 24, 0 ; o64 o16 retf 24
1872BS3_PROC_END_CMN bs3CpuBasic2_retf_i24_rexw_opsize
1873 %endif
1874
1875%endif ; BS3_INSTANTIATING_CMN
1876
1877%include "bs3kit-template-footer.mac" ; reset environment
1878
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