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