add openrisc QOM cpu implement. Signed-off-by: Jia Liu <pro...@gmail.com> --- Makefile.target | 2 + hw/openrisc_cpudev.h | 29 ++++++++++++ hw/openrisc_pic.c | 28 ++++++++++++ target-openrisc/cpu.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++ target-openrisc/cpu.h | 29 ++++++++++++ target-openrisc/helper.c | 2 +- target-openrisc/mmu.c | 4 ++ 7 files changed, 203 insertions(+), 1 deletion(-) create mode 100644 hw/openrisc_cpudev.h create mode 100644 hw/openrisc_pic.c
diff --git a/Makefile.target b/Makefile.target index 0415db8..0efabd2 100644 --- a/Makefile.target +++ b/Makefile.target @@ -390,6 +390,8 @@ obj-xtensa-y += core-dc232b.o obj-xtensa-y += core-dc233c.o obj-xtensa-y += core-fsf.o +obj-openrisc-y += openrisc_pic.o + main.o: QEMU_CFLAGS+=$(GPROF_CFLAGS) monitor.o: hmp-commands.h qmp-commands-old.h diff --git a/hw/openrisc_cpudev.h b/hw/openrisc_cpudev.h new file mode 100644 index 0000000..f1c45e7 --- /dev/null +++ b/hw/openrisc_cpudev.h @@ -0,0 +1,29 @@ +/* + * Qemu Openrisc CPU device support. + * + * Copyright (c) 2011-2012 Jia Liu <pro...@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..201c6bc --- /dev/null +++ b/hw/openrisc_pic.c @@ -0,0 +1,28 @@ +/* + * Generic Openrisc Programmable Interrupt Controller support. + * + * Copyright (c) 2011-2012 Jia Liu <pro...@gmail.com> + * Feng Gao <gf91...@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) +{ +} diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c index ef3ffb1..aec0e01 100644 --- a/target-openrisc/cpu.c +++ b/target-openrisc/cpu.c @@ -22,3 +22,113 @@ #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)); + env->pc = 0x100; + env->sr = SR_FO | SR_SM; + env->exception_index = -1; +#if !defined(CONFIG_USER_ONLY) + openrisc_mmu_init(env); + cpu_openrisc_pic_reset(env); +#endif + + tlb_flush(env, 1); + tb_flush(env); +} + +static void openrisc_cpu_initfn(Object *obj) +{ + OpenriscCPU *cpu = OPENRISC_CPU(obj); + + cpu_exec_init(&cpu->env); +} + +void openrisc_cpu_realize(OpenriscCPU *cpu) +{ + CPUOpenriscState *env = &cpu->env; + cpu_state_reset(env); + qemu_init_vcpu(env); +} + +/* CPU models */ +static void or1200_initfn(Object *obj) +{ + OpenriscCPU *cpu = OPENRISC_CPU(obj); + CPUOpenriscState *env = &cpu->env; + cpu_state_reset(env); +} + +static void openrisc_any_initfn(Object *obj) +{ + OpenriscCPU *cpu = OPENRISC_CPU(obj); + CPUOpenriscState *env = &cpu->env; + cpu_state_reset(env); +} + +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(oc); + + 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]); + } +} + +type_init(openrisc_cpu_register_types) diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h index 80018df..dbc1380 100644 --- a/target-openrisc/cpu.h +++ b/target-openrisc/cpu.h @@ -68,9 +68,32 @@ enum { R_RVH = R12 }; +/* 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), +}; + typedef struct CPUOpenriscState CPUOpenriscState; struct CPUOpenriscState { target_ulong gpr[32]; /* General registers */ + uint32_t sr; /* Supervisor register */ CPU_COMMON @@ -143,6 +166,8 @@ void openrisc_translate_init(void); void openrisc_reset(CPUOpenriscState *env); #if !defined(CONFIG_USER_ONLY) +void cpu_openrisc_pic_reset(CPUOpenriscState *env); + void openrisc_mmu_init(CPUOpenriscState *env); int get_phys_nommu(CPUOpenriscState *env, target_phys_addr_t *physical, int *prot, target_ulong address, int rw); @@ -150,6 +175,10 @@ int get_phys_nommu(CPUOpenriscState *env, target_phys_addr_t *physical, static inline CPUOpenriscState *cpu_init(const char *cpu_model) { + OpenriscCPU *cpu = cpu_openrisc_init(cpu_model); + if (cpu) { + return &cpu->env; + } return NULL; } diff --git a/target-openrisc/helper.c b/target-openrisc/helper.c index 934f73b..13c68e2 100644 --- a/target-openrisc/helper.c +++ b/target-openrisc/helper.c @@ -41,7 +41,7 @@ OpenriscCPU *cpu_openrisc_init(const char *cpu_model) cpu = OPENRISC_CPU(object_new(cpu_model)); env = &cpu->env; env->cpu_model_str = cpu_model; - /*realize openrisc cpu here*/ + openrisc_cpu_realize(cpu); if (tcg_enabled() && !inited) { inited = 1; diff --git a/target-openrisc/mmu.c b/target-openrisc/mmu.c index bdd4bb4..4f0312f 100644 --- a/target-openrisc/mmu.c +++ b/target-openrisc/mmu.c @@ -32,4 +32,8 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUOpenriscState *env, { return 0; } + +void openrisc_mmu_init(CPUOpenriscState *env) +{ +} #endif -- 1.7.9.5