diff mbox

[07/10,v11] target-tilegx: Add cpu basic features for linux-user

Message ID BLU437-SMTP11F70D5136F1A84987BE2FB9C80@phx.gbl
State New
Headers show

Commit Message

Chen Gang May 30, 2015, 9:15 p.m. UTC
It implements minimized cpu features for linux-user.

Signed-off-by: Chen Gang <gang.chen.5i5j@gmail.com>
---
 target-tilegx/cpu.c | 143 +++++++++++++++++++++++++++++++++++++++++++
 target-tilegx/cpu.h | 171 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 314 insertions(+)
 create mode 100644 target-tilegx/cpu.c
 create mode 100644 target-tilegx/cpu.h

Comments

Peter Maydell June 2, 2015, 5:51 p.m. UTC | #1
On 30 May 2015 at 22:15, Chen Gang <xili_gchen_5257@hotmail.com> wrote:
> It implements minimized cpu features for linux-user.
>
> Signed-off-by: Chen Gang <gang.chen.5i5j@gmail.com>
> ---
>  target-tilegx/cpu.c | 143 +++++++++++++++++++++++++++++++++++++++++++
>  target-tilegx/cpu.h | 171 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 314 insertions(+)
>  create mode 100644 target-tilegx/cpu.c
>  create mode 100644 target-tilegx/cpu.h
>
> diff --git a/target-tilegx/cpu.c b/target-tilegx/cpu.c
> new file mode 100644
> index 0000000..663fcb6
> --- /dev/null
> +++ b/target-tilegx/cpu.c
> @@ -0,0 +1,143 @@
> +/*
> + * QEMU TILE-Gx 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"
> +
> +TileGXCPU *cpu_tilegx_init(const char *cpu_model)
> +{
> +    TileGXCPU *cpu;
> +
> +    cpu = TILEGX_CPU(object_new(TYPE_TILEGX_CPU));
> +
> +    object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
> +
> +    return cpu;
> +}
> +
> +static void tilegx_cpu_set_pc(CPUState *cs, vaddr value)
> +{
> +    TileGXCPU *cpu = TILEGX_CPU(cs);
> +
> +    cpu->env.pc = value;
> +}
> +
> +static bool tilegx_cpu_has_work(CPUState *cs)
> +{
> +    return true;
> +}
> +
> +static void tilegx_cpu_reset(CPUState *s)
> +{
> +    TileGXCPU *cpu = TILEGX_CPU(s);
> +    TileGXCPUClass *tcc = TILEGX_CPU_GET_CLASS(cpu);
> +    CPUTLGState *env = &cpu->env;
> +
> +    tcc->parent_reset(s);
> +
> +    memset(env, 0, sizeof(CPUTLGState));
> +    tlb_flush(s, 1);
> +}
> +
> +static void tilegx_cpu_realizefn(DeviceState *dev, Error **errp)
> +{
> +    CPUState *cs = CPU(dev);
> +    TileGXCPUClass *tcc = TILEGX_CPU_GET_CLASS(dev);
> +
> +    cpu_reset(cs);
> +    qemu_init_vcpu(cs);
> +
> +    tcc->parent_realize(dev, errp);
> +}
> +
> +static void tilegx_cpu_initfn(Object *obj)
> +{
> +    CPUState *cs = CPU(obj);
> +    TileGXCPU *cpu = TILEGX_CPU(obj);
> +    CPUTLGState *env = &cpu->env;
> +    static bool tcg_initialized;
> +
> +    cs->env_ptr = env;
> +    cpu_exec_init(env);
> +
> +    if (tcg_enabled() && !tcg_initialized) {
> +        tcg_initialized = true;
> +        tilegx_tcg_init();
> +    }
> +}
> +
> +static void tilegx_cpu_do_interrupt(CPUState *cs)
> +{
> +    cs->exception_index = -1;
> +}
> +
> +static int tilegx_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
> +                                       int mmu_idx)
> +{
> +    cpu_dump_state(cs, stderr, fprintf, 0);
> +    return 1;
> +}
> +
> +static bool tilegx_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
> +{
> +    if (interrupt_request & CPU_INTERRUPT_HARD) {
> +        tilegx_cpu_do_interrupt(cs);
> +        return true;
> +    }
> +    return false;
> +}
> +
> +static void tilegx_cpu_class_init(ObjectClass *oc, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(oc);
> +    CPUClass *cc = CPU_CLASS(oc);
> +    TileGXCPUClass *tcc = TILEGX_CPU_CLASS(oc);
> +
> +    tcc->parent_realize = dc->realize;
> +    dc->realize = tilegx_cpu_realizefn;
> +
> +    tcc->parent_reset = cc->reset;
> +    cc->reset = tilegx_cpu_reset;
> +
> +    cc->has_work = tilegx_cpu_has_work;
> +    cc->do_interrupt = tilegx_cpu_do_interrupt;
> +    cc->cpu_exec_interrupt = tilegx_cpu_exec_interrupt;
> +    cc->set_pc = tilegx_cpu_set_pc;
> +    cc->handle_mmu_fault = tilegx_cpu_handle_mmu_fault;
> +    cc->gdb_num_core_regs = 0;
> +}
> +
> +static const TypeInfo tilegx_cpu_type_info = {
> +    .name = TYPE_TILEGX_CPU,
> +    .parent = TYPE_CPU,
> +    .instance_size = sizeof(TileGXCPU),
> +    .instance_init = tilegx_cpu_initfn,
> +    .class_size = sizeof(TileGXCPUClass),
> +    .class_init = tilegx_cpu_class_init,
> +};
> +
> +static void tilegx_cpu_register_types(void)
> +{
> +    type_register_static(&tilegx_cpu_type_info);
> +}
> +
> +type_init(tilegx_cpu_register_types)
> diff --git a/target-tilegx/cpu.h b/target-tilegx/cpu.h
> new file mode 100644
> index 0000000..a0f4c6f
> --- /dev/null
> +++ b/target-tilegx/cpu.h
> @@ -0,0 +1,171 @@
> +/*
> + *  TILE-Gx 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_TILEGX_H
> +#define CPU_TILEGX_H
> +
> +#include "config.h"
> +#include "qemu-common.h"
> +
> +#define TARGET_LONG_BITS 64
> +
> +#define CPUArchState struct CPUTLGState
> +
> +#include "exec/cpu-defs.h"
> +
> +
> +/* TILE-Gx common register alias */
> +#define TILEGX_R_RE    0   /*  0 register, for function/syscall return value */
> +#define TILEGX_R_ERR   1   /*  1 register, for syscall errno flag */
> +#define TILEGX_R_NR    10  /* 10 register, for syscall number */
> +#define TILEGX_R_BP    52  /* 52 register, optional frame pointer */
> +#define TILEGX_R_TP    53  /* TP register, thread local storage data */
> +#define TILEGX_R_SP    54  /* SP register, stack pointer */
> +#define TILEGX_R_LR    55  /* LR register, may save pc, but it is not pc */
> +#define TILEGX_R_ZERO  63  /* Zero register, always zero */
> +#define TILEGX_R_COUNT 56  /* Only 56 registers are really useful */
> +#define TILEGX_R_NOREG 255 /* Invalid register value */
> +
> +#define TILEGX_IS_ERRNO(ret) \
> +                       ((ret) > 0xfffffffffffff000ULL) /* errno is 0 -- 4096 */

