1 #include <sys/types.h>
2 #include <sys/stat.h>
3 #include <sys/mman.h>
4 #include <fcntl.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <stdarg.h>
8 #include <sys/types.h>
9 #include <sys/stat.h>
10 #include <fcntl.h>
11 #include <unistd.h>
12 #include <stdlib.h>
13 #include <sys/mman.h>
14 #if !defined(__FreeBSD__) && !defined(__DragonFly__)
15 #include <sys/io.h>
16 #endif
17 #include <string.h>
18 #include <sys/ipc.h>
19 #include <sys/shm.h>
20
21 #define SHMERRORPTR (pointer)(-1)
22
23 #define _INT10_PRIVATE
24 #include "x86emu/include/xf86int10.h"
25 #include "x86emu/include/x86emu.h"
26 #include "x86emu/include/xf86x86emu.h"
27 #include "lrmi.h"
28 #include "x86-common.h"
29
30 #ifndef DEBUG
31 #define DEBUG
32 #endif
33 #define ALLOC_ENTRIES(x) (V_RAM - 1)
34 #define TRUE 1
35 #define FALSE 0
36
37 #define __BUILDIO(bwl,bw,type) \
38 static inline void out##bwl##_local(unsigned long port, unsigned type value) { __asm__ __volatile__("out" #bwl " %" #bw "0, %w1" : : "a"(value), "Nd"(port)); \
39 }\
40 static inline unsigned type in##bwl##_local(unsigned long port) { \
41 unsigned type value; \
42 __asm__ __volatile__("in" #bwl " %w1, %" #bw "0" : "=a"(value) : "Nd"(port)); \
43 return value; \
44 }\
45
46 __BUILDIO(b,b,char)
47 __BUILDIO(w,w,short)
48 __BUILDIO(l,,int)
49
50
51 char *mmap_addr = SHMERRORPTR;
52 struct LRMI_regs *regs;
53 static void *stack;
54
55
56 void
printk(const char * fmt,...)57 printk(const char *fmt, ...)
58 {
59 va_list argptr;
60 va_start(argptr, fmt);
61
62 fprintf(stderr, fmt, argptr);
63 va_end(argptr);
64 }
65
read_b(int addr)66 u8 read_b(int addr) {
67 return *((char *)mmap_addr + addr);
68 }
69
70 CARD8
x_inb(CARD16 port)71 x_inb(CARD16 port)
72 {
73 CARD8 val;
74 val = inb_local(port);
75 return val;
76 }
77
78 CARD16
x_inw(CARD16 port)79 x_inw(CARD16 port)
80 {
81 CARD16 val;
82 val = inw_local(port);
83 return val;
84 }
85
86 CARD32
x_inl(CARD16 port)87 x_inl(CARD16 port)
88 {
89 CARD32 val;
90 val = inl_local(port);
91 return val;
92 }
93
94 void
x_outb(CARD16 port,CARD8 val)95 x_outb(CARD16 port, CARD8 val)
96 {
97 outb_local(port, val);
98 }
99
100 void
x_outw(CARD16 port,CARD16 val)101 x_outw(CARD16 port, CARD16 val)
102 {
103 outw_local(port, val);
104 }
105
x_outl(CARD16 port,CARD32 val)106 void x_outl(CARD16 port, CARD32 val)
107 {
108 outl_local(port, val);
109 }
110
pushw(u16 val)111 void pushw(u16 val)
112 {
113 X86_ESP -= 2;
114 MEM_WW(((u32) X86_SS << 4) + X86_SP, val);
115 }
116
x86emu_do_int(int num)117 static void x86emu_do_int(int num)
118 {
119 u32 eflags;
120
121 /* fprintf(stderr, "Calling INT 0x%X (%04X:%04X)\n", num,
122 (read_b((num << 2) + 3) << 8) + read_b((num << 2) + 2),
123 (read_b((num << 2) + 1) << 8) + read_b((num << 2)));
124
125 fprintf(stderr, " EAX is %X\n", (int) X86_EAX);
126 */
127
128 eflags = X86_EFLAGS;
129 eflags = eflags | X86_IF_MASK;
130 pushw(eflags);
131 pushw(X86_CS);
132 pushw(X86_IP);
133 X86_EFLAGS = X86_EFLAGS & ~(X86_VIF_MASK | X86_TF_MASK);
134 X86_CS = (read_b((num << 2) + 3) << 8) + read_b((num << 2) + 2);
135 X86_IP = (read_b((num << 2) + 1) << 8) + read_b((num << 2));
136
137 /* fprintf(stderr, "Leaving interrupt call.\n"); */
138 }
139
LRMI_init()140 int LRMI_init() {
141 int i;
142 X86EMU_intrFuncs intFuncs[256];
143
144 if (!LRMI_common_init())
145 return 0;
146
147 mmap_addr = 0;
148
149 X86EMU_pioFuncs pioFuncs = {
150 (&x_inb),
151 (&x_inw),
152 (&x_inl),
153 (&x_outb),
154 (&x_outw),
155 (&x_outl)
156 };
157
158 X86EMU_setupPioFuncs(&pioFuncs);
159
160 for (i=0;i<256;i++)
161 intFuncs[i] = x86emu_do_int;
162 X86EMU_setupIntrFuncs(intFuncs);
163
164 X86_EFLAGS = X86_IF_MASK | X86_IOPL_MASK;
165
166 /*
167 * Allocate a 64k stack.
168 */
169 stack = LRMI_alloc_real(64 * 1024);
170 X86_SS = (unsigned int) stack >> 4;
171 X86_ESP = 0xFFF9;
172 memset (stack, 0, 64*1024);
173
174 *((volatile char *)0) = 0x4f; /* Make sure that we end up jumping back to a
175 halt instruction */
176
177 M.mem_base = 0;
178 M.mem_size = 1024*1024;
179
180 return 1;
181 }
182
real_call(struct LRMI_regs * registers)183 int real_call(struct LRMI_regs *registers) {
184 regs = registers;
185
186 X86_EAX = registers->eax;
187 X86_EBX = registers->ebx;
188 X86_ECX = registers->ecx;
189 X86_EDX = registers->edx;
190 X86_ESI = registers->esi;
191 X86_EDI = registers->edi;
192 X86_EBP = registers->ebp;
193 X86_EIP = registers->ip;
194 X86_ES = registers->es;
195 X86_FS = registers->fs;
196 X86_GS = registers->gs;
197 X86_CS = registers->cs;
198
199 if (registers->ss != 0) {
200 X86_SS = registers->ss;
201 } else {
202 X86_SS = (unsigned int) stack >> 4;
203 }
204
205 if (registers->ds != 0) {
206 X86_DS = registers->ds;
207 }
208
209 if (registers->sp != 0) {
210 X86_ESP = registers->sp;
211 } else {
212 X86_ESP = 0xFFF9;
213 }
214
215 M.x86.debug |= DEBUG_DECODE_F;
216
217 memset (stack, 0, 64*1024);
218
219 X86EMU_exec();
220
221 registers->eax = X86_EAX;
222 registers->ebx = X86_EBX;
223 registers->ecx = X86_ECX;
224 registers->edx = X86_EDX;
225 registers->esi = X86_ESI;
226 registers->edi = X86_EDI;
227 registers->ebp = X86_EBP;
228 registers->es = X86_ES;
229
230 return 1;
231 }
232
LRMI_int(int num,struct LRMI_regs * registers)233 int LRMI_int(int num, struct LRMI_regs *registers) {
234 u32 eflags;
235 eflags = X86_EFLAGS;
236 eflags = eflags | X86_IF_MASK;
237 X86_EFLAGS = X86_EFLAGS & ~(X86_VIF_MASK | X86_TF_MASK | X86_IF_MASK | X86_NT_MASK);
238
239 registers->cs = (read_b((num << 2) + 3) << 8) + read_b((num << 2) + 2);
240 registers->ip = (read_b((num << 2) + 1) << 8) + read_b((num << 2));
241 regs = registers;
242 return real_call(registers);
243 }
244
LRMI_call(struct LRMI_regs * registers)245 int LRMI_call(struct LRMI_regs *registers) {
246 return real_call(registers);
247 }
248
249 size_t
LRMI_base_addr(void)250 LRMI_base_addr(void)
251 {
252 return (size_t)mmap_addr;
253 }
254