qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 01/15] Openrisc: add target stub


From: Blue Swirl
Subject: Re: [Qemu-devel] [PATCH 01/15] Openrisc: add target stub
Date: Sat, 19 May 2012 08:51:06 +0000

On Thu, May 17, 2012 at 8:35 AM, Jia Liu <address@hidden> wrote:
> add the openrisc target stub and basic implementation.
>
> Signed-off-by: Jia Liu <address@hidden>
> ---
>  Makefile.target                  |    3 +
>  arch_init.c                      |    2 +
>  arch_init.h                      |    1 +
>  configure                        |    8 +-
>  cpu-exec.c                       |    2 +
>  default-configs/or32-softmmu.mak |    6 +
>  elf.h                            |    2 +
>  poison.h                         |    1 +
>  target-openrisc/cpu-qom.h        |   70 +++++++++
>  target-openrisc/cpu.c            |   74 ++++++++++
>  target-openrisc/cpu.h            |  299 
> ++++++++++++++++++++++++++++++++++++++
>  target-openrisc/helper.c         |   67 +++++++++
>  target-openrisc/helper.h         |   23 +++
>  target-openrisc/machine.c        |   76 ++++++++++
>  target-openrisc/mem.c            |   43 ++++++
>  target-openrisc/mem_helper.c     |   46 ++++++
>  target-openrisc/translate.c      |   90 ++++++++++++
>  17 files changed, 812 insertions(+), 1 deletion(-)
>  create mode 100644 default-configs/or32-softmmu.mak
>  create mode 100644 target-openrisc/cpu-qom.h
>  create mode 100644 target-openrisc/cpu.c
>  create mode 100644 target-openrisc/cpu.h
>  create mode 100644 target-openrisc/helper.c
>  create mode 100644 target-openrisc/helper.h
>  create mode 100644 target-openrisc/machine.c
>  create mode 100644 target-openrisc/mem.c
>  create mode 100644 target-openrisc/mem_helper.c
>  create mode 100644 target-openrisc/translate.c
>
> diff --git a/Makefile.target b/Makefile.target
> index 1582904..0ffb29c 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -83,9 +83,11 @@ libobj-$(CONFIG_TCG_INTERPRETER) += tci.o
>  libobj-y += fpu/softfloat.o
>  ifneq ($(TARGET_BASE_ARCH), sparc)
>  ifneq ($(TARGET_BASE_ARCH), alpha)
> +ifneq ($(TARGET_BASE_ARCH), openrisc)
>  libobj-y += op_helper.o
>  endif
>  endif
> +endif
>  libobj-y += helper.o
>  ifneq ($(TARGET_BASE_ARCH), ppc)
>  libobj-y += cpu.o
> @@ -99,6 +101,7 @@ endif
>  libobj-$(TARGET_SPARC) += int32_helper.o
>  libobj-$(TARGET_SPARC64) += int64_helper.o
>  libobj-$(TARGET_ALPHA) += int_helper.o fpu_helper.o sys_helper.o mem_helper.o
> +libobj-$(TARGET_OPENRISC) += mem.o mem_helper.o
>
>  libobj-y += disas.o
>  libobj-$(CONFIG_TCI_DIS) += tci-dis.o
> diff --git a/arch_init.c b/arch_init.c
> index 988adca..55b608d 100644
> --- a/arch_init.c
> +++ b/arch_init.c
> @@ -71,6 +71,8 @@ int graphic_depth = 15;
>  #define QEMU_ARCH QEMU_ARCH_MICROBLAZE
>  #elif defined(TARGET_MIPS)
>  #define QEMU_ARCH QEMU_ARCH_MIPS
> +#elif defined(TARGET_OPENRISC)
> +#define QEMU_ARCH QEMU_ARCH_OPENRISC
>  #elif defined(TARGET_PPC)
>  #define QEMU_ARCH QEMU_ARCH_PPC
>  #elif defined(TARGET_S390X)
> diff --git a/arch_init.h b/arch_init.h
> index c7cb94a..3dfea3b 100644
> --- a/arch_init.h
> +++ b/arch_init.h
> @@ -16,6 +16,7 @@ enum {
>     QEMU_ARCH_SH4 = 1024,
>     QEMU_ARCH_SPARC = 2048,
>     QEMU_ARCH_XTENSA = 4096,
> +    QEMU_ARCH_OPENRISC = 8192,
>  };
>
>  extern const uint32_t arch_type;
> diff --git a/configure b/configure
> index b55a792..63e2372 100755
> --- a/configure
> +++ b/configure
> @@ -924,6 +924,7 @@ mips-softmmu \
>  mipsel-softmmu \
>  mips64-softmmu \
>  mips64el-softmmu \
> +or32-softmmu \
>  ppc-softmmu \
>  ppcemb-softmmu \
>  ppc64-softmmu \
> @@ -3460,7 +3461,7 @@ target_arch2=`echo $target | cut -d '-' -f 1`
>  target_bigendian="no"
>
>  case "$target_arch2" in
> -  
> armeb|lm32|m68k|microblaze|mips|mipsn32|mips64|ppc|ppcemb|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus|xtensaeb)
> +  
> armeb|lm32|m68k|microblaze|mips|mipsn32|mips64|or32|ppc|ppcemb|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus|xtensaeb)
>   target_bigendian=yes
>   ;;
>  esac
> @@ -3588,6 +3589,11 @@ case "$target_arch2" in
>     target_phys_bits=64
>     target_long_alignment=8
>   ;;
> +  or32)
> +    TARGET_ARCH=openrisc
> +    TARGET_BASE_ARCH=openrisc
> +    target_phys_bits=32
> +  ;;
>   ppc)
>     gdb_xml_files="power-core.xml power-fpu.xml power-altivec.xml 
> power-spe.xml"
>     target_phys_bits=64
> diff --git a/cpu-exec.c b/cpu-exec.c
> index 0344cd5..ba10db1 100644
> --- a/cpu-exec.c
> +++ b/cpu-exec.c
> @@ -222,6 +222,7 @@ int cpu_exec(CPUArchState *env)
>  #elif defined(TARGET_LM32)
>  #elif defined(TARGET_MICROBLAZE)
>  #elif defined(TARGET_MIPS)
> +#elif defined(TARGET_OPENRISC)
>  #elif defined(TARGET_SH4)
>  #elif defined(TARGET_CRIS)
>  #elif defined(TARGET_S390X)
> @@ -620,6 +621,7 @@ int cpu_exec(CPUArchState *env)
>               | env->cc_dest | (env->cc_x << 4);
>  #elif defined(TARGET_MICROBLAZE)
>  #elif defined(TARGET_MIPS)
> +#elif defined(TARGET_OPENRISC)
>  #elif defined(TARGET_SH4)
>  #elif defined(TARGET_ALPHA)
>  #elif defined(TARGET_CRIS)
> diff --git a/default-configs/or32-softmmu.mak 
> b/default-configs/or32-softmmu.mak
> new file mode 100644
> index 0000000..7590eed
> --- /dev/null
> +++ b/default-configs/or32-softmmu.mak
> @@ -0,0 +1,6 @@
> +# Default configuration for or32-softmmu
> +
> +include pci.mak

