diff mbox

tile: Can load elf64 tilegx binary successfully for linux-user.

Message ID 54DBED38.4060005@sunrus.com.cn
State New
Headers show

Commit Message

Chen Gang Feb. 12, 2015, midnight UTC
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.5i5j@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

Comments

Chen Gang Feb. 12, 2015, 12:12 a.m. UTC | #1
Oh, sorry, I forgot to Cc to tile related members.

Thanks.

On 2/12/15 08:00, Chen Gang S wrote:
> 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.5i5j@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)
> +{
> +}
>
Chris Metcalf Feb. 12, 2015, 12:24 a.m. UTC | #2
On 2/12/15 08:00, Chen Gang S wrote:
> After load elf64 tilegx binary for linux-user, the working flow reaches
> the first correct instruction postion "__start".

Congratulations on getting started.  I hope you have success with the emulation part.

> 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
> +  ;;

I would recommend using "tilegx" here and throughout since in principle "tile" includes both the old 32-bit tilepro architecture as well as the newer 64-bit tilegx architecture.

>   
> +#define EM_TILE      191 /* Tile */
> +#define EM_TILE_OLD  0x2597 /* Tile compat */

No need for EM_TILE_OLD - it never really got out into the wild.

Also, 191 is EM_TILEGX in <elf.h>, so you really should use the same name here, not EM_TILE.

> @@ -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:

Stray newline - you should proof read the diff to avoid stuff like this.

> +        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;

Registers from 56 to 63 aren't really worth emulating.  56 to 62 aren't real registers; they're just access to the on-chip networks. If you were to really emulate them for multichip support, you'd need a bunch of special support to understand message formats and header words and wormhole routing, etc, which is probably out of scope. Just ignoring them completely is probably safest for now.  And 63 just always reads as zero and discards writes.

> +++ 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
[...]

Isn't there a way to say "use the asm-generic syscalls"?  What does ARM64 do, for example?  They use the generic syscall list.

> [...]
> +#define TARGET_NR_bpf                           280
> +#define TARGET_NR_execveat                      281
> +
> +/* current tilegx Linux kernel do not want to support the macros below */
> +

Probably better not to define them, then look at fixing anything that breaks as a result.  Again, ARM64 will be the same.

Similar comments apply to the other headers that tile uses that are just asm-generic versions.  It probably makes sense to have a qemu framework for asm-generic as well.

Tilera did some work on a qemu port only intended to be used with KVM for virtualization, so it probably doesn't do you much good.  If you're interested, I can send you the diffs.
Peter Maydell Feb. 12, 2015, 12:49 a.m. UTC | #3
On 12 February 2015 at 00:00, Chen Gang S <gang.chen@sunrus.com.cn> wrote:
> 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.

> ---
>  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(-)

A diffstat like this for a single patch indicates that
you *must* break this down into multiple patches for it
to be sensibly reviewable. Each patch should provide a
small but coherent part of the code. I suggest you look
at the mailing list archives and git history for other
new targets to see how this kind of "add a new architecture"
can be broken up into multiple patches

(Based purely on the number of lines added here I would
expect this to end up at at least 5 and probably more
like 10 patches or maybe more, but aim for a sensible
split of the functionality rather than a particular number
of patches. If in doubt, prefer more smaller patches to
fewer larger ones.)

thanks
-- PMM
Chen Gang Feb. 12, 2015, 2:53 a.m. UTC | #4
On 2/12/15 08:49, Peter Maydell wrote:
> On 12 February 2015 at 00:00, Chen Gang S <gang.chen@sunrus.com.cn> wrote:
>> 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.
> 
>> ---
>>  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(-)
> 
> A diffstat like this for a single patch indicates that
> you *must* break this down into multiple patches for it
> to be sensibly reviewable. Each patch should provide a
> small but coherent part of the code. I suggest you look
> at the mailing list archives and git history for other
> new targets to see how this kind of "add a new architecture"
> can be broken up into multiple patches
> 
> (Based purely on the number of lines added here I would
> expect this to end up at at least 5 and probably more
> like 10 patches or maybe more, but aim for a sensible
> split of the functionality rather than a particular number
> of patches. If in doubt, prefer more smaller patches to
> fewer larger ones.)
> 

OK, thank. I shall read related git log for another architectures, and
split current patch into multiple patches.

Thanks.
Chen Gang Feb. 12, 2015, 3:32 a.m. UTC | #5
On 2/12/15 08:24, Chris Metcalf wrote:
> On 2/12/15 08:00, Chen Gang S wrote:
>> After load elf64 tilegx binary for linux-user, the working flow reaches
>> the first correct instruction postion "__start".
> 
> Congratulations on getting started.  I hope you have success with the emulation part.
> 

