After load elf64 tilegx binary for linux-user, the working flow reaches the first correct instruction postion "__start". Next, we shall load all instructions for qemu using.
This patch is based on Linux kernel tile architecture tilegx 64-bit implementation, and also based on tilegx architecture ABI reference. The related test: [root@localhost qemu]# ./configure --target-list=tile-linux-user && make [root@localhost qemu]# ./tile-linux-user/qemu-tile -d all ./test.tgx CPU Reset (CPU 0) CPU Reset (CPU 0) host mmap_min_addr=0x10000 Reserved 0xe0000 bytes of guest address space Relocating guest address space from 0x0000000000010000 to 0x10000 guest_base 0x0 start end size prot 0000000000010000-00000000000e0000 00000000000d0000 r-x 00000000000e0000-00000000000f0000 0000000000010000 rw- 0000004000000000-0000004000010000 0000000000010000 --- 0000004000010000-0000004000810000 0000000000800000 rw- start_brk 0x0000000000000000 end_code 0x00000000000d86f7 start_code 0x0000000000010000 start_data 0x00000000000e86f8 end_data 0x00000000000ea208 start_stack 0x000000400080f250 brk 0x00000000000ec2b0 entry 0x0000000000010f60 PROLOGUE: [size=40] 0x7fcc44c716f0: push %rbp 0x7fcc44c716f1: push %rbx 0x7fcc44c716f2: push %r12 0x7fcc44c716f4: push %r13 0x7fcc44c716f6: push %r14 0x7fcc44c716f8: push %r15 0x7fcc44c716fa: mov %rdi,%r14 0x7fcc44c716fd: add $0xfffffffffffffb78,%rsp 0x7fcc44c71704: jmpq *%rsi 0x7fcc44c71706: add $0x488,%rsp 0x7fcc44c7170d: pop %r15 0x7fcc44c7170f: pop %r14 0x7fcc44c71711: pop %r13 0x7fcc44c71713: pop %r12 0x7fcc44c71715: pop %rbx 0x7fcc44c71716: pop %rbp 0x7fcc44c71717: retq Load elf64 tilegx successfully reach code start position: [0000000000010f60] _start [root@localhost qemu]# echo $? 0 [root@localhost qemu]# Signed-off-by: Chen Gang <gang.chen.5...@gmail.com> --- configure | 7 + default-configs/tile-linux-user.mak | 1 + include/elf.h | 3 + include/hw/elf_ops.h | 7 + linux-user/elfload.c | 24 +++ linux-user/main.c | 81 +++++++++ linux-user/syscall_defs.h | 34 +++- linux-user/tile/syscall.h | 90 ++++++++++ linux-user/tile/syscall_nr.h | 327 ++++++++++++++++++++++++++++++++++++ linux-user/tile/target_cpu.h | 35 ++++ linux-user/tile/target_signal.h | 28 +++ linux-user/tile/target_structs.h | 48 ++++++ linux-user/tile/termbits.h | 285 +++++++++++++++++++++++++++++++ target-tile/Makefile.objs | 1 + target-tile/cpu-qom.h | 72 ++++++++ target-tile/cpu.c | 159 ++++++++++++++++++ target-tile/cpu.h | 84 +++++++++ target-tile/helper.h | 0 target-tile/translate.c | 54 ++++++ 19 files changed, 1337 insertions(+), 3 deletions(-) create mode 100644 default-configs/tile-linux-user.mak create mode 100644 linux-user/tile/syscall.h create mode 100644 linux-user/tile/syscall_nr.h create mode 100644 linux-user/tile/target_cpu.h create mode 100644 linux-user/tile/target_signal.h create mode 100644 linux-user/tile/target_structs.h create mode 100644 linux-user/tile/termbits.h create mode 100644 target-tile/Makefile.objs create mode 100644 target-tile/cpu-qom.h create mode 100644 target-tile/cpu.c create mode 100644 target-tile/cpu.h create mode 100644 target-tile/helper.h create mode 100644 target-tile/translate.c diff --git a/configure b/configure index f185dd0..d9e0dec 100755 --- a/configure +++ b/configure @@ -5089,6 +5089,9 @@ case "$target_name" in TARGET_BASE_ARCH=mips echo "TARGET_ABI_MIPSN64=y" >> $config_target_mak ;; + tile) + TARGET_ARCH=tile + ;; tricore) ;; moxie) @@ -5313,6 +5316,10 @@ for i in $ARCH $TARGET_BASE_ARCH ; do echo "CONFIG_SPARC_DIS=y" >> $config_target_mak echo "CONFIG_SPARC_DIS=y" >> config-all-disas.mak ;; + tile*) + echo "CONFIG_TILE_DIS=y" >> $config_target_mak + echo "CONFIG_TILE_DIS=y" >> config-all-disas.mak + ;; xtensa*) echo "CONFIG_XTENSA_DIS=y" >> $config_target_mak echo "CONFIG_XTENSA_DIS=y" >> config-all-disas.mak diff --git a/default-configs/tile-linux-user.mak b/default-configs/tile-linux-user.mak new file mode 100644 index 0000000..566fdc0 --- /dev/null +++ b/default-configs/tile-linux-user.mak @@ -0,0 +1 @@ +# Default configuration for microblaze-linux-user diff --git a/include/elf.h b/include/elf.h index a516584..a80608a 100644 --- a/include/elf.h +++ b/include/elf.h @@ -133,6 +133,9 @@ typedef int64_t Elf64_Sxword; #define EM_AARCH64 183 +#define EM_TILE 191 /* Tile */ +#define EM_TILE_OLD 0x2597 /* Tile compat */ + /* This is the info that is needed to parse the dynamic section of the file */ #define DT_NULL 0 #define DT_NEEDED 1 diff --git a/include/hw/elf_ops.h b/include/hw/elf_ops.h index a517753..5a3d02a 100644 --- a/include/hw/elf_ops.h +++ b/include/hw/elf_ops.h @@ -226,6 +226,13 @@ static int glue(load_elf, SZ)(const char *name, int fd, goto fail; } break; + case EM_TILE: + if (EM_TILE != ehdr.e_machine) + if (EM_TILE_OLD != ehdr.e_machine) { + ret = ELF_LOAD_WRONG_ARCH; + goto fail; + } + break; default: if (elf_machine != ehdr.e_machine) { ret = ELF_LOAD_WRONG_ARCH; diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 399c021..a9ec5a1 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -1189,6 +1189,29 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i #endif /* TARGET_S390X */ +#ifdef TARGET_TILE + +/* 42 bits real used address, a half for user mode */ +#define ELF_START_MMAP (0x00000020000000000ULL) + +#define elf_check_arch(x) ((x) == EM_TILE || (x) == EM_TILE_OLD) + +#define ELF_CLASS ELFCLASS64 +#define ELF_DATA ELFDATA2LSB +#define ELF_ARCH EM_TILE + +static inline void init_thread(struct target_pt_regs *regs, + struct image_info *infop) +{ + regs->lr = infop->entry; + regs->sp = infop->start_stack; + +} + +#define ELF_EXEC_PAGESIZE 65536 /* Tilegx page size is 64KB */ + +#endif /* TARGET_TILE */ + #ifndef ELF_PLATFORM #define ELF_PLATFORM (NULL) #endif @@ -2012,6 +2035,7 @@ static void load_elf_interp(const char *filename, struct image_info *info, } load_elf_image(filename, fd, info, NULL, bprm_buf); + return; exit_perror: diff --git a/linux-user/main.c b/linux-user/main.c index cfa7d07..1bfae5b 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -3418,6 +3418,20 @@ void cpu_loop(CPUS390XState *env) #endif /* TARGET_S390X */ +#ifdef TARGET_TILE +void cpu_loop(CPUTLState *env) +{ + CPUState *cs = CPU(tile_env_get_cpu(env)); + + while (1) { + cpu_exec_start(cs); + cpu_tile_exec(env); + cpu_exec_end(cs); + process_pending_signals(env); + } +} +#endif + THREAD CPUState *thread_cpu; void task_settid(TaskState *ts) @@ -4392,6 +4406,73 @@ int main(int argc, char **argv, char **envp) env->psw.mask = regs->psw.mask; env->psw.addr = regs->psw.addr; } +#elif defined(TARGET_TILE) + { + env->regs[0] = regs->r0; + env->regs[1] = regs->r1; + env->regs[2] = regs->r2; + env->regs[3] = regs->r3; + env->regs[4] = regs->r4; + env->regs[5] = regs->r5; + env->regs[6] = regs->r6; + env->regs[7] = regs->r7; + env->regs[8] = regs->r8; + env->regs[9] = regs->r9; + env->regs[10] = regs->r10; + env->regs[11] = regs->r11; + env->regs[12] = regs->r12; + env->regs[13] = regs->r13; + env->regs[14] = regs->r14; + env->regs[15] = regs->r15; + env->regs[16] = regs->r16; + env->regs[17] = regs->r17; + env->regs[18] = regs->r18; + env->regs[19] = regs->r19; + env->regs[20] = regs->r20; + env->regs[21] = regs->r21; + env->regs[22] = regs->r22; + env->regs[23] = regs->r23; + env->regs[24] = regs->r24; + env->regs[25] = regs->r25; + env->regs[26] = regs->r26; + env->regs[27] = regs->r27; + env->regs[28] = regs->r28; + env->regs[29] = regs->r29; + env->regs[30] = regs->r30; + env->regs[31] = regs->r31; + env->regs[32] = regs->r32; + env->regs[33] = regs->r33; + env->regs[34] = regs->r34; + env->regs[35] = regs->r35; + env->regs[36] = regs->r36; + env->regs[37] = regs->r37; + env->regs[38] = regs->r38; + env->regs[39] = regs->r39; + env->regs[40] = regs->r40; + env->regs[41] = regs->r41; + env->regs[42] = regs->r42; + env->regs[43] = regs->r43; + env->regs[44] = regs->r44; + env->regs[45] = regs->r45; + env->regs[46] = regs->r46; + env->regs[47] = regs->r47; + env->regs[48] = regs->r48; + env->regs[49] = regs->r49; + env->regs[50] = regs->r50; + env->regs[51] = regs->r51; + env->regs[52] = regs->r52; /* TILE_R_BP */ + env->regs[53] = regs->tp; /* TILE_R_TP */ + env->regs[54] = regs->sp; /* TILE_R_SP */ + env->regs[55] = regs->lr; /* TILE_R_PC */ + env->regs[56] = regs->sn; + env->regs[57] = regs->idn0; + env->regs[58] = regs->idn1; + env->regs[59] = regs->udn0; + env->regs[60] = regs->udn1; + env->regs[61] = regs->udn2; + env->regs[62] = regs->udn3; + env->regs[63] = regs->zero; + } #else #error unsupported target CPU #endif diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index ebb3be1..145495a 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -65,7 +65,7 @@ #if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SH4) \ || defined(TARGET_M68K) || defined(TARGET_CRIS) || defined(TARGET_UNICORE32) \ - || defined(TARGET_S390X) || defined(TARGET_OPENRISC) + || defined(TARGET_S390X) || defined(TARGET_OPENRISC) || defined(TARGET_TILE) #define TARGET_IOC_SIZEBITS 14 #define TARGET_IOC_DIRBITS 2 @@ -365,7 +365,7 @@ int do_sigaction(int sig, const struct target_sigaction *act, || defined(TARGET_PPC) || defined(TARGET_MIPS) || defined(TARGET_SH4) \ || defined(TARGET_M68K) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) \ || defined(TARGET_MICROBLAZE) || defined(TARGET_UNICORE32) \ - || defined(TARGET_S390X) || defined(TARGET_OPENRISC) + || defined(TARGET_S390X) || defined(TARGET_OPENRISC) || defined(TARGET_TILE) #if defined(TARGET_SPARC) #define TARGET_SA_NOCLDSTOP 8u @@ -1963,6 +1963,32 @@ struct target_stat64 { unsigned int __unused5; }; +#elif defined(TARGET_TILE) + +/* Copy from Linux kernel "uapi/asm-generic/stat.h" */ +struct target_stat { + abi_ulong st_dev; /* Device. */ + abi_ulong st_ino; /* File serial number. */ + unsigned int st_mode; /* File mode. */ + unsigned int st_nlink; /* Link count. */ + unsigned int st_uid; /* User ID of the file's owner. */ + unsigned int st_gid; /* Group ID of the file's group. */ + abi_ulong st_rdev; /* Device number, if device. */ + abi_ulong __pad1; + abi_long st_size; /* Size of file, in bytes. */ + int st_blksize; /* Optimal block size for I/O. */ + int __pad2; + abi_long st_blocks; /* Number 512-byte blocks allocated. */ + abi_long target_st_atime; /* Time of last access. */ + abi_ulong target_st_atime_nsec; + abi_long target_st_mtime; /* Time of last modification. */ + abi_ulong target_st_mtime_nsec; + abi_long target_st_ctime; /* Time of last status change. */ + abi_ulong target_st_ctime_nsec; + unsigned int __unused4; + unsigned int __unused5; +}; + #else #error unsupported CPU #endif @@ -2305,7 +2331,9 @@ struct target_flock { struct target_flock64 { short l_type; short l_whence; -#if defined(TARGET_PPC) || defined(TARGET_X86_64) || defined(TARGET_MIPS) || defined(TARGET_SPARC) || defined(TARGET_HPPA) || defined (TARGET_MICROBLAZE) +#if defined(TARGET_PPC) || defined(TARGET_X86_64) || defined(TARGET_MIPS) || \ + defined(TARGET_SPARC) || defined(TARGET_HPPA) \ + || defined(TARGET_MICROBLAZE) || defined(TARGET_TILE) int __pad; #endif unsigned long long l_start; diff --git a/linux-user/tile/syscall.h b/linux-user/tile/syscall.h new file mode 100644 index 0000000..2eda785 --- /dev/null +++ b/linux-user/tile/syscall.h @@ -0,0 +1,90 @@ +#ifndef TILE_SYSCALLS_H +#define TILE_SYSCALLS_H + +#define UNAME_MACHINE "tilegx" +#define UNAME_MINIMUM_RELEASE "3.19" + +/* We use tile to keep things similar to the kernel sources. */ +typedef uint64_t tile_reg_t; + +struct target_pt_regs { + + /* Can be as parameters */ + tile_reg_t r0; + tile_reg_t r1; + tile_reg_t r2; + tile_reg_t r3; + tile_reg_t r4; + tile_reg_t r5; + tile_reg_t r6; + tile_reg_t r7; + tile_reg_t r8; + tile_reg_t r9; + + /* Normal using, caller saved */ + tile_reg_t r10; + tile_reg_t r11; + tile_reg_t r12; + tile_reg_t r13; + tile_reg_t r14; + tile_reg_t r15; + tile_reg_t r16; + tile_reg_t r17; + tile_reg_t r18; + tile_reg_t r19; + tile_reg_t r20; + tile_reg_t r21; + tile_reg_t r22; + tile_reg_t r23; + tile_reg_t r24; + tile_reg_t r25; + tile_reg_t r26; + tile_reg_t r27; + tile_reg_t r28; + tile_reg_t r29; + + /* Normal using, callee saved */ + tile_reg_t r30; + tile_reg_t r31; + tile_reg_t r32; + tile_reg_t r33; + tile_reg_t r34; + tile_reg_t r35; + tile_reg_t r36; + tile_reg_t r37; + tile_reg_t r38; + tile_reg_t r39; + tile_reg_t r40; + tile_reg_t r41; + tile_reg_t r42; + tile_reg_t r43; + tile_reg_t r44; + tile_reg_t r45; + tile_reg_t r46; + tile_reg_t r47; + tile_reg_t r48; + tile_reg_t r49; + tile_reg_t r50; + tile_reg_t r51; + + /* Control using */ + tile_reg_t r52; /* optional frame pointer */ + tile_reg_t tp; /* thread-local data */ + tile_reg_t sp; /* stack pointer */ + tile_reg_t lr; /* pc pointer */ + + /* Minor for qemu */ + tile_reg_t sn; /* always zero */ + tile_reg_t idn0; + tile_reg_t idn1; + tile_reg_t udn0; + tile_reg_t udn1; + tile_reg_t udn2; + tile_reg_t udn3; + tile_reg_t zero; /* always zero */ +}; + +#define TARGET_MLOCKALL_MCL_CURRENT 1 +#define TARGET_MLOCKALL_MCL_FUTURE 2 + +#endif diff --git a/linux-user/tile/syscall_nr.h b/linux-user/tile/syscall_nr.h new file mode 100644 index 0000000..c2c602f --- /dev/null +++ b/linux-user/tile/syscall_nr.h @@ -0,0 +1,327 @@ +#ifndef TILE_SYSCALL_NR +#define TILE_SYSCALL_NR + +/* + * Copy from linux kernel asm-generic/unistd.h, which tile uses. + * + * At present, do not support 32-bit (-m32) tilegx executable binary + */ +#define TARGET_NR_io_setup 0 +#define TARGET_NR_io_destroy 1 +#define TARGET_NR_io_submit 2 +#define TARGET_NR_io_cancel 3 +#define TARGET_NR_io_getevents 4 +#define TARGET_NR_setxattr 5 +#define TARGET_NR_lsetxattr 6 +#define TARGET_NR_fsetxattr 7 +#define TARGET_NR_getxattr 8 +#define TARGET_NR_lgetxattr 9 +#define TARGET_NR_fgetxattr 10 +#define TARGET_NR_listxattr 11 +#define TARGET_NR_llistxattr 12 +#define TARGET_NR_flistxattr 13 +#define TARGET_NR_removexattr 14 +#define TARGET_NR_lremovexattr 15 +#define TARGET_NR_fremovexattr 16 +#define TARGET_NR_getcwd 17 +#define TARGET_NR_lookup_dcookie 18 +#define TARGET_NR_eventfd2 19 +#define TARGET_NR_epoll_create1 20 +#define TARGET_NR_epoll_ctl 21 +#define TARGET_NR_epoll_pwait 22 +#define TARGET_NR_dup 23 +#define TARGET_NR_dup3 24 +#define TARGET_NR_fcntl 25 +#define TARGET_NR_inotify_init1 26 +#define TARGET_NR_inotify_add_watch 27 +#define TARGET_NR_inotify_rm_watch 28 +#define TARGET_NR_ioctl 29 +#define TARGET_NR_ioprio_set 30 +#define TARGET_NR_ioprio_get 31 +#define TARGET_NR_flock 32 +#define TARGET_NR_mknodat 33 +#define TARGET_NR_mkdirat 34 +#define TARGET_NR_unlinkat 35 +#define TARGET_NR_symlinkat 36 +#define TARGET_NR_linkat 37 +#define TARGET_NR_renameat 38 +#define TARGET_NR_umount2 39 +#define TARGET_NR_mount 40 +#define TARGET_NR_pivot_root 41 +#define TARGET_NR_nfsservctl 42 +#define TARGET_NR_statfs 43 +#define TARGET_NR_fstatfs 44 +#define TARGET_NR_truncate 45 +#define TARGET_NR_ftruncate 46 +#define TARGET_NR_fallocate 47 +#define TARGET_NR_faccessat 48 +#define TARGET_NR_chdir 49 +#define TARGET_NR_fchdir 50 +#define TARGET_NR_chroot 51 +#define TARGET_NR_fchmod 52 +#define TARGET_NR_fchmodat 53 +#define TARGET_NR_fchownat 54 +#define TARGET_NR_fchown 55 +#define TARGET_NR_openat 56 +#define TARGET_NR_close 57 +#define TARGET_NR_vhangup 58 +#define TARGET_NR_pipe2 59 +#define TARGET_NR_quotactl 60 +#define TARGET_NR_getdents64 61 +#define TARGET_NR_lseek 62 +#define TARGET_NR_read 63 +#define TARGET_NR_write 64 +#define TARGET_NR_readv 65 +#define TARGET_NR_writev 66 +#define TARGET_NR_pread64 67 +#define TARGET_NR_pwrite64 68 +#define TARGET_NR_preadv 69 +#define TARGET_NR_pwritev 70 +#define TARGET_NR_sendfile 71 +#define TARGET_NR_pselect6 72 +#define TARGET_NR_ppoll 73 +#define TARGET_NR_signalfd4 74 +#define TARGET_NR_vmsplice 75 +#define TARGET_NR_splice 76 +#define TARGET_NR_tee 77 +#define TARGET_NR_readlinkat 78 +#define TARGET_NR_fstatat 79 +#define TARGET_NR_fstat 80 +#define TARGET_NR_sync 81 +#define TARGET_NR_fsync 82 +#define TARGET_NR_fdatasync 83 +#define TARGET_NR_sync_file_range 84 /* For tilegx, no range2 */ +#define TARGET_NR_timerfd_create 85 +#define TARGET_NR_timerfd_settime 86 +#define TARGET_NR_timerfd_gettime 87 +#define TARGET_NR_utimensat 88 +#define TARGET_NR_acct 89 +#define TARGET_NR_capget 90 +#define TARGET_NR_capset 91 +#define TARGET_NR_personality 92 +#define TARGET_NR_exit 93 +#define TARGET_NR_exit_group 94 +#define TARGET_NR_waitid 95 +#define TARGET_NR_set_tid_address 96 +#define TARGET_NR_unshare 97 +#define TARGET_NR_futex 98 +#define TARGET_NR_set_robust_list 99 +#define TARGET_NR_get_robust_list 100 +#define TARGET_NR_nanosleep 101 +#define TARGET_NR_getitimer 102 +#define TARGET_NR_setitimer 103 +#define TARGET_NR_kexec_load 104 +#define TARGET_NR_init_module 105 +#define TARGET_NR_delete_module 106 +#define TARGET_NR_timer_create 107 +#define TARGET_NR_timer_gettime 108 +#define TARGET_NR_timer_getoverrun 109 +#define TARGET_NR_timer_settime 110 +#define TARGET_NR_timer_delete 111 +#define TARGET_NR_clock_settime 112 +#define TARGET_NR_clock_gettime 113 +#define TARGET_NR_clock_getres 114 +#define TARGET_NR_clock_nanosleep 115 +#define TARGET_NR_syslog 116 +#define TARGET_NR_ptrace 117 +#define TARGET_NR_sched_setparam 118 +#define TARGET_NR_sched_setscheduler 119 +#define TARGET_NR_sched_getscheduler 120 +#define TARGET_NR_sched_getparam 121 +#define TARGET_NR_sched_setaffinity 122 +#define TARGET_NR_sched_getaffinity 123 +#define TARGET_NR_sched_yield 124 +#define TARGET_NR_sched_get_priority_max 125 +#define TARGET_NR_sched_get_priority_min 126 +#define TARGET_NR_sched_rr_get_interval 127 +#define TARGET_NR_restart_syscall 128 +#define TARGET_NR_kill 129 +#define TARGET_NR_tkill 130 +#define TARGET_NR_tgkill 131 +#define TARGET_NR_sigaltstack 132 +#define TARGET_NR_rt_sigsuspend 133 +#define TARGET_NR_rt_sigaction 134 +#define TARGET_NR_rt_sigprocmask 135 +#define TARGET_NR_rt_sigpending 136 +#define TARGET_NR_rt_sigtimedwait 137 +#define TARGET_NR_rt_sigqueueinfo 138 +#define TARGET_NR_rt_sigreturn 139 +#define TARGET_NR_setpriority 140 +#define TARGET_NR_getpriority 141 +#define TARGET_NR_reboot 142 +#define TARGET_NR_setregid 143 +#define TARGET_NR_setgid 144 +#define TARGET_NR_setreuid 145 +#define TARGET_NR_setuid 146 +#define TARGET_NR_setresuid 147 +#define TARGET_NR_getresuid 148 +#define TARGET_NR_setresgid 149 +#define TARGET_NR_getresgid 150 +#define TARGET_NR_setfsuid 151 +#define TARGET_NR_setfsgid 152 +#define TARGET_NR_times 153 +#define TARGET_NR_setpgid 154 +#define TARGET_NR_getpgid 155 +#define TARGET_NR_getsid 156 +#define TARGET_NR_setsid 157 +#define TARGET_NR_getgroups 158 +#define TARGET_NR_setgroups 159 +#define TARGET_NR_uname 160 +#define TARGET_NR_sethostname 161 +#define TARGET_NR_setdomainname 162 +#define TARGET_NR_getrlimit 163 +#define TARGET_NR_setrlimit 164 +#define TARGET_NR_getrusage 165 +#define TARGET_NR_umask 166 +#define TARGET_NR_prctl 167 +#define TARGET_NR_getcpu 168 +#define TARGET_NR_gettimeofday 169 +#define TARGET_NR_settimeofday 170 +#define TARGET_NR_adjtimex 171 +#define TARGET_NR_getpid 172 +#define TARGET_NR_getppid 173 +#define TARGET_NR_getuid 174 +#define TARGET_NR_geteuid 175 +#define TARGET_NR_getgid 176 +#define TARGET_NR_getegid 177 +#define TARGET_NR_gettid 178 +#define TARGET_NR_sysinfo 179 +#define TARGET_NR_mq_open 180 +#define TARGET_NR_mq_unlink 181 +#define TARGET_NR_mq_timedsend 182 +#define TARGET_NR_mq_timedreceive 183 +#define TARGET_NR_mq_notify 184 +#define TARGET_NR_mq_getsetattr 185 +#define TARGET_NR_msgget 186 +#define TARGET_NR_msgctl 187 +#define TARGET_NR_msgrcv 188 +#define TARGET_NR_msgsnd 189 +#define TARGET_NR_semget 190 +#define TARGET_NR_semctl 191 +#define TARGET_NR_semtimedop 192 +#define TARGET_NR_semop 193 +#define TARGET_NR_shmget 194 +#define TARGET_NR_shmctl 195 +#define TARGET_NR_shmat 196 +#define TARGET_NR_shmdt 197 +#define TARGET_NR_socket 198 +#define TARGET_NR_socketpair 199 +#define TARGET_NR_bind 200 +#define TARGET_NR_listen 201 +#define TARGET_NR_accept 202 +#define TARGET_NR_connect 203 +#define TARGET_NR_getsockname 204 +#define TARGET_NR_getpeername 205 +#define TARGET_NR_sendto 206 +#define TARGET_NR_recvfrom 207 +#define TARGET_NR_setsockopt 208 +#define TARGET_NR_getsockopt 209 +#define TARGET_NR_shutdown 210 +#define TARGET_NR_sendmsg 211 +#define TARGET_NR_recvmsg 212 +#define TARGET_NR_readahead 213 +#define TARGET_NR_brk 214 +#define TARGET_NR_munmap 215 +#define TARGET_NR_mremap 216 +#define TARGET_NR_add_key 217 +#define TARGET_NR_request_key 218 +#define TARGET_NR_keyctl 219 +#define TARGET_NR_clone 220 +#define TARGET_NR_execve 221 +#define TARGET_NR_mmap 222 +#define TARGET_NR_fadvise64 223 +#define TARGET_NR_swapon 224 +#define TARGET_NR_swapoff 225 +#define TARGET_NR_mprotect 226 +#define TARGET_NR_msync 227 +#define TARGET_NR_mlock 228 +#define TARGET_NR_munlock 229 +#define TARGET_NR_mlockall 230 +#define TARGET_NR_munlockall 231 +#define TARGET_NR_mincore 232 +#define TARGET_NR_madvise 233 +#define TARGET_NR_remap_file_pages 234 +#define TARGET_NR_mbind 235 +#define TARGET_NR_get_mempolicy 236 +#define TARGET_NR_set_mempolicy 237 +#define TARGET_NR_migrate_pages 238 +#define TARGET_NR_move_pages 239 +#define TARGET_NR_rt_tgsigqueueinfo 240 +#define TARGET_NR_perf_event_open 241 +#define TARGET_NR_accept4 242 +#define TARGET_NR_recvmmsg 243 + +#define TARGET_NR_arch_specific_syscall 244 +#define TARGET_NR_cacheflush 245 /* tile specific syscall */ + +#define TARGET_NR_wait4 260 +#define TARGET_NR_prlimit64 261 +#define TARGET_NR_fanotify_init 262 +#define TARGET_NR_fanotify_mark 263 +#define TARGET_NR_name_to_handle_at 264 +#define TARGET_NR_open_by_handle_at 265 +#define TARGET_NR_clock_adjtime 266 +#define TARGET_NR_syncfs 267 +#define TARGET_NR_setns 268 +#define TARGET_NR_sendmmsg 269 +#define TARGET_NR_process_vm_readv 270 +#define TARGET_NR_process_vm_writev 271 +#define TARGET_NR_kcmp 272 +#define TARGET_NR_finit_module 273 +#define TARGET_NR_sched_setattr 274 +#define TARGET_NR_sched_getattr 275 +#define TARGET_NR_renameat2 276 +#define TARGET_NR_seccomp 277 +#define TARGET_NR_getrandom 278 +#define TARGET_NR_memfd_create 279 +#define TARGET_NR_bpf 280 +#define TARGET_NR_execveat 281 + +/* current tilegx Linux kernel do not want to support the macros below */ + +#define TARGET_NR_open 1024 +#define TARGET_NR_link 1025 +#define TARGET_NR_unlink 1026 +#define TARGET_NR_mknod 1027 +#define TARGET_NR_chmod 1028 +#define TARGET_NR_chown 1029 +#define TARGET_NR_mkdir 1030 +#define TARGET_NR_rmdir 1031 +#define TARGET_NR_lchown 1032 +#define TARGET_NR_access 1033 +#define TARGET_NR_rename 1034 +#define TARGET_NR_readlink 1035 +#define TARGET_NR_symlink 1036 +#define TARGET_NR_utimes 1037 +#define TARGET_NR_stat 1038 +#define TARGET_NR_lstat 1039 +#define TARGET_NR_pipe 1040 +#define TARGET_NR_dup2 1041 +#define TARGET_NR_epoll_create 1042 +#define TARGET_NR_inotify_init 1043 +#define TARGET_NR_eventfd 1044 +#define TARGET_NR_signalfd 1045 + +#define TARGET_NR_alarm 1059 +#define TARGET_NR_getpgrp 1060 +#define TARGET_NR_pause 1061 +#define TARGET_NR_time 1062 +#define TARGET_NR_utime 1063 +#define TARGET_NR_creat 1064 +#define TARGET_NR_getdents 1065 +#define TARGET_NR_futimesat 1066 +#define TARGET_NR_select 1067 +#define TARGET_NR_poll 1068 +#define TARGET_NR_epoll_wait 1069 +#define TARGET_NR_ustat 1070 +#define TARGET_NR_vfork 1071 +#define TARGET_NR_oldwait4 1072 +#define TARGET_NR_recv 1073 +#define TARGET_NR_send 1074 +#define TARGET_NR_bdflush 1075 +#define TARGET_NR_umount 1076 +#define TARGET_NR_uselib 1077 +#define TARGET_NR__sysctl 1078 +#define TARGET_NR_fork 1079 + +#endif diff --git a/linux-user/tile/target_cpu.h b/linux-user/tile/target_cpu.h new file mode 100644 index 0000000..8e2f39c --- /dev/null +++ b/linux-user/tile/target_cpu.h @@ -0,0 +1,35 @@ +/* + * Tile specific CPU ABI and functions for linux-user + * + * Copyright (c) 2015 Chen Gang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + */ +#ifndef TARGET_CPU_H +#define TARGET_CPU_H + +static inline void cpu_clone_regs(CPUTLState *env, target_ulong newsp) +{ + if (newsp) { + env->regs[TILE_R_SP] = newsp; + } + env->regs[TILE_R_RE] = 0; +} + +static inline void cpu_set_tls(CPUTLState *env, target_ulong newtls) +{ + env->regs[TILE_R_TP] = newtls; +} + +#endif diff --git a/linux-user/tile/target_signal.h b/linux-user/tile/target_signal.h new file mode 100644 index 0000000..327d8f4 --- /dev/null +++ b/linux-user/tile/target_signal.h @@ -0,0 +1,28 @@ +#ifndef TARGET_SIGNAL_H +#define TARGET_SIGNAL_H + +#include "cpu.h" + +/* this struct defines a stack used during syscall handling */ + +typedef struct target_sigaltstack { + abi_ulong ss_sp; + abi_ulong ss_size; + abi_long ss_flags; +} target_stack_t; + +/* + * sigaltstack controls + */ +#define TARGET_SS_ONSTACK 1 +#define TARGET_SS_DISABLE 2 + +#define TARGET_MINSIGSTKSZ 2048 +#define TARGET_SIGSTKSZ 8192 + +static inline abi_ulong get_sp_from_cpustate(CPUTLState *state) +{ + return state->regs[54]; +} + +#endif /* TARGET_SIGNAL_H */ diff --git a/linux-user/tile/target_structs.h b/linux-user/tile/target_structs.h new file mode 100644 index 0000000..6fed776 --- /dev/null +++ b/linux-user/tile/target_structs.h @@ -0,0 +1,48 @@ +/* + * Tile specific structures for linux-user + * + * Copyright (c) 2015 Chen Gang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + */ +#ifndef TARGET_STRUCTS_H +#define TARGET_STRUCTS_H + +struct target_ipc_perm { + abi_int __key; /* Key. */ + abi_uint uid; /* Owner's user ID. */ + abi_uint gid; /* Owner's group ID. */ + abi_uint cuid; /* Creator's user ID. */ + abi_uint cgid; /* Creator's group ID. */ + abi_uint mode; /* Read/write permission. */ + abi_ushort __seq; /* Sequence number. */ + abi_ushort __pad2; + abi_ulong __unused1; + abi_ulong __unused2; +}; + +struct target_shmid_ds { + struct target_ipc_perm shm_perm; /* operation permission struct */ + abi_long shm_segsz; /* size of segment in bytes */ + abi_ulong shm_atime; /* time of last shmat() */ + abi_ulong shm_dtime; /* time of last shmdt() */ + abi_ulong shm_ctime; /* time of last change by shmctl() */ + abi_int shm_cpid; /* pid of creator */ + abi_int shm_lpid; /* pid of last shmop */ + abi_ulong shm_nattch; /* number of current attaches */ + abi_ulong __unused4; + abi_ulong __unused5; +}; + +#endif diff --git a/linux-user/tile/termbits.h b/linux-user/tile/termbits.h new file mode 100644 index 0000000..854d2ba --- /dev/null +++ b/linux-user/tile/termbits.h @@ -0,0 +1,285 @@ +#ifndef TILE_TERMBITS_H +#define TILE_TERMBITS_H + +/* From asm-generic/termbits.h, which is used by tile */ + +#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 */ +}; + +struct target_termios2 { + 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 */ + unsigned int c_ispeed; /* input speed */ + unsigned int c_ospeed; /* output speed */ +}; + +struct target_ktermios { + 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 */ + unsigned int c_ispeed; /* input speed */ + unsigned int c_ospeed; /* output speed */ +}; + +/* c_cc characters */ +#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 + +/* 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 +#define TARGET_IUTF8 0040000 + +/* 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 TARGET_B19200 +#define TARGET_EXTB TARGET_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_BOTHER 0010000 +#define TARGET_B57600 0010001 +#define TARGET_B115200 0010002 +#define TARGET_B230400 0010003 +#define TARGET_B460800 0010004 +#define TARGET_B500000 0010005 +#define TARGET_B576000 0010006 +#define TARGET_B921600 0010007 +#define TARGET_B1000000 0010010 +#define TARGET_B1152000 0010011 +#define TARGET_B1500000 0010012 +#define TARGET_B2000000 0010013 +#define TARGET_B2500000 0010014 +#define TARGET_B3000000 0010015 +#define TARGET_B3500000 0010016 +#define TARGET_B4000000 0010017 +#define TARGET_CIBAUD 002003600000 /* input baud rate */ +#define TARGET_CMSPAR 010000000000 /* mark or space (stick) parity */ +#define TARGET_CRTSCTS 020000000000 /* flow control */ + +#define TARGET_IBSHIFT 16 /* Shift from CBAUD to CIBAUD */ + +/* 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 +#define TARGET_EXTPROC 0200000 + +/* tcflow() and TCXONC use these */ +#define TARGET_TCOOFF 0 +#define TARGET_TCOON 1 +#define TARGET_TCIOFF 2 +#define TARGET_TCION 3 + +/* tcflush() and TCFLSH use these */ +#define TARGET_TCIFLUSH 0 +#define TARGET_TCOFLUSH 1 +#define TARGET_TCIOFLUSH 2 + +/* tcsetattr uses these */ +#define TARGET_TCSANOW 0 +#define TARGET_TCSADRAIN 1 +#define TARGET_TCSAFLUSH 2 + +/* From asm-generic/ioctls.h, which is used by tile */ + +#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 +#define TARGET_TIOCSBRK 0x5427 +#define TARGET_TIOCCBRK 0x5428 +#define TARGET_TIOCGSID 0x5429 +#define TARGET_TCGETS2 _IOR('T', 0x2A, struct termios2) +#define TARGET_TCSETS2 _IOW('T', 0x2B, struct termios2) +#define TARGET_TCSETSW2 _IOW('T', 0x2C, struct termios2) +#define TARGET_TCSETSF2 _IOW('T', 0x2D, struct termios2) +#define TARGET_TIOCGRS485 0x542E +#define TARGET_TIOCSRS485 0x542F +#define TARGET_TIOCGPTN _IOR('T', 0x30, unsigned int) +#define TARGET_TIOCSPTLCK _IOW('T', 0x31, int) +#define TARGET_TIOCGDEV _IOR('T', 0x32, unsigned int) +#define TARGET_TCGETX 0x5432 +#define TARGET_TCSETX 0x5433 +#define TARGET_TCSETXF 0x5434 +#define TARGET_TCSETXW 0x5435 +#define TARGET_TIOCSIG _IOW('T', 0x36, int) +#define TARGET_TIOCVHANGUP 0x5437 +#define TARGET_TIOCGPKT _IOR('T', 0x38, int) +#define TARGET_TIOCGPTLCK _IOR('T', 0x39, int) +#define TARGET_TIOCGEXCL _IOR('T', 0x40, int) + +#define TARGET_FIONCLEX 0x5450 +#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 +#define TARGET_TIOCSERGETLSR 0x5459 +#define TARGET_TIOCSERGETMULTI 0x545A +#define TARGET_TIOCSERSETMULTI 0x545B + +#define TARGET_TIOCMIWAIT 0x545C +#define TARGET_TIOCGICOUNT 0x545D +#define TARGET_FIOQSIZE 0x5460 + +#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_TIOCPKT_IOCTL 64 + +#define TARGET_TIOCSER_TEMT 0x01 + +#endif diff --git a/target-tile/Makefile.objs b/target-tile/Makefile.objs new file mode 100644 index 0000000..dcf2fe4 --- /dev/null +++ b/target-tile/Makefile.objs @@ -0,0 +1 @@ +obj-y += cpu.o translate.o diff --git a/target-tile/cpu-qom.h b/target-tile/cpu-qom.h new file mode 100644 index 0000000..6026b81 --- /dev/null +++ b/target-tile/cpu-qom.h @@ -0,0 +1,72 @@ +/* + * QEMU Tile CPU + * + * Copyright (c) 2015 Chen Gang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see + * <http://www.gnu.org/licenses/lgpl-2.1.html> + */ +#ifndef QEMU_TILE_CPU_QOM_H +#define QEMU_TILE_CPU_QOM_H + +#include "qom/cpu.h" + +#define TYPE_TILE_CPU "tile-cpu" + +#define TILE_CPU_CLASS(klass) \ + OBJECT_CLASS_CHECK(TileCPUClass, (klass), TYPE_TILE_CPU) +#define TILE_CPU(obj) \ + OBJECT_CHECK(TileCPU, (obj), TYPE_TILE_CPU) +#define TILE_CPU_GET_CLASS(obj) \ + OBJECT_GET_CLASS(TileCPUClass, (obj), TYPE_TILE_CPU) + +/** + * TileCPUClass: + * @parent_realize: The parent class' realize handler. + * @parent_reset: The parent class' reset handler. + * + * A Tile CPU model. + */ +typedef struct TileCPUClass { + /*< private >*/ + CPUClass parent_class; + /*< public >*/ + + DeviceRealize parent_realize; + void (*parent_reset)(CPUState *cpu); +} TileCPUClass; + +/** + * TileCPU: + * @env: #CPUTLState + * + * A Tile CPU. + */ +typedef struct TileCPU { + /*< private >*/ + CPUState parent_obj; + uint64_t base_vectors; + /*< public >*/ + + CPUTLState env; +} TileCPU; + +static inline TileCPU *tile_env_get_cpu(CPUTLState *env) +{ + return container_of(env, TileCPU, env); +} + +#define ENV_GET_CPU(e) CPU(tile_env_get_cpu(e)) + +#endif diff --git a/target-tile/cpu.c b/target-tile/cpu.c new file mode 100644 index 0000000..365ec7a --- /dev/null +++ b/target-tile/cpu.c @@ -0,0 +1,159 @@ +/* + * QEMU Tile CPU + * + * Copyright (c) 2015 Chen Gang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see + * <http://www.gnu.org/licenses/lgpl-2.1.html> + */ + +#include "cpu.h" +#include "qemu-common.h" +#include "hw/qdev-properties.h" +#include "migration/vmstate.h" + +TileCPU *cpu_tile_init(const char *cpu_model) +{ + TileCPU *cpu; + + cpu = TILE_CPU(object_new(TYPE_TILE_CPU)); + + object_property_set_bool(OBJECT(cpu), true, "realized", NULL); + + return cpu; +} + +static void tile_cpu_set_pc(CPUState *cs, vaddr value) +{ +} + +static bool tile_cpu_has_work(CPUState *cs) +{ + return true; +} + +static void tile_cpu_reset(CPUState *s) +{ + TileCPU *cpu = TILE_CPU(s); + TileCPUClass *mcc = TILE_CPU_GET_CLASS(cpu); + CPUTLState *env = &cpu->env; + + mcc->parent_reset(s); + + memset(env, 0, sizeof(CPUTLState)); + tlb_flush(s, 1); +} + +static void tile_cpu_realizefn(DeviceState *dev, Error **errp) +{ + CPUState *cs = CPU(dev); + TileCPUClass *mcc = TILE_CPU_GET_CLASS(dev); + + cpu_reset(cs); + qemu_init_vcpu(cs); + + mcc->parent_realize(dev, errp); +} + +static void tile_tcg_init(void) +{ +} + +static void tile_cpu_initfn(Object *obj) +{ + CPUState *cs = CPU(obj); + TileCPU *cpu = TILE_CPU(obj); + CPUTLState *env = &cpu->env; + static bool tcg_initialized; + + cs->env_ptr = env; + cpu_exec_init(env); + + if (tcg_enabled() && !tcg_initialized) { + tcg_initialized = true; + tile_tcg_init(); + } +} + +static const VMStateDescription vmstate_tile_cpu = { + .name = "cpu", + .unmigratable = 1, +}; + +static Property tile_properties[] = { + DEFINE_PROP_UINT64("tile.base-vectors", TileCPU, base_vectors, 0), + DEFINE_PROP_END_OF_LIST(), +}; + +static void tile_cpu_do_interrupt(CPUState *cs) +{ + cs->exception_index = -1; +} + +static int tile_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw, + int mmu_idx) +{ + cpu_dump_state(cs, stderr, fprintf, 0); + return 1; +} + +static bool tile_cpu_exec_interrupt(CPUState *cs, int interrupt_request) +{ + if (interrupt_request & CPU_INTERRUPT_HARD) { + tile_cpu_do_interrupt(cs); + return true; + } + return false; +} + +static void tile_cpu_class_init(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + CPUClass *cc = CPU_CLASS(oc); + TileCPUClass *mcc = TILE_CPU_CLASS(oc); + + mcc->parent_realize = dc->realize; + dc->realize = tile_cpu_realizefn; + + mcc->parent_reset = cc->reset; + cc->reset = tile_cpu_reset; + + cc->has_work = tile_cpu_has_work; + cc->do_interrupt = tile_cpu_do_interrupt; + cc->cpu_exec_interrupt = tile_cpu_exec_interrupt; + cc->dump_state = NULL; + cc->set_pc = tile_cpu_set_pc; + cc->gdb_read_register = NULL; + cc->gdb_write_register = NULL; + cc->handle_mmu_fault = tile_cpu_handle_mmu_fault; + dc->vmsd = &vmstate_tile_cpu; + dc->props = tile_properties; + cc->gdb_num_core_regs = 0; +} + +static const TypeInfo tile_cpu_type_info = { + .name = TYPE_TILE_CPU, + .parent = TYPE_CPU, + .instance_size = sizeof(TileCPU), + .instance_init = tile_cpu_initfn, + .class_size = sizeof(TileCPUClass), + .class_init = tile_cpu_class_init, +}; + +static void tile_cpu_register_types(void) +{ + type_register_static(&tile_cpu_type_info); +} + +type_init(tile_cpu_register_types) diff --git a/target-tile/cpu.h b/target-tile/cpu.h new file mode 100644 index 0000000..e9fb746 --- /dev/null +++ b/target-tile/cpu.h @@ -0,0 +1,84 @@ +/* + * Tile virtual CPU header + * + * Copyright (c) 2015 Chen Gang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + */ +#ifndef CPU_TILE_H +#define CPU_TILE_H + +#include "config.h" +#include "qemu-common.h" + +#define TARGET_LONG_BITS 64 + +#define CPUArchState struct CPUTLState + +#include "exec/cpu-defs.h" +#include "fpu/softfloat.h" + +/* Tilegx register alias */ +#define TILE_R_RE 0 /* 0 register, for function/syscall return value */ +#define TILE_R_NR 10 /* 10 register, for syscall number */ +#define TILE_R_BP 52 /* 52 register, optional frame pointer */ +#define TILE_R_TP 53 /* TP register, thread local storage data */ +#define TILE_R_SP 54 /* SP register, stack pointer */ +#define TILE_R_PC 55 /* LR register, pc pointer */ + +typedef struct CPUTLState { + uint64_t regs[64]; + CPU_COMMON +} CPUTLState; + +#include "cpu-qom.h" + +/* Tilegx memory attributes */ +#define TARGET_PAGE_BITS 16 /* Tilegx uses 64KB page size */ +#define MMAP_SHIFT TARGET_PAGE_BITS +#define TARGET_PHYS_ADDR_SPACE_BITS 42 /* Tilegx is 42 bit physical address */ +#define TARGET_VIRT_ADDR_SPACE_BITS 64 /* Tilegx has 64 bit virtual address */ +#define MMU_USER_IDX 0 /* independent from both qemu and architecture */ + +#include "exec/cpu-all.h" + +int cpu_tile_exec(CPUTLState *s); +int cpu_tile_signal_handler(int host_signum, void *pinfo, void *puc); + +#define cpu_exec cpu_tile_exec +#define cpu_gen_code cpu_tile_gen_code +#define cpu_signal_handler cpu_tile_signal_handler + +TileCPU *cpu_tile_init(const char *cpu_model); + +static inline CPUTLState *cpu_init(const char *cpu_model) +{ + TileCPU *cpu = cpu_tile_init(cpu_model); + if (cpu == NULL) { + return NULL; + } + return &cpu->env; +} + +static inline void cpu_get_tb_cpu_state(CPUTLState *env, target_ulong *pc, + target_ulong *cs_base, int *flags) +{ + *pc = env->regs[TILE_R_PC]; + *cs_base = 0; + *flags = 0; +} + +#include "exec/exec-all.h" + +#endif diff --git a/target-tile/helper.h b/target-tile/helper.h new file mode 100644 index 0000000..e69de29 diff --git a/target-tile/translate.c b/target-tile/translate.c new file mode 100644 index 0000000..d9fbf71 --- /dev/null +++ b/target-tile/translate.c @@ -0,0 +1,54 @@ +/* + * QEMU Tile CPU + * + * Copyright (c) 2015 Chen Gang + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see + * <http://www.gnu.org/licenses/lgpl-2.1.html> + */ + +#include "cpu.h" +#include "disas/disas.h" +#include "tcg-op.h" +#include "exec/helper-proto.h" +#include "exec/cpu_ldst.h" +#include "exec/helper-gen.h" + +static inline void gen_intermediate_code_internal(TileCPU *cpu, + TranslationBlock *tb, + bool search_pc) +{ + /* + * FIXME: after load elf64 tilegx binary successfully, it will quit, at + * present, and will implement the related features next. + */ + fprintf(stderr, "\nLoad elf64 tilegx successfully\n"); + fprintf(stderr, "reach code start position: [" TARGET_FMT_lx "] %s\n\n", + tb->pc, lookup_symbol(tb->pc)); + exit(0); +} + +void gen_intermediate_code(CPUTLState *env, struct TranslationBlock *tb) +{ + gen_intermediate_code_internal(tile_env_get_cpu(env), tb, false); +} + +void gen_intermediate_code_pc(CPUTLState *env, struct TranslationBlock *tb) +{ + gen_intermediate_code_internal(tile_env_get_cpu(env), tb, true); +} + +void restore_state_to_opc(CPUTLState *env, TranslationBlock *tb, int pc_pos) +{ +} -- 1.9.3