TILEGX_IS_ERRNO is specific to the Linux syscall ABI; it
belongs in linux-user/ somewhere, not here.


> +
> +/* TILE-Gx special registers used by outside */
> +enum {
> +    TILEGX_SPR_CMPEXCH = 0,
> +    TILEGX_SPR_CRITICAL_SEC = 1,
> +    TILEGX_SPR_SIM_CONTROL = 2,
> +    TILEGX_SPR_COUNT
> +};
> +
> +/* Exception numbers */
> +enum {
> +    TILEGX_EXCP_NONE = 0,
> +    TILEGX_EXCP_SYSCALL = 1,
> +    TILEGX_EXCP_OPCODE_UNKNOWN = 0x101,
> +    TILEGX_EXCP_OPCODE_UNIMPLEMENTED = 0x102,
> +    TILEGX_EXCP_OPCODE_CMPEXCH = 0x103,
> +    TILEGX_EXCP_OPCODE_CMPEXCH4 = 0x104,
> +    TILEGX_EXCP_OPCODE_EXCH = 0x105,
> +    TILEGX_EXCP_OPCODE_EXCH4 = 0x106,
> +    TILEGX_EXCP_OPCODE_FETCHADD = 0x107,
> +    TILEGX_EXCP_OPCODE_FETCHADD4 = 0x108,
> +    TILEGX_EXCP_OPCODE_FETCHADDGEZ = 0x109,
> +    TILEGX_EXCP_OPCODE_FETCHADDGEZ4 = 0x10a,
> +    TILEGX_EXCP_OPCODE_FETCHAND = 0x10b,
> +    TILEGX_EXCP_OPCODE_FETCHAND4 = 0x10c,
> +    TILEGX_EXCP_OPCODE_FETCHOR = 0x10d,
> +    TILEGX_EXCP_OPCODE_FETCHOR4 = 0x10e,
> +    TILEGX_EXCP_REG_UNSUPPORTED = 0x181,
> +    TILEGX_EXCP_UNALIGNMENT = 0x201,
> +    TILEGX_EXCP_DBUG_BREAK = 0x301
> +};
> +
> +typedef struct CPUTLGState {
> +    uint64_t regs[TILEGX_R_COUNT];     /* Common used registers by outside */
> +    uint64_t spregs[TILEGX_SPR_COUNT]; /* Special used registers by outside */
> +    uint64_t pc;                       /* Current pc */
> +
> +#if defined(CONFIG_USER_ONLY)
> +    uint32_t excparam;                 /* exception parameter */
> +#endif
> +
> +    CPU_COMMON
> +} CPUTLGState;
> +
> +#include "qom/cpu.h"
> +
> +#define TYPE_TILEGX_CPU "tilegx-cpu"
> +
> +#define TILEGX_CPU_CLASS(klass) \
> +    OBJECT_CLASS_CHECK(TileGXCPUClass, (klass), TYPE_TILEGX_CPU)
> +#define TILEGX_CPU(obj) \
> +    OBJECT_CHECK(TileGXCPU, (obj), TYPE_TILEGX_CPU)
> +#define TILEGX_CPU_GET_CLASS(obj) \
> +    OBJECT_GET_CLASS(TileGXCPUClass, (obj), TYPE_TILEGX_CPU)
> +
> +/**
> + * TileGXCPUClass:
> + * @parent_realize: The parent class' realize handler.
> + * @parent_reset: The parent class' reset handler.
> + *
> + * A Tile-Gx CPU model.
> + */
> +typedef struct TileGXCPUClass {
> +    /*< private >*/
> +    CPUClass parent_class;
> +    /*< public >*/
> +
> +    DeviceRealize parent_realize;
> +    void (*parent_reset)(CPUState *cpu);
> +} TileGXCPUClass;
> +
> +/**
> + * TileGXCPU:
> + * @env: #CPUTLGState
> + *
> + * A Tile-GX CPU.
> + */
> +typedef struct TileGXCPU {
> +    /*< private >*/
> +    CPUState parent_obj;
> +    /*< public >*/
> +
> +    CPUTLGState env;
> +} TileGXCPU;
> +
> +static inline TileGXCPU *tilegx_env_get_cpu(CPUTLGState *env)
> +{
> +    return container_of(env, TileGXCPU, env);
> +}
> +
> +#define ENV_GET_CPU(e) CPU(tilegx_env_get_cpu(e))
> +
> +#define ENV_OFFSET offsetof(TileGXCPU, env)
> +
> +/* TILE-Gx memory attributes */
> +#define TARGET_PAGE_BITS 16  /* TILE-Gx uses 64KB page size */
> +#define MMAP_SHIFT TARGET_PAGE_BITS

