VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.mac@ 60097

Last change on this file since 60097 was 60097, checked in by vboxsync, 9 years ago

bs3kit: Updates

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 52.5 KB
Line 
1; $Id: bs3kit.mac 60097 2016-03-18 13:14:40Z vboxsync $
2;; @file
3; BS3Kit - structures, symbols, macros and stuff.
4;
5
6;
7; Copyright (C) 2007-2015 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%ifndef ___bs3kit_mac___
28%define ___bs3kit_mac___
29
30;
31; Before we can include anything, we need to override NAME and switch section.
32; If we don't do the latter we end up with an unused 'text' section.
33;
34
35; Drop the asmdefs-first.mac header for native bs3kit files.
36%undef RT_ASMDEFS_INC_FIRST_FILE
37
38;;
39; Macro for setting register aliases according to the bit count given by %1.
40;
41%macro BS3_SET_REG_ALIASES 1
42 ;
43 ; Register aliases.
44 ;
45 %if %1 == 64
46 %define xCB 8
47 %define xDEF dq
48 %define xRES resq
49 %define xPRE qword
50 %define xSP rsp
51 %define xBP rbp
52 %define xAX rax
53 %define xBX rbx
54 %define xCX rcx
55 %define xDX rdx
56 %define xDI rdi
57 %define xSI rsi
58 %define xWrtRIP wrt rip
59 %define xPUSHF pushfq
60 %define xPOPF popfq
61 %define xRETF o64 retf
62 %elif %1 == 32
63 %define xCB 4
64 %define xDEF dd
65 %define xRES resd
66 %define xPRE dword
67 %define xSP esp
68 %define xBP ebp
69 %define xAX eax
70 %define xBX ebx
71 %define xCX ecx
72 %define xDX edx
73 %define xDI edi
74 %define xSI esi
75 %define xWrtRIP
76 %define xPUSHF pushfd
77 %define xPOPF popfd
78 %define xRETF retf
79 %elif %1 == 16
80 %define xCB 2
81 %define xDEF dw
82 %define xRES resw
83 %define xPRE word
84 %define xSP sp
85 %define xBP bp
86 %define xAX ax
87 %define xBX bx
88 %define xCX cx
89 %define xDX dx
90 %define xDI di
91 %define xSI si
92 %define xWrtRIP
93 %define xPUSHF pushf
94 %define xPOPF popf
95 %define xRETF retf
96 %else
97 %error "Invalid BS3_SET_REG_ALIASES argument:" %1
98 %endif
99
100
101 ;
102 ; Register names corresponding to the max size for pop/push <reg>.
103 ;
104 ; 16-bit can push both 32-bit and 16-bit registers. This 's' prefixed variant
105 ; is used when 16-bit should use the 32-bit register.
106 ;
107 %if %1 == 64
108 %define sCB 8
109 %define sDEF dq
110 %define sRES resq
111 %define sPRE qword
112 %define sSP rsp
113 %define sBP rbp
114 %define sAX rax
115 %define sBX rbx
116 %define sCX rcx
117 %define sDX rdx
118 %define sDI rdi
119 %define sSI rsi
120 %define sPUSHF pushfq
121 %define sPOPF popfq
122 %else
123 %define sCB 4
124 %define sDEF dd
125 %define sRES resd
126 %define sPRE dword
127 %define sSP esp
128 %define sBP ebp
129 %define sAX eax
130 %define sBX ebx
131 %define sCX ecx
132 %define sDX edx
133 %define sDI edi
134 %define sSI esi
135 %define sPUSHF pushfd
136 %define sPOPF popfd
137 %endif
138%endmacro
139
140; Default to register aliases for ARCH_BITS.
141BS3_SET_REG_ALIASES ARCH_BITS
142
143
144;; Wrapper around BITS.
145; Updates __BITS__ (built-in variable in nasm, we work it for yasm) as well
146; a number of convenient macros and register aliases.
147;
148; @param %1 The CPU bit count: 16, 32 or 64
149; @remarks ARCH_BITS is not modified and will remain what it was on the
150; assembler command line.
151%macro BS3_SET_BITS 1
152 BITS %1
153
154 %ifdef __YASM__
155 %undef __BITS__
156 %define __BITS__ %1
157 %endif
158
159 %undef BS3_NAME_UNDERSCORE
160 %if %1 == 64
161 %define BS3_NAME_UNDERSCORE
162 %else
163 %define BS3_NAME_UNDERSCORE _
164 %endif
165
166 %undef BS3_ONLY_16BIT
167 %if %1 == 16
168 %define BS3_ONLY_16BIT(a_Expr) a_Expr
169 %else
170 %define BS3_ONLY_16BIT(a_Expr)
171 %endif
172
173 %undef BS3_ONLY_64BIT
174 %if %1 == 64
175 %define BS3_ONLY_64BIT(a_Expr) a_Expr
176 %else
177 %define BS3_ONLY_64BIT(a_Expr)
178 %endif
179
180 %undef BS3_NOT_64BIT
181 %if %1 == 64
182 %define BS3_NOT_64BIT(a_Expr)
183 %else
184 %define BS3_NOT_64BIT(a_Expr) a_Expr
185 %endif
186
187 %undef BS3_IF_16_32_64BIT
188 %if %1 == 16
189 %define BS3_IF_16_32_64BIT(a_16BitExpr, a_32BitExpr, a_64BitExpr) a_16BitExpr
190 %elif %1 == 32
191 %define BS3_IF_16_32_64BIT(a_16BitExpr, a_32BitExpr, a_64BitExpr) a_32BitExpr
192 %else
193 %define BS3_IF_16_32_64BIT(a_16BitExpr, a_32BitExpr, a_64BitExpr) a_64BitExpr
194 %endif
195
196 %undef BS3_WRT_RIP
197 %if %1 == 64
198 %define BS3_WRT_RIP(a_Sym) rel a_Sym
199 %else
200 %define BS3_WRT_RIP(a_Sym) a_Sym
201 %endif
202
203 %undef BS3_LEA_MOV_WRT_RIP
204 %if %1 == 64
205 %define BS3_LEA_MOV_WRT_RIP(a_DstReg, a_Sym) lea a_DstReg, [BS3_WRT_RIP(a_Sym)]
206 %else
207 %define BS3_LEA_MOV_WRT_RIP(a_DstReg, a_Sym) mov a_DstReg, a_Sym
208 %endif
209
210 ;; @def BS3_DATA16_WRT
211 ; For accessing BS3DATA16 correctly.
212 ; @param a_Var The BS3DATA16 variable.
213 %undef BS3_DATA16_WRT
214 %if %1 == 16
215 %define BS3_DATA16_WRT(a_Var) a_Var wrt BS3DATA16
216 %elif %1 == 32
217 %define BS3_DATA16_WRT(a_Var) a_Var wrt FLAT
218 %else
219 %define BS3_DATA16_WRT(a_Var) BS3_WRT_RIP(a_Var) wrt FLAT
220 %endif
221
222 %undef BS3_IF_16BIT_OTHERWISE
223 %if %1 == 16
224 %define BS3_IF_16BIT_OTHERWISE(a_16BitExpr, a_OtherwiseExpr) a_16BitExpr
225 %else
226 %define BS3_IF_16BIT_OTHERWISE(a_16BitExpr, a_OtherwiseExpr) a_OtherwiseExpr
227 %endif
228
229 %undef BS3_IF_32BIT_OTHERWISE
230 %if %1 == 32
231 %define BS3_IF_32BIT_OTHERWISE(a_32BitExpr, a_OtherwiseExpr) a_32BitExpr
232 %else
233 %define BS3_IF_32BIT_OTHERWISE(a_32BitExpr, a_OtherwiseExpr) a_OtherwiseExpr
234 %endif
235
236 %undef BS3_IF_64BIT_OTHERWISE
237 %if %1 == 32
238 %define BS3_IF_64BIT_OTHERWISE(a_64BitExpr, a_OtherwiseExpr) a_32BitExpr
239 %else
240 %define BS3_IF_64BIT_OTHERWISE(a_64BitExpr, a_OtherwiseExpr) a_OtherwiseExpr
241 %endif
242
243 BS3_SET_REG_ALIASES %1
244%endmacro
245
246
247;; Emulate the __BITS__ macro in NASM 2.0+. Follows BS3_SET_BITS.
248%ifdef __YASM__
249 %define __BITS__ ARCH_BITS
250%endif
251
252;; Mostly internal macro. Follows BS3_SET_BITS.
253%if ARCH_BITS == 64
254 %define BS3_NAME_UNDERSCORE
255%else
256 %define BS3_NAME_UNDERSCORE _
257%endif
258
259;; For RIP relative addressing in 64-bit mode and absolute addressing in
260; other modes. Follows BS3_SET_BITS.
261%if ARCH_BITS == 64
262 %ifdef __YASM__
263 %define BS3_WRT_RIP(a_Sym) a_Sym wrt rip
264 %else
265 %define BS3_WRT_RIP(a_Sym) rel a_Sym ; Baka! Why couldn't they do 'wrt rip' like yasm?
266 %endif
267%else
268 %define BS3_WRT_RIP(a_Sym) a_Sym
269%endif
270
271;; For segment overrides and stuff. Follows BS3_SET_BITS.
272%if ARCH_BITS == 16
273 %define BS3_ONLY_16BIT(a_Expr) a_Expr
274%else
275 %define BS3_ONLY_16BIT(a_Expr)
276%endif
277
278;; For odd 64-bit stuff. Follows BS3_SET_BITS.
279%if ARCH_BITS == 64
280 %define BS3_ONLY_64BIT(a_Expr) a_Expr
281%else
282 %define BS3_ONLY_64BIT(a_Expr)
283%endif
284
285;; For segment overrides and stuff. Follows BS3_SET_BITS.
286%if ARCH_BITS == 64
287 %define BS3_NOT_64BIT(a_Expr)
288%else
289 %define BS3_NOT_64BIT(a_Expr) a_Expr
290%endif
291
292;; For stack cleanups and similar where each bit mode is different. Follows BS3_SET_BITS.
293%if ARCH_BITS == 16
294 %define BS3_IF_16_32_64BIT(a_16BitExpr, a_32BitExpr, a_64BitExpr) a_16BitExpr
295%elif ARCH_BITS == 32
296 %define BS3_IF_16_32_64BIT(a_16BitExpr, a_32BitExpr, a_64BitExpr) a_32BitExpr
297%else
298 %define BS3_IF_16_32_64BIT(a_16BitExpr, a_32BitExpr, a_64BitExpr) a_64BitExpr
299%endif
300
301
302;;
303; For instruction that should only be emitted in 16-bit mode. Follows BS3_SET_BITS.
304%macro BS3_ONLY_16BIT_STMT 1+
305 %if __BITS__ == 16
306 %1
307 %endif
308%endmacro
309
310;;
311; For instruction that should only be emitted in 32-bit mode. Follows BS3_SET_BITS.
312%macro BS3_ONLY_32BIT_STMT 1+
313 %if __BITS__ == 32
314 %1
315 %endif
316%endmacro
317
318;;
319; For instruction that should only be emitted in 64-bit mode. Follows BS3_SET_BITS.
320%macro BS3_ONLY_64BIT_STMT 1+
321 %if __BITS__ == 64
322 %1
323 %endif
324%endmacro
325
326
327
328;; @name Segment definitions.
329;; @{
330
331%ifdef ASM_FORMAT_OMF
332; !!HACK ALERT!!
333;
334; To make FLAT actually be flat, i.e. have a base of 0 rather than the same as
335; the target (?) segment, we tweak it a little bit here. We associate a segment
336; with it so that we can get at it in the class/segment ordering directives
337; we pass to the linker. The segment does not contain any data or anything, it
338; is just an empty one which we assign the address of zero.
339;
340; Look for 'clname BS3FLAT segaddr=0x0000' and 'segment BS3FLAT segaddr=0x0000'
341; in the makefile.
342;
343; !!HACK ALERT!!
344segment BS3FLAT use32 class=BS3FLAT
345GROUP FLAT BS3FLAT
346%endif
347
348%macro BS3_BEGIN_TEXT16 0
349 %ifndef BS3_BEGIN_TEXT16_NOT_FIRST
350 %define BS3_BEGIN_TEXT16_NOT_FIRST
351 %ifdef ASM_FORMAT_ELF
352 section BS3TEXT16 align=2 progbits alloc exec nowrite
353 %else
354 section BS3TEXT16 align=2 CLASS=BS3CLASS16CODE PUBLIC USE16
355 %endif
356 %else
357 section BS3TEXT16
358 %endif
359 BS3_SET_BITS 16
360%endmacro
361
362%macro BS3_BEGIN_DATA16 0
363 %ifndef BS3_BEGIN_DATA16_NOT_FIRST
364 %define BS3_BEGIN_DATA16_NOT_FIRST
365 %ifdef ASM_FORMAT_ELF
366 section BS3DATA16 align=2 progbits alloc noexec write
367 %else
368 section BS3DATA16 align=2 CLASS=FAR_DATA PUBLIC USE16
369 %endif
370 %else
371 section BS3DATA16
372 %endif
373 BS3_SET_BITS 16
374%endmacro
375
376%macro BS3_BEGIN_TEXT32 0
377 %ifndef BS3_BEGIN_TEXT32_NOT_FIRST
378 %define BS3_BEGIN_TEXT32_NOT_FIRST
379 %ifdef ASM_FORMAT_ELF
380 section BS3TEXT32 align=1 progbits alloc exec nowrite
381 %else
382 section BS3TEXT32 align=1 CLASS=BS3CLASS32CODE PUBLIC USE32 FLAT
383 %endif
384 %else
385 section BS3TEXT32
386 %endif
387 BS3_SET_BITS 32
388%endmacro
389
390%macro BS3_BEGIN_DATA32 0
391 %ifndef BS3_BEGIN_DATA32_NOT_FIRST
392 %define BS3_BEGIN_DATA32_NOT_FIRST
393 %ifdef ASM_FORMAT_ELF
394 section BS3DATA32 align=16 progbits alloc noexec write
395 %else
396 section BS3DATA32 align=16 CLASS=FAR_DATA PUBLIC USE32 ;FLAT - compiler doesn't make data flat.
397 %endif
398 %else
399 section BS3DATA32
400 %endif
401 BS3_SET_BITS 32
402%endmacro
403
404%macro BS3_BEGIN_TEXT64 0
405 %ifndef BS3_BEGIN_TEXT64_NOT_FIRST
406 %define BS3_BEGIN_TEXT64_NOT_FIRST
407 %ifdef ASM_FORMAT_ELF
408 section BS3TEXT64 align=1 progbits alloc exec nowrite
409 %else
410 section BS3TEXT64 align=1 CLASS=BS3CLASS64CODE PUBLIC USE32 FLAT
411 %endif
412 %else
413 section BS3TEXT64
414 %endif
415 BS3_SET_BITS 64
416%endmacro
417
418%macro BS3_BEGIN_DATA64 0
419 %ifndef BS3_BEGIN_DATA64_NOT_FIRST
420 %define BS3_BEGIN_DATA64_NOT_FIRST
421 %ifdef ASM_FORMAT_ELF
422 section BS3DATA64 align=16 progbits alloc noexec write
423 %else
424 section BS3DATA64 align=16 CLASS=FAR_DATA PUBLIC USE32 ;FLAT (see DATA32)
425 %endif
426 %else
427 section BS3DATA64
428 %endif
429 BS3_SET_BITS 64
430%endmacro
431
432;; The system data segment containing the GDT, TSSes and IDTs.
433%macro BS3_BEGIN_SYSTEM16 0
434 %ifndef BS3_BEGIN_SYSTEM16_NOT_FIRST
435 %define BS3_BEGIN_SYSTEM16_NOT_FIRST
436 %ifdef ASM_FORMAT_ELF
437 section BS3SYSTEM16 align=16 progbits alloc noexec write
438 %else
439 section BS3SYSTEM16 align=16 CLASS=BS3SYSTEM16 PUBLIC USE16
440 %endif
441 %else
442 section BS3SYSTEM16
443 %endif
444 BS3_SET_BITS 16
445%endmacro
446
447;; Default text section.
448%macro BS3_BEGIN_DEFAULT_TEXT 0
449 %if ARCH_BITS == 16
450 BS3_BEGIN_TEXT16
451 %elif ARCH_BITS == 32
452 BS3_BEGIN_TEXT32
453 %elif ARCH_BITS == 64
454 BS3_BEGIN_TEXT64
455 %else
456 %error "ARCH_BITS must be defined as either 16, 32, or 64!"
457 INVALID_ARCH_BITS
458 %endif
459%endmacro
460
461;; @}
462
463
464;
465; Now, ditch the default 'text' section and define our own NAME macro.
466;
467%ifndef ASM_FORMAT_BIN
468 BS3_BEGIN_DEFAULT_TEXT
469 BS3_BEGIN_DEFAULT_TEXT ; stupid nasm automagically repeats the segment attributes.
470%endif
471
472;; When using watcom + OMF, we're using __cdecl by default, which
473; get an underscore added in front.
474%ifdef ASM_FORMAT_OMF
475 %define NAME(name) _ %+ NAME_OVERLOAD(name)
476%endif
477
478
479;
480; Include the standard headers from iprt.
481;
482
483
484%include "iprt/asmdefs.mac"
485%include "iprt/x86.mac"
486
487
488;;
489; Extern macro which mangles the name using NAME().
490%macro EXTERN 1
491 extern NAME(%1)
492%endmacro
493
494;;
495; Mangles a common name according to the current cpu bit count.
496; @remarks Requires the use of the BS3_SET_BITS macro instead of the BITS directive.
497%define BS3_CMN_NM(a_Name) BS3_NAME_UNDERSCORE %+ a_Name %+ _c %+ __BITS__
498
499;;
500; Extern macro which mangles the common name correctly, redefining the unmangled
501; name to the mangled one for ease of use.
502;
503; @param %1 The unmangled common name.
504;
505; @remarks Must enter the segment in which this name is defined.
506;
507%macro BS3_EXTERN_CMN 1
508 extern BS3_CMN_NM(%1)
509 %undef %1
510 %define %1 BS3_CMN_NM(%1)
511%endmacro
512
513;; @def BS3_EXTERN_TMPL
514; Mangles the given name into a template specific one. For ease of use, the
515; name is redefined to the mangled one, just like BS3_EXTERN_CMN does.
516; @note Segment does not change.
517%macro BS3_EXTERN_TMPL 1
518 extern TMPL_NM(%1)
519 %undef %1
520 %define %1 TMPL_NM(%1)
521%endmacro
522
523
524;;
525; Mangles a 16-bit and 32-bit accessible data name.
526; @remarks Requires the use of the BS3_SET_BITS macro instead of the BITS directive.
527%define BS3_DATA_NM(a_Name) _ %+ a_Name
528
529;;
530; Extern macro which mangles a DATA16 symbol correctly, redefining the
531; unmangled name to the mangled one for ease of use.
532;
533; @param %1 The unmangled common name.
534;
535; @remarks Will change to the DATA16 segment, use must switch back afterwards!
536;
537%macro BS3_EXTERN_DATA16 1
538 BS3_BEGIN_DATA16
539 extern _ %+ %1
540 %undef %1
541 %define %1 _ %+ %1
542%endmacro
543
544;;
545; Extern macro which mangles a BS3SYSTEM16 symbol correctly, redefining the
546; unmangled name to the mangled one for ease of use.
547;
548; @param %1 The unmangled common name.
549;
550; @remarks Will change to the SYSTEM16 segment, use must switch back afterwards!
551;
552%macro BS3_EXTERN_SYSTEM16 1
553 BS3_BEGIN_SYSTEM16
554 extern _ %+ %1
555 %undef %1
556 %define %1 _ %+ %1
557%endmacro
558
559
560;;
561; Global name with ELF attributes and size.
562;
563; This differs from GLOBALNAME_EX in that it expects a mangled symbol name,
564; and allows for nasm style symbol size expressions.
565;
566; @param %1 The mangled name.
567; @param %2 Symbol attributes.
568; @param %3 The size expression.
569;
570%macro BS3_GLOBAL_NAME_EX 3
571%ifdef ASM_FORMAT_ELF
572 %ifdef __NASM__
573global %1:%2 %3
574 %else
575global %1:%2
576 %endif
577%else
578global %1
579%endif
580%1:
581%endmacro
582
583;;
584; Global data unmangled label.
585;
586; @param %1 The unmangled name.
587; @param %2 The size (0 is fine).
588;
589%macro BS3_GLOBAL_DATA 2
590BS3_GLOBAL_NAME_EX BS3_DATA_NM(%1), , %2
591%endmacro
592
593;;
594; Starts a procedure.
595;
596; This differs from BEGINPROC in that it expects a mangled symbol name and
597; does the NASM symbol size stuff.
598;
599; @param %1 The mangled name.
600;
601%macro BS3_PROC_BEGIN 1
602%if __BITS__ == 64
603 BS3_GLOBAL_NAME_EX _ %+ %1, function, (_ %+ %1 %+ _EndProc - %1)
604%endif
605BS3_GLOBAL_NAME_EX %1, function, (%1 %+ _EndProc - %1)
606%endmacro
607
608;;
609; Ends a procedure.
610;
611; Counter part to BS3_PROC_BEGIN.
612;
613; @param %1 The mangled name.
614;
615%macro BS3_PROC_END 1
616BS3_GLOBAL_NAME_EX %1 %+ _EndProc, function hidden, (%1 %+ _EndProc - %1)
617 %ifdef ASM_FORMAT_ELF
618 %ifdef __YASM__
619size %1 %1 %+ _EndProc - %1
620size %1 %+ _EndProc 0
621 %endif
622 %endif
623 int3 ; handy and avoids overlapping labels.
624%endmacro
625
626
627;; Convenience macro for defining common procedures.
628%macro BS3_PROC_BEGIN_CMN 1
629 BS3_PROC_BEGIN BS3_CMN_NM(%1)
630%endmacro
631
632;; Convenience macro for defining common procedures.
633%macro BS3_PROC_END_CMN 1
634 BS3_PROC_END BS3_CMN_NM(%1)
635%endmacro
636
637
638;; Convenience macro for defining mode specific procedures.
639%macro BS3_PROC_BEGIN_MODE 1
640 BS3_PROC_BEGIN TMPL_NM(%1)
641%endmacro
642
643;; Convenience macro for defining mode specific procedures.
644%macro BS3_PROC_END_MODE 1
645 BS3_PROC_END TMPL_NM(%1)
646%endmacro
647
648
649;;
650; Prologue hacks for 64-bit code.
651;
652; This saves the four register parameters onto the stack so we can pretend
653; the calling convention is stack based. The 64-bit calling convension is
654; the microsoft one, so this is straight forward.
655;
656; Pairs with BS3_CALL_CONV_EPILOG.
657;
658; @param %1 The number of parameters.
659;
660; @remarks Must be invoked before any stack changing instructions are emitted.
661;
662%macro BS3_CALL_CONV_PROLOG 1
663 %undef BS3_CALL_CONV_PROLOG_PARAMS
664 %define BS3_CALL_CONV_PROLOG_PARAMS %1
665 %if __BITS__ == 64
666 %if %1 >= 1
667 mov [rsp + 008h], rcx
668 %elifdef BS3_STRICT
669 and qword [rsp + 008h], 1
670 %endif
671 %if %1 >= 2
672 mov [rsp + 010h], rdx
673 %elifdef BS3_STRICT
674 and qword [rsp + 010h], 2
675 %endif
676 %if %1 >= 3
677 mov [rsp + 018h], r8
678 %elifdef BS3_STRICT
679 and qword [rsp + 018h], 3
680 %endif
681 %if %1 >= 4
682 mov [rsp + 020h], r9
683 %elifdef BS3_STRICT
684 and qword [rsp + 020h], 4
685 %endif
686 %endif
687%endmacro
688
689;;
690; Epilogue hacks for 64-bit code.
691;
692; Counter part to BS3_CALL_CONV_PROLOG.
693;
694; @param %1 The number of parameters.
695;
696; @remarks Must be invoked right before the return instruction as it uses RSP.
697;
698%macro BS3_CALL_CONV_EPILOG 1
699 %if BS3_CALL_CONV_PROLOG_PARAMS != %1
700 %error "BS3_CALL_CONV_EPILOG argument differs from BS3_CALL_CONV_PROLOG."
701 %endif
702 %if __BITS__ == 64
703 %ifdef BS3_STRICT
704 mov dword [rsp + 008h], 31h
705 mov dword [rsp + 010h], 32h
706 mov dword [rsp + 018h], 33h
707 mov dword [rsp + 020h], 34h
708 %endif
709 %endif
710%endmacro
711
712;;
713; Wrapper for the call instruction that hides calling convension differences.
714;
715; This always calls %1.
716; In 64-bit code, it will load up to 4 parameters into register.
717;
718; @param %1 The function to call (mangled).
719; @param %2 The number of parameters.
720;
721%macro BS3_CALL 2
722 %if __BITS__ == 64
723 %if %2 >= 1
724 mov rcx, [rsp]
725 %ifdef BS3_STRICT
726 and qword [rsp], 11h
727 %endif
728 %endif
729 %if %2 >= 2
730 mov rdx, [rsp + 008h]
731 %ifdef BS3_STRICT
732 and qword [rsp + 008h], 12h
733 %endif
734 %endif
735 %if %2 >= 3
736 mov r8, [rsp + 010h]
737 %ifdef BS3_STRICT
738 and qword [rsp + 010h], 13h
739 %endif
740 %endif
741 %if %2 >= 4
742 mov r9, [rsp + 018h]
743 %ifdef BS3_STRICT
744 and qword [rsp + 018h], 14h
745 %endif
746 %endif
747 %endif
748 call %1
749%endmacro
750
751
752;; @name Execution Modes
753; @{
754%define BS3_MODE_INVALID 000h
755%define BS3_MODE_RM 001h ;;< real mode.
756%define BS3_MODE_PE16 011h ;;< 16-bit protected mode kernel+tss, running 16-bit code, unpaged.
757%define BS3_MODE_PE16_32 012h ;;< 16-bit protected mode kernel+tss, running 32-bit code, unpaged.
758%define BS3_MODE_PE16_V86 013h ;;< 16-bit protected mode kernel+tss, running virtual 8086 mode code, unpaged.
759%define BS3_MODE_PE32 022h ;;< 32-bit protected mode kernel+tss, running 32-bit code, unpaged.
760%define BS3_MODE_PE32_16 021h ;;< 32-bit protected mode kernel+tss, running 16-bit code, unpaged.
761%define BS3_MODE_PEV86 023h ;;< 32-bit protected mode kernel+tss, running virtual 8086 mode code, unpaged.
762%define BS3_MODE_PP16 031h ;;< 16-bit protected mode kernel+tss, running 16-bit code, paged.
763%define BS3_MODE_PP16_32 032h ;;< 16-bit protected mode kernel+tss, running 32-bit code, paged.
764%define BS3_MODE_PP16_V86 033h ;;< 16-bit protected mode kernel+tss, running virtual 8086 mode code, paged.
765%define BS3_MODE_PP32 042h ;;< 32-bit protected mode kernel+tss, running 32-bit code, paged.
766%define BS3_MODE_PP32_16 041h ;;< 32-bit protected mode kernel+tss, running 16-bit code, paged.
767%define BS3_MODE_PPV86 043h ;;< 32-bit protected mode kernel+tss, running virtual 8086 mode code, paged.
768%define BS3_MODE_PAE16 051h ;;< 16-bit protected mode kernel+tss, running 16-bit code, PAE paging.
769%define BS3_MODE_PAE16_32 052h ;;< 16-bit protected mode kernel+tss, running 32-bit code, PAE paging.
770%define BS3_MODE_PAE16_V86 053h ;;< 16-bit protected mode kernel+tss, running virtual 8086 mode, PAE paging.
771%define BS3_MODE_PAE32 062h ;;< 32-bit protected mode kernel+tss, running 32-bit code, PAE paging.
772%define BS3_MODE_PAE32_16 061h ;;< 32-bit protected mode kernel+tss, running 16-bit code, PAE paging.
773%define BS3_MODE_PAEV86 063h ;;< 32-bit protected mode kernel+tss, running virtual 8086 mode, PAE paging.
774%define BS3_MODE_LM16 071h ;;< 16-bit long mode (paged), kernel+tss always 64-bit.
775%define BS3_MODE_LM32 072h ;;< 32-bit long mode (paged), kernel+tss always 64-bit.
776%define BS3_MODE_LM64 074h ;;< 64-bit long mode (paged), kernel+tss always 64-bit.
777
778%define BS3_MODE_CODE_MASK 00fh ;;< Running code mask.
779%define BS3_MODE_CODE_16 001h ;;< Running 16-bit code.
780%define BS3_MODE_CODE_32 002h ;;< Running 32-bit code.
781%define BS3_MODE_CODE_V86 003h ;;< Running 16-bit virtual 8086 code.
782%define BS3_MODE_CODE_64 004h ;;< Running 64-bit code.
783
784%define BS3_MODE_SYS_MASK 0f0h ;;< kernel+tss mask.
785%define BS3_MODE_SYS_RM 000h ;;< Real mode kernel+tss.
786%define BS3_MODE_SYS_PE16 010h ;;< 16-bit protected mode kernel+tss.
787%define BS3_MODE_SYS_PE32 020h ;;< 32-bit protected mode kernel+tss.
788%define BS3_MODE_SYS_PP16 030h ;;< 16-bit paged protected mode kernel+tss.
789%define BS3_MODE_SYS_PP32 040h ;;< 32-bit paged protected mode kernel+tss.
790%define BS3_MODE_SYS_PAE16 050h ;;< 16-bit PAE paged protected mode kernel+tss.
791%define BS3_MODE_SYS_PAE32 060h ;;< 32-bit PAE paged protected mode kernel+tss.
792%define BS3_MODE_SYS_LM 070h ;;< 64-bit (paged) long mode protected mode kernel+tss.
793
794;; Whether the mode has paging enabled.
795%define BS3_MODE_IS_PAGED(a_fMode) ((a_fMode) >= BS3_MODE_PP16)
796
797;; Whether the mode is running v8086 code.
798%define BS3_MODE_IS_V86(a_fMode) (((a_fMode) & BS3_MODE_CODE_MASK) == BS3_MODE_CODE_V86)
799;; Whether the we're executing in real mode or v8086 mode.
800%define BS3_MODE_IS_RM_OR_V86(a_fMode) ((a_fMode) == BS3_MODE_RM || BS3_MODE_IS_V86(a_fMode))
801;; Whether the mode is running 16-bit code, except v8086.
802%define BS3_MODE_IS_16BIT_CODE_NO_V86(a_fMode) (((a_fMode) & BS3_MODE_CODE_MASK) == BS3_MODE_CODE_16)
803;; Whether the mode is running 16-bit code (includes v8086).
804%define BS3_MODE_IS_16BIT_CODE(a_fMode) (BS3_MODE_IS_16BIT_CODE_NO_V86(a_fMode) || BS3_MODE_IS_V86(a_fMode))
805;; Whether the mode is running 32-bit code.
806%define BS3_MODE_IS_32BIT_CODE(a_fMode) (((a_fMode) & BS3_MODE_CODE_MASK) == BS3_MODE_CODE_32)
807;; Whether the mode is running 64-bit code.
808%define BS3_MODE_IS_64BIT_CODE(a_fMode) (((a_fMode) & BS3_MODE_CODE_MASK) == BS3_MODE_CODE_64)
809
810;; Whether the system is in real mode.
811%define BS3_MODE_IS_RM_SYS(a_fMode) (((a_fMode) & BS3_MODE_SYS_MASK) == BS3_MODE_SYS_RM)
812;; Whether the system is some 16-bit mode that isn't real mode.
813%define BS3_MODE_IS_16BIT_SYS_NO_RM(a_fMode) ( ((a_fMode) & BS3_MODE_SYS_MASK) == BS3_MODE_SYS_PE16 \
814 || ((a_fMode) & BS3_MODE_SYS_MASK) == BS3_MODE_SYS_PP16 \
815 || ((a_fMode) & BS3_MODE_SYS_MASK) == BS3_MODE_SYS_PAE16)
816;; Whether the system is some 16-bit mode (includes real mode).
817%define BS3_MODE_IS_16BIT_SYS(a_fMode) (BS3_MODE_IS_16BIT_SYS_NO_RM(a_fMode) || BS3_MODE_IS_RM_SYS(a_fMode))
818;; Whether the system is some 32-bit mode.
819%define BS3_MODE_IS_32BIT_SYS(a_fMode) ( ((a_fMode) & BS3_MODE_SYS_MASK) == BS3_MODE_SYS_PE32 \
820 || ((a_fMode) & BS3_MODE_SYS_MASK) == BS3_MODE_SYS_PP32 \
821 || ((a_fMode) & BS3_MODE_SYS_MASK) == BS3_MODE_SYS_PAE32)
822;; Whether the system is long mode.
823%define BS3_MODE_IS_64BIT_SYS(a_fMode) (((a_fMode) & BS3_MODE_SYS_MASK) == BS3_MODE_SYS_LM)
824
825;; @}
826
827;; @name For mode specfic lookups:
828;; %[BS3_MODE_NM %+ BS3_MODE_PE32](SomeBaseName)
829;; %[BS3_MODE_LNAME_ %+ TMPL_MODE]
830;; @{
831%define BS3_MODE_NM_001h(a_Name) _ %+ a_Name %+ _rm
832%define BS3_MODE_NM_011h(a_Name) _ %+ a_Name %+ _pe16
833%define BS3_MODE_NM_012h(a_Name) _ %+ a_Name %+ _pe16_32
834%define BS3_MODE_NM_013h(a_Name) _ %+ a_Name %+ _pe16_v86
835%define BS3_MODE_NM_022h(a_Name) _ %+ a_Name %+ _pe32
836%define BS3_MODE_NM_021h(a_Name) _ %+ a_Name %+ _pe32_16
837%define BS3_MODE_NM_023h(a_Name) _ %+ a_Name %+ _pev86
838%define BS3_MODE_NM_031h(a_Name) _ %+ a_Name %+ _pp16
839%define BS3_MODE_NM_032h(a_Name) _ %+ a_Name %+ _pp16_32
840%define BS3_MODE_NM_033h(a_Name) _ %+ a_Name %+ _pp16_v86
841%define BS3_MODE_NM_042h(a_Name) _ %+ a_Name %+ _pp32
842%define BS3_MODE_NM_041h(a_Name) _ %+ a_Name %+ _pp32_16
843%define BS3_MODE_NM_043h(a_Name) _ %+ a_Name %+ _ppv86
844%define BS3_MODE_NM_051h(a_Name) _ %+ a_Name %+ _pae16
845%define BS3_MODE_NM_052h(a_Name) _ %+ a_Name %+ _pae16_32
846%define BS3_MODE_NM_053h(a_Name) _ %+ a_Name %+ _pae16_v86
847%define BS3_MODE_NM_062h(a_Name) _ %+ a_Name %+ _pae32
848%define BS3_MODE_NM_061h(a_Name) _ %+ a_Name %+ _pae32_16
849%define BS3_MODE_NM_063h(a_Name) _ %+ a_Name %+ _paev86
850%define BS3_MODE_NM_071h(a_Name) _ %+ a_Name %+ _lm16
851%define BS3_MODE_NM_072h(a_Name) _ %+ a_Name %+ _lm32
852%define BS3_MODE_NM_074h(a_Name) a_Name %+ _lm64
853
854%define BS3_MODE_LNAME_001h rm
855%define BS3_MODE_LNAME_011h pe16
856%define BS3_MODE_LNAME_012h pe16_32
857%define BS3_MODE_LNAME_013h pe16_v86
858%define BS3_MODE_LNAME_022h pe32
859%define BS3_MODE_LNAME_021h pe32_16
860%define BS3_MODE_LNAME_023h pev86
861%define BS3_MODE_LNAME_031h pp16
862%define BS3_MODE_LNAME_032h pp16_32
863%define BS3_MODE_LNAME_033h pp16_v86
864%define BS3_MODE_LNAME_042h pp32
865%define BS3_MODE_LNAME_041h pp32_16
866%define BS3_MODE_LNAME_043h ppv86
867%define BS3_MODE_LNAME_051h pae16
868%define BS3_MODE_LNAME_052h pae16_32
869%define BS3_MODE_LNAME_053h pae16_v86
870%define BS3_MODE_LNAME_062h pae32
871%define BS3_MODE_LNAME_061h pae32_16
872%define BS3_MODE_LNAME_063h paev86
873%define BS3_MODE_LNAME_071h lm16
874%define BS3_MODE_LNAME_072h lm32
875%define BS3_MODE_LNAME_074h lm64
876
877%define BS3_MODE_UNAME_001h RM
878%define BS3_MODE_UNAME_011h PE16
879%define BS3_MODE_UNAME_012h PE16_32
880%define BS3_MODE_UNAME_013h PE16_V86
881%define BS3_MODE_UNAME_022h PE32
882%define BS3_MODE_UNAME_021h PE32_16
883%define BS3_MODE_UNAME_023h PEV86
884%define BS3_MODE_UNAME_031h PP16
885%define BS3_MODE_UNAME_032h PP16_32
886%define BS3_MODE_UNAME_033h PP16_V86
887%define BS3_MODE_UNAME_042h PP32
888%define BS3_MODE_UNAME_041h PP32_16
889%define BS3_MODE_UNAME_043h PPV86
890%define BS3_MODE_UNAME_051h PAE16
891%define BS3_MODE_UNAME_052h PAE16_32
892%define BS3_MODE_UNAME_053h PAE16_V86
893%define BS3_MODE_UNAME_062h PAE32
894%define BS3_MODE_UNAME_061h PAE32_16
895%define BS3_MODE_UNAME_063h PAEV86
896%define BS3_MODE_UNAME_071h LM16
897%define BS3_MODE_UNAME_072h LM32
898%define BS3_MODE_UNAME_074h LM64
899
900%define BS3_MODE_UNDERSCORE_001h _
901%define BS3_MODE_UNDERSCORE_011h _
902%define BS3_MODE_UNDERSCORE_012h _
903%define BS3_MODE_UNDERSCORE_013h _
904%define BS3_MODE_UNDERSCORE_022h _
905%define BS3_MODE_UNDERSCORE_021h _
906%define BS3_MODE_UNDERSCORE_023h _
907%define BS3_MODE_UNDERSCORE_031h _
908%define BS3_MODE_UNDERSCORE_032h _
909%define BS3_MODE_UNDERSCORE_033h _
910%define BS3_MODE_UNDERSCORE_042h _
911%define BS3_MODE_UNDERSCORE_041h _
912%define BS3_MODE_UNDERSCORE_043h _
913%define BS3_MODE_UNDERSCORE_051h _
914%define BS3_MODE_UNDERSCORE_052h _
915%define BS3_MODE_UNDERSCORE_053h _
916%define BS3_MODE_UNDERSCORE_062h _
917%define BS3_MODE_UNDERSCORE_061h _
918%define BS3_MODE_UNDERSCORE_063h _
919%define BS3_MODE_UNDERSCORE_071h _
920%define BS3_MODE_UNDERSCORE_072h _
921%define BS3_MODE_UNDERSCORE_074h
922
923%define BS3_MODE_CNAME_001h c16
924%define BS3_MODE_CNAME_011h c16
925%define BS3_MODE_CNAME_012h c32
926%define BS3_MODE_CNAME_013h c16
927%define BS3_MODE_CNAME_022h c32
928%define BS3_MODE_CNAME_021h c16
929%define BS3_MODE_CNAME_023h c16
930%define BS3_MODE_CNAME_031h c16
931%define BS3_MODE_CNAME_032h c32
932%define BS3_MODE_CNAME_033h c16
933%define BS3_MODE_CNAME_042h c32
934%define BS3_MODE_CNAME_041h c16
935%define BS3_MODE_CNAME_043h c16
936%define BS3_MODE_CNAME_051h c16
937%define BS3_MODE_CNAME_052h c32
938%define BS3_MODE_CNAME_053h c16
939%define BS3_MODE_CNAME_062h c32
940%define BS3_MODE_CNAME_061h c16
941%define BS3_MODE_CNAME_063h c16
942%define BS3_MODE_CNAME_071h c16
943%define BS3_MODE_CNAME_072h c32
944%define BS3_MODE_CNAME_074h c64
945;; @}
946
947;; @name For getting the ring-0 mode for v86 modes: %[BS3_MODE_R0_NM_001h %+ TMPL_MODE](Bs3SwitchToRM)
948;; @{
949%define BS3_MODE_R0_NM_001h(a_Name) _ %+ a_Name %+ _rm
950%define BS3_MODE_R0_NM_011h(a_Name) _ %+ a_Name %+ _pe16
951%define BS3_MODE_R0_NM_012h(a_Name) _ %+ a_Name %+ _pe16_32
952%define BS3_MODE_R0_NM_013h(a_Name) _ %+ a_Name %+ _pe16
953%define BS3_MODE_R0_NM_022h(a_Name) _ %+ a_Name %+ _pe32
954%define BS3_MODE_R0_NM_021h(a_Name) _ %+ a_Name %+ _pe32_16
955%define BS3_MODE_R0_NM_023h(a_Name) _ %+ a_Name %+ _pe32_16
956%define BS3_MODE_R0_NM_031h(a_Name) _ %+ a_Name %+ _pp16
957%define BS3_MODE_R0_NM_032h(a_Name) _ %+ a_Name %+ _pp16_32
958%define BS3_MODE_R0_NM_033h(a_Name) _ %+ a_Name %+ _pp16
959%define BS3_MODE_R0_NM_042h(a_Name) _ %+ a_Name %+ _pp32
960%define BS3_MODE_R0_NM_041h(a_Name) _ %+ a_Name %+ _pp32_16
961%define BS3_MODE_R0_NM_043h(a_Name) _ %+ a_Name %+ _pp32_16
962%define BS3_MODE_R0_NM_051h(a_Name) _ %+ a_Name %+ _pae16
963%define BS3_MODE_R0_NM_052h(a_Name) _ %+ a_Name %+ _pae16_32
964%define BS3_MODE_R0_NM_053h(a_Name) _ %+ a_Name %+ _pae16
965%define BS3_MODE_R0_NM_062h(a_Name) _ %+ a_Name %+ _pae32
966%define BS3_MODE_R0_NM_061h(a_Name) _ %+ a_Name %+ _pae32_16
967%define BS3_MODE_R0_NM_063h(a_Name) _ %+ a_Name %+ _pae32_16
968%define BS3_MODE_R0_NM_071h(a_Name) _ %+ a_Name %+ _lm16
969%define BS3_MODE_R0_NM_072h(a_Name) _ %+ a_Name %+ _lm32
970%define BS3_MODE_R0_NM_074h(a_Name) a_Name %+ _lm64
971;; @}
972
973
974;;
975; Includes the file %1 with TMPL_MODE set to all possible value.
976; @param 1 Double quoted include file name.
977%macro BS3_INSTANTIATE_TEMPLATE_WITH_WEIRD_ONES 1
978 %define TMPL_MODE BS3_MODE_RM
979 %include %1
980
981 %define TMPL_MODE BS3_MODE_PE16
982 %include %1
983 %define TMPL_MODE BS3_MODE_PE16_32
984 %include %1
985 %define TMPL_MODE BS3_MODE_PE16_V86
986 %include %1
987
988 %define TMPL_MODE BS3_MODE_PE32
989 %include %1
990 %define TMPL_MODE BS3_MODE_PE32_16
991 %include %1
992 %define TMPL_MODE BS3_MODE_PEV86
993 %include %1
994
995 %define TMPL_MODE BS3_MODE_PP16
996 %include %1
997 %define TMPL_MODE BS3_MODE_PP16_32
998 %include %1
999 %define TMPL_MODE BS3_MODE_PP16_V86
1000 %include %1
1001
1002 %define TMPL_MODE BS3_MODE_PP32
1003 %include %1
1004 %define TMPL_MODE BS3_MODE_PP32_16
1005 %include %1
1006 %define TMPL_MODE BS3_MODE_PPV86
1007 %include %1
1008
1009 %define TMPL_MODE BS3_MODE_PAE16
1010 %include %1
1011 %define TMPL_MODE BS3_MODE_PAE16_32
1012 %include %1
1013 %define TMPL_MODE BS3_MODE_PAE16_V86
1014 %include %1
1015
1016 %define TMPL_MODE BS3_MODE_PAE32
1017 %include %1
1018 %define TMPL_MODE BS3_MODE_PAE32_16
1019 %include %1
1020 %define TMPL_MODE BS3_MODE_PAEV86
1021 %include %1
1022
1023 %define TMPL_MODE BS3_MODE_LM16
1024 %include %1
1025 %define TMPL_MODE BS3_MODE_LM32
1026 %include %1
1027 %define TMPL_MODE BS3_MODE_LM64
1028 %include %1
1029%endmacro
1030
1031
1032;;
1033; Includes the file %1 with TMPL_MODE set to all but the "weird" value.
1034; @param 1 Double quoted include file name.
1035%macro BS3_INSTANTIATE_TEMPLATE_ESSENTIALS 1
1036 %define TMPL_MODE BS3_MODE_RM
1037 %include %1
1038
1039 %define TMPL_MODE BS3_MODE_PE16
1040 %include %1
1041
1042 %define TMPL_MODE BS3_MODE_PE32
1043 %include %1
1044 %define TMPL_MODE BS3_MODE_PEV86
1045 %include %1
1046
1047 %define TMPL_MODE BS3_MODE_PP16
1048 %include %1
1049
1050 %define TMPL_MODE BS3_MODE_PP32
1051 %include %1
1052 %define TMPL_MODE BS3_MODE_PPV86
1053 %include %1
1054
1055 %define TMPL_MODE BS3_MODE_PAE16
1056 %include %1
1057
1058 %define TMPL_MODE BS3_MODE_PAE32
1059 %include %1
1060 %define TMPL_MODE BS3_MODE_PAEV86
1061 %include %1
1062
1063 %define TMPL_MODE BS3_MODE_LM16
1064 %include %1
1065 %define TMPL_MODE BS3_MODE_LM32
1066 %include %1
1067 %define TMPL_MODE BS3_MODE_LM64
1068 %include %1
1069%endmacro
1070
1071;;
1072; Includes the file %1 with TMPL_MODE set to a 16-bit, a 32-bit and a 64-bit value.
1073; @param 1 Double quoted include file name.
1074%macro BS3_INSTANTIATE_COMMON_TEMPLATE 1
1075 %define TMPL_MODE BS3_MODE_RM
1076 %include %1
1077 %define TMPL_MODE BS3_MODE_PE32
1078 %include %1
1079 %define TMPL_MODE BS3_MODE_LM64
1080 %include %1
1081%endmacro
1082
1083
1084;; @name Static Memory Allocation
1085; @{
1086;; The flat load address for the code after the bootsector.
1087%define BS3_ADDR_LOAD 010000h
1088;; Where we save the boot registers during init.
1089; Located right before the code.
1090%define BS3_ADDR_REG_SAVE (BS3_ADDR_LOAD - BS3REGCTX_size - 8)
1091;; Where the stack starts (initial RSP value).
1092; Located 16 bytes (assumed by boot sector) before the saved registers. SS.BASE=0.
1093%define BS3_ADDR_STACK (BS3_ADDR_REG_SAVE - 16)
1094;; The ring-0 stack (8KB) for ring transitions.
1095%define BS3_ADDR_STACK_R0 006000h
1096;; The ring-1 stack (8KB) for ring transitions.
1097%define BS3_ADDR_STACK_R1 004000h
1098;; The ring-2 stack (8KB) for ring transitions.
1099%define BS3_ADDR_STACK_R2 002000h
1100;; IST1 ring-0 stack for long mode (4KB), used for double faults elsewhere.
1101%define BS3_ADDR_STACK_R0_IST1 009000h
1102;; IST2 ring-0 stack for long mode (3KB), used for spare 0 stack elsewhere.
1103%define BS3_ADDR_STACK_R0_IST2 008000h
1104;; IST3 ring-0 stack for long mode (1KB).
1105%define BS3_ADDR_STACK_R0_IST3 007400h
1106;; IST4 ring-0 stack for long mode (1KB), used for spare 1 stack elsewhere.
1107%define BS3_ADDR_STACK_R0_IST4 007000h
1108;; IST5 ring-0 stack for long mode (1KB).
1109%define BS3_ADDR_STACK_R0_IST5 006c00h
1110;; IST6 ring-0 stack for long mode (1KB).
1111%define BS3_ADDR_STACK_R0_IST6 006800h
1112;; IST7 ring-0 stack for long mode (1KB).
1113%define BS3_ADDR_STACK_R0_IST7 006400h
1114
1115;; The base address of the BS3TEXT16 segment (same as BS3_LOAD_ADDR).
1116;; @sa BS3_SEL_TEXT16
1117%define BS3_ADDR_BS3TEXT16 010000h
1118;; The base address of the BS3SYSTEM16 segment.
1119;; @sa BS3_SEL_SYSTEM16
1120%define BS3_ADDR_BS3SYSTEM16 020000h
1121;; The base address of the BS3DATA16 segment.
1122;; @sa BS3_SEL_DATA16
1123%define BS3_ADDR_BS3DATA16 027000h
1124;; @}
1125
1126
1127;;
1128; BS3 register context. Used by traps and such.
1129;
1130struc BS3REGCTX
1131 .rax resq 1 ; BS3REG rax; /**< 0x00 */
1132 .rcx resq 1 ; BS3REG rcx; /**< 0x08 */
1133 .rdx resq 1 ; BS3REG rdx; /**< 0x10 */
1134 .rbx resq 1 ; BS3REG rbx; /**< 0x18 */
1135 .rsp resq 1 ; BS3REG rsp; /**< 0x20 */
1136 .rbp resq 1 ; BS3REG rbp; /**< 0x28 */
1137 .rsi resq 1 ; BS3REG rsi; /**< 0x30 */
1138 .rdi resq 1 ; BS3REG rdi; /**< 0x38 */
1139 .r8 resq 1 ; BS3REG r8; /**< 0x40 */
1140 .r9 resq 1 ; BS3REG r9; /**< 0x48 */
1141 .r10 resq 1 ; BS3REG r10; /**< 0x50 */
1142 .r11 resq 1 ; BS3REG r11; /**< 0x58 */
1143 .r12 resq 1 ; BS3REG r12; /**< 0x60 */
1144 .r13 resq 1 ; BS3REG r13; /**< 0x68 */
1145 .r14 resq 1 ; BS3REG r14; /**< 0x70 */
1146 .r15 resq 1 ; BS3REG r15; /**< 0x78 */
1147 .rflags resq 1 ; BS3REG rflags; /**< 0x80 */
1148 .rip resq 1 ; BS3REG rip; /**< 0x88 */
1149 .cs resw 1 ; uint16_t cs; /**< 0x90 */
1150 .ds resw 1 ; uint16_t ds; /**< 0x92 */
1151 .es resw 1 ; uint16_t es; /**< 0x94 */
1152 .fs resw 1 ; uint16_t fs; /**< 0x96 */
1153 .gs resw 1 ; uint16_t gs; /**< 0x98 */
1154 .ss resw 1 ; uint16_t ss; /**< 0x9a */
1155 .tr resw 1 ; uint16_t tr; /**< 0x9c */
1156 .ldtr resw 1 ; uint16_t ldtr; /**< 0x9e */
1157 .bMode resb 1 ; uint8_t bMode; /**< 0xa0: BS3_MODE_XXX. */
1158 .bCpl resb 1 ; uint8_t bCpl; /**< 0xa1: 0-3, 0 is used for real mode. */
1159 .abPadding resb 6 ; uint8_t abPadding[6]; /**< 0xa2 */
1160 .cr0 resq 1 ; BS3REG cr0; /**< 0xa8 */
1161 .cr2 resq 1 ; BS3REG cr2; /**< 0xb0 */
1162 .cr3 resq 1 ; BS3REG cr3; /**< 0xb8 */
1163 .cr4 resq 1 ; BS3REG cr4; /**< 0xc0 */
1164endstruc
1165
1166;;
1167; BS3 Trap Frame.
1168;
1169struc BS3TRAPFRAME
1170 .bXcpt resb 1
1171 .bAlignment resb 1
1172 .uHandlerCs resw 1
1173 .uHandlerSs resw 1
1174 .usAlignment resw 1
1175 .uHandlerRsp resq 1
1176 .fHandlerRfl resq 1
1177 .uErrCd resq 1
1178 .Ctx resb BS3REGCTX_size
1179endstruc
1180
1181;; Flag for Bs3TrapXxResumeFrame methods.
1182%define BS3TRAPRESUME_F_SKIP_CRX 1
1183
1184
1185;;
1186; Trap record.
1187;
1188struc BS3TRAPREC
1189 ;; The trap location relative to the base address given at
1190 ; registration time.
1191 .offWhere resd 1
1192 ;; What to add to .offWhere to calculate the resume address.
1193 .offResumeAddend resb 1
1194 ;; The trap number.
1195 .u8TrapNo resb 1
1196 ;; The error code if the trap takes one.
1197 .u16ErrCd resw 1
1198endstruc
1199
1200;; The size shift.
1201%define BS3TRAPREC_SIZE_SHIFT 3
1202
1203
1204;; The system call vector.
1205%define BS3_TRAP_SYSCALL 20h
1206
1207;; @name System call numbers (ax)
1208;; @{
1209;; Print char (cl).
1210%define BS3_SYSCALL_PRINT_CHR 0001h
1211;; Print string (pointer in ds:[e]si, length in cx).
1212%define BS3_SYSCALL_PRINT_STR 0002h
1213;; Switch to ring-0.
1214%define BS3_SYSCALL_TO_RING0 0003h
1215;; Switch to ring-1.
1216%define BS3_SYSCALL_TO_RING1 0004h
1217;; Switch to ring-2.
1218%define BS3_SYSCALL_TO_RING2 0005h
1219;; Switch to ring-3.
1220%define BS3_SYSCALL_TO_RING3 0006h
1221;; The last system call value.
1222%define BS3_SYSCALL_LAST BS3_SYSCALL_TO_RING3
1223;; @}
1224
1225
1226
1227;; @name BS3_SEL_XXX - GDT selectors
1228;; @{
1229
1230%define BS3_SEL_LDT 0010h ;;< The LDT selector (requires setting up).
1231%define BS3_SEL_TSS16 0020h ;;< The 16-bit TSS selector.
1232%define BS3_SEL_TSS16_DF 0028h ;;< The 16-bit TSS selector for double faults.
1233%define BS3_SEL_TSS16_SPARE0 0030h ;;< The 16-bit TSS selector for testing.
1234%define BS3_SEL_TSS16_SPARE1 0038h ;;< The 16-bit TSS selector for testing.
1235%define BS3_SEL_TSS32 0040h ;;< The 32-bit TSS selector.
1236%define BS3_SEL_TSS32_DF 0048h ;;< The 32-bit TSS selector for double faults.
1237%define BS3_SEL_TSS32_SPARE0 0050h ;;< The 32-bit TSS selector for testing.
1238%define BS3_SEL_TSS32_SPARE1 0058h ;;< The 32-bit TSS selector for testing.
1239%define BS3_SEL_TSS32_IOBP_IRB 0060h ;;< The 32-bit TSS selector with I/O permission and interrupt redirection bitmaps.
1240%define BS3_SEL_TSS32_IRB 0068h ;;< The 32-bit TSS selector with only interrupt redirection bitmap (IOPB stripped by limit).
1241%define BS3_SEL_TSS64 0070h ;;< The 64-bit TSS selector.
1242%define BS3_SEL_TSS64_SPARE0 0080h ;;< The 64-bit TSS selector.
1243%define BS3_SEL_TSS64_SPARE1 0090h ;;< The 64-bit TSS selector.
1244%define BS3_SEL_TSS64_IOBP 00a0h ;;< The 64-bit TSS selector.
1245
1246%define BS3_SEL_VMMDEV_MMIO16 00f8h ;;< Selector for accessing the VMMDev MMIO segment at 0100000h from 16-bit code.
1247
1248%define BS3_SEL_RING_SHIFT 8 ;;< For the formula: BS3_SEL_R0_XXX + ((cs & 3) << BS3_SEL_RING_SHIFT)
1249
1250%define BS3_SEL_R0_FIRST 0100h ;;< The first selector in the ring-0 block.
1251%define BS3_SEL_R0_CS16 0100h ;;< ring-0: 16-bit code selector, base 0x10000.
1252%define BS3_SEL_R0_DS16 0108h ;;< ring-0: 16-bit data selector, base 0x23000.
1253%define BS3_SEL_R0_SS16 0110h ;;< ring-0: 16-bit stack selector, base 0x00000.
1254%define BS3_SEL_R0_CS32 0118h ;;< ring-0: 32-bit flat code selector.
1255%define BS3_SEL_R0_DS32 0120h ;;< ring-0: 32-bit flat data selector.
1256%define BS3_SEL_R0_SS32 0128h ;;< ring-0: 32-bit flat stack selector.
1257%define BS3_SEL_R0_CS64 0130h ;;< ring-0: 64-bit flat code selector.
1258%define BS3_SEL_R0_DS64 0138h ;;< ring-0: 64-bit flat data & stack selector.
1259%define BS3_SEL_R0_CS16_EO 0140h ;;< ring-0: 16-bit execute-only code selector, not accessed, 0xfffe limit, CS16 base.
1260%define BS3_SEL_R0_CS16_CNF 0148h ;;< ring-0: 16-bit conforming code selector, not accessed, 0xfffe limit, CS16 base.
1261%define BS3_SEL_R0_CS16_CNF_EO 0150h ;;< ring-0: 16-bit execute-only conforming code selector, not accessed, 0xfffe limit, CS16 base.
1262%define BS3_SEL_R0_CS32_EO 0158h ;;< ring-0: 32-bit execute-only code selector, not accessed, flat.
1263%define BS3_SEL_R0_CS32_CNF 0160h ;;< ring-0: 32-bit conforming code selector, not accessed, flat.
1264%define BS3_SEL_R0_CS32_CNF_EO 0168h ;;< ring-0: 32-bit execute-only conforming code selector, not accessed, flat.
1265%define BS3_SEL_R0_CS64_EO 0170h ;;< ring-0: 64-bit execute-only code selector, not accessed, flat.
1266%define BS3_SEL_R0_CS64_CNF 0178h ;;< ring-0: 64-bit conforming code selector, not accessed, flat.
1267%define BS3_SEL_R0_CS64_CNF_EO 0180h ;;< ring-0: 64-bit execute-only conforming code selector, not accessed, flat.
1268
1269%define BS3_SEL_R1_FIRST 0200h ;;< The first selector in the ring-1 block.
1270%define BS3_SEL_R1_CS16 0200h ;;< ring-1: 16-bit code selector, base 0x10000.
1271%define BS3_SEL_R1_DS16 0208h ;;< ring-1: 16-bit data selector, base 0x23000.
1272%define BS3_SEL_R1_SS16 0210h ;;< ring-1: 16-bit stack selector, base 0x00000.
1273%define BS3_SEL_R1_CS32 0218h ;;< ring-1: 32-bit flat code selector.
1274%define BS3_SEL_R1_DS32 0220h ;;< ring-1: 32-bit flat data selector.
1275%define BS3_SEL_R1_SS32 0228h ;;< ring-1: 32-bit flat stack selector.
1276%define BS3_SEL_R1_CS64 0230h ;;< ring-1: 64-bit flat code selector.
1277%define BS3_SEL_R1_DS64 0238h ;;< ring-1: 64-bit flat data & stack selector.
1278%define BS3_SEL_R1_CS16_EO 0240h ;;< ring-1: 16-bit execute-only code selector, not accessed, 0xfffe limit, CS16 base.
1279%define BS3_SEL_R1_CS16_CNF 0248h ;;< ring-1: 16-bit conforming code selector, not accessed, 0xfffe limit, CS16 base.
1280%define BS3_SEL_R1_CS16_CNF_EO 0250h ;;< ring-1: 16-bit execute-only conforming code selector, not accessed, 0xfffe limit, CS16 base.
1281%define BS3_SEL_R1_CS32_EO 0258h ;;< ring-1: 32-bit execute-only code selector, not accessed, flat.
1282%define BS3_SEL_R1_CS32_CNF 0260h ;;< ring-1: 32-bit conforming code selector, not accessed, flat.
1283%define BS3_SEL_R1_CS32_CNF_EO 0268h ;;< ring-1: 32-bit execute-only conforming code selector, not accessed, flat.
1284%define BS3_SEL_R1_CS64_EO 0270h ;;< ring-1: 64-bit execute-only code selector, not accessed, flat.
1285%define BS3_SEL_R1_CS64_CNF 0278h ;;< ring-1: 64-bit conforming code selector, not accessed, flat.
1286%define BS3_SEL_R1_CS64_CNF_EO 0280h ;;< ring-1: 64-bit execute-only conforming code selector, not accessed, flat.
1287
1288%define BS3_SEL_R2_FIRST 0300h ;;< The first selector in the ring-2 block.
1289%define BS3_SEL_R2_CS16 0300h ;;< ring-2: 16-bit code selector, base 0x10000.
1290%define BS3_SEL_R2_DS16 0308h ;;< ring-2: 16-bit data selector, base 0x23000.
1291%define BS3_SEL_R2_SS16 0310h ;;< ring-2: 16-bit stack selector, base 0x00000.
1292%define BS3_SEL_R2_CS32 0318h ;;< ring-2: 32-bit flat code selector.
1293%define BS3_SEL_R2_DS32 0320h ;;< ring-2: 32-bit flat data selector.
1294%define BS3_SEL_R2_SS32 0328h ;;< ring-2: 32-bit flat stack selector.
1295%define BS3_SEL_R2_CS64 0330h ;;< ring-2: 64-bit flat code selector.
1296%define BS3_SEL_R2_DS64 0338h ;;< ring-2: 64-bit flat data & stack selector.
1297%define BS3_SEL_R2_CS16_EO 0340h ;;< ring-2: 16-bit execute-only code selector, not accessed, 0xfffe limit, CS16 base.
1298%define BS3_SEL_R2_CS16_CNF 0348h ;;< ring-2: 16-bit conforming code selector, not accessed, 0xfffe limit, CS16 base.
1299%define BS3_SEL_R2_CS16_CNF_EO 0350h ;;< ring-2: 16-bit execute-only conforming code selector, not accessed, 0xfffe limit, CS16 base.
1300%define BS3_SEL_R2_CS32_EO 0358h ;;< ring-2: 32-bit execute-only code selector, not accessed, flat.
1301%define BS3_SEL_R2_CS32_CNF 0360h ;;< ring-2: 32-bit conforming code selector, not accessed, flat.
1302%define BS3_SEL_R2_CS32_CNF_EO 0368h ;;< ring-2: 32-bit execute-only conforming code selector, not accessed, flat.
1303%define BS3_SEL_R2_CS64_EO 0370h ;;< ring-2: 64-bit execute-only code selector, not accessed, flat.
1304%define BS3_SEL_R2_CS64_CNF 0378h ;;< ring-2: 64-bit conforming code selector, not accessed, flat.
1305%define BS3_SEL_R2_CS64_CNF_EO 0380h ;;< ring-2: 64-bit execute-only conforming code selector, not accessed, flat.
1306
1307%define BS3_SEL_R3_FIRST 0400h ;;< The first selector in the ring-3 block.
1308%define BS3_SEL_R3_CS16 0400h ;;< ring-3: 16-bit code selector, base 0x10000.
1309%define BS3_SEL_R3_DS16 0408h ;;< ring-3: 16-bit data selector, base 0x23000.
1310%define BS3_SEL_R3_SS16 0410h ;;< ring-3: 16-bit stack selector, base 0x00000.
1311%define BS3_SEL_R3_CS32 0418h ;;< ring-3: 32-bit flat code selector.
1312%define BS3_SEL_R3_DS32 0420h ;;< ring-3: 32-bit flat data selector.
1313%define BS3_SEL_R3_SS32 0428h ;;< ring-3: 32-bit flat stack selector.
1314%define BS3_SEL_R3_CS64 0430h ;;< ring-3: 64-bit flat code selector.
1315%define BS3_SEL_R3_DS64 0438h ;;< ring-3: 64-bit flat data & stack selector.
1316%define BS3_SEL_R3_CS16_EO 0440h ;;< ring-3: 16-bit execute-only code selector, not accessed, 0xfffe limit, CS16 base.
1317%define BS3_SEL_R3_CS16_CNF 0448h ;;< ring-3: 16-bit conforming code selector, not accessed, 0xfffe limit, CS16 base.
1318%define BS3_SEL_R3_CS16_CNF_EO 0450h ;;< ring-3: 16-bit execute-only conforming code selector, not accessed, 0xfffe limit, CS16 base.
1319%define BS3_SEL_R3_CS32_EO 0458h ;;< ring-3: 32-bit execute-only code selector, not accessed, flat.
1320%define BS3_SEL_R3_CS32_CNF 0460h ;;< ring-3: 32-bit conforming code selector, not accessed, flat.
1321%define BS3_SEL_R3_CS32_CNF_EO 0468h ;;< ring-3: 32-bit execute-only conforming code selector, not accessed, flat.
1322%define BS3_SEL_R3_CS64_EO 0470h ;;< ring-3: 64-bit execute-only code selector, not accessed, flat.
1323%define BS3_SEL_R3_CS64_CNF 0478h ;;< ring-3: 64-bit conforming code selector, not accessed, flat.
1324%define BS3_SEL_R3_CS64_CNF_EO 0480h ;;< ring-3: 64-bit execute-only conforming code selector, not accessed, flat.
1325
1326%define BS3_SEL_SPARE_FIRST 0500h ;;< The first selector in the spare block
1327%define BS3_SEL_SPARE_00 0500h ;;< Spare selector number 00h.
1328%define BS3_SEL_SPARE_01 0508h ;;< Spare selector number 01h.
1329%define BS3_SEL_SPARE_02 0510h ;;< Spare selector number 02h.
1330%define BS3_SEL_SPARE_03 0518h ;;< Spare selector number 03h.
1331%define BS3_SEL_SPARE_04 0520h ;;< Spare selector number 04h.
1332%define BS3_SEL_SPARE_05 0528h ;;< Spare selector number 05h.
1333%define BS3_SEL_SPARE_06 0530h ;;< Spare selector number 06h.
1334%define BS3_SEL_SPARE_07 0538h ;;< Spare selector number 07h.
1335%define BS3_SEL_SPARE_08 0540h ;;< Spare selector number 08h.
1336%define BS3_SEL_SPARE_09 0548h ;;< Spare selector number 09h.
1337%define BS3_SEL_SPARE_0a 0550h ;;< Spare selector number 0ah.
1338%define BS3_SEL_SPARE_0b 0558h ;;< Spare selector number 0bh.
1339%define BS3_SEL_SPARE_0c 0560h ;;< Spare selector number 0ch.
1340%define BS3_SEL_SPARE_0d 0568h ;;< Spare selector number 0dh.
1341%define BS3_SEL_SPARE_0e 0570h ;;< Spare selector number 0eh.
1342%define BS3_SEL_SPARE_0f 0578h ;;< Spare selector number 0fh.
1343%define BS3_SEL_SPARE_10 0580h ;;< Spare selector number 10h.
1344%define BS3_SEL_SPARE_11 0588h ;;< Spare selector number 11h.
1345%define BS3_SEL_SPARE_12 0590h ;;< Spare selector number 12h.
1346%define BS3_SEL_SPARE_13 0598h ;;< Spare selector number 13h.
1347%define BS3_SEL_SPARE_14 05a0h ;;< Spare selector number 14h.
1348%define BS3_SEL_SPARE_15 05a8h ;;< Spare selector number 15h.
1349%define BS3_SEL_SPARE_16 05b0h ;;< Spare selector number 16h.
1350%define BS3_SEL_SPARE_17 05b8h ;;< Spare selector number 17h.
1351%define BS3_SEL_SPARE_18 05c0h ;;< Spare selector number 18h.
1352%define BS3_SEL_SPARE_19 05c8h ;;< Spare selector number 19h.
1353%define BS3_SEL_SPARE_1a 05d0h ;;< Spare selector number 1ah.
1354%define BS3_SEL_SPARE_1b 05d8h ;;< Spare selector number 1bh.
1355%define BS3_SEL_SPARE_1c 05e0h ;;< Spare selector number 1ch.
1356%define BS3_SEL_SPARE_1d 05e8h ;;< Spare selector number 1dh.
1357%define BS3_SEL_SPARE_1e 05f0h ;;< Spare selector number 1eh.
1358%define BS3_SEL_SPARE_1f 05f8h ;;< Spare selector number 1fh.
1359
1360%define BS3_SEL_TILED 0600h ;;< 16-bit data tiling: First - base=0x00000000, limit=64KB, DPL=3.
1361%define BS3_SEL_TILED_LAST 0df8h ;;< 16-bit data tiling: Last - base=0x00ff0000, limit=64KB, DPL=3.
1362%define BS3_SEL_TILED_AREA_SIZE 001000000h ;;< 16-bit data tiling: Size of addressable area, in bytes. (16 MB)
1363
1364%define BS3_SEL_FREE_PART1 0e00h ;;< Free selector space - part \%1.
1365%define BS3_SEL_FREE_PART1_LAST 0ff8h ;;< Free selector space - part \%1, last entry.
1366
1367%define BS3_SEL_TEXT16 1000h ;;< The BS3TEXT16 selector.
1368
1369%define BS3_SEL_FREE_PART2 1008h ;;< Free selector space - part \#2.
1370%define BS3_SEL_FREE_PART2_LAST 17f8h ;;< Free selector space - part \#2, last entry.
1371
1372%define BS3_SEL_TILED_R0 1800h ;;< 16-bit data/stack tiling: First - base=0x00000000, limit=64KB, DPL=0.
1373%define BS3_SEL_TILED_R0_LAST 1ff8h ;;< 16-bit data/stack tiling: Last - base=0x00ff0000, limit=64KB, DPL=0.
1374
1375%define BS3_SEL_SYSTEM16 2000h ;;< The BS3SYSTEM16 selector.
1376
1377%define BS3_SEL_FREE_PART3 2008h ;;< Free selector space - part \%3.
1378%define BS3_SEL_FREE_PART3_LAST 26f8h ;;< Free selector space - part \%3, last entry.
1379
1380%define BS3_SEL_DATA16 2700h ;;< The BS3DATA16 selector.
1381
1382%define BS3_SEL_GDT_LIMIT 2707h ;;< The GDT limit.
1383
1384;; @}
1385
1386
1387;
1388; Sanity checks.
1389;
1390%if BS3_ADDR_BS3TEXT16 != BS3_ADDR_LOAD
1391 %error "BS3_ADDR_BS3TEXT16 and BS3_ADDR_LOAD are out of sync"
1392%endif
1393%if (BS3_ADDR_BS3TEXT16 / 16) != BS3_SEL_TEXT16
1394 %error "BS3_ADDR_BS3TEXT16 and BS3_SEL_TEXT16 are out of sync"
1395%endif
1396%if (BS3_ADDR_BS3DATA16 / 16) != BS3_SEL_DATA16
1397 %error "BS3_ADDR_BS3DATA16 and BS3_SEL_DATA16 are out of sync"
1398%endif
1399%if (BS3_ADDR_BS3SYSTEM16 / 16) != BS3_SEL_SYSTEM16
1400 %error "BS3_ADDR_BS3SYSTEM16 and BS3_SEL_SYSTEM16 are out of sync"
1401%endif
1402
1403
1404;; @name BS3CPU_XXX - Bs3CpuDetect_mmm return value and g_bBs3CpuDetected.
1405;; @{
1406%define BS3CPU_8086 0x0001
1407%define BS3CPU_V20 0x0002
1408%define BS3CPU_80186 0x0003
1409%define BS3CPU_80286 0x0004
1410%define BS3CPU_80386 0x0005
1411%define BS3CPU_80486 0x0006
1412%define BS3CPU_Pentium 0x0007
1413%define BS3CPU_PPro 0x0008
1414%define BS3CPU_PProOrNewer 0x0009
1415%define BS3CPU_TYPE_MASK 0x00ff
1416%define BS3CPU_F_CPUID 0x0100
1417%define BS3CPU_F_CPUID_EXT_LEAVES 0x0200
1418%define BS3CPU_F_PAE 0x0400
1419%define BS3CPU_F_PAE_BIT 10
1420%define BS3CPU_F_LONG_MODE 0x0800
1421;; @}
1422
1423
1424%endif
1425
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