On 30 May 2015 at 22:15, Chen Gang <xili_gchen_5...@hotmail.com> wrote: > It implements minimized cpu features for linux-user. > > Signed-off-by: Chen Gang <gang.chen.5...@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