MMAP_SHIFT is linux ABI specific and doesn't belong in this file.

> +#define TARGET_PHYS_ADDR_SPACE_BITS 42 /* It has 42 bit physical addresses */
> +#define TARGET_VIRT_ADDR_SPACE_BITS 64 /* It has 64 bit virtual addresses */

These comments are stating the obvious and can be deleted.

> +#define MMU_USER_IDX    0  /* Current memory operation is in user mode */
> +
> +#include "exec/cpu-all.h"
> +
> +void tilegx_tcg_init(void);
> +int cpu_tilegx_exec(CPUTLGState *s);
> +int cpu_tilegx_signal_handler(int host_signum, void *pinfo, void *puc);
> +
> +TileGXCPU *cpu_tilegx_init(const char *cpu_model);
> +
> +#define cpu_init(cpu_model) CPU(cpu_tilegx_init(cpu_model))
> +
> +#define cpu_exec cpu_tilegx_exec
> +#define cpu_gen_code cpu_tilegx_gen_code
> +#define cpu_signal_handler cpu_tilegx_signal_handler
> +
> +static inline void cpu_get_tb_cpu_state(CPUTLGState *env, target_ulong *pc,
> +                                        target_ulong *cs_base, int *flags)
> +{
> +    *pc = env->pc;
> +    *cs_base = 0;
> +    *flags = 0;
> +}
> +
> +#include "exec/exec-all.h"
> +
> +#endif
> --
> 1.9.3


