Message ID | 1339981384-9117-2-git-send-email-proljc@gmail.com |
---|---|
State | New |
Headers | show |
On Mon, Jun 18, 2012 at 1:02 AM, Jia Liu <proljc@gmail.com> wrote: > Add OpenRISC target stubs and basic cpu support. > > Signed-off-by: Jia Liu <proljc@gmail.com> > --- > arch_init.c | 2 + > arch_init.h | 1 + > configure | 14 +- > cpu-exec.c | 2 + > default-configs/or32-softmmu.mak | 6 + > elf.h | 2 + > hw/openrisc/Makefile.objs | 3 + > hw/openrisc_cpudev.h | 29 ++++ > hw/openrisc_pic.c | 30 ++++ > hw/openrisc_timer.c | 30 ++++ > poison.h | 1 + > target-openrisc/Makefile.objs | 3 + > target-openrisc/cpu.c | 240 +++++++++++++++++++++++++++++++ > target-openrisc/cpu.h | 288 ++++++++++++++++++++++++++++++++++++++ > target-openrisc/intrpt.c | 30 ++++ > target-openrisc/machine.c | 30 ++++ > target-openrisc/mmu.c | 39 ++++++ > target-openrisc/mmu_helper.c | 43 ++++++ > target-openrisc/translate.c | 75 ++++++++++ > 19 files changed, 866 insertions(+), 2 deletions(-) > create mode 100644 default-configs/or32-softmmu.mak > create mode 100644 hw/openrisc/Makefile.objs > create mode 100644 hw/openrisc_cpudev.h > create mode 100644 hw/openrisc_pic.c > create mode 100644 hw/openrisc_timer.c > create mode 100644 target-openrisc/Makefile.objs > create mode 100644 target-openrisc/cpu.c > create mode 100644 target-openrisc/cpu.h > create mode 100644 target-openrisc/intrpt.c > create mode 100644 target-openrisc/machine.c > create mode 100644 target-openrisc/mmu.c > create mode 100644 target-openrisc/mmu_helper.c > create mode 100644 target-openrisc/translate.c > > diff --git a/arch_init.c b/arch_init.c > index a9e8b74..4b521e5 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 c2366ee..3ba7c91 100755 > --- a/configure > +++ b/configure > @@ -925,6 +925,7 @@ mips-softmmu \ > mipsel-softmmu \ > mips64-softmmu \ > mips64el-softmmu \ > +or32-softmmu \ > ppc-softmmu \ > ppcemb-softmmu \ > ppc64-softmmu \ > @@ -3482,7 +3483,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 > @@ -3598,6 +3599,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 > @@ -3676,7 +3682,7 @@ symlink "$source_path/Makefile.target" "$target_dir/Makefile" > > > case "$target_arch2" in > - alpha | sparc* | xtensa*) > + alpha | or32 | sparc* | xtensa*) > echo "CONFIG_TCG_PASS_AREG0=y" >> $config_target_mak > ;; > esac > @@ -3847,6 +3853,10 @@ for i in $ARCH $TARGET_BASE_ARCH ; do > echo "CONFIG_MIPS_DIS=y" >> $config_target_mak > echo "CONFIG_MIPS_DIS=y" >> $libdis_config_mak > ;; > + or32) > + echo "CONFIG_OPENRISC_DIS=y" >> $config_target_mak > + echo "CONFIG_OPENRISC_DIS=y" >> $libdis_config_mak > + ;; > ppc*) > echo "CONFIG_PPC_DIS=y" >> $config_target_mak > echo "CONFIG_PPC_DIS=y" >> $libdis_config_mak > diff --git a/cpu-exec.c b/cpu-exec.c > index 624c409..7d0d87b 100644 > --- a/cpu-exec.c > +++ b/cpu-exec.c > @@ -225,6 +225,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) > @@ -630,6 +631,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 > +CONFIG_SERIAL=y > +CONFIG_NE2000_ISA=y > +CONFIG_I8259=y > diff --git a/elf.h b/elf.h > index 9c9acfa..a21ea53 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/hw/openrisc/Makefile.objs b/hw/openrisc/Makefile.objs > new file mode 100644 > index 0000000..1c541a5 > --- /dev/null > +++ b/hw/openrisc/Makefile.objs > @@ -0,0 +1,3 @@ > +obj-y = openrisc_pic.o openrisc_timer.o > + > +obj-y := $(addprefix ../,$(obj-y)) > diff --git a/hw/openrisc_cpudev.h b/hw/openrisc_cpudev.h > new file mode 100644 > index 0000000..01bd422 > --- /dev/null > +++ b/hw/openrisc_cpudev.h > @@ -0,0 +1,29 @@ > +/* > + * QEMU OpenRISC CPU device support. > + * > + * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com> > + * > + * 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 HW_OPENRISC_CPUDEV_H > +#define HW_OPENRISC_CPUDEV_H > + > +/* openrisc_pic.c */ > +void cpu_openrisc_pic_init(CPUOpenRISCState *env); > + > +/* openrisc_timer.c*/ > +void cpu_openrisc_clock_init(CPUOpenRISCState *env); > + > +#endif > diff --git a/hw/openrisc_pic.c b/hw/openrisc_pic.c > new file mode 100644 > index 0000000..0d14bbe > --- /dev/null > +++ b/hw/openrisc_pic.c > @@ -0,0 +1,30 @@ > +/* > + * OpenRISC Programmable Interrupt Controller support. > + * > + * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com> > + * Feng Gao <gf91597@gmail.com> > + * > + * 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 "hw.h" > +#include "openrisc_cpudev.h" > +#include "cpu.h" > + > +/* Reset PIC */ > +void cpu_openrisc_pic_reset(CPUOpenRISCState *env) > +{ > + env->picmr = 0x00000000; > + env->picsr = 0x00000000; > +} > diff --git a/hw/openrisc_timer.c b/hw/openrisc_timer.c > new file mode 100644 > index 0000000..df384f6 > --- /dev/null > +++ b/hw/openrisc_timer.c > @@ -0,0 +1,30 @@ > +/* > + * QEMU OpenRISC timer support > + * > + * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com> > + * Zhizhou Zhang <etouzh@gmail.com> > + * > + * 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 "hw.h" > +#include "openrisc_cpudev.h" > +#include "qemu-timer.h" > + > +/* Reset Timer */ > +void cpu_openrisc_timer_reset(CPUOpenRISCState *env) > +{ > + env->ttmr = 0x00000000; > + env->ttcr = 0x00000000; > +} > 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/Makefile.objs b/target-openrisc/Makefile.objs > new file mode 100644 > index 0000000..21b76b2 > --- /dev/null > +++ b/target-openrisc/Makefile.objs > @@ -0,0 +1,3 @@ > +obj-$(CONFIG_SOFTMMU) += machine.o > +obj-y += cpu.o intrpt.o mmu.o translate.o > +obj-y += mmu_helper.o > diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c > new file mode 100644 > index 0000000..17cfe78 > --- /dev/null > +++ b/target-openrisc/cpu.c > @@ -0,0 +1,240 @@ > +/* > + * QEMU OpenRISC CPU > + * > + * Copyright (c) 2012 Jia Liu <proljc@gmail.com> > + * > + * 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" > +#if !defined(CONFIG_USER_ONLY) > +#include "hw/loader.h" > +#endif > + > +/* 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; > + > + if (qemu_loglevel_mask(CPU_LOG_RESET)) { > + qemu_log("CPU Reset (CPU %d)\n", env->cpu_index); > + log_cpu_state(env, 0); > + } > + > + occ->parent_reset(s); > + > + memset(env, 0, offsetof(CPUOpenRISCState, breakpoints)); > + > + tlb_flush(env, 1); > + /*tb_flush(env); FIXME: Do we need it? */ > + > + env->pc = 0x100; > + env->sr = SR_FO | SR_SM; > + env->exception_index = -1; > + > + env->upr = UPR_UP | UPR_DMP | UPR_IMP | UPR_PICP | UPR_TTP; > + env->cpucfgr = CPUCFGR_OB32S | CPUCFGR_OF32S; > + env->dmmucfgr = (DMMUCFGR_NTW & (0 << 2)) | (DMMUCFGR_NTS & (6 << 2)); > + env->immucfgr = (IMMUCFGR_NTW & (0 << 2)) | (IMMUCFGR_NTS & (6 << 2)); > + > +#if !defined(CONFIG_USER_ONLY) > + cpu_openrisc_timer_reset(env); > + cpu_openrisc_pic_reset(env); > +#endif > +} > + > +static inline int openrisc_feature(CPUOpenRISCState *env, int feature) > +{ > + return (env->feature & (1u << feature)) != 0; > +} > + > +static inline void set_feature(CPUOpenRISCState *env, int feature) > +{ > + env->feature |= 1u << feature; > +} > + > +void openrisc_cpu_realize(Object *obj, Error **errp) > +{ > + OpenRISCCPU *cpu = OPENRISC_CPU(obj); > + CPUOpenRISCState *env = &cpu->env; > + if (openrisc_feature(env, OPENRISC_FEATURE_OR1200)) { > + set_feature(env, OPENRISC_FEATURE_OB32S); > + set_feature(env, OPENRISC_FEATURE_OF32S); > + } > + > + qemu_init_vcpu(&cpu->env); > +} > + > +static void openrisc_cpu_initfn(Object *obj) > +{ > + OpenRISCCPU *cpu = OPENRISC_CPU(obj); > + cpu_exec_init(&cpu->env); > +} > + > +/* CPU models */ > +static void or1200_initfn(Object *obj) > +{ > + OpenRISCCPU *cpu = OPENRISC_CPU(obj); > + CPUOpenRISCState *env = &cpu->env; > + > + set_feature(env, OPENRISC_FEATURE_OR1200); > + > + cpu_reset(CPU(cpu)); > + > +} > + > +static void openrisc_any_initfn(Object *obj) > +{ > + OpenRISCCPU *cpu = OPENRISC_CPU(obj); > + CPUOpenRISCState *env = &cpu->env; > + > + set_feature(env, OPENRISC_FEATURE_OB32S); > + set_feature(env, OPENRISC_FEATURE_OF32S); > + > + cpu_reset(CPU(cpu)); > +} > + > +typedef struct OpenRISCCPUInfo { > + const char *name; > + void (*initfn)(Object *obj); > +} OpenRISCCPUInfo; > + > +static const OpenRISCCPUInfo openrisc_cpus[] = { > + { .name = "or1200", .initfn = or1200_initfn }, > + { .name = "any", .initfn = openrisc_any_initfn }, > +}; > + > +static void openrisc_cpu_class_init(ObjectClass *oc, void *data) > +{ > + OpenRISCCPUClass *occ = OPENRISC_CPU_CLASS(oc); > + CPUClass *cc = CPU_CLASS(occ); > + > + occ->parent_reset = cc->reset; > + cc->reset = openrisc_cpu_reset; > +} > + > +static void cpu_register(const OpenRISCCPUInfo *info) > +{ > + TypeInfo type_info = { > + .name = info->name, > + .parent = TYPE_OPENRISC_CPU, > + .instance_size = sizeof(OpenRISCCPU), > + .instance_init = info->initfn, > + .class_size = sizeof(OpenRISCCPUClass), > + }; > + > + type_register_static(&type_info); > +} > + > +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) > +{ > + int i; > + > + type_register_static(&openrisc_cpu_type_info); > + for (i = 0; i < ARRAY_SIZE(openrisc_cpus); i++) { > + cpu_register(&openrisc_cpus[i]); > + } > +} > + > +OpenRISCCPU *cpu_openrisc_init(const char *cpu_model) > +{ > + OpenRISCCPU *cpu; > + CPUOpenRISCState *env; > + static int inited; > + inited = 0; > + > + if (!object_class_by_name(cpu_model)) { > + return NULL; > + } > + cpu = OPENRISC_CPU(object_new(cpu_model)); > + env = &cpu->env; > + env->cpu_model_str = cpu_model; > + > + openrisc_cpu_realize(OBJECT(cpu), NULL); > + > +#if !defined(CONFIG_USER_ONLY) > + openrisc_mmu_init(env); > +#endif > + > + if (tcg_enabled() && !inited) { > + inited = 1; > + openrisc_translate_init(); > + } > + > + cpu_reset(CPU(cpu)); > + > + return cpu; > +} > + > +typedef struct OpenRISCCPUListState { > + fprintf_function cpu_fprintf; > + FILE *file; > +} OpenRISCCPUListState; > + > +/* Sort alphabetically by type name, except for "any". */ > +static gint openrisc_cpu_list_compare(gconstpointer a, gconstpointer b) > +{ > + ObjectClass *class_a = (ObjectClass *)a; > + ObjectClass *class_b = (ObjectClass *)b; > + const char *name_a, *name_b; > + > + name_a = object_class_get_name(class_a); > + name_b = object_class_get_name(class_b); > + if (strcmp(name_a, "any") == 0) { > + return 1; > + } else if (strcmp(name_b, "any") == 0) { > + return -1; > + } else { > + return strcmp(name_a, name_b); > + } > +} > + > +static void openrisc_cpu_list_entry(gpointer data, gpointer user_data) > +{ > + ObjectClass *oc = data; > + OpenRISCCPUListState *s = user_data; > + > + (*s->cpu_fprintf)(s->file, " %s\n", > + object_class_get_name(oc)); > +} > + > +void cpu_openrisc_list(FILE *f, fprintf_function cpu_fprintf) > +{ > + OpenRISCCPUListState s = { > + .file = f, > + .cpu_fprintf = cpu_fprintf, > + }; > + GSList *list; > + > + list = object_class_get_list(TYPE_OPENRISC_CPU, false); > + list = g_slist_sort(list, openrisc_cpu_list_compare); > + (*cpu_fprintf)(f, "Available CPUs:\n"); > + g_slist_foreach(list, openrisc_cpu_list_entry, &s); > + g_slist_free(list); > +} > + > +type_init(openrisc_cpu_register_types) > diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h > new file mode 100644 > index 0000000..9f9f4b5 > --- /dev/null > +++ b/target-openrisc/cpu.h > @@ -0,0 +1,288 @@ > +/* > + * OpenRISC virtual CPU header. > + * > + * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com> > + * > + * 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" > +#include "qemu/cpu.h" > +#include "error.h" > + > +struct CPUOpenRISCState; > + > +#define NB_MMU_MODES 3 > + > +#define TARGET_PAGE_BITS 13 > + > +#define TARGET_PHYS_ADDR_SPACE_BITS 32 > +#define TARGET_VIRT_ADDR_SPACE_BITS 32 > + > +/* Internel flags, delay slot flag */ > +#define D_FLAG 1 > + > +/* Verison Register */ > +#define SPR_VR 0xFFFF003F > + > +/* 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 > +}; > + > +/* Unit presece register */ > +enum { > + UPR_UP = (1 << 0), > + UPR_DCP = (1 << 1), > + UPR_ICP = (1 << 2), > + UPR_DMP = (1 << 3), > + UPR_IMP = (1 << 4), > + UPR_MP = (1 << 5), > + UPR_DUP = (1 << 6), > + UPR_PCUR = (1 << 7), > + UPR_PMP = (1 << 8), > + UPR_PICP = (1 << 9), > + UPR_TTP = (1 << 10), > + UPR_CUP = (255 << 24), > +}; > + > +/* CPU configure register */ > +enum { > + CPUCFGR_NSGF = (15 << 0), > + CPUCFGR_CGF = (1 << 4), > + CPUCFGR_OB32S = (1 << 5), > + CPUCFGR_OB64S = (1 << 6), > + CPUCFGR_OF32S = (1 << 7), > + CPUCFGR_OF64S = (1 << 8), > + CPUCFGR_OV64S = (1 << 9), > +}; > + > +/* DMMU configure register */ > +enum { > + DMMUCFGR_NTW = (3 << 0), > + DMMUCFGR_NTS = (7 << 2), > + DMMUCFGR_NAE = (7 << 5), > + DMMUCFGR_CRI = (1 << 8), > + DMMUCFGR_PRI = (1 << 9), > + DMMUCFGR_TEIRI = (1 << 10), > + DMMUCFGR_HTR = (1 << 11), > +}; > + > +/* IMMU configure register */ > +enum { > + IMMUCFGR_NTW = (3 << 0), > + IMMUCFGR_NTS = (7 << 2), > + IMMUCFGR_NAE = (7 << 5), > + IMMUCFGR_CRI = (1 << 8), > + IMMUCFGR_PRI = (1 << 9), > + IMMUCFGR_TEIRI = (1 << 10), > + IMMUCFGR_HTR = (1 << 11), > +}; > + > +/* 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), > +}; > + > +/* OpenRISC Hardware Capabilities */ > +enum { > + OPENRISC_FEATURE_NSGF, > + OPENRISC_FEATURE_CGF, > + OPENRISC_FEATURE_OB32S, > + OPENRISC_FEATURE_OB64S, > + OPENRISC_FEATURE_OF32S, > + OPENRISC_FEATURE_OF64S, > + OPENRISC_FEATURE_OV64S, > + OPENRISC_FEATURE_OR1200, > +}; > + > +typedef struct CPUOpenRISCState CPUOpenRISCState; > +struct CPUOpenRISCState { > + target_ulong gpr[32]; /* General registers */ > + target_ulong pc; /* Program counter */ > + target_ulong npc; /* Next PC */ > + target_ulong ppc; /* Prev PC */ > + target_ulong jmp_pc; /* Jump PC */ > + > + uint32_t sr; /* Supervisor register */ > + uint32_t vr; /* Version register */ > + uint32_t upr; /* Unit presence register */ > + uint32_t cpucfgr; /* CPU configure register */ > + uint32_t dmmucfgr; /* DMMU configure register */ > + uint32_t immucfgr; /* IMMU configure register */ > + uint32_t flags; /* cpu_flags, we only use it for exception > + in solt so far. */ > + uint32_t btaken; /* the SR_F bit */ > + > + CPU_COMMON > + > +#if !defined(CONFIG_USER_ONLY) > + 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 > + uint32_t feature; /* CPU Capabilities */ > +}; > + > +#define TYPE_OPENRISC_CPU "or32-cpu" > + > +#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)) > + > +void openrisc_cpu_realize(Object *obj, Error **errp); > + > +void cpu_openrisc_list(FILE *f, fprintf_function cpu_fprintf); > +OpenRISCCPU *cpu_openrisc_init(const char *cpu_model); > +int cpu_openrisc_exec(CPUOpenRISCState *s); > +void do_interrupt(CPUOpenRISCState *env); > +void openrisc_translate_init(void); > + > +#define cpu_list cpu_openrisc_list > +#define cpu_exec cpu_openrisc_exec > +#define cpu_gen_code cpu_openrisc_gen_code > + > +#define CPU_SAVE_VERSION 1 > + > +#if !defined(CONFIG_USER_ONLY) > +void cpu_openrisc_pic_reset(CPUOpenRISCState *env); > + > +void cpu_openrisc_timer_reset(CPUOpenRISCState *env); > + > +void openrisc_mmu_init(CPUOpenRISCState *env); > +#endif > + > +static inline CPUOpenRISCState *cpu_init(const char *cpu_model) > +{ > + OpenRISCCPU *cpu = cpu_openrisc_init(cpu_model); > + if (cpu) { > + return &cpu->env; > + } > + return NULL; > +} > + > +#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 = 0; > +} > + > +static inline int cpu_mmu_index(CPUOpenRISCState *env) > +{ > + return 0; > +} > + > +static inline bool cpu_has_work(CPUOpenRISCState *env) > +{ > + return true; > +} > + > +#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/intrpt.c b/target-openrisc/intrpt.c > new file mode 100644 > index 0000000..72ee402 > --- /dev/null > +++ b/target-openrisc/intrpt.c > @@ -0,0 +1,30 @@ > +/* > + * OpenRISC interrupt. > + * > + * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com> > + * > + * 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 "host-utils.h" > +#if !defined(CONFIG_USER_ONLY) > +#include "hw/loader.h" > +#endif > + > +void do_interrupt(CPUOpenRISCState *env) > +{ > +} > diff --git a/target-openrisc/machine.c b/target-openrisc/machine.c > new file mode 100644 > index 0000000..11bf275 > --- /dev/null > +++ b/target-openrisc/machine.c > @@ -0,0 +1,30 @@ > +/* > + * OpenRISC Machine > + * > + * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com> > + * > + * 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 "hw/hw.h" > +#include "hw/boards.h" > + > +void cpu_save(QEMUFile *f, void *opaque) > +{ > +} > + > +int cpu_load(QEMUFile *f, void *opaque, int version_id) > +{ > + return 0; > +} > diff --git a/target-openrisc/mmu.c b/target-openrisc/mmu.c > new file mode 100644 > index 0000000..20a1b5a > --- /dev/null > +++ b/target-openrisc/mmu.c > @@ -0,0 +1,39 @@ > +/* > + * OpenRISC MMU. > + * > + * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com> > + * Zhizhou Zhang <etouzh@gmail.com> > + * > + * 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 "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 addr; > +} > + > +void openrisc_mmu_init(CPUOpenRISCState *env) > +{ > +} > +#endif > diff --git a/target-openrisc/mmu_helper.c b/target-openrisc/mmu_helper.c > new file mode 100644 > index 0000000..43dd42f > --- /dev/null > +++ b/target-openrisc/mmu_helper.c > @@ -0,0 +1,43 @@ > +/* > + * OpenRISC MMU helper routines > + * > + * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com> > + * Zhizhou Zhang <etouzh@gmail.com> > + * > + * 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" > + > +#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 *env, target_ulong addr, int is_write, > + int mmu_idx, uintptr_t retaddr) > +{ > +} > +#endif Since there is no code for user emulator case, you could try to avoid compiling this file and also mmu.c if possible. This can be done later though. > diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c > new file mode 100644 > index 0000000..1d87d76 > --- /dev/null > +++ b/target-openrisc/translate.c > @@ -0,0 +1,75 @@ > +/* > + * OpenRISC translation > + * > + * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com> > + * Feng Gao <gf91597@gmail.com> > + * > + * 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 "exec-all.h" > +#include "disas.h" > +#include "tcg-op.h" > +#include "qemu-common.h" > +#include "qemu-log.h" > +#include "config.h" > + > +#define OPENRISC_DISAS > + > +#ifdef OPENRISC_DISAS > +# define LOG_DIS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__) > +#else > +# define LOG_DIS(...) do { } while (0) > +#endif > + > +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) > +{ > + int i; > + uint32_t *regs = env->gpr; > + cpu_fprintf(f, "PC=%08x\n", env->pc); > + for (i = 0; i < 32; ++i) { > + cpu_fprintf(f, "R%02d=%08x%c", i, regs[i], > + (i % 4) == 3 ? '\n' : ' '); > + } > +} > + > +void restore_state_to_opc(CPUOpenRISCState *env, TranslationBlock *tb, > + int pc_pos) > +{ > + env->pc = gen_opc_pc[pc_pos]; > +} > -- > 1.7.9.5 > >
Hi Blue, On Tue, Jun 19, 2012 at 2:28 AM, Blue Swirl <blauwirbel@gmail.com> wrote: > On Mon, Jun 18, 2012 at 1:02 AM, Jia Liu <proljc@gmail.com> wrote: >> Add OpenRISC target stubs and basic cpu support. >> >> Signed-off-by: Jia Liu <proljc@gmail.com> >> --- >> arch_init.c | 2 + >> arch_init.h | 1 + >> configure | 14 +- >> cpu-exec.c | 2 + >> default-configs/or32-softmmu.mak | 6 + >> elf.h | 2 + >> hw/openrisc/Makefile.objs | 3 + >> hw/openrisc_cpudev.h | 29 ++++ >> hw/openrisc_pic.c | 30 ++++ >> hw/openrisc_timer.c | 30 ++++ >> poison.h | 1 + >> target-openrisc/Makefile.objs | 3 + >> target-openrisc/cpu.c | 240 +++++++++++++++++++++++++++++++ >> target-openrisc/cpu.h | 288 ++++++++++++++++++++++++++++++++++++++ >> target-openrisc/intrpt.c | 30 ++++ >> target-openrisc/machine.c | 30 ++++ >> target-openrisc/mmu.c | 39 ++++++ >> target-openrisc/mmu_helper.c | 43 ++++++ >> target-openrisc/translate.c | 75 ++++++++++ >> 19 files changed, 866 insertions(+), 2 deletions(-) >> create mode 100644 default-configs/or32-softmmu.mak >> create mode 100644 hw/openrisc/Makefile.objs >> create mode 100644 hw/openrisc_cpudev.h >> create mode 100644 hw/openrisc_pic.c >> create mode 100644 hw/openrisc_timer.c >> create mode 100644 target-openrisc/Makefile.objs >> create mode 100644 target-openrisc/cpu.c >> create mode 100644 target-openrisc/cpu.h >> create mode 100644 target-openrisc/intrpt.c >> create mode 100644 target-openrisc/machine.c >> create mode 100644 target-openrisc/mmu.c >> create mode 100644 target-openrisc/mmu_helper.c >> create mode 100644 target-openrisc/translate.c >> >> diff --git a/arch_init.c b/arch_init.c >> index a9e8b74..4b521e5 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 c2366ee..3ba7c91 100755 >> --- a/configure >> +++ b/configure >> @@ -925,6 +925,7 @@ mips-softmmu \ >> mipsel-softmmu \ >> mips64-softmmu \ >> mips64el-softmmu \ >> +or32-softmmu \ >> ppc-softmmu \ >> ppcemb-softmmu \ >> ppc64-softmmu \ >> @@ -3482,7 +3483,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 >> @@ -3598,6 +3599,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 >> @@ -3676,7 +3682,7 @@ symlink "$source_path/Makefile.target" "$target_dir/Makefile" >> >> >> case "$target_arch2" in >> - alpha | sparc* | xtensa*) >> + alpha | or32 | sparc* | xtensa*) >> echo "CONFIG_TCG_PASS_AREG0=y" >> $config_target_mak >> ;; >> esac >> @@ -3847,6 +3853,10 @@ for i in $ARCH $TARGET_BASE_ARCH ; do >> echo "CONFIG_MIPS_DIS=y" >> $config_target_mak >> echo "CONFIG_MIPS_DIS=y" >> $libdis_config_mak >> ;; >> + or32) >> + echo "CONFIG_OPENRISC_DIS=y" >> $config_target_mak >> + echo "CONFIG_OPENRISC_DIS=y" >> $libdis_config_mak >> + ;; >> ppc*) >> echo "CONFIG_PPC_DIS=y" >> $config_target_mak >> echo "CONFIG_PPC_DIS=y" >> $libdis_config_mak >> diff --git a/cpu-exec.c b/cpu-exec.c >> index 624c409..7d0d87b 100644 >> --- a/cpu-exec.c >> +++ b/cpu-exec.c >> @@ -225,6 +225,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) >> @@ -630,6 +631,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 >> +CONFIG_SERIAL=y >> +CONFIG_NE2000_ISA=y >> +CONFIG_I8259=y >> diff --git a/elf.h b/elf.h >> index 9c9acfa..a21ea53 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/hw/openrisc/Makefile.objs b/hw/openrisc/Makefile.objs >> new file mode 100644 >> index 0000000..1c541a5 >> --- /dev/null >> +++ b/hw/openrisc/Makefile.objs >> @@ -0,0 +1,3 @@ >> +obj-y = openrisc_pic.o openrisc_timer.o >> + >> +obj-y := $(addprefix ../,$(obj-y)) >> diff --git a/hw/openrisc_cpudev.h b/hw/openrisc_cpudev.h >> new file mode 100644 >> index 0000000..01bd422 >> --- /dev/null >> +++ b/hw/openrisc_cpudev.h >> @@ -0,0 +1,29 @@ >> +/* >> + * QEMU OpenRISC CPU device support. >> + * >> + * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com> >> + * >> + * 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 HW_OPENRISC_CPUDEV_H >> +#define HW_OPENRISC_CPUDEV_H >> + >> +/* openrisc_pic.c */ >> +void cpu_openrisc_pic_init(CPUOpenRISCState *env); >> + >> +/* openrisc_timer.c*/ >> +void cpu_openrisc_clock_init(CPUOpenRISCState *env); >> + >> +#endif >> diff --git a/hw/openrisc_pic.c b/hw/openrisc_pic.c >> new file mode 100644 >> index 0000000..0d14bbe >> --- /dev/null >> +++ b/hw/openrisc_pic.c >> @@ -0,0 +1,30 @@ >> +/* >> + * OpenRISC Programmable Interrupt Controller support. >> + * >> + * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com> >> + * Feng Gao <gf91597@gmail.com> >> + * >> + * 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 "hw.h" >> +#include "openrisc_cpudev.h" >> +#include "cpu.h" >> + >> +/* Reset PIC */ >> +void cpu_openrisc_pic_reset(CPUOpenRISCState *env) >> +{ >> + env->picmr = 0x00000000; >> + env->picsr = 0x00000000; >> +} >> diff --git a/hw/openrisc_timer.c b/hw/openrisc_timer.c >> new file mode 100644 >> index 0000000..df384f6 >> --- /dev/null >> +++ b/hw/openrisc_timer.c >> @@ -0,0 +1,30 @@ >> +/* >> + * QEMU OpenRISC timer support >> + * >> + * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com> >> + * Zhizhou Zhang <etouzh@gmail.com> >> + * >> + * 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 "hw.h" >> +#include "openrisc_cpudev.h" >> +#include "qemu-timer.h" >> + >> +/* Reset Timer */ >> +void cpu_openrisc_timer_reset(CPUOpenRISCState *env) >> +{ >> + env->ttmr = 0x00000000; >> + env->ttcr = 0x00000000; >> +} >> 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/Makefile.objs b/target-openrisc/Makefile.objs >> new file mode 100644 >> index 0000000..21b76b2 >> --- /dev/null >> +++ b/target-openrisc/Makefile.objs >> @@ -0,0 +1,3 @@ >> +obj-$(CONFIG_SOFTMMU) += machine.o >> +obj-y += cpu.o intrpt.o mmu.o translate.o >> +obj-y += mmu_helper.o >> diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c >> new file mode 100644 >> index 0000000..17cfe78 >> --- /dev/null >> +++ b/target-openrisc/cpu.c >> @@ -0,0 +1,240 @@ >> +/* >> + * QEMU OpenRISC CPU >> + * >> + * Copyright (c) 2012 Jia Liu <proljc@gmail.com> >> + * >> + * 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" >> +#if !defined(CONFIG_USER_ONLY) >> +#include "hw/loader.h" >> +#endif >> + >> +/* 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; >> + >> + if (qemu_loglevel_mask(CPU_LOG_RESET)) { >> + qemu_log("CPU Reset (CPU %d)\n", env->cpu_index); >> + log_cpu_state(env, 0); >> + } >> + >> + occ->parent_reset(s); >> + >> + memset(env, 0, offsetof(CPUOpenRISCState, breakpoints)); >> + >> + tlb_flush(env, 1); >> + /*tb_flush(env); FIXME: Do we need it? */ >> + >> + env->pc = 0x100; >> + env->sr = SR_FO | SR_SM; >> + env->exception_index = -1; >> + >> + env->upr = UPR_UP | UPR_DMP | UPR_IMP | UPR_PICP | UPR_TTP; >> + env->cpucfgr = CPUCFGR_OB32S | CPUCFGR_OF32S; >> + env->dmmucfgr = (DMMUCFGR_NTW & (0 << 2)) | (DMMUCFGR_NTS & (6 << 2)); >> + env->immucfgr = (IMMUCFGR_NTW & (0 << 2)) | (IMMUCFGR_NTS & (6 << 2)); >> + >> +#if !defined(CONFIG_USER_ONLY) >> + cpu_openrisc_timer_reset(env); >> + cpu_openrisc_pic_reset(env); >> +#endif >> +} >> + >> +static inline int openrisc_feature(CPUOpenRISCState *env, int feature) >> +{ >> + return (env->feature & (1u << feature)) != 0; >> +} >> + >> +static inline void set_feature(CPUOpenRISCState *env, int feature) >> +{ >> + env->feature |= 1u << feature; >> +} >> + >> +void openrisc_cpu_realize(Object *obj, Error **errp) >> +{ >> + OpenRISCCPU *cpu = OPENRISC_CPU(obj); >> + CPUOpenRISCState *env = &cpu->env; >> + if (openrisc_feature(env, OPENRISC_FEATURE_OR1200)) { >> + set_feature(env, OPENRISC_FEATURE_OB32S); >> + set_feature(env, OPENRISC_FEATURE_OF32S); >> + } >> + >> + qemu_init_vcpu(&cpu->env); >> +} >> + >> +static void openrisc_cpu_initfn(Object *obj) >> +{ >> + OpenRISCCPU *cpu = OPENRISC_CPU(obj); >> + cpu_exec_init(&cpu->env); >> +} >> + >> +/* CPU models */ >> +static void or1200_initfn(Object *obj) >> +{ >> + OpenRISCCPU *cpu = OPENRISC_CPU(obj); >> + CPUOpenRISCState *env = &cpu->env; >> + >> + set_feature(env, OPENRISC_FEATURE_OR1200); >> + >> + cpu_reset(CPU(cpu)); >> + >> +} >> + >> +static void openrisc_any_initfn(Object *obj) >> +{ >> + OpenRISCCPU *cpu = OPENRISC_CPU(obj); >> + CPUOpenRISCState *env = &cpu->env; >> + >> + set_feature(env, OPENRISC_FEATURE_OB32S); >> + set_feature(env, OPENRISC_FEATURE_OF32S); >> + >> + cpu_reset(CPU(cpu)); >> +} >> + >> +typedef struct OpenRISCCPUInfo { >> + const char *name; >> + void (*initfn)(Object *obj); >> +} OpenRISCCPUInfo; >> + >> +static const OpenRISCCPUInfo openrisc_cpus[] = { >> + { .name = "or1200", .initfn = or1200_initfn }, >> + { .name = "any", .initfn = openrisc_any_initfn }, >> +}; >> + >> +static void openrisc_cpu_class_init(ObjectClass *oc, void *data) >> +{ >> + OpenRISCCPUClass *occ = OPENRISC_CPU_CLASS(oc); >> + CPUClass *cc = CPU_CLASS(occ); >> + >> + occ->parent_reset = cc->reset; >> + cc->reset = openrisc_cpu_reset; >> +} >> + >> +static void cpu_register(const OpenRISCCPUInfo *info) >> +{ >> + TypeInfo type_info = { >> + .name = info->name, >> + .parent = TYPE_OPENRISC_CPU, >> + .instance_size = sizeof(OpenRISCCPU), >> + .instance_init = info->initfn, >> + .class_size = sizeof(OpenRISCCPUClass), >> + }; >> + >> + type_register_static(&type_info); >> +} >> + >> +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) >> +{ >> + int i; >> + >> + type_register_static(&openrisc_cpu_type_info); >> + for (i = 0; i < ARRAY_SIZE(openrisc_cpus); i++) { >> + cpu_register(&openrisc_cpus[i]); >> + } >> +} >> + >> +OpenRISCCPU *cpu_openrisc_init(const char *cpu_model) >> +{ >> + OpenRISCCPU *cpu; >> + CPUOpenRISCState *env; >> + static int inited; >> + inited = 0; >> + >> + if (!object_class_by_name(cpu_model)) { >> + return NULL; >> + } >> + cpu = OPENRISC_CPU(object_new(cpu_model)); >> + env = &cpu->env; >> + env->cpu_model_str = cpu_model; >> + >> + openrisc_cpu_realize(OBJECT(cpu), NULL); >> + >> +#if !defined(CONFIG_USER_ONLY) >> + openrisc_mmu_init(env); >> +#endif >> + >> + if (tcg_enabled() && !inited) { >> + inited = 1; >> + openrisc_translate_init(); >> + } >> + >> + cpu_reset(CPU(cpu)); >> + >> + return cpu; >> +} >> + >> +typedef struct OpenRISCCPUListState { >> + fprintf_function cpu_fprintf; >> + FILE *file; >> +} OpenRISCCPUListState; >> + >> +/* Sort alphabetically by type name, except for "any". */ >> +static gint openrisc_cpu_list_compare(gconstpointer a, gconstpointer b) >> +{ >> + ObjectClass *class_a = (ObjectClass *)a; >> + ObjectClass *class_b = (ObjectClass *)b; >> + const char *name_a, *name_b; >> + >> + name_a = object_class_get_name(class_a); >> + name_b = object_class_get_name(class_b); >> + if (strcmp(name_a, "any") == 0) { >> + return 1; >> + } else if (strcmp(name_b, "any") == 0) { >> + return -1; >> + } else { >> + return strcmp(name_a, name_b); >> + } >> +} >> + >> +static void openrisc_cpu_list_entry(gpointer data, gpointer user_data) >> +{ >> + ObjectClass *oc = data; >> + OpenRISCCPUListState *s = user_data; >> + >> + (*s->cpu_fprintf)(s->file, " %s\n", >> + object_class_get_name(oc)); >> +} >> + >> +void cpu_openrisc_list(FILE *f, fprintf_function cpu_fprintf) >> +{ >> + OpenRISCCPUListState s = { >> + .file = f, >> + .cpu_fprintf = cpu_fprintf, >> + }; >> + GSList *list; >> + >> + list = object_class_get_list(TYPE_OPENRISC_CPU, false); >> + list = g_slist_sort(list, openrisc_cpu_list_compare); >> + (*cpu_fprintf)(f, "Available CPUs:\n"); >> + g_slist_foreach(list, openrisc_cpu_list_entry, &s); >> + g_slist_free(list); >> +} >> + >> +type_init(openrisc_cpu_register_types) >> diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h >> new file mode 100644 >> index 0000000..9f9f4b5 >> --- /dev/null >> +++ b/target-openrisc/cpu.h >> @@ -0,0 +1,288 @@ >> +/* >> + * OpenRISC virtual CPU header. >> + * >> + * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com> >> + * >> + * 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" >> +#include "qemu/cpu.h" >> +#include "error.h" >> + >> +struct CPUOpenRISCState; >> + >> +#define NB_MMU_MODES 3 >> + >> +#define TARGET_PAGE_BITS 13 >> + >> +#define TARGET_PHYS_ADDR_SPACE_BITS 32 >> +#define TARGET_VIRT_ADDR_SPACE_BITS 32 >> + >> +/* Internel flags, delay slot flag */ >> +#define D_FLAG 1 >> + >> +/* Verison Register */ >> +#define SPR_VR 0xFFFF003F >> + >> +/* 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 >> +}; >> + >> +/* Unit presece register */ >> +enum { >> + UPR_UP = (1 << 0), >> + UPR_DCP = (1 << 1), >> + UPR_ICP = (1 << 2), >> + UPR_DMP = (1 << 3), >> + UPR_IMP = (1 << 4), >> + UPR_MP = (1 << 5), >> + UPR_DUP = (1 << 6), >> + UPR_PCUR = (1 << 7), >> + UPR_PMP = (1 << 8), >> + UPR_PICP = (1 << 9), >> + UPR_TTP = (1 << 10), >> + UPR_CUP = (255 << 24), >> +}; >> + >> +/* CPU configure register */ >> +enum { >> + CPUCFGR_NSGF = (15 << 0), >> + CPUCFGR_CGF = (1 << 4), >> + CPUCFGR_OB32S = (1 << 5), >> + CPUCFGR_OB64S = (1 << 6), >> + CPUCFGR_OF32S = (1 << 7), >> + CPUCFGR_OF64S = (1 << 8), >> + CPUCFGR_OV64S = (1 << 9), >> +}; >> + >> +/* DMMU configure register */ >> +enum { >> + DMMUCFGR_NTW = (3 << 0), >> + DMMUCFGR_NTS = (7 << 2), >> + DMMUCFGR_NAE = (7 << 5), >> + DMMUCFGR_CRI = (1 << 8), >> + DMMUCFGR_PRI = (1 << 9), >> + DMMUCFGR_TEIRI = (1 << 10), >> + DMMUCFGR_HTR = (1 << 11), >> +}; >> + >> +/* IMMU configure register */ >> +enum { >> + IMMUCFGR_NTW = (3 << 0), >> + IMMUCFGR_NTS = (7 << 2), >> + IMMUCFGR_NAE = (7 << 5), >> + IMMUCFGR_CRI = (1 << 8), >> + IMMUCFGR_PRI = (1 << 9), >> + IMMUCFGR_TEIRI = (1 << 10), >> + IMMUCFGR_HTR = (1 << 11), >> +}; >> + >> +/* 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), >> +}; >> + >> +/* OpenRISC Hardware Capabilities */ >> +enum { >> + OPENRISC_FEATURE_NSGF, >> + OPENRISC_FEATURE_CGF, >> + OPENRISC_FEATURE_OB32S, >> + OPENRISC_FEATURE_OB64S, >> + OPENRISC_FEATURE_OF32S, >> + OPENRISC_FEATURE_OF64S, >> + OPENRISC_FEATURE_OV64S, >> + OPENRISC_FEATURE_OR1200, >> +}; >> + >> +typedef struct CPUOpenRISCState CPUOpenRISCState; >> +struct CPUOpenRISCState { >> + target_ulong gpr[32]; /* General registers */ >> + target_ulong pc; /* Program counter */ >> + target_ulong npc; /* Next PC */ >> + target_ulong ppc; /* Prev PC */ >> + target_ulong jmp_pc; /* Jump PC */ >> + >> + uint32_t sr; /* Supervisor register */ >> + uint32_t vr; /* Version register */ >> + uint32_t upr; /* Unit presence register */ >> + uint32_t cpucfgr; /* CPU configure register */ >> + uint32_t dmmucfgr; /* DMMU configure register */ >> + uint32_t immucfgr; /* IMMU configure register */ >> + uint32_t flags; /* cpu_flags, we only use it for exception >> + in solt so far. */ >> + uint32_t btaken; /* the SR_F bit */ >> + >> + CPU_COMMON >> + >> +#if !defined(CONFIG_USER_ONLY) >> + 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 >> + uint32_t feature; /* CPU Capabilities */ >> +}; >> + >> +#define TYPE_OPENRISC_CPU "or32-cpu" >> + >> +#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)) >> + >> +void openrisc_cpu_realize(Object *obj, Error **errp); >> + >> +void cpu_openrisc_list(FILE *f, fprintf_function cpu_fprintf); >> +OpenRISCCPU *cpu_openrisc_init(const char *cpu_model); >> +int cpu_openrisc_exec(CPUOpenRISCState *s); >> +void do_interrupt(CPUOpenRISCState *env); >> +void openrisc_translate_init(void); >> + >> +#define cpu_list cpu_openrisc_list >> +#define cpu_exec cpu_openrisc_exec >> +#define cpu_gen_code cpu_openrisc_gen_code >> + >> +#define CPU_SAVE_VERSION 1 >> + >> +#if !defined(CONFIG_USER_ONLY) >> +void cpu_openrisc_pic_reset(CPUOpenRISCState *env); >> + >> +void cpu_openrisc_timer_reset(CPUOpenRISCState *env); >> + >> +void openrisc_mmu_init(CPUOpenRISCState *env); >> +#endif >> + >> +static inline CPUOpenRISCState *cpu_init(const char *cpu_model) >> +{ >> + OpenRISCCPU *cpu = cpu_openrisc_init(cpu_model); >> + if (cpu) { >> + return &cpu->env; >> + } >> + return NULL; >> +} >> + >> +#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 = 0; >> +} >> + >> +static inline int cpu_mmu_index(CPUOpenRISCState *env) >> +{ >> + return 0; >> +} >> + >> +static inline bool cpu_has_work(CPUOpenRISCState *env) >> +{ >> + return true; >> +} >> + >> +#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/intrpt.c b/target-openrisc/intrpt.c >> new file mode 100644 >> index 0000000..72ee402 >> --- /dev/null >> +++ b/target-openrisc/intrpt.c >> @@ -0,0 +1,30 @@ >> +/* >> + * OpenRISC interrupt. >> + * >> + * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com> >> + * >> + * 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 "host-utils.h" >> +#if !defined(CONFIG_USER_ONLY) >> +#include "hw/loader.h" >> +#endif >> + >> +void do_interrupt(CPUOpenRISCState *env) >> +{ >> +} >> diff --git a/target-openrisc/machine.c b/target-openrisc/machine.c >> new file mode 100644 >> index 0000000..11bf275 >> --- /dev/null >> +++ b/target-openrisc/machine.c >> @@ -0,0 +1,30 @@ >> +/* >> + * OpenRISC Machine >> + * >> + * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com> >> + * >> + * 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 "hw/hw.h" >> +#include "hw/boards.h" >> + >> +void cpu_save(QEMUFile *f, void *opaque) >> +{ >> +} >> + >> +int cpu_load(QEMUFile *f, void *opaque, int version_id) >> +{ >> + return 0; >> +} >> diff --git a/target-openrisc/mmu.c b/target-openrisc/mmu.c >> new file mode 100644 >> index 0000000..20a1b5a >> --- /dev/null >> +++ b/target-openrisc/mmu.c >> @@ -0,0 +1,39 @@ >> +/* >> + * OpenRISC MMU. >> + * >> + * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com> >> + * Zhizhou Zhang <etouzh@gmail.com> >> + * >> + * 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 "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 addr; >> +} >> + >> +void openrisc_mmu_init(CPUOpenRISCState *env) >> +{ >> +} >> +#endif >> diff --git a/target-openrisc/mmu_helper.c b/target-openrisc/mmu_helper.c >> new file mode 100644 >> index 0000000..43dd42f >> --- /dev/null >> +++ b/target-openrisc/mmu_helper.c >> @@ -0,0 +1,43 @@ >> +/* >> + * OpenRISC MMU helper routines >> + * >> + * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com> >> + * Zhizhou Zhang <etouzh@gmail.com> >> + * >> + * 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" >> + >> +#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 *env, target_ulong addr, int is_write, >> + int mmu_idx, uintptr_t retaddr) >> +{ >> +} >> +#endif > > Since there is no code for user emulator case, you could try to avoid > compiling this file and also mmu.c if possible. This can be done later > though. > I've tried, but it need tlb_fill and cpu_get_phys_page_debug, so, I add the empty functions. >> diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c >> new file mode 100644 >> index 0000000..1d87d76 >> --- /dev/null >> +++ b/target-openrisc/translate.c >> @@ -0,0 +1,75 @@ >> +/* >> + * OpenRISC translation >> + * >> + * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com> >> + * Feng Gao <gf91597@gmail.com> >> + * >> + * 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 "exec-all.h" >> +#include "disas.h" >> +#include "tcg-op.h" >> +#include "qemu-common.h" >> +#include "qemu-log.h" >> +#include "config.h" >> + >> +#define OPENRISC_DISAS >> + >> +#ifdef OPENRISC_DISAS >> +# define LOG_DIS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__) >> +#else >> +# define LOG_DIS(...) do { } while (0) >> +#endif >> + >> +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) >> +{ >> + int i; >> + uint32_t *regs = env->gpr; >> + cpu_fprintf(f, "PC=%08x\n", env->pc); >> + for (i = 0; i < 32; ++i) { >> + cpu_fprintf(f, "R%02d=%08x%c", i, regs[i], >> + (i % 4) == 3 ? '\n' : ' '); >> + } >> +} >> + >> +void restore_state_to_opc(CPUOpenRISCState *env, TranslationBlock *tb, >> + int pc_pos) >> +{ >> + env->pc = gen_opc_pc[pc_pos]; >> +} >> -- >> 1.7.9.5 >> >> Regards, Jia.
On Wed, Jun 20, 2012 at 7:14 AM, Jia Liu <proljc@gmail.com> wrote: > Hi Blue, > > On Tue, Jun 19, 2012 at 2:28 AM, Blue Swirl <blauwirbel@gmail.com> wrote: >> On Mon, Jun 18, 2012 at 1:02 AM, Jia Liu <proljc@gmail.com> wrote: >>> Add OpenRISC target stubs and basic cpu support. >>> >>> Signed-off-by: Jia Liu <proljc@gmail.com> >>> --- >>> arch_init.c | 2 + >>> arch_init.h | 1 + >>> configure | 14 +- >>> cpu-exec.c | 2 + >>> default-configs/or32-softmmu.mak | 6 + >>> elf.h | 2 + >>> hw/openrisc/Makefile.objs | 3 + >>> hw/openrisc_cpudev.h | 29 ++++ >>> hw/openrisc_pic.c | 30 ++++ >>> hw/openrisc_timer.c | 30 ++++ >>> poison.h | 1 + >>> target-openrisc/Makefile.objs | 3 + >>> target-openrisc/cpu.c | 240 +++++++++++++++++++++++++++++++ >>> target-openrisc/cpu.h | 288 ++++++++++++++++++++++++++++++++++++++ >>> target-openrisc/intrpt.c | 30 ++++ >>> target-openrisc/machine.c | 30 ++++ >>> target-openrisc/mmu.c | 39 ++++++ >>> target-openrisc/mmu_helper.c | 43 ++++++ >>> target-openrisc/translate.c | 75 ++++++++++ >>> 19 files changed, 866 insertions(+), 2 deletions(-) >>> create mode 100644 default-configs/or32-softmmu.mak >>> create mode 100644 hw/openrisc/Makefile.objs >>> create mode 100644 hw/openrisc_cpudev.h >>> create mode 100644 hw/openrisc_pic.c >>> create mode 100644 hw/openrisc_timer.c >>> create mode 100644 target-openrisc/Makefile.objs >>> create mode 100644 target-openrisc/cpu.c >>> create mode 100644 target-openrisc/cpu.h >>> create mode 100644 target-openrisc/intrpt.c >>> create mode 100644 target-openrisc/machine.c >>> create mode 100644 target-openrisc/mmu.c >>> create mode 100644 target-openrisc/mmu_helper.c >>> create mode 100644 target-openrisc/translate.c >>> >>> diff --git a/arch_init.c b/arch_init.c >>> index a9e8b74..4b521e5 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 c2366ee..3ba7c91 100755 >>> --- a/configure >>> +++ b/configure >>> @@ -925,6 +925,7 @@ mips-softmmu \ >>> mipsel-softmmu \ >>> mips64-softmmu \ >>> mips64el-softmmu \ >>> +or32-softmmu \ >>> ppc-softmmu \ >>> ppcemb-softmmu \ >>> ppc64-softmmu \ >>> @@ -3482,7 +3483,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 >>> @@ -3598,6 +3599,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 >>> @@ -3676,7 +3682,7 @@ symlink "$source_path/Makefile.target" "$target_dir/Makefile" >>> >>> >>> case "$target_arch2" in >>> - alpha | sparc* | xtensa*) >>> + alpha | or32 | sparc* | xtensa*) >>> echo "CONFIG_TCG_PASS_AREG0=y" >> $config_target_mak >>> ;; >>> esac >>> @@ -3847,6 +3853,10 @@ for i in $ARCH $TARGET_BASE_ARCH ; do >>> echo "CONFIG_MIPS_DIS=y" >> $config_target_mak >>> echo "CONFIG_MIPS_DIS=y" >> $libdis_config_mak >>> ;; >>> + or32) >>> + echo "CONFIG_OPENRISC_DIS=y" >> $config_target_mak >>> + echo "CONFIG_OPENRISC_DIS=y" >> $libdis_config_mak >>> + ;; >>> ppc*) >>> echo "CONFIG_PPC_DIS=y" >> $config_target_mak >>> echo "CONFIG_PPC_DIS=y" >> $libdis_config_mak >>> diff --git a/cpu-exec.c b/cpu-exec.c >>> index 624c409..7d0d87b 100644 >>> --- a/cpu-exec.c >>> +++ b/cpu-exec.c >>> @@ -225,6 +225,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) >>> @@ -630,6 +631,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 >>> +CONFIG_SERIAL=y >>> +CONFIG_NE2000_ISA=y >>> +CONFIG_I8259=y >>> diff --git a/elf.h b/elf.h >>> index 9c9acfa..a21ea53 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/hw/openrisc/Makefile.objs b/hw/openrisc/Makefile.objs >>> new file mode 100644 >>> index 0000000..1c541a5 >>> --- /dev/null >>> +++ b/hw/openrisc/Makefile.objs >>> @@ -0,0 +1,3 @@ >>> +obj-y = openrisc_pic.o openrisc_timer.o >>> + >>> +obj-y := $(addprefix ../,$(obj-y)) >>> diff --git a/hw/openrisc_cpudev.h b/hw/openrisc_cpudev.h >>> new file mode 100644 >>> index 0000000..01bd422 >>> --- /dev/null >>> +++ b/hw/openrisc_cpudev.h >>> @@ -0,0 +1,29 @@ >>> +/* >>> + * QEMU OpenRISC CPU device support. >>> + * >>> + * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com> >>> + * >>> + * 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 HW_OPENRISC_CPUDEV_H >>> +#define HW_OPENRISC_CPUDEV_H >>> + >>> +/* openrisc_pic.c */ >>> +void cpu_openrisc_pic_init(CPUOpenRISCState *env); >>> + >>> +/* openrisc_timer.c*/ >>> +void cpu_openrisc_clock_init(CPUOpenRISCState *env); >>> + >>> +#endif >>> diff --git a/hw/openrisc_pic.c b/hw/openrisc_pic.c >>> new file mode 100644 >>> index 0000000..0d14bbe >>> --- /dev/null >>> +++ b/hw/openrisc_pic.c >>> @@ -0,0 +1,30 @@ >>> +/* >>> + * OpenRISC Programmable Interrupt Controller support. >>> + * >>> + * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com> >>> + * Feng Gao <gf91597@gmail.com> >>> + * >>> + * 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 "hw.h" >>> +#include "openrisc_cpudev.h" >>> +#include "cpu.h" >>> + >>> +/* Reset PIC */ >>> +void cpu_openrisc_pic_reset(CPUOpenRISCState *env) >>> +{ >>> + env->picmr = 0x00000000; >>> + env->picsr = 0x00000000; >>> +} >>> diff --git a/hw/openrisc_timer.c b/hw/openrisc_timer.c >>> new file mode 100644 >>> index 0000000..df384f6 >>> --- /dev/null >>> +++ b/hw/openrisc_timer.c >>> @@ -0,0 +1,30 @@ >>> +/* >>> + * QEMU OpenRISC timer support >>> + * >>> + * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com> >>> + * Zhizhou Zhang <etouzh@gmail.com> >>> + * >>> + * 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 "hw.h" >>> +#include "openrisc_cpudev.h" >>> +#include "qemu-timer.h" >>> + >>> +/* Reset Timer */ >>> +void cpu_openrisc_timer_reset(CPUOpenRISCState *env) >>> +{ >>> + env->ttmr = 0x00000000; >>> + env->ttcr = 0x00000000; >>> +} >>> 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/Makefile.objs b/target-openrisc/Makefile.objs >>> new file mode 100644 >>> index 0000000..21b76b2 >>> --- /dev/null >>> +++ b/target-openrisc/Makefile.objs >>> @@ -0,0 +1,3 @@ >>> +obj-$(CONFIG_SOFTMMU) += machine.o >>> +obj-y += cpu.o intrpt.o mmu.o translate.o >>> +obj-y += mmu_helper.o >>> diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c >>> new file mode 100644 >>> index 0000000..17cfe78 >>> --- /dev/null >>> +++ b/target-openrisc/cpu.c >>> @@ -0,0 +1,240 @@ >>> +/* >>> + * QEMU OpenRISC CPU >>> + * >>> + * Copyright (c) 2012 Jia Liu <proljc@gmail.com> >>> + * >>> + * 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" >>> +#if !defined(CONFIG_USER_ONLY) >>> +#include "hw/loader.h" >>> +#endif >>> + >>> +/* 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; >>> + >>> + if (qemu_loglevel_mask(CPU_LOG_RESET)) { >>> + qemu_log("CPU Reset (CPU %d)\n", env->cpu_index); >>> + log_cpu_state(env, 0); >>> + } >>> + >>> + occ->parent_reset(s); >>> + >>> + memset(env, 0, offsetof(CPUOpenRISCState, breakpoints)); >>> + >>> + tlb_flush(env, 1); >>> + /*tb_flush(env); FIXME: Do we need it? */ >>> + >>> + env->pc = 0x100; >>> + env->sr = SR_FO | SR_SM; >>> + env->exception_index = -1; >>> + >>> + env->upr = UPR_UP | UPR_DMP | UPR_IMP | UPR_PICP | UPR_TTP; >>> + env->cpucfgr = CPUCFGR_OB32S | CPUCFGR_OF32S; >>> + env->dmmucfgr = (DMMUCFGR_NTW & (0 << 2)) | (DMMUCFGR_NTS & (6 << 2)); >>> + env->immucfgr = (IMMUCFGR_NTW & (0 << 2)) | (IMMUCFGR_NTS & (6 << 2)); >>> + >>> +#if !defined(CONFIG_USER_ONLY) >>> + cpu_openrisc_timer_reset(env); >>> + cpu_openrisc_pic_reset(env); >>> +#endif >>> +} >>> + >>> +static inline int openrisc_feature(CPUOpenRISCState *env, int feature) >>> +{ >>> + return (env->feature & (1u << feature)) != 0; >>> +} >>> + >>> +static inline void set_feature(CPUOpenRISCState *env, int feature) >>> +{ >>> + env->feature |= 1u << feature; >>> +} >>> + >>> +void openrisc_cpu_realize(Object *obj, Error **errp) >>> +{ >>> + OpenRISCCPU *cpu = OPENRISC_CPU(obj); >>> + CPUOpenRISCState *env = &cpu->env; >>> + if (openrisc_feature(env, OPENRISC_FEATURE_OR1200)) { >>> + set_feature(env, OPENRISC_FEATURE_OB32S); >>> + set_feature(env, OPENRISC_FEATURE_OF32S); >>> + } >>> + >>> + qemu_init_vcpu(&cpu->env); >>> +} >>> + >>> +static void openrisc_cpu_initfn(Object *obj) >>> +{ >>> + OpenRISCCPU *cpu = OPENRISC_CPU(obj); >>> + cpu_exec_init(&cpu->env); >>> +} >>> + >>> +/* CPU models */ >>> +static void or1200_initfn(Object *obj) >>> +{ >>> + OpenRISCCPU *cpu = OPENRISC_CPU(obj); >>> + CPUOpenRISCState *env = &cpu->env; >>> + >>> + set_feature(env, OPENRISC_FEATURE_OR1200); >>> + >>> + cpu_reset(CPU(cpu)); >>> + >>> +} >>> + >>> +static void openrisc_any_initfn(Object *obj) >>> +{ >>> + OpenRISCCPU *cpu = OPENRISC_CPU(obj); >>> + CPUOpenRISCState *env = &cpu->env; >>> + >>> + set_feature(env, OPENRISC_FEATURE_OB32S); >>> + set_feature(env, OPENRISC_FEATURE_OF32S); >>> + >>> + cpu_reset(CPU(cpu)); >>> +} >>> + >>> +typedef struct OpenRISCCPUInfo { >>> + const char *name; >>> + void (*initfn)(Object *obj); >>> +} OpenRISCCPUInfo; >>> + >>> +static const OpenRISCCPUInfo openrisc_cpus[] = { >>> + { .name = "or1200", .initfn = or1200_initfn }, >>> + { .name = "any", .initfn = openrisc_any_initfn }, >>> +}; >>> + >>> +static void openrisc_cpu_class_init(ObjectClass *oc, void *data) >>> +{ >>> + OpenRISCCPUClass *occ = OPENRISC_CPU_CLASS(oc); >>> + CPUClass *cc = CPU_CLASS(occ); >>> + >>> + occ->parent_reset = cc->reset; >>> + cc->reset = openrisc_cpu_reset; >>> +} >>> + >>> +static void cpu_register(const OpenRISCCPUInfo *info) >>> +{ >>> + TypeInfo type_info = { >>> + .name = info->name, >>> + .parent = TYPE_OPENRISC_CPU, >>> + .instance_size = sizeof(OpenRISCCPU), >>> + .instance_init = info->initfn, >>> + .class_size = sizeof(OpenRISCCPUClass), >>> + }; >>> + >>> + type_register_static(&type_info); >>> +} >>> + >>> +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) >>> +{ >>> + int i; >>> + >>> + type_register_static(&openrisc_cpu_type_info); >>> + for (i = 0; i < ARRAY_SIZE(openrisc_cpus); i++) { >>> + cpu_register(&openrisc_cpus[i]); >>> + } >>> +} >>> + >>> +OpenRISCCPU *cpu_openrisc_init(const char *cpu_model) >>> +{ >>> + OpenRISCCPU *cpu; >>> + CPUOpenRISCState *env; >>> + static int inited; >>> + inited = 0; >>> + >>> + if (!object_class_by_name(cpu_model)) { >>> + return NULL; >>> + } >>> + cpu = OPENRISC_CPU(object_new(cpu_model)); >>> + env = &cpu->env; >>> + env->cpu_model_str = cpu_model; >>> + >>> + openrisc_cpu_realize(OBJECT(cpu), NULL); >>> + >>> +#if !defined(CONFIG_USER_ONLY) >>> + openrisc_mmu_init(env); >>> +#endif >>> + >>> + if (tcg_enabled() && !inited) { >>> + inited = 1; >>> + openrisc_translate_init(); >>> + } >>> + >>> + cpu_reset(CPU(cpu)); >>> + >>> + return cpu; >>> +} >>> + >>> +typedef struct OpenRISCCPUListState { >>> + fprintf_function cpu_fprintf; >>> + FILE *file; >>> +} OpenRISCCPUListState; >>> + >>> +/* Sort alphabetically by type name, except for "any". */ >>> +static gint openrisc_cpu_list_compare(gconstpointer a, gconstpointer b) >>> +{ >>> + ObjectClass *class_a = (ObjectClass *)a; >>> + ObjectClass *class_b = (ObjectClass *)b; >>> + const char *name_a, *name_b; >>> + >>> + name_a = object_class_get_name(class_a); >>> + name_b = object_class_get_name(class_b); >>> + if (strcmp(name_a, "any") == 0) { >>> + return 1; >>> + } else if (strcmp(name_b, "any") == 0) { >>> + return -1; >>> + } else { >>> + return strcmp(name_a, name_b); >>> + } >>> +} >>> + >>> +static void openrisc_cpu_list_entry(gpointer data, gpointer user_data) >>> +{ >>> + ObjectClass *oc = data; >>> + OpenRISCCPUListState *s = user_data; >>> + >>> + (*s->cpu_fprintf)(s->file, " %s\n", >>> + object_class_get_name(oc)); >>> +} >>> + >>> +void cpu_openrisc_list(FILE *f, fprintf_function cpu_fprintf) >>> +{ >>> + OpenRISCCPUListState s = { >>> + .file = f, >>> + .cpu_fprintf = cpu_fprintf, >>> + }; >>> + GSList *list; >>> + >>> + list = object_class_get_list(TYPE_OPENRISC_CPU, false); >>> + list = g_slist_sort(list, openrisc_cpu_list_compare); >>> + (*cpu_fprintf)(f, "Available CPUs:\n"); >>> + g_slist_foreach(list, openrisc_cpu_list_entry, &s); >>> + g_slist_free(list); >>> +} >>> + >>> +type_init(openrisc_cpu_register_types) >>> diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h >>> new file mode 100644 >>> index 0000000..9f9f4b5 >>> --- /dev/null >>> +++ b/target-openrisc/cpu.h >>> @@ -0,0 +1,288 @@ >>> +/* >>> + * OpenRISC virtual CPU header. >>> + * >>> + * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com> >>> + * >>> + * 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" >>> +#include "qemu/cpu.h" >>> +#include "error.h" >>> + >>> +struct CPUOpenRISCState; >>> + >>> +#define NB_MMU_MODES 3 >>> + >>> +#define TARGET_PAGE_BITS 13 >>> + >>> +#define TARGET_PHYS_ADDR_SPACE_BITS 32 >>> +#define TARGET_VIRT_ADDR_SPACE_BITS 32 >>> + >>> +/* Internel flags, delay slot flag */ >>> +#define D_FLAG 1 >>> + >>> +/* Verison Register */ >>> +#define SPR_VR 0xFFFF003F >>> + >>> +/* 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 >>> +}; >>> + >>> +/* Unit presece register */ >>> +enum { >>> + UPR_UP = (1 << 0), >>> + UPR_DCP = (1 << 1), >>> + UPR_ICP = (1 << 2), >>> + UPR_DMP = (1 << 3), >>> + UPR_IMP = (1 << 4), >>> + UPR_MP = (1 << 5), >>> + UPR_DUP = (1 << 6), >>> + UPR_PCUR = (1 << 7), >>> + UPR_PMP = (1 << 8), >>> + UPR_PICP = (1 << 9), >>> + UPR_TTP = (1 << 10), >>> + UPR_CUP = (255 << 24), >>> +}; >>> + >>> +/* CPU configure register */ >>> +enum { >>> + CPUCFGR_NSGF = (15 << 0), >>> + CPUCFGR_CGF = (1 << 4), >>> + CPUCFGR_OB32S = (1 << 5), >>> + CPUCFGR_OB64S = (1 << 6), >>> + CPUCFGR_OF32S = (1 << 7), >>> + CPUCFGR_OF64S = (1 << 8), >>> + CPUCFGR_OV64S = (1 << 9), >>> +}; >>> + >>> +/* DMMU configure register */ >>> +enum { >>> + DMMUCFGR_NTW = (3 << 0), >>> + DMMUCFGR_NTS = (7 << 2), >>> + DMMUCFGR_NAE = (7 << 5), >>> + DMMUCFGR_CRI = (1 << 8), >>> + DMMUCFGR_PRI = (1 << 9), >>> + DMMUCFGR_TEIRI = (1 << 10), >>> + DMMUCFGR_HTR = (1 << 11), >>> +}; >>> + >>> +/* IMMU configure register */ >>> +enum { >>> + IMMUCFGR_NTW = (3 << 0), >>> + IMMUCFGR_NTS = (7 << 2), >>> + IMMUCFGR_NAE = (7 << 5), >>> + IMMUCFGR_CRI = (1 << 8), >>> + IMMUCFGR_PRI = (1 << 9), >>> + IMMUCFGR_TEIRI = (1 << 10), >>> + IMMUCFGR_HTR = (1 << 11), >>> +}; >>> + >>> +/* 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), >>> +}; >>> + >>> +/* OpenRISC Hardware Capabilities */ >>> +enum { >>> + OPENRISC_FEATURE_NSGF, >>> + OPENRISC_FEATURE_CGF, >>> + OPENRISC_FEATURE_OB32S, >>> + OPENRISC_FEATURE_OB64S, >>> + OPENRISC_FEATURE_OF32S, >>> + OPENRISC_FEATURE_OF64S, >>> + OPENRISC_FEATURE_OV64S, >>> + OPENRISC_FEATURE_OR1200, >>> +}; >>> + >>> +typedef struct CPUOpenRISCState CPUOpenRISCState; >>> +struct CPUOpenRISCState { >>> + target_ulong gpr[32]; /* General registers */ >>> + target_ulong pc; /* Program counter */ >>> + target_ulong npc; /* Next PC */ >>> + target_ulong ppc; /* Prev PC */ >>> + target_ulong jmp_pc; /* Jump PC */ >>> + >>> + uint32_t sr; /* Supervisor register */ >>> + uint32_t vr; /* Version register */ >>> + uint32_t upr; /* Unit presence register */ >>> + uint32_t cpucfgr; /* CPU configure register */ >>> + uint32_t dmmucfgr; /* DMMU configure register */ >>> + uint32_t immucfgr; /* IMMU configure register */ >>> + uint32_t flags; /* cpu_flags, we only use it for exception >>> + in solt so far. */ >>> + uint32_t btaken; /* the SR_F bit */ >>> + >>> + CPU_COMMON >>> + >>> +#if !defined(CONFIG_USER_ONLY) >>> + 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 >>> + uint32_t feature; /* CPU Capabilities */ >>> +}; >>> + >>> +#define TYPE_OPENRISC_CPU "or32-cpu" >>> + >>> +#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)) >>> + >>> +void openrisc_cpu_realize(Object *obj, Error **errp); >>> + >>> +void cpu_openrisc_list(FILE *f, fprintf_function cpu_fprintf); >>> +OpenRISCCPU *cpu_openrisc_init(const char *cpu_model); >>> +int cpu_openrisc_exec(CPUOpenRISCState *s); >>> +void do_interrupt(CPUOpenRISCState *env); >>> +void openrisc_translate_init(void); >>> + >>> +#define cpu_list cpu_openrisc_list >>> +#define cpu_exec cpu_openrisc_exec >>> +#define cpu_gen_code cpu_openrisc_gen_code >>> + >>> +#define CPU_SAVE_VERSION 1 >>> + >>> +#if !defined(CONFIG_USER_ONLY) >>> +void cpu_openrisc_pic_reset(CPUOpenRISCState *env); >>> + >>> +void cpu_openrisc_timer_reset(CPUOpenRISCState *env); >>> + >>> +void openrisc_mmu_init(CPUOpenRISCState *env); >>> +#endif >>> + >>> +static inline CPUOpenRISCState *cpu_init(const char *cpu_model) >>> +{ >>> + OpenRISCCPU *cpu = cpu_openrisc_init(cpu_model); >>> + if (cpu) { >>> + return &cpu->env; >>> + } >>> + return NULL; >>> +} >>> + >>> +#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 = 0; >>> +} >>> + >>> +static inline int cpu_mmu_index(CPUOpenRISCState *env) >>> +{ >>> + return 0; >>> +} >>> + >>> +static inline bool cpu_has_work(CPUOpenRISCState *env) >>> +{ >>> + return true; >>> +} >>> + >>> +#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/intrpt.c b/target-openrisc/intrpt.c >>> new file mode 100644 >>> index 0000000..72ee402 >>> --- /dev/null >>> +++ b/target-openrisc/intrpt.c >>> @@ -0,0 +1,30 @@ >>> +/* >>> + * OpenRISC interrupt. >>> + * >>> + * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com> >>> + * >>> + * 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 "host-utils.h" >>> +#if !defined(CONFIG_USER_ONLY) >>> +#include "hw/loader.h" >>> +#endif >>> + >>> +void do_interrupt(CPUOpenRISCState *env) >>> +{ >>> +} >>> diff --git a/target-openrisc/machine.c b/target-openrisc/machine.c >>> new file mode 100644 >>> index 0000000..11bf275 >>> --- /dev/null >>> +++ b/target-openrisc/machine.c >>> @@ -0,0 +1,30 @@ >>> +/* >>> + * OpenRISC Machine >>> + * >>> + * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com> >>> + * >>> + * 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 "hw/hw.h" >>> +#include "hw/boards.h" >>> + >>> +void cpu_save(QEMUFile *f, void *opaque) >>> +{ >>> +} >>> + >>> +int cpu_load(QEMUFile *f, void *opaque, int version_id) >>> +{ >>> + return 0; >>> +} >>> diff --git a/target-openrisc/mmu.c b/target-openrisc/mmu.c >>> new file mode 100644 >>> index 0000000..20a1b5a >>> --- /dev/null >>> +++ b/target-openrisc/mmu.c >>> @@ -0,0 +1,39 @@ >>> +/* >>> + * OpenRISC MMU. >>> + * >>> + * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com> >>> + * Zhizhou Zhang <etouzh@gmail.com> >>> + * >>> + * 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 "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 addr; >>> +} >>> + >>> +void openrisc_mmu_init(CPUOpenRISCState *env) >>> +{ >>> +} >>> +#endif >>> diff --git a/target-openrisc/mmu_helper.c b/target-openrisc/mmu_helper.c >>> new file mode 100644 >>> index 0000000..43dd42f >>> --- /dev/null >>> +++ b/target-openrisc/mmu_helper.c >>> @@ -0,0 +1,43 @@ >>> +/* >>> + * OpenRISC MMU helper routines >>> + * >>> + * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com> >>> + * Zhizhou Zhang <etouzh@gmail.com> >>> + * >>> + * 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" >>> + >>> +#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 *env, target_ulong addr, int is_write, >>> + int mmu_idx, uintptr_t retaddr) >>> +{ >>> +} >>> +#endif >> >> Since there is no code for user emulator case, you could try to avoid >> compiling this file and also mmu.c if possible. This can be done later >> though. >> > > I've tried, but it need tlb_fill and cpu_get_phys_page_debug, so, I > add the empty functions. I meant that in target-openrisc/Makefile.objs, move mmu_helper.o (maybe mmu.o if you can) to this line: +obj-$(CONFIG_SOFTMMU) += machine.o Then you can remove the #ifdeffery in mmu_helper.c, the file will not be compiled for CONFIG_USER_ONLY. This just speeds up compilation a bit. >>> diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c >>> new file mode 100644 >>> index 0000000..1d87d76 >>> --- /dev/null >>> +++ b/target-openrisc/translate.c >>> @@ -0,0 +1,75 @@ >>> +/* >>> + * OpenRISC translation >>> + * >>> + * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com> >>> + * Feng Gao <gf91597@gmail.com> >>> + * >>> + * 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 "exec-all.h" >>> +#include "disas.h" >>> +#include "tcg-op.h" >>> +#include "qemu-common.h" >>> +#include "qemu-log.h" >>> +#include "config.h" >>> + >>> +#define OPENRISC_DISAS >>> + >>> +#ifdef OPENRISC_DISAS >>> +# define LOG_DIS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__) >>> +#else >>> +# define LOG_DIS(...) do { } while (0) >>> +#endif >>> + >>> +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) >>> +{ >>> + int i; >>> + uint32_t *regs = env->gpr; >>> + cpu_fprintf(f, "PC=%08x\n", env->pc); >>> + for (i = 0; i < 32; ++i) { >>> + cpu_fprintf(f, "R%02d=%08x%c", i, regs[i], >>> + (i % 4) == 3 ? '\n' : ' '); >>> + } >>> +} >>> + >>> +void restore_state_to_opc(CPUOpenRISCState *env, TranslationBlock *tb, >>> + int pc_pos) >>> +{ >>> + env->pc = gen_opc_pc[pc_pos]; >>> +} >>> -- >>> 1.7.9.5 >>> >>> > > Regards, > Jia.
diff --git a/arch_init.c b/arch_init.c index a9e8b74..4b521e5 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 c2366ee..3ba7c91 100755 --- a/configure +++ b/configure @@ -925,6 +925,7 @@ mips-softmmu \ mipsel-softmmu \ mips64-softmmu \ mips64el-softmmu \ +or32-softmmu \ ppc-softmmu \ ppcemb-softmmu \ ppc64-softmmu \ @@ -3482,7 +3483,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 @@ -3598,6 +3599,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 @@ -3676,7 +3682,7 @@ symlink "$source_path/Makefile.target" "$target_dir/Makefile" case "$target_arch2" in - alpha | sparc* | xtensa*) + alpha | or32 | sparc* | xtensa*) echo "CONFIG_TCG_PASS_AREG0=y" >> $config_target_mak ;; esac @@ -3847,6 +3853,10 @@ for i in $ARCH $TARGET_BASE_ARCH ; do echo "CONFIG_MIPS_DIS=y" >> $config_target_mak echo "CONFIG_MIPS_DIS=y" >> $libdis_config_mak ;; + or32) + echo "CONFIG_OPENRISC_DIS=y" >> $config_target_mak + echo "CONFIG_OPENRISC_DIS=y" >> $libdis_config_mak + ;; ppc*) echo "CONFIG_PPC_DIS=y" >> $config_target_mak echo "CONFIG_PPC_DIS=y" >> $libdis_config_mak diff --git a/cpu-exec.c b/cpu-exec.c index 624c409..7d0d87b 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -225,6 +225,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) @@ -630,6 +631,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 +CONFIG_SERIAL=y +CONFIG_NE2000_ISA=y +CONFIG_I8259=y diff --git a/elf.h b/elf.h index 9c9acfa..a21ea53 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/hw/openrisc/Makefile.objs b/hw/openrisc/Makefile.objs new file mode 100644 index 0000000..1c541a5 --- /dev/null +++ b/hw/openrisc/Makefile.objs @@ -0,0 +1,3 @@ +obj-y = openrisc_pic.o openrisc_timer.o + +obj-y := $(addprefix ../,$(obj-y)) diff --git a/hw/openrisc_cpudev.h b/hw/openrisc_cpudev.h new file mode 100644 index 0000000..01bd422 --- /dev/null +++ b/hw/openrisc_cpudev.h @@ -0,0 +1,29 @@ +/* + * QEMU OpenRISC CPU device support. + * + * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com> + * + * 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 HW_OPENRISC_CPUDEV_H +#define HW_OPENRISC_CPUDEV_H + +/* openrisc_pic.c */ +void cpu_openrisc_pic_init(CPUOpenRISCState *env); + +/* openrisc_timer.c*/ +void cpu_openrisc_clock_init(CPUOpenRISCState *env); + +#endif diff --git a/hw/openrisc_pic.c b/hw/openrisc_pic.c new file mode 100644 index 0000000..0d14bbe --- /dev/null +++ b/hw/openrisc_pic.c @@ -0,0 +1,30 @@ +/* + * OpenRISC Programmable Interrupt Controller support. + * + * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com> + * Feng Gao <gf91597@gmail.com> + * + * 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 "hw.h" +#include "openrisc_cpudev.h" +#include "cpu.h" + +/* Reset PIC */ +void cpu_openrisc_pic_reset(CPUOpenRISCState *env) +{ + env->picmr = 0x00000000; + env->picsr = 0x00000000; +} diff --git a/hw/openrisc_timer.c b/hw/openrisc_timer.c new file mode 100644 index 0000000..df384f6 --- /dev/null +++ b/hw/openrisc_timer.c @@ -0,0 +1,30 @@ +/* + * QEMU OpenRISC timer support + * + * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com> + * Zhizhou Zhang <etouzh@gmail.com> + * + * 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 "hw.h" +#include "openrisc_cpudev.h" +#include "qemu-timer.h" + +/* Reset Timer */ +void cpu_openrisc_timer_reset(CPUOpenRISCState *env) +{ + env->ttmr = 0x00000000; + env->ttcr = 0x00000000; +} 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/Makefile.objs b/target-openrisc/Makefile.objs new file mode 100644 index 0000000..21b76b2 --- /dev/null +++ b/target-openrisc/Makefile.objs @@ -0,0 +1,3 @@ +obj-$(CONFIG_SOFTMMU) += machine.o +obj-y += cpu.o intrpt.o mmu.o translate.o +obj-y += mmu_helper.o diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c new file mode 100644 index 0000000..17cfe78 --- /dev/null +++ b/target-openrisc/cpu.c @@ -0,0 +1,240 @@ +/* + * QEMU OpenRISC CPU + * + * Copyright (c) 2012 Jia Liu <proljc@gmail.com> + * + * 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" +#if !defined(CONFIG_USER_ONLY) +#include "hw/loader.h" +#endif + +/* 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; + + if (qemu_loglevel_mask(CPU_LOG_RESET)) { + qemu_log("CPU Reset (CPU %d)\n", env->cpu_index); + log_cpu_state(env, 0); + } + + occ->parent_reset(s); + + memset(env, 0, offsetof(CPUOpenRISCState, breakpoints)); + + tlb_flush(env, 1); + /*tb_flush(env); FIXME: Do we need it? */ + + env->pc = 0x100; + env->sr = SR_FO | SR_SM; + env->exception_index = -1; + + env->upr = UPR_UP | UPR_DMP | UPR_IMP | UPR_PICP | UPR_TTP; + env->cpucfgr = CPUCFGR_OB32S | CPUCFGR_OF32S; + env->dmmucfgr = (DMMUCFGR_NTW & (0 << 2)) | (DMMUCFGR_NTS & (6 << 2)); + env->immucfgr = (IMMUCFGR_NTW & (0 << 2)) | (IMMUCFGR_NTS & (6 << 2)); + +#if !defined(CONFIG_USER_ONLY) + cpu_openrisc_timer_reset(env); + cpu_openrisc_pic_reset(env); +#endif +} + +static inline int openrisc_feature(CPUOpenRISCState *env, int feature) +{ + return (env->feature & (1u << feature)) != 0; +} + +static inline void set_feature(CPUOpenRISCState *env, int feature) +{ + env->feature |= 1u << feature; +} + +void openrisc_cpu_realize(Object *obj, Error **errp) +{ + OpenRISCCPU *cpu = OPENRISC_CPU(obj); + CPUOpenRISCState *env = &cpu->env; + if (openrisc_feature(env, OPENRISC_FEATURE_OR1200)) { + set_feature(env, OPENRISC_FEATURE_OB32S); + set_feature(env, OPENRISC_FEATURE_OF32S); + } + + qemu_init_vcpu(&cpu->env); +} + +static void openrisc_cpu_initfn(Object *obj) +{ + OpenRISCCPU *cpu = OPENRISC_CPU(obj); + cpu_exec_init(&cpu->env); +} + +/* CPU models */ +static void or1200_initfn(Object *obj) +{ + OpenRISCCPU *cpu = OPENRISC_CPU(obj); + CPUOpenRISCState *env = &cpu->env; + + set_feature(env, OPENRISC_FEATURE_OR1200); + + cpu_reset(CPU(cpu)); + +} + +static void openrisc_any_initfn(Object *obj) +{ + OpenRISCCPU *cpu = OPENRISC_CPU(obj); + CPUOpenRISCState *env = &cpu->env; + + set_feature(env, OPENRISC_FEATURE_OB32S); + set_feature(env, OPENRISC_FEATURE_OF32S); + + cpu_reset(CPU(cpu)); +} + +typedef struct OpenRISCCPUInfo { + const char *name; + void (*initfn)(Object *obj); +} OpenRISCCPUInfo; + +static const OpenRISCCPUInfo openrisc_cpus[] = { + { .name = "or1200", .initfn = or1200_initfn }, + { .name = "any", .initfn = openrisc_any_initfn }, +}; + +static void openrisc_cpu_class_init(ObjectClass *oc, void *data) +{ + OpenRISCCPUClass *occ = OPENRISC_CPU_CLASS(oc); + CPUClass *cc = CPU_CLASS(occ); + + occ->parent_reset = cc->reset; + cc->reset = openrisc_cpu_reset; +} + +static void cpu_register(const OpenRISCCPUInfo *info) +{ + TypeInfo type_info = { + .name = info->name, + .parent = TYPE_OPENRISC_CPU, + .instance_size = sizeof(OpenRISCCPU), + .instance_init = info->initfn, + .class_size = sizeof(OpenRISCCPUClass), + }; + + type_register_static(&type_info); +} + +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) +{ + int i; + + type_register_static(&openrisc_cpu_type_info); + for (i = 0; i < ARRAY_SIZE(openrisc_cpus); i++) { + cpu_register(&openrisc_cpus[i]); + } +} + +OpenRISCCPU *cpu_openrisc_init(const char *cpu_model) +{ + OpenRISCCPU *cpu; + CPUOpenRISCState *env; + static int inited; + inited = 0; + + if (!object_class_by_name(cpu_model)) { + return NULL; + } + cpu = OPENRISC_CPU(object_new(cpu_model)); + env = &cpu->env; + env->cpu_model_str = cpu_model; + + openrisc_cpu_realize(OBJECT(cpu), NULL); + +#if !defined(CONFIG_USER_ONLY) + openrisc_mmu_init(env); +#endif + + if (tcg_enabled() && !inited) { + inited = 1; + openrisc_translate_init(); + } + + cpu_reset(CPU(cpu)); + + return cpu; +} + +typedef struct OpenRISCCPUListState { + fprintf_function cpu_fprintf; + FILE *file; +} OpenRISCCPUListState; + +/* Sort alphabetically by type name, except for "any". */ +static gint openrisc_cpu_list_compare(gconstpointer a, gconstpointer b) +{ + ObjectClass *class_a = (ObjectClass *)a; + ObjectClass *class_b = (ObjectClass *)b; + const char *name_a, *name_b; + + name_a = object_class_get_name(class_a); + name_b = object_class_get_name(class_b); + if (strcmp(name_a, "any") == 0) { + return 1; + } else if (strcmp(name_b, "any") == 0) { + return -1; + } else { + return strcmp(name_a, name_b); + } +} + +static void openrisc_cpu_list_entry(gpointer data, gpointer user_data) +{ + ObjectClass *oc = data; + OpenRISCCPUListState *s = user_data; + + (*s->cpu_fprintf)(s->file, " %s\n", + object_class_get_name(oc)); +} + +void cpu_openrisc_list(FILE *f, fprintf_function cpu_fprintf) +{ + OpenRISCCPUListState s = { + .file = f, + .cpu_fprintf = cpu_fprintf, + }; + GSList *list; + + list = object_class_get_list(TYPE_OPENRISC_CPU, false); + list = g_slist_sort(list, openrisc_cpu_list_compare); + (*cpu_fprintf)(f, "Available CPUs:\n"); + g_slist_foreach(list, openrisc_cpu_list_entry, &s); + g_slist_free(list); +} + +type_init(openrisc_cpu_register_types) diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h new file mode 100644 index 0000000..9f9f4b5 --- /dev/null +++ b/target-openrisc/cpu.h @@ -0,0 +1,288 @@ +/* + * OpenRISC virtual CPU header. + * + * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com> + * + * 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" +#include "qemu/cpu.h" +#include "error.h" + +struct CPUOpenRISCState; + +#define NB_MMU_MODES 3 + +#define TARGET_PAGE_BITS 13 + +#define TARGET_PHYS_ADDR_SPACE_BITS 32 +#define TARGET_VIRT_ADDR_SPACE_BITS 32 + +/* Internel flags, delay slot flag */ +#define D_FLAG 1 + +/* Verison Register */ +#define SPR_VR 0xFFFF003F + +/* 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 +}; + +/* Unit presece register */ +enum { + UPR_UP = (1 << 0), + UPR_DCP = (1 << 1), + UPR_ICP = (1 << 2), + UPR_DMP = (1 << 3), + UPR_IMP = (1 << 4), + UPR_MP = (1 << 5), + UPR_DUP = (1 << 6), + UPR_PCUR = (1 << 7), + UPR_PMP = (1 << 8), + UPR_PICP = (1 << 9), + UPR_TTP = (1 << 10), + UPR_CUP = (255 << 24), +}; + +/* CPU configure register */ +enum { + CPUCFGR_NSGF = (15 << 0), + CPUCFGR_CGF = (1 << 4), + CPUCFGR_OB32S = (1 << 5), + CPUCFGR_OB64S = (1 << 6), + CPUCFGR_OF32S = (1 << 7), + CPUCFGR_OF64S = (1 << 8), + CPUCFGR_OV64S = (1 << 9), +}; + +/* DMMU configure register */ +enum { + DMMUCFGR_NTW = (3 << 0), + DMMUCFGR_NTS = (7 << 2), + DMMUCFGR_NAE = (7 << 5), + DMMUCFGR_CRI = (1 << 8), + DMMUCFGR_PRI = (1 << 9), + DMMUCFGR_TEIRI = (1 << 10), + DMMUCFGR_HTR = (1 << 11), +}; + +/* IMMU configure register */ +enum { + IMMUCFGR_NTW = (3 << 0), + IMMUCFGR_NTS = (7 << 2), + IMMUCFGR_NAE = (7 << 5), + IMMUCFGR_CRI = (1 << 8), + IMMUCFGR_PRI = (1 << 9), + IMMUCFGR_TEIRI = (1 << 10), + IMMUCFGR_HTR = (1 << 11), +}; + +/* 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), +}; + +/* OpenRISC Hardware Capabilities */ +enum { + OPENRISC_FEATURE_NSGF, + OPENRISC_FEATURE_CGF, + OPENRISC_FEATURE_OB32S, + OPENRISC_FEATURE_OB64S, + OPENRISC_FEATURE_OF32S, + OPENRISC_FEATURE_OF64S, + OPENRISC_FEATURE_OV64S, + OPENRISC_FEATURE_OR1200, +}; + +typedef struct CPUOpenRISCState CPUOpenRISCState; +struct CPUOpenRISCState { + target_ulong gpr[32]; /* General registers */ + target_ulong pc; /* Program counter */ + target_ulong npc; /* Next PC */ + target_ulong ppc; /* Prev PC */ + target_ulong jmp_pc; /* Jump PC */ + + uint32_t sr; /* Supervisor register */ + uint32_t vr; /* Version register */ + uint32_t upr; /* Unit presence register */ + uint32_t cpucfgr; /* CPU configure register */ + uint32_t dmmucfgr; /* DMMU configure register */ + uint32_t immucfgr; /* IMMU configure register */ + uint32_t flags; /* cpu_flags, we only use it for exception + in solt so far. */ + uint32_t btaken; /* the SR_F bit */ + + CPU_COMMON + +#if !defined(CONFIG_USER_ONLY) + 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 + uint32_t feature; /* CPU Capabilities */ +}; + +#define TYPE_OPENRISC_CPU "or32-cpu" + +#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)) + +void openrisc_cpu_realize(Object *obj, Error **errp); + +void cpu_openrisc_list(FILE *f, fprintf_function cpu_fprintf); +OpenRISCCPU *cpu_openrisc_init(const char *cpu_model); +int cpu_openrisc_exec(CPUOpenRISCState *s); +void do_interrupt(CPUOpenRISCState *env); +void openrisc_translate_init(void); + +#define cpu_list cpu_openrisc_list +#define cpu_exec cpu_openrisc_exec +#define cpu_gen_code cpu_openrisc_gen_code + +#define CPU_SAVE_VERSION 1 + +#if !defined(CONFIG_USER_ONLY) +void cpu_openrisc_pic_reset(CPUOpenRISCState *env); + +void cpu_openrisc_timer_reset(CPUOpenRISCState *env); + +void openrisc_mmu_init(CPUOpenRISCState *env); +#endif + +static inline CPUOpenRISCState *cpu_init(const char *cpu_model) +{ + OpenRISCCPU *cpu = cpu_openrisc_init(cpu_model); + if (cpu) { + return &cpu->env; + } + return NULL; +} + +#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 = 0; +} + +static inline int cpu_mmu_index(CPUOpenRISCState *env) +{ + return 0; +} + +static inline bool cpu_has_work(CPUOpenRISCState *env) +{ + return true; +} + +#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/intrpt.c b/target-openrisc/intrpt.c new file mode 100644 index 0000000..72ee402 --- /dev/null +++ b/target-openrisc/intrpt.c @@ -0,0 +1,30 @@ +/* + * OpenRISC interrupt. + * + * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com> + * + * 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 "host-utils.h" +#if !defined(CONFIG_USER_ONLY) +#include "hw/loader.h" +#endif + +void do_interrupt(CPUOpenRISCState *env) +{ +} diff --git a/target-openrisc/machine.c b/target-openrisc/machine.c new file mode 100644 index 0000000..11bf275 --- /dev/null +++ b/target-openrisc/machine.c @@ -0,0 +1,30 @@ +/* + * OpenRISC Machine + * + * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com> + * + * 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 "hw/hw.h" +#include "hw/boards.h" + +void cpu_save(QEMUFile *f, void *opaque) +{ +} + +int cpu_load(QEMUFile *f, void *opaque, int version_id) +{ + return 0; +} diff --git a/target-openrisc/mmu.c b/target-openrisc/mmu.c new file mode 100644 index 0000000..20a1b5a --- /dev/null +++ b/target-openrisc/mmu.c @@ -0,0 +1,39 @@ +/* + * OpenRISC MMU. + * + * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com> + * Zhizhou Zhang <etouzh@gmail.com> + * + * 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 "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 addr; +} + +void openrisc_mmu_init(CPUOpenRISCState *env) +{ +} +#endif diff --git a/target-openrisc/mmu_helper.c b/target-openrisc/mmu_helper.c new file mode 100644 index 0000000..43dd42f --- /dev/null +++ b/target-openrisc/mmu_helper.c @@ -0,0 +1,43 @@ +/* + * OpenRISC MMU helper routines + * + * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com> + * Zhizhou Zhang <etouzh@gmail.com> + * + * 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" + +#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 *env, 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..1d87d76 --- /dev/null +++ b/target-openrisc/translate.c @@ -0,0 +1,75 @@ +/* + * OpenRISC translation + * + * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com> + * Feng Gao <gf91597@gmail.com> + * + * 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 "exec-all.h" +#include "disas.h" +#include "tcg-op.h" +#include "qemu-common.h" +#include "qemu-log.h" +#include "config.h" + +#define OPENRISC_DISAS + +#ifdef OPENRISC_DISAS +# define LOG_DIS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__) +#else +# define LOG_DIS(...) do { } while (0) +#endif + +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) +{ + int i; + uint32_t *regs = env->gpr; + cpu_fprintf(f, "PC=%08x\n", env->pc); + for (i = 0; i < 32; ++i) { + cpu_fprintf(f, "R%02d=%08x%c", i, regs[i], + (i % 4) == 3 ? '\n' : ' '); + } +} + +void restore_state_to_opc(CPUOpenRISCState *env, TranslationBlock *tb, + int pc_pos) +{ + env->pc = gen_opc_pc[pc_pos]; +}
Add OpenRISC target stubs and basic cpu support. Signed-off-by: Jia Liu <proljc@gmail.com> --- arch_init.c | 2 + arch_init.h | 1 + configure | 14 +- cpu-exec.c | 2 + default-configs/or32-softmmu.mak | 6 + elf.h | 2 + hw/openrisc/Makefile.objs | 3 + hw/openrisc_cpudev.h | 29 ++++ hw/openrisc_pic.c | 30 ++++ hw/openrisc_timer.c | 30 ++++ poison.h | 1 + target-openrisc/Makefile.objs | 3 + target-openrisc/cpu.c | 240 +++++++++++++++++++++++++++++++ target-openrisc/cpu.h | 288 ++++++++++++++++++++++++++++++++++++++ target-openrisc/intrpt.c | 30 ++++ target-openrisc/machine.c | 30 ++++ target-openrisc/mmu.c | 39 ++++++ target-openrisc/mmu_helper.c | 43 ++++++ target-openrisc/translate.c | 75 ++++++++++ 19 files changed, 866 insertions(+), 2 deletions(-) create mode 100644 default-configs/or32-softmmu.mak create mode 100644 hw/openrisc/Makefile.objs create mode 100644 hw/openrisc_cpudev.h create mode 100644 hw/openrisc_pic.c create mode 100644 hw/openrisc_timer.c create mode 100644 target-openrisc/Makefile.objs create mode 100644 target-openrisc/cpu.c create mode 100644 target-openrisc/cpu.h create mode 100644 target-openrisc/intrpt.c create mode 100644 target-openrisc/machine.c create mode 100644 target-openrisc/mmu.c create mode 100644 target-openrisc/mmu_helper.c create mode 100644 target-openrisc/translate.c