All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Andreas Färber" <afaerber@suse.de>
To: Mike Frysinger <vapier@gentoo.org>
Cc: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH 2/5] Blackfin: initial port
Date: Fri, 28 Jun 2013 16:24:13 +0200	[thread overview]
Message-ID: <51CD9C8D.90304@suse.de> (raw)
In-Reply-To: <1371453383-11484-1-git-send-email-vapier@gentoo.org>

Hi,

Am 17.06.2013 09:16, schrieb Mike Frysinger:
> diff --git a/target-bfin/cpu-qom.h b/target-bfin/cpu-qom.h
> new file mode 100644
> index 0000000..697797b
> --- /dev/null
> +++ b/target-bfin/cpu-qom.h

For a new target, a separate cpu-qom.h should be unnecessary - it has
become impossible to include it without cpu.h. Just inline it into cpu.h
and group CPUState vs. CPUBfinState stuff together there.

> @@ -0,0 +1,61 @@
> +/*
> + * QEMU Blackfin CPU
> + *
> + * Copyright 2007-2013 Mike Frysinger
> + * Copyright 2007-2011 Analog Devices, Inc.
> + *
> + * Licensed under the Lesser GPL 2 or later.
> + */
> +
> +#ifndef QEMU_BFIN_CPU_QOM_H
> +#define QEMU_BFIN_CPU_QOM_H
> +
> +#include "qom/cpu.h"
> +
> +#define TYPE_BFIN_CPU "bfin-cpu"
> +
> +#define BFIN_CPU_CLASS(klass) \
> +    OBJECT_CLASS_CHECK(BfinCPUClass, (klass), TYPE_BFIN_CPU)
> +#define BFIN_CPU(obj) \
> +    OBJECT_CHECK(BfinCPU, (obj), TYPE_BFIN_CPU)
> +#define BFIN_CPU_GET_CLASS(obj) \
> +    OBJECT_GET_CLASS(BfinCPUClass, (obj), TYPE_BFIN_CPU)
> +
> +/**
> + * BfinCPUClass:
> + * @parent_reset: The parent class' reset handler.
> + *
> + * An Bfin CPU model.
> + */
> +typedef struct BfinCPUClass {
> +    /*< private >*/
> +    CPUClass parent_class;
> +    /*< public >*/
> +
> +    void (*parent_reset)(CPUState *cpu);
> +} BfinCPUClass;
> +
> +/**
> + * BfinCPU:

QOM types should have verbose, readable names. Please use BlackfinCPU,
BlackfinCPUClass, TYPE_BLACKFIN_CPU.
By contrast, CPUBfinState, bfin_cpu_... and bfin-cpu are totally fine, I
guess.

> + * @env: #CPUArchState

Please don't use CPUArchState anywhere in bfin code except for the
#define CPUArchState CPUBfinState.

> + *
> + * An Bfin CPU.
> + */
> +typedef struct BfinCPU {
> +    /*< private >*/
> +    CPUState parent_obj;
> +    /*< public >*/
> +
> +    CPUArchState env;
> +} BfinCPU;
> +
> +static inline BfinCPU *bfin_env_get_cpu(CPUArchState *env)

CPUbfinState *env

