VirtualBox

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

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

bs3kit: Managed to link 16, 32 and 64-bit C code into the same binary, where the 64-bit C code was produced by the microsoft compiler. That doesn't mean it actually works, but chances are high. Bad new though, no debug info. OTOH, a lot of the assembly code can be converted to C, which is faster and safer than adjusting it to the new calling convensions.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.2 KB
Line 
1; $Id: bs3kit.mac 58628 2015-11-10 01:25:13Z 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;; Wrapper around BITS.
36; Updates __BITS__ (built-in variable in nasm, we work it for yasm).
37; @param %1 The CPU bit count: 16, 32 or 64
38; @remarks ARCH_BITS is not modified and will remain what it was on the
39; assembler command line.
40%macro BS3_SET_BITS 1
41 BITS %1
42
43 %ifdef __YASM__
44 %undef __BITS__
45 %define __BITS__ %1
46 %endif
47
48 %undef BS3_NAME_UNDERSCORE
49 %if %1 == 64
50 %define BS3_NAME_UNDERSCORE
51 %else
52 %define BS3_NAME_UNDERSCORE _
53 %endif
54
55 %undef BS3_ONLY_16BIT
56 %if %1 == 16
57 %define BS3_ONLY_16BIT(a_Expr) a_Expr
58 %else
59 %define BS3_ONLY_16BIT(a_Expr)
60 %endif
61
62 %undef BS3_WRT_RIP
63 %if %1 == 64
64 %define BS3_WRT_RIP wrt rip
65 %else
66 %define BS3_WRT_RIP
67 %endif
68%endmacro
69
70;; Emulate the __BITS__ macro in NASM 2.0+. Follows BS3_SET_BITS.
71%ifdef __YASM__
72 %define __BITS__ ARCH_BITS
73%endif
74
75;; Mostly internal macro. Follows BS3_SET_BITS.
76%if ARCH_BITS == 64
77 %define BS3_NAME_UNDERSCORE
78%else
79 %define BS3_NAME_UNDERSCORE _
80%endif
81
82;; For RIP relative addressing in 64-bit mode and absolute addressing in
83; other modes. Follows BS3_SET_BITS.
84%if ARCH_BITS == 64
85 %define BS3_WRT_RIP wrt rip
86%else
87 %define BS3_WRT_RIP
88%endif
89
90;; For segment overrides and stuff. Follows BS3_SET_BITS.
91%if ARCH_BITS == 16
92 %define BS3_ONLY_16BIT(a_Expr) a_Expr
93%else
94 %define BS3_ONLY_16BIT(a_Expr)
95%endif
96
97;;
98; For instruction that should only be emitted in 16-bit mode. Follows BS3_SET_BITS.
99%macro BS3_ONLY_16BIT_STMT 1+
100 %if __BITS__ == 16
101 %1
102 %endif
103%endmacro
104
105;;
106; For instruction that should only be emitted in 32-bit mode. Follows BS3_SET_BITS.
107%macro BS3_ONLY_32BIT_STMT 1+
108 %if __BITS__ == 32
109 %1
110 %endif
111%endmacro
112
113;;
114; For instruction that should only be emitted in 64-bit mode. Follows BS3_SET_BITS.
115%macro BS3_ONLY_64BIT_STMT 1+
116 %if __BITS__ == 64
117 %1
118 %endif
119%endmacro
120
121
122
123;; @name Segment definitions.
124;; @{
125%macro BS3_BEGIN_TEXT16 0
126 %ifndef BS3_BEGIN_TEXT16_NOT_FIRST
127 %define BS3_BEGIN_TEXT16_NOT_FIRST
128 %ifdef ASM_FORMAT_ELF
129 section BS3TEXT16 align=1 progbits alloc exec nowrite
130 %else
131 section BS3TEXT16 align=1 CLASS=BS3CODE16 PUBLIC USE16
132 %endif
133
134 %else
135 section BS3TEXT16
136 %endif
137 BS3_SET_BITS 16
138%endmacro
139
140%macro BS3_BEGIN_DATA16 0
141 %ifndef BS3_BEGIN_DATA16_NOT_FIRST
142 %define BS3_BEGIN_DATA16_NOT_FIRST
143 %ifdef ASM_FORMAT_ELF
144 section BS3DATA16 align=2 progbits alloc noexec write
145 %else
146 section BS3DATA16 align=2 CLASS=FAR_DATA PUBLIC USE16
147 %endif
148 %else
149 section BS3DATA16
150 %endif
151 BS3_SET_BITS 16
152%endmacro
153
154%macro BS3_BEGIN_TEXT32 0
155 %ifndef BS3_BEGIN_TEXT32_NOT_FIRST
156 %define BS3_BEGIN_TEXT32_NOT_FIRST
157 %ifdef ASM_FORMAT_ELF
158 section BS3TEXT32 align=1 progbits alloc exec nowrite
159 %else
160 section BS3TEXT32 align=1 CLASS=BS3CODE32 PUBLIC USE32
161 %endif
162 %else
163 section BS3TEXT32
164 %endif
165 BS3_SET_BITS 32
166%endmacro
167
168%macro BS3_BEGIN_DATA32 0
169 %ifndef BS3_BEGIN_DATA32_NOT_FIRST
170 %define BS3_BEGIN_DATA32_NOT_FIRST
171 %ifdef ASM_FORMAT_ELF
172 section BS3DATA32 align=16 progbits alloc noexec write
173 %else
174 section BS3DATA32 align=16 CLASS=FAR_DATA PUBLIC USE32
175 %endif
176 %else
177 section BS3DATA32
178 %endif
179 BS3_SET_BITS 32
180%endmacro
181
182%macro BS3_BEGIN_TEXT64 0
183 %ifndef BS3_BEGIN_TEXT64_NOT_FIRST
184 %define BS3_BEGIN_TEXT64_NOT_FIRST
185 %ifdef ASM_FORMAT_ELF
186 section BS3TEXT64 align=1 progbits alloc exec nowrite
187 %else
188 section BS3TEXT64 align=1 CLASS=CODE PUBLIC USE32 ; class=CODE here because of 64-bit cl and/or wlink.exe
189 %endif
190 %else
191 section BS3TEXT64
192 %endif
193 BS3_SET_BITS 64
194%endmacro
195
196%macro BS3_BEGIN_DATA64 0
197 %ifndef BS3_BEGIN_DATA64_NOT_FIRST
198 %define BS3_BEGIN_DATA64_NOT_FIRST
199 %ifdef ASM_FORMAT_ELF
200 section BS3DATA64 align=16 progbits alloc noexec write
201 %else
202 section BS3DATA64 align=16 CLASS=DATA PUBLIC USE32 ; class=DATA here because of 64-bit cl and/or wlink.exe
203 %endif
204 %else
205 section BS3DATA64
206 %endif
207 BS3_SET_BITS 64
208%endmacro
209
210;; Default text section.
211%macro BS3_BEGIN_DEFAULT_TEXT 0
212 %if ARCH_BITS == 16
213 BS3_BEGIN_TEXT16
214 %elif ARCH_BITS == 32
215 BS3_BEGIN_TEXT32
216 %elif ARCH_BITS == 64
217 BS3_BEGIN_TEXT64
218 %else
219 %error "ARCH_BITS must be defined as either 16, 32, or 64!"
220 INVALID_ARCH_BITS
221 %endif
222%endmacro
223
224;; @}
225
226
227;
228; Now, ditch the default 'text' section and define our own NAME macro.
229;
230%ifndef ASM_FORMAT_BIN
231 BS3_BEGIN_DEFAULT_TEXT
232 BS3_BEGIN_DEFAULT_TEXT ; stupid nasm automagically repeats the segment attributes.
233%endif
234
235;; When using watcom + OMF, we're using __cdecl by default, which
236; get an underscore added in front.
237%ifdef ASM_FORMAT_OMF
238 %define NAME(name) _ %+ NAME_OVERLOAD(name)
239%endif
240
241
242;
243; Include the standard headers from iprt.
244;
245
246
247%include "iprt/asmdefs.mac"
248%include "iprt/x86.mac"
249
250
251;;
252; Extern macro which mangles the name using NAME().
253%macro EXTERN 1
254 extern NAME(%1)
255%endmacro
256
257;;
258; Mangles a common name according to the current cpu bit count.
259; @remarks Requires the use of the BS3_SET_BITS macro instead of the BITS directive.
260%define BS3_CMN_NM(a_Name) BS3_NAME_UNDERSCORE %+ a_Name %+ _c %+ __BITS__
261
262;;
263; Extern macro which mangles the common name correctly, redefining the unmangled
264; name with to the mangled one for ease of use.
265;
266; @param %1 The unmangled common name.
267;
268; @remarks Must enter the segment in which this name is defined.
269;
270%macro BS3_EXTERN_CMN 1
271 extern BS3_CMN_NM(%1)
272 %undef %1
273 %define %1 BS3_CMN_NM(%1)
274%endmacro
275
276;;
277; Global name with ELF attributes and size.
278;
279; This differs from GLOBALNAME_EX in that it expects a mangled symbol name,
280; and allows for nasm style symbol size expressions.
281;
282; @param %1 The mangled name.
283; @param %2 Symbol attributes.
284; @param %3 The size expression.
285;
286%macro BS3_GLOBAL_NAME_EX 3
287%ifdef ASM_FORMAT_ELF
288 %ifdef __NASM__
289global %1:%2 %3
290 %else
291global %1:%2
292 %endif
293%else
294global %1
295%endif
296%1:
297%endmacro
298
299;;
300; Starts a procedure.
301;
302; This differs from BEGINPROC in that it expects a mangled symbol name and
303; does the NASM symbol size stuff.
304;
305; @param %1 The mangled name.
306;
307%macro BS3_PROC_BEGIN 1
308BS3_GLOBAL_NAME_EX %1, function, (%1 %+ _EndProc - %1)
309%endmacro
310
311;;
312; Ends a procedure.
313;
314; Counter part to BS3_PROC_BEGIN.
315;
316; @param %1 The mangled name.
317;
318%macro BS3_PROC_END 1
319BS3_GLOBAL_NAME_EX %1 %+ _EndProc, function hidden, (%1 %+ _EndProc - %1)
320 %ifdef ASM_FORMAT_ELF
321 %ifdef __YASM__
322size %1 %1 %+ _EndProc - %1
323size %1 %+ _EndProc 0
324 %endif
325 %endif
326%endmacro
327
328;; Convenience macro for defining common procedures.
329%macro BS3_PROC_BEGIN_CMN 1
330 BS3_PROC_BEGIN BS3_CMN_NM(%1)
331%endmacro
332
333;; Convenience macro for defining common procedures.
334%macro BS3_PROC_END_CMN 1
335 BS3_PROC_END BS3_CMN_NM(%1)
336%endmacro
337
338;;
339; Prologue hacks for 64-bit code.
340;
341; This saves the four register parameters onto the stack so we can pretend
342; the calling convention is stack based. The 64-bit calling convension is
343; the microsoft one, so this is straight forward.
344;
345; Pairs with BS3_CALL_CONV_EPILOG.
346;
347; @param %1 The number of parameters.
348;
349; @remarks Must be invoked before any stack changing instructions are emitted.
350;
351%macro BS3_CALL_CONV_PROLOG 1
352 %undef BS3_CALL_CONV_PROLOG_PARAMS
353 %define BS3_CALL_CONV_PROLOG_PARAMS %1
354 %if __BITS__ == 64
355 %if %1 >= 1
356 mov [rsp + 008h], rcx
357 %elifdef BS3_STRICT
358 and qword [rsp + 008h], 1
359 %endif
360 %if %1 >= 2
361 mov [rsp + 010h], rdx
362 %elifdef BS3_STRICT
363 and qword [rsp + 010h], 2
364 %endif
365 %if %1 >= 3
366 mov [rsp + 018h], r8
367 %elifdef BS3_STRICT
368 and qword [rsp + 018h], 3
369 %endif
370 %if %1 >= 4
371 mov [rsp + 020h], r9
372 %elifdef BS3_STRICT
373 and qword [rsp + 020h], 4
374 %endif
375 %endif
376%endmacro
377
378;;
379; Epilogue hacks for 64-bit code.
380;
381; Counter part to BS3_CALL_CONV_PROLOG.
382;
383; @param %1 The number of parameters.
384;
385; @remarks Must be invoked right before the return instruction as it uses RSP.
386;
387%macro BS3_CALL_CONV_EPILOG 1
388 %if BS3_CALL_CONV_PROLOG_PARAMS != %1
389 %error "BS3_CALL_CONV_EPILOG argument differs from BS3_CALL_CONV_PROLOG."
390 %endif
391 %if __BITS__ == 64
392 %ifdef BS3_STRICT
393 mov dword [rsp + 008h], 31h
394 mov dword [rsp + 010h], 32h
395 mov dword [rsp + 018h], 33h
396 mov dword [rsp + 020h], 34h
397 %endif
398 %endif
399%endmacro
400
401;;
402; Wrapper for the call instruction that hides calling convension differences.
403;
404; This always calls %1.
405; In 64-bit code, it will load up to 4 parameters into register.
406;
407; @param %1 The function to call (mangled).
408; @param %2 The number of parameters.
409;
410%macro BS3_CALL 2
411 %if __BITS__ == 64
412 %if %2 >= 1
413 mov rcx, [rsp + 008h]
414 %ifdef BS3_STRICT
415 and qword [rsp + 008h], 11h
416 %endif
417 %endif
418 %if %2 >= 2
419 mov rdx, [rsp + 010h]
420 %ifdef BS3_STRICT
421 and qword [rsp + 010h], 12h
422 %endif
423 %endif
424 %if %2 >= 3
425 mov r8, [rsp + 018h]
426 %ifdef BS3_STRICT
427 and qword [rsp + 018h], 13h
428 %endif
429 %endif
430 %if %2 >= 4
431 mov r9, [rsp + 020h]
432 %ifdef BS3_STRICT
433 and qword [rsp + 020h], 14h
434 %endif
435 %endif
436 %endif
437 call %1
438%endmacro
439
440
441;; @name Static Memory Allocation
442; @{
443;; The flat load address for the code after the bootsector.
444%define BS3_LOAD_ADDR 010000h
445;; Where we save the boot registers during init.
446; Located right before the code.
447%define BS3_REG_SAVE_ADDR (BS3_LOAD_ADDR - BS3REGS_size - 8)
448;; Where the stack starts (initial RSP value).
449; Located right before the saved registers. SS.BASE=0.
450%define BS3_STACK_ADDR (BS3_REG_SAVE_ADDR - 16)
451;; @}
452
453
454;;
455; Registers. Used by traps and such.
456;
457struc BS3REGS
458 .rax resq 1
459 .rbx resq 1
460 .rcx resq 1
461 .rdx resq 1
462 .rdi resq 1
463 .rsi resq 1
464 .rbp resq 1
465 .rsp resq 1
466 .rip resq 1
467 .r8 resq 1
468 .r9 resq 1
469 .r10 resq 1
470 .r11 resq 1
471 .r12 resq 1
472 .r13 resq 1
473 .r14 resq 1
474 .r15 resq 1
475 .rflags resq 1
476 .cs resw 1
477 .ds resw 1
478 .es resw 1
479 .fs resw 1
480 .gs resw 1
481 .ss resw 1
482 .cBits resb 1
483 .pad resb 3
484 .cr0 resq 1
485 .cr2 resq 1
486 .cr3 resq 1
487 .cr4 resq 1
488 .cr8 resq 1
489 ;; @todo Add floating point registers when they are active.
490endstruc
491
492
493
494;;
495; Trap record.
496;
497struc BS3TRAPREC
498 ;; The trap location relative to the base address given at
499 ; registration time.
500 .offWhere resd 1
501 ;; What to add to .offWhere to calculate the resume address.
502 .offResumeAddend resb 1
503 ;; The trap number.
504 .u8TrapNo resb 1
505 ;; The error code if the trap takes one.
506 .u16ErrCd resw 1
507endstruc
508
509;; The size shift.
510%define BS3TRAPREC_SIZE_SHIFT 3
511
512
513%endif
514
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette