diff mbox

[1/6,v2] target-tilegx: Firstly add to qemu with minimized features

Message ID 54E1F56E.803@sunrus.com.cn
State New
Headers show

Commit Message

Chen Gang Feb. 16, 2015, 1:49 p.m. UTC
It almost likes a template for adding an architecture target.

Signed-off-by: Chen Gang <gang.chen.5i5j@gmail.com>
---
 configure                             |   7 ++
 default-configs/tilegx-linux-user.mak |   1 +
 target-tilegx/Makefile.objs           |   1 +
 target-tilegx/cpu-qom.h               |  72 +++++++++++++++
 target-tilegx/cpu.c                   | 159 ++++++++++++++++++++++++++++++++++
 target-tilegx/cpu.h                   |  84 ++++++++++++++++++
 target-tilegx/helper.h                |   0
 target-tilegx/translate.c             |  54 ++++++++++++
 8 files changed, 378 insertions(+)
 create mode 100644 default-configs/tilegx-linux-user.mak
 create mode 100644 target-tilegx/Makefile.objs
 create mode 100644 target-tilegx/cpu-qom.h
 create mode 100644 target-tilegx/cpu.c
 create mode 100644 target-tilegx/cpu.h
 create mode 100644 target-tilegx/helper.h
 create mode 100644 target-tilegx/translate.c

Comments

Richard Henderson Feb. 16, 2015, 4:25 p.m. UTC | #1
On 02/16/2015 05:49 AM, Chen Gang S wrote:
> +#define TILEGX_R_PC  55  /* LR register, pc pointer */

No, register 55 is the link register, not the PC.
I.e. it is only special in that it receives the
return address from the JAL instructions.

> +typedef struct CPUTLState {
> +    uint64_t regs[56];
> +    CPU_COMMON
> +} CPUTLState;

Which means you need another entry here for the PC.

> +static inline void cpu_get_tb_cpu_state(CPUTLState *env, target_ulong *pc,
> +                                        target_ulong *cs_base, int *flags)
> +{
> +    *pc = env->regs[TILEGX_R_PC];

And you should not reference the link register here.


r~
Chen Gang Feb. 16, 2015, 10:51 p.m. UTC | #2
On 2/17/15 00:25, Richard Henderson wrote:
> On 02/16/2015 05:49 AM, Chen Gang S wrote:
>> +#define TILEGX_R_PC  55  /* LR register, pc pointer */
> 
> No, register 55 is the link register, not the PC.
> I.e. it is only special in that it receives the
> return address from the JAL instructions.
> 
>> +typedef struct CPUTLState {
>> +    uint64_t regs[56];
>> +    CPU_COMMON
>> +} CPUTLState;
> 
> Which means you need another entry here for the PC.
> 
>> +static inline void cpu_get_tb_cpu_state(CPUTLState *env, target_ulong *pc,
>> +                                        target_ulong *cs_base, int *flags)
>> +{
>> +    *pc = env->regs[TILEGX_R_PC];
> 
> And you should not reference the link register here.
> 
> 

OK, thanks. What you said sound reasonable to me. I shall send patch v3
if no any additiona reply for patch v2 within 3 days (2015-02-20).

And excuse me, I still want to know, is there a real world register as a
PC register for tile (e.g. just like 'rip' for x86_64) which can be used
by software programer? (is it in SPR?)

Thanks.
Chris Metcalf Feb. 17, 2015, 12:28 a.m. UTC | #3
On 2/16/2015 5:51 PM, Chen Gang S wrote:

> And excuse me, I still want to know, is there a real world register as a
> PC register for tile (e.g. just like 'rip' for x86_64) which can be used
> by software programer? (is it in SPR?)

There is no register you can read that holds the current PC.  You can
issue a "lnk REG" instruction to load the address of the following register
into register REG.  And if you have interrupted the machine execution
with an interrupt or fault, you will find the interrupted address in an SPR.
But the current PC is not otherwise accessible.
Chen Gang Feb. 17, 2015, 2:05 a.m. UTC | #4
On 2/17/15 08:28, Chris Metcalf wrote:
> On 2/16/2015 5:51 PM, Chen Gang S wrote:
> 
>> And excuse me, I still want to know, is there a real world register as a
>> PC register for tile (e.g. just like 'rip' for x86_64) which can be used
>> by software programer? (is it in SPR?)
> 
> There is no register you can read that holds the current PC.  You can
> issue a "lnk REG" instruction to load the address of the following register
> into register REG.  And if you have interrupted the machine execution
> with an interrupt or fault, you will find the interrupted address in an SPR.
> But the current PC is not otherwise accessible.
> 

OK, thanks.
Richard Henderson Feb. 17, 2015, 2:15 a.m. UTC | #5
On 02/16/2015 02:51 PM, Chen Gang S wrote:
> And excuse me, I still want to know, is there a real world register as a
> PC register for tile (e.g. just like 'rip' for x86_64) which can be used
> by software programer? (is it in SPR?)

Do you actually have the manual for this chip?  If you're asking this question,
it sounds like you don't.  And if you don't have the manual, I don't see how
you plan to actually write this translator.


r~
Chen Gang Feb. 17, 2015, 2:59 a.m. UTC | #6
On 2/17/15 10:15, Richard Henderson wrote:
> On 02/16/2015 02:51 PM, Chen Gang S wrote:
>> And excuse me, I still want to know, is there a real world register as a
>> PC register for tile (e.g. just like 'rip' for x86_64) which can be used
>> by software programer? (is it in SPR?)
> 
> Do you actually have the manual for this chip?  If you're asking this question,
> it sounds like you don't.  And if you don't have the manual, I don't see how
> you plan to actually write this translator.
> 
> 

I have the related documents, but I can not find pc register, and I
originally misunderstood lr can be treated as pc. After I know we can
not treat lr as pc, so I want to consult about it for confirmation.

And at present, I have get the related confirmation for it, and I shall
continue next. :-)

Thanks.
Richard Henderson Feb. 17, 2015, 3:58 p.m. UTC | #7
On 02/16/2015 06:59 PM, Chen Gang S wrote:
> I have the related documents, but I can not find pc register, and I
> originally misunderstood lr can be treated as pc. After I know we can
> not treat lr as pc, so I want to consult about it for confirmation.

Section 3.4 Program Counter, concisely describes the register.


r~
Chen Gang Feb. 17, 2015, 11:10 p.m. UTC | #8
On 2/17/15 23:58, Richard Henderson wrote:
> On 02/16/2015 06:59 PM, Chen Gang S wrote:
>> I have the related documents, but I can not find pc register, and I
>> originally misunderstood lr can be treated as pc. After I know we can
>> not treat lr as pc, so I want to consult about it for confirmation.
> 
> Section 3.4 Program Counter, concisely describes the register.
> 

Yeah, thanks. But it does not say whether it can be seen by software
programmers or not (so I can not find pc register).

Excuse me, I have no any more experience for other architectures (only
know about x86), so after read Section 3.4, I originally misunderstood
lr is pc. When I know I can not see/find pc, I want to get confirmation.


Thanks.
diff mbox

Patch

diff --git a/configure b/configure
index 7ba4bcb..23aa8f6 100755
--- a/configure
+++ b/configure
@@ -5191,6 +5191,9 @@  case "$target_name" in
   s390x)
     gdb_xml_files="s390x-core64.xml s390-acr.xml s390-fpr.xml"
   ;;
