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