xref: /openbsd/sys/dev/x86emu/x86emu_util.c (revision 21dab745)
1 /*	$OpenBSD: x86emu_util.c,v 1.6 2015/03/14 03:38:50 jsg Exp $	*/
2 /*	$NetBSD: x86emu_util.c,v 1.2 2007/12/04 17:32:22 joerg Exp $	*/
3 
4 /*
5  *
6  *  Realmode X86 Emulator Library
7  *
8  *  Copyright (C) 1996-1999 SciTech Software, Inc.
9  *  Copyright (C) David Mosberger-Tang
10  *  Copyright (C) 1999 Egbert Eich
11  *  Copyright (C) 2007 Joerg Sonnenberger
12  *
13  *  ========================================================================
14  *
15  *  Permission to use, copy, modify, distribute, and sell this software and
16  *  its documentation for any purpose is hereby granted without fee,
17  *  provided that the above copyright notice appear in all copies and that
18  *  both that copyright notice and this permission notice appear in
19  *  supporting documentation, and that the name of the authors not be used
20  *  in advertising or publicity pertaining to distribution of the software
21  *  without specific, written prior permission.  The authors makes no
22  *  representations about the suitability of this software for any purpose.
23  *  It is provided "as is" without express or implied warranty.
24  *
25  *  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
26  *  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
27  *  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
28  *  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
29  *  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
30  *  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
31  *  PERFORMANCE OF THIS SOFTWARE.
32  *
33  */
34 
35 #include <sys/param.h>
36 #include <sys/endian.h>
37 
38 #include <dev/x86emu/x86emu.h>
39 
40 
41 
42 /*
43  * PARAMETERS:
44  * addr	- Emulator memory address to read
45  *
46  * RETURNS:
47  * Byte value read from emulator memory.
48  *
49  * REMARKS:
50  * Reads a byte value from the emulator memory.
51  */
52 static uint8_t
rdb(struct x86emu * emu,uint32_t addr)53 rdb(struct x86emu *emu, uint32_t addr)
54 {
55 	if (addr > emu->mem_size - 1)
56 		x86emu_halt_sys(emu);
57 	return emu->mem_base[addr];
58 }
59 
60 /*
61  * PARAMETERS:
62  * addr	- Emulator memory address to read
63  *
64  * RETURNS:
65  * Word value read from emulator memory.
66  *
67  * REMARKS:
68  * Reads a word value from the emulator memory.
69  */
70 static uint16_t
rdw(struct x86emu * emu,uint32_t addr)71 rdw(struct x86emu *emu, uint32_t addr)
72 {
73 	if (addr > emu->mem_size - 2)
74 		x86emu_halt_sys(emu);
75 #ifdef __STRICT_ALIGNMENT
76 	if (addr & 1) {
77 		u_int8_t *a = emu->mem_base + addr;
78 		u_int16_t r;
79 
80 		r = ((*(a + 0) << 0) & 0x00ff) |
81 		    ((*(a + 1) << 8) & 0xff00);
82 		return r;
83 	} else
84 		return letoh32(*(u_int32_t *)(emu->mem_base + addr));
85 #else
86 	return letoh16(*(u_int16_t *)(emu->mem_base + addr));
87 #endif
88 }
89 
90 /*
91  * PARAMETERS:
92  * addr	- Emulator memory address to read
93  *
94  * RETURNS:
95  * Long value read from emulator memory.
96  * REMARKS:
97  * Reads a long value from the emulator memory.
98  */
99 static uint32_t
rdl(struct x86emu * emu,uint32_t addr)100 rdl(struct x86emu *emu, uint32_t addr)
101 {
102 	if (addr > emu->mem_size - 4)
103 		x86emu_halt_sys(emu);
104 #ifdef __STRICT_ALIGNMENT
105 	if (addr & 3) {
106 		u_int8_t *a = emu->mem_base + addr;
107 		u_int32_t r;
108 
109 		r = ((*(a + 0) <<  0) & 0x000000ff) |
110 		    ((*(a + 1) <<  8) & 0x0000ff00) |
111 		    ((*(a + 2) << 16) & 0x00ff0000) |
112 		    ((*(a + 3) << 24) & 0xff000000);
113 		return r;
114 	} else
115 		return letoh32(*(u_int32_t *)(emu->mem_base + addr));
116 #else
117 	return letoh32(*(u_int32_t *)(emu->mem_base + addr));
118 #endif
119 }
120 
121 /*
122  * PARAMETERS:
123  * addr	- Emulator memory address to read
124  * val		- Value to store
125  *
126  * REMARKS:
127  * Writes a byte value to emulator memory.
128  */
129 static void
wrb(struct x86emu * emu,uint32_t addr,uint8_t val)130 wrb(struct x86emu *emu, uint32_t addr, uint8_t val)
131 {
132 	if (addr > emu->mem_size - 1)
133 		x86emu_halt_sys(emu);
134 	emu->mem_base[addr] = val;
135 }
136 
137 /*
138  * PARAMETERS:
139  * addr	- Emulator memory address to read
140  * val		- Value to store
141  *
142  * REMARKS:
143  * Writes a word value to emulator memory.
144  */
145 static void
wrw(struct x86emu * emu,uint32_t addr,uint16_t val)146 wrw(struct x86emu *emu, uint32_t addr, uint16_t val)
147 {
148 	if (addr > emu->mem_size - 2)
149 		x86emu_halt_sys(emu);
150 #ifdef __STRICT_ALIGNMENT
151 	if (addr & 1) {
152 		u_int8_t *a = emu->mem_base + addr;
153 
154 		*((a + 0)) = (val >> 0) & 0xff;
155 		*((a + 1)) = (val >> 8) & 0xff;
156 	} else
157 		*((u_int16_t *)(emu->mem_base + addr)) = htole16(val);
158 #else
159 	*((u_int16_t *)(emu->mem_base + addr)) = htole16(val);
160 #endif
161 }
162 
163 /*
164  * PARAMETERS:
165  * addr	- Emulator memory address to read
166  * val		- Value to store
167  *
168  * REMARKS:
169  * Writes a long value to emulator memory.
170  */
171 static void
wrl(struct x86emu * emu,uint32_t addr,uint32_t val)172 wrl(struct x86emu *emu, uint32_t addr, uint32_t val)
173 {
174 	if (addr > emu->mem_size - 4)
175 		x86emu_halt_sys(emu);
176 #ifdef __STRICT_ALIGNMENT
177 	if (addr & 3) {
178 		u_int8_t *a = emu->mem_base + addr;
179 
180 		*((a + 0) = (val >>  0) & 0xff;
181 		*((a + 1) = (val >>  8) & 0xff;
182 		*((a + 2) = (val >> 16) & 0xff;
183 		*((a + 3) = (val >> 24) & 0xff;
184 	} else
185 		*((u_int32_t *)(emu->mem_base + addr)) = htole32(val);
186 #else
187 	*((u_int32_t *)(emu->mem_base + addr)) = htole32(val);
188 #endif
189 }
190 
191 /* Setup */
192 
193 void
194 x86emu_init_default(struct x86emu *emu)
195 {
196 	int i;
197 
198 	emu->emu_rdb = rdb;
199 	emu->emu_rdw = rdw;
200 	emu->emu_rdl = rdl;
201 	emu->emu_wrb = wrb;
202 	emu->emu_wrw = wrw;
203 	emu->emu_wrl = wrl;
204 
205 	for (i = 0; i < 256; i++)
206 		emu->_x86emu_intrTab[i] = NULL;
207 }
208