annotate osdep/lrmi.c @ 11434:5084f09ba20e

Fix pthread & lrmi segfault issue. ("Oleg I. Vdovikin" <vdovikin@jscc.ru>)
author ranma
date Tue, 11 Nov 2003 10:39:36 +0000
parents 608666e629b2
children 22f8732b5d97
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2212
f0f681ef92ff LRMI import
nick
parents:
diff changeset
1 /*
f0f681ef92ff LRMI import
nick
parents:
diff changeset
2 Linux Real Mode Interface - A library of DPMI-like functions for Linux.
f0f681ef92ff LRMI import
nick
parents:
diff changeset
3
f0f681ef92ff LRMI import
nick
parents:
diff changeset
4 Copyright (C) 1998 by Josh Vanderhoof
f0f681ef92ff LRMI import
nick
parents:
diff changeset
5
f0f681ef92ff LRMI import
nick
parents:
diff changeset
6 You are free to distribute and modify this file, as long as you
f0f681ef92ff LRMI import
nick
parents:
diff changeset
7 do not remove this copyright notice and clearly label modified
f0f681ef92ff LRMI import
nick
parents:
diff changeset
8 versions as being modified.
f0f681ef92ff LRMI import
nick
parents:
diff changeset
9
f0f681ef92ff LRMI import
nick
parents:
diff changeset
10 This software has NO WARRANTY. Use it at your own risk.
f0f681ef92ff LRMI import
nick
parents:
diff changeset
11 Original location: http://cvs.debian.org/lrmi/
f0f681ef92ff LRMI import
nick
parents:
diff changeset
12 */
f0f681ef92ff LRMI import
nick
parents:
diff changeset
13
11434
5084f09ba20e Fix pthread & lrmi segfault issue. ("Oleg I. Vdovikin" <vdovikin@jscc.ru>)
ranma
parents: 10857
diff changeset
14 #include <signal.h>
2212
f0f681ef92ff LRMI import
nick
parents:
diff changeset
15 #include <stdio.h>
f0f681ef92ff LRMI import
nick
parents:
diff changeset
16 #include <string.h>
f0f681ef92ff LRMI import
nick
parents:
diff changeset
17 #include <sys/io.h>
f0f681ef92ff LRMI import
nick
parents:
diff changeset
18 #include <asm/vm86.h>
f0f681ef92ff LRMI import
nick
parents:
diff changeset
19
f0f681ef92ff LRMI import
nick
parents:
diff changeset
20 #ifdef USE_LIBC_VM86
f0f681ef92ff LRMI import
nick
parents:
diff changeset
21 #include <sys/vm86.h>
f0f681ef92ff LRMI import
nick
parents:
diff changeset
22 #endif
f0f681ef92ff LRMI import
nick
parents:
diff changeset
23
f0f681ef92ff LRMI import
nick
parents:
diff changeset
24 #include <sys/types.h>
f0f681ef92ff LRMI import
nick
parents:
diff changeset
25 #include <sys/stat.h>
f0f681ef92ff LRMI import
nick
parents:
diff changeset
26 #include <sys/mman.h>
f0f681ef92ff LRMI import
nick
parents:
diff changeset
27 #include <unistd.h>
f0f681ef92ff LRMI import
nick
parents:
diff changeset
28 #include <fcntl.h>
f0f681ef92ff LRMI import
nick
parents:
diff changeset
29
f0f681ef92ff LRMI import
nick
parents:
diff changeset
30 #include "lrmi.h"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
31
f0f681ef92ff LRMI import
nick
parents:
diff changeset
32 #define REAL_MEM_BASE ((void *)0x10000)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
33 #define REAL_MEM_SIZE 0x10000
f0f681ef92ff LRMI import
nick
parents:
diff changeset
34 #define REAL_MEM_BLOCKS 0x100
f0f681ef92ff LRMI import
nick
parents:
diff changeset
35
f0f681ef92ff LRMI import
nick
parents:
diff changeset
36 struct mem_block
f0f681ef92ff LRMI import
nick
parents:
diff changeset
37 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
38 unsigned int size : 20;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
39 unsigned int free : 1;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
40 };
f0f681ef92ff LRMI import
nick
parents:
diff changeset
41
f0f681ef92ff LRMI import
nick
parents:
diff changeset
42 static struct
f0f681ef92ff LRMI import
nick
parents:
diff changeset
43 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
44 int ready;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
45 int count;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
46 struct mem_block blocks[REAL_MEM_BLOCKS];
10857
608666e629b2 warning fix (missing C initializer)
pl
parents: 9380
diff changeset
47 } mem_info = { .ready = 0, };
2212
f0f681ef92ff LRMI import
nick
parents:
diff changeset
48
f0f681ef92ff LRMI import
nick
parents:
diff changeset
49 static int
f0f681ef92ff LRMI import
nick
parents:
diff changeset
50 real_mem_init(void)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
51 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
52 void *m;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
53 int fd_zero;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
54
f0f681ef92ff LRMI import
nick
parents:
diff changeset
55 if (mem_info.ready)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
56 return 1;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
57
f0f681ef92ff LRMI import
nick
parents:
diff changeset
58 fd_zero = open("/dev/zero", O_RDONLY);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
59 if (fd_zero == -1)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
60 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
61 perror("open /dev/zero");
f0f681ef92ff LRMI import
nick
parents:
diff changeset
62 return 0;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
63 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
64
f0f681ef92ff LRMI import
nick
parents:
diff changeset
65 m = mmap((void *)REAL_MEM_BASE, REAL_MEM_SIZE,
f0f681ef92ff LRMI import
nick
parents:
diff changeset
66 PROT_READ | PROT_WRITE | PROT_EXEC,
f0f681ef92ff LRMI import
nick
parents:
diff changeset
67 MAP_FIXED | MAP_PRIVATE, fd_zero, 0);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
68
f0f681ef92ff LRMI import
nick
parents:
diff changeset
69 if (m == (void *)-1)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
70 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
71 perror("mmap /dev/zero");
f0f681ef92ff LRMI import
nick
parents:
diff changeset
72 close(fd_zero);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
73 return 0;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
74 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
75
f0f681ef92ff LRMI import
nick
parents:
diff changeset
76 mem_info.ready = 1;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
77 mem_info.count = 1;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
78 mem_info.blocks[0].size = REAL_MEM_SIZE;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
79 mem_info.blocks[0].free = 1;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
80
f0f681ef92ff LRMI import
nick
parents:
diff changeset
81 return 1;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
82 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
83
f0f681ef92ff LRMI import
nick
parents:
diff changeset
84
f0f681ef92ff LRMI import
nick
parents:
diff changeset
85 static void
f0f681ef92ff LRMI import
nick
parents:
diff changeset
86 insert_block(int i)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
87 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
88 memmove(
f0f681ef92ff LRMI import
nick
parents:
diff changeset
89 mem_info.blocks + i + 1,
f0f681ef92ff LRMI import
nick
parents:
diff changeset
90 mem_info.blocks + i,
f0f681ef92ff LRMI import
nick
parents:
diff changeset
91 (mem_info.count - i) * sizeof(struct mem_block));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
92
f0f681ef92ff LRMI import
nick
parents:
diff changeset
93 mem_info.count++;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
94 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
95
f0f681ef92ff LRMI import
nick
parents:
diff changeset
96 static void
f0f681ef92ff LRMI import
nick
parents:
diff changeset
97 delete_block(int i)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
98 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
99 mem_info.count--;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
100
f0f681ef92ff LRMI import
nick
parents:
diff changeset
101 memmove(
f0f681ef92ff LRMI import
nick
parents:
diff changeset
102 mem_info.blocks + i,
f0f681ef92ff LRMI import
nick
parents:
diff changeset
103 mem_info.blocks + i + 1,
f0f681ef92ff LRMI import
nick
parents:
diff changeset
104 (mem_info.count - i) * sizeof(struct mem_block));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
105 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
106
f0f681ef92ff LRMI import
nick
parents:
diff changeset
107 void *
f0f681ef92ff LRMI import
nick
parents:
diff changeset
108 LRMI_alloc_real(int size)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
109 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
110 int i;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
111 char *r = (char *)REAL_MEM_BASE;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
112
f0f681ef92ff LRMI import
nick
parents:
diff changeset
113 if (!mem_info.ready)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
114 return NULL;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
115
f0f681ef92ff LRMI import
nick
parents:
diff changeset
116 if (mem_info.count == REAL_MEM_BLOCKS)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
117 return NULL;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
118
f0f681ef92ff LRMI import
nick
parents:
diff changeset
119 size = (size + 15) & ~15;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
120
f0f681ef92ff LRMI import
nick
parents:
diff changeset
121 for (i = 0; i < mem_info.count; i++)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
122 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
123 if (mem_info.blocks[i].free && size < mem_info.blocks[i].size)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
124 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
125 insert_block(i);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
126
f0f681ef92ff LRMI import
nick
parents:
diff changeset
127 mem_info.blocks[i].size = size;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
128 mem_info.blocks[i].free = 0;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
129 mem_info.blocks[i + 1].size -= size;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
130
f0f681ef92ff LRMI import
nick
parents:
diff changeset
131 return (void *)r;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
132 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
133
f0f681ef92ff LRMI import
nick
parents:
diff changeset
134 r += mem_info.blocks[i].size;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
135 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
136
f0f681ef92ff LRMI import
nick
parents:
diff changeset
137 return NULL;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
138 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
139
f0f681ef92ff LRMI import
nick
parents:
diff changeset
140
f0f681ef92ff LRMI import
nick
parents:
diff changeset
141 void
f0f681ef92ff LRMI import
nick
parents:
diff changeset
142 LRMI_free_real(void *m)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
143 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
144 int i;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
145 char *r = (char *)REAL_MEM_BASE;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
146
f0f681ef92ff LRMI import
nick
parents:
diff changeset
147 if (!mem_info.ready)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
148 return;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
149
f0f681ef92ff LRMI import
nick
parents:
diff changeset
150 i = 0;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
151 while (m != (void *)r)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
152 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
153 r += mem_info.blocks[i].size;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
154 i++;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
155 if (i == mem_info.count)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
156 return;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
157 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
158
f0f681ef92ff LRMI import
nick
parents:
diff changeset
159 mem_info.blocks[i].free = 1;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
160
f0f681ef92ff LRMI import
nick
parents:
diff changeset
161 if (i + 1 < mem_info.count && mem_info.blocks[i + 1].free)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
162 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
163 mem_info.blocks[i].size += mem_info.blocks[i + 1].size;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
164 delete_block(i + 1);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
165 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
166
f0f681ef92ff LRMI import
nick
parents:
diff changeset
167 if (i - 1 >= 0 && mem_info.blocks[i - 1].free)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
168 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
169 mem_info.blocks[i - 1].size += mem_info.blocks[i].size;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
170 delete_block(i);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
171 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
172 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
173
f0f681ef92ff LRMI import
nick
parents:
diff changeset
174
f0f681ef92ff LRMI import
nick
parents:
diff changeset
175 #define DEFAULT_VM86_FLAGS (IF_MASK | IOPL_MASK)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
176 #define DEFAULT_STACK_SIZE 0x1000
f0f681ef92ff LRMI import
nick
parents:
diff changeset
177 #define RETURN_TO_32_INT 255
f0f681ef92ff LRMI import
nick
parents:
diff changeset
178
f0f681ef92ff LRMI import
nick
parents:
diff changeset
179 static struct
f0f681ef92ff LRMI import
nick
parents:
diff changeset
180 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
181 int ready;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
182 unsigned short ret_seg, ret_off;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
183 unsigned short stack_seg, stack_off;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
184 struct vm86_struct vm;
10857
608666e629b2 warning fix (missing C initializer)
pl
parents: 9380
diff changeset
185 } context = { .ready = 0, };
2212
f0f681ef92ff LRMI import
nick
parents:
diff changeset
186
f0f681ef92ff LRMI import
nick
parents:
diff changeset
187
f0f681ef92ff LRMI import
nick
parents:
diff changeset
188 static inline void
f0f681ef92ff LRMI import
nick
parents:
diff changeset
189 set_bit(unsigned int bit, void *array)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
190 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
191 unsigned char *a = array;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
192
f0f681ef92ff LRMI import
nick
parents:
diff changeset
193 a[bit / 8] |= (1 << (bit % 8));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
194 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
195
f0f681ef92ff LRMI import
nick
parents:
diff changeset
196
f0f681ef92ff LRMI import
nick
parents:
diff changeset
197 static inline unsigned int
f0f681ef92ff LRMI import
nick
parents:
diff changeset
198 get_int_seg(int i)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
199 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
200 return *(unsigned short *)(i * 4 + 2);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
201 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
202
f0f681ef92ff LRMI import
nick
parents:
diff changeset
203
f0f681ef92ff LRMI import
nick
parents:
diff changeset
204 static inline unsigned int
f0f681ef92ff LRMI import
nick
parents:
diff changeset
205 get_int_off(int i)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
206 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
207 return *(unsigned short *)(i * 4);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
208 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
209
f0f681ef92ff LRMI import
nick
parents:
diff changeset
210
f0f681ef92ff LRMI import
nick
parents:
diff changeset
211 static inline void
f0f681ef92ff LRMI import
nick
parents:
diff changeset
212 pushw(unsigned short i)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
213 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
214 struct vm86_regs *r = &context.vm.regs;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
215 r->esp -= 2;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
216 *(unsigned short *)(((unsigned int)r->ss << 4) + r->esp) = i;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
217 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
218
f0f681ef92ff LRMI import
nick
parents:
diff changeset
219
f0f681ef92ff LRMI import
nick
parents:
diff changeset
220 int
f0f681ef92ff LRMI import
nick
parents:
diff changeset
221 LRMI_init(void)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
222 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
223 void *m;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
224 int fd_mem;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
225
f0f681ef92ff LRMI import
nick
parents:
diff changeset
226 if (context.ready)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
227 return 1;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
228
f0f681ef92ff LRMI import
nick
parents:
diff changeset
229 if (!real_mem_init())
f0f681ef92ff LRMI import
nick
parents:
diff changeset
230 return 0;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
231
f0f681ef92ff LRMI import
nick
parents:
diff changeset
232 /*
f0f681ef92ff LRMI import
nick
parents:
diff changeset
233 Map the Interrupt Vectors (0x0 - 0x400) + BIOS data (0x400 - 0x502)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
234 and the ROM (0xa0000 - 0x100000)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
235 */
f0f681ef92ff LRMI import
nick
parents:
diff changeset
236 fd_mem = open("/dev/mem", O_RDWR);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
237
f0f681ef92ff LRMI import
nick
parents:
diff changeset
238 if (fd_mem == -1)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
239 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
240 perror("open /dev/mem");
f0f681ef92ff LRMI import
nick
parents:
diff changeset
241 return 0;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
242 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
243
f0f681ef92ff LRMI import
nick
parents:
diff changeset
244 m = mmap((void *)0, 0x502,
f0f681ef92ff LRMI import
nick
parents:
diff changeset
245 PROT_READ | PROT_WRITE | PROT_EXEC,
f0f681ef92ff LRMI import
nick
parents:
diff changeset
246 MAP_FIXED | MAP_PRIVATE, fd_mem, 0);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
247
f0f681ef92ff LRMI import
nick
parents:
diff changeset
248 if (m == (void *)-1)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
249 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
250 perror("mmap /dev/mem");
f0f681ef92ff LRMI import
nick
parents:
diff changeset
251 return 0;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
252 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
253
f0f681ef92ff LRMI import
nick
parents:
diff changeset
254 m = mmap((void *)0xa0000, 0x100000 - 0xa0000,
f0f681ef92ff LRMI import
nick
parents:
diff changeset
255 PROT_READ | PROT_WRITE,
f0f681ef92ff LRMI import
nick
parents:
diff changeset
256 MAP_FIXED | MAP_SHARED, fd_mem, 0xa0000);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
257
f0f681ef92ff LRMI import
nick
parents:
diff changeset
258 if (m == (void *)-1)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
259 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
260 perror("mmap /dev/mem");
f0f681ef92ff LRMI import
nick
parents:
diff changeset
261 return 0;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
262 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
263
f0f681ef92ff LRMI import
nick
parents:
diff changeset
264
f0f681ef92ff LRMI import
nick
parents:
diff changeset
265 /*
f0f681ef92ff LRMI import
nick
parents:
diff changeset
266 Allocate a stack
f0f681ef92ff LRMI import
nick
parents:
diff changeset
267 */
f0f681ef92ff LRMI import
nick
parents:
diff changeset
268 m = LRMI_alloc_real(DEFAULT_STACK_SIZE);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
269
f0f681ef92ff LRMI import
nick
parents:
diff changeset
270 context.stack_seg = (unsigned int)m >> 4;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
271 context.stack_off = DEFAULT_STACK_SIZE;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
272
f0f681ef92ff LRMI import
nick
parents:
diff changeset
273 /*
f0f681ef92ff LRMI import
nick
parents:
diff changeset
274 Allocate the return to 32 bit routine
f0f681ef92ff LRMI import
nick
parents:
diff changeset
275 */
f0f681ef92ff LRMI import
nick
parents:
diff changeset
276 m = LRMI_alloc_real(2);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
277
f0f681ef92ff LRMI import
nick
parents:
diff changeset
278 context.ret_seg = (unsigned int)m >> 4;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
279 context.ret_off = (unsigned int)m & 0xf;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
280
f0f681ef92ff LRMI import
nick
parents:
diff changeset
281 ((unsigned char *)m)[0] = 0xcd; /* int opcode */
f0f681ef92ff LRMI import
nick
parents:
diff changeset
282 ((unsigned char *)m)[1] = RETURN_TO_32_INT;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
283
f0f681ef92ff LRMI import
nick
parents:
diff changeset
284 memset(&context.vm, 0, sizeof(context.vm));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
285
f0f681ef92ff LRMI import
nick
parents:
diff changeset
286 /*
f0f681ef92ff LRMI import
nick
parents:
diff changeset
287 Enable kernel emulation of all ints except RETURN_TO_32_INT
f0f681ef92ff LRMI import
nick
parents:
diff changeset
288 */
f0f681ef92ff LRMI import
nick
parents:
diff changeset
289 memset(&context.vm.int_revectored, 0, sizeof(context.vm.int_revectored));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
290 set_bit(RETURN_TO_32_INT, &context.vm.int_revectored);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
291
f0f681ef92ff LRMI import
nick
parents:
diff changeset
292 context.ready = 1;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
293
f0f681ef92ff LRMI import
nick
parents:
diff changeset
294 return 1;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
295 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
296
f0f681ef92ff LRMI import
nick
parents:
diff changeset
297
f0f681ef92ff LRMI import
nick
parents:
diff changeset
298 static void
f0f681ef92ff LRMI import
nick
parents:
diff changeset
299 set_regs(struct LRMI_regs *r)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
300 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
301 context.vm.regs.edi = r->edi;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
302 context.vm.regs.esi = r->esi;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
303 context.vm.regs.ebp = r->ebp;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
304 context.vm.regs.ebx = r->ebx;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
305 context.vm.regs.edx = r->edx;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
306 context.vm.regs.ecx = r->ecx;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
307 context.vm.regs.eax = r->eax;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
308 context.vm.regs.eflags = DEFAULT_VM86_FLAGS;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
309 context.vm.regs.es = r->es;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
310 context.vm.regs.ds = r->ds;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
311 context.vm.regs.fs = r->fs;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
312 context.vm.regs.gs = r->gs;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
313 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
314
f0f681ef92ff LRMI import
nick
parents:
diff changeset
315
f0f681ef92ff LRMI import
nick
parents:
diff changeset
316 static void
f0f681ef92ff LRMI import
nick
parents:
diff changeset
317 get_regs(struct LRMI_regs *r)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
318 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
319 r->edi = context.vm.regs.edi;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
320 r->esi = context.vm.regs.esi;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
321 r->ebp = context.vm.regs.ebp;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
322 r->ebx = context.vm.regs.ebx;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
323 r->edx = context.vm.regs.edx;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
324 r->ecx = context.vm.regs.ecx;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
325 r->eax = context.vm.regs.eax;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
326 r->flags = context.vm.regs.eflags;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
327 r->es = context.vm.regs.es;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
328 r->ds = context.vm.regs.ds;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
329 r->fs = context.vm.regs.fs;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
330 r->gs = context.vm.regs.gs;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
331 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
332
f0f681ef92ff LRMI import
nick
parents:
diff changeset
333 #define DIRECTION_FLAG (1 << 10)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
334
f0f681ef92ff LRMI import
nick
parents:
diff changeset
335 static void
f0f681ef92ff LRMI import
nick
parents:
diff changeset
336 em_ins(int size)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
337 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
338 unsigned int edx, edi;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
339
f0f681ef92ff LRMI import
nick
parents:
diff changeset
340 edx = context.vm.regs.edx & 0xffff;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
341 edi = context.vm.regs.edi & 0xffff;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
342 edi += (unsigned int)context.vm.regs.ds << 4;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
343
f0f681ef92ff LRMI import
nick
parents:
diff changeset
344 if (context.vm.regs.eflags & DIRECTION_FLAG)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
345 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
346 if (size == 4)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
347 asm volatile ("std; insl; cld"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
348 : "=D" (edi) : "d" (edx), "0" (edi));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
349 else if (size == 2)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
350 asm volatile ("std; insw; cld"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
351 : "=D" (edi) : "d" (edx), "0" (edi));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
352 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
353 asm volatile ("std; insb; cld"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
354 : "=D" (edi) : "d" (edx), "0" (edi));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
355 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
356 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
357 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
358 if (size == 4)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
359 asm volatile ("cld; insl"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
360 : "=D" (edi) : "d" (edx), "0" (edi));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
361 else if (size == 2)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
362 asm volatile ("cld; insw"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
363 : "=D" (edi) : "d" (edx), "0" (edi));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
364 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
365 asm volatile ("cld; insb"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
366 : "=D" (edi) : "d" (edx), "0" (edi));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
367 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
368
f0f681ef92ff LRMI import
nick
parents:
diff changeset
369 edi -= (unsigned int)context.vm.regs.ds << 4;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
370
f0f681ef92ff LRMI import
nick
parents:
diff changeset
371 context.vm.regs.edi &= 0xffff0000;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
372 context.vm.regs.edi |= edi & 0xffff;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
373 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
374
f0f681ef92ff LRMI import
nick
parents:
diff changeset
375 static void
f0f681ef92ff LRMI import
nick
parents:
diff changeset
376 em_rep_ins(int size)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
377 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
378 unsigned int ecx, edx, edi;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
379
f0f681ef92ff LRMI import
nick
parents:
diff changeset
380 ecx = context.vm.regs.ecx & 0xffff;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
381 edx = context.vm.regs.edx & 0xffff;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
382 edi = context.vm.regs.edi & 0xffff;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
383 edi += (unsigned int)context.vm.regs.ds << 4;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
384
f0f681ef92ff LRMI import
nick
parents:
diff changeset
385 if (context.vm.regs.eflags & DIRECTION_FLAG)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
386 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
387 if (size == 4)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
388 asm volatile ("std; rep; insl; cld"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
389 : "=D" (edi), "=c" (ecx)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
390 : "d" (edx), "0" (edi), "1" (ecx));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
391 else if (size == 2)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
392 asm volatile ("std; rep; insw; cld"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
393 : "=D" (edi), "=c" (ecx)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
394 : "d" (edx), "0" (edi), "1" (ecx));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
395 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
396 asm volatile ("std; rep; insb; cld"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
397 : "=D" (edi), "=c" (ecx)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
398 : "d" (edx), "0" (edi), "1" (ecx));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
399 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
400 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
401 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
402 if (size == 4)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
403 asm volatile ("cld; rep; insl"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
404 : "=D" (edi), "=c" (ecx)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
405 : "d" (edx), "0" (edi), "1" (ecx));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
406 else if (size == 2)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
407 asm volatile ("cld; rep; insw"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
408 : "=D" (edi), "=c" (ecx)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
409 : "d" (edx), "0" (edi), "1" (ecx));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
410 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
411 asm volatile ("cld; rep; insb"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
412 : "=D" (edi), "=c" (ecx)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
413 : "d" (edx), "0" (edi), "1" (ecx));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
414 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
415
f0f681ef92ff LRMI import
nick
parents:
diff changeset
416 edi -= (unsigned int)context.vm.regs.ds << 4;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
417
f0f681ef92ff LRMI import
nick
parents:
diff changeset
418 context.vm.regs.edi &= 0xffff0000;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
419 context.vm.regs.edi |= edi & 0xffff;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
420
f0f681ef92ff LRMI import
nick
parents:
diff changeset
421 context.vm.regs.ecx &= 0xffff0000;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
422 context.vm.regs.ecx |= ecx & 0xffff;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
423 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
424
f0f681ef92ff LRMI import
nick
parents:
diff changeset
425 static void
f0f681ef92ff LRMI import
nick
parents:
diff changeset
426 em_outs(int size)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
427 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
428 unsigned int edx, esi;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
429
f0f681ef92ff LRMI import
nick
parents:
diff changeset
430 edx = context.vm.regs.edx & 0xffff;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
431 esi = context.vm.regs.esi & 0xffff;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
432 esi += (unsigned int)context.vm.regs.ds << 4;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
433
f0f681ef92ff LRMI import
nick
parents:
diff changeset
434 if (context.vm.regs.eflags & DIRECTION_FLAG)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
435 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
436 if (size == 4)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
437 asm volatile ("std; outsl; cld"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
438 : "=S" (esi) : "d" (edx), "0" (esi));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
439 else if (size == 2)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
440 asm volatile ("std; outsw; cld"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
441 : "=S" (esi) : "d" (edx), "0" (esi));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
442 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
443 asm volatile ("std; outsb; cld"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
444 : "=S" (esi) : "d" (edx), "0" (esi));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
445 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
446 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
447 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
448 if (size == 4)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
449 asm volatile ("cld; outsl"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
450 : "=S" (esi) : "d" (edx), "0" (esi));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
451 else if (size == 2)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
452 asm volatile ("cld; outsw"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
453 : "=S" (esi) : "d" (edx), "0" (esi));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
454 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
455 asm volatile ("cld; outsb"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
456 : "=S" (esi) : "d" (edx), "0" (esi));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
457 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
458
f0f681ef92ff LRMI import
nick
parents:
diff changeset
459 esi -= (unsigned int)context.vm.regs.ds << 4;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
460
f0f681ef92ff LRMI import
nick
parents:
diff changeset
461 context.vm.regs.esi &= 0xffff0000;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
462 context.vm.regs.esi |= esi & 0xffff;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
463 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
464
f0f681ef92ff LRMI import
nick
parents:
diff changeset
465 static void
f0f681ef92ff LRMI import
nick
parents:
diff changeset
466 em_rep_outs(int size)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
467 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
468 unsigned int ecx, edx, esi;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
469
f0f681ef92ff LRMI import
nick
parents:
diff changeset
470 ecx = context.vm.regs.ecx & 0xffff;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
471 edx = context.vm.regs.edx & 0xffff;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
472 esi = context.vm.regs.esi & 0xffff;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
473 esi += (unsigned int)context.vm.regs.ds << 4;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
474
f0f681ef92ff LRMI import
nick
parents:
diff changeset
475 if (context.vm.regs.eflags & DIRECTION_FLAG)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
476 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
477 if (size == 4)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
478 asm volatile ("std; rep; outsl; cld"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
479 : "=S" (esi), "=c" (ecx)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
480 : "d" (edx), "0" (esi), "1" (ecx));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
481 else if (size == 2)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
482 asm volatile ("std; rep; outsw; cld"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
483 : "=S" (esi), "=c" (ecx)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
484 : "d" (edx), "0" (esi), "1" (ecx));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
485 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
486 asm volatile ("std; rep; outsb; cld"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
487 : "=S" (esi), "=c" (ecx)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
488 : "d" (edx), "0" (esi), "1" (ecx));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
489 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
490 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
491 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
492 if (size == 4)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
493 asm volatile ("cld; rep; outsl"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
494 : "=S" (esi), "=c" (ecx)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
495 : "d" (edx), "0" (esi), "1" (ecx));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
496 else if (size == 2)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
497 asm volatile ("cld; rep; outsw"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
498 : "=S" (esi), "=c" (ecx)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
499 : "d" (edx), "0" (esi), "1" (ecx));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
500 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
501 asm volatile ("cld; rep; outsb"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
502 : "=S" (esi), "=c" (ecx)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
503 : "d" (edx), "0" (esi), "1" (ecx));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
504 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
505
f0f681ef92ff LRMI import
nick
parents:
diff changeset
506 esi -= (unsigned int)context.vm.regs.ds << 4;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
507
f0f681ef92ff LRMI import
nick
parents:
diff changeset
508 context.vm.regs.esi &= 0xffff0000;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
509 context.vm.regs.esi |= esi & 0xffff;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
510
f0f681ef92ff LRMI import
nick
parents:
diff changeset
511 context.vm.regs.ecx &= 0xffff0000;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
512 context.vm.regs.ecx |= ecx & 0xffff;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
513 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
514
f0f681ef92ff LRMI import
nick
parents:
diff changeset
515 static void
f0f681ef92ff LRMI import
nick
parents:
diff changeset
516 em_inbl(unsigned char literal)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
517 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
518 context.vm.regs.eax = inb(literal) & 0xff;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
519 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
520
f0f681ef92ff LRMI import
nick
parents:
diff changeset
521 static void
f0f681ef92ff LRMI import
nick
parents:
diff changeset
522 em_inb(void)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
523 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
524 asm volatile ("inb (%w1), %b0"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
525 : "=a" (context.vm.regs.eax)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
526 : "d" (context.vm.regs.edx), "0" (context.vm.regs.eax));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
527 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
528
f0f681ef92ff LRMI import
nick
parents:
diff changeset
529 static void
f0f681ef92ff LRMI import
nick
parents:
diff changeset
530 em_inw(void)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
531 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
532 asm volatile ("inw (%w1), %w0"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
533 : "=a" (context.vm.regs.eax)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
534 : "d" (context.vm.regs.edx), "0" (context.vm.regs.eax));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
535 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
536
f0f681ef92ff LRMI import
nick
parents:
diff changeset
537 static void
f0f681ef92ff LRMI import
nick
parents:
diff changeset
538 em_inl(void)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
539 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
540 asm volatile ("inl (%w1), %0"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
541 : "=a" (context.vm.regs.eax)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
542 : "d" (context.vm.regs.edx));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
543 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
544
f0f681ef92ff LRMI import
nick
parents:
diff changeset
545 static void
f0f681ef92ff LRMI import
nick
parents:
diff changeset
546 em_outbl(unsigned char literal)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
547 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
548 outb(context.vm.regs.eax & 0xff, literal);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
549 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
550
f0f681ef92ff LRMI import
nick
parents:
diff changeset
551 static void
f0f681ef92ff LRMI import
nick
parents:
diff changeset
552 em_outb(void)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
553 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
554 asm volatile ("outb %b0, (%w1)"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
555 : : "a" (context.vm.regs.eax),
f0f681ef92ff LRMI import
nick
parents:
diff changeset
556 "d" (context.vm.regs.edx));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
557 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
558
f0f681ef92ff LRMI import
nick
parents:
diff changeset
559 static void
f0f681ef92ff LRMI import
nick
parents:
diff changeset
560 em_outw(void)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
561 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
562 asm volatile ("outw %w0, (%w1)"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
563 : : "a" (context.vm.regs.eax),
f0f681ef92ff LRMI import
nick
parents:
diff changeset
564 "d" (context.vm.regs.edx));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
565 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
566
f0f681ef92ff LRMI import
nick
parents:
diff changeset
567 static void
f0f681ef92ff LRMI import
nick
parents:
diff changeset
568 em_outl(void)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
569 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
570 asm volatile ("outl %0, (%w1)"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
571 : : "a" (context.vm.regs.eax),
f0f681ef92ff LRMI import
nick
parents:
diff changeset
572 "d" (context.vm.regs.edx));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
573 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
574
f0f681ef92ff LRMI import
nick
parents:
diff changeset
575 static int
f0f681ef92ff LRMI import
nick
parents:
diff changeset
576 emulate(void)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
577 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
578 unsigned char *insn;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
579 struct
f0f681ef92ff LRMI import
nick
parents:
diff changeset
580 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
581 unsigned int size : 1;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
582 unsigned int rep : 1;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
583 } prefix = { 0, 0 };
f0f681ef92ff LRMI import
nick
parents:
diff changeset
584 int i = 0;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
585
f0f681ef92ff LRMI import
nick
parents:
diff changeset
586 insn = (unsigned char *)((unsigned int)context.vm.regs.cs << 4);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
587 insn += context.vm.regs.eip;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
588
f0f681ef92ff LRMI import
nick
parents:
diff changeset
589 while (1)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
590 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
591 if (insn[i] == 0x66)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
592 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
593 prefix.size = 1 - prefix.size;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
594 i++;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
595 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
596 else if (insn[i] == 0xf3)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
597 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
598 prefix.rep = 1;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
599 i++;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
600 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
601 else if (insn[i] == 0xf0 || insn[i] == 0xf2
f0f681ef92ff LRMI import
nick
parents:
diff changeset
602 || insn[i] == 0x26 || insn[i] == 0x2e
f0f681ef92ff LRMI import
nick
parents:
diff changeset
603 || insn[i] == 0x36 || insn[i] == 0x3e
f0f681ef92ff LRMI import
nick
parents:
diff changeset
604 || insn[i] == 0x64 || insn[i] == 0x65
f0f681ef92ff LRMI import
nick
parents:
diff changeset
605 || insn[i] == 0x67)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
606 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
607 /* these prefixes are just ignored */
f0f681ef92ff LRMI import
nick
parents:
diff changeset
608 i++;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
609 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
610 else if (insn[i] == 0x6c)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
611 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
612 if (prefix.rep)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
613 em_rep_ins(1);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
614 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
615 em_ins(1);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
616 i++;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
617 break;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
618 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
619 else if (insn[i] == 0x6d)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
620 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
621 if (prefix.rep)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
622 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
623 if (prefix.size)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
624 em_rep_ins(4);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
625 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
626 em_rep_ins(2);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
627 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
628 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
629 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
630 if (prefix.size)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
631 em_ins(4);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
632 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
633 em_ins(2);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
634 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
635 i++;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
636 break;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
637 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
638 else if (insn[i] == 0x6e)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
639 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
640 if (prefix.rep)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
641 em_rep_outs(1);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
642 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
643 em_outs(1);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
644 i++;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
645 break;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
646 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
647 else if (insn[i] == 0x6f)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
648 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
649 if (prefix.rep)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
650 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
651 if (prefix.size)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
652 em_rep_outs(4);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
653 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
654 em_rep_outs(2);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
655 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
656 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
657 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
658 if (prefix.size)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
659 em_outs(4);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
660 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
661 em_outs(2);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
662 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
663 i++;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
664 break;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
665 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
666 else if (insn[i] == 0xe4)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
667 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
668 em_inbl(insn[i + 1]);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
669 i += 2;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
670 break;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
671 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
672 else if (insn[i] == 0xe6)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
673 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
674 em_outbl(insn[i + 1]);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
675 i += 2;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
676 break;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
677 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
678 else if (insn[i] == 0xec)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
679 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
680 em_inb();
f0f681ef92ff LRMI import
nick
parents:
diff changeset
681 i++;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
682 break;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
683 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
684 else if (insn[i] == 0xed)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
685 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
686 if (prefix.size)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
687 em_inl();
f0f681ef92ff LRMI import
nick
parents:
diff changeset
688 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
689 em_inw();
f0f681ef92ff LRMI import
nick
parents:
diff changeset
690 i++;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
691 break;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
692 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
693 else if (insn[i] == 0xee)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
694 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
695 em_outb();
f0f681ef92ff LRMI import
nick
parents:
diff changeset
696 i++;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
697 break;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
698 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
699 else if (insn[i] == 0xef)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
700 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
701 if (prefix.size)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
702 em_outl();
f0f681ef92ff LRMI import
nick
parents:
diff changeset
703 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
704 em_outw();
f0f681ef92ff LRMI import
nick
parents:
diff changeset
705
f0f681ef92ff LRMI import
nick
parents:
diff changeset
706 i++;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
707 break;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
708 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
709 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
710 return 0;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
711 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
712
f0f681ef92ff LRMI import
nick
parents:
diff changeset
713 context.vm.regs.eip += i;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
714 return 1;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
715 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
716
f0f681ef92ff LRMI import
nick
parents:
diff changeset
717
f0f681ef92ff LRMI import
nick
parents:
diff changeset
718 /*
f0f681ef92ff LRMI import
nick
parents:
diff changeset
719 I don't know how to make sure I get the right vm86() from libc.
f0f681ef92ff LRMI import
nick
parents:
diff changeset
720 The one I want is syscall # 113 (vm86old() in libc 5, vm86() in glibc)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
721 which should be declared as "int vm86(struct vm86_struct *);" in
f0f681ef92ff LRMI import
nick
parents:
diff changeset
722 <sys/vm86.h>.
f0f681ef92ff LRMI import
nick
parents:
diff changeset
723
f0f681ef92ff LRMI import
nick
parents:
diff changeset
724 This just does syscall 113 with inline asm, which should work
f0f681ef92ff LRMI import
nick
parents:
diff changeset
725 for both libc's (I hope).
f0f681ef92ff LRMI import
nick
parents:
diff changeset
726 */
f0f681ef92ff LRMI import
nick
parents:
diff changeset
727 #if !defined(USE_LIBC_VM86)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
728 static int
f0f681ef92ff LRMI import
nick
parents:
diff changeset
729 lrmi_vm86(struct vm86_struct *vm)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
730 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
731 int r;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
732 #ifdef __PIC__
f0f681ef92ff LRMI import
nick
parents:
diff changeset
733 asm volatile (
f0f681ef92ff LRMI import
nick
parents:
diff changeset
734 "pushl %%ebx\n\t"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
735 "movl %2, %%ebx\n\t"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
736 "int $0x80\n\t"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
737 "popl %%ebx"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
738 : "=a" (r)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
739 : "0" (113), "r" (vm));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
740 #else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
741 asm volatile (
f0f681ef92ff LRMI import
nick
parents:
diff changeset
742 "int $0x80"
f0f681ef92ff LRMI import
nick
parents:
diff changeset
743 : "=a" (r)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
744 : "0" (113), "b" (vm));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
745 #endif
f0f681ef92ff LRMI import
nick
parents:
diff changeset
746 return r;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
747 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
748 #else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
749 #define lrmi_vm86 vm86
f0f681ef92ff LRMI import
nick
parents:
diff changeset
750 #endif
f0f681ef92ff LRMI import
nick
parents:
diff changeset
751
f0f681ef92ff LRMI import
nick
parents:
diff changeset
752
f0f681ef92ff LRMI import
nick
parents:
diff changeset
753 static void
f0f681ef92ff LRMI import
nick
parents:
diff changeset
754 debug_info(int vret)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
755 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
756 int i;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
757 unsigned char *p;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
758
f0f681ef92ff LRMI import
nick
parents:
diff changeset
759 fputs("vm86() failed\n", stderr);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
760 fprintf(stderr, "return = 0x%x\n", vret);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
761 fprintf(stderr, "eax = 0x%08lx\n", context.vm.regs.eax);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
762 fprintf(stderr, "ebx = 0x%08lx\n", context.vm.regs.ebx);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
763 fprintf(stderr, "ecx = 0x%08lx\n", context.vm.regs.ecx);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
764 fprintf(stderr, "edx = 0x%08lx\n", context.vm.regs.edx);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
765 fprintf(stderr, "esi = 0x%08lx\n", context.vm.regs.esi);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
766 fprintf(stderr, "edi = 0x%08lx\n", context.vm.regs.edi);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
767 fprintf(stderr, "ebp = 0x%08lx\n", context.vm.regs.ebp);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
768 fprintf(stderr, "eip = 0x%08lx\n", context.vm.regs.eip);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
769 fprintf(stderr, "cs = 0x%04x\n", context.vm.regs.cs);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
770 fprintf(stderr, "esp = 0x%08lx\n", context.vm.regs.esp);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
771 fprintf(stderr, "ss = 0x%04x\n", context.vm.regs.ss);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
772 fprintf(stderr, "ds = 0x%04x\n", context.vm.regs.ds);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
773 fprintf(stderr, "es = 0x%04x\n", context.vm.regs.es);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
774 fprintf(stderr, "fs = 0x%04x\n", context.vm.regs.fs);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
775 fprintf(stderr, "gs = 0x%04x\n", context.vm.regs.gs);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
776 fprintf(stderr, "eflags = 0x%08lx\n", context.vm.regs.eflags);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
777
f0f681ef92ff LRMI import
nick
parents:
diff changeset
778 fputs("cs:ip = [ ", stderr);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
779
f0f681ef92ff LRMI import
nick
parents:
diff changeset
780 p = (unsigned char *)((context.vm.regs.cs << 4) + (context.vm.regs.eip & 0xffff));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
781
f0f681ef92ff LRMI import
nick
parents:
diff changeset
782 for (i = 0; i < 16; ++i)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
783 fprintf(stderr, "%02x ", (unsigned int)p[i]);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
784
f0f681ef92ff LRMI import
nick
parents:
diff changeset
785 fputs("]\n", stderr);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
786 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
787
f0f681ef92ff LRMI import
nick
parents:
diff changeset
788
f0f681ef92ff LRMI import
nick
parents:
diff changeset
789 static int
f0f681ef92ff LRMI import
nick
parents:
diff changeset
790 run_vm86(void)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
791 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
792 unsigned int vret;
11434
5084f09ba20e Fix pthread & lrmi segfault issue. ("Oleg I. Vdovikin" <vdovikin@jscc.ru>)
ranma
parents: 10857
diff changeset
793 sigset_t allsigs, cursigs;
5084f09ba20e Fix pthread & lrmi segfault issue. ("Oleg I. Vdovikin" <vdovikin@jscc.ru>)
ranma
parents: 10857
diff changeset
794 unsigned long oldgs;
2212
f0f681ef92ff LRMI import
nick
parents:
diff changeset
795
f0f681ef92ff LRMI import
nick
parents:
diff changeset
796 while (1)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
797 {
11434
5084f09ba20e Fix pthread & lrmi segfault issue. ("Oleg I. Vdovikin" <vdovikin@jscc.ru>)
ranma
parents: 10857
diff changeset
798 sigfillset(&allsigs);
5084f09ba20e Fix pthread & lrmi segfault issue. ("Oleg I. Vdovikin" <vdovikin@jscc.ru>)
ranma
parents: 10857
diff changeset
799 sigprocmask(SIG_SETMASK, &allsigs, &cursigs);
5084f09ba20e Fix pthread & lrmi segfault issue. ("Oleg I. Vdovikin" <vdovikin@jscc.ru>)
ranma
parents: 10857
diff changeset
800 asm volatile ("movl %%gs, %0" : "=g" (oldgs));
2212
f0f681ef92ff LRMI import
nick
parents:
diff changeset
801 vret = lrmi_vm86(&context.vm);
11434
5084f09ba20e Fix pthread & lrmi segfault issue. ("Oleg I. Vdovikin" <vdovikin@jscc.ru>)
ranma
parents: 10857
diff changeset
802 asm volatile ("movl %0, %%gs" :: "g" (oldgs));
5084f09ba20e Fix pthread & lrmi segfault issue. ("Oleg I. Vdovikin" <vdovikin@jscc.ru>)
ranma
parents: 10857
diff changeset
803 sigprocmask(SIG_SETMASK, &cursigs, NULL);
2212
f0f681ef92ff LRMI import
nick
parents:
diff changeset
804
f0f681ef92ff LRMI import
nick
parents:
diff changeset
805 if (VM86_TYPE(vret) == VM86_INTx)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
806 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
807 unsigned int v = VM86_ARG(vret);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
808
f0f681ef92ff LRMI import
nick
parents:
diff changeset
809 if (v == RETURN_TO_32_INT)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
810 return 1;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
811
f0f681ef92ff LRMI import
nick
parents:
diff changeset
812 pushw(context.vm.regs.eflags);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
813 pushw(context.vm.regs.cs);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
814 pushw(context.vm.regs.eip);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
815
f0f681ef92ff LRMI import
nick
parents:
diff changeset
816 context.vm.regs.cs = get_int_seg(v);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
817 context.vm.regs.eip = get_int_off(v);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
818 context.vm.regs.eflags &= ~(VIF_MASK | TF_MASK);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
819
f0f681ef92ff LRMI import
nick
parents:
diff changeset
820 continue;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
821 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
822
f0f681ef92ff LRMI import
nick
parents:
diff changeset
823 if (VM86_TYPE(vret) != VM86_UNKNOWN)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
824 break;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
825
f0f681ef92ff LRMI import
nick
parents:
diff changeset
826 if (!emulate())
f0f681ef92ff LRMI import
nick
parents:
diff changeset
827 break;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
828 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
829
f0f681ef92ff LRMI import
nick
parents:
diff changeset
830 #ifdef ORIGINAL_LRMI_CODE_THAT_GOT_IFDEFED_OUT
f0f681ef92ff LRMI import
nick
parents:
diff changeset
831 debug_info(vret);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
832 #endif
f0f681ef92ff LRMI import
nick
parents:
diff changeset
833 return 0;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
834 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
835
f0f681ef92ff LRMI import
nick
parents:
diff changeset
836
f0f681ef92ff LRMI import
nick
parents:
diff changeset
837 int
f0f681ef92ff LRMI import
nick
parents:
diff changeset
838 LRMI_call(struct LRMI_regs *r)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
839 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
840 unsigned int vret;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
841
f0f681ef92ff LRMI import
nick
parents:
diff changeset
842 memset(&context.vm.regs, 0, sizeof(context.vm.regs));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
843
f0f681ef92ff LRMI import
nick
parents:
diff changeset
844 set_regs(r);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
845
f0f681ef92ff LRMI import
nick
parents:
diff changeset
846 context.vm.regs.cs = r->cs;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
847 context.vm.regs.eip = r->ip;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
848
f0f681ef92ff LRMI import
nick
parents:
diff changeset
849 if (r->ss == 0 && r->sp == 0)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
850 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
851 context.vm.regs.ss = context.stack_seg;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
852 context.vm.regs.esp = context.stack_off;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
853 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
854 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
855 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
856 context.vm.regs.ss = r->ss;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
857 context.vm.regs.esp = r->sp;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
858 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
859
f0f681ef92ff LRMI import
nick
parents:
diff changeset
860 pushw(context.ret_seg);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
861 pushw(context.ret_off);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
862
f0f681ef92ff LRMI import
nick
parents:
diff changeset
863 vret = run_vm86();
f0f681ef92ff LRMI import
nick
parents:
diff changeset
864
f0f681ef92ff LRMI import
nick
parents:
diff changeset
865 get_regs(r);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
866
f0f681ef92ff LRMI import
nick
parents:
diff changeset
867 return vret;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
868 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
869
f0f681ef92ff LRMI import
nick
parents:
diff changeset
870
f0f681ef92ff LRMI import
nick
parents:
diff changeset
871 int
f0f681ef92ff LRMI import
nick
parents:
diff changeset
872 LRMI_int(int i, struct LRMI_regs *r)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
873 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
874 unsigned int vret;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
875 unsigned int seg, off;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
876
f0f681ef92ff LRMI import
nick
parents:
diff changeset
877 seg = get_int_seg(i);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
878 off = get_int_off(i);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
879
f0f681ef92ff LRMI import
nick
parents:
diff changeset
880 /*
f0f681ef92ff LRMI import
nick
parents:
diff changeset
881 If the interrupt is in regular memory, it's probably
f0f681ef92ff LRMI import
nick
parents:
diff changeset
882 still pointing at a dos TSR (which is now gone).
f0f681ef92ff LRMI import
nick
parents:
diff changeset
883 */
f0f681ef92ff LRMI import
nick
parents:
diff changeset
884 if (seg < 0xa000 || (seg << 4) + off >= 0x100000)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
885 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
886 #ifdef ORIGINAL_LRMI_CODE_THAT_GOT_IFDEFED_OUT
f0f681ef92ff LRMI import
nick
parents:
diff changeset
887 fprintf(stderr, "Int 0x%x is not in rom (%04x:%04x)\n", i, seg, off);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
888 #endif
f0f681ef92ff LRMI import
nick
parents:
diff changeset
889 return 0;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
890 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
891
f0f681ef92ff LRMI import
nick
parents:
diff changeset
892 memset(&context.vm.regs, 0, sizeof(context.vm.regs));
f0f681ef92ff LRMI import
nick
parents:
diff changeset
893
f0f681ef92ff LRMI import
nick
parents:
diff changeset
894 set_regs(r);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
895
f0f681ef92ff LRMI import
nick
parents:
diff changeset
896 context.vm.regs.cs = seg;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
897 context.vm.regs.eip = off;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
898
f0f681ef92ff LRMI import
nick
parents:
diff changeset
899 if (r->ss == 0 && r->sp == 0)
f0f681ef92ff LRMI import
nick
parents:
diff changeset
900 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
901 context.vm.regs.ss = context.stack_seg;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
902 context.vm.regs.esp = context.stack_off;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
903 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
904 else
f0f681ef92ff LRMI import
nick
parents:
diff changeset
905 {
f0f681ef92ff LRMI import
nick
parents:
diff changeset
906 context.vm.regs.ss = r->ss;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
907 context.vm.regs.esp = r->sp;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
908 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
909
f0f681ef92ff LRMI import
nick
parents:
diff changeset
910 pushw(DEFAULT_VM86_FLAGS);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
911 pushw(context.ret_seg);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
912 pushw(context.ret_off);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
913
f0f681ef92ff LRMI import
nick
parents:
diff changeset
914 vret = run_vm86();
f0f681ef92ff LRMI import
nick
parents:
diff changeset
915
f0f681ef92ff LRMI import
nick
parents:
diff changeset
916 get_regs(r);
f0f681ef92ff LRMI import
nick
parents:
diff changeset
917
f0f681ef92ff LRMI import
nick
parents:
diff changeset
918 return vret;
f0f681ef92ff LRMI import
nick
parents:
diff changeset
919 }
f0f681ef92ff LRMI import
nick
parents:
diff changeset
920