Probably not needed?

> +CONFIG_SERIAL=y
> +CONFIG_NE2000_ISA=y
> +CONFIG_I8259=y
> diff --git a/elf.h b/elf.h
> index e1422b8..e65f4b9 100644
> --- a/elf.h
> +++ b/elf.h
> @@ -106,6 +106,8 @@ typedef int64_t  Elf64_Sxword;
>  #define EM_H8S          48      /* Hitachi H8S     */
>  #define EM_LATTICEMICO32 138    /* LatticeMico32 */
>
> +#define EM_OPENRISC     92        /* Opencores Openrisc */
> +
>  #define EM_UNICORE32    110     /* UniCore32 */
>
>  /*
> diff --git a/poison.h b/poison.h
> index d396f20..7d7b23b 100644
> --- a/poison.h
> +++ b/poison.h
> @@ -14,6 +14,7 @@
>  #pragma GCC poison TARGET_M68K
>  #pragma GCC poison TARGET_MIPS
>  #pragma GCC poison TARGET_MIPS64
> +#pragma GCC poison TARGET_OPENRISC
>  #pragma GCC poison TARGET_PPC
>  #pragma GCC poison TARGET_PPCEMB
>  #pragma GCC poison TARGET_PPC64
> diff --git a/target-openrisc/cpu-qom.h b/target-openrisc/cpu-qom.h
> new file mode 100644
> index 0000000..8c936df
> --- /dev/null
> +++ b/target-openrisc/cpu-qom.h
> @@ -0,0 +1,70 @@
> +/*
> + *  QEMU Openrisc CPU
> + *
> + *  Copyright (c) 2012 Jia Liu <address@hidden>
> + *
> + * 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
> + * 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/>.
> + */
> +
> +#ifndef QEMU_OPENRISC_CPU_QOM_H
> +#define QEMU_OPENRISC_CPU_QOM_H
> +
> +#include "qemu/cpu.h"
> +#include "cpu.h"
> +
> +#define TYPE_OPENRISC_CPU "or32"
> +
> +#define OPENRISC_CPU_CLASS(klass) \
> +    OBJECT_CLASS_CHECK(OPENRISCCPUClass, (klass), TYPE_OPENRISC_CPU)
> +#define OPENRISC_CPU(obj) \
> +    OBJECT_CHECK(OPENRISCCPU, (obj), TYPE_OPENRISC_CPU)
> +#define OPENRISC_CPU_GET_CLASS(obj) \
> +    OBJECT_GET_CLASS(OPENRISCCPUClass, (obj), TYPE_OPENRISC_CPU)
> +
> +/**
> + * OPENRISCCPUClass:
> + * @parent_reset: The parent class' reset handler.
> + *
> + * A Openrisc CPU model.
> + */
> +typedef struct OPENRISCCPUClass {
> +    /*< private >*/
> +    CPUClass parent_class;
> +    /*< public >*/
> +
> +    void (*parent_reset)(CPUState *cpu);
> +} OPENRISCCPUClass;
> +
> +/**
> + * OPENRISCCPU:
> + * @env: #CPUOPENRISCState
> + *
> + * A Openrisc CPU.
> + */
> +typedef struct OPENRISCCPU {
> +    /*< private >*/
> +    CPUState parent_obj;
> +    /*< public >*/
> +
> +    CPUOPENRISCState env;
> +} OPENRISCCPU;
> +
> +static inline OPENRISCCPU *openrisc_env_get_cpu(CPUOPENRISCState *env)
> +{
> +    return OPENRISC_CPU(container_of(env, OPENRISCCPU, env));
> +}
> +
> +#define ENV_GET_CPU(e) CPU(openrisc_env_get_cpu(e))
> +
> +#endif /* QEMU_OPENRISC_CPU_QOM_H */
> diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c
> new file mode 100644
> index 0000000..01e65a2
> --- /dev/null
> +++ b/target-openrisc/cpu.c
> @@ -0,0 +1,74 @@
> +/*
> + *  QEMU Openrisc CPU
> + *
> + *  Copyright (c) 2012 Jia Liu <address@hidden>
> + *
> + * 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
> + * 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/>.
> + */
> +
> +#include "cpu.h"
> +#include "cpu-qom.h"
> +#include "qemu-common.h"
> +
> +
> +/* CPUClass::reset() */
> +static void openrisc_cpu_reset(CPUState *s)
> +{
> +    OPENRISCCPU *cpu = OPENRISC_CPU(s);
> +    OPENRISCCPUClass *occ = OPENRISC_CPU_GET_CLASS(cpu);
> +    CPUOPENRISCState *env = &cpu->env;
> +
> +    occ->parent_reset(s);
> +
> +    openrisc_reset(env);
> +
> +}
> +
> +static void openrisc_cpu_initfn(Object *obj)
> +{
> +    OPENRISCCPU *cpu = OPENRISC_CPU(obj);
> +    CPUOPENRISCState *env = &cpu->env;
> +
> +    cpu_exec_init(env);
> +
> +    env->flags = 0;
> +
> +    cpu_reset(CPU(cpu));
> +}
> +
> +static void openrisc_cpu_class_init(ObjectClass *oc, void *data)
> +{
> +    OPENRISCCPUClass *occ = OPENRISC_CPU_CLASS(oc);
> +    CPUClass *cc = CPU_CLASS(oc);
> +
> +    occ->parent_reset = cc->reset;
> +    cc->reset = openrisc_cpu_reset;
> +}
> +
> +static const TypeInfo openrisc_cpu_type_info = {
> +    .name = TYPE_OPENRISC_CPU,
> +    .parent = TYPE_CPU,
> +    .instance_size = sizeof(OPENRISCCPU),
> +    .instance_init = openrisc_cpu_initfn,
> +    .abstract = false,
> +    .class_size = sizeof(OPENRISCCPUClass),
> +    .class_init = openrisc_cpu_class_init,
> +};
> +
> +static void openrisc_cpu_register_types(void)
> +{
> +    type_register_static(&openrisc_cpu_type_info);
> +}
> +
> +type_init(openrisc_cpu_register_types)
> diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h
> new file mode 100644
> index 0000000..11ea13c
> --- /dev/null
> +++ b/target-openrisc/cpu.h
> @@ -0,0 +1,299 @@
> +/*
> + *  Openrisc virtual CPU header.
> + *
> + *  Copyright (c) 2011-2012 Jia Liu <address@hidden>
> + *
> + * 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
> + * 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/>.
> + */
> +
> +#ifndef CPU_OPENRISC_H
> +#define CPU_OPENRISC_H
> +
> +#define TARGET_HAS_ICE 1
> +
> +#define ELF_MACHINE EM_OPENRISC
> +
> +#define CPUArchState struct CPUOPENRISCState
> +
> +#define TARGET_LONG_BITS 32
> +
> +#include "config.h"
> +#include "qemu-common.h"
> +#include "cpu-defs.h"
> +#include "softfloat.h"
> +
> +struct CPUOPENRISCState;
> +
> +#define NB_MMU_MODES 3
> +#define MMU_NOMMU_IDX   0
> +#define MMU_SUPERVISOR_IDX  1
> +#define MMU_USER_IDX    2
> +
> +#define TARGET_PAGE_BITS 13
> +
> +
> +#define TARGET_PHYS_ADDR_SPACE_BITS 32
> +#define TARGET_VIRT_ADDR_SPACE_BITS 32
> +
> +#define SET_FP_CAUSE(reg, v)    do {\
> +                                    (reg) = ((reg) & ~(0x3f << 12)) | \
> +                                            ((v & 0x3f) << 12);\
> +                                } while (0)
> +#define GET_FP_ENABLE(reg)       (((reg) >>  7) & 0x1f)
> +#define UPDATE_FP_FLAGS(reg, v)   do {\
> +                                      (reg) |= ((v & 0x1f) << 2);\
> +                                  } while (0)
> +
> +/* Internel flags, delay slot flag */
> +#define D_FLAG    1
> +
> +#define NR_IRQS  32
> +#define PIC_MASK 0xFFFFFFFF
> +
> +/* Verison Register */
> +#define SPR_VR       0x12000001
> +#define SPR_CPUCFGR  0x12000001
> +
> +/* Registers */
> +enum {
> +    R0 = 0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10,
> +    R11, R12, R13, R14, R15, R16, R17, R18, R19, R20,
> +    R21, R22, R23, R24, R25, R26, R27, R28, R29, R30,
> +    R31
> +};
> +
> +/* Register aliases */
> +enum {
> +    R_ZERO = R0,
> +    R_SP = R1,
> +    R_FP = R2,
> +    R_LR = R9,
> +    R_RV = R11,
> +    R_RVH = R12
> +};
> +
> +/* Exceptions indices */
> +enum {
> +    EXCP_RESET    = 0x1,
> +    EXCP_BUSERR   = 0x2,
> +    EXCP_DPF      = 0x3,
> +    EXCP_IPF      = 0x4,
> +    EXCP_TICK     = 0x5,
> +    EXCP_ALIGN    = 0x6,
> +    EXCP_ILLEGAL  = 0x7,
> +    EXCP_INT      = 0x8,
> +    EXCP_DTLBMISS = 0x9,
> +    EXCP_ITLBMISS = 0xa,
> +    EXCP_RANGE    = 0xb,
> +    EXCP_SYSCALL  = 0xc,
> +    EXCP_FPE      = 0xd,
> +    EXCP_TRAP     = 0xe,
> +    EXCP_NR,
> +};
> +
> +/* Supervisor register */
> +enum {
> +    SR_SM = 1,
> +    SR_TEE = (1<<1),
> +    SR_IEE = (1<<2),
> +    SR_DCE = (1<<3),
> +    SR_ICE = (1<<4),
> +    SR_DME = (1<<5),
> +    SR_IME = (1<<6),
> +    SR_LEE = (1<<7),
> +    SR_CE  = (1<<8),
> +    SR_F   = (1<<9),
> +    SR_CY  = (1<<10),
> +    SR_OV  = (1<<11),
> +    SR_OVE = (1<<12),
> +    SR_DSX = (1<<13),
> +    SR_EPH = (1<<14),
> +    SR_FO  = (1<<15),
> +    SR_SUMRA = (1<<16),
> +    SR_SCE = (1<<17),
> +};
> +
> +/* FPCSR register */
> +enum {
> +    FPCSR_FPEE = 1,
> +    FPCSR_RM = (3 << 1),
> +    FPCSR_OVF = (1 << 3),
> +    FPCSR_UNF = (1 << 4),
> +    FPCSR_SNF = (1 << 5),
> +    FPCSR_QNF = (1 << 6),
> +    FPCSR_ZF = (1 << 7),
> +    FPCSR_IXF = (1 << 8),
> +    FPCSR_IVF = (1 << 9),
> +    FPCSR_INF = (1 << 10),
> +    FPCSR_DZF = (1 << 11),
> +};
> +
> +/* TTMR bit */
> +enum {
> +    TTMR_TP = (0xfffffff),
> +    TTMR_IP = (1<<28),
> +    TTMR_IE = (1<<29),
> +    TTMR_M  = (3<<30),
> +};
> +
> +enum {
> +    DTLB_WAYS = 1,
> +    DTLB_SIZE = 64,
> +    DTLB_MASK = (DTLB_SIZE-1),
> +    ITLB_WAYS = 1,
> +    ITLB_SIZE = 64,
> +    ITLB_MASK = (ITLB_SIZE-1),
> +};
> +
> +/* TLB prot */
> +enum {
> +    URE = (1<<6),
> +    UWE = (1<<7),
> +    SRE = (1<<8),
> +    SWE = (1<<9),
> +
> +    SXE = (1<<6),
> +    UXE = (1<<7),
> +};
> +
> +typedef struct tlb_entry {
> +    uint32_t mr;
> +    uint32_t tr;
> +} tlb_entry;

