Preliminary patch for Alpha Linux user mode emulation support.
authorj_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162>
Thu, 5 Apr 2007 07:13:51 +0000 (07:13 +0000)
committerj_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162>
Thu, 5 Apr 2007 07:13:51 +0000 (07:13 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2600 c046a42c-6fe2-441c-8c8c-71466251a162

linux-user/elfload.c
linux-user/main.c
linux-user/syscall.c
linux-user/syscall_defs.h

index c0ea5a0..5caa44e 100644 (file)
@@ -313,6 +313,31 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i
 
 #endif
 
+#ifdef TARGET_ALPHA
+
+#define ELF_START_MMAP (0x30000000000ULL)
+
+#define elf_check_arch(x) ( (x) == ELF_ARCH )
+
+#define ELF_CLASS      ELFCLASS64
+#define ELF_DATA       ELFDATA2MSB
+#define ELF_ARCH       EM_ALPHA
+
+static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
+{
+    regs->pc = infop->entry;
+    regs->ps = 8;
+    regs->usp = infop->start_stack;
+    regs->unique = infop->start_data; /* ? */
+    printf("Set unique value to " TARGET_FMT_lx " (" TARGET_FMT_lx ")\n",
+           regs->unique, infop->start_data);
+}
+
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE        8192
+
+#endif /* TARGET_ALPHA */
+
 #ifndef ELF_PLATFORM
 #define ELF_PLATFORM (NULL)
 #endif
@@ -431,11 +456,11 @@ static void bswap_shdr(struct elf_shdr *shdr)
     bswaptls(&shdr->sh_entsize);
 }
 
-static void bswap_sym(Elf32_Sym *sym)
+static void bswap_sym(struct elf_sym *sym)
 {
     bswap32s(&sym->st_name);
-    bswap32s(&sym->st_value);
-    bswap32s(&sym->st_size);
+    bswaptls(&sym->st_value);
+    bswaptls(&sym->st_size);
     bswap16s(&sym->st_shndx);
 }
 #endif
index 0c5e6b5..cad10e6 100644 (file)
@@ -1534,6 +1534,96 @@ void cpu_loop(CPUM68KState *env)
 }
 #endif /* TARGET_M68K */
 
+#ifdef TARGET_ALPHA
+void cpu_loop (CPUState *env)
+{
+    int trapnr, ret;
+    target_siginfo_t info;
+    
+    while (1) {
+        trapnr = cpu_alpha_exec (env);
+        
+        switch (trapnr) {
+        case EXCP_RESET:
+            fprintf(stderr, "Reset requested. Exit\n");
+            exit(1);
+            break;
+        case EXCP_MCHK:
+            fprintf(stderr, "Machine check exception. Exit\n");
+            exit(1);
+            break;
+        case EXCP_ARITH:
+            fprintf(stderr, "Arithmetic trap.\n");
+            exit(1);
+            break;
+        case EXCP_HW_INTERRUPT:
+            fprintf(stderr, "External interrupt. Exit\n"); 
+            exit(1);
+            break;
+        case EXCP_DFAULT:
+            fprintf(stderr, "MMU data fault\n");
+            exit(1);
+            break;
+        case EXCP_DTB_MISS_PAL:
+            fprintf(stderr, "MMU data TLB miss in PALcode\n");
+            exit(1);
+            break;
+        case EXCP_ITB_MISS:
+            fprintf(stderr, "MMU instruction TLB miss\n");
+            exit(1);
+            break;
+        case EXCP_ITB_ACV:
+            fprintf(stderr, "MMU instruction access violation\n");
+            exit(1);
+            break;
+        case EXCP_DTB_MISS_NATIVE:
+            fprintf(stderr, "MMU data TLB miss\n");
+            exit(1);
+            break;
+        case EXCP_UNALIGN:
+            fprintf(stderr, "Unaligned access\n");
+            exit(1);
+            break;
+        case EXCP_OPCDEC:
+            fprintf(stderr, "Invalid instruction\n");
+            exit(1);
+            break;
+        case EXCP_FEN:
+            fprintf(stderr, "Floating-point not allowed\n");
+            exit(1);
+            break;
+        case EXCP_CALL_PAL ... (EXCP_CALL_PALP - 1):
+            fprintf(stderr, "Call to PALcode\n");
+            call_pal(env, (trapnr >> 6) | 0x80);
+            break;
+        case EXCP_CALL_PALP ... (EXCP_CALL_PALE - 1):
+            fprintf(stderr, "Priviledged call to PALcode\n");
+            exit(1);
+            break;
+        case EXCP_DEBUG:
+            {
+                int sig;
+
+                sig = gdb_handlesig (env, TARGET_SIGTRAP);
+                if (sig)
+                  {
+                    info.si_signo = sig;
+                    info.si_errno = 0;
+                    info.si_code = TARGET_TRAP_BRKPT;
+                    queue_signal(info.si_signo, &info);
+                  }
+            }
+            break;
+        default:
+            printf ("Unhandled trap: 0x%x\n", trapnr);
+            cpu_dump_state(env, stderr, fprintf, 0);
+            exit (1);
+        }
+        process_pending_signals (env);
+    }
+}
+#endif /* TARGET_ALPHA */
+
 void usage(void)
 {
     printf("qemu-" TARGET_ARCH " version " QEMU_VERSION ", Copyright (c) 2003-2007 Fabrice Bellard\n"
@@ -1877,6 +1967,18 @@ int main(int argc, char **argv)
         }
         env->pc = regs->pc;
     }
