summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/PC/BIOS/inlines.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Devices/PC/BIOS/inlines.h')
-rw-r--r--src/VBox/Devices/PC/BIOS/inlines.h271
1 files changed, 271 insertions, 0 deletions
diff --git a/src/VBox/Devices/PC/BIOS/inlines.h b/src/VBox/Devices/PC/BIOS/inlines.h
new file mode 100644
index 00000000..13c81adf
--- /dev/null
+++ b/src/VBox/Devices/PC/BIOS/inlines.h
@@ -0,0 +1,271 @@
+/* $Id: inlines.h $ */
+/** @file
+ * Inline routines for Watcom C.
+ */
+
+/*
+ * Copyright (C) 2010-2022 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef VBOX_INCLUDED_SRC_PC_BIOS_inlines_h
+#define VBOX_INCLUDED_SRC_PC_BIOS_inlines_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+extern unsigned inp(unsigned port);
+extern unsigned outp(unsigned port, unsigned value);
+extern unsigned inpw(unsigned port);
+extern unsigned outpw(unsigned port, unsigned value);
+#pragma intrinsic(inp,outp,inpw,outpw)
+#define inb(p) inp(p)
+#define outb(p, v) outp(p, v)
+#define inw(p) inpw(p)
+#define outw(p, v) outpw(p, v)
+
+/* Far byte/word/dword access routines. */
+
+inline uint8_t read_byte(uint16_t seg, uint16_t offset)
+{
+ return( *(seg:>(uint8_t *)offset) );
+}
+
+inline void write_byte(uint16_t seg, uint16_t offset, uint8_t data)
+{
+ *(seg:>(uint8_t *)offset) = data;
+}
+
+inline uint16_t read_word(uint16_t seg, uint16_t offset)
+{
+ return( *(seg:>(uint16_t *)offset) );
+}
+
+inline void write_word(uint16_t seg, uint16_t offset, uint16_t data)
+{
+ *(seg:>(uint16_t *)offset) = data;
+}
+
+inline uint32_t read_dword(uint16_t seg, uint16_t offset)
+{
+ return( *(seg:>(uint32_t *)offset) );
+}
+
+inline void write_dword(uint16_t seg, uint16_t offset, uint32_t data)
+{
+ *(seg:>(uint32_t *)offset) = data;
+}
+
+
+void int_enable(void);
+#pragma aux int_enable = "sti" modify exact [] nomemory;
+
+void int_disable(void);
+#pragma aux int_disable = "cli" modify exact [] nomemory;
+
+void int_enable_hlt_disable(void);
+#pragma aux int_enable_hlt_disable = \
+ "sti" \
+ "hlt" \
+ "cli" \
+ modify exact [] nomemory;
+
+uint16_t int_query(void);
+#pragma aux int_query = \
+ "pushf" \
+ "pop ax" \
+ value [ax] modify exact [ax] nomemory;
+
+void int_restore(uint16_t old_flags);
+#pragma aux int_restore = \
+ "push ax" \
+ "popf" \
+ parm [ax] modify exact [] nomemory;
+
+void halt(void);
+#pragma aux halt = "hlt" modify exact [] nomemory;
+
+void halt_forever(void);
+#pragma aux halt_forever = \
+ "forever:" \
+ "hlt" \
+ "jmp forever" \
+ modify exact [] nomemory aborts;
+
+/* Output a null-terminated string to a specified port, without the
+ * terminating null character.
+ */
+static void out_ctrl_str_asm(uint16_t port, const char *s);
+#pragma aux out_ctrl_str_asm = \
+ "mov al, [bx]" \
+ "next:" \
+ "out dx, al" \
+ "inc bx" \
+ "mov al, [bx]" \
+ "or al, al" \
+ "jnz next" \
+ parm [dx] [bx] modify exact [ax bx] nomemory;
+
+#ifdef __386__
+
+void rep_movsb(void __far *d, void __far *s, int nbytes);
+#pragma aux rep_movsb = \
+ "push ds" \
+ "mov ds, dx" \
+ "rep movsb" \
+ "pop ds" \
+ parm [es edi] [dx esi] [ecx];
+
+#else
+
+void rep_movsb(void __far *d, void __far *s, int nbytes);
+#pragma aux rep_movsb = \
+ "push ds" \
+ "mov ds, dx" \
+ "rep movsb" \
+ "pop ds" \
+ parm [es di] [dx si] [cx];
+
+#endif
+
+void rep_movsw(void __far *d, void __far *s, int nwords);
+#pragma aux rep_movsw = \
+ "push ds" \
+ "mov ds, dx" \
+ "rep movsw" \
+ "pop ds" \
+ parm [es di] [dx si] [cx];
+
+#ifndef __386__
+
+char __far *rep_insb(char __far *buffer, unsigned nbytes, unsigned port);
+#pragma aux rep_insb = ".286" "rep insb" parm [es di] [cx] [dx] value [es di] modify exact [cx di];
+
+char __far *rep_insw(char __far *buffer, unsigned nwords, unsigned port);
+#pragma aux rep_insw = ".286" "rep insw" parm [es di] [cx] [dx] value [es di] modify exact [cx di];
+
+# if VBOX_BIOS_CPU >= 80386
+char __far *rep_insd(char __far *buffer, unsigned ndwords, unsigned port);
+# pragma aux rep_insd = ".386" "rep insd" parm [es di] [cx] [dx] value [es di] modify exact [cx di];
+# endif
+
+char __far *rep_outsb(char __far *buffer, unsigned nbytes, unsigned port);
+#pragma aux rep_outsb = ".286" "rep outs dx,byte ptr es:[si]" parm [es si] [cx] [dx] value [es si] modify exact [cx si];
+
+char __far *rep_outsw(char __far *buffer, unsigned nwords, unsigned port);
+#pragma aux rep_outsw = ".286" "rep outs dx,word ptr es:[si]" parm [es si] [cx] [dx] value [es si] modify exact [cx si];
+
+# if VBOX_BIOS_CPU >= 80386
+char __far *rep_outsd(char __far *buffer, unsigned ndwords, unsigned port);
+# pragma aux rep_outsd = ".386" "rep outs dx,dword ptr es:[si]" parm [es si] [cx] [dx] value [es si] modify exact [cx si];
+# endif
+
+uint16_t swap_16(uint16_t val);
+#pragma aux swap_16 = "xchg ah,al" parm [ax] value [ax] modify exact [ax] nomemory;
+
+uint32_t swap_32(uint32_t val);
+#pragma aux swap_32 = \
+ "xchg ah, al" \
+ "xchg dh, dl" \
+ "xchg ax, dx" \
+ parm [dx ax] value [dx ax] modify exact [dx ax] nomemory;
+
+uint64_t swap_64(uint64_t val);
+#pragma aux swap_64 = \
+ "xchg ah, al" \
+ "xchg bh, bl" \
+ "xchg ch, cl" \
+ "xchg dh, dl" \
+ "xchg ax, dx" \
+ "xchg bx, cx" \
+ parm [ax bx cx dx] value [ax bx cx dx] modify exact [ax bx cx dx] nomemory;
+
+#endif
+
+#if VBOX_BIOS_CPU >= 80386
+
+/* Warning: msr_read/msr_write destroy high bits of 32-bit registers (EAX, ECX, EDX). */
+
+uint64_t msr_read(uint32_t msr);
+#pragma aux msr_read = \
+ ".586" \
+ "shl ecx, 16" \
+ "mov cx, ax" \
+ "rdmsr" \
+ "xchg eax, edx" \
+ "mov bx, ax" \
+ "shr eax, 16" \
+ "mov cx, dx" \
+ "shr edx, 16" \
+ "xchg dx, cx" \
+ parm [cx ax] value [ax bx cx dx] modify [] nomemory;
+
+void msr_write(uint64_t val, uint32_t msr);
+#pragma aux msr_write = \
+ ".586" \
+ "shl eax, 16" \
+ "mov ax, bx" \
+ "xchg dx, cx" \
+ "shl edx, 16" \
+ "mov dx, cx" \
+ "xchg eax, edx" \
+ "mov cx, di" \
+ "shl ecx, 16" \
+ "mov cx, si" \
+ "wrmsr" \
+ parm [ax bx cx dx] [di si] modify [] nomemory;
+
+/* Warning: eflags_read/eflags_write destroy high bits of 32-bit registers (EDX). */
+uint32_t eflags_read( void );
+#pragma aux eflags_read = \
+ ".386" \
+ "pushfd" \
+ "pop edx" \
+ "mov ax, dx" \
+ "shr edx, 16" \
+ value [dx ax] modify [dx ax];
+
+uint32_t eflags_write( uint32_t e_flags );
+#pragma aux eflags_write = \
+ ".386" \
+ "shl edx, 16" \
+ "mov dx, ax" \
+ "push edx" \
+ "popfd" \
+ parm [dx ax] modify [dx ax];
+
+/* Warning cpuid destroys high bits of 32-bit registers (EAX, EBX, ECX, EDX). */
+void cpuid( uint32_t __far cpu_id[4], uint32_t leaf );
+#pragma aux cpuid = \
+ ".586" \
+ "shl edx, 16" \
+ "mov dx, ax" \
+ "mov eax, edx" \
+ "cpuid" \
+ "mov es:[di+0], eax" \
+ "mov es:[di+4], ebx" \
+ "mov es:[di+8], ecx" \
+ "mov es:[di+12], edx" \
+ parm [es di] [dx ax] modify [bx cx dx]
+
+#endif
+
+#endif /* !VBOX_INCLUDED_SRC_PC_BIOS_inlines_h */
+