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) 65 { 66 CPUState *s = CPU(obj); 67 CRISCPU *cpu = CRIS_CPU(s); 68 CRISCPUClass *ccc = CRIS_CPU_GET_CLASS(cpu); 69 CPUCRISState *env = &cpu->env; 70 uint32_t vr; 71 72 if (ccc->parent_phases.hold) { 73 ccc->parent_phases.hold(obj); 74 } 75 76 vr = env->pregs[PR_VR]; 77 memset(env, 0, offsetof(CPUCRISState, end_reset_fields)); 78 env->pregs[PR_VR] = vr; 79 80 #if defined(CONFIG_USER_ONLY) 81 /* start in user mode with interrupts enabled. */ 82 env->pregs[PR_CCS] |= U_FLAG | I_FLAG | P_FLAG; 83 #else 84 cris_mmu_init(env); 85 env->pregs[PR_CCS] = 0; 86 #endif 87 } 88 89 static ObjectClass *cris_cpu_class_by_name(const char *cpu_model) 90 { 91 ObjectClass *oc; 92 char *typename; 93 94 #if defined(CONFIG_USER_ONLY) 95 if (strcasecmp(cpu_model, "any") == 0) { 96 return object_class_by_name(CRIS_CPU_TYPE_NAME("crisv32")); 97 } 98 #endif 99 100 typename = g_strdup_printf(CRIS_CPU_TYPE_NAME("%s"), cpu_model); 101 oc = object_class_by_name(typename); 102 g_free(typename); 103 104 return oc; 105 } 106 107 static void cris_cpu_realizefn(DeviceState *dev, Error **errp) 108 { 109 CPUState *cs = CPU(dev); 110 CRISCPUClass *ccc = CRIS_CPU_GET_CLASS(dev); 111 Error *local_err = NULL; 112 113 cpu_exec_realizefn(cs, &local_err); 114 if (local_err != NULL) { 115 error_propagate(errp, local_err); 116 return; 117 } 118 119 cpu_reset(cs); 120 qemu_init_vcpu(cs); 121 122 ccc->parent_realize(dev, errp); 123 } 124 125 #ifndef CONFIG_USER_ONLY 126 static void cris_cpu_set_irq(void *opaque, int irq, int level) 127 { 128 CRISCPU *cpu = opaque; 129 CPUState *cs = CPU(cpu); 130 int type = irq == CRIS_CPU_IRQ ? CPU_INTERRUPT_HARD : CPU_INTERRUPT_NMI; 131 132 if (irq == CRIS_CPU_IRQ) { 133 /* 134 * The PIC passes us the vector for the IRQ as the value it sends 135 * over the qemu_irq line 136 */ 137 cpu->env.interrupt_vector = level; 138 } 139 140 if (level) { 141 cpu_interrupt(cs, type); 142 } else { 143 cpu_reset_interrupt(cs, type); 144 } 145 } 146 #endif 147 148 static void cris_disas_set_info(CPUState *cpu, disassemble_info *info) 149 { 150 CRISCPU *cc = CRIS_CPU(cpu); 151 CPUCRISState *env = &cc->env; 152 153 if (env->pregs[PR_VR] != 32) { 154 info->mach = bfd_mach_cris_v0_v10; 155 info->print_insn = print_insn_crisv10; 156 } else { 157 info->mach = bfd_mach_cris_v32; 158 info->print_insn = print_insn_crisv32; 159 } 160 } 161 162 static void cris_cpu_initfn(Object *obj) 163 { 164 CRISCPU *cpu = CRIS_CPU(obj); 165 CRISCPUClass *ccc = CRIS_CPU_GET_CLASS(obj); 166 CPUCRISState *env = &cpu->env; 167 168 env->pregs[PR_VR] = ccc->vr; 169 170 #ifndef CONFIG_USER_ONLY 171 /* IRQ and NMI lines. */ 172 qdev_init_gpio_in(DEVICE(cpu), cris_cpu_set_irq, 2); 173 #endif 174 } 175 176 #ifndef CONFIG_USER_ONLY 177 #include "hw/core/sysemu-cpu-ops.h" 178 179 static const struct SysemuCPUOps cris_sysemu_ops = { 180 .get_phys_page_debug = cris_cpu_get_phys_page_debug, 181 }; 182 #endif 183 184 #include "hw/core/tcg-cpu-ops.h" 185 186 static const TCGCPUOps crisv10_tcg_ops = { 187 .initialize = cris_initialize_crisv10_tcg, 188 .restore_state_to_opc = cris_restore_state_to_opc, 189 190 #ifndef CONFIG_USER_ONLY 191 .tlb_fill = cris_cpu_tlb_fill, 192 .cpu_exec_interrupt = cris_cpu_exec_interrupt, 193 .do_interrupt = crisv10_cpu_do_interrupt, 194 #endif /* !CONFIG_USER_ONLY */ 195 }; 196 197 static const TCGCPUOps crisv32_tcg_ops = { 198 .initialize = cris_initialize_tcg, 199 .restore_state_to_opc = cris_restore_state_to_opc, 200 201 #ifndef CONFIG_USER_ONLY 202 .tlb_fill = cris_cpu_tlb_fill, 203 .cpu_exec_interrupt = cris_cpu_exec_interrupt, 204 .do_interrupt = cris_cpu_do_interrupt, 205 #endif /* !CONFIG_USER_ONLY */ 206 }; 207 208 static void crisv8_cpu_class_init(ObjectClass *oc, void *data) 209 { 210 CPUClass *cc = CPU_CLASS(oc); 211 CRISCPUClass *ccc = CRIS_CPU_CLASS(oc); 212 213 ccc->vr = 8; 214 cc->gdb_read_register = crisv10_cpu_gdb_read_register; 215 cc->tcg_ops = &crisv10_tcg_ops; 216 } 217 218 static void crisv9_cpu_class_init(ObjectClass *oc, void *data) 219 { 220 CPUClass *cc = CPU_CLASS(oc); 221 CRISCPUClass *ccc = CRIS_CPU_CLASS(oc); 222 223 ccc->vr = 9; 224 cc->gdb_read_register = crisv10_cpu_gdb_read_register; 225 cc->tcg_ops = &crisv10_tcg_ops; 226 } 227 228 static void crisv10_cpu_class_init(ObjectClass *oc, void *data) 229 { 230 CPUClass *cc = CPU_CLASS(oc); 231 CRISCPUClass *ccc = CRIS_CPU_CLASS(oc); 232 233 ccc->vr = 10; 234 cc->gdb_read_register = crisv10_cpu_gdb_read_register; 235 cc->tcg_ops = &crisv10_tcg_ops; 236 } 237 238 static void crisv11_cpu_class_init(ObjectClass *oc, void *data) 239 { 240 CPUClass *cc = CPU_CLASS(oc); 241 CRISCPUClass *ccc = CRIS_CPU_CLASS(oc); 242 243 ccc->vr = 11; 244 cc->gdb_read_register = crisv10_cpu_gdb_read_register; 245 cc->tcg_ops = &crisv10_tcg_ops; 246 } 247 248 static void crisv17_cpu_class_init(ObjectClass *oc, void *data) 249 { 250 CPUClass *cc = CPU_CLASS(oc); 251 CRISCPUClass *ccc = CRIS_CPU_CLASS(oc); 252 253 ccc->vr = 17; 254 cc->gdb_read_register = crisv10_cpu_gdb_read_register; 255 cc->tcg_ops = &crisv10_tcg_ops; 256 } 257 258 static void crisv32_cpu_class_init(ObjectClass *oc, void *data) 259 { 260 CPUClass *cc = CPU_CLASS(oc); 261 CRISCPUClass *ccc = CRIS_CPU_CLASS(oc); 262 263 ccc->vr = 32; 264 cc->tcg_ops = &crisv32_tcg_ops; 265 } 266 267 static void cris_cpu_class_init(ObjectClass *oc, void *data) 268 { 269 DeviceClass *dc = DEVICE_CLASS(oc); 270 CPUClass *cc = CPU_CLASS(oc); 271 CRISCPUClass *ccc = CRIS_CPU_CLASS(oc); 272 ResettableClass *rc = RESETTABLE_CLASS(oc); 273 274 device_class_set_parent_realize(dc, cris_cpu_realizefn, 275 &ccc->parent_realize); 276 277 resettable_class_set_parent_phases(rc, NULL, cris_cpu_reset_hold, NULL, 278 &ccc->parent_phases); 279 280 cc->class_by_name = cris_cpu_class_by_name; 281 cc->has_work = cris_cpu_has_work; 282 cc->mmu_index = cris_cpu_mmu_index; 283 cc->dump_state = cris_cpu_dump_state; 284 cc->set_pc = cris_cpu_set_pc; 285 cc->get_pc = cris_cpu_get_pc; 286 cc->gdb_read_register = cris_cpu_gdb_read_register; 287 cc->gdb_write_register = cris_cpu_gdb_write_register; 288 #ifndef CONFIG_USER_ONLY 289 dc->vmsd = &vmstate_cris_cpu; 290 cc->sysemu_ops = &cris_sysemu_ops; 291 #endif 292 293 cc->gdb_num_core_regs = 49; 294 cc->gdb_stop_before_watchpoint = true; 295 296 cc->disas_set_info = cris_disas_set_info; 297 } 298 299 #define DEFINE_CRIS_CPU_TYPE(cpu_model, initfn) \ 300 { \ 301 .parent = TYPE_CRIS_CPU, \ 302 .class_init = initfn, \ 303 .name = CRIS_CPU_TYPE_NAME(cpu_model), \ 304 } 305 306 static const TypeInfo cris_cpu_model_type_infos[] = { 307 { 308 .name = TYPE_CRIS_CPU, 309 .parent = TYPE_CPU, 310 .instance_size = sizeof(CRISCPU), 311 .instance_align = __alignof(CRISCPU), 312 .instance_init = cris_cpu_initfn, 313 .abstract = true, 314 .class_size = sizeof(CRISCPUClass), 315 .class_init = cris_cpu_class_init, 316 }, 317 DEFINE_CRIS_CPU_TYPE("crisv8", crisv8_cpu_class_init), 318 DEFINE_CRIS_CPU_TYPE("crisv9", crisv9_cpu_class_init), 319 DEFINE_CRIS_CPU_TYPE("crisv10", crisv10_cpu_class_init), 320 DEFINE_CRIS_CPU_TYPE("crisv11", crisv11_cpu_class_init), 321 DEFINE_CRIS_CPU_TYPE("crisv17", crisv17_cpu_class_init), 322 DEFINE_CRIS_CPU_TYPE("crisv32", crisv32_cpu_class_init), 323 }; 324 325 DEFINE_TYPES(cris_cpu_model_type_infos) 326