+#elif defined(TARGET_ALPHA)
+    {
+        int i;
+
+        for(i = 0; i < 28; i++) {
+            env->ir[i] = ((target_ulong *)regs)[i];
+        }
+        env->ipr[IPR_USP] = regs->usp;
+        env->ir[30] = regs->usp;
+        env->pc = regs->pc;
+        env->unique = regs->unique;
+    }
 #else
 #error unsupported target CPU
 #endif
index 33778aa..9dc0b09 100644 (file)
@@ -1765,6 +1765,16 @@ int do_fork(CPUState *env, unsigned int flags, unsigned long newsp)
          newsp = env->gregs[15];
        new_env->gregs[15] = newsp;
        /* XXXXX */
+#elif defined(TARGET_ALPHA)
+       if (!newsp)
+         newsp = env->ir[30];
+       new_env->ir[30] = newsp;
+        /* ? */
+        {
+            int i;
+            for (i = 7; i < 30; i++)
+                new_env->ir[i] = 0;
+        }
 #else
 #error unsupported target CPU
 #endif
@@ -2067,11 +2077,13 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
         }
         break;
 #endif
+#ifdef TARGET_NR_creat /* not on alpha */
     case TARGET_NR_creat:
         p = lock_user_string(arg1);
         ret = get_errno(creat(p, arg2));
         unlock_user(p, arg1, 0);
         break;
