|
|
1.1 root 1: /*
2: * qemu user main
1.1.1.6 root 3: *
4: * Copyright (c) 2003-2008 Fabrice Bellard
1.1 root 5: *
6: * This program is free software; you can redistribute it and/or modify
7: * it under the terms of the GNU General Public License as published by
8: * the Free Software Foundation; either version 2 of the License, or
9: * (at your option) any later version.
10: *
11: * This program is distributed in the hope that it will be useful,
12: * but WITHOUT ANY WARRANTY; without even the implied warranty of
13: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14: * GNU General Public License for more details.
15: *
16: * You should have received a copy of the GNU General Public License
1.1.1.8 root 17: * along with this program; if not, see <http://www.gnu.org/licenses/>.
1.1 root 18: */
19: #include <stdlib.h>
20: #include <stdio.h>
21: #include <stdarg.h>
22: #include <string.h>
23: #include <errno.h>
24: #include <unistd.h>
1.1.1.7 root 25: #include <sys/mman.h>
1.1.1.8 root 26: #include <sys/syscall.h>
1.1 root 27:
28: #include "qemu.h"
1.1.1.7 root 29: #include "qemu-common.h"
30: #include "cache-utils.h"
31: /* For tb_lock */
32: #include "exec-all.h"
33:
34:
35: #include "envlist.h"
1.1 root 36:
37: #define DEBUG_LOGFILE "/tmp/qemu.log"
38:
1.1.1.7 root 39: char *exec_path;
40:
1.1.1.8 root 41: int singlestep;
1.1.1.9 root 42: #if defined(CONFIG_USE_GUEST_BASE)
43: unsigned long mmap_min_addr;
44: unsigned long guest_base;
45: int have_guest_base;
46: #endif
1.1.1.8 root 47:
1.1 root 48: static const char *interp_prefix = CONFIG_QEMU_PREFIX;
1.1.1.4 root 49: const char *qemu_uname_release = CONFIG_UNAME_RELEASE;
1.1 root 50:
51: /* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
52: we allocate a bigger stack. Need a better solution, for example
53: by remapping the process stack directly at the right place */
54: unsigned long x86_stack_size = 512 * 1024;
55:
56: void gemu_log(const char *fmt, ...)
57: {
58: va_list ap;
59:
60: va_start(ap, fmt);
61: vfprintf(stderr, fmt, ap);
62: va_end(ap);
63: }
64:
1.1.1.7 root 65: #if defined(TARGET_I386)
1.1 root 66: int cpu_get_pic_interrupt(CPUState *env)
67: {
68: return -1;
69: }
1.1.1.7 root 70: #endif
1.1 root 71:
72: /* timers for rdtsc */
73:
1.1.1.4 root 74: #if 0
1.1 root 75:
76: static uint64_t emu_time;
77:
78: int64_t cpu_get_real_ticks(void)
79: {
80: return emu_time++;
81: }
82:
83: #endif
84:
1.1.1.9 root 85: #if defined(CONFIG_USE_NPTL)
1.1.1.7 root 86: /***********************************************************/
87: /* Helper routines for implementing atomic operations. */
88:
89: /* To implement exclusive operations we force all cpus to syncronise.
90: We don't require a full sync, only that no cpus are executing guest code.
91: The alternative is to map target atomic ops onto host equivalents,
92: which requires quite a lot of per host/target work. */
1.1.1.8 root 93: static pthread_mutex_t cpu_list_mutex = PTHREAD_MUTEX_INITIALIZER;
1.1.1.7 root 94: static pthread_mutex_t exclusive_lock = PTHREAD_MUTEX_INITIALIZER;
95: static pthread_cond_t exclusive_cond = PTHREAD_COND_INITIALIZER;
96: static pthread_cond_t exclusive_resume = PTHREAD_COND_INITIALIZER;
97: static int pending_cpus;
98:
99: /* Make sure everything is in a consistent state for calling fork(). */
100: void fork_start(void)
101: {
102: mmap_fork_start();
103: pthread_mutex_lock(&tb_lock);
104: pthread_mutex_lock(&exclusive_lock);
105: }
106:
107: void fork_end(int child)
108: {
109: if (child) {
110: /* Child processes created by fork() only have a single thread.
111: Discard information about the parent threads. */
112: first_cpu = thread_env;
113: thread_env->next_cpu = NULL;
114: pending_cpus = 0;
115: pthread_mutex_init(&exclusive_lock, NULL);
1.1.1.8 root 116: pthread_mutex_init(&cpu_list_mutex, NULL);
1.1.1.7 root 117: pthread_cond_init(&exclusive_cond, NULL);
118: pthread_cond_init(&exclusive_resume, NULL);
119: pthread_mutex_init(&tb_lock, NULL);
120: gdbserver_fork(thread_env);
121: } else {
122: pthread_mutex_unlock(&exclusive_lock);
123: pthread_mutex_unlock(&tb_lock);
124: }
125: mmap_fork_end(child);
126: }
127:
128: /* Wait for pending exclusive operations to complete. The exclusive lock
129: must be held. */
130: static inline void exclusive_idle(void)
131: {
132: while (pending_cpus) {
133: pthread_cond_wait(&exclusive_resume, &exclusive_lock);
134: }
135: }
136:
137: /* Start an exclusive operation.
138: Must only be called from outside cpu_arm_exec. */
139: static inline void start_exclusive(void)
140: {
141: CPUState *other;
142: pthread_mutex_lock(&exclusive_lock);
143: exclusive_idle();
144:
145: pending_cpus = 1;
146: /* Make all other cpus stop executing. */
147: for (other = first_cpu; other; other = other->next_cpu) {
148: if (other->running) {
149: pending_cpus++;
1.1.1.8 root 150: cpu_exit(other);
1.1.1.7 root 151: }
152: }
153: if (pending_cpus > 1) {
154: pthread_cond_wait(&exclusive_cond, &exclusive_lock);
155: }
156: }
157:
158: /* Finish an exclusive operation. */
159: static inline void end_exclusive(void)
160: {
161: pending_cpus = 0;
162: pthread_cond_broadcast(&exclusive_resume);
163: pthread_mutex_unlock(&exclusive_lock);
164: }
165:
166: /* Wait for exclusive ops to finish, and begin cpu execution. */
167: static inline void cpu_exec_start(CPUState *env)
168: {
169: pthread_mutex_lock(&exclusive_lock);
170: exclusive_idle();
171: env->running = 1;
172: pthread_mutex_unlock(&exclusive_lock);
173: }
174:
175: /* Mark cpu as not executing, and release pending exclusive ops. */
176: static inline void cpu_exec_end(CPUState *env)
177: {
178: pthread_mutex_lock(&exclusive_lock);
179: env->running = 0;
180: if (pending_cpus > 1) {
181: pending_cpus--;
182: if (pending_cpus == 1) {
183: pthread_cond_signal(&exclusive_cond);
184: }
185: }
186: exclusive_idle();
187: pthread_mutex_unlock(&exclusive_lock);
188: }
1.1.1.8 root 189:
190: void cpu_list_lock(void)
191: {
192: pthread_mutex_lock(&cpu_list_mutex);
193: }
194:
195: void cpu_list_unlock(void)
196: {
197: pthread_mutex_unlock(&cpu_list_mutex);
198: }
1.1.1.9 root 199: #else /* if !CONFIG_USE_NPTL */
1.1.1.7 root 200: /* These are no-ops because we are not threadsafe. */
201: static inline void cpu_exec_start(CPUState *env)
202: {
203: }
204:
205: static inline void cpu_exec_end(CPUState *env)
206: {
207: }
208:
209: static inline void start_exclusive(void)
210: {
211: }
212:
213: static inline void end_exclusive(void)
214: {
215: }
216:
217: void fork_start(void)
218: {
219: }
220:
221: void fork_end(int child)
222: {
223: if (child) {
224: gdbserver_fork(thread_env);
225: }
226: }
1.1.1.8 root 227:
228: void cpu_list_lock(void)
229: {
230: }
231:
232: void cpu_list_unlock(void)
233: {
234: }
1.1.1.7 root 235: #endif
236:
237:
1.1 root 238: #ifdef TARGET_I386
239: /***********************************************************/
240: /* CPUX86 core interface */
241:
1.1.1.5 root 242: void cpu_smm_update(CPUState *env)
243: {
244: }
245:
1.1 root 246: uint64_t cpu_get_tsc(CPUX86State *env)
247: {
248: return cpu_get_real_ticks();
249: }
250:
1.1.1.6 root 251: static void write_dt(void *ptr, unsigned long addr, unsigned long limit,
1.1 root 252: int flags)
253: {
254: unsigned int e1, e2;
1.1.1.3 root 255: uint32_t *p;
1.1 root 256: e1 = (addr << 16) | (limit & 0xffff);
257: e2 = ((addr >> 16) & 0xff) | (addr & 0xff000000) | (limit & 0x000f0000);
258: e2 |= flags;
1.1.1.3 root 259: p = ptr;
1.1.1.7 root 260: p[0] = tswap32(e1);
261: p[1] = tswap32(e2);
1.1 root 262: }
263:
1.1.1.7 root 264: static uint64_t *idt_table;
265: #ifdef TARGET_X86_64
1.1.1.6 root 266: static void set_gate64(void *ptr, unsigned int type, unsigned int dpl,
267: uint64_t addr, unsigned int sel)
1.1 root 268: {
1.1.1.6 root 269: uint32_t *p, e1, e2;
1.1 root 270: e1 = (addr & 0xffff) | (sel << 16);
271: e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8);
1.1.1.3 root 272: p = ptr;
1.1.1.6 root 273: p[0] = tswap32(e1);
274: p[1] = tswap32(e2);
275: p[2] = tswap32(addr >> 32);
276: p[3] = 0;
1.1 root 277: }
1.1.1.6 root 278: /* only dpl matters as we do only user space emulation */
279: static void set_idt(int n, unsigned int dpl)
280: {
281: set_gate64(idt_table + n * 2, 0, dpl, 0, 0);
282: }
283: #else
284: static void set_gate(void *ptr, unsigned int type, unsigned int dpl,
285: uint32_t addr, unsigned int sel)
286: {
287: uint32_t *p, e1, e2;
288: e1 = (addr & 0xffff) | (sel << 16);
289: e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8);
290: p = ptr;
291: p[0] = tswap32(e1);
292: p[1] = tswap32(e2);
293: }
294:
1.1 root 295: /* only dpl matters as we do only user space emulation */
296: static void set_idt(int n, unsigned int dpl)
297: {
298: set_gate(idt_table + n, 0, dpl, 0, 0);
299: }
1.1.1.6 root 300: #endif
1.1 root 301:
302: void cpu_loop(CPUX86State *env)
303: {
304: int trapnr;
1.1.1.6 root 305: abi_ulong pc;
1.1 root 306: target_siginfo_t info;
307:
308: for(;;) {
309: trapnr = cpu_x86_exec(env);
310: switch(trapnr) {
311: case 0x80:
1.1.1.6 root 312: /* linux syscall from int $0x80 */
313: env->regs[R_EAX] = do_syscall(env,
314: env->regs[R_EAX],
1.1 root 315: env->regs[R_EBX],
316: env->regs[R_ECX],
317: env->regs[R_EDX],
318: env->regs[R_ESI],
319: env->regs[R_EDI],
320: env->regs[R_EBP]);
321: break;
1.1.1.6 root 322: #ifndef TARGET_ABI32
323: case EXCP_SYSCALL:
324: /* linux syscall from syscall intruction */
325: env->regs[R_EAX] = do_syscall(env,
326: env->regs[R_EAX],
327: env->regs[R_EDI],
328: env->regs[R_ESI],
329: env->regs[R_EDX],
330: env->regs[10],
331: env->regs[8],
332: env->regs[9]);
333: env->eip = env->exception_next_eip;
334: break;
335: #endif
1.1 root 336: case EXCP0B_NOSEG:
337: case EXCP0C_STACK:
338: info.si_signo = SIGBUS;
339: info.si_errno = 0;
340: info.si_code = TARGET_SI_KERNEL;
341: info._sifields._sigfault._addr = 0;
1.1.1.7 root 342: queue_signal(env, info.si_signo, &info);
1.1 root 343: break;
344: case EXCP0D_GPF:
1.1.1.6 root 345: /* XXX: potential problem if ABI32 */
346: #ifndef TARGET_X86_64
1.1 root 347: if (env->eflags & VM_MASK) {
348: handle_vm86_fault(env);
1.1.1.6 root 349: } else
350: #endif
351: {
1.1 root 352: info.si_signo = SIGSEGV;
353: info.si_errno = 0;
354: info.si_code = TARGET_SI_KERNEL;
355: info._sifields._sigfault._addr = 0;
1.1.1.7 root 356: queue_signal(env, info.si_signo, &info);
1.1 root 357: }
358: break;
359: case EXCP0E_PAGE:
360: info.si_signo = SIGSEGV;
361: info.si_errno = 0;
362: if (!(env->error_code & 1))
363: info.si_code = TARGET_SEGV_MAPERR;
364: else
365: info.si_code = TARGET_SEGV_ACCERR;
366: info._sifields._sigfault._addr = env->cr[2];
1.1.1.7 root 367: queue_signal(env, info.si_signo, &info);
1.1 root 368: break;
369: case EXCP00_DIVZ:
1.1.1.6 root 370: #ifndef TARGET_X86_64
1.1 root 371: if (env->eflags & VM_MASK) {
372: handle_vm86_trap(env, trapnr);
1.1.1.6 root 373: } else
374: #endif
375: {
1.1 root 376: /* division by zero */
377: info.si_signo = SIGFPE;
378: info.si_errno = 0;
379: info.si_code = TARGET_FPE_INTDIV;
380: info._sifields._sigfault._addr = env->eip;
1.1.1.7 root 381: queue_signal(env, info.si_signo, &info);
1.1 root 382: }
383: break;
1.1.1.7 root 384: case EXCP01_DB:
1.1 root 385: case EXCP03_INT3:
1.1.1.6 root 386: #ifndef TARGET_X86_64
1.1 root 387: if (env->eflags & VM_MASK) {
388: handle_vm86_trap(env, trapnr);
1.1.1.6 root 389: } else
390: #endif
391: {
1.1 root 392: info.si_signo = SIGTRAP;
393: info.si_errno = 0;
1.1.1.7 root 394: if (trapnr == EXCP01_DB) {
1.1 root 395: info.si_code = TARGET_TRAP_BRKPT;
396: info._sifields._sigfault._addr = env->eip;
397: } else {
398: info.si_code = TARGET_SI_KERNEL;
399: info._sifields._sigfault._addr = 0;
400: }
1.1.1.7 root 401: queue_signal(env, info.si_signo, &info);
1.1 root 402: }
403: break;
404: case EXCP04_INTO:
405: case EXCP05_BOUND:
1.1.1.6 root 406: #ifndef TARGET_X86_64
1.1 root 407: if (env->eflags & VM_MASK) {
408: handle_vm86_trap(env, trapnr);
1.1.1.6 root 409: } else
410: #endif
411: {
1.1 root 412: info.si_signo = SIGSEGV;
413: info.si_errno = 0;
414: info.si_code = TARGET_SI_KERNEL;
415: info._sifields._sigfault._addr = 0;
1.1.1.7 root 416: queue_signal(env, info.si_signo, &info);
1.1 root 417: }
418: break;
419: case EXCP06_ILLOP:
420: info.si_signo = SIGILL;
421: info.si_errno = 0;
422: info.si_code = TARGET_ILL_ILLOPN;
423: info._sifields._sigfault._addr = env->eip;
1.1.1.7 root 424: queue_signal(env, info.si_signo, &info);
1.1 root 425: break;
426: case EXCP_INTERRUPT:
427: /* just indicate that signals should be handled asap */
428: break;
429: case EXCP_DEBUG:
430: {
431: int sig;
432:
433: sig = gdb_handlesig (env, TARGET_SIGTRAP);
434: if (sig)
435: {
436: info.si_signo = sig;
437: info.si_errno = 0;
438: info.si_code = TARGET_TRAP_BRKPT;
1.1.1.7 root 439: queue_signal(env, info.si_signo, &info);
1.1 root 440: }
441: }
442: break;
443: default:
444: pc = env->segs[R_CS].base + env->eip;
1.1.1.6 root 445: fprintf(stderr, "qemu: 0x%08lx: unhandled CPU exception 0x%x - aborting\n",
1.1 root 446: (long)pc, trapnr);
447: abort();
448: }
449: process_pending_signals(env);
450: }
451: }
452: #endif
453:
454: #ifdef TARGET_ARM
455:
1.1.1.6 root 456: static void arm_cache_flush(abi_ulong start, abi_ulong last)
1.1 root 457: {
1.1.1.6 root 458: abi_ulong addr, last1;
1.1 root 459:
460: if (last < start)
461: return;
462: addr = start;
463: for(;;) {
464: last1 = ((addr + TARGET_PAGE_SIZE) & TARGET_PAGE_MASK) - 1;
465: if (last1 > last)
466: last1 = last;
467: tb_invalidate_page_range(addr, last1 + 1);
468: if (last1 == last)
469: break;
470: addr = last1 + 1;
471: }
472: }
473:
1.1.1.7 root 474: /* Handle a jump to the kernel code page. */
475: static int
476: do_kernel_trap(CPUARMState *env)
477: {
478: uint32_t addr;
479: uint32_t cpsr;
480: uint32_t val;
481:
482: switch (env->regs[15]) {
483: case 0xffff0fa0: /* __kernel_memory_barrier */
484: /* ??? No-op. Will need to do better for SMP. */
485: break;
486: case 0xffff0fc0: /* __kernel_cmpxchg */
487: /* XXX: This only works between threads, not between processes.
488: It's probably possible to implement this with native host
489: operations. However things like ldrex/strex are much harder so
490: there's not much point trying. */
491: start_exclusive();
492: cpsr = cpsr_read(env);
493: addr = env->regs[2];
494: /* FIXME: This should SEGV if the access fails. */
495: if (get_user_u32(val, addr))
496: val = ~env->regs[0];
497: if (val == env->regs[0]) {
498: val = env->regs[1];
499: /* FIXME: Check for segfaults. */
500: put_user_u32(val, addr);
501: env->regs[0] = 0;
502: cpsr |= CPSR_C;
503: } else {
504: env->regs[0] = -1;
505: cpsr &= ~CPSR_C;
506: }
507: cpsr_write(env, cpsr, CPSR_C);
508: end_exclusive();
509: break;
510: case 0xffff0fe0: /* __kernel_get_tls */
511: env->regs[0] = env->cp15.c13_tls2;
512: break;
513: default:
514: return 1;
515: }
516: /* Jump back to the caller. */
517: addr = env->regs[14];
518: if (addr & 1) {
519: env->thumb = 1;
520: addr &= ~1;
521: }
522: env->regs[15] = addr;
523:
524: return 0;
525: }
526:
1.1.1.9 root 527: static int do_strex(CPUARMState *env)
528: {
529: uint32_t val;
530: int size;
531: int rc = 1;
532: int segv = 0;
533: uint32_t addr;
534: start_exclusive();
535: addr = env->exclusive_addr;
536: if (addr != env->exclusive_test) {
537: goto fail;
538: }
539: size = env->exclusive_info & 0xf;
540: switch (size) {
541: case 0:
542: segv = get_user_u8(val, addr);
543: break;
544: case 1:
545: segv = get_user_u16(val, addr);
546: break;
547: case 2:
548: case 3:
549: segv = get_user_u32(val, addr);
550: break;
551: }
552: if (segv) {
553: env->cp15.c6_data = addr;
554: goto done;
555: }
556: if (val != env->exclusive_val) {
557: goto fail;
558: }
559: if (size == 3) {
560: segv = get_user_u32(val, addr + 4);
561: if (segv) {
562: env->cp15.c6_data = addr + 4;
563: goto done;
564: }
565: if (val != env->exclusive_high) {
566: goto fail;
567: }
568: }
569: val = env->regs[(env->exclusive_info >> 8) & 0xf];
570: switch (size) {
571: case 0:
572: segv = put_user_u8(val, addr);
573: break;
574: case 1:
575: segv = put_user_u16(val, addr);
576: break;
577: case 2:
578: case 3:
579: segv = put_user_u32(val, addr);
580: break;
581: }
582: if (segv) {
583: env->cp15.c6_data = addr;
584: goto done;
585: }
586: if (size == 3) {
587: val = env->regs[(env->exclusive_info >> 12) & 0xf];
588: segv = put_user_u32(val, addr);
589: if (segv) {
590: env->cp15.c6_data = addr + 4;
591: goto done;
592: }
593: }
594: rc = 0;
595: fail:
596: env->regs[15] += 4;
597: env->regs[(env->exclusive_info >> 4) & 0xf] = rc;
598: done:
599: end_exclusive();
600: return segv;
601: }
602:
1.1 root 603: void cpu_loop(CPUARMState *env)
604: {
605: int trapnr;
606: unsigned int n, insn;
607: target_siginfo_t info;
1.1.1.2 root 608: uint32_t addr;
1.1.1.6 root 609:
1.1 root 610: for(;;) {
1.1.1.7 root 611: cpu_exec_start(env);
1.1 root 612: trapnr = cpu_arm_exec(env);
1.1.1.7 root 613: cpu_exec_end(env);
1.1 root 614: switch(trapnr) {
615: case EXCP_UDEF:
616: {
617: TaskState *ts = env->opaque;
618: uint32_t opcode;
1.1.1.7 root 619: int rc;
1.1 root 620:
621: /* we handle the FPU emulation here, as Linux */
622: /* we get the opcode */
1.1.1.6 root 623: /* FIXME - what to do if get_user() fails? */
624: get_user_u32(opcode, env->regs[15]);
625:
1.1.1.7 root 626: rc = EmulateAll(opcode, &ts->fpa, env);
627: if (rc == 0) { /* illegal instruction */
1.1 root 628: info.si_signo = SIGILL;
629: info.si_errno = 0;
630: info.si_code = TARGET_ILL_ILLOPN;
631: info._sifields._sigfault._addr = env->regs[15];
1.1.1.7 root 632: queue_signal(env, info.si_signo, &info);
633: } else if (rc < 0) { /* FP exception */
634: int arm_fpe=0;
635:
636: /* translate softfloat flags to FPSR flags */
637: if (-rc & float_flag_invalid)
638: arm_fpe |= BIT_IOC;
639: if (-rc & float_flag_divbyzero)
640: arm_fpe |= BIT_DZC;
641: if (-rc & float_flag_overflow)
642: arm_fpe |= BIT_OFC;
643: if (-rc & float_flag_underflow)
644: arm_fpe |= BIT_UFC;
645: if (-rc & float_flag_inexact)
646: arm_fpe |= BIT_IXC;
647:
648: FPSR fpsr = ts->fpa.fpsr;
649: //printf("fpsr 0x%x, arm_fpe 0x%x\n",fpsr,arm_fpe);
650:
651: if (fpsr & (arm_fpe << 16)) { /* exception enabled? */
652: info.si_signo = SIGFPE;
653: info.si_errno = 0;
654:
655: /* ordered by priority, least first */
656: if (arm_fpe & BIT_IXC) info.si_code = TARGET_FPE_FLTRES;
657: if (arm_fpe & BIT_UFC) info.si_code = TARGET_FPE_FLTUND;
658: if (arm_fpe & BIT_OFC) info.si_code = TARGET_FPE_FLTOVF;
659: if (arm_fpe & BIT_DZC) info.si_code = TARGET_FPE_FLTDIV;
660: if (arm_fpe & BIT_IOC) info.si_code = TARGET_FPE_FLTINV;
661:
662: info._sifields._sigfault._addr = env->regs[15];
663: queue_signal(env, info.si_signo, &info);
664: } else {
665: env->regs[15] += 4;
666: }
667:
668: /* accumulate unenabled exceptions */
669: if ((!(fpsr & BIT_IXE)) && (arm_fpe & BIT_IXC))
670: fpsr |= BIT_IXC;
671: if ((!(fpsr & BIT_UFE)) && (arm_fpe & BIT_UFC))
672: fpsr |= BIT_UFC;
673: if ((!(fpsr & BIT_OFE)) && (arm_fpe & BIT_OFC))
674: fpsr |= BIT_OFC;
675: if ((!(fpsr & BIT_DZE)) && (arm_fpe & BIT_DZC))
676: fpsr |= BIT_DZC;
677: if ((!(fpsr & BIT_IOE)) && (arm_fpe & BIT_IOC))
678: fpsr |= BIT_IOC;
679: ts->fpa.fpsr=fpsr;
680: } else { /* everything OK */
1.1 root 681: /* increment PC */
682: env->regs[15] += 4;
683: }
684: }
685: break;
686: case EXCP_SWI:
1.1.1.3 root 687: case EXCP_BKPT:
1.1 root 688: {
1.1.1.3 root 689: env->eabi = 1;
1.1 root 690: /* system call */
1.1.1.3 root 691: if (trapnr == EXCP_BKPT) {
692: if (env->thumb) {
1.1.1.6 root 693: /* FIXME - what to do if get_user() fails? */
694: get_user_u16(insn, env->regs[15]);
1.1.1.3 root 695: n = insn & 0xff;
696: env->regs[15] += 2;
697: } else {
1.1.1.6 root 698: /* FIXME - what to do if get_user() fails? */
699: get_user_u32(insn, env->regs[15]);
1.1.1.3 root 700: n = (insn & 0xf) | ((insn >> 4) & 0xff0);
701: env->regs[15] += 4;
702: }
1.1 root 703: } else {
1.1.1.3 root 704: if (env->thumb) {
1.1.1.6 root 705: /* FIXME - what to do if get_user() fails? */
706: get_user_u16(insn, env->regs[15] - 2);
1.1.1.3 root 707: n = insn & 0xff;
708: } else {
1.1.1.6 root 709: /* FIXME - what to do if get_user() fails? */
710: get_user_u32(insn, env->regs[15] - 4);
1.1.1.3 root 711: n = insn & 0xffffff;
712: }
1.1 root 713: }
714:
715: if (n == ARM_NR_cacheflush) {
716: arm_cache_flush(env->regs[0], env->regs[1]);
717: } else if (n == ARM_NR_semihosting
718: || n == ARM_NR_thumb_semihosting) {
719: env->regs[0] = do_arm_semihosting (env);
1.1.1.3 root 720: } else if (n == 0 || n >= ARM_SYSCALL_BASE
1.1 root 721: || (env->thumb && n == ARM_THUMB_SYSCALL)) {
722: /* linux syscall */
1.1.1.3 root 723: if (env->thumb || n == 0) {
1.1 root 724: n = env->regs[7];
725: } else {
726: n -= ARM_SYSCALL_BASE;
1.1.1.3 root 727: env->eabi = 0;
1.1 root 728: }
1.1.1.7 root 729: if ( n > ARM_NR_BASE) {
730: switch (n) {
731: case ARM_NR_cacheflush:
732: arm_cache_flush(env->regs[0], env->regs[1]);
733: break;
734: case ARM_NR_set_tls:
735: cpu_set_tls(env, env->regs[0]);
736: env->regs[0] = 0;
737: break;
738: default:
739: gemu_log("qemu: Unsupported ARM syscall: 0x%x\n",
740: n);
741: env->regs[0] = -TARGET_ENOSYS;
742: break;
743: }
744: } else {
745: env->regs[0] = do_syscall(env,
746: n,
747: env->regs[0],
748: env->regs[1],
749: env->regs[2],
750: env->regs[3],
751: env->regs[4],
752: env->regs[5]);
753: }
1.1 root 754: } else {
755: goto error;
756: }
757: }
758: break;
759: case EXCP_INTERRUPT:
760: /* just indicate that signals should be handled asap */
761: break;
762: case EXCP_PREFETCH_ABORT:
1.1.1.7 root 763: addr = env->cp15.c6_insn;
1.1.1.2 root 764: goto do_segv;
1.1 root 765: case EXCP_DATA_ABORT:
1.1.1.7 root 766: addr = env->cp15.c6_data;
1.1.1.2 root 767: goto do_segv;
768: do_segv:
1.1 root 769: {
770: info.si_signo = SIGSEGV;
771: info.si_errno = 0;
772: /* XXX: check env->error_code */
773: info.si_code = TARGET_SEGV_MAPERR;
1.1.1.2 root 774: info._sifields._sigfault._addr = addr;
1.1.1.7 root 775: queue_signal(env, info.si_signo, &info);
1.1 root 776: }
777: break;
778: case EXCP_DEBUG:
779: {
780: int sig;
781:
782: sig = gdb_handlesig (env, TARGET_SIGTRAP);
783: if (sig)
784: {
785: info.si_signo = sig;
786: info.si_errno = 0;
787: info.si_code = TARGET_TRAP_BRKPT;
1.1.1.7 root 788: queue_signal(env, info.si_signo, &info);
1.1 root 789: }
790: }
791: break;
1.1.1.7 root 792: case EXCP_KERNEL_TRAP:
793: if (do_kernel_trap(env))
794: goto error;
795: break;
1.1.1.9 root 796: case EXCP_STREX:
797: if (do_strex(env)) {
798: addr = env->cp15.c6_data;
799: goto do_segv;
800: }
801: break;
1.1 root 802: default:
803: error:
1.1.1.6 root 804: fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
1.1 root 805: trapnr);
806: cpu_dump_state(env, stderr, fprintf, 0);
807: abort();
808: }
809: process_pending_signals(env);
810: }
811: }
812:
813: #endif
814:
815: #ifdef TARGET_SPARC
1.1.1.7 root 816: #define SPARC64_STACK_BIAS 2047
1.1 root 817:
818: //#define DEBUG_WIN
819:
820: /* WARNING: dealing with register windows _is_ complicated. More info
821: can be found at http://www.sics.se/~psm/sparcstack.html */
822: static inline int get_reg_index(CPUSPARCState *env, int cwp, int index)
823: {
1.1.1.7 root 824: index = (index + cwp * 16) % (16 * env->nwindows);
1.1 root 825: /* wrap handling : if cwp is on the last window, then we use the
826: registers 'after' the end */
1.1.1.7 root 827: if (index < 8 && env->cwp == env->nwindows - 1)
828: index += 16 * env->nwindows;
1.1 root 829: return index;
830: }
831:
832: /* save the register window 'cwp1' */
833: static inline void save_window_offset(CPUSPARCState *env, int cwp1)
834: {
835: unsigned int i;
1.1.1.6 root 836: abi_ulong sp_ptr;
837:
1.1.1.3 root 838: sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
1.1.1.7 root 839: #ifdef TARGET_SPARC64
840: if (sp_ptr & 3)
841: sp_ptr += SPARC64_STACK_BIAS;
842: #endif
1.1 root 843: #if defined(DEBUG_WIN)
1.1.1.7 root 844: printf("win_overflow: sp_ptr=0x" TARGET_ABI_FMT_lx " save_cwp=%d\n",
845: sp_ptr, cwp1);
1.1 root 846: #endif
847: for(i = 0; i < 16; i++) {
1.1.1.6 root 848: /* FIXME - what to do if put_user() fails? */
849: put_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
850: sp_ptr += sizeof(abi_ulong);
1.1 root 851: }
852: }
853:
854: static void save_window(CPUSPARCState *env)
855: {
1.1.1.4 root 856: #ifndef TARGET_SPARC64
1.1 root 857: unsigned int new_wim;
1.1.1.7 root 858: new_wim = ((env->wim >> 1) | (env->wim << (env->nwindows - 1))) &
859: ((1LL << env->nwindows) - 1);
860: save_window_offset(env, cpu_cwp_dec(env, env->cwp - 2));
1.1 root 861: env->wim = new_wim;
1.1.1.4 root 862: #else
1.1.1.7 root 863: save_window_offset(env, cpu_cwp_dec(env, env->cwp - 2));
1.1.1.4 root 864: env->cansave++;
865: env->canrestore--;
866: #endif
1.1 root 867: }
868:
869: static void restore_window(CPUSPARCState *env)
870: {
1.1.1.7 root 871: #ifndef TARGET_SPARC64
872: unsigned int new_wim;
873: #endif
874: unsigned int i, cwp1;
1.1.1.6 root 875: abi_ulong sp_ptr;
876:
1.1.1.7 root 877: #ifndef TARGET_SPARC64
878: new_wim = ((env->wim << 1) | (env->wim >> (env->nwindows - 1))) &
879: ((1LL << env->nwindows) - 1);
880: #endif
1.1.1.6 root 881:
1.1 root 882: /* restore the invalid window */
1.1.1.7 root 883: cwp1 = cpu_cwp_inc(env, env->cwp + 1);
1.1.1.3 root 884: sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
1.1.1.7 root 885: #ifdef TARGET_SPARC64
886: if (sp_ptr & 3)
887: sp_ptr += SPARC64_STACK_BIAS;
888: #endif
1.1 root 889: #if defined(DEBUG_WIN)
1.1.1.7 root 890: printf("win_underflow: sp_ptr=0x" TARGET_ABI_FMT_lx " load_cwp=%d\n",
891: sp_ptr, cwp1);
1.1 root 892: #endif
893: for(i = 0; i < 16; i++) {
1.1.1.6 root 894: /* FIXME - what to do if get_user() fails? */
895: get_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
896: sp_ptr += sizeof(abi_ulong);
1.1 root 897: }
1.1.1.4 root 898: #ifdef TARGET_SPARC64
899: env->canrestore++;
1.1.1.7 root 900: if (env->cleanwin < env->nwindows - 1)
901: env->cleanwin++;
1.1.1.4 root 902: env->cansave--;
1.1.1.7 root 903: #else
904: env->wim = new_wim;
1.1.1.4 root 905: #endif
1.1 root 906: }
907:
908: static void flush_windows(CPUSPARCState *env)
909: {
910: int offset, cwp1;
911:
912: offset = 1;
913: for(;;) {
914: /* if restore would invoke restore_window(), then we can stop */
1.1.1.7 root 915: cwp1 = cpu_cwp_inc(env, env->cwp + offset);
916: #ifndef TARGET_SPARC64
1.1 root 917: if (env->wim & (1 << cwp1))
918: break;
1.1.1.7 root 919: #else
920: if (env->canrestore == 0)
921: break;
922: env->cansave++;
923: env->canrestore--;
924: #endif
1.1 root 925: save_window_offset(env, cwp1);
926: offset++;
927: }
1.1.1.7 root 928: cwp1 = cpu_cwp_inc(env, env->cwp + 1);
929: #ifndef TARGET_SPARC64
1.1 root 930: /* set wim so that restore will reload the registers */
931: env->wim = 1 << cwp1;
1.1.1.7 root 932: #endif
1.1 root 933: #if defined(DEBUG_WIN)
934: printf("flush_windows: nb=%d\n", offset - 1);
935: #endif
936: }
937:
938: void cpu_loop (CPUSPARCState *env)
939: {
940: int trapnr, ret;
941: target_siginfo_t info;
1.1.1.6 root 942:
1.1 root 943: while (1) {
944: trapnr = cpu_sparc_exec (env);
1.1.1.6 root 945:
1.1 root 946: switch (trapnr) {
1.1.1.4 root 947: #ifndef TARGET_SPARC64
1.1.1.6 root 948: case 0x88:
1.1 root 949: case 0x90:
1.1.1.4 root 950: #else
1.1.1.6 root 951: case 0x110:
1.1.1.4 root 952: case 0x16d:
953: #endif
1.1 root 954: ret = do_syscall (env, env->gregs[1],
1.1.1.6 root 955: env->regwptr[0], env->regwptr[1],
956: env->regwptr[2], env->regwptr[3],
1.1 root 957: env->regwptr[4], env->regwptr[5]);
958: if ((unsigned int)ret >= (unsigned int)(-515)) {
1.1.1.6 root 959: #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
1.1.1.5 root 960: env->xcc |= PSR_CARRY;
961: #else
1.1 root 962: env->psr |= PSR_CARRY;
1.1.1.5 root 963: #endif
1.1 root 964: ret = -ret;
965: } else {
1.1.1.6 root 966: #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
1.1.1.5 root 967: env->xcc &= ~PSR_CARRY;
968: #else
1.1 root 969: env->psr &= ~PSR_CARRY;
1.1.1.5 root 970: #endif
1.1 root 971: }
972: env->regwptr[0] = ret;
973: /* next instruction */
974: env->pc = env->npc;
975: env->npc = env->npc + 4;
976: break;
977: case 0x83: /* flush windows */
1.1.1.6 root 978: #ifdef TARGET_ABI32
979: case 0x103:
980: #endif
1.1 root 981: flush_windows(env);
982: /* next instruction */
983: env->pc = env->npc;
984: env->npc = env->npc + 4;
985: break;
986: #ifndef TARGET_SPARC64
987: case TT_WIN_OVF: /* window overflow */
988: save_window(env);
989: break;
990: case TT_WIN_UNF: /* window underflow */
991: restore_window(env);
992: break;
993: case TT_TFAULT:
994: case TT_DFAULT:
995: {
996: info.si_signo = SIGSEGV;
997: info.si_errno = 0;
998: /* XXX: check env->error_code */
999: info.si_code = TARGET_SEGV_MAPERR;
1000: info._sifields._sigfault._addr = env->mmuregs[4];
1.1.1.7 root 1001: queue_signal(env, info.si_signo, &info);
1.1 root 1002: }
1003: break;
1004: #else
1.1.1.4 root 1005: case TT_SPILL: /* window overflow */
1006: save_window(env);
1007: break;
1008: case TT_FILL: /* window underflow */
1009: restore_window(env);
1010: break;
1.1.1.6 root 1011: case TT_TFAULT:
1012: case TT_DFAULT:
1013: {
1014: info.si_signo = SIGSEGV;
1015: info.si_errno = 0;
1016: /* XXX: check env->error_code */
1017: info.si_code = TARGET_SEGV_MAPERR;
1018: if (trapnr == TT_DFAULT)
1019: info._sifields._sigfault._addr = env->dmmuregs[4];
1020: else
1.1.1.9 root 1021: info._sifields._sigfault._addr = cpu_tsptr(env)->tpc;
1.1.1.7 root 1022: queue_signal(env, info.si_signo, &info);
1.1.1.6 root 1023: }
1024: break;
1025: #ifndef TARGET_ABI32
1026: case 0x16e:
1027: flush_windows(env);
1028: sparc64_get_context(env);
1029: break;
1030: case 0x16f:
1031: flush_windows(env);
1032: sparc64_set_context(env);
1033: break;
1034: #endif
1.1 root 1035: #endif
1.1.1.4 root 1036: case EXCP_INTERRUPT:
1037: /* just indicate that signals should be handled asap */
1038: break;
1.1 root 1039: case EXCP_DEBUG:
1040: {
1041: int sig;
1042:
1043: sig = gdb_handlesig (env, TARGET_SIGTRAP);
1044: if (sig)
1045: {
1046: info.si_signo = sig;
1047: info.si_errno = 0;
1048: info.si_code = TARGET_TRAP_BRKPT;
1.1.1.7 root 1049: queue_signal(env, info.si_signo, &info);
1.1 root 1050: }
1051: }
1052: break;
1053: default:
1054: printf ("Unhandled trap: 0x%x\n", trapnr);
1055: cpu_dump_state(env, stderr, fprintf, 0);
1056: exit (1);
1057: }
1058: process_pending_signals (env);
1059: }
1060: }
1061:
1062: #endif
1063:
1064: #ifdef TARGET_PPC
1065: static inline uint64_t cpu_ppc_get_tb (CPUState *env)
1066: {
1067: /* TO FIX */
1068: return 0;
1069: }
1.1.1.6 root 1070:
1.1 root 1071: uint32_t cpu_ppc_load_tbl (CPUState *env)
1072: {
1073: return cpu_ppc_get_tb(env) & 0xFFFFFFFF;
1074: }
1.1.1.6 root 1075:
1.1 root 1076: uint32_t cpu_ppc_load_tbu (CPUState *env)
1077: {
1078: return cpu_ppc_get_tb(env) >> 32;
1079: }
1.1.1.6 root 1080:
1081: uint32_t cpu_ppc_load_atbl (CPUState *env)
1.1 root 1082: {
1.1.1.6 root 1083: return cpu_ppc_get_tb(env) & 0xFFFFFFFF;
1.1 root 1084: }
1085:
1.1.1.6 root 1086: uint32_t cpu_ppc_load_atbu (CPUState *env)
1.1 root 1087: {
1.1.1.6 root 1088: return cpu_ppc_get_tb(env) >> 32;
1.1 root 1089: }
1.1.1.6 root 1090:
1091: uint32_t cpu_ppc601_load_rtcu (CPUState *env)
1092: __attribute__ (( alias ("cpu_ppc_load_tbu") ));
1093:
1094: uint32_t cpu_ppc601_load_rtcl (CPUState *env)
1.1 root 1095: {
1.1.1.6 root 1096: return cpu_ppc_load_tbl(env) & 0x3FFFFF80;
1.1 root 1097: }
1.1.1.6 root 1098:
1099: /* XXX: to be fixed */
1100: int ppc_dcr_read (ppc_dcr_t *dcr_env, int dcrn, target_ulong *valp)
1.1 root 1101: {
1102: return -1;
1103: }
1.1.1.6 root 1104:
1105: int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val)
1.1 root 1106: {
1.1.1.6 root 1107: return -1;
1.1 root 1108: }
1.1.1.6 root 1109:
1.1.1.8 root 1110: #define EXCP_DUMP(env, fmt, ...) \
1111: do { \
1112: fprintf(stderr, fmt , ## __VA_ARGS__); \
1113: cpu_dump_state(env, stderr, fprintf, 0); \
1114: qemu_log(fmt, ## __VA_ARGS__); \
1115: if (logfile) \
1116: log_cpu_state(env, 0); \
1.1.1.6 root 1117: } while (0)
1118:
1.1.1.9 root 1119: static int do_store_exclusive(CPUPPCState *env)
1120: {
1121: target_ulong addr;
1122: target_ulong page_addr;
1123: target_ulong val;
1124: int flags;
1125: int segv = 0;
1126:
1127: addr = env->reserve_ea;
1128: page_addr = addr & TARGET_PAGE_MASK;
1129: start_exclusive();
1130: mmap_lock();
1131: flags = page_get_flags(page_addr);
1132: if ((flags & PAGE_READ) == 0) {
1133: segv = 1;
1134: } else {
1135: int reg = env->reserve_info & 0x1f;
1136: int size = (env->reserve_info >> 5) & 0xf;
1137: int stored = 0;
1138:
1139: if (addr == env->reserve_addr) {
1140: switch (size) {
1141: case 1: segv = get_user_u8(val, addr); break;
1142: case 2: segv = get_user_u16(val, addr); break;
1143: case 4: segv = get_user_u32(val, addr); break;
1144: #if defined(TARGET_PPC64)
1145: case 8: segv = get_user_u64(val, addr); break;
1146: #endif
1147: default: abort();
1148: }
1149: if (!segv && val == env->reserve_val) {
1150: val = env->gpr[reg];
1151: switch (size) {
1152: case 1: segv = put_user_u8(val, addr); break;
1153: case 2: segv = put_user_u16(val, addr); break;
1154: case 4: segv = put_user_u32(val, addr); break;
1155: #if defined(TARGET_PPC64)
1156: case 8: segv = put_user_u64(val, addr); break;
1157: #endif
1158: default: abort();
1159: }
1160: if (!segv) {
1161: stored = 1;
1162: }
1163: }
1164: }
1165: env->crf[0] = (stored << 1) | xer_so;
1166: env->reserve_addr = (target_ulong)-1;
1167: }
1168: if (!segv) {
1169: env->nip += 4;
1170: }
1171: mmap_unlock();
1172: end_exclusive();
1173: return segv;
1174: }
1175:
1.1 root 1176: void cpu_loop(CPUPPCState *env)
1177: {
1178: target_siginfo_t info;
1179: int trapnr;
1180: uint32_t ret;
1.1.1.6 root 1181:
1.1 root 1182: for(;;) {
1.1.1.9 root 1183: cpu_exec_start(env);
1.1 root 1184: trapnr = cpu_ppc_exec(env);
1.1.1.9 root 1185: cpu_exec_end(env);
1.1 root 1186: switch(trapnr) {
1.1.1.6 root 1187: case POWERPC_EXCP_NONE:
1188: /* Just go on */
1.1 root 1189: break;
1.1.1.6 root 1190: case POWERPC_EXCP_CRITICAL: /* Critical input */
1191: cpu_abort(env, "Critical interrupt while in user mode. "
1192: "Aborting\n");
1193: break;
1194: case POWERPC_EXCP_MCHECK: /* Machine check exception */
1195: cpu_abort(env, "Machine check exception while in user mode. "
1196: "Aborting\n");
1197: break;
1198: case POWERPC_EXCP_DSI: /* Data storage exception */
1.1.1.9 root 1199: EXCP_DUMP(env, "Invalid data memory access: 0x" TARGET_FMT_lx "\n",
1.1.1.6 root 1200: env->spr[SPR_DAR]);
1201: /* XXX: check this. Seems bugged */
1.1 root 1202: switch (env->error_code & 0xFF000000) {
1203: case 0x40000000:
1204: info.si_signo = TARGET_SIGSEGV;
1205: info.si_errno = 0;
1206: info.si_code = TARGET_SEGV_MAPERR;
1207: break;
1208: case 0x04000000:
1209: info.si_signo = TARGET_SIGILL;
1210: info.si_errno = 0;
1211: info.si_code = TARGET_ILL_ILLADR;
1212: break;
1213: case 0x08000000:
1214: info.si_signo = TARGET_SIGSEGV;
1215: info.si_errno = 0;
1216: info.si_code = TARGET_SEGV_ACCERR;
1217: break;
1218: default:
1219: /* Let's send a regular segfault... */
1.1.1.6 root 1220: EXCP_DUMP(env, "Invalid segfault errno (%02x)\n",
1221: env->error_code);
1.1 root 1222: info.si_signo = TARGET_SIGSEGV;
1223: info.si_errno = 0;
1224: info.si_code = TARGET_SEGV_MAPERR;
1225: break;
1226: }
1227: info._sifields._sigfault._addr = env->nip;
1.1.1.7 root 1228: queue_signal(env, info.si_signo, &info);
1.1 root 1229: break;
1.1.1.6 root 1230: case POWERPC_EXCP_ISI: /* Instruction storage exception */
1.1.1.9 root 1231: EXCP_DUMP(env, "Invalid instruction fetch: 0x\n" TARGET_FMT_lx
1232: "\n", env->spr[SPR_SRR0]);
1.1.1.6 root 1233: /* XXX: check this */
1.1 root 1234: switch (env->error_code & 0xFF000000) {
1235: case 0x40000000:
1236: info.si_signo = TARGET_SIGSEGV;
1237: info.si_errno = 0;
1238: info.si_code = TARGET_SEGV_MAPERR;
1239: break;
1240: case 0x10000000:
1241: case 0x08000000:
1242: info.si_signo = TARGET_SIGSEGV;
1243: info.si_errno = 0;
1244: info.si_code = TARGET_SEGV_ACCERR;
1245: break;
1246: default:
1247: /* Let's send a regular segfault... */
1.1.1.6 root 1248: EXCP_DUMP(env, "Invalid segfault errno (%02x)\n",
1249: env->error_code);
1.1 root 1250: info.si_signo = TARGET_SIGSEGV;
1251: info.si_errno = 0;
1252: info.si_code = TARGET_SEGV_MAPERR;
1253: break;
1254: }
1255: info._sifields._sigfault._addr = env->nip - 4;
1.1.1.7 root 1256: queue_signal(env, info.si_signo, &info);
1.1 root 1257: break;
1.1.1.6 root 1258: case POWERPC_EXCP_EXTERNAL: /* External input */
1259: cpu_abort(env, "External interrupt while in user mode. "
1260: "Aborting\n");
1261: break;
1262: case POWERPC_EXCP_ALIGN: /* Alignment exception */
1263: EXCP_DUMP(env, "Unaligned memory access\n");
1264: /* XXX: check this */
1.1 root 1265: info.si_signo = TARGET_SIGBUS;
1266: info.si_errno = 0;
1267: info.si_code = TARGET_BUS_ADRALN;
1268: info._sifields._sigfault._addr = env->nip - 4;
1.1.1.7 root 1269: queue_signal(env, info.si_signo, &info);
1.1 root 1270: break;
1.1.1.6 root 1271: case POWERPC_EXCP_PROGRAM: /* Program exception */
1272: /* XXX: check this */
1.1 root 1273: switch (env->error_code & ~0xF) {
1.1.1.6 root 1274: case POWERPC_EXCP_FP:
1275: EXCP_DUMP(env, "Floating point program exception\n");
1.1 root 1276: info.si_signo = TARGET_SIGFPE;
1277: info.si_errno = 0;
1278: switch (env->error_code & 0xF) {
1.1.1.6 root 1279: case POWERPC_EXCP_FP_OX:
1.1 root 1280: info.si_code = TARGET_FPE_FLTOVF;
1281: break;
1.1.1.6 root 1282: case POWERPC_EXCP_FP_UX:
1.1 root 1283: info.si_code = TARGET_FPE_FLTUND;
1284: break;
1.1.1.6 root 1285: case POWERPC_EXCP_FP_ZX:
1286: case POWERPC_EXCP_FP_VXZDZ:
1.1 root 1287: info.si_code = TARGET_FPE_FLTDIV;
1288: break;
1.1.1.6 root 1289: case POWERPC_EXCP_FP_XX:
1.1 root 1290: info.si_code = TARGET_FPE_FLTRES;
1291: break;
1.1.1.6 root 1292: case POWERPC_EXCP_FP_VXSOFT:
1.1 root 1293: info.si_code = TARGET_FPE_FLTINV;
1294: break;
1.1.1.6 root 1295: case POWERPC_EXCP_FP_VXSNAN:
1296: case POWERPC_EXCP_FP_VXISI:
1297: case POWERPC_EXCP_FP_VXIDI:
1298: case POWERPC_EXCP_FP_VXIMZ:
1299: case POWERPC_EXCP_FP_VXVC:
1300: case POWERPC_EXCP_FP_VXSQRT:
1301: case POWERPC_EXCP_FP_VXCVI:
1.1 root 1302: info.si_code = TARGET_FPE_FLTSUB;
1303: break;
1304: default:
1.1.1.6 root 1305: EXCP_DUMP(env, "Unknown floating point exception (%02x)\n",
1306: env->error_code);
1307: break;
1.1 root 1308: }
1.1.1.6 root 1309: break;
1310: case POWERPC_EXCP_INVAL:
1311: EXCP_DUMP(env, "Invalid instruction\n");
1.1 root 1312: info.si_signo = TARGET_SIGILL;
1313: info.si_errno = 0;
1314: switch (env->error_code & 0xF) {
1.1.1.6 root 1315: case POWERPC_EXCP_INVAL_INVAL:
1.1 root 1316: info.si_code = TARGET_ILL_ILLOPC;
1317: break;
1.1.1.6 root 1318: case POWERPC_EXCP_INVAL_LSWX:
1319: info.si_code = TARGET_ILL_ILLOPN;
1.1 root 1320: break;
1.1.1.6 root 1321: case POWERPC_EXCP_INVAL_SPR:
1.1 root 1322: info.si_code = TARGET_ILL_PRVREG;
1323: break;
1.1.1.6 root 1324: case POWERPC_EXCP_INVAL_FP:
1.1 root 1325: info.si_code = TARGET_ILL_COPROC;
1326: break;
1327: default:
1.1.1.6 root 1328: EXCP_DUMP(env, "Unknown invalid operation (%02x)\n",
1329: env->error_code & 0xF);
1.1 root 1330: info.si_code = TARGET_ILL_ILLADR;
1331: break;
1332: }
1333: break;
1.1.1.6 root 1334: case POWERPC_EXCP_PRIV:
1335: EXCP_DUMP(env, "Privilege violation\n");
1.1 root 1336: info.si_signo = TARGET_SIGILL;
1337: info.si_errno = 0;
1338: switch (env->error_code & 0xF) {
1.1.1.6 root 1339: case POWERPC_EXCP_PRIV_OPC:
1.1 root 1340: info.si_code = TARGET_ILL_PRVOPC;
1341: break;
1.1.1.6 root 1342: case POWERPC_EXCP_PRIV_REG:
1.1 root 1343: info.si_code = TARGET_ILL_PRVREG;
1.1.1.6 root 1344: break;
1.1 root 1345: default:
1.1.1.6 root 1346: EXCP_DUMP(env, "Unknown privilege violation (%02x)\n",
1347: env->error_code & 0xF);
1.1 root 1348: info.si_code = TARGET_ILL_PRVOPC;
1349: break;
1350: }
1351: break;
1.1.1.6 root 1352: case POWERPC_EXCP_TRAP:
1353: cpu_abort(env, "Tried to call a TRAP\n");
1354: break;
1.1 root 1355: default:
1356: /* Should not happen ! */
1.1.1.6 root 1357: cpu_abort(env, "Unknown program exception (%02x)\n",
1358: env->error_code);
1359: break;
1.1 root 1360: }
1361: info._sifields._sigfault._addr = env->nip - 4;
1.1.1.7 root 1362: queue_signal(env, info.si_signo, &info);
1.1 root 1363: break;
1.1.1.6 root 1364: case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
1365: EXCP_DUMP(env, "No floating point allowed\n");
1.1 root 1366: info.si_signo = TARGET_SIGILL;
1367: info.si_errno = 0;
1368: info.si_code = TARGET_ILL_COPROC;
1369: info._sifields._sigfault._addr = env->nip - 4;
1.1.1.7 root 1370: queue_signal(env, info.si_signo, &info);
1.1 root 1371: break;
1.1.1.6 root 1372: case POWERPC_EXCP_SYSCALL: /* System call exception */
1373: cpu_abort(env, "Syscall exception while in user mode. "
1374: "Aborting\n");
1.1 root 1375: break;
1.1.1.6 root 1376: case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */
1377: EXCP_DUMP(env, "No APU instruction allowed\n");
1378: info.si_signo = TARGET_SIGILL;
1379: info.si_errno = 0;
1380: info.si_code = TARGET_ILL_COPROC;
1381: info._sifields._sigfault._addr = env->nip - 4;
1.1.1.7 root 1382: queue_signal(env, info.si_signo, &info);
1.1 root 1383: break;
1.1.1.6 root 1384: case POWERPC_EXCP_DECR: /* Decrementer exception */
1385: cpu_abort(env, "Decrementer interrupt while in user mode. "
1386: "Aborting\n");
1387: break;
1388: case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */
1389: cpu_abort(env, "Fix interval timer interrupt while in user mode. "
1390: "Aborting\n");
1391: break;
1392: case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */
1393: cpu_abort(env, "Watchdog timer interrupt while in user mode. "
1394: "Aborting\n");
1395: break;
1396: case POWERPC_EXCP_DTLB: /* Data TLB error */
1397: cpu_abort(env, "Data TLB exception while in user mode. "
1398: "Aborting\n");
1399: break;
1400: case POWERPC_EXCP_ITLB: /* Instruction TLB error */
1401: cpu_abort(env, "Instruction TLB exception while in user mode. "
1402: "Aborting\n");
1.1 root 1403: break;
1.1.1.6 root 1404: case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavail. */
1405: EXCP_DUMP(env, "No SPE/floating-point instruction allowed\n");
1406: info.si_signo = TARGET_SIGILL;
1407: info.si_errno = 0;
1408: info.si_code = TARGET_ILL_COPROC;
1409: info._sifields._sigfault._addr = env->nip - 4;
1.1.1.7 root 1410: queue_signal(env, info.si_signo, &info);
1.1.1.6 root 1411: break;
1412: case POWERPC_EXCP_EFPDI: /* Embedded floating-point data IRQ */
1413: cpu_abort(env, "Embedded floating-point data IRQ not handled\n");
1414: break;
1415: case POWERPC_EXCP_EFPRI: /* Embedded floating-point round IRQ */
1416: cpu_abort(env, "Embedded floating-point round IRQ not handled\n");
1417: break;
1418: case POWERPC_EXCP_EPERFM: /* Embedded performance monitor IRQ */
1419: cpu_abort(env, "Performance monitor exception not handled\n");
1420: break;
1421: case POWERPC_EXCP_DOORI: /* Embedded doorbell interrupt */
1422: cpu_abort(env, "Doorbell interrupt while in user mode. "
1423: "Aborting\n");
1424: break;
1425: case POWERPC_EXCP_DOORCI: /* Embedded doorbell critical interrupt */
1426: cpu_abort(env, "Doorbell critical interrupt while in user mode. "
1427: "Aborting\n");
1428: break;
1429: case POWERPC_EXCP_RESET: /* System reset exception */
1430: cpu_abort(env, "Reset interrupt while in user mode. "
1431: "Aborting\n");
1432: break;
1433: case POWERPC_EXCP_DSEG: /* Data segment exception */
1434: cpu_abort(env, "Data segment exception while in user mode. "
1435: "Aborting\n");
1436: break;
1437: case POWERPC_EXCP_ISEG: /* Instruction segment exception */
1438: cpu_abort(env, "Instruction segment exception "
1439: "while in user mode. Aborting\n");
1440: break;
1441: /* PowerPC 64 with hypervisor mode support */
1442: case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception */
1443: cpu_abort(env, "Hypervisor decrementer interrupt "
1444: "while in user mode. Aborting\n");
1445: break;
1446: case POWERPC_EXCP_TRACE: /* Trace exception */
1447: /* Nothing to do:
1448: * we use this exception to emulate step-by-step execution mode.
1449: */
1450: break;
1451: /* PowerPC 64 with hypervisor mode support */
1452: case POWERPC_EXCP_HDSI: /* Hypervisor data storage exception */
1453: cpu_abort(env, "Hypervisor data storage exception "
1454: "while in user mode. Aborting\n");
1455: break;
1456: case POWERPC_EXCP_HISI: /* Hypervisor instruction storage excp */
1457: cpu_abort(env, "Hypervisor instruction storage exception "
1458: "while in user mode. Aborting\n");
1459: break;
1460: case POWERPC_EXCP_HDSEG: /* Hypervisor data segment exception */
1461: cpu_abort(env, "Hypervisor data segment exception "
1462: "while in user mode. Aborting\n");
1463: break;
1464: case POWERPC_EXCP_HISEG: /* Hypervisor instruction segment excp */
1465: cpu_abort(env, "Hypervisor instruction segment exception "
1466: "while in user mode. Aborting\n");
1467: break;
1468: case POWERPC_EXCP_VPU: /* Vector unavailable exception */
1469: EXCP_DUMP(env, "No Altivec instructions allowed\n");
1470: info.si_signo = TARGET_SIGILL;
1471: info.si_errno = 0;
1472: info.si_code = TARGET_ILL_COPROC;
1473: info._sifields._sigfault._addr = env->nip - 4;
1.1.1.7 root 1474: queue_signal(env, info.si_signo, &info);
1.1.1.6 root 1475: break;
1476: case POWERPC_EXCP_PIT: /* Programmable interval timer IRQ */
1477: cpu_abort(env, "Programable interval timer interrupt "
1478: "while in user mode. Aborting\n");
1479: break;
1480: case POWERPC_EXCP_IO: /* IO error exception */
1481: cpu_abort(env, "IO error exception while in user mode. "
1482: "Aborting\n");
1483: break;
1484: case POWERPC_EXCP_RUNM: /* Run mode exception */
1485: cpu_abort(env, "Run mode exception while in user mode. "
1486: "Aborting\n");
1487: break;
1488: case POWERPC_EXCP_EMUL: /* Emulation trap exception */
1489: cpu_abort(env, "Emulation trap exception not handled\n");
1490: break;
1491: case POWERPC_EXCP_IFTLB: /* Instruction fetch TLB error */
1492: cpu_abort(env, "Instruction fetch TLB exception "
1493: "while in user-mode. Aborting");
1494: break;
1495: case POWERPC_EXCP_DLTLB: /* Data load TLB miss */
1496: cpu_abort(env, "Data load TLB exception while in user-mode. "
1497: "Aborting");
1498: break;
1499: case POWERPC_EXCP_DSTLB: /* Data store TLB miss */
1500: cpu_abort(env, "Data store TLB exception while in user-mode. "
1501: "Aborting");
1502: break;
1503: case POWERPC_EXCP_FPA: /* Floating-point assist exception */
1504: cpu_abort(env, "Floating-point assist exception not handled\n");
1505: break;
1506: case POWERPC_EXCP_IABR: /* Instruction address breakpoint */
1507: cpu_abort(env, "Instruction address breakpoint exception "
1508: "not handled\n");
1509: break;
1510: case POWERPC_EXCP_SMI: /* System management interrupt */
1511: cpu_abort(env, "System management interrupt while in user mode. "
1512: "Aborting\n");
1513: break;
1514: case POWERPC_EXCP_THERM: /* Thermal interrupt */
1515: cpu_abort(env, "Thermal interrupt interrupt while in user mode. "
1516: "Aborting\n");
1517: break;
1518: case POWERPC_EXCP_PERFM: /* Embedded performance monitor IRQ */
1519: cpu_abort(env, "Performance monitor exception not handled\n");
1520: break;
1521: case POWERPC_EXCP_VPUA: /* Vector assist exception */
1522: cpu_abort(env, "Vector assist exception not handled\n");
1523: break;
1524: case POWERPC_EXCP_SOFTP: /* Soft patch exception */
1525: cpu_abort(env, "Soft patch exception not handled\n");
1526: break;
1527: case POWERPC_EXCP_MAINT: /* Maintenance exception */
1528: cpu_abort(env, "Maintenance exception while in user mode. "
1529: "Aborting\n");
1530: break;
1531: case POWERPC_EXCP_STOP: /* stop translation */
1532: /* We did invalidate the instruction cache. Go on */
1533: break;
1534: case POWERPC_EXCP_BRANCH: /* branch instruction: */
1535: /* We just stopped because of a branch. Go on */
1536: break;
1537: case POWERPC_EXCP_SYSCALL_USER:
1538: /* system call in user-mode emulation */
1539: /* WARNING:
1540: * PPC ABI uses overflow flag in cr0 to signal an error
1541: * in syscalls.
1542: */
1543: #if 0
1544: printf("syscall %d 0x%08x 0x%08x 0x%08x 0x%08x\n", env->gpr[0],
1545: env->gpr[3], env->gpr[4], env->gpr[5], env->gpr[6]);
1546: #endif
1547: env->crf[0] &= ~0x1;
1548: ret = do_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4],
1549: env->gpr[5], env->gpr[6], env->gpr[7],
1550: env->gpr[8]);
1.1.1.8 root 1551: if (ret == (uint32_t)(-TARGET_QEMU_ESIGRETURN)) {
1552: /* Returning from a successful sigreturn syscall.
1553: Avoid corrupting register state. */
1554: break;
1555: }
1.1.1.6 root 1556: if (ret > (uint32_t)(-515)) {
1557: env->crf[0] |= 0x1;
1558: ret = -ret;
1.1 root 1559: }
1.1.1.6 root 1560: env->gpr[3] = ret;
1561: #if 0
1562: printf("syscall returned 0x%08x (%d)\n", ret, ret);
1563: #endif
1564: break;
1.1.1.9 root 1565: case POWERPC_EXCP_STCX:
1566: if (do_store_exclusive(env)) {
1567: info.si_signo = TARGET_SIGSEGV;
1568: info.si_errno = 0;
1569: info.si_code = TARGET_SEGV_MAPERR;
1570: info._sifields._sigfault._addr = env->nip;
1571: queue_signal(env, info.si_signo, &info);
1572: }
1573: break;
1.1.1.7 root 1574: case EXCP_DEBUG:
1575: {
1576: int sig;
1577:
1578: sig = gdb_handlesig(env, TARGET_SIGTRAP);
1579: if (sig) {
1580: info.si_signo = sig;
1581: info.si_errno = 0;
1582: info.si_code = TARGET_TRAP_BRKPT;
1583: queue_signal(env, info.si_signo, &info);
1584: }
1585: }
1586: break;
1.1.1.6 root 1587: case EXCP_INTERRUPT:
1588: /* just indicate that signals should be handled asap */
1589: break;
1590: default:
1591: cpu_abort(env, "Unknown exception 0x%d. Aborting\n", trapnr);
1592: break;
1.1 root 1593: }
1594: process_pending_signals(env);
1595: }
1596: }
1597: #endif
1598:
1.1.1.2 root 1599: #ifdef TARGET_MIPS
1600:
1601: #define MIPS_SYS(name, args) args,
1602:
1603: static const uint8_t mips_syscall_args[] = {
1604: MIPS_SYS(sys_syscall , 0) /* 4000 */
1605: MIPS_SYS(sys_exit , 1)
1606: MIPS_SYS(sys_fork , 0)
1607: MIPS_SYS(sys_read , 3)
1608: MIPS_SYS(sys_write , 3)
1609: MIPS_SYS(sys_open , 3) /* 4005 */
1610: MIPS_SYS(sys_close , 1)
1611: MIPS_SYS(sys_waitpid , 3)
1612: MIPS_SYS(sys_creat , 2)
1613: MIPS_SYS(sys_link , 2)
1614: MIPS_SYS(sys_unlink , 1) /* 4010 */
1615: MIPS_SYS(sys_execve , 0)
1616: MIPS_SYS(sys_chdir , 1)
1617: MIPS_SYS(sys_time , 1)
1618: MIPS_SYS(sys_mknod , 3)
1619: MIPS_SYS(sys_chmod , 2) /* 4015 */
1620: MIPS_SYS(sys_lchown , 3)
1621: MIPS_SYS(sys_ni_syscall , 0)
1622: MIPS_SYS(sys_ni_syscall , 0) /* was sys_stat */
1623: MIPS_SYS(sys_lseek , 3)
1624: MIPS_SYS(sys_getpid , 0) /* 4020 */
1625: MIPS_SYS(sys_mount , 5)
1626: MIPS_SYS(sys_oldumount , 1)
1627: MIPS_SYS(sys_setuid , 1)
1628: MIPS_SYS(sys_getuid , 0)
1629: MIPS_SYS(sys_stime , 1) /* 4025 */
1630: MIPS_SYS(sys_ptrace , 4)
1631: MIPS_SYS(sys_alarm , 1)
1632: MIPS_SYS(sys_ni_syscall , 0) /* was sys_fstat */
1633: MIPS_SYS(sys_pause , 0)
1634: MIPS_SYS(sys_utime , 2) /* 4030 */
1635: MIPS_SYS(sys_ni_syscall , 0)
1636: MIPS_SYS(sys_ni_syscall , 0)
1637: MIPS_SYS(sys_access , 2)
1638: MIPS_SYS(sys_nice , 1)
1639: MIPS_SYS(sys_ni_syscall , 0) /* 4035 */
1640: MIPS_SYS(sys_sync , 0)
1641: MIPS_SYS(sys_kill , 2)
1642: MIPS_SYS(sys_rename , 2)
1643: MIPS_SYS(sys_mkdir , 2)
1644: MIPS_SYS(sys_rmdir , 1) /* 4040 */
1645: MIPS_SYS(sys_dup , 1)
1646: MIPS_SYS(sys_pipe , 0)
1647: MIPS_SYS(sys_times , 1)
1648: MIPS_SYS(sys_ni_syscall , 0)
1649: MIPS_SYS(sys_brk , 1) /* 4045 */
1650: MIPS_SYS(sys_setgid , 1)
1651: MIPS_SYS(sys_getgid , 0)
1652: MIPS_SYS(sys_ni_syscall , 0) /* was signal(2) */
1653: MIPS_SYS(sys_geteuid , 0)
1654: MIPS_SYS(sys_getegid , 0) /* 4050 */
1655: MIPS_SYS(sys_acct , 0)
1656: MIPS_SYS(sys_umount , 2)
1657: MIPS_SYS(sys_ni_syscall , 0)
1658: MIPS_SYS(sys_ioctl , 3)
1659: MIPS_SYS(sys_fcntl , 3) /* 4055 */
1660: MIPS_SYS(sys_ni_syscall , 2)
1661: MIPS_SYS(sys_setpgid , 2)
1662: MIPS_SYS(sys_ni_syscall , 0)
1663: MIPS_SYS(sys_olduname , 1)
1664: MIPS_SYS(sys_umask , 1) /* 4060 */
1665: MIPS_SYS(sys_chroot , 1)
1666: MIPS_SYS(sys_ustat , 2)
1667: MIPS_SYS(sys_dup2 , 2)
1668: MIPS_SYS(sys_getppid , 0)
1669: MIPS_SYS(sys_getpgrp , 0) /* 4065 */
1670: MIPS_SYS(sys_setsid , 0)
1671: MIPS_SYS(sys_sigaction , 3)
1672: MIPS_SYS(sys_sgetmask , 0)
1673: MIPS_SYS(sys_ssetmask , 1)
1674: MIPS_SYS(sys_setreuid , 2) /* 4070 */
1675: MIPS_SYS(sys_setregid , 2)
1676: MIPS_SYS(sys_sigsuspend , 0)
1677: MIPS_SYS(sys_sigpending , 1)
1678: MIPS_SYS(sys_sethostname , 2)
1679: MIPS_SYS(sys_setrlimit , 2) /* 4075 */
1680: MIPS_SYS(sys_getrlimit , 2)
1681: MIPS_SYS(sys_getrusage , 2)
1682: MIPS_SYS(sys_gettimeofday, 2)
1683: MIPS_SYS(sys_settimeofday, 2)
1684: MIPS_SYS(sys_getgroups , 2) /* 4080 */
1685: MIPS_SYS(sys_setgroups , 2)
1686: MIPS_SYS(sys_ni_syscall , 0) /* old_select */
1687: MIPS_SYS(sys_symlink , 2)
1688: MIPS_SYS(sys_ni_syscall , 0) /* was sys_lstat */
1689: MIPS_SYS(sys_readlink , 3) /* 4085 */
1690: MIPS_SYS(sys_uselib , 1)
1691: MIPS_SYS(sys_swapon , 2)
1692: MIPS_SYS(sys_reboot , 3)
1693: MIPS_SYS(old_readdir , 3)
1694: MIPS_SYS(old_mmap , 6) /* 4090 */
1695: MIPS_SYS(sys_munmap , 2)
1696: MIPS_SYS(sys_truncate , 2)
1697: MIPS_SYS(sys_ftruncate , 2)
1698: MIPS_SYS(sys_fchmod , 2)
1699: MIPS_SYS(sys_fchown , 3) /* 4095 */
1700: MIPS_SYS(sys_getpriority , 2)
1701: MIPS_SYS(sys_setpriority , 3)
1702: MIPS_SYS(sys_ni_syscall , 0)
1703: MIPS_SYS(sys_statfs , 2)
1704: MIPS_SYS(sys_fstatfs , 2) /* 4100 */
1705: MIPS_SYS(sys_ni_syscall , 0) /* was ioperm(2) */
1706: MIPS_SYS(sys_socketcall , 2)
1707: MIPS_SYS(sys_syslog , 3)
1708: MIPS_SYS(sys_setitimer , 3)
1709: MIPS_SYS(sys_getitimer , 2) /* 4105 */
1710: MIPS_SYS(sys_newstat , 2)
1711: MIPS_SYS(sys_newlstat , 2)
1712: MIPS_SYS(sys_newfstat , 2)
1713: MIPS_SYS(sys_uname , 1)
1714: MIPS_SYS(sys_ni_syscall , 0) /* 4110 was iopl(2) */
1715: MIPS_SYS(sys_vhangup , 0)
1716: MIPS_SYS(sys_ni_syscall , 0) /* was sys_idle() */
1717: MIPS_SYS(sys_ni_syscall , 0) /* was sys_vm86 */
1718: MIPS_SYS(sys_wait4 , 4)
1719: MIPS_SYS(sys_swapoff , 1) /* 4115 */
1720: MIPS_SYS(sys_sysinfo , 1)
1721: MIPS_SYS(sys_ipc , 6)
1722: MIPS_SYS(sys_fsync , 1)
1723: MIPS_SYS(sys_sigreturn , 0)
1.1.1.8 root 1724: MIPS_SYS(sys_clone , 6) /* 4120 */
1.1.1.2 root 1725: MIPS_SYS(sys_setdomainname, 2)
1726: MIPS_SYS(sys_newuname , 1)
1727: MIPS_SYS(sys_ni_syscall , 0) /* sys_modify_ldt */
1728: MIPS_SYS(sys_adjtimex , 1)
1729: MIPS_SYS(sys_mprotect , 3) /* 4125 */
1730: MIPS_SYS(sys_sigprocmask , 3)
1731: MIPS_SYS(sys_ni_syscall , 0) /* was create_module */
1732: MIPS_SYS(sys_init_module , 5)
1733: MIPS_SYS(sys_delete_module, 1)
1734: MIPS_SYS(sys_ni_syscall , 0) /* 4130 was get_kernel_syms */
1735: MIPS_SYS(sys_quotactl , 0)
1736: MIPS_SYS(sys_getpgid , 1)
1737: MIPS_SYS(sys_fchdir , 1)
1738: MIPS_SYS(sys_bdflush , 2)
1739: MIPS_SYS(sys_sysfs , 3) /* 4135 */
1740: MIPS_SYS(sys_personality , 1)
1741: MIPS_SYS(sys_ni_syscall , 0) /* for afs_syscall */
1742: MIPS_SYS(sys_setfsuid , 1)
1743: MIPS_SYS(sys_setfsgid , 1)
1744: MIPS_SYS(sys_llseek , 5) /* 4140 */
1745: MIPS_SYS(sys_getdents , 3)
1746: MIPS_SYS(sys_select , 5)
1747: MIPS_SYS(sys_flock , 2)
1748: MIPS_SYS(sys_msync , 3)
1749: MIPS_SYS(sys_readv , 3) /* 4145 */
1750: MIPS_SYS(sys_writev , 3)
1751: MIPS_SYS(sys_cacheflush , 3)
1752: MIPS_SYS(sys_cachectl , 3)
1753: MIPS_SYS(sys_sysmips , 4)
1754: MIPS_SYS(sys_ni_syscall , 0) /* 4150 */
1755: MIPS_SYS(sys_getsid , 1)
1756: MIPS_SYS(sys_fdatasync , 0)
1757: MIPS_SYS(sys_sysctl , 1)
1758: MIPS_SYS(sys_mlock , 2)
1759: MIPS_SYS(sys_munlock , 2) /* 4155 */
1760: MIPS_SYS(sys_mlockall , 1)
1761: MIPS_SYS(sys_munlockall , 0)
1762: MIPS_SYS(sys_sched_setparam, 2)
1763: MIPS_SYS(sys_sched_getparam, 2)
1764: MIPS_SYS(sys_sched_setscheduler, 3) /* 4160 */
1765: MIPS_SYS(sys_sched_getscheduler, 1)
1766: MIPS_SYS(sys_sched_yield , 0)
1767: MIPS_SYS(sys_sched_get_priority_max, 1)
1768: MIPS_SYS(sys_sched_get_priority_min, 1)
1769: MIPS_SYS(sys_sched_rr_get_interval, 2) /* 4165 */
1770: MIPS_SYS(sys_nanosleep, 2)
1771: MIPS_SYS(sys_mremap , 4)
1772: MIPS_SYS(sys_accept , 3)
1773: MIPS_SYS(sys_bind , 3)
1774: MIPS_SYS(sys_connect , 3) /* 4170 */
1775: MIPS_SYS(sys_getpeername , 3)
1776: MIPS_SYS(sys_getsockname , 3)
1777: MIPS_SYS(sys_getsockopt , 5)
1778: MIPS_SYS(sys_listen , 2)
1779: MIPS_SYS(sys_recv , 4) /* 4175 */
1780: MIPS_SYS(sys_recvfrom , 6)
1781: MIPS_SYS(sys_recvmsg , 3)
1782: MIPS_SYS(sys_send , 4)
1783: MIPS_SYS(sys_sendmsg , 3)
1784: MIPS_SYS(sys_sendto , 6) /* 4180 */
1785: MIPS_SYS(sys_setsockopt , 5)
1786: MIPS_SYS(sys_shutdown , 2)
1787: MIPS_SYS(sys_socket , 3)
1788: MIPS_SYS(sys_socketpair , 4)
1789: MIPS_SYS(sys_setresuid , 3) /* 4185 */
1790: MIPS_SYS(sys_getresuid , 3)
1791: MIPS_SYS(sys_ni_syscall , 0) /* was sys_query_module */
1792: MIPS_SYS(sys_poll , 3)
1793: MIPS_SYS(sys_nfsservctl , 3)
1794: MIPS_SYS(sys_setresgid , 3) /* 4190 */
1795: MIPS_SYS(sys_getresgid , 3)
1796: MIPS_SYS(sys_prctl , 5)
1797: MIPS_SYS(sys_rt_sigreturn, 0)
1798: MIPS_SYS(sys_rt_sigaction, 4)
1799: MIPS_SYS(sys_rt_sigprocmask, 4) /* 4195 */
1800: MIPS_SYS(sys_rt_sigpending, 2)
1801: MIPS_SYS(sys_rt_sigtimedwait, 4)
1802: MIPS_SYS(sys_rt_sigqueueinfo, 3)
1803: MIPS_SYS(sys_rt_sigsuspend, 0)
1804: MIPS_SYS(sys_pread64 , 6) /* 4200 */
1805: MIPS_SYS(sys_pwrite64 , 6)
1806: MIPS_SYS(sys_chown , 3)
1807: MIPS_SYS(sys_getcwd , 2)
1808: MIPS_SYS(sys_capget , 2)
1809: MIPS_SYS(sys_capset , 2) /* 4205 */
1810: MIPS_SYS(sys_sigaltstack , 0)
1811: MIPS_SYS(sys_sendfile , 4)
1812: MIPS_SYS(sys_ni_syscall , 0)
1813: MIPS_SYS(sys_ni_syscall , 0)
1814: MIPS_SYS(sys_mmap2 , 6) /* 4210 */
1815: MIPS_SYS(sys_truncate64 , 4)
1816: MIPS_SYS(sys_ftruncate64 , 4)
1817: MIPS_SYS(sys_stat64 , 2)
1818: MIPS_SYS(sys_lstat64 , 2)
1819: MIPS_SYS(sys_fstat64 , 2) /* 4215 */
1820: MIPS_SYS(sys_pivot_root , 2)
1821: MIPS_SYS(sys_mincore , 3)
1822: MIPS_SYS(sys_madvise , 3)
1823: MIPS_SYS(sys_getdents64 , 3)
1824: MIPS_SYS(sys_fcntl64 , 3) /* 4220 */
1825: MIPS_SYS(sys_ni_syscall , 0)
1826: MIPS_SYS(sys_gettid , 0)
1827: MIPS_SYS(sys_readahead , 5)
1828: MIPS_SYS(sys_setxattr , 5)
1829: MIPS_SYS(sys_lsetxattr , 5) /* 4225 */
1830: MIPS_SYS(sys_fsetxattr , 5)
1831: MIPS_SYS(sys_getxattr , 4)
1832: MIPS_SYS(sys_lgetxattr , 4)
1833: MIPS_SYS(sys_fgetxattr , 4)
1834: MIPS_SYS(sys_listxattr , 3) /* 4230 */
1835: MIPS_SYS(sys_llistxattr , 3)
1836: MIPS_SYS(sys_flistxattr , 3)
1837: MIPS_SYS(sys_removexattr , 2)
1838: MIPS_SYS(sys_lremovexattr, 2)
1839: MIPS_SYS(sys_fremovexattr, 2) /* 4235 */
1840: MIPS_SYS(sys_tkill , 2)
1841: MIPS_SYS(sys_sendfile64 , 5)
1842: MIPS_SYS(sys_futex , 2)
1843: MIPS_SYS(sys_sched_setaffinity, 3)
1844: MIPS_SYS(sys_sched_getaffinity, 3) /* 4240 */
1845: MIPS_SYS(sys_io_setup , 2)
1846: MIPS_SYS(sys_io_destroy , 1)
1847: MIPS_SYS(sys_io_getevents, 5)
1848: MIPS_SYS(sys_io_submit , 3)
1849: MIPS_SYS(sys_io_cancel , 3) /* 4245 */
1850: MIPS_SYS(sys_exit_group , 1)
1851: MIPS_SYS(sys_lookup_dcookie, 3)
1852: MIPS_SYS(sys_epoll_create, 1)
1853: MIPS_SYS(sys_epoll_ctl , 4)
1854: MIPS_SYS(sys_epoll_wait , 3) /* 4250 */
1855: MIPS_SYS(sys_remap_file_pages, 5)
1856: MIPS_SYS(sys_set_tid_address, 1)
1857: MIPS_SYS(sys_restart_syscall, 0)
1858: MIPS_SYS(sys_fadvise64_64, 7)
1859: MIPS_SYS(sys_statfs64 , 3) /* 4255 */
1860: MIPS_SYS(sys_fstatfs64 , 2)
1861: MIPS_SYS(sys_timer_create, 3)
1862: MIPS_SYS(sys_timer_settime, 4)
1863: MIPS_SYS(sys_timer_gettime, 2)
1864: MIPS_SYS(sys_timer_getoverrun, 1) /* 4260 */
1865: MIPS_SYS(sys_timer_delete, 1)
1866: MIPS_SYS(sys_clock_settime, 2)
1867: MIPS_SYS(sys_clock_gettime, 2)
1868: MIPS_SYS(sys_clock_getres, 2)
1869: MIPS_SYS(sys_clock_nanosleep, 4) /* 4265 */
1870: MIPS_SYS(sys_tgkill , 3)
1871: MIPS_SYS(sys_utimes , 2)
1872: MIPS_SYS(sys_mbind , 4)
1873: MIPS_SYS(sys_ni_syscall , 0) /* sys_get_mempolicy */
1874: MIPS_SYS(sys_ni_syscall , 0) /* 4270 sys_set_mempolicy */
1875: MIPS_SYS(sys_mq_open , 4)
1876: MIPS_SYS(sys_mq_unlink , 1)
1877: MIPS_SYS(sys_mq_timedsend, 5)
1878: MIPS_SYS(sys_mq_timedreceive, 5)
1879: MIPS_SYS(sys_mq_notify , 2) /* 4275 */
1880: MIPS_SYS(sys_mq_getsetattr, 3)
1881: MIPS_SYS(sys_ni_syscall , 0) /* sys_vserver */
1882: MIPS_SYS(sys_waitid , 4)
1883: MIPS_SYS(sys_ni_syscall , 0) /* available, was setaltroot */
1884: MIPS_SYS(sys_add_key , 5)
1.1.1.6 root 1885: MIPS_SYS(sys_request_key, 4)
1.1.1.2 root 1886: MIPS_SYS(sys_keyctl , 5)
1.1.1.6 root 1887: MIPS_SYS(sys_set_thread_area, 1)
1888: MIPS_SYS(sys_inotify_init, 0)
1889: MIPS_SYS(sys_inotify_add_watch, 3) /* 4285 */
1890: MIPS_SYS(sys_inotify_rm_watch, 2)
1891: MIPS_SYS(sys_migrate_pages, 4)
1892: MIPS_SYS(sys_openat, 4)
1893: MIPS_SYS(sys_mkdirat, 3)
1894: MIPS_SYS(sys_mknodat, 4) /* 4290 */
1895: MIPS_SYS(sys_fchownat, 5)
1896: MIPS_SYS(sys_futimesat, 3)
1897: MIPS_SYS(sys_fstatat64, 4)
1898: MIPS_SYS(sys_unlinkat, 3)
1899: MIPS_SYS(sys_renameat, 4) /* 4295 */
1900: MIPS_SYS(sys_linkat, 5)
1901: MIPS_SYS(sys_symlinkat, 3)
1902: MIPS_SYS(sys_readlinkat, 4)
1903: MIPS_SYS(sys_fchmodat, 3)
1904: MIPS_SYS(sys_faccessat, 3) /* 4300 */
1905: MIPS_SYS(sys_pselect6, 6)
1906: MIPS_SYS(sys_ppoll, 5)
1907: MIPS_SYS(sys_unshare, 1)
1908: MIPS_SYS(sys_splice, 4)
1909: MIPS_SYS(sys_sync_file_range, 7) /* 4305 */
1910: MIPS_SYS(sys_tee, 4)
1911: MIPS_SYS(sys_vmsplice, 4)
1912: MIPS_SYS(sys_move_pages, 6)
1913: MIPS_SYS(sys_set_robust_list, 2)
1914: MIPS_SYS(sys_get_robust_list, 3) /* 4310 */
1915: MIPS_SYS(sys_kexec_load, 4)
1916: MIPS_SYS(sys_getcpu, 3)
1917: MIPS_SYS(sys_epoll_pwait, 6)
1918: MIPS_SYS(sys_ioprio_set, 3)
1919: MIPS_SYS(sys_ioprio_get, 2)
1.1.1.2 root 1920: };
1921:
1922: #undef MIPS_SYS
1923:
1.1.1.8 root 1924: static int do_store_exclusive(CPUMIPSState *env)
1925: {
1926: target_ulong addr;
1927: target_ulong page_addr;
1928: target_ulong val;
1929: int flags;
1930: int segv = 0;
1931: int reg;
1932: int d;
1933:
1.1.1.9 root 1934: addr = env->lladdr;
1.1.1.8 root 1935: page_addr = addr & TARGET_PAGE_MASK;
1936: start_exclusive();
1937: mmap_lock();
1938: flags = page_get_flags(page_addr);
1939: if ((flags & PAGE_READ) == 0) {
1940: segv = 1;
1941: } else {
1942: reg = env->llreg & 0x1f;
1943: d = (env->llreg & 0x20) != 0;
1944: if (d) {
1945: segv = get_user_s64(val, addr);
1946: } else {
1947: segv = get_user_s32(val, addr);
1948: }
1949: if (!segv) {
1950: if (val != env->llval) {
1951: env->active_tc.gpr[reg] = 0;
1952: } else {
1953: if (d) {
1954: segv = put_user_u64(env->llnewval, addr);
1955: } else {
1956: segv = put_user_u32(env->llnewval, addr);
1957: }
1958: if (!segv) {
1959: env->active_tc.gpr[reg] = 1;
1960: }
1961: }
1962: }
1963: }
1.1.1.9 root 1964: env->lladdr = -1;
1.1.1.8 root 1965: if (!segv) {
1966: env->active_tc.PC += 4;
1967: }
1968: mmap_unlock();
1969: end_exclusive();
1970: return segv;
1971: }
1972:
1.1.1.2 root 1973: void cpu_loop(CPUMIPSState *env)
1974: {
1975: target_siginfo_t info;
1.1.1.6 root 1976: int trapnr, ret;
1.1.1.2 root 1977: unsigned int syscall_num;
1978:
1979: for(;;) {
1.1.1.8 root 1980: cpu_exec_start(env);
1.1.1.2 root 1981: trapnr = cpu_mips_exec(env);
1.1.1.8 root 1982: cpu_exec_end(env);
1.1.1.2 root 1983: switch(trapnr) {
1984: case EXCP_SYSCALL:
1.1.1.7 root 1985: syscall_num = env->active_tc.gpr[2] - 4000;
1986: env->active_tc.PC += 4;
1.1.1.6 root 1987: if (syscall_num >= sizeof(mips_syscall_args)) {
1988: ret = -ENOSYS;
1989: } else {
1990: int nb_args;
1991: abi_ulong sp_reg;
1992: abi_ulong arg5 = 0, arg6 = 0, arg7 = 0, arg8 = 0;
1993:
1994: nb_args = mips_syscall_args[syscall_num];
1.1.1.7 root 1995: sp_reg = env->active_tc.gpr[29];
1.1.1.6 root 1996: switch (nb_args) {
1997: /* these arguments are taken from the stack */
1998: /* FIXME - what to do if get_user() fails? */
1999: case 8: get_user_ual(arg8, sp_reg + 28);
2000: case 7: get_user_ual(arg7, sp_reg + 24);
2001: case 6: get_user_ual(arg6, sp_reg + 20);
2002: case 5: get_user_ual(arg5, sp_reg + 16);
2003: default:
2004: break;
1.1.1.2 root 2005: }
1.1.1.7 root 2006: ret = do_syscall(env, env->active_tc.gpr[2],
2007: env->active_tc.gpr[4],
2008: env->active_tc.gpr[5],
2009: env->active_tc.gpr[6],
2010: env->active_tc.gpr[7],
1.1.1.6 root 2011: arg5, arg6/*, arg7, arg8*/);
2012: }
1.1.1.8 root 2013: if (ret == -TARGET_QEMU_ESIGRETURN) {
2014: /* Returning from a successful sigreturn syscall.
2015: Avoid clobbering register state. */
2016: break;
2017: }
1.1.1.6 root 2018: if ((unsigned int)ret >= (unsigned int)(-1133)) {
1.1.1.7 root 2019: env->active_tc.gpr[7] = 1; /* error flag */
1.1.1.6 root 2020: ret = -ret;
2021: } else {
1.1.1.7 root 2022: env->active_tc.gpr[7] = 0; /* error flag */
1.1.1.2 root 2023: }
1.1.1.7 root 2024: env->active_tc.gpr[2] = ret;
1.1.1.2 root 2025: break;
1.1.1.5 root 2026: case EXCP_TLBL:
2027: case EXCP_TLBS:
1.1.1.8 root 2028: info.si_signo = TARGET_SIGSEGV;
2029: info.si_errno = 0;
2030: /* XXX: check env->error_code */
2031: info.si_code = TARGET_SEGV_MAPERR;
2032: info._sifields._sigfault._addr = env->CP0_BadVAddr;
2033: queue_signal(env, info.si_signo, &info);
2034: break;
1.1.1.2 root 2035: case EXCP_CpU:
2036: case EXCP_RI:
1.1.1.4 root 2037: info.si_signo = TARGET_SIGILL;
2038: info.si_errno = 0;
2039: info.si_code = 0;
1.1.1.7 root 2040: queue_signal(env, info.si_signo, &info);
1.1.1.4 root 2041: break;
2042: case EXCP_INTERRUPT:
2043: /* just indicate that signals should be handled asap */
1.1.1.2 root 2044: break;
1.1.1.5 root 2045: case EXCP_DEBUG:
2046: {
2047: int sig;
2048:
2049: sig = gdb_handlesig (env, TARGET_SIGTRAP);
2050: if (sig)
2051: {
2052: info.si_signo = sig;
2053: info.si_errno = 0;
2054: info.si_code = TARGET_TRAP_BRKPT;
1.1.1.7 root 2055: queue_signal(env, info.si_signo, &info);
1.1.1.5 root 2056: }
2057: }
2058: break;
1.1.1.8 root 2059: case EXCP_SC:
2060: if (do_store_exclusive(env)) {
2061: info.si_signo = TARGET_SIGSEGV;
2062: info.si_errno = 0;
2063: info.si_code = TARGET_SEGV_MAPERR;
2064: info._sifields._sigfault._addr = env->active_tc.PC;
2065: queue_signal(env, info.si_signo, &info);
2066: }
2067: break;
1.1.1.2 root 2068: default:
2069: // error:
1.1.1.6 root 2070: fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
1.1.1.2 root 2071: trapnr);
2072: cpu_dump_state(env, stderr, fprintf, 0);
2073: abort();
2074: }
2075: process_pending_signals(env);
2076: }
2077: }
2078: #endif
2079:
1.1.1.3 root 2080: #ifdef TARGET_SH4
2081: void cpu_loop (CPUState *env)
2082: {
2083: int trapnr, ret;
1.1.1.4 root 2084: target_siginfo_t info;
1.1.1.6 root 2085:
1.1.1.3 root 2086: while (1) {
2087: trapnr = cpu_sh4_exec (env);
1.1.1.6 root 2088:
1.1.1.3 root 2089: switch (trapnr) {
2090: case 0x160:
1.1.1.7 root 2091: env->pc += 2;
1.1.1.6 root 2092: ret = do_syscall(env,
2093: env->gregs[3],
2094: env->gregs[4],
2095: env->gregs[5],
2096: env->gregs[6],
2097: env->gregs[7],
2098: env->gregs[0],
2099: env->gregs[1]);
1.1.1.4 root 2100: env->gregs[0] = ret;
1.1.1.3 root 2101: break;
1.1.1.6 root 2102: case EXCP_INTERRUPT:
2103: /* just indicate that signals should be handled asap */
2104: break;
2105: case EXCP_DEBUG:
2106: {
2107: int sig;
2108:
2109: sig = gdb_handlesig (env, TARGET_SIGTRAP);
2110: if (sig)
2111: {
2112: info.si_signo = sig;
2113: info.si_errno = 0;
2114: info.si_code = TARGET_TRAP_BRKPT;
1.1.1.7 root 2115: queue_signal(env, info.si_signo, &info);
1.1.1.6 root 2116: }
2117: }
2118: break;
2119: case 0xa0:
2120: case 0xc0:
2121: info.si_signo = SIGSEGV;
2122: info.si_errno = 0;
2123: info.si_code = TARGET_SEGV_MAPERR;
2124: info._sifields._sigfault._addr = env->tea;
1.1.1.7 root 2125: queue_signal(env, info.si_signo, &info);
1.1.1.6 root 2126: break;
2127:
2128: default:
2129: printf ("Unhandled trap: 0x%x\n", trapnr);
2130: cpu_dump_state(env, stderr, fprintf, 0);
2131: exit (1);
2132: }
2133: process_pending_signals (env);
2134: }
2135: }
2136: #endif
2137:
2138: #ifdef TARGET_CRIS
2139: void cpu_loop (CPUState *env)
2140: {
2141: int trapnr, ret;
2142: target_siginfo_t info;
2143:
2144: while (1) {
2145: trapnr = cpu_cris_exec (env);
2146: switch (trapnr) {
2147: case 0xaa:
2148: {
2149: info.si_signo = SIGSEGV;
2150: info.si_errno = 0;
2151: /* XXX: check env->error_code */
2152: info.si_code = TARGET_SEGV_MAPERR;
1.1.1.7 root 2153: info._sifields._sigfault._addr = env->pregs[PR_EDA];
2154: queue_signal(env, info.si_signo, &info);
1.1.1.6 root 2155: }
2156: break;
1.1.1.7 root 2157: case EXCP_INTERRUPT:
2158: /* just indicate that signals should be handled asap */
2159: break;
1.1.1.6 root 2160: case EXCP_BREAK:
2161: ret = do_syscall(env,
2162: env->regs[9],
2163: env->regs[10],
2164: env->regs[11],
2165: env->regs[12],
2166: env->regs[13],
2167: env->pregs[7],
2168: env->pregs[11]);
2169: env->regs[10] = ret;
2170: break;
1.1.1.4 root 2171: case EXCP_DEBUG:
2172: {
2173: int sig;
2174:
2175: sig = gdb_handlesig (env, TARGET_SIGTRAP);
2176: if (sig)
2177: {
2178: info.si_signo = sig;
2179: info.si_errno = 0;
2180: info.si_code = TARGET_TRAP_BRKPT;
1.1.1.7 root 2181: queue_signal(env, info.si_signo, &info);
1.1.1.4 root 2182: }
2183: }
2184: break;
1.1.1.3 root 2185: default:
2186: printf ("Unhandled trap: 0x%x\n", trapnr);
2187: cpu_dump_state(env, stderr, fprintf, 0);
2188: exit (1);
2189: }
2190: process_pending_signals (env);
2191: }
2192: }
2193: #endif
2194:
1.1.1.8 root 2195: #ifdef TARGET_MICROBLAZE
2196: void cpu_loop (CPUState *env)
2197: {
2198: int trapnr, ret;
2199: target_siginfo_t info;
2200:
2201: while (1) {
2202: trapnr = cpu_mb_exec (env);
2203: switch (trapnr) {
2204: case 0xaa:
2205: {
2206: info.si_signo = SIGSEGV;
2207: info.si_errno = 0;
2208: /* XXX: check env->error_code */
2209: info.si_code = TARGET_SEGV_MAPERR;
2210: info._sifields._sigfault._addr = 0;
2211: queue_signal(env, info.si_signo, &info);
2212: }
2213: break;
2214: case EXCP_INTERRUPT:
2215: /* just indicate that signals should be handled asap */
2216: break;
2217: case EXCP_BREAK:
2218: /* Return address is 4 bytes after the call. */
2219: env->regs[14] += 4;
2220: ret = do_syscall(env,
2221: env->regs[12],
2222: env->regs[5],
2223: env->regs[6],
2224: env->regs[7],
2225: env->regs[8],
2226: env->regs[9],
2227: env->regs[10]);
2228: env->regs[3] = ret;
2229: env->sregs[SR_PC] = env->regs[14];
2230: break;
2231: case EXCP_DEBUG:
2232: {
2233: int sig;
2234:
2235: sig = gdb_handlesig (env, TARGET_SIGTRAP);
2236: if (sig)
2237: {
2238: info.si_signo = sig;
2239: info.si_errno = 0;
2240: info.si_code = TARGET_TRAP_BRKPT;
2241: queue_signal(env, info.si_signo, &info);
2242: }
2243: }
2244: break;
2245: default:
2246: printf ("Unhandled trap: 0x%x\n", trapnr);
2247: cpu_dump_state(env, stderr, fprintf, 0);
2248: exit (1);
2249: }
2250: process_pending_signals (env);
2251: }
2252: }
2253: #endif
2254:
1.1.1.5 root 2255: #ifdef TARGET_M68K
2256:
2257: void cpu_loop(CPUM68KState *env)
2258: {
2259: int trapnr;
2260: unsigned int n;
2261: target_siginfo_t info;
2262: TaskState *ts = env->opaque;
1.1.1.6 root 2263:
1.1.1.5 root 2264: for(;;) {
2265: trapnr = cpu_m68k_exec(env);
2266: switch(trapnr) {
2267: case EXCP_ILLEGAL:
2268: {
2269: if (ts->sim_syscalls) {
2270: uint16_t nr;
2271: nr = lduw(env->pc + 2);
2272: env->pc += 4;
2273: do_m68k_simcall(env, nr);
2274: } else {
2275: goto do_sigill;
2276: }
2277: }
2278: break;
1.1.1.6 root 2279: case EXCP_HALT_INSN:
1.1.1.5 root 2280: /* Semihosing syscall. */
1.1.1.6 root 2281: env->pc += 4;
1.1.1.5 root 2282: do_m68k_semihosting(env, env->dregs[0]);
2283: break;
2284: case EXCP_LINEA:
2285: case EXCP_LINEF:
2286: case EXCP_UNSUPPORTED:
2287: do_sigill:
2288: info.si_signo = SIGILL;
2289: info.si_errno = 0;
2290: info.si_code = TARGET_ILL_ILLOPN;
2291: info._sifields._sigfault._addr = env->pc;
1.1.1.7 root 2292: queue_signal(env, info.si_signo, &info);
1.1.1.5 root 2293: break;
2294: case EXCP_TRAP0:
2295: {
2296: ts->sim_syscalls = 0;
2297: n = env->dregs[0];
2298: env->pc += 2;
1.1.1.6 root 2299: env->dregs[0] = do_syscall(env,
2300: n,
1.1.1.5 root 2301: env->dregs[1],
2302: env->dregs[2],
2303: env->dregs[3],
2304: env->dregs[4],
2305: env->dregs[5],
1.1.1.7 root 2306: env->aregs[0]);
1.1.1.5 root 2307: }
2308: break;
2309: case EXCP_INTERRUPT:
2310: /* just indicate that signals should be handled asap */
2311: break;
2312: case EXCP_ACCESS:
2313: {
2314: info.si_signo = SIGSEGV;
2315: info.si_errno = 0;
2316: /* XXX: check env->error_code */
2317: info.si_code = TARGET_SEGV_MAPERR;
2318: info._sifields._sigfault._addr = env->mmu.ar;
1.1.1.7 root 2319: queue_signal(env, info.si_signo, &info);
1.1.1.5 root 2320: }
2321: break;
2322: case EXCP_DEBUG:
2323: {
2324: int sig;
2325:
2326: sig = gdb_handlesig (env, TARGET_SIGTRAP);
2327: if (sig)
2328: {
2329: info.si_signo = sig;
2330: info.si_errno = 0;
2331: info.si_code = TARGET_TRAP_BRKPT;
1.1.1.7 root 2332: queue_signal(env, info.si_signo, &info);
1.1.1.5 root 2333: }
2334: }
2335: break;
2336: default:
1.1.1.6 root 2337: fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
1.1.1.5 root 2338: trapnr);
2339: cpu_dump_state(env, stderr, fprintf, 0);
2340: abort();
2341: }
2342: process_pending_signals(env);
2343: }
2344: }
2345: #endif /* TARGET_M68K */
2346:
1.1.1.6 root 2347: #ifdef TARGET_ALPHA
2348: void cpu_loop (CPUState *env)
2349: {
2350: int trapnr;
2351: target_siginfo_t info;
2352:
2353: while (1) {
2354: trapnr = cpu_alpha_exec (env);
2355:
2356: switch (trapnr) {
2357: case EXCP_RESET:
2358: fprintf(stderr, "Reset requested. Exit\n");
2359: exit(1);
2360: break;
2361: case EXCP_MCHK:
2362: fprintf(stderr, "Machine check exception. Exit\n");
2363: exit(1);
2364: break;
2365: case EXCP_ARITH:
2366: fprintf(stderr, "Arithmetic trap.\n");
2367: exit(1);
2368: break;
2369: case EXCP_HW_INTERRUPT:
2370: fprintf(stderr, "External interrupt. Exit\n");
2371: exit(1);
2372: break;
2373: case EXCP_DFAULT:
2374: fprintf(stderr, "MMU data fault\n");
2375: exit(1);
2376: break;
2377: case EXCP_DTB_MISS_PAL:
2378: fprintf(stderr, "MMU data TLB miss in PALcode\n");
2379: exit(1);
2380: break;
2381: case EXCP_ITB_MISS:
2382: fprintf(stderr, "MMU instruction TLB miss\n");
2383: exit(1);
2384: break;
2385: case EXCP_ITB_ACV:
2386: fprintf(stderr, "MMU instruction access violation\n");
2387: exit(1);
2388: break;
2389: case EXCP_DTB_MISS_NATIVE:
2390: fprintf(stderr, "MMU data TLB miss\n");
2391: exit(1);
2392: break;
2393: case EXCP_UNALIGN:
2394: fprintf(stderr, "Unaligned access\n");
2395: exit(1);
2396: break;
2397: case EXCP_OPCDEC:
2398: fprintf(stderr, "Invalid instruction\n");
2399: exit(1);
2400: break;
2401: case EXCP_FEN:
2402: fprintf(stderr, "Floating-point not allowed\n");
2403: exit(1);
2404: break;
2405: case EXCP_CALL_PAL ... (EXCP_CALL_PALP - 1):
2406: call_pal(env, (trapnr >> 6) | 0x80);
2407: break;
2408: case EXCP_CALL_PALP ... (EXCP_CALL_PALE - 1):
2409: fprintf(stderr, "Privileged call to PALcode\n");
2410: exit(1);
2411: break;
2412: case EXCP_DEBUG:
2413: {
2414: int sig;
2415:
2416: sig = gdb_handlesig (env, TARGET_SIGTRAP);
2417: if (sig)
2418: {
2419: info.si_signo = sig;
2420: info.si_errno = 0;
2421: info.si_code = TARGET_TRAP_BRKPT;
1.1.1.7 root 2422: queue_signal(env, info.si_signo, &info);
1.1.1.6 root 2423: }
2424: }
2425: break;
2426: default:
2427: printf ("Unhandled trap: 0x%x\n", trapnr);
2428: cpu_dump_state(env, stderr, fprintf, 0);
2429: exit (1);
2430: }
2431: process_pending_signals (env);
2432: }
2433: }
2434: #endif /* TARGET_ALPHA */
2435:
1.1.1.7 root 2436: static void usage(void)
1.1 root 2437: {
1.1.1.8 root 2438: printf("qemu-" TARGET_ARCH " version " QEMU_VERSION QEMU_PKGVERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n"
1.1.1.6 root 2439: "usage: qemu-" TARGET_ARCH " [options] program [arguments...]\n"
1.1 root 2440: "Linux CPU emulator (compiled for %s emulation)\n"
2441: "\n"
1.1.1.6 root 2442: "Standard options:\n"
2443: "-h print this help\n"
2444: "-g port wait gdb connection to port\n"
2445: "-L path set the elf interpreter prefix (default=%s)\n"
2446: "-s size set the stack size in bytes (default=%ld)\n"
2447: "-cpu model select CPU (-cpu ? for list)\n"
2448: "-drop-ld-preload drop LD_PRELOAD for target process\n"
1.1.1.7 root 2449: "-E var=value sets/modifies targets environment variable(s)\n"
2450: "-U var unsets targets environment variable(s)\n"
1.1.1.8 root 2451: "-0 argv0 forces target process argv[0] to be argv0\n"
1.1.1.9 root 2452: #if defined(CONFIG_USE_GUEST_BASE)
2453: "-B address set guest_base address to address\n"
2454: #endif
1.1 root 2455: "\n"
1.1.1.6 root 2456: "Debug options:\n"
1.1 root 2457: "-d options activate log (logfile=%s)\n"
1.1.1.6 root 2458: "-p pagesize set the host page size to 'pagesize'\n"
1.1.1.8 root 2459: "-singlestep always run in singlestep mode\n"
1.1.1.6 root 2460: "-strace log system calls\n"
2461: "\n"
2462: "Environment variables:\n"
2463: "QEMU_STRACE Print system calls and arguments similar to the\n"
2464: " 'strace' program. Enable by setting to any value.\n"
1.1.1.7 root 2465: "You can use -E and -U options to set/unset environment variables\n"
2466: "for target process. It is possible to provide several variables\n"
2467: "by repeating the option. For example:\n"
2468: " -E var1=val2 -E var2=val2 -U LD_PRELOAD -U LD_DEBUG\n"
2469: "Note that if you provide several changes to single variable\n"
2470: "last change will stay in effect.\n"
1.1.1.6 root 2471: ,
1.1 root 2472: TARGET_ARCH,
1.1.1.6 root 2473: interp_prefix,
1.1 root 2474: x86_stack_size,
2475: DEBUG_LOGFILE);
1.1.1.7 root 2476: exit(1);
1.1 root 2477: }
2478:
1.1.1.7 root 2479: THREAD CPUState *thread_env;
1.1 root 2480:
1.1.1.8 root 2481: void task_settid(TaskState *ts)
2482: {
2483: if (ts->ts_tid == 0) {
1.1.1.9 root 2484: #ifdef CONFIG_USE_NPTL
1.1.1.8 root 2485: ts->ts_tid = (pid_t)syscall(SYS_gettid);
2486: #else
2487: /* when no threads are used, tid becomes pid */
2488: ts->ts_tid = getpid();
2489: #endif
2490: }
2491: }
2492:
2493: void stop_all_tasks(void)
2494: {
2495: /*
2496: * We trust that when using NPTL, start_exclusive()
2497: * handles thread stopping correctly.
2498: */
2499: start_exclusive();
2500: }
2501:
1.1.1.7 root 2502: /* Assumes contents are already zeroed. */
2503: void init_task_state(TaskState *ts)
2504: {
2505: int i;
2506:
2507: ts->used = 1;
2508: ts->first_free = ts->sigqueue_table;
2509: for (i = 0; i < MAX_SIGQUEUE_SIZE - 1; i++) {
2510: ts->sigqueue_table[i].next = &ts->sigqueue_table[i + 1];
2511: }
2512: ts->sigqueue_table[i].next = NULL;
2513: }
2514:
2515: int main(int argc, char **argv, char **envp)
1.1 root 2516: {
2517: const char *filename;
1.1.1.6 root 2518: const char *cpu_model;
1.1 root 2519: struct target_pt_regs regs1, *regs = ®s1;
2520: struct image_info info1, *info = &info1;
1.1.1.8 root 2521: struct linux_binprm bprm;
1.1 root 2522: TaskState ts1, *ts = &ts1;
2523: CPUState *env;
2524: int optind;
2525: const char *r;
1.1.1.2 root 2526: int gdbstub_port = 0;
1.1.1.7 root 2527: char **target_environ, **wrk;
1.1.1.8 root 2528: char **target_argv;
2529: int target_argc;
1.1.1.7 root 2530: envlist_t *envlist = NULL;
1.1.1.8 root 2531: const char *argv0 = NULL;
2532: int i;
2533: int ret;
1.1.1.6 root 2534:
1.1 root 2535: if (argc <= 1)
2536: usage();
2537:
1.1.1.7 root 2538: qemu_cache_utils_init(envp);
2539:
1.1 root 2540: /* init debug */
2541: cpu_set_log_filename(DEBUG_LOGFILE);
2542:
1.1.1.7 root 2543: if ((envlist = envlist_create()) == NULL) {
2544: (void) fprintf(stderr, "Unable to allocate envlist\n");
2545: exit(1);
2546: }
2547:
2548: /* add current environment into the list */
2549: for (wrk = environ; *wrk != NULL; wrk++) {
2550: (void) envlist_setenv(envlist, *wrk);
2551: }
2552:
1.1.1.6 root 2553: cpu_model = NULL;
1.1 root 2554: optind = 1;
2555: for(;;) {
2556: if (optind >= argc)
2557: break;
2558: r = argv[optind];
2559: if (r[0] != '-')
2560: break;
2561: optind++;
2562: r++;
2563: if (!strcmp(r, "-")) {
2564: break;
2565: } else if (!strcmp(r, "d")) {
2566: int mask;
1.1.1.7 root 2567: const CPULogItem *item;
1.1 root 2568:
2569: if (optind >= argc)
2570: break;
1.1.1.6 root 2571:
1.1 root 2572: r = argv[optind++];
2573: mask = cpu_str_to_log_mask(r);
2574: if (!mask) {
2575: printf("Log items (comma separated):\n");
2576: for(item = cpu_log_items; item->mask != 0; item++) {
2577: printf("%-10s %s\n", item->name, item->help);
2578: }
2579: exit(1);
2580: }
2581: cpu_set_log(mask);
1.1.1.7 root 2582: } else if (!strcmp(r, "E")) {
2583: r = argv[optind++];
2584: if (envlist_setenv(envlist, r) != 0)
2585: usage();
2586: } else if (!strcmp(r, "U")) {
2587: r = argv[optind++];
2588: if (envlist_unsetenv(envlist, r) != 0)
2589: usage();
1.1.1.8 root 2590: } else if (!strcmp(r, "0")) {
2591: r = argv[optind++];
2592: argv0 = r;
1.1 root 2593: } else if (!strcmp(r, "s")) {
1.1.1.7 root 2594: if (optind >= argc)
2595: break;
1.1 root 2596: r = argv[optind++];
2597: x86_stack_size = strtol(r, (char **)&r, 0);
2598: if (x86_stack_size <= 0)
2599: usage();
2600: if (*r == 'M')
2601: x86_stack_size *= 1024 * 1024;
2602: else if (*r == 'k' || *r == 'K')
2603: x86_stack_size *= 1024;
2604: } else if (!strcmp(r, "L")) {
2605: interp_prefix = argv[optind++];
2606: } else if (!strcmp(r, "p")) {
1.1.1.7 root 2607: if (optind >= argc)
2608: break;
1.1 root 2609: qemu_host_page_size = atoi(argv[optind++]);
2610: if (qemu_host_page_size == 0 ||
2611: (qemu_host_page_size & (qemu_host_page_size - 1)) != 0) {
2612: fprintf(stderr, "page size must be a power of two\n");
2613: exit(1);
2614: }
2615: } else if (!strcmp(r, "g")) {
1.1.1.7 root 2616: if (optind >= argc)
2617: break;
1.1.1.2 root 2618: gdbstub_port = atoi(argv[optind++]);
1.1.1.4 root 2619: } else if (!strcmp(r, "r")) {
2620: qemu_uname_release = argv[optind++];
1.1.1.6 root 2621: } else if (!strcmp(r, "cpu")) {
2622: cpu_model = argv[optind++];
1.1.1.7 root 2623: if (cpu_model == NULL || strcmp(cpu_model, "?") == 0) {
1.1.1.6 root 2624: /* XXX: implement xxx_cpu_list for targets that still miss it */
2625: #if defined(cpu_list)
2626: cpu_list(stdout, &fprintf);
2627: #endif
1.1.1.7 root 2628: exit(1);
1.1.1.6 root 2629: }
1.1.1.9 root 2630: #if defined(CONFIG_USE_GUEST_BASE)
2631: } else if (!strcmp(r, "B")) {
2632: guest_base = strtol(argv[optind++], NULL, 0);
2633: have_guest_base = 1;
2634: #endif
1.1.1.6 root 2635: } else if (!strcmp(r, "drop-ld-preload")) {
1.1.1.7 root 2636: (void) envlist_unsetenv(envlist, "LD_PRELOAD");
1.1.1.8 root 2637: } else if (!strcmp(r, "singlestep")) {
2638: singlestep = 1;
1.1.1.6 root 2639: } else if (!strcmp(r, "strace")) {
2640: do_strace = 1;
2641: } else
1.1 root 2642: {
2643: usage();
2644: }
2645: }
2646: if (optind >= argc)
2647: usage();
2648: filename = argv[optind];
1.1.1.7 root 2649: exec_path = argv[optind];
1.1 root 2650:
2651: /* Zero out regs */
2652: memset(regs, 0, sizeof(struct target_pt_regs));
2653:
2654: /* Zero out image_info */
2655: memset(info, 0, sizeof(struct image_info));
2656:
1.1.1.8 root 2657: memset(&bprm, 0, sizeof (bprm));
2658:
1.1 root 2659: /* Scan interp_prefix dir for replacement files. */
2660: init_paths(interp_prefix);
2661:
1.1.1.6 root 2662: if (cpu_model == NULL) {
2663: #if defined(TARGET_I386)
2664: #ifdef TARGET_X86_64
2665: cpu_model = "qemu64";
2666: #else
2667: cpu_model = "qemu32";
2668: #endif
2669: #elif defined(TARGET_ARM)
1.1.1.8 root 2670: cpu_model = "any";
1.1.1.6 root 2671: #elif defined(TARGET_M68K)
2672: cpu_model = "any";
2673: #elif defined(TARGET_SPARC)
2674: #ifdef TARGET_SPARC64
2675: cpu_model = "TI UltraSparc II";
2676: #else
2677: cpu_model = "Fujitsu MB86904";
2678: #endif
2679: #elif defined(TARGET_MIPS)
2680: #if defined(TARGET_ABI_MIPSN32) || defined(TARGET_ABI_MIPSN64)
2681: cpu_model = "20Kc";
2682: #else
2683: cpu_model = "24Kf";
2684: #endif
2685: #elif defined(TARGET_PPC)
2686: #ifdef TARGET_PPC64
1.1.1.10! root 2687: cpu_model = "970fx";
1.1.1.6 root 2688: #else
2689: cpu_model = "750";
2690: #endif
2691: #else
2692: cpu_model = "any";
2693: #endif
2694: }
1.1.1.7 root 2695: cpu_exec_init_all(0);
1.1 root 2696: /* NOTE: we need to init the CPU at this stage to get
2697: qemu_host_page_size */
1.1.1.6 root 2698: env = cpu_init(cpu_model);
2699: if (!env) {
2700: fprintf(stderr, "Unable to find CPU definition\n");
2701: exit(1);
2702: }
1.1.1.9 root 2703: #if defined(TARGET_I386) || defined(TARGET_SPARC) || defined(TARGET_PPC)
2704: cpu_reset(env);
2705: #endif
2706:
1.1.1.7 root 2707: thread_env = env;
1.1.1.6 root 2708:
2709: if (getenv("QEMU_STRACE")) {
2710: do_strace = 1;
1.1 root 2711: }
1.1.1.6 root 2712:
1.1.1.7 root 2713: target_environ = envlist_to_environ(envlist, NULL);
2714: envlist_free(envlist);
1.1.1.6 root 2715:
1.1.1.9 root 2716: #if defined(CONFIG_USE_GUEST_BASE)
2717: /*
2718: * Now that page sizes are configured in cpu_init() we can do
2719: * proper page alignment for guest_base.
2720: */
2721: guest_base = HOST_PAGE_ALIGN(guest_base);
2722:
2723: /*
2724: * Read in mmap_min_addr kernel parameter. This value is used
2725: * When loading the ELF image to determine whether guest_base
2726: * is needed.
2727: *
2728: * When user has explicitly set the quest base, we skip this
2729: * test.
2730: */
2731: if (!have_guest_base) {
2732: FILE *fp;
2733:
2734: if ((fp = fopen("/proc/sys/vm/mmap_min_addr", "r")) != NULL) {
2735: unsigned long tmp;
2736: if (fscanf(fp, "%lu", &tmp) == 1) {
2737: mmap_min_addr = tmp;
2738: qemu_log("host mmap_min_addr=0x%lx\n", mmap_min_addr);
2739: }
2740: fclose(fp);
2741: }
2742: }
2743: #endif /* CONFIG_USE_GUEST_BASE */
2744:
1.1.1.8 root 2745: /*
2746: * Prepare copy of argv vector for target.
2747: */
2748: target_argc = argc - optind;
2749: target_argv = calloc(target_argc + 1, sizeof (char *));
2750: if (target_argv == NULL) {
2751: (void) fprintf(stderr, "Unable to allocate memory for target_argv\n");
2752: exit(1);
2753: }
2754:
2755: /*
2756: * If argv0 is specified (using '-0' switch) we replace
2757: * argv[0] pointer with the given one.
2758: */
2759: i = 0;
2760: if (argv0 != NULL) {
2761: target_argv[i++] = strdup(argv0);
2762: }
2763: for (; i < target_argc; i++) {
2764: target_argv[i] = strdup(argv[optind + i]);
2765: }
2766: target_argv[target_argc] = NULL;
2767:
2768: memset(ts, 0, sizeof(TaskState));
2769: init_task_state(ts);
2770: /* build Task State */
2771: ts->info = info;
2772: ts->bprm = &bprm;
2773: env->opaque = ts;
2774: task_settid(ts);
2775:
2776: ret = loader_exec(filename, target_argv, target_environ, regs,
2777: info, &bprm);
2778: if (ret != 0) {
2779: printf("Error %d while loading %s\n", ret, filename);
1.1.1.6 root 2780: _exit(1);
2781: }
2782:
1.1.1.8 root 2783: for (i = 0; i < target_argc; i++) {
2784: free(target_argv[i]);
2785: }
2786: free(target_argv);
2787:
1.1.1.6 root 2788: for (wrk = target_environ; *wrk; wrk++) {
2789: free(*wrk);
2790: }
2791:
2792: free(target_environ);
2793:
1.1.1.7 root 2794: if (qemu_log_enabled()) {
1.1.1.9 root 2795: #if defined(CONFIG_USE_GUEST_BASE)
2796: qemu_log("guest_base 0x%lx\n", guest_base);
2797: #endif
1.1.1.7 root 2798: log_page_dump();
1.1.1.6 root 2799:
1.1.1.7 root 2800: qemu_log("start_brk 0x" TARGET_ABI_FMT_lx "\n", info->start_brk);
2801: qemu_log("end_code 0x" TARGET_ABI_FMT_lx "\n", info->end_code);
2802: qemu_log("start_code 0x" TARGET_ABI_FMT_lx "\n",
2803: info->start_code);
2804: qemu_log("start_data 0x" TARGET_ABI_FMT_lx "\n",
2805: info->start_data);
2806: qemu_log("end_data 0x" TARGET_ABI_FMT_lx "\n", info->end_data);
2807: qemu_log("start_stack 0x" TARGET_ABI_FMT_lx "\n",
2808: info->start_stack);
2809: qemu_log("brk 0x" TARGET_ABI_FMT_lx "\n", info->brk);
2810: qemu_log("entry 0x" TARGET_ABI_FMT_lx "\n", info->entry);
1.1 root 2811: }
2812:
1.1.1.3 root 2813: target_set_brk(info->brk);
1.1 root 2814: syscall_init();
2815: signal_init();
2816:
2817: #if defined(TARGET_I386)
2818: cpu_x86_set_cpl(env, 3);
2819:
2820: env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;
2821: env->hflags |= HF_PE_MASK;
2822: if (env->cpuid_features & CPUID_SSE) {
2823: env->cr[4] |= CR4_OSFXSR_MASK;
2824: env->hflags |= HF_OSFXSR_MASK;
2825: }
1.1.1.6 root 2826: #ifndef TARGET_ABI32
2827: /* enable 64 bit mode if possible */
2828: if (!(env->cpuid_ext2_features & CPUID_EXT2_LM)) {
2829: fprintf(stderr, "The selected x86 CPU does not support 64 bit mode\n");
2830: exit(1);
2831: }
2832: env->cr[4] |= CR4_PAE_MASK;
2833: env->efer |= MSR_EFER_LMA | MSR_EFER_LME;
2834: env->hflags |= HF_LMA_MASK;
2835: #endif
1.1 root 2836:
2837: /* flags setup : we activate the IRQs by default as in user mode */
2838: env->eflags |= IF_MASK;
1.1.1.6 root 2839:
1.1 root 2840: /* linux register setup */
1.1.1.6 root 2841: #ifndef TARGET_ABI32
2842: env->regs[R_EAX] = regs->rax;
2843: env->regs[R_EBX] = regs->rbx;
2844: env->regs[R_ECX] = regs->rcx;
2845: env->regs[R_EDX] = regs->rdx;
2846: env->regs[R_ESI] = regs->rsi;
2847: env->regs[R_EDI] = regs->rdi;
2848: env->regs[R_EBP] = regs->rbp;
2849: env->regs[R_ESP] = regs->rsp;
2850: env->eip = regs->rip;
2851: #else
1.1 root 2852: env->regs[R_EAX] = regs->eax;
2853: env->regs[R_EBX] = regs->ebx;
2854: env->regs[R_ECX] = regs->ecx;
2855: env->regs[R_EDX] = regs->edx;
2856: env->regs[R_ESI] = regs->esi;
2857: env->regs[R_EDI] = regs->edi;
2858: env->regs[R_EBP] = regs->ebp;
2859: env->regs[R_ESP] = regs->esp;
2860: env->eip = regs->eip;
1.1.1.6 root 2861: #endif
1.1 root 2862:
2863: /* linux interrupt setup */
1.1.1.7 root 2864: #ifndef TARGET_ABI32
2865: env->idt.limit = 511;
2866: #else
2867: env->idt.limit = 255;
2868: #endif
2869: env->idt.base = target_mmap(0, sizeof(uint64_t) * (env->idt.limit + 1),
2870: PROT_READ|PROT_WRITE,
2871: MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
2872: idt_table = g2h(env->idt.base);
1.1 root 2873: set_idt(0, 0);
2874: set_idt(1, 0);
2875: set_idt(2, 0);
2876: set_idt(3, 3);
2877: set_idt(4, 3);
1.1.1.7 root 2878: set_idt(5, 0);
1.1 root 2879: set_idt(6, 0);
2880: set_idt(7, 0);
2881: set_idt(8, 0);
2882: set_idt(9, 0);
2883: set_idt(10, 0);
2884: set_idt(11, 0);
2885: set_idt(12, 0);
2886: set_idt(13, 0);
2887: set_idt(14, 0);
2888: set_idt(15, 0);
2889: set_idt(16, 0);
2890: set_idt(17, 0);
2891: set_idt(18, 0);
2892: set_idt(19, 0);
2893: set_idt(0x80, 3);
2894:
2895: /* linux segment setup */
1.1.1.6 root 2896: {
2897: uint64_t *gdt_table;
1.1.1.7 root 2898: env->gdt.base = target_mmap(0, sizeof(uint64_t) * TARGET_GDT_ENTRIES,
2899: PROT_READ|PROT_WRITE,
2900: MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
1.1.1.6 root 2901: env->gdt.limit = sizeof(uint64_t) * TARGET_GDT_ENTRIES - 1;
1.1.1.7 root 2902: gdt_table = g2h(env->gdt.base);
1.1.1.6 root 2903: #ifdef TARGET_ABI32
2904: write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff,
2905: DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
2906: (3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT));
2907: #else
2908: /* 64 bit code segment */
2909: write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff,
2910: DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
2911: DESC_L_MASK |
2912: (3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT));
2913: #endif
2914: write_dt(&gdt_table[__USER_DS >> 3], 0, 0xfffff,
2915: DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
2916: (3 << DESC_DPL_SHIFT) | (0x2 << DESC_TYPE_SHIFT));
2917: }
1.1 root 2918: cpu_x86_load_seg(env, R_CS, __USER_CS);
1.1.1.6 root 2919: cpu_x86_load_seg(env, R_SS, __USER_DS);
2920: #ifdef TARGET_ABI32
1.1 root 2921: cpu_x86_load_seg(env, R_DS, __USER_DS);
2922: cpu_x86_load_seg(env, R_ES, __USER_DS);
2923: cpu_x86_load_seg(env, R_FS, __USER_DS);
2924: cpu_x86_load_seg(env, R_GS, __USER_DS);
1.1.1.6 root 2925: /* This hack makes Wine work... */
2926: env->segs[R_FS].selector = 0;
2927: #else
2928: cpu_x86_load_seg(env, R_DS, 0);
2929: cpu_x86_load_seg(env, R_ES, 0);
2930: cpu_x86_load_seg(env, R_FS, 0);
2931: cpu_x86_load_seg(env, R_GS, 0);
2932: #endif
1.1 root 2933: #elif defined(TARGET_ARM)
2934: {
2935: int i;
1.1.1.2 root 2936: cpsr_write(env, regs->uregs[16], 0xffffffff);
1.1 root 2937: for(i = 0; i < 16; i++) {
2938: env->regs[i] = regs->uregs[i];
2939: }
2940: }
2941: #elif defined(TARGET_SPARC)
2942: {
2943: int i;
2944: env->pc = regs->pc;
2945: env->npc = regs->npc;
2946: env->y = regs->y;
2947: for(i = 0; i < 8; i++)
2948: env->gregs[i] = regs->u_regs[i];
2949: for(i = 0; i < 8; i++)
2950: env->regwptr[i] = regs->u_regs[i + 8];
2951: }
2952: #elif defined(TARGET_PPC)
2953: {
2954: int i;
2955:
1.1.1.6 root 2956: #if defined(TARGET_PPC64)
2957: #if defined(TARGET_ABI32)
2958: env->msr &= ~((target_ulong)1 << MSR_SF);
2959: #else
2960: env->msr |= (target_ulong)1 << MSR_SF;
2961: #endif
2962: #endif
1.1 root 2963: env->nip = regs->nip;
2964: for(i = 0; i < 32; i++) {
2965: env->gpr[i] = regs->gpr[i];
2966: }
2967: }
1.1.1.5 root 2968: #elif defined(TARGET_M68K)
2969: {
2970: env->pc = regs->pc;
2971: env->dregs[0] = regs->d0;
2972: env->dregs[1] = regs->d1;
2973: env->dregs[2] = regs->d2;
2974: env->dregs[3] = regs->d3;
2975: env->dregs[4] = regs->d4;
2976: env->dregs[5] = regs->d5;
2977: env->dregs[6] = regs->d6;
2978: env->dregs[7] = regs->d7;
2979: env->aregs[0] = regs->a0;
2980: env->aregs[1] = regs->a1;
2981: env->aregs[2] = regs->a2;
2982: env->aregs[3] = regs->a3;
2983: env->aregs[4] = regs->a4;
2984: env->aregs[5] = regs->a5;
2985: env->aregs[6] = regs->a6;
2986: env->aregs[7] = regs->usp;
2987: env->sr = regs->sr;
2988: ts->sim_syscalls = 1;
2989: }
1.1.1.8 root 2990: #elif defined(TARGET_MICROBLAZE)
2991: {
2992: env->regs[0] = regs->r0;
2993: env->regs[1] = regs->r1;
2994: env->regs[2] = regs->r2;
2995: env->regs[3] = regs->r3;
2996: env->regs[4] = regs->r4;
2997: env->regs[5] = regs->r5;
2998: env->regs[6] = regs->r6;
2999: env->regs[7] = regs->r7;
3000: env->regs[8] = regs->r8;
3001: env->regs[9] = regs->r9;
3002: env->regs[10] = regs->r10;
3003: env->regs[11] = regs->r11;
3004: env->regs[12] = regs->r12;
3005: env->regs[13] = regs->r13;
3006: env->regs[14] = regs->r14;
3007: env->regs[15] = regs->r15;
3008: env->regs[16] = regs->r16;
3009: env->regs[17] = regs->r17;
3010: env->regs[18] = regs->r18;
3011: env->regs[19] = regs->r19;
3012: env->regs[20] = regs->r20;
3013: env->regs[21] = regs->r21;
3014: env->regs[22] = regs->r22;
3015: env->regs[23] = regs->r23;
3016: env->regs[24] = regs->r24;
3017: env->regs[25] = regs->r25;
3018: env->regs[26] = regs->r26;
3019: env->regs[27] = regs->r27;
3020: env->regs[28] = regs->r28;
3021: env->regs[29] = regs->r29;
3022: env->regs[30] = regs->r30;
3023: env->regs[31] = regs->r31;
3024: env->sregs[SR_PC] = regs->pc;
3025: }
1.1.1.2 root 3026: #elif defined(TARGET_MIPS)
3027: {
3028: int i;
3029:
3030: for(i = 0; i < 32; i++) {
1.1.1.7 root 3031: env->active_tc.gpr[i] = regs->regs[i];
1.1.1.2 root 3032: }
1.1.1.7 root 3033: env->active_tc.PC = regs->cp0_epc;
1.1.1.2 root 3034: }
1.1.1.3 root 3035: #elif defined(TARGET_SH4)
3036: {
3037: int i;
3038:
3039: for(i = 0; i < 16; i++) {
3040: env->gregs[i] = regs->regs[i];
3041: }
3042: env->pc = regs->pc;
3043: }
1.1.1.6 root 3044: #elif defined(TARGET_ALPHA)
3045: {
3046: int i;
3047:
3048: for(i = 0; i < 28; i++) {
3049: env->ir[i] = ((abi_ulong *)regs)[i];
3050: }
3051: env->ipr[IPR_USP] = regs->usp;
3052: env->ir[30] = regs->usp;
3053: env->pc = regs->pc;
3054: env->unique = regs->unique;
3055: }
3056: #elif defined(TARGET_CRIS)
3057: {
3058: env->regs[0] = regs->r0;
3059: env->regs[1] = regs->r1;
3060: env->regs[2] = regs->r2;
3061: env->regs[3] = regs->r3;
3062: env->regs[4] = regs->r4;
3063: env->regs[5] = regs->r5;
3064: env->regs[6] = regs->r6;
3065: env->regs[7] = regs->r7;
3066: env->regs[8] = regs->r8;
3067: env->regs[9] = regs->r9;
3068: env->regs[10] = regs->r10;
3069: env->regs[11] = regs->r11;
3070: env->regs[12] = regs->r12;
3071: env->regs[13] = regs->r13;
3072: env->regs[14] = info->start_stack;
3073: env->regs[15] = regs->acr;
3074: env->pc = regs->erp;
3075: }
1.1 root 3076: #else
3077: #error unsupported target CPU
3078: #endif
3079:
1.1.1.6 root 3080: #if defined(TARGET_ARM) || defined(TARGET_M68K)
3081: ts->stack_base = info->start_stack;
3082: ts->heap_base = info->brk;
3083: /* This will be filled in on the first SYS_HEAPINFO call. */
3084: ts->heap_limit = 0;
3085: #endif
3086:
1.1.1.2 root 3087: if (gdbstub_port) {
3088: gdbserver_start (gdbstub_port);
1.1 root 3089: gdb_handlesig(env, 0);
3090: }
3091: cpu_loop(env);
3092: /* never exits */
3093: return 0;
3094: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.