Thank you very much for your encourage!  :-)


>> 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
>> +  ;;
> 
> I would recommend using "tilegx" here and throughout since in principle "tile" includes both the old 32-bit tilepro architecture as well as the newer 64-bit tilegx architecture.
> 

OK, I shall use tilegx.


>>   +#define EM_TILE      191 /* Tile */
>> +#define EM_TILE_OLD  0x2597 /* Tile compat */
> 
> No need for EM_TILE_OLD - it never really got out into the wild.
> 
> Also, 191 is EM_TILEGX in <elf.h>, so you really should use the same name here, not EM_TILE.
> 

OK, I shall use EM_TILEGX directly, also remove EM_TILE_OLD and all
related code.


>> @@ -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:
> 
> Stray newline - you should proof read the diff to avoid stuff like this.
> 

OK, thanks. I shall notice about it, next time.


>> +        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;
> 
> Registers from 56 to 63 aren't really worth emulating.  56 to 62 aren't real registers; they're just access to the on-chip networks. If you were to really emulate them for multichip support, you'd need a bunch of special support to understand message formats and header words and wormhole routing, etc, which is probably out of scope. Just ignoring them completely is probably safest for now.  And 63 just always reads as zero and discards writes.
> 

OK, thanks. I shall remove them.


>> +++ 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
> [...]
> 
> Isn't there a way to say "use the asm-generic syscalls"?  What does ARM64 do, for example?  They use the generic syscall list.
> 
>> [...]
>> +#define TARGET_NR_bpf                           280
>> +#define TARGET_NR_execveat                      281
>> +

Do you mean we need to remove them?


>> +/* current tilegx Linux kernel do not want to support the macros below */
>> +
> 
> Probably better not to define them, then look at fixing anything that breaks as a result.  Again, ARM64 will be the same.
> 

Do you mean we do not need to define 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
  ...

And excuse me, my English is not quite well, I don't quite understand:

  "fixing anything that breaks as a result".

Could you provide more details? Thanks.


> Similar comments apply to the other headers that tile uses that are just asm-generic versions.  It probably makes sense to have a qemu framework for asm-generic as well.
> 

What you said above sounds reasonable to me, but I guess, I am not the
suitable member to do it, at present.


> Tilera did some work on a qemu port only intended to be used with KVM for virtualization, so it probably doesn't do you much good.  If you're interested, I can send you the diffs.
> 

Welcome the related diffs, I guess, it must be helpful. :-)


Thanks.
Chen Gang Feb. 12, 2015, 3:48 a.m. UTC | #6
On 2/12/15 11:32, Chen Gang S wrote:
>>> >>   +#define EM_TILE      191 /* Tile */
>>> >> +#define EM_TILE_OLD  0x2597 /* Tile compat */
>> > 
>> > No need for EM_TILE_OLD - it never really got out into the wild.
>> > 
>> > Also, 191 is EM_TILEGX in <elf.h>, so you really should use the same name here, not EM_TILE.
>> > 

Oh, I can not fine EM_TILEGX in "elf.h" in master branch. I guess, I
need to define it, too.

> OK, I shall use EM_TILEGX directly, also remove EM_TILE_OLD and all
> related code.
> 
>
Chris Metcalf Feb. 12, 2015, 10:31 p.m. UTC | #7
On 2/11/2015 10:32 PM, Chen Gang S wrote:
>>> + */
>>> +#define TARGET_NR_io_setup                      0
>>> +#define TARGET_NR_io_destroy                    1
>>> +#define TARGET_NR_io_submit                     2
>> [...]
>>
>> Isn't there a way to say "use the asm-generic syscalls"?  What does ARM64 do, for example?  They use the generic syscall list.
>>
>>> [...]
>>> +#define TARGET_NR_bpf                           280
>>> +#define TARGET_NR_execveat                      281
>>> +
> Do you mean we need to remove them?

No, I'm saying it would be good to be able to have a single shared header that listed all the asm-generic syscall numbers that could be shared by tile, arm64, etc.

>>> +/* current tilegx Linux kernel do not want to support the macros below */
>>> +
>> Probably better not to define them, then look at fixing anything that breaks as a result.  Again, ARM64 will be the same.
>>
> Do you mean we do not need to define the macros below?
>
>    #define TARGET_NR_open 1024
>    #define TARGET_NR_link 1025
>    #define TARGET_NR_unlink 1026

That's my suggestion, yes.

> And excuse me, my English is not quite well, I don't quite understand:
>
>    "fixing anything that breaks as a result".
>
> Could you provide more details? Thanks.

