diff options
Diffstat (limited to 'linux-user')
-rw-r--r-- | linux-user/elfload.c | 25 | ||||
-rw-r--r-- | linux-user/m68k-semi.c | 216 | ||||
-rw-r--r-- | linux-user/m68k-sim.c | 171 | ||||
-rw-r--r-- | linux-user/m68k/syscall.h | 22 | ||||
-rw-r--r-- | linux-user/m68k/syscall_nr.h | 283 | ||||
-rw-r--r-- | linux-user/m68k/termbits.h | 215 | ||||
-rw-r--r-- | linux-user/main.c | 121 | ||||
-rw-r--r-- | linux-user/mmap.c | 2 | ||||
-rw-r--r-- | linux-user/qemu.h | 3 | ||||
-rw-r--r-- | linux-user/syscall.c | 11 | ||||
-rw-r--r-- | linux-user/syscall_defs.h | 67 |
11 files changed, 1131 insertions, 5 deletions
diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 57b5ed27d8..042c65dc7a 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -288,6 +288,31 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i #endif +#ifdef TARGET_M68K + +#define ELF_START_MMAP 0x80000000 + +#define elf_check_arch(x) ( (x) == EM_68K ) + +#define ELF_CLASS ELFCLASS32 +#define ELF_DATA ELFDATA2MSB +#define ELF_ARCH EM_68K + +/* ??? Does this need to do anything? +#define ELF_PLAT_INIT(_r) */ + +static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) +{ + regs->usp = infop->start_stack; + regs->sr = 0; + regs->pc = infop->entry; +} + +#define USE_ELF_CORE_DUMP +#define ELF_EXEC_PAGESIZE 8192 + +#endif + #ifndef ELF_PLATFORM #define ELF_PLATFORM (NULL) #endif diff --git a/linux-user/m68k-semi.c b/linux-user/m68k-semi.c new file mode 100644 index 0000000000..7f6dddaee4 --- /dev/null +++ b/linux-user/m68k-semi.c @@ -0,0 +1,216 @@ +/* + * m68k/ColdFire Semihosting ssycall interface + * + * Copyright (c) 2005 CodeSourcery, LLC. Written by Paul Brook. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <errno.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> +#include <sys/time.h> +#include <time.h> + +#include "qemu.h" + +#define HOSTED_EXIT 0 +#define HOSTED_PUTCHAR 1 /* Obsolete */ +#define HOSTED_OPEN 2 +#define HOSTED_CLOSE 3 +#define HOSTED_READ 4 +#define HOSTED_WRITE 5 +#define HOSTED_LSEEK 6 +#define HOSTED_RENAME 7 +#define HOSTED_UNLINK 8 +#define HOSTED_STAT 9 +#define HOSTED_FSTAT 10 +#define HOSTED_GETTIMEOFDAY 11 +#define HOSTED_ISATTY 12 +#define HOSTED_SYSTEM 13 + +typedef uint32_t gdb_mode_t; +typedef uint32_t gdb_time_t; + +struct m68k_gdb_stat { + uint32_t gdb_st_dev; /* device */ + uint32_t gdb_st_ino; /* inode */ + gdb_mode_t gdb_st_mode; /* protection */ + uint32_t gdb_st_nlink; /* number of hard links */ + uint32_t gdb_st_uid; /* user ID of owner */ + uint32_t gdb_st_gid; /* group ID of owner */ + uint32_t gdb_st_rdev; /* device type (if inode device) */ + uint64_t gdb_st_size; /* total size, in bytes */ + uint64_t gdb_st_blksize; /* blocksize for filesystem I/O */ + uint64_t gdb_st_blocks; /* number of blocks allocated */ + gdb_time_t gdb_st_atime; /* time of last access */ + gdb_time_t gdb_st_mtime; /* time of last modification */ + gdb_time_t gdb_st_ctime; /* time of last change */ +}; + +struct gdb_timeval { + gdb_time_t tv_sec; /* second */ + uint64_t tv_usec; /* microsecond */ +}; + +#define GDB_O_RDONLY 0x0 +#define GDB_O_WRONLY 0x1 +#define GDB_O_RDWR 0x2 +#define GDB_O_APPEND 0x8 +#define GDB_O_CREAT 0x200 +#define GDB_O_TRUNC 0x400 +#define GDB_O_EXCL 0x800 + +static int translate_openflags(int flags) +{ + int hf; + + if (flags & GDB_O_WRONLY) + hf = O_WRONLY; + else if (flags & GDB_O_RDWR) + hf = O_RDWR; + else + hf = O_RDONLY; + + if (flags & GDB_O_APPEND) hf |= O_APPEND; + if (flags & GDB_O_CREAT) hf |= O_CREAT; + if (flags & GDB_O_TRUNC) hf |= O_TRUNC; + if (flags & GDB_O_EXCL) hf |= O_EXCL; + + return hf; +} + +static void translate_stat(struct m68k_gdb_stat *p, struct stat *s) +{ + p->gdb_st_dev = tswap16(s->st_dev); + p->gdb_st_ino = tswap16(s->st_ino); + p->gdb_st_mode = tswap32(s->st_mode); + p->gdb_st_nlink = tswap16(s->st_nlink); + p->gdb_st_uid = tswap16(s->st_uid); + p->gdb_st_gid = tswap16(s->st_gid); + p->gdb_st_rdev = tswap16(s->st_rdev); + p->gdb_st_size = tswap32(s->st_size); + p->gdb_st_atime = tswap32(s->st_atime); + p->gdb_st_mtime = tswap32(s->st_mtime); + p->gdb_st_ctime = tswap32(s->st_ctime); + p->gdb_st_blksize = tswap32(s->st_blksize); + p->gdb_st_blocks = tswap32(s->st_blocks); +} + +static inline uint32_t check_err(CPUM68KState *env, uint32_t code) +{ + if (code == (uint32_t)-1) { + env->sr |= CCF_C; + } else { + env->sr &= ~CCF_C; + env->dregs[0] = code; + } + return code; +} + +#define ARG(x) tswap32(args[x]) +void do_m68k_semihosting(CPUM68KState *env, int nr) +{ + uint32_t *args; + + args = (uint32_t *)env->dregs[1]; + switch (nr) { + case HOSTED_EXIT: + exit(env->dregs[0]); + case HOSTED_OPEN: + /* Assume name is NULL terminated. */ + check_err(env, open((char *)ARG(0), translate_openflags(ARG(2)), + ARG(3))); + break; + case HOSTED_CLOSE: + { + /* Ignore attempts to close stdin/out/err. */ + int fd = ARG(0); + if (fd > 2) + check_err(env, close(fd)); + else + check_err(env, 0); + break; + } + case HOSTED_READ: + check_err(env, read(ARG(0), (void *)ARG(1), ARG(2))); + break; + case HOSTED_WRITE: + check_err(env, write(ARG(0), (void *)ARG(1), ARG(2))); + break; + case HOSTED_LSEEK: + { + uint64_t off; + off = (uint32_t)ARG(2) | ((uint64_t)ARG(1) << 32); + check_err(env, lseek(ARG(0), off, ARG(3))); + } + break; + case HOSTED_RENAME: + /* Assume names are NULL terminated. */ + check_err(env, rename((char *)ARG(0), (char *)ARG(2))); + break; + case HOSTED_UNLINK: + /* Assume name is NULL terminated. */ + check_err(env, unlink((char *)ARG(0))); + break; + case HOSTED_STAT: + /* Assume name is NULL terminated. */ + { + struct stat s; + int rc; + rc = check_err(env, stat((char *)ARG(0), &s)); + if (rc == 0) { + translate_stat((struct m68k_gdb_stat *)ARG(2), &s); + } + } + break; + case HOSTED_FSTAT: + { + struct stat s; + int rc; + rc = check_err(env, fstat(ARG(0), &s)); + if (rc == 0) { + translate_stat((struct m68k_gdb_stat *)ARG(1), &s); + } + } + break; + case HOSTED_GETTIMEOFDAY: + { + struct timeval tv; + struct gdb_timeval *p; + int rc; + rc = check_err(env, gettimeofday(&tv, NULL)); + if (rc != 0) { + p = (struct gdb_timeval *)ARG(0); + p->tv_sec = tswap32(tv.tv_sec); + p->tv_usec = tswap64(tv.tv_usec); + } + } + break; + case HOSTED_ISATTY: + check_err(env, isatty(ARG(0))); + break; + case HOSTED_SYSTEM: + /* Assume name is NULL terminated. */ + check_err(env, system((char *)ARG(0))); + break; + default: + cpu_abort(env, "Unsupported semihosting syscall %d\n", nr); + } +} diff --git a/linux-user/m68k-sim.c b/linux-user/m68k-sim.c new file mode 100644 index 0000000000..667808e8c8 --- /dev/null +++ b/linux-user/m68k-sim.c @@ -0,0 +1,171 @@ +/* + * m68k simulator syscall interface + * + * Copyright (c) 2005 CodeSourcery, LLC. Written by Paul Brook. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <errno.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> +#include <time.h> + +#include "qemu.h" + +#define SYS_EXIT 1 +#define SYS_READ 3 +#define SYS_WRITE 4 +#define SYS_OPEN 5 +#define SYS_CLOSE 6 +#define SYS_BRK 17 +#define SYS_FSTAT 28 +#define SYS_ISATTY 29 +#define SYS_LSEEK 199 + +struct m86k_sim_stat { + uint16_t sim_st_dev; + uint16_t sim_st_ino; + uint32_t sim_st_mode; + uint16_t sim_st_nlink; + uint16_t sim_st_uid; + uint16_t sim_st_gid; + uint16_t sim_st_rdev; + uint32_t sim_st_size; + uint32_t sim_st_atime; + uint32_t sim_st_mtime; + uint32_t sim_st_ctime; + uint32_t sim_st_blksize; + uint32_t sim_st_blocks; +}; + +static inline uint32_t check_err(CPUM68KState *env, uint32_t code) +{ + env->dregs[0] = code; + if (code == (uint32_t)-1) { + env->dregs[1] = errno; + } else { + env->dregs[1] = 0; + } + return code; +} + +#define SIM_O_APPEND 0x0008 +#define SIM_O_CREAT 0x0200 +#define SIM_O_TRUNC 0x0400 +#define SIM_O_EXCL 0x0800 +#define SIM_O_NONBLOCK 0x4000 +#define SIM_O_NOCTTY 0x8000 +#define SIM_O_SYNC 0x2000 + +static int translate_openflags(int flags) +{ + int hf; + + switch (flags & 3) { + case 0: hf = O_RDONLY; break; + case 1: hf = O_WRONLY; break; + case 2: hf = O_RDWR; break; + default: hf = O_RDWR; break; + } + + if (flags & SIM_O_APPEND) hf |= O_APPEND; + if (flags & SIM_O_CREAT) hf |= O_CREAT; + if (flags & SIM_O_TRUNC) hf |= O_TRUNC; + if (flags & SIM_O_EXCL) hf |= O_EXCL; + if (flags & SIM_O_NONBLOCK) hf |= O_NONBLOCK; + if (flags & SIM_O_NOCTTY) hf |= O_NOCTTY; + if (flags & SIM_O_SYNC) hf |= O_SYNC; + + return hf; +} + +#define ARG(x) tswap32(args[x]) +void do_m68k_simcall(CPUM68KState *env, int nr) +{ + uint32_t *args; + + args = (uint32_t *)(env->aregs[7] + 4); + switch (nr) { + case SYS_EXIT: + exit(ARG(0)); + case SYS_READ: + check_err(env, read(ARG(0), (void *)ARG(1), ARG(2))); + break; + case SYS_WRITE: + check_err(env, write(ARG(0), (void *)ARG(1), ARG(2))); + break; + case SYS_OPEN: + check_err(env, open((char *)ARG(0), translate_openflags(ARG(1)), + ARG(2))); + break; + case SYS_CLOSE: + { + /* Ignore attempts to close stdin/out/err. */ + int fd = ARG(0); + if (fd > 2) + check_err(env, close(fd)); + else + check_err(env, 0); + break; + } + case SYS_BRK: + { + int32_t ret; + + ret = do_brk((void *)ARG(0)); + if (ret == -ENOMEM) + ret = -1; + check_err(env, ret); + } + break; + case SYS_FSTAT: + { + struct stat s; + int rc; + struct m86k_sim_stat *p; + rc = check_err(env, fstat(ARG(0), &s)); + if (rc == 0) { + p = (struct m86k_sim_stat *)ARG(1); + p->sim_st_dev = tswap16(s.st_dev); + p->sim_st_ino = tswap16(s.st_ino); + p->sim_st_mode = tswap32(s.st_mode); + p->sim_st_nlink = tswap16(s.st_nlink); + p->sim_st_uid = tswap16(s.st_uid); + p->sim_st_gid = tswap16(s.st_gid); + p->sim_st_rdev = tswap16(s.st_rdev); + p->sim_st_size = tswap32(s.st_size); + p->sim_st_atime = tswap32(s.st_atime); + p->sim_st_mtime = tswap32(s.st_mtime); + p->sim_st_ctime = tswap32(s.st_ctime); + p->sim_st_blksize = tswap32(s.st_blksize); + p->sim_st_blocks = tswap32(s.st_blocks); + } + } + break; + case SYS_ISATTY: + check_err(env, isatty(ARG(0))); + break; + case SYS_LSEEK: + check_err(env, lseek(ARG(0), (int32_t)ARG(1), ARG(2))); + break; + default: + cpu_abort(env, "Unsupported m68k sim syscall %d\n", nr); + } +} diff --git a/linux-user/m68k/syscall.h b/linux-user/m68k/syscall.h new file mode 100644 index 0000000000..c225567d2a --- /dev/null +++ b/linux-user/m68k/syscall.h @@ -0,0 +1,22 @@ + +/* this struct defines the way the registers are stored on the + stack during a system call. */ + +struct target_pt_regs { + target_long d1, d2, d3, d4, d5, d6, d7; + target_long a0, a1, a2, a3, a4, a5, a6; + target_ulong d0; + target_ulong usp; + target_ulong orig_d0; + int16_t stkadj; + uint16_t sr; + target_ulong pc; + uint16_t fntvex; + uint16_t __fill; +}; + + +#define UNAME_MACHINE "m68k" + +void do_m68k_semihosting(CPUState *, int); +void do_m68k_simcall(CPUState *, int); diff --git a/linux-user/m68k/syscall_nr.h b/linux-user/m68k/syscall_nr.h new file mode 100644 index 0000000000..a39535f5f3 --- /dev/null +++ b/linux-user/m68k/syscall_nr.h @@ -0,0 +1,283 @@ +/* + * This file contains the system call numbers. + */ + +#define TARGET_NR_exit 1 +#define TARGET_NR_fork 2 +#define TARGET_NR_read 3 +#define TARGET_NR_write 4 +#define TARGET_NR_open 5 +#define TARGET_NR_close 6 +#define TARGET_NR_waitpid 7 +#define TARGET_NR_creat 8 +#define TARGET_NR_link 9 +#define TARGET_NR_unlink 10 +#define TARGET_NR_execve 11 +#define TARGET_NR_chdir 12 +#define TARGET_NR_time 13 +#define TARGET_NR_mknod 14 +#define TARGET_NR_chmod 15 +#define TARGET_NR_chown 16 +#define TARGET_NR_break 17 +#define TARGET_NR_oldstat 18 +#define TARGET_NR_lseek 19 +#define TARGET_NR_getpid 20 +#define TARGET_NR_mount 21 +#define TARGET_NR_umount 22 +#define TARGET_NR_setuid 23 +#define TARGET_NR_getuid 24 +#define TARGET_NR_stime 25 +#define TARGET_NR_ptrace 26 +#define TARGET_NR_alarm 27 +#define TARGET_NR_oldfstat 28 +#define TARGET_NR_pause 29 +#define TARGET_NR_utime 30 +#define TARGET_NR_stty 31 +#define TARGET_NR_gtty 32 +#define TARGET_NR_access 33 +#define TARGET_NR_nice 34 +#define TARGET_NR_ftime 35 +#define TARGET_NR_sync 36 +#define TARGET_NR_kill 37 +#define TARGET_NR_rename 38 +#define TARGET_NR_mkdir 39 +#define TARGET_NR_rmdir 40 +#define TARGET_NR_dup 41 +#define TARGET_NR_pipe 42 +#define TARGET_NR_times 43 +#define TARGET_NR_prof 44 +#define TARGET_NR_brk 45 +#define TARGET_NR_setgid 46 +#define TARGET_NR_getgid 47 +#define TARGET_NR_signal 48 +#define TARGET_NR_geteuid 49 +#define TARGET_NR_getegid 50 +#define TARGET_NR_acct 51 +#define TARGET_NR_umount2 52 +#define TARGET_NR_lock 53 +#define TARGET_NR_ioctl 54 +#define TARGET_NR_fcntl 55 +#define TARGET_NR_mpx 56 +#define TARGET_NR_setpgid 57 +#define TARGET_NR_ulimit 58 +#define TARGET_NR_oldolduname 59 +#define TARGET_NR_umask 60 +#define TARGET_NR_chroot 61 +#define TARGET_NR_ustat 62 +#define TARGET_NR_dup2 63 +#define TARGET_NR_getppid 64 +#define TARGET_NR_getpgrp 65 +#define TARGET_NR_setsid 66 +#define TARGET_NR_sigaction 67 +#define TARGET_NR_sgetmask 68 +#define TARGET_NR_ssetmask 69 +#define TARGET_NR_setreuid 70 +#define TARGET_NR_setregid 71 +#define TARGET_NR_sigsuspend 72 +#define TARGET_NR_sigpending 73 +#define TARGET_NR_sethostname 74 +#define TARGET_NR_setrlimit 75 +#define TARGET_NR_getrlimit 76 +#define TARGET_NR_getrusage 77 +#define TARGET_NR_gettimeofday 78 +#define TARGET_NR_settimeofday 79 +#define TARGET_NR_getgroups 80 +#define TARGET_NR_setgroups 81 +#define TARGET_NR_select 82 +#define TARGET_NR_symlink 83 +#define TARGET_NR_oldlstat 84 +#define TARGET_NR_readlink 85 +#define TARGET_NR_uselib 86 +#define TARGET_NR_swapon 87 +#define TARGET_NR_reboot 88 +#define TARGET_NR_readdir 89 +#define TARGET_NR_mmap 90 +#define TARGET_NR_munmap 91 +#define TARGET_NR_truncate 92 +#define TARGET_NR_ftruncate 93 +#define TARGET_NR_fchmod 94 +#define TARGET_NR_fchown 95 +#define TARGET_NR_getpriority 96 +#define TARGET_NR_setpriority 97 +#define TARGET_NR_profil 98 +#define TARGET_NR_statfs 99 +#define TARGET_NR_fstatfs 100 +#define TARGET_NR_ioperm 101 +#define TARGET_NR_socketcall 102 +#define TARGET_NR_syslog 103 +#define TARGET_NR_setitimer 104 +#define TARGET_NR_getitimer 105 +#define TARGET_NR_stat 106 +#define TARGET_NR_lstat 107 +#define TARGET_NR_fstat 108 +#define TARGET_NR_olduname 109 +//#define TARGET_NR_iopl /* 110 */ not supported +#define TARGET_NR_vhangup 111 +//#define TARGET_NR_idle /* 112 */ Obsolete +//#define TARGET_NR_vm86 /* 113 */ not supported +#define TARGET_NR_wait4 114 +#define TARGET_NR_swapoff 115 +#define TARGET_NR_sysinfo 116 +#define TARGET_NR_ipc 117 +#define TARGET_NR_fsync 118 +#define TARGET_NR_sigreturn 119 +#define TARGET_NR_clone 120 +#define TARGET_NR_setdomainname 121 +#define TARGET_NR_uname 122 +#define TARGET_NR_cacheflush 123 +#define TARGET_NR_adjtimex 124 +#define TARGET_NR_mprotect 125 +#define TARGET_NR_sigprocmask 126 +#define TARGET_NR_create_module 127 +#define TARGET_NR_init_module 128 +#define TARGET_NR_delete_module 129 +#define TARGET_NR_get_kernel_syms 130 +#define TARGET_NR_quotactl 131 +#define TARGET_NR_getpgid 132 +#define TARGET_NR_fchdir 133 +#define TARGET_NR_bdflush 134 +#define TARGET_NR_sysfs 135 +#define TARGET_NR_personality 136 +#define TARGET_NR_afs_syscall 137 /* Syscall for Andrew File System */ +#define TARGET_NR_setfsuid 138 +#define TARGET_NR_setfsgid 139 +#define TARGET_NR__llseek 140 +#define TARGET_NR_getdents 141 +#define TARGET_NR__newselect 142 +#define TARGET_NR_flock 143 +#define TARGET_NR_msync 144 +#define TARGET_NR_readv 145 +#define TARGET_NR_writev 146 +#define TARGET_NR_getsid 147 +#define TARGET_NR_fdatasync 148 +#define TARGET_NR__sysctl 149 +#define TARGET_NR_mlock 150 +#define TARGET_NR_munlock 151 +#define TARGET_NR_mlockall 152 +#define TARGET_NR_munlockall 153 +#define TARGET_NR_sched_setparam 154 +#define TARGET_NR_sched_getparam 155 +#define TARGET_NR_sched_setscheduler 156 +#define TARGET_NR_sched_getscheduler 157 +#define TARGET_NR_sched_yield 158 +#define TARGET_NR_sched_get_priority_max 159 +#define TARGET_NR_sched_get_priority_min 160 +#define TARGET_NR_sched_rr_get_interval 161 +#define TARGET_NR_nanosleep 162 +#define TARGET_NR_mremap 163 +#define TARGET_NR_setresuid 164 +#define TARGET_NR_getresuid 165 +#define TARGET_NR_getpagesize 166 +#define TARGET_NR_query_module 167 +#define TARGET_NR_poll 168 +#define TARGET_NR_nfsservctl 169 +#define TARGET_NR_setresgid 170 +#define TARGET_NR_getresgid 171 +#define TARGET_NR_prctl 172 +#define TARGET_NR_rt_sigreturn 173 +#define TARGET_NR_rt_sigaction 174 +#define TARGET_NR_rt_sigprocmask 175 +#define TARGET_NR_rt_sigpending 176 +#define TARGET_NR_rt_sigtimedwait 177 +#define TARGET_NR_rt_sigqueueinfo 178 +#define TARGET_NR_rt_sigsuspend 179 +#define TARGET_NR_pread64 180 +#define TARGET_NR_pwrite64 181 +#define TARGET_NR_lchown 182 +#define TARGET_NR_getcwd 183 +#define TARGET_NR_capget 184 +#define TARGET_NR_capset 185 +#define TARGET_NR_sigaltstack 186 +#define TARGET_NR_sendfile 187 +#define TARGET_NR_getpmsg 188 /* some people actually want streams */ +#define TARGET_NR_putpmsg 189 /* some people actually want streams */ +#define TARGET_NR_vfork 190 +#define TARGET_NR_ugetrlimit 191 +#define TARGET_NR_mmap2 192 +#define TARGET_NR_truncate64 193 +#define TARGET_NR_ftruncate64 194 +#define TARGET_NR_stat64 195 +#define TARGET_NR_lstat64 196 +#define TARGET_NR_fstat64 197 +#define TARGET_NR_chown32 198 +#define TARGET_NR_getuid32 199 +#define TARGET_NR_getgid32 200 +#define TARGET_NR_geteuid32 201 +#define TARGET_NR_getegid32 202 +#define TARGET_NR_setreuid32 203 +#define TARGET_NR_setregid32 204 +#define TARGET_NR_getgroups32 205 +#define TARGET_NR_setgroups32 206 +#define TARGET_NR_fchown32 207 +#define TARGET_NR_setresuid32 208 +#define TARGET_NR_getresuid32 209 +#define TARGET_NR_setresgid32 210 +#define TARGET_NR_getresgid32 211 +#define TARGET_NR_lchown32 212 +#define TARGET_NR_setuid32 213 +#define TARGET_NR_setgid32 214 +#define TARGET_NR_setfsuid32 215 +#define TARGET_NR_setfsgid32 216 +#define TARGET_NR_pivot_root 217 +#define TARGET_NR_getdents64 220 +#define TARGET_NR_gettid 221 +#define TARGET_NR_tkill 222 +#define TARGET_NR_setxattr 223 +#define TARGET_NR_lsetxattr 224 +#define TARGET_NR_fsetxattr 225 +#define TARGET_NR_getxattr 226 +#define TARGET_NR_lgetxattr 227 +#define TARGET_NR_fgetxattr 228 +#define TARGET_NR_listxattr 229 +#define TARGET_NR_llistxattr 230 +#define TARGET_NR_flistxattr 231 +#define TARGET_NR_removexattr 232 +#define TARGET_NR_lremovexattr 233 +#define TARGET_NR_fremovexattr 234 +#define TARGET_NR_futex 235 +#define TARGET_NR_sendfile64 236 +#define TARGET_NR_mincore 237 +#define TARGET_NR_madvise 238 +#define TARGET_NR_fcntl64 239 +#define TARGET_NR_readahead 240 +#define TARGET_NR_io_setup 241 +#define TARGET_NR_io_destroy 242 +#define TARGET_NR_io_getevents 243 +#define TARGET_NR_io_submit 244 +#define TARGET_NR_io_cancel 245 +#define TARGET_NR_fadvise64 246 +#define TARGET_NR_exit_group 247 +#define TARGET_NR_lookup_dcookie 248 +#define TARGET_NR_epoll_create 249 +#define TARGET_NR_epoll_ctl 250 +#define TARGET_NR_epoll_wait 251 +#define TARGET_NR_remap_file_pages 252 +#define TARGET_NR_set_tid_address 253 +#define TARGET_NR_timer_create 254 +#define TARGET_NR_timer_settime 255 +#define TARGET_NR_timer_gettime 256 +#define TARGET_NR_timer_getoverrun 257 +#define TARGET_NR_timer_delete 258 +#define TARGET_NR_clock_settime 259 +#define TARGET_NR_clock_gettime 260 +#define TARGET_NR_clock_getres 261 +#define TARGET_NR_clock_nanosleep 262 +#define TARGET_NR_statfs64 263 +#define TARGET_NR_fstatfs64 264 +#define TARGET_NR_tgkill 265 +#define TARGET_NR_utimes 266 +#define TARGET_NR_fadvise64_64 267 +#define TARGET_NR_mbind 268 +#define TARGET_NR_get_mempolicy 269 +#define TARGET_NR_set_mempolicy 270 +#define TARGET_NR_mq_open 271 +#define TARGET_NR_mq_unlink 272 +#define TARGET_NR_mq_timedsend 273 +#define TARGET_NR_mq_timedreceive 274 +#define TARGET_NR_mq_notify 275 +#define TARGET_NR_mq_getsetattr 276 +#define TARGET_NR_waitid 277 +#define TARGET_NR_vserver 278 +#define TARGET_NR_add_key 279 +#define TARGET_NR_request_key 280 +#define TARGET_NR_keyctl 281 diff --git a/linux-user/m68k/termbits.h b/linux-user/m68k/termbits.h new file mode 100644 index 0000000000..36ead08957 --- /dev/null +++ b/linux-user/m68k/termbits.h @@ -0,0 +1,215 @@ +/* from asm/termbits.h */ +/* NOTE: exactly the same as i386 */ + +#define TARGET_NCCS 19 + +struct target_termios { + unsigned int c_iflag; /* input mode flags */ + unsigned int c_oflag; /* output mode flags */ + unsigned int c_cflag; /* control mode flags */ + unsigned int c_lflag; /* local mode flags */ + unsigned char c_line; /* line discipline */ + unsigned char c_cc[TARGET_NCCS]; /* control characters */ +}; + +/* c_iflag bits */ +#define TARGET_IGNBRK 0000001 +#define TARGET_BRKINT 0000002 +#define TARGET_IGNPAR 0000004 +#define TARGET_PARMRK 0000010 +#define TARGET_INPCK 0000020 +#define TARGET_ISTRIP 0000040 +#define TARGET_INLCR 0000100 +#define TARGET_IGNCR 0000200 +#define TARGET_ICRNL 0000400 +#define TARGET_IUCLC 0001000 +#define TARGET_IXON 0002000 +#define TARGET_IXANY 0004000 +#define TARGET_IXOFF 0010000 +#define TARGET_IMAXBEL 0020000 + +/* c_oflag bits */ +#define TARGET_OPOST 0000001 +#define TARGET_OLCUC 0000002 +#define TARGET_ONLCR 0000004 +#define TARGET_OCRNL 0000010 +#define TARGET_ONOCR 0000020 +#define TARGET_ONLRET 0000040 +#define TARGET_OFILL 0000100 +#define TARGET_OFDEL 0000200 +#define TARGET_NLDLY 0000400 +#define TARGET_NL0 0000000 +#define TARGET_NL1 0000400 +#define TARGET_CRDLY 0003000 +#define TARGET_CR0 0000000 +#define TARGET_CR1 0001000 +#define TARGET_CR2 0002000 +#define TARGET_CR3 0003000 +#define TARGET_TABDLY 0014000 +#define TARGET_TAB0 0000000 +#define TARGET_TAB1 0004000 +#define TARGET_TAB2 0010000 +#define TARGET_TAB3 0014000 +#define TARGET_XTABS 0014000 +#define TARGET_BSDLY 0020000 +#define TARGET_BS0 0000000 +#define TARGET_BS1 0020000 +#define TARGET_VTDLY 0040000 +#define TARGET_VT0 0000000 +#define TARGET_VT1 0040000 +#define TARGET_FFDLY 0100000 +#define TARGET_FF0 0000000 +#define TARGET_FF1 0100000 + +/* c_cflag bit meaning */ +#define TARGET_CBAUD 0010017 +#define TARGET_B0 0000000 /* hang up */ +#define TARGET_B50 0000001 +#define TARGET_B75 0000002 +#define TARGET_B110 0000003 +#define TARGET_B134 0000004 +#define TARGET_B150 0000005 +#define TARGET_B200 0000006 +#define TARGET_B300 0000007 +#define TARGET_B600 0000010 +#define TARGET_B1200 0000011 +#define TARGET_B1800 0000012 +#define TARGET_B2400 0000013 +#define TARGET_B4800 0000014 +#define TARGET_B9600 0000015 +#define TARGET_B19200 0000016 +#define TARGET_B38400 0000017 +#define TARGET_EXTA B19200 +#define TARGET_EXTB B38400 +#define TARGET_CSIZE 0000060 +#define TARGET_CS5 0000000 +#define TARGET_CS6 0000020 +#define TARGET_CS7 0000040 +#define TARGET_CS8 0000060 +#define TARGET_CSTOPB 0000100 +#define TARGET_CREAD 0000200 +#define TARGET_PARENB 0000400 +#define TARGET_PARODD 0001000 +#define TARGET_HUPCL 0002000 +#define TARGET_CLOCAL 0004000 +#define TARGET_CBAUDEX 0010000 +#define TARGET_B57600 0010001 +#define TARGET_B115200 0010002 +#define TARGET_B230400 0010003 +#define TARGET_B460800 0010004 +#define TARGET_CIBAUD 002003600000 /* input baud rate (not used) */ +#define TARGET_CRTSCTS 020000000000 /* flow control */ + +/* c_lflag bits */ +#define TARGET_ISIG 0000001 +#define TARGET_ICANON 0000002 +#define TARGET_XCASE 0000004 +#define TARGET_ECHO 0000010 +#define TARGET_ECHOE 0000020 +#define TARGET_ECHOK 0000040 +#define TARGET_ECHONL 0000100 +#define TARGET_NOFLSH 0000200 +#define TARGET_TOSTOP 0000400 +#define TARGET_ECHOCTL 0001000 +#define TARGET_ECHOPRT 0002000 +#define TARGET_ECHOKE 0004000 +#define TARGET_FLUSHO 0010000 +#define TARGET_PENDIN 0040000 +#define TARGET_IEXTEN 0100000 + +/* c_cc character offsets */ +#define TARGET_VINTR 0 +#define TARGET_VQUIT 1 +#define TARGET_VERASE 2 +#define TARGET_VKILL 3 +#define TARGET_VEOF 4 +#define TARGET_VTIME 5 +#define TARGET_VMIN 6 +#define TARGET_VSWTC 7 +#define TARGET_VSTART 8 +#define TARGET_VSTOP 9 +#define TARGET_VSUSP 10 +#define TARGET_VEOL 11 +#define TARGET_VREPRINT 12 +#define TARGET_VDISCARD 13 +#define TARGET_VWERASE 14 +#define TARGET_VLNEXT 15 +#define TARGET_VEOL2 16 + +/* ioctls */ + +#define TARGET_TCGETS 0x5401 +#define TARGET_TCSETS 0x5402 +#define TARGET_TCSETSW 0x5403 +#define TARGET_TCSETSF 0x5404 +#define TARGET_TCGETA 0x5405 +#define TARGET_TCSETA 0x5406 +#define TARGET_TCSETAW 0x5407 +#define TARGET_TCSETAF 0x5408 +#define TARGET_TCSBRK 0x5409 +#define TARGET_TCXONC 0x540A +#define TARGET_TCFLSH 0x540B + +#define TARGET_TIOCEXCL 0x540C +#define TARGET_TIOCNXCL 0x540D +#define TARGET_TIOCSCTTY 0x540E +#define TARGET_TIOCGPGRP 0x540F +#define TARGET_TIOCSPGRP 0x5410 +#define TARGET_TIOCOUTQ 0x5411 +#define TARGET_TIOCSTI 0x5412 +#define TARGET_TIOCGWINSZ 0x5413 +#define TARGET_TIOCSWINSZ 0x5414 +#define TARGET_TIOCMGET 0x5415 +#define TARGET_TIOCMBIS 0x5416 +#define TARGET_TIOCMBIC 0x5417 +#define TARGET_TIOCMSET 0x5418 +#define TARGET_TIOCGSOFTCAR 0x5419 +#define TARGET_TIOCSSOFTCAR 0x541A +#define TARGET_FIONREAD 0x541B +#define TARGET_TIOCINQ TARGET_FIONREAD +#define TARGET_TIOCLINUX 0x541C +#define TARGET_TIOCCONS 0x541D +#define TARGET_TIOCGSERIAL 0x541E +#define TARGET_TIOCSSERIAL 0x541F +#define TARGET_TIOCPKT 0x5420 +#define TARGET_FIONBIO 0x5421 +#define TARGET_TIOCNOTTY 0x5422 +#define TARGET_TIOCSETD 0x5423 +#define TARGET_TIOCGETD 0x5424 +#define TARGET_TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ +#define TARGET_TIOCTTYGSTRUCT 0x5426 /* For debugging only */ +#define TARGET_TIOCSBRK 0x5427 /* BSD compatibility */ +#define TARGET_TIOCCBRK 0x5428 /* BSD compatibility */ +#define TARGET_TIOCGSID 0x5429 /* Return the session ID of FD */ +#define TARGET_TIOCGPTN TARGET_IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ +#define TARGET_TIOCSPTLCK TARGET_IOW('T',0x31, int) /* Lock/unlock Pty */ + +#define TARGET_FIONCLEX 0x5450 /* these numbers need to be adjusted. */ +#define TARGET_FIOCLEX 0x5451 +#define TARGET_FIOASYNC 0x5452 +#define TARGET_TIOCSERCONFIG 0x5453 +#define TARGET_TIOCSERGWILD 0x5454 +#define TARGET_TIOCSERSWILD 0x5455 +#define TARGET_TIOCGLCKTRMIOS 0x5456 +#define TARGET_TIOCSLCKTRMIOS 0x5457 +#define TARGET_TIOCSERGSTRUCT 0x5458 /* For debugging only */ +#define TARGET_TIOCSERGETLSR 0x5459 /* Get line status register */ +#define TARGET_TIOCSERGETMULTI 0x545A /* Get multiport config */ +#define TARGET_TIOCSERSETMULTI 0x545B /* Set multiport config */ + +#define TARGET_TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ +#define TARGET_TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ +#define TARGET_TIOCGHAYESESP 0x545E /* Get Hayes ESP configuration */ +#define TARGET_TIOCSHAYESESP 0x545F /* Set Hayes ESP configuration */ + +/* Used for packet mode */ +#define TARGET_TIOCPKT_DATA 0 +#define TARGET_TIOCPKT_FLUSHREAD 1 +#define TARGET_TIOCPKT_FLUSHWRITE 2 +#define TARGET_TIOCPKT_STOP 4 +#define TARGET_TIOCPKT_START 8 +#define TARGET_TIOCPKT_NOSTOP 16 +#define TARGET_TIOCPKT_DOSTOP 32 + +#define TARGET_TIOCSER_TEMT 0x01 /* Transmitter physically empty */ + diff --git a/linux-user/main.c b/linux-user/main.c index 42f4a03506..53bf1bb92e 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -1412,6 +1412,98 @@ void cpu_loop (CPUState *env) } #endif +#ifdef TARGET_M68K + +void cpu_loop(CPUM68KState *env) +{ + int trapnr; + unsigned int n; + target_siginfo_t info; + TaskState *ts = env->opaque; + + for(;;) { + trapnr = cpu_m68k_exec(env); + switch(trapnr) { + case EXCP_ILLEGAL: + { + if (ts->sim_syscalls) { + uint16_t nr; + nr = lduw(env->pc + 2); + env->pc += 4; + do_m68k_simcall(env, nr); + } else { + goto do_sigill; + } + } + break; + case EXCP_HALTED: + /* Semihosing syscall. */ + env->pc += 2; + do_m68k_semihosting(env, env->dregs[0]); + break; + case EXCP_LINEA: + case EXCP_LINEF: + case EXCP_UNSUPPORTED: + do_sigill: + info.si_signo = SIGILL; + info.si_errno = 0; + info.si_code = TARGET_ILL_ILLOPN; + info._sifields._sigfault._addr = env->pc; + queue_signal(info.si_signo, &info); + break; + case EXCP_TRAP0: + { + ts->sim_syscalls = 0; + n = env->dregs[0]; + env->pc += 2; + env->dregs[0] = do_syscall(env, + n, + env->dregs[1], + env->dregs[2], + env->dregs[3], + env->dregs[4], + env->dregs[5], + env->dregs[6]); + } + break; + case EXCP_INTERRUPT: + /* just indicate that signals should be handled asap */ + break; + case EXCP_ACCESS: + { + info.si_signo = SIGSEGV; + info.si_errno = 0; + /* XXX: check env->error_code */ + info.si_code = TARGET_SEGV_MAPERR; + info._sifields._sigfault._addr = env->mmu.ar; + queue_signal(info.si_signo, &info); + } + 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: + fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", + trapnr); + cpu_dump_state(env, stderr, fprintf, 0); + abort(); + } + process_pending_signals(env); + } +} +#endif /* TARGET_M68K */ + void usage(void) { printf("qemu-" TARGET_ARCH " version " QEMU_VERSION ", Copyright (c) 2003-2005 Fabrice Bellard\n" @@ -1685,6 +1777,35 @@ int main(int argc, char **argv) env->gpr[i] = regs->gpr[i]; } } +#elif defined(TARGET_M68K) + { + m68k_def_t *def; + def = m68k_find_by_name("cfv4e"); + if (def == NULL) { + cpu_abort(cpu_single_env, + "Unable to find m68k CPU definition\n"); + } + cpu_m68k_register(cpu_single_env, def); + env->pc = regs->pc; + env->dregs[0] = regs->d0; + env->dregs[1] = regs->d1; + env->dregs[2] = regs->d2; + env->dregs[3] = regs->d3; + env->dregs[4] = regs->d4; + env->dregs[5] = regs->d5; + env->dregs[6] = regs->d6; + env->dregs[7] = regs->d7; + env->aregs[0] = regs->a0; + env->aregs[1] = regs->a1; + env->aregs[2] = regs->a2; + env->aregs[3] = regs->a3; + env->aregs[4] = regs->a4; + env->aregs[5] = regs->a5; + env->aregs[6] = regs->a6; + env->aregs[7] = regs->usp; + env->sr = regs->sr; + ts->sim_syscalls = 1; + } #elif defined(TARGET_MIPS) { int i; diff --git a/linux-user/mmap.c b/linux-user/mmap.c index 0c906257b1..cbaa7ce2c0 100644 --- a/linux-user/mmap.c +++ b/linux-user/mmap.c @@ -209,7 +209,7 @@ long target_mmap(target_ulong start, target_ulong len, int prot, last_start += HOST_PAGE_ALIGN(len); } #endif - if (qemu_host_page_size != qemu_real_host_page_size) { + if (0 && qemu_host_page_size != qemu_real_host_page_size) { /* NOTE: this code is only for debugging with '-p' option */ /* ??? Can also occur when TARGET_PAGE_SIZE > host page size. */ /* reserve a memory area */ diff --git a/linux-user/qemu.h b/linux-user/qemu.h index 218e846a0a..d35455de33 100644 --- a/linux-user/qemu.h +++ b/linux-user/qemu.h @@ -74,6 +74,9 @@ typedef struct TaskState { uint32_t v86flags; uint32_t v86mask; #endif +#ifdef TARGET_M68K + int sim_syscalls; +#endif int used; /* non zero if used */ struct image_info *info; uint8_t stack[0]; diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 60ed9a6078..e5e4139fd3 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -69,7 +69,8 @@ //#define DEBUG -#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) +#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) \ + || defined(TARGET_M68K) /* 16 bit uid wrappers emulation */ #define USE_UID16 #endif @@ -1645,6 +1646,12 @@ int do_fork(CPUState *env, unsigned int flags, unsigned long newsp) new_env->regwptr[0] = 0; /* XXXXX */ printf ("HELPME: %s:%d\n", __FILE__, __LINE__); +#elif defined(TARGET_M68K) + if (!newsp) + newsp = env->aregs[7]; + new_env->aregs[7] = newsp; + new_env->dregs[0] = 0; + /* ??? is this sufficient? */ #elif defined(TARGET_MIPS) printf ("HELPME: %s:%d\n", __FILE__, __LINE__); #elif defined(TARGET_PPC) @@ -2604,7 +2611,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, case TARGET_NR_readdir: goto unimplemented; case TARGET_NR_mmap: -#if defined(TARGET_I386) || defined(TARGET_ARM) +#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_M68K) { target_ulong *v; target_ulong v1, v2, v3, v4, v5, v6; diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 015f3ba248..e33c12bebe 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -48,7 +48,8 @@ #define TARGET_IOC_NRBITS 8 #define TARGET_IOC_TYPEBITS 8 -#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SH4) +#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SH4) \ + || defined(TARGET_M68K) #define TARGET_IOC_SIZEBITS 14 #define TARGET_IOC_DIRBITS 2 @@ -293,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) +#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_SPARC) #define TARGET_SA_NOCLDSTOP 8u @@ -1070,6 +1071,68 @@ struct target_stat64 { target_ulong __unused5; }; +#elif defined(TARGET_M68K) + +struct target_stat { + unsigned short st_dev; + unsigned short __pad1; + target_ulong st_ino; + unsigned short st_mode; + unsigned short st_nlink; + unsigned short st_uid; + unsigned short st_gid; + unsigned short st_rdev; + unsigned short __pad2; + target_ulong st_size; + target_ulong st_blksize; + target_ulong st_blocks; + target_ulong target_st_atime; + target_ulong __unused1; + target_ulong target_st_mtime; + target_ulong __unused2; + target_ulong target_st_ctime; + target_ulong __unused3; + target_ulong __unused4; + target_ulong __unused5; +}; + +/* This matches struct stat64 in glibc2.1, hence the absolutely + * insane amounts of padding around dev_t's. + */ +struct target_stat64 { + unsigned long long st_dev; + unsigned char __pad1[2]; + +#define TARGET_STAT64_HAS_BROKEN_ST_INO 1 + target_ulong __st_ino; + + unsigned int st_mode; + unsigned int st_nlink; + + target_ulong st_uid; + target_ulong st_gid; + + unsigned long long st_rdev; + unsigned char __pad3[2]; + + long long st_size; + target_ulong st_blksize; + + target_ulong __pad4; /* future possible st_blocks high bits */ + target_ulong st_blocks; /* Number 512-byte blocks allocated. */ + + 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; + + unsigned long long st_ino; +} __attribute__((packed)); + #elif defined(TARGET_MIPS) struct target_stat { |