TLBEntry

> +
> +typedef struct CPUOPENRISCState CPUOPENRISCState;
> +struct CPUOPENRISCState {
> +    target_ulong gpr[32];   /* General registers */
> +    uint32_t sr;            /* Supervisor register */
> +    target_ulong machi;     /* Multiply register  MACHI */
> +    target_ulong maclo;     /* Multiply register  MACLO */
> +    target_ulong fpmaddhi;  /* Multiply and add float register FPMADDHI */
> +    target_ulong fpmaddlo;  /* Multiply and add float register FPMADDLO */
> +    target_ulong epcr;      /* Exception PC register */
> +    target_ulong eear;      /* Exception EA register */
> +    uint32_t esr;           /* Exception supervisor register */
> +    void *irq[32];          /* Interrupt irq input */

CPU reset usually zeros all fields up to breakpoints field in
CPU_COMMON. Then these and the MMU function pointers below would be
broken, please move below CPU_COMMON.

> +    uint32_t fpcsr;         /* Float register */
> +    float_status fp_status;
> +    target_ulong pc;        /* Program counter */
> +    target_ulong npc;       /* Next PC */
> +    target_ulong ppc;       /* Prev PC */
> +    target_ulong jmp_pc;    /* Jump PC */
> +    uint32_t flags;
> +
> +    /* Branch. */
> +    uint32_t btaken;        /* the SR_F bit */
> +
> +#if !defined(CONFIG_USER_ONLY)
> +    /* MMU */
> +    tlb_entry(*itlb)[ITLB_SIZE], (*dtlb)[DTLB_SIZE];
> +    int (*map_address_code)(struct CPUOPENRISCState *env,
> +                            target_phys_addr_t *physical, int *prot,
> +                            target_ulong address, int rw);
> +    int (*map_address_data)(struct CPUOPENRISCState *env,
> +                            target_phys_addr_t *physical, int *prot,
> +                            target_ulong address, int rw);
> +
> +    /* Internal Timer */
> +    struct QEMUTimer *timer;
> +    uint32_t ttmr;          /* Timer tick mode register */
> +    uint32_t ttcr;          /* Timer tick count register */
> +
> +    uint32_t picmr;         /* Interrupt mask register */
> +    uint32_t picsr;         /* Interrupt contrl register*/
> +#endif
> +
> +    CPU_COMMON
> +};
> +
> +#include "cpu-qom.h"
> +
> +void cpu_openrisc_list(FILE *f, fprintf_function cpu_fprintf);
> +CPUOPENRISCState *cpu_openrisc_init(const char *cpu_model);
> +int cpu_openrisc_exec(CPUOPENRISCState *s);
> +void do_interrupt(CPUOPENRISCState *env);
> +int cpu_openrisc_signal_handler(int host_signum, void *pinfo, void *puc);
> +void openrisc_translate_init(void);
> +int cpu_openrisc_handle_mmu_fault(CPUOPENRISCState *env, target_ulong 
> address,
> +                                  int rw, int mmu_idx);
> +#define cpu_list cpu_openrisc_list
> +#define cpu_init cpu_openrisc_init
> +#define cpu_exec cpu_openrisc_exec
> +#define cpu_gen_code cpu_openrisc_gen_code
> +#define cpu_signal_handler cpu_openrisc_signal_handler
> +#define cpu_handle_mmu_fault cpu_openrisc_handle_mmu_fault
> +
> +void openrisc_reset(CPUOPENRISCState *env);
> +#if !defined(CONFIG_USER_ONLY)
> +void cpu_openrisc_store_count(CPUOPENRISCState *env, target_ulong count);
> +void cpu_openrisc_store_compare(CPUOPENRISCState *env, target_ulong value);
> +uint32_t cpu_openrisc_get_count(CPUOPENRISCState *env);
> +
> +void cpu_openrisc_pic_reset(CPUOPENRISCState *env);
> +void cpu_openrisc_store_picsr(CPUOPENRISCState *env, uint32_t value);
> +void cpu_openrisc_store_picmr(CPUOPENRISCState *env, uint32_t value);
> +
> +void openrisc_mmu_init(CPUOPENRISCState *env);
> +int get_phys_nommu(CPUOPENRISCState *env, target_phys_addr_t *physical,
> +                   int *prot, target_ulong address, int rw);
> +int get_phys_code(CPUOPENRISCState *env, target_phys_addr_t *physical,
> +                  int *prot, target_ulong address, int rw);
> +int get_phys_data(CPUOPENRISCState *env, target_phys_addr_t *physical,
> +                  int *prot, target_ulong address, int rw);
> +#endif
> +
> +#if defined(CONFIG_USER_ONLY)
> +static inline void cpu_clone_regs(CPUOPENRISCState *env, target_ulong newsp)
> +{
> +    if (newsp) {
> +        env->gpr[1] = newsp;
> +    }
> +    env->gpr[2] = 0;
> +}
> +#endif
> +
> +#include "cpu-all.h"
> +
> +static inline void cpu_get_tb_cpu_state(CPUOPENRISCState *env,
> +                                        target_ulong *pc,
> +                                        target_ulong *cs_base, int *flags)
> +{
> +    *pc = env->pc;
> +    *cs_base = 0;
> +    *flags = env->flags;

Maybe it's fixed in later patches, but this does not look correct, the
TB flags tell when the CPU mode is compatible with the previously
generated translated blocks. I'd expect only MMU enable/disable flags
to be included here (assuming that if MMU state changes, TBs are
flushed), supervisor flag also if the translator checks the status
during translation.

> +}
> +
> +static inline int cpu_mmu_index(CPUOPENRISCState *env)
> +{
> +    if (!(env->sr & SR_IME)) {
> +        return MMU_NOMMU_IDX;
> +    }
> +    return (env->sr & SR_SM) == 0 ? MMU_USER_IDX : MMU_SUPERVISOR_IDX;
> +}
> +
> +#define CPU_INTERRUPT_TIMER   CPU_INTERRUPT_TGT_INT_0
> +static inline bool cpu_has_work(CPUOPENRISCState *env)
> +{
> +    return env->interrupt_request & (CPU_INTERRUPT_HARD |
> +                                     CPU_INTERRUPT_TIMER);
> +}
> +
> +#include "exec-all.h"
> +
> +static inline void cpu_pc_from_tb(CPUOPENRISCState *env, TranslationBlock 
> *tb)
> +{
> +    env->pc = tb->pc;
> +}
> +
> +#endif /* CPU_OPENRISC_H */
> diff --git a/target-openrisc/helper.c b/target-openrisc/helper.c
> new file mode 100644
> index 0000000..dcb61c9
> --- /dev/null
> +++ b/target-openrisc/helper.c
> @@ -0,0 +1,67 @@
> +/*
> + * Openrisc helpers
> + *
> + *  Copyright (c) 2011-2012 Jia Liu <address@hidden>
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Library 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
> + * Library General Public License for more details.
> + *
> + * You should have received a copy of the GNU Library General Public
> + * License along with this library; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 
> USA
> + */
> +
> +#include "cpu.h"
> +#include "qemu-common.h"
> +#include "gdbstub.h"
> +#include "helper.h"
> +#include "host-utils.h"
> +#if !defined(CONFIG_USER_ONLY)
> +#include "hw/loader.h"

