(linenum→info "unix/slp.c:2238")

qemu/0.9.1/darwin-user/main.c

    1: /*
    2:  *  qemu user main
    3:  *
    4:  *  Copyright (c) 2003 Fabrice Bellard
    5:  *  Copyright (c) 2006 Pierre d'Herbemont
    6:  *
    7:  *  This program is free software; you can redistribute it and/or modify
    8:  *  it under the terms of the GNU General Public License as published by
    9:  *  the Free Software Foundation; either version 2 of the License, or
   10:  *  (at your option) any later version.
   11:  *
   12:  *  This program is distributed in the hope that it will be useful,
   13:  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   14:  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15:  *  GNU General Public License for more details.
   16:  *
   17:  *  You should have received a copy of the GNU General Public License
   18:  *  along with this program; if not, write to the Free Software
   19:  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   20:  */
   21: #include <stdlib.h>
   22: #include <stdio.h>
   23: #include <stdarg.h>
   24: #include <string.h>
   25: #include <errno.h>
   26: #include <unistd.h>
   27: 
   28: #include <sys/syscall.h>
   29: #include <sys/mman.h>
   30: 
   31: #include "qemu.h"
   32: 
   33: #define DEBUG_LOGFILE "/tmp/qemu.log"
   34: 
   35: #ifdef __APPLE__
   36: #include <crt_externs.h>
   37: # define environ  (*_NSGetEnviron())
   38: #endif
   39: 
   40: #include <mach/mach_init.h>
   41: #include <mach/vm_map.h>
   42: 
   43: const char *interp_prefix = "";
   44: 
   45: asm(".zerofill __STD_PROG_ZONE, __STD_PROG_ZONE, __std_prog_zone, 0x0dfff000");
   46: 
   47: /* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
   48:    we allocate a bigger stack. Need a better solution, for example
   49:    by remapping the process stack directly at the right place */
   50: unsigned long stack_size = 512 * 1024;
   51: 
   52: void qerror(const char *fmt, ...)
   53: {
   54:     va_list ap;
   55: 
   56:     va_start(ap, fmt);
   57:     vfprintf(stderr, fmt, ap);
   58:     va_end(ap);
   59:     fprintf(stderr, "\n");
   60:     exit(1);
   61: }
   62: 
   63: void gemu_log(const char *fmt, ...)
   64: {
   65:     va_list ap;
   66: 
   67:     va_start(ap, fmt);
   68:     vfprintf(stderr, fmt, ap);
   69:     va_end(ap);
   70: }
   71: 
   72: void cpu_outb(CPUState *env, int addr, int val)
   73: {
   74:     fprintf(stderr, "outb: port=0x%04x, data=%02x\n", addr, val);
   75: }
   76: 
   77: void cpu_outw(CPUState *env, int addr, int val)
   78: {
   79:     fprintf(stderr, "outw: port=0x%04x, data=%04x\n", addr, val);
   80: }
   81: 
   82: void cpu_outl(CPUState *env, int addr, int val)
   83: {
   84:     fprintf(stderr, "outl: port=0x%04x, data=%08x\n", addr, val);
   85: }
   86: 
   87: int cpu_inb(CPUState *env, int addr)
   88: {
   89:     fprintf(stderr, "inb: port=0x%04x\n", addr);
   90:     return 0;
   91: }
   92: 
   93: int cpu_inw(CPUState *env, int addr)
   94: {
   95:     fprintf(stderr, "inw: port=0x%04x\n", addr);
   96:     return 0;
   97: }
   98: 
   99: int cpu_inl(CPUState *env, int addr)
  100: {
  101:     fprintf(stderr, "inl: port=0x%04x\n", addr);
  102:     return 0;
  103: }
  104: 
  105: int cpu_get_pic_interrupt(CPUState *env)
  106: {
  107:     return -1;
  108: }
  109: #ifdef TARGET_PPC
  110: 
  111: static inline uint64_t cpu_ppc_get_tb (CPUState *env)
  112: {
  113:     /* TO FIX */
  114:     return 0;
  115: }
  116: 
  117: uint32_t cpu_ppc_load_tbl (CPUState *env)
  118: {
  119:     return cpu_ppc_get_tb(env) & 0xFFFFFFFF;
  120: }
  121: 
  122: uint32_t cpu_ppc_load_tbu (CPUState *env)
  123: {
  124:     return cpu_ppc_get_tb(env) >> 32;
  125: }
  126: 
  127: uint32_t cpu_ppc_load_atbl (CPUState *env)
  128: {
  129:     return cpu_ppc_get_tb(env) & 0xFFFFFFFF;
  130: }
  131: 
  132: uint32_t cpu_ppc_load_atbu (CPUState *env)
  133: {
  134:     return cpu_ppc_get_tb(env) >> 32;
  135: }
  136: 
  137: uint32_t cpu_ppc601_load_rtcu (CPUState *env)
  138: {
  139:     cpu_ppc_load_tbu(env);
  140: }
  141: 
  142: uint32_t cpu_ppc601_load_rtcl (CPUState *env)
  143: {
  144:     return cpu_ppc_load_tbl(env) & 0x3FFFFF80;
  145: }
  146: 
  147: /* XXX: to be fixed */
  148: int ppc_dcr_read (ppc_dcr_t *dcr_env, int dcrn, target_ulong *valp)
  149: {
  150:     return -1;
  151: }
  152: 
  153: int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val)
  154: {
  155:     return -1;
  156: }
  157: 
  158: #define EXCP_DUMP(env, fmt, args...)                                         \
  159: do {                                                                          \
  160:     fprintf(stderr, fmt , ##args);                                            \
  161:     cpu_dump_state(env, stderr, fprintf, 0);                                  \
  162:     if (loglevel != 0) {                                                      \
  163:         fprintf(logfile, fmt , ##args);                                       \
  164:         cpu_dump_state(env, logfile, fprintf, 0);                             \
  165:     }                                                                         \
  166: } while (0)
  167: 
  168: void cpu_loop(CPUPPCState *env)
  169: {
  170:     int trapnr;
  171:     uint32_t ret;
  172:     target_siginfo_t info;
  173: 
  174:     for(;;) {
  175:         trapnr = cpu_ppc_exec(env);
  176:         switch(trapnr) {
  177:         case POWERPC_EXCP_NONE:
  178:             /* Just go on */
  179:             break;
  180:         case POWERPC_EXCP_CRITICAL: /* Critical input                        */
  181:             cpu_abort(env, "Critical interrupt while in user mode. "
  182:                       "Aborting\n");
  183:             break;
  184:         case POWERPC_EXCP_MCHECK:   /* Machine check exception               */
  185:             cpu_abort(env, "Machine check exception while in user mode. "
  186:                       "Aborting\n");
  187:             break;
  188:         case POWERPC_EXCP_DSI:      /* Data storage exception                */
  189: #ifndef DAR
  190: /* To deal with multiple qemu header version as host for the darwin-user code */
  191: # define DAR SPR_DAR
  192: #endif
  193:             EXCP_DUMP(env, "Invalid data memory access: 0x" ADDRX "\n",
  194:                       env->spr[SPR_DAR]);
  195:             /* Handle this via the gdb */
  196:             gdb_handlesig (env, SIGSEGV);
  197: 
  198:             info.si_addr = (void*)env->nip;
  199:             queue_signal(info.si_signo, &info);
  200:             break;
  201:         case POWERPC_EXCP_ISI:      /* Instruction storage exception         */
  202:             EXCP_DUMP(env, "Invalid instruction fetch: 0x\n" ADDRX "\n",
  203:                       env->spr[SPR_DAR]);
  204:             /* Handle this via the gdb */
  205:             gdb_handlesig (env, SIGSEGV);
  206: 
  207:             info.si_addr = (void*)(env->nip - 4);
  208:             queue_signal(info.si_signo, &info);
  209:             break;
  210:         case POWERPC_EXCP_EXTERNAL: /* External input                        */
  211:             cpu_abort(env, "External interrupt while in user mode. "
  212:                       "Aborting\n");
  213:             break;
  214:         case POWERPC_EXCP_ALIGN:    /* Alignment exception                   */
  215:             EXCP_DUMP(env, "Unaligned memory access\n");
  216:             info.si_errno = 0;
  217:             info.si_code = BUS_ADRALN;
  218:             info.si_addr = (void*)(env->nip - 4);
  219:             queue_signal(info.si_signo, &info);
  220:             break;
  221:         case POWERPC_EXCP_PROGRAM:  /* Program exception                     */
  222:             /* XXX: check this */
  223:             switch (env->error_code & ~0xF) {
  224:             case POWERPC_EXCP_FP:
  225:                 EXCP_DUMP(env, "Floating point program exception\n");
  226:                 /* Set FX */
  227:                 info.si_signo = SIGFPE;
  228:                 info.si_errno = 0;
  229:                 switch (env->error_code & 0xF) {
  230:                 case POWERPC_EXCP_FP_OX:
  231:                     info.si_code = FPE_FLTOVF;
  232:                     break;
  233:                 case POWERPC_EXCP_FP_UX:
  234:                     info.si_code = FPE_FLTUND;
  235:                     break;
  236:                 case POWERPC_EXCP_FP_ZX:
  237:                 case POWERPC_EXCP_FP_VXZDZ:
  238:                     info.si_code = FPE_FLTDIV;
  239:                     break;
  240:                 case POWERPC_EXCP_FP_XX:
  241:                     info.si_code = FPE_FLTRES;
  242:                     break;
  243:                 case POWERPC_EXCP_FP_VXSOFT:
  244:                     info.si_code = FPE_FLTINV;
  245:                     break;
  246:                 case POWERPC_EXCP_FP_VXSNAN:
  247:                 case POWERPC_EXCP_FP_VXISI:
  248:                 case POWERPC_EXCP_FP_VXIDI:
  249:                 case POWERPC_EXCP_FP_VXIMZ:
  250:                 case POWERPC_EXCP_FP_VXVC:
  251:                 case POWERPC_EXCP_FP_VXSQRT:
  252:                 case POWERPC_EXCP_FP_VXCVI:
  253:                     info.si_code = FPE_FLTSUB;
  254:                     break;
  255:                 default:
  256:                     EXCP_DUMP(env, "Unknown floating point exception (%02x)\n",
  257:                               env->error_code);
  258:                     break;
  259:                 }
  260:                 break;
  261:             case POWERPC_EXCP_INVAL:
  262:                 EXCP_DUMP(env, "Invalid instruction\n");
  263:                 info.si_signo = SIGILL;
  264:                 info.si_errno = 0;
  265:                 switch (env->error_code & 0xF) {
  266:                 case POWERPC_EXCP_INVAL_INVAL:
  267:                     info.si_code = ILL_ILLOPC;
  268:                     break;
  269:                 case POWERPC_EXCP_INVAL_LSWX:
  270:                     info.si_code = ILL_ILLOPN;
  271:                     break;
  272:                 case POWERPC_EXCP_INVAL_SPR:
  273:                     info.si_code = ILL_PRVREG;
  274:                     break;
  275:                 case POWERPC_EXCP_INVAL_FP:
  276:                     info.si_code = ILL_COPROC;
  277:                     break;
  278:                 default:
  279:                     EXCP_DUMP(env, "Unknown invalid operation (%02x)\n",
  280:                               env->error_code & 0xF);
  281:                     info.si_code = ILL_ILLADR;
  282:                     break;
  283:                 }
  284:                 /* Handle this via the gdb */
  285:                 gdb_handlesig (env, SIGSEGV);
  286:                 break;
  287:             case POWERPC_EXCP_PRIV:
  288:                 EXCP_DUMP(env, "Privilege violation\n");
  289:                 info.si_signo = SIGILL;
  290:                 info.si_errno = 0;
  291:                 switch (env->error_code & 0xF) {
  292:                 case POWERPC_EXCP_PRIV_OPC:
  293:                     info.si_code = ILL_PRVOPC;
  294:                     break;
  295:                 case POWERPC_EXCP_PRIV_REG:
  296:                     info.si_code = ILL_PRVREG;
  297:                     break;
  298:                 default:
  299:                     EXCP_DUMP(env, "Unknown privilege violation (%02x)\n",
  300:                               env->error_code & 0xF);
  301:                     info.si_code = ILL_PRVOPC;
  302:                     break;
  303:                 }
  304:                 break;
  305:             case POWERPC_EXCP_TRAP:
  306:                 cpu_abort(env, "Tried to call a TRAP\n");
  307:                 break;
  308:             default:
  309:                 /* Should not happen ! */
  310:                 cpu_abort(env, "Unknown program exception (%02x)\n",
  311:                           env->error_code);
  312:                 break;
  313:             }
  314:             info.si_addr = (void*)(env->nip - 4);
  315:             queue_signal(info.si_signo, &info);
  316:             break;
  317:         case POWERPC_EXCP_FPU:      /* Floating-point unavailable exception  */
  318:             EXCP_DUMP(env, "No floating point allowed\n");
  319:             info.si_signo = SIGILL;
  320:             info.si_errno = 0;
  321:             info.si_code = ILL_COPROC;
  322:             info.si_addr = (void*)(env->nip - 4);
  323:             queue_signal(info.si_signo, &info);
  324:             break;
  325:         case POWERPC_EXCP_SYSCALL:  /* System call exception                 */
  326:             cpu_abort(env, "Syscall exception while in user mode. "
  327:                       "Aborting\n");
  328:             break;
  329:         case POWERPC_EXCP_APU:      /* Auxiliary processor unavailable       */
  330:             EXCP_DUMP(env, "No APU instruction allowed\n");
  331:             info.si_signo = SIGILL;
  332:             info.si_errno = 0;
  333:             info.si_code = ILL_COPROC;
  334:             info.si_addr = (void*)(env->nip - 4);
  335:             queue_signal(info.si_signo, &info);
  336:             break;
  337:         case POWERPC_EXCP_DECR:     /* Decrementer exception                 */
  338:             cpu_abort(env, "Decrementer interrupt while in user mode. "
  339:                       "Aborting\n");
  340:             break;
  341:         case POWERPC_EXCP_FIT:      /* Fixed-interval timer interrupt        */
  342:             cpu_abort(env, "Fix interval timer interrupt while in user mode. "
  343:                       "Aborting\n");
  344:             break;
  345:         case POWERPC_EXCP_WDT:      /* Watchdog timer interrupt              */
  346:             cpu_abort(env, "Watchdog timer interrupt while in user mode. "
  347:                       "Aborting\n");
  348:             break;
  349:         case POWERPC_EXCP_DTLB:     /* Data TLB error                        */
  350:             cpu_abort(env, "Data TLB exception while in user mode. "
  351:                       "Aborting\n");
  352:             break;
  353:         case POWERPC_EXCP_ITLB:     /* Instruction TLB error                 */
  354:             cpu_abort(env, "Instruction TLB exception while in user mode. "
  355:                       "Aborting\n");
  356:             break;
  357:         case POWERPC_EXCP_DEBUG:    /* Debug interrupt                       */
  358:             gdb_handlesig (env, SIGTRAP);
  359:             break;
  360:         case POWERPC_EXCP_SPEU:     /* SPE/embedded floating-point unavail.  */
  361:             EXCP_DUMP(env, "No SPE/floating-point instruction allowed\n");
  362:             info.si_signo = SIGILL;
  363:             info.si_errno = 0;
  364:             info.si_code = ILL_COPROC;
  365:             info.si_addr = (void*)(env->nip - 4);
  366:             queue_signal(info.si_signo, &info);
  367:             break;
  368:         case POWERPC_EXCP_EFPDI:    /* Embedded floating-point data IRQ      */
  369:             cpu_abort(env, "Embedded floating-point data IRQ not handled\n");
  370:             break;
  371:         case POWERPC_EXCP_EFPRI:    /* Embedded floating-point round IRQ     */
  372:             cpu_abort(env, "Embedded floating-point round IRQ not handled\n");
  373:             break;
  374:         case POWERPC_EXCP_EPERFM:   /* Embedded performance monitor IRQ      */
  375:             cpu_abort(env, "Performance monitor exception not handled\n");
  376:             break;
  377:         case POWERPC_EXCP_DOORI:    /* Embedded doorbell interrupt           */
  378:             cpu_abort(env, "Doorbell interrupt while in user mode. "
  379:                        "Aborting\n");
  380:             break;
  381:         case POWERPC_EXCP_DOORCI:   /* Embedded doorbell critical interrupt  */
  382:             cpu_abort(env, "Doorbell critical interrupt while in user mode. "
  383:                       "Aborting\n");
  384:             break;
  385:         case POWERPC_EXCP_RESET:    /* System reset exception                */
  386:             cpu_abort(env, "Reset interrupt while in user mode. "
  387:                       "Aborting\n");
  388:             break;
  389:         case POWERPC_EXCP_DSEG:     /* Data segment exception                */
  390:             cpu_abort(env, "Data segment exception while in user mode. "
  391:                       "Aborting\n");
  392:             break;
  393:         case POWERPC_EXCP_ISEG:     /* Instruction segment exception         */
  394:             cpu_abort(env, "Instruction segment exception "
  395:                       "while in user mode. Aborting\n");
  396:             break;
  397:         case POWERPC_EXCP_HDECR:    /* Hypervisor decrementer exception      */
  398:             cpu_abort(env, "Hypervisor decrementer interrupt "
  399:                       "while in user mode. Aborting\n");
  400:             break;
  401:         case POWERPC_EXCP_TRACE:    /* Trace exception                       */
  402:             /* Nothing to do:
  403:              * we use this exception to emulate step-by-step execution mode.
  404:              */
  405:             break;
  406:         case POWERPC_EXCP_HDSI:     /* Hypervisor data storage exception     */
  407:             cpu_abort(env, "Hypervisor data storage exception "
  408:                       "while in user mode. Aborting\n");
  409:             break;
  410:         case POWERPC_EXCP_HISI:     /* Hypervisor instruction storage excp   */
  411:             cpu_abort(env, "Hypervisor instruction storage exception "
  412:                       "while in user mode. Aborting\n");
  413:             break;
  414:         case POWERPC_EXCP_HDSEG:    /* Hypervisor data segment exception     */
  415:             cpu_abort(env, "Hypervisor data segment exception "
  416:                       "while in user mode. Aborting\n");
  417:             break;
  418:         case POWERPC_EXCP_HISEG:    /* Hypervisor instruction segment excp   */
  419:             cpu_abort(env, "Hypervisor instruction segment exception "
  420:                       "while in user mode. Aborting\n");
  421:             break;
  422:         case POWERPC_EXCP_VPU:      /* Vector unavailable exception          */
  423:             EXCP_DUMP(env, "No Altivec instructions allowed\n");
  424:             info.si_signo = SIGILL;
  425:             info.si_errno = 0;
  426:             info.si_code = ILL_COPROC;
  427:             info.si_addr = (void*)(env->nip - 4);
  428:             queue_signal(info.si_signo, &info);
  429:             break;
  430:         case POWERPC_EXCP_PIT:      /* Programmable interval timer IRQ       */
  431:             cpu_abort(env, "Programable interval timer interrupt "
  432:                       "while in user mode. Aborting\n");
  433:             break;
  434:         case POWERPC_EXCP_IO:       /* IO error exception                    */
  435:             cpu_abort(env, "IO error exception while in user mode. "
  436:                       "Aborting\n");
  437:             break;
  438:         case POWERPC_EXCP_RUNM:     /* Run mode exception                    */
  439:             cpu_abort(env, "Run mode exception while in user mode. "
  440:                       "Aborting\n");
  441:             break;
  442:         case POWERPC_EXCP_EMUL:     /* Emulation trap exception              */
  443:             cpu_abort(env, "Emulation trap exception not handled\n");
  444:             break;
  445:         case POWERPC_EXCP_IFTLB:    /* Instruction fetch TLB error           */
  446:             cpu_abort(env, "Instruction fetch TLB exception "
  447:                       "while in user-mode. Aborting");
  448:             break;
  449:         case POWERPC_EXCP_DLTLB:    /* Data load TLB miss                    */
  450:             cpu_abort(env, "Data load TLB exception while in user-mode. "
  451:                       "Aborting");
  452:             break;
  453:         case POWERPC_EXCP_DSTLB:    /* Data store TLB miss                   */
  454:             cpu_abort(env, "Data store TLB exception while in user-mode. "
  455:                       "Aborting");
  456:             break;
  457:         case POWERPC_EXCP_FPA:      /* Floating-point assist exception       */
  458:             cpu_abort(env, "Floating-point assist exception not handled\n");
  459:             break;
  460:         case POWERPC_EXCP_IABR:     /* Instruction address breakpoint        */
  461:             cpu_abort(env, "Instruction address breakpoint exception "
  462:                       "not handled\n");
  463:             break;
  464:         case POWERPC_EXCP_SMI:      /* System management interrupt           */
  465:             cpu_abort(env, "System management interrupt while in user mode. "
  466:                       "Aborting\n");
  467:             break;
  468:         case POWERPC_EXCP_THERM:    /* Thermal interrupt                     */
  469:             cpu_abort(env, "Thermal interrupt interrupt while in user mode. "
  470:                       "Aborting\n");
  471:             break;
  472:         case POWERPC_EXCP_PERFM:    /* Embedded performance monitor IRQ      */
  473:             cpu_abort(env, "Performance monitor exception not handled\n");
  474:             break;
  475:         case POWERPC_EXCP_VPUA:     /* Vector assist exception               */
  476:             cpu_abort(env, "Vector assist exception not handled\n");
  477:             break;
  478:         case POWERPC_EXCP_SOFTP:    /* Soft patch exception                  */
  479:             cpu_abort(env, "Soft patch exception not handled\n");
  480:             break;
  481:         case POWERPC_EXCP_MAINT:    /* Maintenance exception                 */
  482:             cpu_abort(env, "Maintenance exception while in user mode. "
  483:                       "Aborting\n");
  484:             break;
  485:         case POWERPC_EXCP_STOP:     /* stop translation                      */
  486:             /* We did invalidate the instruction cache. Go on */
  487:             break;
  488:         case POWERPC_EXCP_BRANCH:   /* branch instruction:                   */
  489:             /* We just stopped because of a branch. Go on */
  490:             break;
  491:         case POWERPC_EXCP_SYSCALL_USER:
  492:             /* system call in user-mode emulation */
  493:             /* system call */
  494:             if(((int)env->gpr[0]) <= SYS_MAXSYSCALL && ((int)env->gpr[0])>0)
  495:                 ret = do_unix_syscall(env, env->gpr[0]/*, env->gpr[3], env->gpr[4],
  496:                                       env->gpr[5], env->gpr[6], env->gpr[7],
  497:                                       env->gpr[8], env->gpr[9], env->gpr[10]*/);
  498:             else if(((int)env->gpr[0])<0)
  499:                 ret = do_mach_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4],
  500:                                       env->gpr[5], env->gpr[6], env->gpr[7],
  501:                                       env->gpr[8], env->gpr[9], env->gpr[10]);
  502:             else
  503:                 ret = do_thread_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4],
  504:                                         env->gpr[5], env->gpr[6], env->gpr[7],
  505:                                         env->gpr[8], env->gpr[9], env->gpr[10]);
  506: 
  507:             /* Unix syscall error signaling */
  508:             if(((int)env->gpr[0]) <= SYS_MAXSYSCALL && ((int)env->gpr[0])>0)
  509:             {
  510:                 if( (int)ret < 0 )
  511:                     env->nip += 0;
  512:                 else
  513:                     env->nip += 4;
  514:             }
  515: 
  516:             /* Return value */
  517:             env->gpr[3] = ret;
  518:             break;
  519:         case EXCP_INTERRUPT:
  520:             /* just indicate that signals should be handled asap */
  521:             break;
  522:         default:
  523:             cpu_abort(env, "Unknown exception 0x%d. Aborting\n", trapnr);
  524:             break;
  525:         }
  526:         process_pending_signals(env);
  527:     }
  528: }
  529: #endif
  530: 
  531: 
  532: #ifdef TARGET_I386
  533: 
  534: /***********************************************************/
  535: /* CPUX86 core interface */
  536: 
  537: uint64_t cpu_get_tsc(CPUX86State *env)
  538: {
  539:     return cpu_get_real_ticks();
  540: }
  541: 
  542: void
  543: write_dt(void *ptr, unsigned long addr, unsigned long limit,
  544:                      int flags)
  545: {
  546:     unsigned int e1, e2;
  547:     e1 = (addr <<