thanks
-- PMM
Chen Gang June 2, 2015, 8:47 p.m. UTC | #2
Firstly, thank you very much for your valuable work for all patches.

On 6/3/15 01:51, Peter Maydell wrote:
> On 30 May 2015 at 22:15, Chen Gang <xili_gchen_5257@hotmail.com> wrote:
>> +
>> +#define TILEGX_IS_ERRNO(ret) \
>> +                       ((ret) > 0xfffffffffffff000ULL) /* errno is 0 -- 4096 */
> 
> TILEGX_IS_ERRNO is specific to the Linux syscall ABI; it
> belongs in linux-user/ somewhere, not here.
> 

OK, thanks. I shall move it to linux-user/tilegx/syscall.h.

>> +#define ENV_GET_CPU(e) CPU(tilegx_env_get_cpu(e))
>> +
>> +#define ENV_OFFSET offsetof(TileGXCPU, env)
>> +
>> +/* TILE-Gx memory attributes */
>> +#define TARGET_PAGE_BITS 16  /* TILE-Gx uses 64KB page size */
>> +#define MMAP_SHIFT TARGET_PAGE_BITS
> 
> MMAP_SHIFT is linux ABI specific and doesn't belong in this file.
> 

OK, thanks. I shall move it to linux-user/tilegx/syscall.h (although
all the other targets still put it in "target-*/cpu.h").


>> +#define TARGET_PHYS_ADDR_SPACE_BITS 42 /* It has 42 bit physical addresses */
>> +#define TARGET_VIRT_ADDR_SPACE_BITS 64 /* It has 64 bit virtual addresses */
> 
> These comments are stating the obvious and can be deleted.
>

OK, thanks.
diff mbox

Patch

