xref: /openbsd/sys/dev/x86emu/x86emu_util.c (revision 21dab745)
1*21dab745Sjsg /*	$OpenBSD: x86emu_util.c,v 1.6 2015/03/14 03:38:50 jsg Exp $	*/
2e208dfa2Spirofti /*	$NetBSD: x86emu_util.c,v 1.2 2007/12/04 17:32:22 joerg Exp $	*/
3e208dfa2Spirofti 
4bb806961Spirofti /*
5e208dfa2Spirofti  *
6e208dfa2Spirofti  *  Realmode X86 Emulator Library
7e208dfa2Spirofti  *
8e208dfa2Spirofti  *  Copyright (C) 1996-1999 SciTech Software, Inc.
9e208dfa2Spirofti  *  Copyright (C) David Mosberger-Tang
10e208dfa2Spirofti  *  Copyright (C) 1999 Egbert Eich
11e208dfa2Spirofti  *  Copyright (C) 2007 Joerg Sonnenberger
12e208dfa2Spirofti  *
13e208dfa2Spirofti  *  ========================================================================
14e208dfa2Spirofti  *
15e208dfa2Spirofti  *  Permission to use, copy, modify, distribute, and sell this software and
16e208dfa2Spirofti  *  its documentation for any purpose is hereby granted without fee,
17e208dfa2Spirofti  *  provided that the above copyright notice appear in all copies and that
18e208dfa2Spirofti  *  both that copyright notice and this permission notice appear in
19e208dfa2Spirofti  *  supporting documentation, and that the name of the authors not be used
20e208dfa2Spirofti  *  in advertising or publicity pertaining to distribution of the software
21e208dfa2Spirofti  *  without specific, written prior permission.  The authors makes no
22e208dfa2Spirofti  *  representations about the suitability of this software for any purpose.
23e208dfa2Spirofti  *  It is provided "as is" without express or implied warranty.
24e208dfa2Spirofti  *
25e208dfa2Spirofti  *  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
26e208dfa2Spirofti  *  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
27e208dfa2Spirofti  *  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
28e208dfa2Spirofti  *  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
29e208dfa2Spirofti  *  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
30e208dfa2Spirofti  *  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
31e208dfa2Spirofti  *  PERFORMANCE OF THIS SOFTWARE.
32e208dfa2Spirofti  *
33bb806961Spirofti  */
34e208dfa2Spirofti 
35e208dfa2Spirofti #include <sys/param.h>
36e208dfa2Spirofti #include <sys/endian.h>
37e208dfa2Spirofti 
384b013528Sderaadt #include <dev/x86emu/x86emu.h>
39e208dfa2Spirofti 
40e208dfa2Spirofti 
41e208dfa2Spirofti 
42bb806961Spirofti /*
43bb806961Spirofti  * PARAMETERS:
44bb806961Spirofti  * addr	- Emulator memory address to read
45bb806961Spirofti  *
46bb806961Spirofti  * RETURNS:
47bb806961Spirofti  * Byte value read from emulator memory.
48bb806961Spirofti  *
49bb806961Spirofti  * REMARKS:
50bb806961Spirofti  * Reads a byte value from the emulator memory.
51bb806961Spirofti  */
52e208dfa2Spirofti static uint8_t
rdb(struct x86emu * emu,uint32_t addr)536bf2980cSderaadt rdb(struct x86emu *emu, uint32_t addr)
54e208dfa2Spirofti {
55e208dfa2Spirofti 	if (addr > emu->mem_size - 1)
566bf2980cSderaadt 		x86emu_halt_sys(emu);
57e208dfa2Spirofti 	return emu->mem_base[addr];
58e208dfa2Spirofti }
59e208dfa2Spirofti 
60bb806961Spirofti /*
61bb806961Spirofti  * PARAMETERS:
62bb806961Spirofti  * addr	- Emulator memory address to read
63bb806961Spirofti  *
64bb806961Spirofti  * RETURNS:
65bb806961Spirofti  * Word value read from emulator memory.
66bb806961Spirofti  *
67bb806961Spirofti  * REMARKS:
68bb806961Spirofti  * Reads a word value from the emulator memory.
69bb806961Spirofti  */
70e208dfa2Spirofti static uint16_t
rdw(struct x86emu * emu,uint32_t addr)716bf2980cSderaadt rdw(struct x86emu *emu, uint32_t addr)
72e208dfa2Spirofti {
73e208dfa2Spirofti 	if (addr > emu->mem_size - 2)
746bf2980cSderaadt 		x86emu_halt_sys(emu);
75341eb07dSderaadt #ifdef __STRICT_ALIGNMENT
76341eb07dSderaadt 	if (addr & 1) {
77341eb07dSderaadt 		u_int8_t *a = emu->mem_base + addr;
78341eb07dSderaadt 		u_int16_t r;
79341eb07dSderaadt 
80341eb07dSderaadt 		r = ((*(a + 0) << 0) & 0x00ff) |
81341eb07dSderaadt 		    ((*(a + 1) << 8) & 0xff00);
82341eb07dSderaadt 		return r;
83341eb07dSderaadt 	} else
84341eb07dSderaadt 		return letoh32(*(u_int32_t *)(emu->mem_base + addr));
85341eb07dSderaadt #else
86341eb07dSderaadt 	return letoh16(*(u_int16_t *)(emu->mem_base + addr));
87341eb07dSderaadt #endif
88e208dfa2Spirofti }
89e208dfa2Spirofti 
90bb806961Spirofti /*
91bb806961Spirofti  * PARAMETERS:
92bb806961Spirofti  * addr	- Emulator memory address to read
93bb806961Spirofti  *
94bb806961Spirofti  * RETURNS:
95bb806961Spirofti  * Long value read from emulator memory.
96bb806961Spirofti  * REMARKS:
97bb806961Spirofti  * Reads a long value from the emulator memory.
98bb806961Spirofti  */
99e208dfa2Spirofti static uint32_t
rdl(struct x86emu * emu,uint32_t addr)1006bf2980cSderaadt rdl(struct x86emu *emu, uint32_t addr)
101e208dfa2Spirofti {
102e208dfa2Spirofti 	if (addr > emu->mem_size - 4)
1036bf2980cSderaadt 		x86emu_halt_sys(emu);
104341eb07dSderaadt #ifdef __STRICT_ALIGNMENT
105341eb07dSderaadt 	if (addr & 3) {
106341eb07dSderaadt 		u_int8_t *a = emu->mem_base + addr;
107341eb07dSderaadt 		u_int32_t r;
108341eb07dSderaadt 
109341eb07dSderaadt 		r = ((*(a + 0) <<  0) & 0x000000ff) |
110341eb07dSderaadt 		    ((*(a + 1) <<  8) & 0x0000ff00) |
111341eb07dSderaadt 		    ((*(a + 2) << 16) & 0x00ff0000) |
112341eb07dSderaadt 		    ((*(a + 3) << 24) & 0xff000000);
113341eb07dSderaadt 		return r;
114341eb07dSderaadt 	} else
115341eb07dSderaadt 		return letoh32(*(u_int32_t *)(emu->mem_base + addr));
116341eb07dSderaadt #else
117341eb07dSderaadt 	return letoh32(*(u_int32_t *)(emu->mem_base + addr));
118341eb07dSderaadt #endif
119e208dfa2Spirofti }
120e208dfa2Spirofti 
121bb806961Spirofti /*
122bb806961Spirofti  * PARAMETERS:
123bb806961Spirofti  * addr	- Emulator memory address to read
124bb806961Spirofti  * val		- Value to store
125bb806961Spirofti  *
126bb806961Spirofti  * REMARKS:
127bb806961Spirofti  * Writes a byte value to emulator memory.
128bb806961Spirofti  */
129e208dfa2Spirofti static void
wrb(struct x86emu * emu,uint32_t addr,uint8_t val)1306bf2980cSderaadt wrb(struct x86emu *emu, uint32_t addr, uint8_t val)
131e208dfa2Spirofti {
132e208dfa2Spirofti 	if (addr > emu->mem_size - 1)
1336bf2980cSderaadt 		x86emu_halt_sys(emu);
134e208dfa2Spirofti 	emu->mem_base[addr] = val;
135e208dfa2Spirofti }
136e208dfa2Spirofti 
137bb806961Spirofti /*
138bb806961Spirofti  * PARAMETERS:
139bb806961Spirofti  * addr	- Emulator memory address to read
140bb806961Spirofti  * val		- Value to store
141bb806961Spirofti  *
142bb806961Spirofti  * REMARKS:
143bb806961Spirofti  * Writes a word value to emulator memory.
144bb806961Spirofti  */
145e208dfa2Spirofti static void
wrw(struct x86emu * emu,uint32_t addr,uint16_t val)1466bf2980cSderaadt wrw(struct x86emu *emu, uint32_t addr, uint16_t val)
147e208dfa2Spirofti {
148e208dfa2Spirofti 	if (addr > emu->mem_size - 2)
1496bf2980cSderaadt 		x86emu_halt_sys(emu);
150341eb07dSderaadt #ifdef __STRICT_ALIGNMENT
151341eb07dSderaadt 	if (addr & 1) {
152341eb07dSderaadt 		u_int8_t *a = emu->mem_base + addr;
153341eb07dSderaadt 
154341eb07dSderaadt 		*((a + 0)) = (val >> 0) & 0xff;
155341eb07dSderaadt 		*((a + 1)) = (val >> 8) & 0xff;
156341eb07dSderaadt 	} else
157341eb07dSderaadt 		*((u_int16_t *)(emu->mem_base + addr)) = htole16(val);
158341eb07dSderaadt #else
159341eb07dSderaadt 	*((u_int16_t *)(emu->mem_base + addr)) = htole16(val);
160341eb07dSderaadt #endif
161e208dfa2Spirofti }
162e208dfa2Spirofti 
163bb806961Spirofti /*
164bb806961Spirofti  * PARAMETERS:
165bb806961Spirofti  * addr	- Emulator memory address to read
166bb806961Spirofti  * val		- Value to store
167bb806961Spirofti  *
168bb806961Spirofti  * REMARKS:
169bb806961Spirofti  * Writes a long value to emulator memory.
170bb806961Spirofti  */
171e208dfa2Spirofti static void
wrl(struct x86emu * emu,uint32_t addr,uint32_t val)1726bf2980cSderaadt wrl(struct x86emu *emu, uint32_t addr, uint32_t val)
173e208dfa2Spirofti {
174e208dfa2Spirofti 	if (addr > emu->mem_size - 4)
1756bf2980cSderaadt 		x86emu_halt_sys(emu);
176341eb07dSderaadt #ifdef __STRICT_ALIGNMENT
177341eb07dSderaadt 	if (addr & 3) {
178341eb07dSderaadt 		u_int8_t *a = emu->mem_base + addr;
179341eb07dSderaadt 
180341eb07dSderaadt 		*((a + 0) = (val >>  0) & 0xff;
181341eb07dSderaadt 		*((a + 1) = (val >>  8) & 0xff;
182341eb07dSderaadt 		*((a + 2) = (val >> 16) & 0xff;
183341eb07dSderaadt 		*((a + 3) = (val >> 24) & 0xff;
184341eb07dSderaadt 	} else
185341eb07dSderaadt 		*((u_int32_t *)(emu->mem_base + addr)) = htole32(val);
186341eb07dSderaadt #else
187341eb07dSderaadt 	*((u_int32_t *)(emu->mem_base + addr)) = htole32(val);
188341eb07dSderaadt #endif
189e208dfa2Spirofti }
190e208dfa2Spirofti 
191bb806961Spirofti /* Setup */
192e208dfa2Spirofti 
193e208dfa2Spirofti void
1946bf2980cSderaadt x86emu_init_default(struct x86emu *emu)
195e208dfa2Spirofti {
196e208dfa2Spirofti 	int i;
197e208dfa2Spirofti 
198e208dfa2Spirofti 	emu->emu_rdb = rdb;
199e208dfa2Spirofti 	emu->emu_rdw = rdw;
200e208dfa2Spirofti 	emu->emu_rdl = rdl;
201e208dfa2Spirofti 	emu->emu_wrb = wrb;
202e208dfa2Spirofti 	emu->emu_wrw = wrw;
203e208dfa2Spirofti 	emu->emu_wrl = wrl;
204e208dfa2Spirofti 
205e208dfa2Spirofti 	for (i = 0; i < 256; i++)
2066bf2980cSderaadt 		emu->_x86emu_intrTab[i] = NULL;
207e208dfa2Spirofti }
208