> +{
> +    return BFIN_CPU(container_of(env, BfinCPU, env));

I've just posted a patch to drop these FOO_CPU() casts from all targets.
While there's no ACK yet, there was agreement on v1, so please just
return the container_of() here.

> +}
> +
> +#define ENV_GET_CPU(e) CPU(bfin_env_get_cpu(e))
> +
> +#define ENV_OFFSET offsetof(BfinCPU, env)
> +
> +#endif
> diff --git a/target-bfin/cpu.c b/target-bfin/cpu.c
> new file mode 100644
> index 0000000..871a1a1
> --- /dev/null
> +++ b/target-bfin/cpu.c
> @@ -0,0 +1,55 @@
> +/*
> + * QEMU Blackfin CPU
> + *
> + * Copyright 2007-2013 Mike Frysinger
> + * Copyright 2007-2011 Analog Devices, Inc.
> + *
> + * Licensed under the Lesser GPL 2 or later.
> + */
> +
> +#include "cpu.h"
> +#include "qemu-common.h"
> +
> +
> +/* CPUClass::reset() */
> +static void bfin_cpu_reset(CPUState *s)
> +{
> +    BfinCPU *cpu = BFIN_CPU(s);
> +    CPUArchState *env = &cpu->env;

CPUBfinState *

Missing memset(env, 0, offsetof(CPUBfinState, breakpoints)).

> +
> +    env->pc = 0xEF000000;
> +}
> +
> +static void bfin_cpu_initfn(Object *obj)
> +{
> +    CPUState *cs = CPU(obj);
> +    BfinCPU *cpu = BFIN_CPU(obj);
> +    CPUArchState *env = &cpu->env;
> +
> +    cs->env_ptr = env;
> +    cpu_exec_init(env);
> +}
> +
> +static void bfin_cpu_class_init(ObjectClass *oc, void *data)
> +{
> +    CPUClass *cc = CPU_CLASS(oc);
> +
> +    cc->reset = bfin_cpu_reset;
> +}
> +
> +static const TypeInfo bfin_cpu_type_info = {
> +    .name = TYPE_BFIN_CPU,
> +    .parent = TYPE_CPU,
> +    .instance_size = sizeof(BfinCPU),
> +    .instance_init = bfin_cpu_initfn,
> +    .abstract = false,
> +    .class_size = sizeof(BfinCPUClass),
> +    .class_init = bfin_cpu_class_init,
> +};
> +
> +static void bfin_cpu_register_types(void)
> +{
> +    type_register_static(&bfin_cpu_type_info);
> +}
> +
> +type_init(bfin_cpu_register_types)
> diff --git a/target-bfin/cpu.h b/target-bfin/cpu.h
> new file mode 100644
> index 0000000..d288197
> --- /dev/null
> +++ b/target-bfin/cpu.h
> @@ -0,0 +1,236 @@
> +/*
> + * Blackfin emulation
> + *
> + * Copyright 2007-2013 Mike Frysinger
> + * Copyright 2007-2011 Analog Devices, Inc.
> + *
> + * Licensed under the Lesser GPL 2 or later.
> + */
> +
> +#ifndef CPU_BFIN_H
> +#define CPU_BFIN_H
> +
> +struct DisasContext;
> +
> +#define TARGET_LONG_BITS 32
> +
> +#define ELF_MACHINE	EM_BLACKFIN
> +
> +#define CPUArchState struct CPUBfinState
> +
> +#include "config.h"
> +#include "qemu-common.h"
> +#include "exec/cpu-defs.h"
> +
> +#define TARGET_HAS_ICE 1
> +
> +#define EXCP_SYSCALL        0
> +#define EXCP_SOFT_BP        1
> +#define EXCP_STACK_OVERFLOW 3
> +#define EXCP_SINGLE_STEP    0x10
> +#define EXCP_TRACE_FULL     0x11
> +#define EXCP_UNDEF_INST     0x21
> +#define EXCP_ILL_INST       0x22
> +#define EXCP_DCPLB_VIOLATE  0x23
> +#define EXCP_DATA_MISALGIN  0x24
> +#define EXCP_UNRECOVERABLE  0x25
> +#define EXCP_DCPLB_MISS     0x26
> +#define EXCP_DCPLB_MULT     0x27
> +#define EXCP_EMU_WATCH      0x28
> +#define EXCP_MISALIG_INST   0x2a
> +#define EXCP_ICPLB_PROT     0x2b
> +#define EXCP_ICPLB_MISS     0x2c
> +#define EXCP_ICPLB_MULT     0x2d
> +#define EXCP_ILL_SUPV       0x2e
> +#define EXCP_ABORT          0x100
> +#define EXCP_DBGA           0x101
> +#define EXCP_OUTC           0x102
> +
> +#define CPU_INTERRUPT_NMI   CPU_INTERRUPT_TGT_EXT_1
> +
> +#define BFIN_L1_CACHE_BYTES 32
> +
> +/* Blackfin does 1K/4K/1M/4M, but for now only support 4k */
> +#define TARGET_PAGE_BITS    12
> +#define NB_MMU_MODES        2
> +
> +#define TARGET_PHYS_ADDR_SPACE_BITS 32
> +#define TARGET_VIRT_ADDR_SPACE_BITS 32
> +
> +#define cpu_init cpu_bfin_init
> +#define cpu_exec cpu_bfin_exec
> +#define cpu_gen_code cpu_bfin_gen_code
> +#define cpu_signal_handler cpu_bfin_signal_handler
> +
> +/* Indexes into astat array; matches bitpos in hardware too */
> +enum {
> +    ASTAT_AZ = 0,
> +    ASTAT_AN,
> +    ASTAT_AC0_COPY,
> +    ASTAT_V_COPY,
> +    ASTAT_CC = 5,
> +    ASTAT_AQ,
> +    ASTAT_RND_MOD = 8,
> +    ASTAT_AC0 = 12,
> +    ASTAT_AC1,
> +    ASTAT_AV0 = 16,
> +    ASTAT_AV0S,
> +    ASTAT_AV1,
> +    ASTAT_AV1S,
> +    ASTAT_V = 24,
> +    ASTAT_VS
> +};
> +
> +typedef struct CPUBfinState {
> +    CPU_COMMON
> +    int personality;
> +
> +    uint32_t dreg[8];
> +    uint32_t preg[8];
> +    uint32_t ireg[4];
> +    uint32_t mreg[4];
> +    uint32_t breg[4];
> +    uint32_t lreg[4];
> +    uint64_t areg[2];
> +    uint32_t rets;
> +    uint32_t lcreg[2], ltreg[2], lbreg[2];
> +    uint32_t cycles[2];
> +    uint32_t uspreg;
> +    uint32_t seqstat;
> +    uint32_t syscfg;
> +    uint32_t reti;
> +    uint32_t retx;
> +    uint32_t retn;
> +    uint32_t rete;
> +    uint32_t emudat;
> +    uint32_t pc;
> +
> +    /* ASTAT bits; broken up for speeeeeeeed */
> +    uint32_t astat[32];
> +    /* ASTAT delayed helpers */
> +    uint32_t astat_op, astat_arg[3];

Are you sure this field placement is what you want? Usually reset
memset()s all fields up to breakpoints (inside CPU_COMMON) so registers
are usually placed before CPU_COMMON.

Any field that is not a register accessed by TCG should rather be in
BlackfinCPU or BlackfinCPUClass - personality sounds like a candidate?

> +} CPUBfinState;
> +#define spreg preg[6]
> +#define fpreg preg[7]
> +
> +static inline uint32_t bfin_astat_read(CPUArchState *env)
> +{
> +    unsigned int i, ret;
> +
> +    ret = 0;
> +    for (i = 0; i < 32; ++i)
> +        ret |= (env->astat[i] << i);
> +
> +    return ret;
> +}
> +
> +static inline void bfin_astat_write(CPUArchState *env, uint32_t astat)
> +{
> +    unsigned int i;
> +    for (i = 0; i < 32; ++i)
> +        env->astat[i] = !!(astat & (1 << i));
> +}
> +
> +enum astat_ops {
> +    ASTAT_OP_NONE,
> +    ASTAT_OP_DYNAMIC,
> +    ASTAT_OP_ABS,
> +    ASTAT_OP_ABS_VECTOR,
> +    ASTAT_OP_ADD16,
> +    ASTAT_OP_ADD32,
> +    ASTAT_OP_ASHIFT16,
> +    ASTAT_OP_ASHIFT32,
> +    ASTAT_OP_COMPARE_SIGNED,
> +    ASTAT_OP_COMPARE_UNSIGNED,
> +    ASTAT_OP_LOGICAL,
> +    ASTAT_OP_LSHIFT16,
> +    ASTAT_OP_LSHIFT32,
> +    ASTAT_OP_LSHIFT_RT16,
> +    ASTAT_OP_LSHIFT_RT32,
> +    ASTAT_OP_MIN_MAX,
> +    ASTAT_OP_MIN_MAX_VECTOR,
> +    ASTAT_OP_NEGATE,
> +    ASTAT_OP_SUB16,
> +    ASTAT_OP_SUB32,
> +    ASTAT_OP_VECTOR_ADD_ADD,    /* +|+ */
> +    ASTAT_OP_VECTOR_ADD_SUB,    /* +|- */
> +    ASTAT_OP_VECTOR_SUB_SUB,    /* -|- */
> +    ASTAT_OP_VECTOR_SUB_ADD,    /* -|+ */
> +};
> +
> +typedef void (*hwloop_callback)(struct DisasContext *dc, int loop);
> +
> +typedef struct DisasContext {
> +    CPUArchState *env;
> +    struct TranslationBlock *tb;
> +    /* The current PC we're decoding (could be middle of parallel insn) */
> +    target_ulong pc;
> +    /* Length of current insn (2/4/8) */
> +    target_ulong insn_len;
> +
> +    /* For delayed ASTAT handling */
> +    enum astat_ops astat_op;
> +
> +    /* For hardware loop processing */
> +    hwloop_callback hwloop_callback;
> +    void *hwloop_data;
> +
> +    /* Was a DISALGNEXCPT used in this parallel insn ? */
> +    int disalgnexcpt;
> +
> +    int is_jmp;
> +    int mem_idx;
> +} DisasContext;
> +
> +void do_interrupt(CPUArchState *env);

