qemu-devel
[Top][All Lists]
Advanced

[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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]