So if you undefine TARGET_NR_open, etc, hopefully qemu will build. If it does not build, you should probably find out why, and fix it. Perhaps you can use NR_openat as a replacement for NR_open, etc.

>> Tilera did some work on a qemu port only intended to be used with KVM for virtualization, so it probably doesn't do you much good.  If you're interested, I can send you the diffs.
>>
> Welcome the related diffs, I guess, it must be helpful. :-)

I uploaded it to:

   http://173.201.26.195/scm/qemu-kvm-0.13.0.get

Notice that this is against a much older version of qemu, though.
Chris Metcalf Feb. 12, 2015, 10:32 p.m. UTC | #8
On 2/11/2015 10:48 PM, Chen Gang S wrote:
> On 2/12/15 11:32, Chen Gang S wrote:
>>>>>> >>> >>   +#define EM_TILE      191 /* Tile */
>>>>>> >>> >>+#define EM_TILE_OLD  0x2597 /* Tile compat */
>>>> >> >
>>>> >> >No need for EM_TILE_OLD - it never really got out into the wild.
>>>> >> >
>>>> >> >Also, 191 is EM_TILEGX in <elf.h>, so you really should use the same name here, not EM_TILE.
>>>> >> >
> Oh, I can not fine EM_TILEGX in "elf.h" in master branch. I guess, I
> need to define it, too.

It is in glibc's /usr/include/elf.h since version 2.16.
Chen Gang Feb. 13, 2015, 4:03 a.m. UTC | #9
On 2/13/15 06:32, Chris Metcalf wrote:
> On 2/11/2015 10:48 PM, Chen Gang S wrote:
>> On 2/12/15 11:32, Chen Gang S wrote:
>>>>>>> >>> >>   +#define EM_TILE      191 /* Tile */
>>>>>>> >>> >>+#define EM_TILE_OLD  0x2597 /* Tile compat */
>>>>> >> >
>>>>> >> >No need for EM_TILE_OLD - it never really got out into the wild.
>>>>> >> >
>>>>> >> >Also, 191 is EM_TILEGX in <elf.h>, so you really should use the same name here, not EM_TILE.
>>>>> >> >
>> Oh, I can not fine EM_TILEGX in "elf.h" in master branch. I guess, I
>> need to define it, too.
> 
> It is in glibc's /usr/include/elf.h since version 2.16.
> 

OK, thanks. Really it is, and glibc also defines another archs (e.g.
microblaze). But I guess, at present, we have to use qemu's "elf.h":

 - qemu may use another libc libraries (e.g. newlibc, I guess), which
   may not have these macros.

 - If qemu will consider about the system elf.h file in the future, it
   will change all related macros (it almost means rewrite its elf.h).

So for me, at present, just follow with the current qemu's elf.h is OK:
(define EM_TILEGX directly without ifdef EM_TILEGX or endif).


Thanks.
Chen Gang Feb. 13, 2015, 4:43 a.m. UTC | #10
On 2/13/15 06:31, Chris Metcalf wrote:
> On 2/11/2015 10:32 PM, Chen Gang S wrote:
>> And excuse me, my English is not quite well, I don't quite understand:
>>
>>    "fixing anything that breaks as a result".
>>
>> Could you provide more details? Thanks.
> 
> So if you undefine TARGET_NR_open, etc, hopefully qemu will build. If it does not build, you should probably find out why, and fix it. Perhaps you can use NR_openat as a replacement for NR_open, etc.
>

Originally, I have tried to remove TARGET_NR_open and others, they can
not pass building, and I also noticed about NR_openat. But at last, I
still remain TARGET_NR_open and others (with related comments):

 - Another platforms (e.g. microblaze, arm64) defined them, too.

 - It is only for linux-user, can bypass Linux tile kernel. So it is
   still correct.

 - It really wastes memory and storage a little, but for me, the related
   maintainers (not me) need to consider about whether let the code more
   complex or save memory a little.

 
>> Welcome the related diffs, I guess, it must be helpful. :-)
> 
> I uploaded it to:
> 
>   http://173.201.26.195/scm/qemu-kvm-0.13.0.get
> 
> Notice that this is against a much older version of qemu, though.
> 

OK, thanks. After read through, it is useful to me. :-)


Thanks.
Peter Maydell Feb. 13, 2015, 4:56 a.m. UTC | #11
On 13 February 2015 at 04:43, Chen Gang S <gang.chen@sunrus.com.cn> wrote:
> Originally, I have tried to remove TARGET_NR_open and others, they can
> not pass building, and I also noticed about NR_openat. But at last, I
> still remain TARGET_NR_open and others (with related comments):
>
>  - Another platforms (e.g. microblaze, arm64) defined them, too.
>
>  - It is only for linux-user, can bypass Linux tile kernel. So it is
>    still correct.