+#endif
     case TARGET_NR_link:
         {
             void * p2;
@@ -2179,7 +2191,11 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
     case TARGET_NR_lseek:
         ret = get_errno(lseek(arg1, arg2, arg3));
         break;
+#ifdef TARGET_NR_getxpid
+    case TARGET_NR_getxpid:
+#else
     case TARGET_NR_getpid:
+#endif
         ret = get_errno(getpid());
         break;
     case TARGET_NR_mount:
@@ -2202,6 +2218,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
         unlock_user(p, arg1, 0);
         break;
 #endif
+#ifdef TARGET_NR_stime /* not on alpha */
     case TARGET_NR_stime:
         {
             time_t host_time;
@@ -2209,18 +2226,23 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
             ret = get_errno(stime(&host_time));
         }
         break;
+#endif
     case TARGET_NR_ptrace:
         goto unimplemented;
+#ifdef TARGET_NR_alarm /* not on alpha */
     case TARGET_NR_alarm:
         ret = alarm(arg1);
         break;
+#endif
 #ifdef TARGET_NR_oldfstat
     case TARGET_NR_oldfstat:
         goto unimplemented;
 #endif
+#ifdef TARGET_NR_pause /* not on alpha */
     case TARGET_NR_pause:
         ret = get_errno(pause());
         break;
+#endif
 #ifdef TARGET_NR_utime
     case TARGET_NR_utime:
         {
@@ -2270,9 +2292,11 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
         ret = get_errno(access(p, arg2));
         unlock_user(p, arg1, 0);
         break;
+#ifdef TARGET_NR_nice /* not on alpha */
     case TARGET_NR_nice:
         ret = get_errno(nice(arg1));
         break;
+#endif
 #ifdef TARGET_NR_ftime
     case TARGET_NR_ftime:
         goto unimplemented;
@@ -2346,11 +2370,13 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
         ret = get_errno(acct(path(p)));
         unlock_user(p, arg1, 0);
         break;
+#ifdef TARGET_NR_umount2 /* not on alpha */
     case TARGET_NR_umount2:
         p = lock_user_string(arg1);
         ret = get_errno(umount2(p, arg2));
         unlock_user(p, arg1, 0);
         break;
+#endif
 #ifdef TARGET_NR_lock
     case TARGET_NR_lock:
         goto unimplemented;
@@ -2389,9 +2415,11 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
     case TARGET_NR_dup2:
         ret = get_errno(dup2(arg1, arg2));
         break;
+#ifdef TARGET_NR_getppid /* not on alpha */
     case TARGET_NR_getppid:
         ret = get_errno(getppid());
         break;
+#endif
     case TARGET_NR_getpgrp:
         ret = get_errno(getpgrp());
         break;
@@ -2474,6 +2502,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
                 unlock_user_struct(oact, arg3, 1);
         }
         break;
+#ifdef TARGET_NR_sgetmask /* not on alpha */
     case TARGET_NR_sgetmask:
         {
             sigset_t cur_set;
@@ -2483,6 +2512,8 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
             ret = target_set;
         }
         break;
+#endif
+#ifdef TARGET_NR_ssetmask /* not on alpha */
     case TARGET_NR_ssetmask:
         {
             sigset_t set, oset, cur_set;
@@ -2495,6 +2526,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
             ret = target_set;
         }
         break;
+#endif
 #ifdef TARGET_NR_sigprocmask
     case TARGET_NR_sigprocmask:
         {
@@ -3256,6 +3288,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
     case TARGET_NR_afs_syscall:
         goto unimplemented;
 #endif
+#ifdef TARGET_NR__llseek /* Not on alpha */
     case TARGET_NR__llseek:
         {
 #if defined (__x86_64__)
@@ -3268,6 +3301,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
 #endif
         }
         break;
+#endif
     case TARGET_NR_getdents:
 #if TARGET_LONG_SIZE != 4
         goto unimplemented;
@@ -3431,9 +3465,11 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
     case TARGET_NR_getsid:
         ret = get_errno(getsid(arg1));
         break;
+#if defined(TARGET_NR_fdatasync) /* Not on alpha (osf_datasync ?) */
     case TARGET_NR_fdatasync:
         ret = get_errno(fdatasync(arg1));
         break;
+#endif
     case TARGET_NR__sysctl:
         /* We don't implement this, but ENODIR is always a safe
            return value. */
index e33c12b..2989bb7 100644 (file)
@@ -49,7 +49,7 @@
 #define TARGET_IOC_TYPEBITS    8
 
 #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SH4) \
-    || defined(TARGET_M68K)
+    || defined(TARGET_M68K) || defined(TARGET_ALPHA)
 
 #define TARGET_IOC_SIZEBITS    14
 #define TARGET_IOC_DIRBITS     2
@@ -294,7 +294,7 @@ struct target_sigaction;
 int do_sigaction(int sig, const struct target_sigaction *act,
                  struct target_sigaction *oact);
 
-#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_MIPS) || defined (TARGET_SH4) || defined(TARGET_M68K)
+#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_MIPS) || defined (TARGET_SH4) || defined(TARGET_M68K) || defined(TARGET_ALPHA)
 
 #if defined(TARGET_SPARC)
 #define TARGET_SA_NOCLDSTOP    8u
@@ -1203,6 +1203,50 @@ struct target_stat64 {
 
        int64_t         st_blocks;
 };
+
+#elif defined(TARGET_ALPHA)
+
+struct target_stat {
+       unsigned int    st_dev;
+       unsigned int    st_ino;
+       unsigned int    st_mode;
+       unsigned int    st_nlink;
+       unsigned int    st_uid;
+       unsigned int    st_gid;
+       unsigned int    st_rdev;
+       target_long     st_size;
+       target_ulong    target_st_atime;
+       target_ulong    target_st_mtime;
+       target_ulong    target_st_ctime;
+       unsigned int    st_blksize;
+       unsigned int    st_blocks;
+       unsigned int    st_flags;
+       unsigned int    st_gen;
+};
+
+struct target_stat64 {
+       target_ulong    st_dev;
+       target_ulong    st_ino;
+       target_ulong    st_rdev;
+       target_long     st_size;
+       target_ulong    st_blocks;
+
+       unsigned int    st_mode;
+       unsigned int    st_uid;
+       unsigned int    st_gid;
+       unsigned int    st_blksize;
+       unsigned int    st_nlink;
+       unsigned int    __pad0;
+
+       target_ulong    target_st_atime;
+       target_ulong    target_st_atime_nsec; 
+       target_ulong    target_st_mtime;
+       target_ulong    target_st_mtime_nsec;
+       target_ulong    target_st_ctime;
+       target_ulong    target_st_ctime_nsec;
+       target_long     __unused[3];
+};
+
 #else
 #error unsupported CPU
 #endif