VirtualBox

source: vbox/trunk/src/VBox/Devices/PC/BIOS/inlines.h@ 104253

Last change on this file since 104253 was 100674, checked in by vboxsync, 16 months ago

BIOS: Added 8086 alternative implementations for rep_insw and rep_outsw, allowing the ATA disk driver to work.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.2 KB
Line 
1/* $Id: inlines.h 100674 2023-07-21 09:50:53Z vboxsync $ */
2/** @file
3 * Inline routines for Watcom C.
4 */
5
6/*
7 * Copyright (C) 2010-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 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28#ifndef VBOX_INCLUDED_SRC_PC_BIOS_inlines_h
29#define VBOX_INCLUDED_SRC_PC_BIOS_inlines_h
30#ifndef RT_WITHOUT_PRAGMA_ONCE
31# pragma once
32#endif
33
34extern unsigned inp(unsigned port);
35extern unsigned outp(unsigned port, unsigned value);
36extern unsigned inpw(unsigned port);
37extern unsigned outpw(unsigned port, unsigned value);
38#pragma intrinsic(inp,outp,inpw,outpw)
39#define inb(p) inp(p)
40#define outb(p, v) outp(p, v)
41#define inw(p) inpw(p)
42#define outw(p, v) outpw(p, v)
43
44/* Far byte/word/dword access routines. */
45
46inline uint8_t read_byte(uint16_t seg, uint16_t offset)
47{
48 return( *(seg:>(uint8_t *)offset) );
49}
50
51inline void write_byte(uint16_t seg, uint16_t offset, uint8_t data)
52{
53 *(seg:>(uint8_t *)offset) = data;
54}
55
56inline uint16_t read_word(uint16_t seg, uint16_t offset)
57{
58 return( *(seg:>(uint16_t *)offset) );
59}
60
61inline void write_word(uint16_t seg, uint16_t offset, uint16_t data)
62{
63 *(seg:>(uint16_t *)offset) = data;
64}
65
66inline uint32_t read_dword(uint16_t seg, uint16_t offset)
67{
68 return( *(seg:>(uint32_t *)offset) );
69}
70
71inline void write_dword(uint16_t seg, uint16_t offset, uint32_t data)
72{
73 *(seg:>(uint32_t *)offset) = data;
74}
75
76
77void int_enable(void);
78#pragma aux int_enable = "sti" modify exact [] nomemory;
79
80void int_disable(void);
81#pragma aux int_disable = "cli" modify exact [] nomemory;
82
83void int_enable_hlt_disable(void);
84#pragma aux int_enable_hlt_disable = \
85 "sti" \
86 "hlt" \
87 "cli" \
88 modify exact [] nomemory;
89
90uint16_t int_query(void);
91#pragma aux int_query = \
92 "pushf" \
93 "pop ax" \
94 value [ax] modify exact [ax] nomemory;
95
96void int_restore(uint16_t old_flags);
97#pragma aux int_restore = \
98 "push ax" \
99 "popf" \
100 parm [ax] modify exact [] nomemory;
101
102void halt(void);
103#pragma aux halt = "hlt" modify exact [] nomemory;
104
105void halt_forever(void);
106#pragma aux halt_forever = \
107 "forever:" \
108 "hlt" \
109 "jmp forever" \
110 modify exact [] nomemory aborts;
111
112/* Output a null-terminated string to a specified port, without the
113 * terminating null character.
114 */
115static void out_ctrl_str_asm(uint16_t port, const char *s);
116#pragma aux out_ctrl_str_asm = \
117 "mov al, [bx]" \
118 "next:" \
119 "out dx, al" \
120 "inc bx" \
121 "mov al, [bx]" \
122 "or al, al" \
123 "jnz next" \
124 parm [dx] [bx] modify exact [ax bx] nomemory;
125
126#ifdef __386__
127
128void rep_movsb(void __far *d, void __far *s, int nbytes);
129#pragma aux rep_movsb = \
130 "push ds" \
131 "mov ds, dx" \
132 "rep movsb" \
133 "pop ds" \
134 parm [es edi] [dx esi] [ecx];
135
136#else
137
138void rep_movsb(void __far *d, void __far *s, int nbytes);
139#pragma aux rep_movsb = \
140 "push ds" \
141 "mov ds, dx" \
142 "rep movsb" \
143 "pop ds" \
144 parm [es di] [dx si] [cx];
145
146#endif
147
148void rep_movsw(void __far *d, void __far *s, int nwords);
149#pragma aux rep_movsw = \
150 "push ds" \
151 "mov ds, dx" \
152 "rep movsw" \
153 "pop ds" \
154 parm [es di] [dx si] [cx];
155
156#ifndef __386__
157
158char __far *rep_insb(char __far *buffer, unsigned nbytes, unsigned port);
159#pragma aux rep_insb = ".286" "rep insb" parm [es di] [cx] [dx] value [es di] modify exact [cx di];
160
161char __far *rep_insw(char __far *buffer, unsigned nwords, unsigned port);
162#if VBOX_BIOS_CPU >= 80286
163#pragma aux rep_insw = ".286" "rep insw" parm [es di] [cx] [dx] value [es di] modify exact [cx di];
164#else
165#pragma aux rep_insw = "next:" "in ax,dx" "stosw" "loop next" parm [es di] [cx] [dx] value [es di] modify exact [cx di];
166#endif
167
168# if VBOX_BIOS_CPU >= 80386
169char __far *rep_insd(char __far *buffer, unsigned ndwords, unsigned port);
170# pragma aux rep_insd = ".386" "rep insd" parm [es di] [cx] [dx] value [es di] modify exact [cx di];
171# endif
172
173char __far *rep_outsb(char __far *buffer, unsigned nbytes, unsigned port);
174#pragma aux rep_outsb = ".286" "rep outs dx,byte ptr es:[si]" parm [es si] [cx] [dx] value [es si] modify exact [cx si];
175
176char __far *rep_outsw(char __far *buffer, unsigned nwords, unsigned port);
177#if VBOX_BIOS_CPU >= 80286
178#pragma aux rep_outsw = ".286" "rep outs dx,word ptr es:[si]" parm [es si] [cx] [dx] value [es si] modify exact [cx si];
179#else
180#pragma aux rep_outsw = "next:" "lods word ptr es:[si]" "out dx,ax" "loop next" parm [es si] [cx] [dx] value [es si] modify exact [cx si];
181#endif
182
183# if VBOX_BIOS_CPU >= 80386
184char __far *rep_outsd(char __far *buffer, unsigned ndwords, unsigned port);
185# pragma aux rep_outsd = ".386" "rep outs dx,dword ptr es:[si]" parm [es si] [cx] [dx] value [es si] modify exact [cx si];
186# endif
187
188uint16_t swap_16(uint16_t val);
189#pragma aux swap_16 = "xchg ah,al" parm [ax] value [ax] modify exact [ax] nomemory;
190
191uint32_t swap_32(uint32_t val);
192#pragma aux swap_32 = \
193 "xchg ah, al" \
194 "xchg dh, dl" \
195 "xchg ax, dx" \
196 parm [dx ax] value [dx ax] modify exact [dx ax] nomemory;
197
198uint64_t swap_64(uint64_t val);
199#pragma aux swap_64 = \
200 "xchg ah, al" \
201 "xchg bh, bl" \
202 "xchg ch, cl" \
203 "xchg dh, dl" \
204 "xchg ax, dx" \
205 "xchg bx, cx" \
206 parm [ax bx cx dx] value [ax bx cx dx] modify exact [ax bx cx dx] nomemory;
207
208#endif
209
210#if VBOX_BIOS_CPU >= 80386
211
212/* Warning: msr_read/msr_write destroy high bits of 32-bit registers (EAX, ECX, EDX). */
213
214uint64_t msr_read(uint32_t msr);
215#pragma aux msr_read = \
216 ".586" \
217 "shl ecx, 16" \
218 "mov cx, ax" \
219 "rdmsr" \
220 "xchg eax, edx" \
221 "mov bx, ax" \
222 "shr eax, 16" \
223 "mov cx, dx" \
224 "shr edx, 16" \
225 "xchg dx, cx" \
226 parm [cx ax] value [ax bx cx dx] modify [] nomemory;
227
228void msr_write(uint64_t val, uint32_t msr);
229#pragma aux msr_write = \
230 ".586" \
231 "shl eax, 16" \
232 "mov ax, bx" \
233 "xchg dx, cx" \
234 "shl edx, 16" \
235 "mov dx, cx" \
236 "xchg eax, edx" \
237 "mov cx, di" \
238 "shl ecx, 16" \
239 "mov cx, si" \
240 "wrmsr" \
241 parm [ax bx cx dx] [di si] modify [] nomemory;
242
243/* Warning: eflags_read/eflags_write destroy high bits of 32-bit registers (EDX). */
244uint32_t eflags_read( void );
245#pragma aux eflags_read = \
246 ".386" \
247 "pushfd" \
248 "pop edx" \
249 "mov ax, dx" \
250 "shr edx, 16" \
251 value [dx ax] modify [dx ax];
252
253uint32_t eflags_write( uint32_t e_flags );
254#pragma aux eflags_write = \
255 ".386" \
256 "shl edx, 16" \
257 "mov dx, ax" \
258 "push edx" \
259 "popfd" \
260 parm [dx ax] modify [dx ax];
261
262/* Warning cpuid destroys high bits of 32-bit registers (EAX, EBX, ECX, EDX). */
263void cpuid( uint32_t __far cpu_id[4], uint32_t leaf );
264#pragma aux cpuid = \
265 ".586" \
266 "shl edx, 16" \
267 "mov dx, ax" \
268 "mov eax, edx" \
269 "cpuid" \
270 "mov es:[di+0], eax" \
271 "mov es:[di+4], ebx" \
272 "mov es:[di+8], ecx" \
273 "mov es:[di+12], edx" \
274 parm [es di] [dx ax] modify [bx cx dx]
275
276#endif
277
278#endif /* !VBOX_INCLUDED_SRC_PC_BIOS_inlines_h */
279
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