Preliminary patch for Alpha Linux user mode emulation support.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2600 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
86cc1ce083
commit
7a3148a955
@ -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
|
||||
|
@ -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
|
||||
|
@ -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. */
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user