Commit 31fc12df2c15a79e75a78288a552797a1be47f25
1 parent
e9c28334
BSD user: initial support for i386 and x86_64 targets
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@7084 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
6 changed files
with
674 additions
and
2 deletions
bsd-user/i386/syscall.h
0 → 100644
1 | +/* default linux values for the selectors */ | |
2 | +#define __USER_CS (0x23) | |
3 | +#define __USER_DS (0x2B) | |
4 | + | |
5 | +struct target_pt_regs { | |
6 | + long ebx; | |
7 | + long ecx; | |
8 | + long edx; | |
9 | + long esi; | |
10 | + long edi; | |
11 | + long ebp; | |
12 | + long eax; | |
13 | + int xds; | |
14 | + int xes; | |
15 | + long orig_eax; | |
16 | + long eip; | |
17 | + int xcs; | |
18 | + long eflags; | |
19 | + long esp; | |
20 | + int xss; | |
21 | +}; | |
22 | + | |
23 | +/* ioctls */ | |
24 | + | |
25 | +#define TARGET_LDT_ENTRIES 8192 | |
26 | +#define TARGET_LDT_ENTRY_SIZE 8 | |
27 | + | |
28 | +#define TARGET_GDT_ENTRIES 9 | |
29 | +#define TARGET_GDT_ENTRY_TLS_ENTRIES 3 | |
30 | +#define TARGET_GDT_ENTRY_TLS_MIN 6 | |
31 | +#define TARGET_GDT_ENTRY_TLS_MAX (TARGET_GDT_ENTRY_TLS_MIN + TARGET_GDT_ENTRY_TLS_ENTRIES - 1) | |
32 | + | |
33 | +struct target_modify_ldt_ldt_s { | |
34 | + unsigned int entry_number; | |
35 | + abi_ulong base_addr; | |
36 | + unsigned int limit; | |
37 | + unsigned int flags; | |
38 | +}; | |
39 | + | |
40 | +/* vm86 defines */ | |
41 | + | |
42 | +#define TARGET_BIOSSEG 0x0f000 | |
43 | + | |
44 | +#define TARGET_CPU_086 0 | |
45 | +#define TARGET_CPU_186 1 | |
46 | +#define TARGET_CPU_286 2 | |
47 | +#define TARGET_CPU_386 3 | |
48 | +#define TARGET_CPU_486 4 | |
49 | +#define TARGET_CPU_586 5 | |
50 | + | |
51 | +#define TARGET_VM86_SIGNAL 0 /* return due to signal */ | |
52 | +#define TARGET_VM86_UNKNOWN 1 /* unhandled GP fault - IO-instruction or similar */ | |
53 | +#define TARGET_VM86_INTx 2 /* int3/int x instruction (ARG = x) */ | |
54 | +#define TARGET_VM86_STI 3 /* sti/popf/iret instruction enabled virtual interrupts */ | |
55 | + | |
56 | +/* | |
57 | + * Additional return values when invoking new vm86() | |
58 | + */ | |
59 | +#define TARGET_VM86_PICRETURN 4 /* return due to pending PIC request */ | |
60 | +#define TARGET_VM86_TRAP 6 /* return due to DOS-debugger request */ | |
61 | + | |
62 | +/* | |
63 | + * function codes when invoking new vm86() | |
64 | + */ | |
65 | +#define TARGET_VM86_PLUS_INSTALL_CHECK 0 | |
66 | +#define TARGET_VM86_ENTER 1 | |
67 | +#define TARGET_VM86_ENTER_NO_BYPASS 2 | |
68 | +#define TARGET_VM86_REQUEST_IRQ 3 | |
69 | +#define TARGET_VM86_FREE_IRQ 4 | |
70 | +#define TARGET_VM86_GET_IRQ_BITS 5 | |
71 | +#define TARGET_VM86_GET_AND_RESET_IRQ 6 | |
72 | + | |
73 | +/* | |
74 | + * This is the stack-layout seen by the user space program when we have | |
75 | + * done a translation of "SAVE_ALL" from vm86 mode. The real kernel layout | |
76 | + * is 'kernel_vm86_regs' (see below). | |
77 | + */ | |
78 | + | |
79 | +struct target_vm86_regs { | |
80 | +/* | |
81 | + * normal regs, with special meaning for the segment descriptors.. | |
82 | + */ | |
83 | + abi_long ebx; | |
84 | + abi_long ecx; | |
85 | + abi_long edx; | |
86 | + abi_long esi; | |
87 | + abi_long edi; | |
88 | + abi_long ebp; | |
89 | + abi_long eax; | |
90 | + abi_long __null_ds; | |
91 | + abi_long __null_es; | |
92 | + abi_long __null_fs; | |
93 | + abi_long __null_gs; | |
94 | + abi_long orig_eax; | |
95 | + abi_long eip; | |
96 | + unsigned short cs, __csh; | |
97 | + abi_long eflags; | |
98 | + abi_long esp; | |
99 | + unsigned short ss, __ssh; | |
100 | +/* | |
101 | + * these are specific to v86 mode: | |
102 | + */ | |
103 | + unsigned short es, __esh; | |
104 | + unsigned short ds, __dsh; | |
105 | + unsigned short fs, __fsh; | |
106 | + unsigned short gs, __gsh; | |
107 | +}; | |
108 | + | |
109 | +struct target_revectored_struct { | |
110 | + abi_ulong __map[8]; /* 256 bits */ | |
111 | +}; | |
112 | + | |
113 | +struct target_vm86_struct { | |
114 | + struct target_vm86_regs regs; | |
115 | + abi_ulong flags; | |
116 | + abi_ulong screen_bitmap; | |
117 | + abi_ulong cpu_type; | |
118 | + struct target_revectored_struct int_revectored; | |
119 | + struct target_revectored_struct int21_revectored; | |
120 | +}; | |
121 | + | |
122 | +/* | |
123 | + * flags masks | |
124 | + */ | |
125 | +#define TARGET_VM86_SCREEN_BITMAP 0x0001 | |
126 | + | |
127 | +struct target_vm86plus_info_struct { | |
128 | + abi_ulong flags; | |
129 | +#define TARGET_force_return_for_pic (1 << 0) | |
130 | +#define TARGET_vm86dbg_active (1 << 1) /* for debugger */ | |
131 | +#define TARGET_vm86dbg_TFpendig (1 << 2) /* for debugger */ | |
132 | +#define TARGET_is_vm86pus (1 << 31) /* for vm86 internal use */ | |
133 | + unsigned char vm86dbg_intxxtab[32]; /* for debugger */ | |
134 | +}; | |
135 | + | |
136 | +struct target_vm86plus_struct { | |
137 | + struct target_vm86_regs regs; | |
138 | + abi_ulong flags; | |
139 | + abi_ulong screen_bitmap; | |
140 | + abi_ulong cpu_type; | |
141 | + struct target_revectored_struct int_revectored; | |
142 | + struct target_revectored_struct int21_revectored; | |
143 | + struct target_vm86plus_info_struct vm86plus; | |
144 | +}; | |
145 | + | |
146 | +#define UNAME_MACHINE "i386" | |
147 | + | ... | ... |
bsd-user/i386/target_signal.h
0 → 100644
1 | +#ifndef TARGET_SIGNAL_H | |
2 | +#define TARGET_SIGNAL_H | |
3 | + | |
4 | +#include "cpu.h" | |
5 | + | |
6 | +/* this struct defines a stack used during syscall handling */ | |
7 | + | |
8 | +typedef struct target_sigaltstack { | |
9 | + abi_ulong ss_sp; | |
10 | + abi_long ss_flags; | |
11 | + abi_ulong ss_size; | |
12 | +} target_stack_t; | |
13 | + | |
14 | + | |
15 | +static inline abi_ulong get_sp_from_cpustate(CPUX86State *state) | |
16 | +{ | |
17 | + return state->regs[R_ESP]; | |
18 | +} | |
19 | + | |
20 | +#endif /* TARGET_SIGNAL_H */ | ... | ... |
bsd-user/main.c
... | ... | @@ -25,6 +25,8 @@ |
25 | 25 | #include <errno.h> |
26 | 26 | #include <unistd.h> |
27 | 27 | #include <machine/trap.h> |
28 | +#include <sys/types.h> | |
29 | +#include <sys/mman.h> | |
28 | 30 | |
29 | 31 | #include "qemu.h" |
30 | 32 | #include "qemu-common.h" |
... | ... | @@ -53,6 +55,46 @@ void gemu_log(const char *fmt, ...) |
53 | 55 | va_end(ap); |
54 | 56 | } |
55 | 57 | |
58 | +void cpu_outb(CPUState *env, int addr, int val) | |
59 | +{ | |
60 | + fprintf(stderr, "outb: port=0x%04x, data=%02x\n", addr, val); | |
61 | +} | |
62 | + | |
63 | +void cpu_outw(CPUState *env, int addr, int val) | |
64 | +{ | |
65 | + fprintf(stderr, "outw: port=0x%04x, data=%04x\n", addr, val); | |
66 | +} | |
67 | + | |
68 | +void cpu_outl(CPUState *env, int addr, int val) | |
69 | +{ | |
70 | + fprintf(stderr, "outl: port=0x%04x, data=%08x\n", addr, val); | |
71 | +} | |
72 | + | |
73 | +int cpu_inb(CPUState *env, int addr) | |
74 | +{ | |
75 | + fprintf(stderr, "inb: port=0x%04x\n", addr); | |
76 | + return 0; | |
77 | +} | |
78 | + | |
79 | +int cpu_inw(CPUState *env, int addr) | |
80 | +{ | |
81 | + fprintf(stderr, "inw: port=0x%04x\n", addr); | |
82 | + return 0; | |
83 | +} | |
84 | + | |
85 | +int cpu_inl(CPUState *env, int addr) | |
86 | +{ | |
87 | + fprintf(stderr, "inl: port=0x%04x\n", addr); | |
88 | + return 0; | |
89 | +} | |
90 | + | |
91 | +#if defined(TARGET_I386) | |
92 | +int cpu_get_pic_interrupt(CPUState *env) | |
93 | +{ | |
94 | + return -1; | |
95 | +} | |
96 | +#endif | |
97 | + | |
56 | 98 | /* These are no-ops because we are not threadsafe. */ |
57 | 99 | static inline void cpu_exec_start(CPUState *env) |
58 | 100 | { |
... | ... | @@ -89,6 +131,226 @@ void cpu_list_unlock(void) |
89 | 131 | { |
90 | 132 | } |
91 | 133 | |
134 | +#ifdef TARGET_I386 | |
135 | +/***********************************************************/ | |
136 | +/* CPUX86 core interface */ | |
137 | + | |
138 | +void cpu_smm_update(CPUState *env) | |
139 | +{ | |
140 | +} | |
141 | + | |
142 | +uint64_t cpu_get_tsc(CPUX86State *env) | |
143 | +{ | |
144 | + return cpu_get_real_ticks(); | |
145 | +} | |
146 | + | |
147 | +static void write_dt(void *ptr, unsigned long addr, unsigned long limit, | |
148 | + int flags) | |
149 | +{ | |
150 | + unsigned int e1, e2; | |
151 | + uint32_t *p; | |
152 | + e1 = (addr << 16) | (limit & 0xffff); | |
153 | + e2 = ((addr >> 16) & 0xff) | (addr & 0xff000000) | (limit & 0x000f0000); | |
154 | + e2 |= flags; | |
155 | + p = ptr; | |
156 | + p[0] = tswap32(e1); | |
157 | + p[1] = tswap32(e2); | |
158 | +} | |
159 | + | |
160 | +static uint64_t *idt_table; | |
161 | +#ifdef TARGET_X86_64 | |
162 | +static void set_gate64(void *ptr, unsigned int type, unsigned int dpl, | |
163 | + uint64_t addr, unsigned int sel) | |
164 | +{ | |
165 | + uint32_t *p, e1, e2; | |
166 | + e1 = (addr & 0xffff) | (sel << 16); | |
167 | + e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8); | |
168 | + p = ptr; | |
169 | + p[0] = tswap32(e1); | |
170 | + p[1] = tswap32(e2); | |
171 | + p[2] = tswap32(addr >> 32); | |
172 | + p[3] = 0; | |
173 | +} | |
174 | +/* only dpl matters as we do only user space emulation */ | |
175 | +static void set_idt(int n, unsigned int dpl) | |
176 | +{ | |
177 | + set_gate64(idt_table + n * 2, 0, dpl, 0, 0); | |
178 | +} | |
179 | +#else | |
180 | +static void set_gate(void *ptr, unsigned int type, unsigned int dpl, | |
181 | + uint32_t addr, unsigned int sel) | |
182 | +{ | |
183 | + uint32_t *p, e1, e2; | |
184 | + e1 = (addr & 0xffff) | (sel << 16); | |
185 | + e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8); | |
186 | + p = ptr; | |
187 | + p[0] = tswap32(e1); | |
188 | + p[1] = tswap32(e2); | |
189 | +} | |
190 | + | |
191 | +/* only dpl matters as we do only user space emulation */ | |
192 | +static void set_idt(int n, unsigned int dpl) | |
193 | +{ | |
194 | + set_gate(idt_table + n, 0, dpl, 0, 0); | |
195 | +} | |
196 | +#endif | |
197 | + | |
198 | +void cpu_loop(CPUX86State *env, enum BSDType bsd_type) | |
199 | +{ | |
200 | + int trapnr; | |
201 | + abi_ulong pc; | |
202 | + //target_siginfo_t info; | |
203 | + | |
204 | + for(;;) { | |
205 | + trapnr = cpu_x86_exec(env); | |
206 | + switch(trapnr) { | |
207 | + case 0x80: | |
208 | + /* syscall from int $0x80 */ | |
209 | + env->regs[R_EAX] = do_openbsd_syscall(env, | |
210 | + env->regs[R_EAX], | |
211 | + env->regs[R_EBX], | |
212 | + env->regs[R_ECX], | |
213 | + env->regs[R_EDX], | |
214 | + env->regs[R_ESI], | |
215 | + env->regs[R_EDI], | |
216 | + env->regs[R_EBP]); | |
217 | + break; | |
218 | +#ifndef TARGET_ABI32 | |
219 | + case EXCP_SYSCALL: | |
220 | + /* linux syscall from syscall intruction */ | |
221 | + env->regs[R_EAX] = do_openbsd_syscall(env, | |
222 | + env->regs[R_EAX], | |
223 | + env->regs[R_EDI], | |
224 | + env->regs[R_ESI], | |
225 | + env->regs[R_EDX], | |
226 | + env->regs[10], | |
227 | + env->regs[8], | |
228 | + env->regs[9]); | |
229 | + env->eip = env->exception_next_eip; | |
230 | + break; | |
231 | +#endif | |
232 | +#if 0 | |
233 | + case EXCP0B_NOSEG: | |
234 | + case EXCP0C_STACK: | |
235 | + info.si_signo = SIGBUS; | |
236 | + info.si_errno = 0; | |
237 | + info.si_code = TARGET_SI_KERNEL; | |
238 | + info._sifields._sigfault._addr = 0; | |
239 | + queue_signal(env, info.si_signo, &info); | |
240 | + break; | |
241 | + case EXCP0D_GPF: | |
242 | + /* XXX: potential problem if ABI32 */ | |
243 | +#ifndef TARGET_X86_64 | |
244 | + if (env->eflags & VM_MASK) { | |
245 | + handle_vm86_fault(env); | |
246 | + } else | |
247 | +#endif | |
248 | + { | |
249 | + info.si_signo = SIGSEGV; | |
250 | + info.si_errno = 0; | |
251 | + info.si_code = TARGET_SI_KERNEL; | |
252 | + info._sifields._sigfault._addr = 0; | |
253 | + queue_signal(env, info.si_signo, &info); | |
254 | + } | |
255 | + break; | |
256 | + case EXCP0E_PAGE: | |
257 | + info.si_signo = SIGSEGV; | |
258 | + info.si_errno = 0; | |
259 | + if (!(env->error_code & 1)) | |
260 | + info.si_code = TARGET_SEGV_MAPERR; | |
261 | + else | |
262 | + info.si_code = TARGET_SEGV_ACCERR; | |
263 | + info._sifields._sigfault._addr = env->cr[2]; | |
264 | + queue_signal(env, info.si_signo, &info); | |
265 | + break; | |
266 | + case EXCP00_DIVZ: | |
267 | +#ifndef TARGET_X86_64 | |
268 | + if (env->eflags & VM_MASK) { | |
269 | + handle_vm86_trap(env, trapnr); | |
270 | + } else | |
271 | +#endif | |
272 | + { | |
273 | + /* division by zero */ | |
274 | + info.si_signo = SIGFPE; | |
275 | + info.si_errno = 0; | |
276 | + info.si_code = TARGET_FPE_INTDIV; | |
277 | + info._sifields._sigfault._addr = env->eip; | |
278 | + queue_signal(env, info.si_signo, &info); | |
279 | + } | |
280 | + break; | |
281 | + case EXCP01_DB: | |
282 | + case EXCP03_INT3: | |
283 | +#ifndef TARGET_X86_64 | |
284 | + if (env->eflags & VM_MASK) { | |
285 | + handle_vm86_trap(env, trapnr); | |
286 | + } else | |
287 | +#endif | |
288 | + { | |
289 | + info.si_signo = SIGTRAP; | |
290 | + info.si_errno = 0; | |
291 | + if (trapnr == EXCP01_DB) { | |
292 | + info.si_code = TARGET_TRAP_BRKPT; | |
293 | + info._sifields._sigfault._addr = env->eip; | |
294 | + } else { | |
295 | + info.si_code = TARGET_SI_KERNEL; | |
296 | + info._sifields._sigfault._addr = 0; | |
297 | + } | |
298 | + queue_signal(env, info.si_signo, &info); | |
299 | + } | |
300 | + break; | |
301 | + case EXCP04_INTO: | |
302 | + case EXCP05_BOUND: | |
303 | +#ifndef TARGET_X86_64 | |
304 | + if (env->eflags & VM_MASK) { | |
305 | + handle_vm86_trap(env, trapnr); | |
306 | + } else | |
307 | +#endif | |
308 | + { | |
309 | + info.si_signo = SIGSEGV; | |
310 | + info.si_errno = 0; | |
311 | + info.si_code = TARGET_SI_KERNEL; | |
312 | + info._sifields._sigfault._addr = 0; | |
313 | + queue_signal(env, info.si_signo, &info); | |
314 | + } | |
315 | + break; | |
316 | + case EXCP06_ILLOP: | |
317 | + info.si_signo = SIGILL; | |
318 | + info.si_errno = 0; | |
319 | + info.si_code = TARGET_ILL_ILLOPN; | |
320 | + info._sifields._sigfault._addr = env->eip; | |
321 | + queue_signal(env, info.si_signo, &info); | |
322 | + break; | |
323 | +#endif | |
324 | + case EXCP_INTERRUPT: | |
325 | + /* just indicate that signals should be handled asap */ | |
326 | + break; | |
327 | +#if 0 | |
328 | + case EXCP_DEBUG: | |
329 | + { | |
330 | + int sig; | |
331 | + | |
332 | + sig = gdb_handlesig (env, TARGET_SIGTRAP); | |
333 | + if (sig) | |
334 | + { | |
335 | + info.si_signo = sig; | |
336 | + info.si_errno = 0; | |
337 | + info.si_code = TARGET_TRAP_BRKPT; | |
338 | + queue_signal(env, info.si_signo, &info); | |
339 | + } | |
340 | + } | |
341 | + break; | |
342 | +#endif | |
343 | + default: | |
344 | + pc = env->segs[R_CS].base + env->eip; | |
345 | + fprintf(stderr, "qemu: 0x%08lx: unhandled CPU exception 0x%x - aborting\n", | |
346 | + (long)pc, trapnr); | |
347 | + abort(); | |
348 | + } | |
349 | + process_pending_signals(env); | |
350 | + } | |
351 | +} | |
352 | +#endif | |
353 | + | |
92 | 354 | #ifdef TARGET_SPARC |
93 | 355 | #define SPARC64_STACK_BIAS 2047 |
94 | 356 | |
... | ... | @@ -526,7 +788,13 @@ int main(int argc, char **argv) |
526 | 788 | init_paths(interp_prefix); |
527 | 789 | |
528 | 790 | if (cpu_model == NULL) { |
529 | -#if defined(TARGET_SPARC) | |
791 | +#if defined(TARGET_I386) | |
792 | +#ifdef TARGET_X86_64 | |
793 | + cpu_model = "qemu64"; | |
794 | +#else | |
795 | + cpu_model = "qemu32"; | |
796 | +#endif | |
797 | +#elif defined(TARGET_SPARC) | |
530 | 798 | #ifdef TARGET_SPARC64 |
531 | 799 | cpu_model = "TI UltraSparc II"; |
532 | 800 | #else |
... | ... | @@ -601,7 +869,124 @@ int main(int argc, char **argv) |
601 | 869 | ts->info = info; |
602 | 870 | env->opaque = ts; |
603 | 871 | |
604 | -#if defined(TARGET_SPARC) | |
872 | +#if defined(TARGET_I386) | |
873 | + cpu_x86_set_cpl(env, 3); | |
874 | + | |
875 | + env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK; | |
876 | + env->hflags |= HF_PE_MASK; | |
877 | + if (env->cpuid_features & CPUID_SSE) { | |
878 | + env->cr[4] |= CR4_OSFXSR_MASK; | |
879 | + env->hflags |= HF_OSFXSR_MASK; | |
880 | + } | |
881 | +#ifndef TARGET_ABI32 | |
882 | + /* enable 64 bit mode if possible */ | |
883 | + if (!(env->cpuid_ext2_features & CPUID_EXT2_LM)) { | |
884 | + fprintf(stderr, "The selected x86 CPU does not support 64 bit mode\n"); | |
885 | + exit(1); | |
886 | + } | |
887 | + env->cr[4] |= CR4_PAE_MASK; | |
888 | + env->efer |= MSR_EFER_LMA | MSR_EFER_LME; | |
889 | + env->hflags |= HF_LMA_MASK; | |
890 | +#endif | |
891 | + | |
892 | + /* flags setup : we activate the IRQs by default as in user mode */ | |
893 | + env->eflags |= IF_MASK; | |
894 | + | |
895 | + /* linux register setup */ | |
896 | +#ifndef TARGET_ABI32 | |
897 | + env->regs[R_EAX] = regs->rax; | |
898 | + env->regs[R_EBX] = regs->rbx; | |
899 | + env->regs[R_ECX] = regs->rcx; | |
900 | + env->regs[R_EDX] = regs->rdx; | |
901 | + env->regs[R_ESI] = regs->rsi; | |
902 | + env->regs[R_EDI] = regs->rdi; | |
903 | + env->regs[R_EBP] = regs->rbp; | |
904 | + env->regs[R_ESP] = regs->rsp; | |
905 | + env->eip = regs->rip; | |
906 | +#else | |
907 | + env->regs[R_EAX] = regs->eax; | |
908 | + env->regs[R_EBX] = regs->ebx; | |
909 | + env->regs[R_ECX] = regs->ecx; | |
910 | + env->regs[R_EDX] = regs->edx; | |
911 | + env->regs[R_ESI] = regs->esi; | |
912 | + env->regs[R_EDI] = regs->edi; | |
913 | + env->regs[R_EBP] = regs->ebp; | |
914 | + env->regs[R_ESP] = regs->esp; | |
915 | + env->eip = regs->eip; | |
916 | +#endif | |
917 | + | |
918 | + /* linux interrupt setup */ | |
919 | +#ifndef TARGET_ABI32 | |
920 | + env->idt.limit = 511; | |
921 | +#else | |
922 | + env->idt.limit = 255; | |
923 | +#endif | |
924 | + env->idt.base = target_mmap(0, sizeof(uint64_t) * (env->idt.limit + 1), | |
925 | + PROT_READ|PROT_WRITE, | |
926 | + MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); | |
927 | + idt_table = g2h(env->idt.base); | |
928 | + set_idt(0, 0); | |
929 | + set_idt(1, 0); | |
930 | + set_idt(2, 0); | |
931 | + set_idt(3, 3); | |
932 | + set_idt(4, 3); | |
933 | + set_idt(5, 0); | |
934 | + set_idt(6, 0); | |
935 | + set_idt(7, 0); | |
936 | + set_idt(8, 0); | |
937 | + set_idt(9, 0); | |
938 | + set_idt(10, 0); | |
939 | + set_idt(11, 0); | |
940 | + set_idt(12, 0); | |
941 | + set_idt(13, 0); | |
942 | + set_idt(14, 0); | |
943 | + set_idt(15, 0); | |
944 | + set_idt(16, 0); | |
945 | + set_idt(17, 0); | |
946 | + set_idt(18, 0); | |
947 | + set_idt(19, 0); | |
948 | + set_idt(0x80, 3); | |
949 | + | |
950 | + /* linux segment setup */ | |
951 | + { | |
952 | + uint64_t *gdt_table; | |
953 | + env->gdt.base = target_mmap(0, sizeof(uint64_t) * TARGET_GDT_ENTRIES, | |
954 | + PROT_READ|PROT_WRITE, | |
955 | + MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); | |
956 | + env->gdt.limit = sizeof(uint64_t) * TARGET_GDT_ENTRIES - 1; | |
957 | + gdt_table = g2h(env->gdt.base); | |
958 | +#ifdef TARGET_ABI32 | |
959 | + write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff, | |
960 | + DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK | | |
961 | + (3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT)); | |
962 | +#else | |
963 | + /* 64 bit code segment */ | |
964 | + write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff, | |
965 | + DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK | | |
966 | + DESC_L_MASK | | |
967 | + (3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT)); | |
968 | +#endif | |
969 | + write_dt(&gdt_table[__USER_DS >> 3], 0, 0xfffff, | |
970 | + DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK | | |
971 | + (3 << DESC_DPL_SHIFT) | (0x2 << DESC_TYPE_SHIFT)); | |
972 | + } | |
973 | + | |
974 | + cpu_x86_load_seg(env, R_CS, __USER_CS); | |
975 | + cpu_x86_load_seg(env, R_SS, __USER_DS); | |
976 | +#ifdef TARGET_ABI32 | |
977 | + cpu_x86_load_seg(env, R_DS, __USER_DS); | |
978 | + cpu_x86_load_seg(env, R_ES, __USER_DS); | |
979 | + cpu_x86_load_seg(env, R_FS, __USER_DS); | |
980 | + cpu_x86_load_seg(env, R_GS, __USER_DS); | |
981 | + /* This hack makes Wine work... */ | |
982 | + env->segs[R_FS].selector = 0; | |
983 | +#else | |
984 | + cpu_x86_load_seg(env, R_DS, 0); | |
985 | + cpu_x86_load_seg(env, R_ES, 0); | |
986 | + cpu_x86_load_seg(env, R_FS, 0); | |
987 | + cpu_x86_load_seg(env, R_GS, 0); | |
988 | +#endif | |
989 | +#elif defined(TARGET_SPARC) | |
605 | 990 | { |
606 | 991 | int i; |
607 | 992 | env->pc = regs->pc; | ... | ... |
bsd-user/x86_64/syscall.h
0 → 100644
1 | +#define __USER_CS (0x33) | |
2 | +#define __USER_DS (0x2B) | |
3 | + | |
4 | +struct target_pt_regs { | |
5 | + abi_ulong r15; | |
6 | + abi_ulong r14; | |
7 | + abi_ulong r13; | |
8 | + abi_ulong r12; | |
9 | + abi_ulong rbp; | |
10 | + abi_ulong rbx; | |
11 | +/* arguments: non interrupts/non tracing syscalls only save upto here*/ | |
12 | + abi_ulong r11; | |
13 | + abi_ulong r10; | |
14 | + abi_ulong r9; | |
15 | + abi_ulong r8; | |
16 | + abi_ulong rax; | |
17 | + abi_ulong rcx; | |
18 | + abi_ulong rdx; | |
19 | + abi_ulong rsi; | |
20 | + abi_ulong rdi; | |
21 | + abi_ulong orig_rax; | |
22 | +/* end of arguments */ | |
23 | +/* cpu exception frame or undefined */ | |
24 | + abi_ulong rip; | |
25 | + abi_ulong cs; | |
26 | + abi_ulong eflags; | |
27 | + abi_ulong rsp; | |
28 | + abi_ulong ss; | |
29 | +/* top of stack page */ | |
30 | +}; | |
31 | + | |
32 | +/* Maximum number of LDT entries supported. */ | |
33 | +#define TARGET_LDT_ENTRIES 8192 | |
34 | +/* The size of each LDT entry. */ | |
35 | +#define TARGET_LDT_ENTRY_SIZE 8 | |
36 | + | |
37 | +#define TARGET_GDT_ENTRIES 16 | |
38 | +#define TARGET_GDT_ENTRY_TLS_ENTRIES 3 | |
39 | +#define TARGET_GDT_ENTRY_TLS_MIN 12 | |
40 | +#define TARGET_GDT_ENTRY_TLS_MAX 14 | |
41 | + | |
42 | +#if 0 // Redefine this | |
43 | +struct target_modify_ldt_ldt_s { | |
44 | + unsigned int entry_number; | |
45 | + abi_ulong base_addr; | |
46 | + unsigned int limit; | |
47 | + unsigned int seg_32bit:1; | |
48 | + unsigned int contents:2; | |
49 | + unsigned int read_exec_only:1; | |
50 | + unsigned int limit_in_pages:1; | |
51 | + unsigned int seg_not_present:1; | |
52 | + unsigned int useable:1; | |
53 | + unsigned int lm:1; | |
54 | +}; | |
55 | +#else | |
56 | +struct target_modify_ldt_ldt_s { | |
57 | + unsigned int entry_number; | |
58 | + abi_ulong base_addr; | |
59 | + unsigned int limit; | |
60 | + unsigned int flags; | |
61 | +}; | |
62 | +#endif | |
63 | + | |
64 | +struct target_ipc64_perm | |
65 | +{ | |
66 | + int key; | |
67 | + uint32_t uid; | |
68 | + uint32_t gid; | |
69 | + uint32_t cuid; | |
70 | + uint32_t cgid; | |
71 | + unsigned short mode; | |
72 | + unsigned short __pad1; | |
73 | + unsigned short seq; | |
74 | + unsigned short __pad2; | |
75 | + abi_ulong __unused1; | |
76 | + abi_ulong __unused2; | |
77 | +}; | |
78 | + | |
79 | +struct target_msqid64_ds { | |
80 | + struct target_ipc64_perm msg_perm; | |
81 | + unsigned int msg_stime; /* last msgsnd time */ | |
82 | + unsigned int msg_rtime; /* last msgrcv time */ | |
83 | + unsigned int msg_ctime; /* last change time */ | |
84 | + abi_ulong msg_cbytes; /* current number of bytes on queue */ | |
85 | + abi_ulong msg_qnum; /* number of messages in queue */ | |
86 | + abi_ulong msg_qbytes; /* max number of bytes on queue */ | |
87 | + unsigned int msg_lspid; /* pid of last msgsnd */ | |
88 | + unsigned int msg_lrpid; /* last receive pid */ | |
89 | + abi_ulong __unused4; | |
90 | + abi_ulong __unused5; | |
91 | +}; | |
92 | + | |
93 | +#define UNAME_MACHINE "x86_64" | |
94 | + | |
95 | +#define TARGET_ARCH_SET_GS 0x1001 | |
96 | +#define TARGET_ARCH_SET_FS 0x1002 | |
97 | +#define TARGET_ARCH_GET_FS 0x1003 | |
98 | +#define TARGET_ARCH_GET_GS 0x1004 | ... | ... |
bsd-user/x86_64/target_signal.h
0 → 100644
1 | +#ifndef TARGET_SIGNAL_H | |
2 | +#define TARGET_SIGNAL_H | |
3 | + | |
4 | +#include "cpu.h" | |
5 | + | |
6 | +/* this struct defines a stack used during syscall handling */ | |
7 | + | |
8 | +typedef struct target_sigaltstack { | |
9 | + abi_ulong ss_sp; | |
10 | + abi_long ss_flags; | |
11 | + abi_ulong ss_size; | |
12 | +} target_stack_t; | |
13 | + | |
14 | +static inline abi_ulong get_sp_from_cpustate(CPUX86State *state) | |
15 | +{ | |
16 | + return state->regs[R_ESP]; | |
17 | +} | |
18 | + | |
19 | +#endif /* TARGET_SIGNAL_H */ | ... | ... |
configure