+  tilegx)
+    TARGET_ARCH=tilegx
+  ;;
   unicore32)
   ;;
   xtensa|xtensaeb)
@@ -5363,6 +5366,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
   ;;
+  tilegx*)
+    echo "CONFIG_TILEGX_DIS=y"  >> $config_target_mak
+    echo "CONFIG_TILEGX_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/tilegx-linux-user.mak b/default-configs/tilegx-linux-user.mak
new file mode 100644
index 0000000..3e47493
--- /dev/null
+++ b/default-configs/tilegx-linux-user.mak
@@ -0,0 +1 @@ 
+# Default configuration for tilegx-linux-user
diff --git a/target-tilegx/Makefile.objs b/target-tilegx/Makefile.objs
new file mode 100644
index 0000000..dcf2fe4
--- /dev/null
+++ b/target-tilegx/Makefile.objs
@@ -0,0 +1 @@ 
+obj-y += cpu.o translate.o
diff --git a/target-tilegx/cpu-qom.h b/target-tilegx/cpu-qom.h
new file mode 100644
index 0000000..e15a8b8
--- /dev/null
+++ b/target-tilegx/cpu-qom.h
@@ -0,0 +1,72 @@ 
+/*
+ * QEMU Tilegx 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_TILEGX_CPU_QOM_H
+#define QEMU_TILEGX_CPU_QOM_H
+
+#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 Tilegx CPU model.
+ */
+typedef struct TilegxCPUClass {
+    /*< private >*/
+    CPUClass parent_class;
+    /*< public >*/
+
+    DeviceRealize parent_realize;
+    void (*parent_reset)(CPUState *cpu);
+} TilegxCPUClass;
+
+/**
+ * TilegxCPU:
+ * @env: #CPUTLState
+ *
+ * A Tilegx CPU.
+ */
+typedef struct TilegxCPU {
+    /*< private >*/
+    CPUState parent_obj;
+    uint64_t base_vectors;
+    /*< public >*/
+
+    CPUTLState env;
+} TilegxCPU;
+
+static inline TilegxCPU *tilegx_env_get_cpu(CPUTLState *env)
+{
+    return container_of(env, TilegxCPU, env);
+}
+
+#define ENV_GET_CPU(e) CPU(tilegx_env_get_cpu(e))
+
+#endif
diff --git a/target-tilegx/cpu.c b/target-tilegx/cpu.c
new file mode 100644
index 0000000..928d4a3
--- /dev/null
+++ b/target-tilegx/cpu.c
@@ -0,0 +1,159 @@ 
+/*
+ * QEMU Tilegx 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)
+{
+}
+
+static bool tilegx_cpu_has_work(CPUState *cs)
+{
+    return true;
+}
+
+static void tilegx_cpu_reset(CPUState *s)
+{
+    TilegxCPU *cpu = TILEGX_CPU(s);
+    TilegxCPUClass *mcc = TILEGX_CPU_GET_CLASS(cpu);
+    CPUTLState *env = &cpu->env;
+
+    mcc->parent_reset(s);
+
+    memset(env, 0, sizeof(CPUTLState));
+    tlb_flush(s, 1);
+}
+
+static void tilegx_cpu_realizefn(DeviceState *dev, Error **errp)
+{
+    CPUState *cs = CPU(dev);
+    TilegxCPUClass *mcc = TILEGX_CPU_GET_CLASS(dev);
+
+    cpu_reset(cs);
+    qemu_init_vcpu(cs);
+
+    mcc->parent_realize(dev, errp);
+}
+
+static void tilegx_tcg_init(void)
+{
+}
+
+static void tilegx_cpu_initfn(Object *obj)
+{
+    CPUState *cs = CPU(obj);
+    TilegxCPU *cpu = TILEGX_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;
+        tilegx_tcg_init();
+    }
+}
+
+static const VMStateDescription vmstate_tilegx_cpu = {
+    .name = "cpu",
+    .unmigratable = 1,
+};
+
+static Property tilegx_properties[] = {
+    DEFINE_PROP_UINT64("tilegx.base-vectors", TilegxCPU, base_vectors, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+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 *mcc = TILEGX_CPU_CLASS(oc);
+
+    mcc->parent_realize = dc->realize;
+    dc->realize = tilegx_cpu_realizefn;
+
+    mcc->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->dump_state = NULL;
+    cc->set_pc = tilegx_cpu_set_pc;
+    cc->gdb_read_register = NULL;
+    cc->gdb_write_register = NULL;
+    cc->handle_mmu_fault = tilegx_cpu_handle_mmu_fault;
+    dc->vmsd = &vmstate_tilegx_cpu;
+    dc->props = tilegx_properties;
+    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..5cacdc9
--- /dev/null
+++ b/target-tilegx/cpu.h
@@ -0,0 +1,84 @@ 
+/*
+ *  Tilegx 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 CPUTLState
+
+#include "exec/cpu-defs.h"
+#include "fpu/softfloat.h"
+
+/* Tilegx register alias */
+#define TILEGX_R_RE  0   /*  0 register, for function/syscall return value */
+#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_PC  55  /* LR register, pc pointer */
+
+typedef struct CPUTLState {
+    uint64_t regs[56];
+    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_tilegx_exec(CPUTLState *s);
+int cpu_tilegx_signal_handler(int host_signum, void *pinfo, void *puc);
+
+#define cpu_exec cpu_tilegx_exec
+#define cpu_gen_code cpu_tilegx_gen_code
+#define cpu_signal_handler cpu_tilegx_signal_handler
+
+TilegxCPU *cpu_tilegx_init(const char *cpu_model);
+
+static inline CPUTLState *cpu_init(const char *cpu_model)
+{
+    TilegxCPU *cpu = cpu_tilegx_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[TILEGX_R_PC];
+    *cs_base = 0;
+    *flags = 0;
+}
+
+#include "exec/exec-all.h"
+
+#endif
diff --git a/target-tilegx/helper.h b/target-tilegx/helper.h
new file mode 100644
index 0000000..e69de29
diff --git a/target-tilegx/translate.c b/target-tilegx/translate.c
new file mode 100644
index 0000000..5131fa7
--- /dev/null
+++ b/target-tilegx/translate.c
@@ -0,0 +1,54 @@ 
+/*
+ * QEMU Tilegx 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(TilegxCPU *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(tilegx_env_get_cpu(env), tb, false);
+}
+
+void gen_intermediate_code_pc(CPUTLState *env, struct TranslationBlock *tb)
+{
+    gen_intermediate_code_internal(tilegx_env_get_cpu(env), tb, true);
+}
+
+void restore_state_to_opc(CPUTLState *env, TranslationBlock *tb, int pc_pos)
+{
+}