[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH 07/10 v11] target-tilegx: Add cpu basic features
From: |
Peter Maydell |
Subject: |
Re: [Qemu-devel] [PATCH 07/10 v11] target-tilegx: Add cpu basic features for linux-user |
Date: |
Tue, 2 Jun 2015 18:51:12 +0100 |
On 30 May 2015 at 22:15, Chen Gang <address@hidden> wrote:
> It implements minimized cpu features for linux-user.
>
> Signed-off-by: Chen Gang <address@hidden>
> ---
> 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
- Re: [Qemu-devel] [PATCH 07/10 v11] target-tilegx: Add cpu basic features for linux-user,
Peter Maydell <=