do_interrupt() has recently been converted to a CPUClass hook.

> +CPUArchState *cpu_init(const char *cpu_model);
> +int cpu_exec(CPUArchState *s);
> +int cpu_bfin_signal_handler(int host_signum, void *pinfo, void *puc);
> +
> +extern const char * const greg_names[];
> +extern const char *get_allreg_name(int grp, int reg);
> +
> +#define MMU_KERNEL_IDX 0
> +#define MMU_USER_IDX   1
> +
> +int cpu_bfin_handle_mmu_fault(CPUArchState *env, target_ulong address, int rw,
> +                              int mmu_idx);
> +#define cpu_handle_mmu_fault cpu_bfin_handle_mmu_fault
> +
> +#if defined(CONFIG_USER_ONLY)
> +static inline void cpu_clone_regs(CPUArchState *env, target_ulong newsp)
> +{
> +    if (newsp)
> +        env->spreg = newsp;
> +}
> +#endif

Note there's a pending patch moving cpu_clone_regs() to
linux-user/*/target_cpu.h.

> +
> +#include "exec/cpu-all.h"
> +#include "cpu-qom.h"
> +
> +static inline bool cpu_has_work(CPUState *cpu)
> +{
> +    return (cpu->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI));
> +}
> +
> +#include "exec/exec-all.h"
> +
> +static inline void cpu_pc_from_tb(CPUArchState *env, TranslationBlock *tb)
> +{
> +    env->pc = tb->pc;
> +}
> +

> +static inline target_ulong cpu_get_pc(CPUArchState *env)
> +{
> +    return env->pc;
> +}

Unused?

> +
> +static inline void cpu_get_tb_cpu_state(CPUArchState *env, target_ulong *pc,
> +                                        target_ulong *cs_base, int *flags)
> +{
> +    *pc = cpu_get_pc(env);
> +    *cs_base = 0;
> +    *flags = env->astat[ASTAT_RND_MOD];
> +}
> +
> +#endif
[...]
> diff --git a/target-bfin/translate.c b/target-bfin/translate.c
> new file mode 100644
> index 0000000..a619f66
> --- /dev/null
> +++ b/target-bfin/translate.c
[...]
> +
> +CPUArchState *cpu_init(const char *cpu_model)
> +{
> +    BfinCPU *cpu;
> +    CPUArchState *env;
> +    static int tcg_initialized = 0;
> +
> +    cpu = BFIN_CPU(object_new(TYPE_BFIN_CPU));
> +    env = &cpu->env;
> +
> +    cpu_reset(CPU(cpu));
> +    qemu_init_vcpu(env);
> +
> +    if (tcg_initialized)
> +        return env;
> +
> +    tcg_initialized = 1;

Please place this into the CPU realizefn. Note that qemu_init_vcpu() is
being moved to generic code with my next pull.

In light of possible bfin-softmmu support, please turn this function
into BlackfinCPU *cpu_bfin_init(const char *cpu_model) and place
cpu_init() as a static inline compatibility wrapper into cpu.h.

> +
> +#define GEN_HELPER 2
> +#include "helper.h"
> +
> +    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
> +
> +    cpu_pc = tcg_global_mem_new(TCG_AREG0,
> +        offsetof(CPUArchState, pc), "PC");
> +    cpu_cc = tcg_global_mem_new(TCG_AREG0,
> +        offsetof(CPUArchState, astat[ASTAT_CC]), "CC");
> +
> +    /*cpu_astat_op = tcg_global_mem_new(TCG_AREG0,
> +        offsetof(CPUArchState, astat_op), "astat_op");*/
> +    cpu_astat_arg[0] = tcg_global_mem_new(TCG_AREG0,
> +        offsetof(CPUArchState, astat_arg[0]), "astat_arg[0]");
> +    cpu_astat_arg[1] = tcg_global_mem_new(TCG_AREG0,
> +        offsetof(CPUArchState, astat_arg[1]), "astat_arg[1]");
> +    cpu_astat_arg[2] = tcg_global_mem_new(TCG_AREG0,
> +        offsetof(CPUArchState, astat_arg[2]), "astat_arg[2]");
> +
> +    cpu_areg[0] = tcg_global_mem_new_i64(TCG_AREG0,
> +        offsetof(CPUArchState, areg[0]), "A0");
> +    cpu_areg[1] = tcg_global_mem_new_i64(TCG_AREG0,
> +        offsetof(CPUArchState, areg[1]), "A1");
> +
> +    bfin_tcg_new_set(dreg, 0);
> +    bfin_tcg_new_set(preg, 8);
> +    bfin_tcg_new_set(ireg, 16);
> +    bfin_tcg_new_set(mreg, 20);
> +    bfin_tcg_new_set(breg, 24);
> +    bfin_tcg_new_set(lreg, 28);
> +    bfin_tcg_new(rets, 39);
> +    bfin_tcg_new(lcreg[0], 48);
> +    bfin_tcg_new(ltreg[0], 49);
> +    bfin_tcg_new(lbreg[0], 50);
> +    bfin_tcg_new(lcreg[1], 51);
> +    bfin_tcg_new(ltreg[1], 52);
> +    bfin_tcg_new(lbreg[1], 53);
> +    bfin_tcg_new_set(cycles, 54);
> +    bfin_tcg_new(uspreg, 56);
> +    bfin_tcg_new(seqstat, 57);
> +    bfin_tcg_new(syscfg, 58);
> +    bfin_tcg_new(reti, 59);
> +    bfin_tcg_new(retx, 60);
> +    bfin_tcg_new(retn, 61);
> +    bfin_tcg_new(rete, 62);
> +    bfin_tcg_new(emudat, 63);
> +
> +    return env;
> +}
> +
> +#define _astat_printf(bit) cpu_fprintf(f, "%s" #bit " ", (env->astat[ASTAT_##bit] ? "" : "~"))
> +void cpu_dump_state(CPUArchState *env, FILE *f,
> +                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
> +                    int flags)
> +{

This will be converted to a CPUClass hook in my next pull.

[...]
> +static void
> +gen_intermediate_code_internal(CPUArchState *env, TranslationBlock *tb,
> +                               int search_pc)
> +{

Please use BlackfinCPU and bool arguments here, I am about to convert
all other targets (github.com/afaerber/qemu-cpu.git qom-cpu-11).

[...]
> +
> +void gen_intermediate_code(CPUArchState *env, struct TranslationBlock *tb)
> +{
> +    gen_intermediate_code_internal(env, tb, 0);
> +}
> +
> +void gen_intermediate_code_pc(CPUArchState *env, struct TranslationBlock *tb)
> +{
> +    gen_intermediate_code_internal(env, tb, 1);
> +}
> +
> +void restore_state_to_opc(CPUArchState *env, TranslationBlock *tb, int pc_pos)
> +{
> +    env->pc = tcg_ctx.gen_opc_pc[pc_pos];
> +}
> +
> +#include "bfin-sim.c"

Regards,
Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

      parent reply	other threads:[~2013-06-28 14:24 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-06-17  7:13 [Qemu-devel] [PATCH 0/5] Initial Blackfin support (linux-user only) Mike Frysinger
2013-06-17  7:13 ` [Qemu-devel] [PATCH 1/5] Blackfin: add disassembler support Mike Frysinger
2013-06-17  7:16 ` [Qemu-devel] [PATCH 2/5] Blackfin: initial port Mike Frysinger
2013-06-17  7:16   ` [Qemu-devel] [PATCH 3/5] Blackfin: add linux-user support Mike Frysinger
2013-06-17  7:16   ` [Qemu-devel] [PATCH 4/5] Blackfin: add test suite Mike Frysinger
2013-06-17  7:16   ` [Qemu-devel] [PATCH 5/5] linux-user: add support for Blackfin syscalls Mike Frysinger
2013-06-25 21:23   ` [Qemu-devel] [PATCH 2/5] Blackfin: initial port Richard Henderson
2013-06-25 23:14     ` Mike Frysinger
2013-06-28 13:47   ` Eric Blake
2013-06-28 14:24   ` Andreas Färber [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=51CD9C8D.90304@suse.de \
    --to=afaerber@suse.de \
    --cc=qemu-devel@nongnu.org \
    --cc=vapier@gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.