Trim?

> +#endif
> +
> +typedef struct {
> +    const char *name;
> +} OPENRISCDef;
> +
> +static const OPENRISCDef openrisc_defs[] = {
> +    {.name = "or1200",}
> +};
> +
> +void cpu_openrisc_list(FILE *f, fprintf_function cpu_fprintf)
> +{
> +    int i;
> +
> +    cpu_fprintf(f, "Available CPUs:\n");
> +    for (i = 0; i < ARRAY_SIZE(openrisc_defs); ++i) {
> +        cpu_fprintf(f, "  %s\n", openrisc_defs[i].name);
> +    }
> +}
> +
> +CPUOPENRISCState *cpu_openrisc_init(const char *cpu_model)
> +{
> +    CPUOPENRISCState *env;
> +    static int tcg_inited;
> +
> +    env = g_malloc0(sizeof(*env));
> +    memset(env, 0, sizeof(*env));
> +    cpu_exec_init(env);
> +    qemu_init_vcpu(env);
> +    if (!tcg_inited) {


To enable qtest, please add && tcg_enabled().

> +        tcg_inited = 1;
> +        openrisc_translate_init();
> +    }
> +
> +    return env;
> +}
> +
> +void do_interrupt(CPUOPENRISCState *env)
> +{
> +}
> diff --git a/target-openrisc/helper.h b/target-openrisc/helper.h
> new file mode 100644
> index 0000000..103d9b4
> --- /dev/null
> +++ b/target-openrisc/helper.h
> @@ -0,0 +1,23 @@
> +/*
> + * OpenRISC helper defines
> + *
> + *  Copyright (c) 2011-2012 Jia Liu <address@hidden>
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Library 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
> + * Library General Public License for more details.
> + *
> + * You should have received a copy of the GNU Library General Public
> + * License along with this library; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 
> USA
> + */
> +
> +#include "def-helper.h"
> +
> +#include "def-helper.h"
> diff --git a/target-openrisc/machine.c b/target-openrisc/machine.c
> new file mode 100644
> index 0000000..c7ac0ea
> --- /dev/null
> +++ b/target-openrisc/machine.c
> @@ -0,0 +1,76 @@
> +/*
> + *  Copyright (c) 2011-2012 Jia Liu <address@hidden>
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Library 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
> + * Library General Public License for more details.
> + *
> + * You should have received a copy of the GNU Library General Public
> + * License along with this library; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 
> USA
> + */
> +
> +#include "hw/hw.h"
> +#include "hw/boards.h"
> +#include "kvm.h"
> +
> +static const VMStateDescription vmstate_cpu = {
> +    .name = "cpu",
> +    .fields = (VMStateField[]) {
> +        VMSTATE_UINT32_ARRAY(gpr, CPUOPENRISCState, 32),
> +        VMSTATE_UINT32(sr, CPUOPENRISCState),
> +        VMSTATE_UINT32(epcr, CPUOPENRISCState),
> +        VMSTATE_UINT32(eear, CPUOPENRISCState),
> +        VMSTATE_UINT32(esr, CPUOPENRISCState),
> +        VMSTATE_UINT32(fpcsr, CPUOPENRISCState),
> +        VMSTATE_UINT32(pc, CPUOPENRISCState),
> +        VMSTATE_UINT32(npc, CPUOPENRISCState),
> +        VMSTATE_UINT32(ppc, CPUOPENRISCState),
> +        VMSTATE_END_OF_LIST()
> +    }
> +};
> +
> +void cpu_save(QEMUFile *f, void *opaque)
> +{
> +    CPUOPENRISCState *env = (CPUOPENRISCState *)opaque;
> +    unsigned int i;
> +
> +    for (i = 0; i < 32; i++) {
> +        qemu_put_betls(f, &env->gpr[i]);
> +    }
> +
> +    qemu_put_betls(f, &env->epcr);
> +    qemu_put_betls(f, &env->eear);
> +    qemu_put_betls(f, &env->esr);
> +
> +    qemu_put_betls(f, &env->sr);
> +    qemu_put_be32s(f, &env->pc);
> +    qemu_put_be32s(f, &env->fpcsr);
> +}
> +
> +int cpu_load(QEMUFile *f, void *opaque, int version_id)
> +{
> +    CPUOPENRISCState *env = (CPUOPENRISCState *)opaque;
> +    unsigned int i;
> +
> +    for (i = 0; i < 32; i++) {
> +        qemu_get_betls(f, &env->gpr[i]);
> +    }
> +
> +    qemu_get_betls(f, &env->epcr);
> +    qemu_get_betls(f, &env->eear);
> +    qemu_get_betls(f, &env->esr);
> +
> +    qemu_get_betls(f, &env->sr);
> +    qemu_get_betls(f, &env->pc);
> +    qemu_get_be32s(f, &env->fpcsr);
> +    tlb_flush(env, 1);
> +
> +    return 0;
> +}
> diff --git a/target-openrisc/mem.c b/target-openrisc/mem.c
> new file mode 100644
> index 0000000..57a0b1b
> --- /dev/null
> +++ b/target-openrisc/mem.c
> @@ -0,0 +1,43 @@
> +/*
> + *  Openrisc MMU.
> + *
> + *  Copyright (c) 2011-2012 Jia Liu <address@hidden>
> + *                          Zhizhou Zhang <address@hidden>
> + *
> + * 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
> + * 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/>.
> + */
> +
> +#include "cpu.h"
> +#include "qemu-common.h"
> +#include "gdbstub.h"
> +#include "helper.h"
> +#include "host-utils.h"
> +#if !defined(CONFIG_USER_ONLY)
> +#include "hw/loader.h"
> +#endif
> +
> +#if !defined(CONFIG_USER_ONLY)
> +target_phys_addr_t cpu_get_phys_page_debug(CPUOPENRISCState *env,
> +                                           target_ulong addr)
> +{
> +    return 0;
> +}
> +#endif
> +
> +void openrisc_reset(CPUOPENRISCState *env)
> +{
> +    env->pc = 0x100;
> +    env->sr = SR_FO | SR_SM;
> +    env->exception_index = -1;
> +}
> diff --git a/target-openrisc/mem_helper.c b/target-openrisc/mem_helper.c
> new file mode 100644
> index 0000000..a2d93c7
> --- /dev/null
> +++ b/target-openrisc/mem_helper.c
> @@ -0,0 +1,46 @@
> +/*
> + * OpenRISC mmu helper routines
> + *
> + *  Copyright (c) 2011-2012 Jia Liu <address@hidden>
> + *                          Zhizhou Zhang <address@hidden>
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Library 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
> + * Library General Public License for more details.
> + *
> + * You should have received a copy of the GNU Library General Public
> + * License along with this library; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 
> USA
> + */
> +
> +#include "cpu.h"
> +#include "dyngen-exec.h"

