1 /* 2 * QEMU CRIS CPU 3 * 4 * Copyright (c) 2008 AXIS Communications AB 5 * Written by Edgar E. Iglesias. 6 * 7 * Copyright (c) 2012 SUSE LINUX Products GmbH 8 * 9 * This library is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU Lesser General Public 11 * License as published by the Free Software Foundation; either 12 * version 2.1 of the License, or (at your option) any later version. 13 * 14 * This library is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * Lesser General Public License for more details. 18 * 19 * You should have received a copy of the GNU Lesser General Public 20 * License along with this library; if not, see 21 * <http://www.gnu.org/licenses/lgpl-2.1.html> 22 */ 23 24 #include "qemu/osdep.h" 25 #include "qapi/error.h" 26 #include "qemu/qemu-print.h" 27 #include "cpu.h" 28 #include "mmu.h" 29 30 31 static void cris_cpu_set_pc(CPUState *cs, vaddr value) 32 { 33 CRISCPU *cpu = CRIS_CPU(cs); 34 35 cpu->env.pc = value; 36 } 37 38 static vaddr cris_cpu_get_pc(CPUState *cs) 39 { 40 CRISCPU *cpu = CRIS_CPU(cs); 41 42 return cpu->env.pc; 43 } 44 45 static void cris_restore_state_to_opc(CPUState *cs, 46 const TranslationBlock *tb, 47 const uint64_t *data) 48 { 49 CRISCPU *cpu = CRIS_CPU(cs); 50 51 cpu->env.pc = data[0]; 52 } 53 54 static bool cris_cpu_has_work(CPUState *cs) 55 { 56 return cs->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI); 57 } 58 59 static int cris_cpu_mmu_index(CPUState *cs, bool ifetch) 60 { 61 return !!(cpu_env(cs)->pregs[PR_CCS] & U_FLAG); 62 } 63 64 static void cris_cpu_reset_hold(Object *obj, ResetType type) 65 { 66 CPUState *cs = CPU(obj); 67 CRISCPUClass *ccc = CRIS_CPU_GET_CLASS(obj); 68 CPUCRISState *env = cpu_env(cs); 69 uint32_t vr; 70 71 if (ccc->parent_phases.hold) { 72 ccc->parent_phases.hold(obj, type); 73 } 74 75 vr = env->pregs[PR_VR]; 76 memset(env, 0, offsetof(CPUCRISState, end_reset_fields)); 77 env->pregs[PR_VR] = vr; 78 79 #if defined(CONFIG_USER_ONLY) 80 /* start in user mode with interrupts enabled. */ 81 env->pregs[PR_CCS] |= U_FLAG | I_FLAG | P_FLAG; 82 #else 83 cris_mmu_init(env); 84 env->pregs[PR_CCS] = 0; 85 #endif 86 } 87 88 static ObjectClass *cris_cpu_class_by_name(const char *cpu_model) 89 { 90 ObjectClass *oc; 91 char *typename; 92 93 #if defined(CONFIG_USER_ONLY) 94 if (strcasecmp(cpu_model, "any") == 0) { 95 return object_class_by_name(CRIS_CPU_TYPE_NAME("crisv32")); 96 } 97 #endif 98 99 typename = g_strdup_printf(CRIS_CPU_TYPE_NAME("%s"), cpu_model); 100 oc = object_class_by_name(typename); 101 g_free(typename); 102 103 return oc; 104 } 105 106 static void cris_cpu_realizefn(DeviceState *dev, Error **errp) 107 { 108 CPUState *cs = CPU(dev); 109 CRISCPUClass *ccc = CRIS_CPU_GET_CLASS(dev); 110 Error *local_err = NULL; 111 112 cpu_exec_realizefn(cs, &local_err); 113 if (local_err != NULL) { 114 error_propagate(errp, local_err); 115 return; 116 } 117 118 cpu_reset(cs); 119 qemu_init_vcpu(cs); 120 121 ccc->parent_realize(dev, errp); 122 } 123 124 #ifndef CONFIG_USER_ONLY 125 static void cris_cpu_set_irq(void *opaque, int irq, int level) 126 { 127 CRISCPU *cpu = opaque; 128 CPUState *cs = CPU(cpu); 129 int type = irq == CRIS_CPU_IRQ ? CPU_INTERRUPT_HARD : CPU_INTERRUPT_NMI; 130 131 if (irq == CRIS_CPU_IRQ) { 132 /* 133 * The PIC passes us the vector for the IRQ as the value it sends 134 * over the qemu_irq line 135 */ 136 cpu->env.interrupt_vector = level; 137 } 138 139 if (level) { 140 cpu_interrupt(cs, type); 141 } else { 142 cpu_reset_interrupt(cs, type); 143 } 144 } 145 #endif 146 147 static void cris_disas_set_info(CPUState *cpu, disassemble_info *info) 148 { 149 if (cpu_env(cpu)->pregs[PR_VR] != 32) { 150 info->mach = bfd_mach_cris_v0_v10; 151 info->print_insn = print_insn_crisv10; 152 } else { 153 info->mach = bfd_mach_cris_v32; 154 info->print_insn = print_insn_crisv32; 155 } 156 } 157 158 static void cris_cpu_initfn(Object *obj) 159 { 160 CRISCPU *cpu = CRIS_CPU(obj); 161 CRISCPUClass *ccc = CRIS_CPU_GET_CLASS(obj); 162 CPUCRISState *env = &cpu->env; 163 164 env->pregs[PR_VR] = ccc->vr; 165 166 #ifndef CONFIG_USER_ONLY 167 /* IRQ and NMI lines. */ 168 qdev_init_gpio_in(DEVICE(cpu), cris_cpu_set_irq, 2); 169 #endif 170 } 171 172 #ifndef CONFIG_USER_ONLY 173 #include "hw/core/sysemu-cpu-ops.h" 174 175 static const struct SysemuCPUOps cris_sysemu_ops = { 176 .get_phys_page_debug = cris_cpu_get_phys_page_debug, 177 }; 178 #endif 179 180 #include "hw/core/tcg-cpu-ops.h" 181 182 static const TCGCPUOps crisv10_tcg_ops = { 183 .initialize = cris_initialize_crisv10_tcg, 184 .restore_state_to_opc = cris_restore_state_to_opc, 185 186 #ifndef CONFIG_USER_ONLY 187 .tlb_fill = cris_cpu_tlb_fill, 188 .cpu_exec_interrupt = cris_cpu_exec_interrupt, 189 .do_interrupt = crisv10_cpu_do_interrupt, 190 #endif /* !CONFIG_USER_ONLY */ 191 }; 192 193 static const TCGCPUOps crisv32_tcg_ops = { 194 .initialize = cris_initialize_tcg, 195 .restore_state_to_opc = cris_restore_state_to_opc, 196 197 #ifndef CONFIG_USER_ONLY 198 .tlb_fill = cris_cpu_tlb_fill, 199 .cpu_exec_interrupt = cris_cpu_exec_interrupt, 200 .do_interrupt = cris_cpu_do_interrupt, 201 #endif /* !CONFIG_USER_ONLY */ 202 }; 203 204 static void crisv8_cpu_class_init(ObjectClass *oc, void *data) 205 { 206 CPUClass *cc = CPU_CLASS(oc); 207 CRISCPUClass *ccc = CRIS_CPU_CLASS(oc); 208 209 ccc->vr = 8; 210 cc->gdb_read_register = crisv10_cpu_gdb_read_register; 211 cc->tcg_ops = &crisv10_tcg_ops; 212 } 213 214 static void crisv9_cpu_class_init(ObjectClass *oc, void *data) 215 { 216 CPUClass *cc = CPU_CLASS(oc); 217 CRISCPUClass *ccc = CRIS_CPU_CLASS(oc); 218 219 ccc->vr = 9; 220 cc->gdb_read_register = crisv10_cpu_gdb_read_register; 221 cc->tcg_ops = &crisv10_tcg_ops; 222 } 223 224 static void crisv10_cpu_class_init(ObjectClass *oc, void *data) 225 { 226 CPUClass *cc = CPU_CLASS(oc); 227 CRISCPUClass *ccc = CRIS_CPU_CLASS(oc); 228 229 ccc->vr = 10; 230 cc->gdb_read_register = crisv10_cpu_gdb_read_register; 231 cc->tcg_ops = &crisv10_tcg_ops; 232 } 233 234 static void crisv11_cpu_class_init(ObjectClass *oc, void *data) 235 { 236 CPUClass *cc = CPU_CLASS(oc); 237 CRISCPUClass *ccc = CRIS_CPU_CLASS(oc); 238 239 ccc->vr = 11; 240 cc->gdb_read_register = crisv10_cpu_gdb_read_register; 241 cc->tcg_ops = &crisv10_tcg_ops; 242 } 243 244 static void crisv17_cpu_class_init(ObjectClass *oc, void *data) 245 { 246 CPUClass *cc = CPU_CLASS(oc); 247 CRISCPUClass *ccc = CRIS_CPU_CLASS(oc); 248 249 ccc->vr = 17; 250 cc->gdb_read_register = crisv10_cpu_gdb_read_register; 251 cc->tcg_ops = &crisv10_tcg_ops; 252 } 253 254 static void crisv32_cpu_class_init(ObjectClass *oc, void *data) 255 { 256 CPUClass *cc = CPU_CLASS(oc); 257 CRISCPUClass *ccc = CRIS_CPU_CLASS(oc); 258 259 ccc->vr = 32; 260 cc->tcg_ops = &crisv32_tcg_ops; 261 } 262 263 static void cris_cpu_class_init(ObjectClass *oc, void *data) 264 { 265 DeviceClass *dc = DEVICE_CLASS(oc); 266 CPUClass *cc = CPU_CLASS(oc); 267 CRISCPUClass *ccc = CRIS_CPU_CLASS(oc); 268 ResettableClass *rc = RESETTABLE_CLASS(oc); 269 270 device_class_set_parent_realize(dc, cris_cpu_realizefn, 271 &ccc->parent_realize); 272 273 resettable_class_set_parent_phases(rc, NULL, cris_cpu_reset_hold, NULL, 274 &ccc->parent_phases); 275 276 cc->class_by_name = cris_cpu_class_by_name; 277 cc->has_work = cris_cpu_has_work; 278 cc->mmu_index = cris_cpu_mmu_index; 279 cc->dump_state = cris_cpu_dump_state; 280 cc->set_pc = cris_cpu_set_pc; 281 cc->get_pc = cris_cpu_get_pc; 282 cc->gdb_read_register = cris_cpu_gdb_read_register; 283 cc->gdb_write_register = cris_cpu_gdb_write_register; 284 #ifndef CONFIG_USER_ONLY 285 dc->vmsd = &vmstate_cris_cpu; 286 cc->sysemu_ops = &cris_sysemu_ops; 287 #endif 288 289 cc->gdb_num_core_regs = 49; 290 cc->gdb_stop_before_watchpoint = true; 291 292 cc->disas_set_info = cris_disas_set_info; 293 } 294 295 #define DEFINE_CRIS_CPU_TYPE(cpu_model, initfn) \ 296 { \ 297 .parent = TYPE_CRIS_CPU, \ 298 .class_init = initfn, \ 299 .name = CRIS_CPU_TYPE_NAME(cpu_model), \ 300 } 301 302 static const TypeInfo cris_cpu_model_type_infos[] = { 303 { 304 .name = TYPE_CRIS_CPU, 305 .parent = TYPE_CPU, 306 .instance_size = sizeof(CRISCPU), 307 .instance_align = __alignof(CRISCPU), 308 .instance_init = cris_cpu_initfn, 309 .abstract = true, 310 .class_size = sizeof(CRISCPUClass), 311 .class_init = cris_cpu_class_init, 312 }, 313 DEFINE_CRIS_CPU_TYPE("crisv8", crisv8_cpu_class_init), 314 DEFINE_CRIS_CPU_TYPE("crisv9", crisv9_cpu_class_init), 315 DEFINE_CRIS_CPU_TYPE("crisv10", crisv10_cpu_class_init), 316 DEFINE_CRIS_CPU_TYPE("crisv11", crisv11_cpu_class_init), 317 DEFINE_CRIS_CPU_TYPE("crisv17", crisv17_cpu_class_init), 318 DEFINE_CRIS_CPU_TYPE("crisv32", crisv32_cpu_class_init), 319 }; 320 321 DEFINE_TYPES(cris_cpu_model_type_infos) 322