diff --git a/target-tilegx/cpu.c b/target-tilegx/cpu.c
new file mode 100644
index 0000000..663fcb6
--- /dev/null
+++ b/target-tilegx/cpu.c
@@ -0,0 +1,143 @@ 
+/*
+ * QEMU TILE-Gx 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"
+
+TileGXCPU *cpu_tilegx_init(const char *cpu_model)
+{
+    TileGXCPU *cpu;
+
+    cpu = TILEGX_CPU(object_new(TYPE_TILEGX_CPU));
+
+    object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
+
+    return cpu;
+}
+
+static void tilegx_cpu_set_pc(CPUState *cs, vaddr value)
+{
+    TileGXCPU *cpu = TILEGX_CPU(cs);
+
+    cpu->env.pc = value;
+}
+
+static bool tilegx_cpu_has_work(CPUState *cs)
+{
+    return true;
+}
+
+static void tilegx_cpu_reset(CPUState *s)
+{
+    TileGXCPU *cpu = TILEGX_CPU(s);
+    TileGXCPUClass *tcc = TILEGX_CPU_GET_CLASS(cpu);
+    CPUTLGState *env = &cpu->env;
+
+    tcc->parent_reset(s);
+
+    memset(env, 0, sizeof(CPUTLGState));
+    tlb_flush(s, 1);
+}
+
+static void tilegx_cpu_realizefn(DeviceState *dev, Error **errp)
+{
+    CPUState *cs = CPU(dev);
+    TileGXCPUClass *tcc = TILEGX_CPU_GET_CLASS(dev);
+
+    cpu_reset(cs);
+    qemu_init_vcpu(cs);
+
+    tcc->parent_realize(dev, errp);
+}
+
+static void tilegx_cpu_initfn(Object *obj)
+{
+    CPUState *cs = CPU(obj);
+    TileGXCPU *cpu = TILEGX_CPU(obj);
+    CPUTLGState *env = &cpu->env;
+    static bool tcg_initialized;
+
+    cs->env_ptr = env;
+    cpu_exec_init(env);
+
+    if (tcg_enabled() && !tcg_initialized) {
+        tcg_initialized = true;
+        tilegx_tcg_init();
+    }
+}
+
+static void tilegx_cpu_do_interrupt(CPUState *cs)
+{
+    cs->exception_index = -1;
+}
+
+static int tilegx_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
+                                       int mmu_idx)
+{
+    cpu_dump_state(cs, stderr, fprintf, 0);
+    return 1;
+}
+
+static bool tilegx_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
+{
+    if (interrupt_request & CPU_INTERRUPT_HARD) {
+        tilegx_cpu_do_interrupt(cs);
+        return true;
+    }
+    return false;
+}
+
+static void tilegx_cpu_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+    CPUClass *cc = CPU_CLASS(oc);
+    TileGXCPUClass *tcc = TILEGX_CPU_CLASS(oc);
+
+    tcc->parent_realize = dc->realize;
+    dc->realize = tilegx_cpu_realizefn;
+
+    tcc->parent_reset = cc->reset;
+    cc->reset = tilegx_cpu_reset;
+
+    cc->has_work = tilegx_cpu_has_work;
+    cc->do_interrupt = tilegx_cpu_do_interrupt;
+    cc->cpu_exec_interrupt = tilegx_cpu_exec_interrupt;
+    cc->set_pc = tilegx_cpu_set_pc;
+    cc->handle_mmu_fault = tilegx_cpu_handle_mmu_fault;
+    cc->gdb_num_core_regs = 0;
+}
+
+static const TypeInfo tilegx_cpu_type_info = {
+    .name = TYPE_TILEGX_CPU,
+    .parent = TYPE_CPU,
+    .instance_size = sizeof(TileGXCPU),
+    .instance_init = tilegx_cpu_initfn,
+    .class_size = sizeof(TileGXCPUClass),
+    .class_init = tilegx_cpu_class_init,
+};
+
+static void tilegx_cpu_register_types(void)
+{
+    type_register_static(&tilegx_cpu_type_info);
+}
+
+type_init(tilegx_cpu_register_types)
diff --git a/target-tilegx/cpu.h b/target-tilegx/cpu.h
new file mode 100644
index 0000000..a0f4c6f
--- /dev/null
+++ b/target-tilegx/cpu.h
@@ -0,0 +1,171 @@ 
+/*
+ *  TILE-Gx 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_TILEGX_H
+#define CPU_TILEGX_H
+
+#include "config.h"
+#include "qemu-common.h"
+
+#define TARGET_LONG_BITS 64
+
+#define CPUArchState struct CPUTLGState
+
+#include "exec/cpu-defs.h"
+
+
+/* TILE-Gx common register alias */
+#define TILEGX_R_RE    0   /*  0 register, for function/syscall return value */
+#define TILEGX_R_ERR   1   /*  1 register, for syscall errno flag */
+#define TILEGX_R_NR    10  /* 10 register, for syscall number */
+#define TILEGX_R_BP    52  /* 52 register, optional frame pointer */
+#define TILEGX_R_TP    53  /* TP register, thread local storage data */
+#define TILEGX_R_SP    54  /* SP register, stack pointer */
+#define TILEGX_R_LR    55  /* LR register, may save pc, but it is not pc */
+#define TILEGX_R_ZERO  63  /* Zero register, always zero */
+#define TILEGX_R_COUNT 56  /* Only 56 registers are really useful */
+#define TILEGX_R_NOREG 255 /* Invalid register value */
+
+#define TILEGX_IS_ERRNO(ret) \
+                       ((ret) > 0xfffffffffffff000ULL) /* errno is 0 -- 4096 */
+
+/* TILE-Gx special registers used by outside */
+enum {
+    TILEGX_SPR_CMPEXCH = 0,
+    TILEGX_SPR_CRITICAL_SEC = 1,
+    TILEGX_SPR_SIM_CONTROL = 2,
+    TILEGX_SPR_COUNT
+};
+
+/* Exception numbers */
+enum {
+    TILEGX_EXCP_NONE = 0,
+    TILEGX_EXCP_SYSCALL = 1,
+    TILEGX_EXCP_OPCODE_UNKNOWN = 0x101,
+    TILEGX_EXCP_OPCODE_UNIMPLEMENTED = 0x102,
+    TILEGX_EXCP_OPCODE_CMPEXCH = 0x103,
+    TILEGX_EXCP_OPCODE_CMPEXCH4 = 0x104,
+    TILEGX_EXCP_OPCODE_EXCH = 0x105,
+    TILEGX_EXCP_OPCODE_EXCH4 = 0x106,
+    TILEGX_EXCP_OPCODE_FETCHADD = 0x107,
+    TILEGX_EXCP_OPCODE_FETCHADD4 = 0x108,
+    TILEGX_EXCP_OPCODE_FETCHADDGEZ = 0x109,
+    TILEGX_EXCP_OPCODE_FETCHADDGEZ4 = 0x10a,
+    TILEGX_EXCP_OPCODE_FETCHAND = 0x10b,
+    TILEGX_EXCP_OPCODE_FETCHAND4 = 0x10c,
+    TILEGX_EXCP_OPCODE_FETCHOR = 0x10d,
+    TILEGX_EXCP_OPCODE_FETCHOR4 = 0x10e,
+    TILEGX_EXCP_REG_UNSUPPORTED = 0x181,
+    TILEGX_EXCP_UNALIGNMENT = 0x201,
+    TILEGX_EXCP_DBUG_BREAK = 0x301
+};
+
+typedef struct CPUTLGState {
+    uint64_t regs[TILEGX_R_COUNT];     /* Common used registers by outside */
+    uint64_t spregs[TILEGX_SPR_COUNT]; /* Special used registers by outside */
+    uint64_t pc;                       /* Current pc */
+
+#if defined(CONFIG_USER_ONLY)
+    uint32_t excparam;                 /* exception parameter */
+#endif
+
+    CPU_COMMON
+} CPUTLGState;
+
+#include "qom/cpu.h"
+
+#define TYPE_TILEGX_CPU "tilegx-cpu"
+
+#define TILEGX_CPU_CLASS(klass) \
+    OBJECT_CLASS_CHECK(TileGXCPUClass, (klass), TYPE_TILEGX_CPU)
+#define TILEGX_CPU(obj) \
+    OBJECT_CHECK(TileGXCPU, (obj), TYPE_TILEGX_CPU)
+#define TILEGX_CPU_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(TileGXCPUClass, (obj), TYPE_TILEGX_CPU)
+
+/**
+ * TileGXCPUClass:
+ * @parent_realize: The parent class' realize handler.
+ * @parent_reset: The parent class' reset handler.
+ *
+ * A Tile-Gx CPU model.
+ */
+typedef struct TileGXCPUClass {
+    /*< private >*/
+    CPUClass parent_class;
+    /*< public >*/
+
+    DeviceRealize parent_realize;
+    void (*parent_reset)(CPUState *cpu);
+} TileGXCPUClass;
+
+/**
+ * TileGXCPU:
+ * @env: #CPUTLGState
+ *
+ * A Tile-GX CPU.
+ */
+typedef struct TileGXCPU {
+    /*< private >*/
+    CPUState parent_obj;
+    /*< public >*/
+
+    CPUTLGState env;
+} TileGXCPU;
+
+static inline TileGXCPU *tilegx_env_get_cpu(CPUTLGState *env)
+{
+    return container_of(env, TileGXCPU, env);
+}
+
+#define ENV_GET_CPU(e) CPU(tilegx_env_get_cpu(e))
+
+#define ENV_OFFSET offsetof(TileGXCPU, env)
+
+/* TILE-Gx memory attributes */
+#define TARGET_PAGE_BITS 16  /* TILE-Gx uses 64KB page size */
+#define MMAP_SHIFT TARGET_PAGE_BITS
+#define TARGET_PHYS_ADDR_SPACE_BITS 42 /* It has 42 bit physical addresses */
+#define TARGET_VIRT_ADDR_SPACE_BITS 64 /* It has 64 bit virtual addresses */
+#define MMU_USER_IDX    0  /* Current memory operation is in user mode */
+
+#include "exec/cpu-all.h"
+
+void tilegx_tcg_init(void);
+int cpu_tilegx_exec(CPUTLGState *s);
+int cpu_tilegx_signal_handler(int host_signum, void *pinfo, void *puc);
+
+TileGXCPU *cpu_tilegx_init(const char *cpu_model);
+
+#define cpu_init(cpu_model) CPU(cpu_tilegx_init(cpu_model))
+
+#define cpu_exec cpu_tilegx_exec
+#define cpu_gen_code cpu_tilegx_gen_code
+#define cpu_signal_handler cpu_tilegx_signal_handler
+
+static inline void cpu_get_tb_cpu_state(CPUTLGState *env, target_ulong *pc,
+                                        target_ulong *cs_base, int *flags)
+{
+    *pc = env->pc;
+    *cs_base = 0;
+    *flags = 0;
+}
+
+#include "exec/exec-all.h"
+
+#endif