The question is, does the Linux kernel for this architecture implement
a particular syscall (eg NR_open)? (That is, is there a syscall number
defined, and if you try to execute a syscall with this syscall number,
does it work, or does it fail?) If it does implement it, then you need to
#define TARGET_NR_open appropriately. If not, then don't define that.
If QEMU doesn't build as a result, this probably means our linux-user
code doesn't expect a target architecture with no implementation of
that syscall. In that case you should fix the linux-user code (eg
by adding ifdefs).

>  - It really wastes memory and storage a little, but for me, the related
>    maintainers (not me) need to consider about whether let the code more
>    complex or save memory a little.

Neither code complexity nor memory use are important here. It is an
issue of correctness.

thanks
-- PMM
Peter Maydell Feb. 13, 2015, 5:43 a.m. UTC | #12
On 13 February 2015 at 05:44, Chen Gang S <gang.chen@sunrus.com.cn> wrote:
> Which issue of correctness will occur? I can not enum it.

If the Linux kernel does not implement these syscalls then
QEMU must not either. Attempting them should fail, same as
if you attempted them with the real kernel.

>  - linux-user already bypasses target linux kernel, and libc for tilegx
>    can not generate these calls (not defined for libc, either).

Just because libc doesn't try to do these things doesn't mean
QEMU should do the wrong thing for them.

>  - For any informal using, linux-user can still operate NR_open and
>    others, it is harmless.

But it is still wrong.

-- PMM
Chen Gang Feb. 13, 2015, 5:44 a.m. UTC | #13
On 2/13/15 12:56, Peter Maydell wrote:
> On 13 February 2015 at 04:43, Chen Gang S <gang.chen@sunrus.com.cn> wrote:
>> Originally, I have tried to remove TARGET_NR_open and others, they can
>> not pass building, and I also noticed about NR_openat. But at last, I
>> still remain TARGET_NR_open and others (with related comments):
>>
>>  - Another platforms (e.g. microblaze, arm64) defined them, too.
>>
>>  - It is only for linux-user, can bypass Linux tile kernel. So it is
>>    still correct.
> 
> The question is, does the Linux kernel for this architecture implement
> a particular syscall (eg NR_open)? (That is, is there a syscall number
> defined, and if you try to execute a syscall with this syscall number,
> does it work, or does it fail?) If it does implement it, then you need to
> #define TARGET_NR_open appropriately. If not, then don't define that.
> If QEMU doesn't build as a result, this probably means our linux-user
> code doesn't expect a target architecture with no implementation of
> that syscall. In that case you should fix the linux-user code (eg
> by adding ifdefs).
>

The tilegx 64-bit Linux kernel doesn't support TARGET_NR_open and others.

>>  - It really wastes memory and storage a little, but for me, the related
>>    maintainers (not me) need to consider about whether let the code more
>>    complex or save memory a little.
> 
> Neither code complexity nor memory use are important here. It is an
> issue of correctness.
> 

Which issue of correctness will occur? I can not enum it. For me, they
are only the waste code:

 - linux-user already bypasses target linux kernel, and libc for tilegx
   can not generate these calls (not defined for libc, either).

 - For any informal using, linux-user can still operate NR_open and
   others, it is harmless.

 - It is about compatible (not about correctness issues).

I guess, tilegx is the new processor than most of others within Tilera,
so it does not want to compatible with the old calls (then can save
memory and spaces, also can let things a little simpler).


Thanks.
Chen Gang Feb. 13, 2015, 6:34 a.m. UTC | #14
On 2/13/15 13:43, Peter Maydell wrote:
> On 13 February 2015 at 05:44, Chen Gang S <gang.chen@sunrus.com.cn> wrote:
>> Which issue of correctness will occur? I can not enum it.
> 
> If the Linux kernel does not implement these syscalls then
> QEMU must not either. Attempting them should fail, same as
> if you attempted them with the real kernel.
> 
>>  - linux-user already bypasses target linux kernel, and libc for tilegx
>>    can not generate these calls (not defined for libc, either).
> 
> Just because libc doesn't try to do these things doesn't mean
> QEMU should do the wrong thing for them.
> 
>>  - For any informal using, linux-user can still operate NR_open and
>>    others, it is harmless.
> 
> But it is still wrong.
> 

OK, I shall send patch v3 for it, after all related patches are reviewed.

Thanks.
diff mbox

Patch

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)
+{
+}