As I mention in the later patch, this makes AREG0 to be used for
CPUState (also HELPER_CFLAGS is not used to compile mem_helper.o).
Please avoid it, then you also need to adjust CONFIG_TCG_PASS_AREG0
case in configure.

> +#include "helper.h"
> +
> +#if !defined(CONFIG_USER_ONLY)
> +#include "softmmu_exec.h"
> +#define MMUSUFFIX _mmu
> +
> +#define SHIFT 0
> +#include "softmmu_template.h"
> +
> +#define SHIFT 1
> +#include "softmmu_template.h"
> +
> +#define SHIFT 2
> +#include "softmmu_template.h"
> +
> +#define SHIFT 3
> +#include "softmmu_template.h"
> +
> +void tlb_fill(CPUOPENRISCState *env1, target_ulong addr, int is_write,
> +              int mmu_idx, uintptr_t retaddr)
> +{
> +}
> +#endif
> diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
> new file mode 100644
> index 0000000..aae483a
> --- /dev/null
> +++ b/target-openrisc/translate.c
> @@ -0,0 +1,90 @@
> +/*
> + * Openrisc translation
> + *
> + *  Copyright (c) 2011-2012 Jia Liu <address@hidden>
> + *                          Feng Gao <address@hidden>
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Library 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
> + * Library General Public License for more details.
> + *
> + * You should have received a copy of the GNU Library General Public
> + * License along with this library; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 
> USA
> + */
> +
> +#include <stdarg.h>
> +#include <stdlib.h>
> +#include <stdio.h>
> +#include <string.h>
> +#include <inttypes.h>
> +#include <assert.h>
> +
> +#include "cpu.h"
> +#include "exec-all.h"
> +#include "disas.h"
> +#include "tcg-op.h"
> +#include "qemu-common.h"
> +#include "qemu-log.h"
> +#include "config.h"
> +
> +#include "helper.h"
> +#define GEN_HELPER 1
> +#include "helper.h"
> +
> +#define DISAS_OPENRISC 1
> +#if DISAS_OPENRISC
> +#  define LOG_DIS(...) do { } while (0)
> +#endif
> +
> +typedef struct DisasContext {
> +    CPUOPENRISCState *env;
> +    TranslationBlock *tb;
> +    target_ulong pc;
> +    target_ulong ppc, npc;
> +    uint32_t tb_flags;
> +    uint32_t is_jmp;
> +    uint32_t mem_idx;
> +    int singlestep_enabled;
> +    uint32_t delayed_branch;
> +} DisasContext;
> +
> +void openrisc_translate_init(void)
> +{
> +}
> +
> +static inline void gen_intermediate_code_internal(CPUOPENRISCState *env,
> +                                                  TranslationBlock *tb,
> +                                                  int search_pc)
> +{
> +}
> +
> +void gen_intermediate_code(CPUOPENRISCState *env, struct TranslationBlock 
> *tb)
> +{
> +    gen_intermediate_code_internal(env, tb, 0);
> +}
> +
> +void gen_intermediate_code_pc(CPUOPENRISCState *env,
> +                              struct TranslationBlock *tb)
> +{
> +    gen_intermediate_code_internal(env, tb, 1);
> +}
> +
> +void cpu_dump_state(CPUOPENRISCState *env, FILE *f,
> +                    fprintf_function cpu_fprintf,
> +                    int flags)
> +{
> +    cpu_fprintf(f, "PC=%08x\n", env->pc);
> +}
> +
> +void restore_state_to_opc(CPUOPENRISCState *env, TranslationBlock *tb,
> +                          int pc_pos)
> +{
> +    env->pc = gen_opc_pc[pc_pos];
> +}
> --
> 1.7.9.5
>
>



reply via email to

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