Diff for /qemu/arm-semi.c between versions 1.1.1.1 and 1.1.1.2

version 1.1.1.1, 2018/04/24 16:45:07 version 1.1.1.2, 2018/04/24 16:47:32
Line 1 Line 1
 /*  /*
  *  Arm "Angel" semihosting syscalls   *  Arm "Angel" semihosting syscalls
  *    *
  *  Copyright (c) 2005, 2007 CodeSourcery.   *  Copyright (c) 2005, 2007 CodeSourcery.
  *  Written by Paul Brook.   *  Written by Paul Brook.
  *   *
Line 33 Line 33
   
 #define ARM_ANGEL_HEAP_SIZE (128 * 1024 * 1024)  #define ARM_ANGEL_HEAP_SIZE (128 * 1024 * 1024)
 #else  #else
 #include "vl.h"  #include "qemu-common.h"
   #include "sysemu.h"
   #include "gdbstub.h"
 #endif  #endif
   
 #define SYS_OPEN        0x01  #define SYS_OPEN        0x01
Line 112  static inline uint32_t set_swi_errno(CPU Line 114  static inline uint32_t set_swi_errno(CPU
     return code;      return code;
 }  }
   
 static uint32_t softmmu_tget32(CPUState *env, uint32_t addr)  #include "softmmu-semi.h"
 {  
     uint32_t val;  
   
     cpu_memory_rw_debug(env, addr, (uint8_t *)&val, 4, 0);  
     return tswap32(val);  
 }  
 static uint32_t softmmu_tget8(CPUState *env, uint32_t addr)  
 {  
     uint8_t val;  
   
     cpu_memory_rw_debug(env, addr, &val, 1, 0);  
     return val;  
 }  
 #define tget32(p) softmmu_tget32(env, p)  
 #define tget8(p) softmmu_tget8(env, p)  
   
 static void *softmmu_lock_user(CPUState *env, uint32_t addr, uint32_t len,  
                                int copy)  
 {  
     char *p;  
     /* TODO: Make this something that isn't fixed size.  */  
     p = malloc(len);  
     if (copy)  
         cpu_memory_rw_debug(env, addr, p, len, 0);  
     return p;  
 }  
 #define lock_user(p, len, copy) softmmu_lock_user(env, p, len, copy)  
 static char *softmmu_lock_user_string(CPUState *env, uint32_t addr)  
 {  
     char *p;  
     char *s;  
     uint8_t c;  
     /* TODO: Make this something that isn't fixed size.  */  
     s = p = malloc(1024);  
     do {  
         cpu_memory_rw_debug(env, addr, &c, 1, 0);  
         addr++;  
         *(p++) = c;  
     } while (c);  
     return s;  
 }  
 #define lock_user_string(p) softmmu_lock_user_string(env, p)  
 static void softmmu_unlock_user(CPUState *env, void *p, target_ulong addr,  
                                 target_ulong len)  
 {  
     if (len)  
         cpu_memory_rw_debug(env, addr, p, len, 1);  
     free(p);  
 }  
 #define unlock_user(s, args, len) softmmu_unlock_user(env, s, args, len)  
 #endif  #endif
   
 static target_ulong arm_semi_syscall_len;  static target_ulong arm_semi_syscall_len;
   
   #if !defined(CONFIG_USER_ONLY)
   static target_ulong syscall_err;
   #endif
   
 static void arm_semi_cb(CPUState *env, target_ulong ret, target_ulong err)  static void arm_semi_cb(CPUState *env, target_ulong ret, target_ulong err)
 {  {
 #ifdef CONFIG_USER_ONLY  #ifdef CONFIG_USER_ONLY
     TaskState *ts = env->opaque;      TaskState *ts = env->opaque;
 #endif  #endif
   
     if (ret == (target_ulong)-1) {      if (ret == (target_ulong)-1) {
 #ifdef CONFIG_USER_ONLY  #ifdef CONFIG_USER_ONLY
         ts->swi_errno = err;          ts->swi_errno = err;
   #else
           syscall_err = err;
 #endif  #endif
         env->regs[0] = ret;          env->regs[0] = ret;
     } else {      } else {
Line 194  static void arm_semi_cb(CPUState *env, t Line 153  static void arm_semi_cb(CPUState *env, t
     }      }
 }  }
   
 #define ARG(n) tget32(args + (n) * 4)  static void arm_semi_flen_cb(CPUState *env, target_ulong ret, target_ulong err)
 #define SET_ARG(n, val) tput32(args + (n) * 4,val)  {
       /* The size is always stored in big-endian order, extract
          the value. We assume the size always fit in 32 bits.  */
       uint32_t size;
       cpu_memory_rw_debug(env, env->regs[13]-64+32, (uint8_t *)&size, 4, 0);
       env->regs[0] = be32_to_cpu(size);
   #ifdef CONFIG_USER_ONLY
       ((TaskState *)env->opaque)->swi_errno = err;
   #else
       syscall_err = err;
   #endif
   }
   
   #define ARG(n)                                  \
   ({                                              \
       target_ulong __arg;                         \
       /* FIXME - handle get_user() failure */     \
       get_user_ual(__arg, args + (n) * 4);        \
       __arg;                                      \
   })
   #define SET_ARG(n, val) put_user_ual(val, args + (n) * 4)
 uint32_t do_arm_semihosting(CPUState *env)  uint32_t do_arm_semihosting(CPUState *env)
 {  {
     target_ulong args;      target_ulong args;
Line 213  uint32_t do_arm_semihosting(CPUState *en Line 192  uint32_t do_arm_semihosting(CPUState *en
     args = env->regs[1];      args = env->regs[1];
     switch (nr) {      switch (nr) {
     case SYS_OPEN:      case SYS_OPEN:
         s = lock_user_string(ARG(0));          if (!(s = lock_user_string(ARG(0))))
               /* FIXME - should this error code be -TARGET_EFAULT ? */
               return (uint32_t)-1;
         if (ARG(1) >= 12)          if (ARG(1) >= 12)
           return (uint32_t)-1;              return (uint32_t)-1;
         if (strcmp(s, ":tt") == 0) {          if (strcmp(s, ":tt") == 0) {
             if (ARG(1) < 4)              if (ARG(1) < 4)
                 return STDIN_FILENO;                  return STDIN_FILENO;
Line 223  uint32_t do_arm_semihosting(CPUState *en Line 204  uint32_t do_arm_semihosting(CPUState *en
                 return STDOUT_FILENO;                  return STDOUT_FILENO;
         }          }
         if (use_gdb_syscalls()) {          if (use_gdb_syscalls()) {
             gdb_do_syscall(arm_semi_cb, "open,%s,%x,1a4", ARG(0), (int)ARG(2),              gdb_do_syscall(arm_semi_cb, "open,%s,%x,1a4", ARG(0),
                            gdb_open_modeflags[ARG(1)]);                             (int)ARG(2)+1, gdb_open_modeflags[ARG(1)]);
             return env->regs[0];              return env->regs[0];
         } else {          } else {
             ret = set_swi_errno(ts, open(s, open_modeflags[ARG(1)], 0644));              ret = set_swi_errno(ts, open(s, open_modeflags[ARG(1)], 0644));
Line 240  uint32_t do_arm_semihosting(CPUState *en Line 221  uint32_t do_arm_semihosting(CPUState *en
         }          }
     case SYS_WRITEC:      case SYS_WRITEC:
         {          {
           char c = tget8(args);            char c;
   
             if (get_user_u8(c, args))
                 /* FIXME - should this error code be -TARGET_EFAULT ? */
                 return (uint32_t)-1;
           /* Write to debug console.  stderr is near enough.  */            /* Write to debug console.  stderr is near enough.  */
           if (use_gdb_syscalls()) {            if (use_gdb_syscalls()) {
                 gdb_do_syscall(arm_semi_cb, "write,2,%x,1", args);                  gdb_do_syscall(arm_semi_cb, "write,2,%x,1", args);
Line 250  uint32_t do_arm_semihosting(CPUState *en Line 235  uint32_t do_arm_semihosting(CPUState *en
           }            }
         }          }
     case SYS_WRITE0:      case SYS_WRITE0:
         s = lock_user_string(args);          if (!(s = lock_user_string(args)))
               /* FIXME - should this error code be -TARGET_EFAULT ? */
               return (uint32_t)-1;
         len = strlen(s);          len = strlen(s);
         if (use_gdb_syscalls()) {          if (use_gdb_syscalls()) {
             gdb_do_syscall(arm_semi_cb, "write,2,%x,%x\n", args, len);              gdb_do_syscall(arm_semi_cb, "write,2,%x,%x\n", args, len);
Line 267  uint32_t do_arm_semihosting(CPUState *en Line 254  uint32_t do_arm_semihosting(CPUState *en
             gdb_do_syscall(arm_semi_cb, "write,%x,%x,%x", ARG(0), ARG(1), len);              gdb_do_syscall(arm_semi_cb, "write,%x,%x,%x", ARG(0), ARG(1), len);
             return env->regs[0];              return env->regs[0];
         } else {          } else {
             s = lock_user(ARG(1), len, 1);              if (!(s = lock_user(VERIFY_READ, ARG(1), len, 1)))
                   /* FIXME - should this error code be -TARGET_EFAULT ? */
                   return (uint32_t)-1;
             ret = set_swi_errno(ts, write(ARG(0), s, len));              ret = set_swi_errno(ts, write(ARG(0), s, len));
             unlock_user(s, ARG(1), 0);              unlock_user(s, ARG(1), 0);
             if (ret == (uint32_t)-1)              if (ret == (uint32_t)-1)
Line 281  uint32_t do_arm_semihosting(CPUState *en Line 270  uint32_t do_arm_semihosting(CPUState *en
             gdb_do_syscall(arm_semi_cb, "read,%x,%x,%x", ARG(0), ARG(1), len);              gdb_do_syscall(arm_semi_cb, "read,%x,%x,%x", ARG(0), ARG(1), len);
             return env->regs[0];              return env->regs[0];
         } else {          } else {
             s = lock_user(ARG(1), len, 0);              if (!(s = lock_user(VERIFY_WRITE, ARG(1), len, 0)))
                   /* FIXME - should this error code be -TARGET_EFAULT ? */
                   return (uint32_t)-1;
             do              do
               ret = set_swi_errno(ts, read(ARG(0), s, len));                ret = set_swi_errno(ts, read(ARG(0), s, len));
             while (ret == -1 && errno == EINTR);              while (ret == -1 && errno == EINTR);
Line 302  uint32_t do_arm_semihosting(CPUState *en Line 293  uint32_t do_arm_semihosting(CPUState *en
         }          }
     case SYS_SEEK:      case SYS_SEEK:
         if (use_gdb_syscalls()) {          if (use_gdb_syscalls()) {
             gdb_do_syscall(arm_semi_cb, "fseek,%x,%x,0", ARG(0), ARG(1));              gdb_do_syscall(arm_semi_cb, "lseek,%x,%x,0", ARG(0), ARG(1));
             return env->regs[0];              return env->regs[0];
         } else {          } else {
             ret = set_swi_errno(ts, lseek(ARG(0), ARG(1), SEEK_SET));              ret = set_swi_errno(ts, lseek(ARG(0), ARG(1), SEEK_SET));
Line 312  uint32_t do_arm_semihosting(CPUState *en Line 303  uint32_t do_arm_semihosting(CPUState *en
         }          }
     case SYS_FLEN:      case SYS_FLEN:
         if (use_gdb_syscalls()) {          if (use_gdb_syscalls()) {
             /* TODO: Use stat syscall.  */              gdb_do_syscall(arm_semi_flen_cb, "fstat,%x,%x",
             return -1;                             ARG(0), env->regs[13]-64);
               return env->regs[0];
         } else {          } else {
             struct stat buf;              struct stat buf;
             ret = set_swi_errno(ts, fstat(ARG(0), &buf));              ret = set_swi_errno(ts, fstat(ARG(0), &buf));
Line 326  uint32_t do_arm_semihosting(CPUState *en Line 318  uint32_t do_arm_semihosting(CPUState *en
         return -1;          return -1;
     case SYS_REMOVE:      case SYS_REMOVE:
         if (use_gdb_syscalls()) {          if (use_gdb_syscalls()) {
             gdb_do_syscall(arm_semi_cb, "unlink,%s", ARG(0), (int)ARG(1));              gdb_do_syscall(arm_semi_cb, "unlink,%s", ARG(0), (int)ARG(1)+1);
             ret = env->regs[0];              ret = env->regs[0];
         } else {          } else {
             s = lock_user_string(ARG(0));              if (!(s = lock_user_string(ARG(0))))
                   /* FIXME - should this error code be -TARGET_EFAULT ? */
                   return (uint32_t)-1;
             ret =  set_swi_errno(ts, remove(s));              ret =  set_swi_errno(ts, remove(s));
             unlock_user(s, ARG(0), 0);              unlock_user(s, ARG(0), 0);
         }          }
Line 337  uint32_t do_arm_semihosting(CPUState *en Line 331  uint32_t do_arm_semihosting(CPUState *en
     case SYS_RENAME:      case SYS_RENAME:
         if (use_gdb_syscalls()) {          if (use_gdb_syscalls()) {
             gdb_do_syscall(arm_semi_cb, "rename,%s,%s",              gdb_do_syscall(arm_semi_cb, "rename,%s,%s",
                            ARG(0), (int)ARG(1), ARG(2), (int)ARG(3));                             ARG(0), (int)ARG(1)+1, ARG(2), (int)ARG(3)+1);
             return env->regs[0];              return env->regs[0];
         } else {          } else {
             char *s2;              char *s2;
             s = lock_user_string(ARG(0));              s = lock_user_string(ARG(0));
             s2 = lock_user_string(ARG(2));              s2 = lock_user_string(ARG(2));
             ret = set_swi_errno(ts, rename(s, s2));              if (!s || !s2)
             unlock_user(s2, ARG(2), 0);                  /* FIXME - should this error code be -TARGET_EFAULT ? */
             unlock_user(s, ARG(0), 0);                  ret = (uint32_t)-1;
               else
                   ret = set_swi_errno(ts, rename(s, s2));
               if (s2)
                   unlock_user(s2, ARG(2), 0);
               if (s)
                   unlock_user(s, ARG(0), 0);
             return ret;              return ret;
         }          }
     case SYS_CLOCK:      case SYS_CLOCK:
Line 354  uint32_t do_arm_semihosting(CPUState *en Line 354  uint32_t do_arm_semihosting(CPUState *en
         return set_swi_errno(ts, time(NULL));          return set_swi_errno(ts, time(NULL));
     case SYS_SYSTEM:      case SYS_SYSTEM:
         if (use_gdb_syscalls()) {          if (use_gdb_syscalls()) {
             gdb_do_syscall(arm_semi_cb, "system,%s", ARG(0), (int)ARG(1));              gdb_do_syscall(arm_semi_cb, "system,%s", ARG(0), (int)ARG(1)+1);
             return env->regs[0];              return env->regs[0];
         } else {          } else {
             s = lock_user_string(ARG(0));              if (!(s = lock_user_string(ARG(0))))
                   /* FIXME - should this error code be -TARGET_EFAULT ? */
                   return (uint32_t)-1;
             ret = set_swi_errno(ts, system(s));              ret = set_swi_errno(ts, system(s));
             unlock_user(s, ARG(0), 0);              unlock_user(s, ARG(0), 0);
         }          }
Line 365  uint32_t do_arm_semihosting(CPUState *en Line 367  uint32_t do_arm_semihosting(CPUState *en
 #ifdef CONFIG_USER_ONLY  #ifdef CONFIG_USER_ONLY
         return ts->swi_errno;          return ts->swi_errno;
 #else  #else
         return 0;          return syscall_err;
 #endif  #endif
     case SYS_GET_CMDLINE:      case SYS_GET_CMDLINE:
 #ifdef CONFIG_USER_ONLY  #ifdef CONFIG_USER_ONLY
Line 374  uint32_t do_arm_semihosting(CPUState *en Line 376  uint32_t do_arm_semihosting(CPUState *en
             char **arg = ts->info->host_argv;              char **arg = ts->info->host_argv;
             int len = ARG(1);              int len = ARG(1);
             /* lock the buffer on the ARM side */              /* lock the buffer on the ARM side */
             char *cmdline_buffer = (char*)lock_user(ARG(0), len, 0);              char *cmdline_buffer = (char*)lock_user(VERIFY_WRITE, ARG(0), len, 0);
   
               if (!cmdline_buffer)
                   /* FIXME - should this error code be -TARGET_EFAULT ? */
                   return (uint32_t)-1;
   
             s = cmdline_buffer;              s = cmdline_buffer;
             while (*arg && len > 2) {              while (*arg && len > 2) {
Line 429  uint32_t do_arm_semihosting(CPUState *en Line 435  uint32_t do_arm_semihosting(CPUState *en
                 }                  }
                 ts->heap_limit = limit;                  ts->heap_limit = limit;
             }              }
                 
             ptr = lock_user(ARG(0), 16, 0);              if (!(ptr = lock_user(VERIFY_WRITE, ARG(0), 16, 0)))
                   /* FIXME - should this error code be -TARGET_EFAULT ? */
                   return (uint32_t)-1;
             ptr[0] = tswap32(ts->heap_base);              ptr[0] = tswap32(ts->heap_base);
             ptr[1] = tswap32(ts->heap_limit);              ptr[1] = tswap32(ts->heap_limit);
             ptr[2] = tswap32(ts->stack_base);              ptr[2] = tswap32(ts->stack_base);
Line 438  uint32_t do_arm_semihosting(CPUState *en Line 446  uint32_t do_arm_semihosting(CPUState *en
             unlock_user(ptr, ARG(0), 16);              unlock_user(ptr, ARG(0), 16);
 #else  #else
             limit = ram_size;              limit = ram_size;
             ptr = lock_user(ARG(0), 16, 0);              if (!(ptr = lock_user(VERIFY_WRITE, ARG(0), 16, 0)))
                   /* FIXME - should this error code be -TARGET_EFAULT ? */
                   return (uint32_t)-1;
             /* TODO: Make this use the limit of the loaded application.  */              /* TODO: Make this use the limit of the loaded application.  */
             ptr[0] = tswap32(limit / 2);              ptr[0] = tswap32(limit / 2);
             ptr[1] = tswap32(limit);              ptr[1] = tswap32(limit);

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.2


unix.superglobalmegacorp.com