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 .cpu_exec_halt = cris_cpu_has_work, 190 .do_interrupt = crisv10_cpu_do_interrupt, 191 #endif /* !CONFIG_USER_ONLY */ 192 }; 193 194 static const TCGCPUOps crisv32_tcg_ops = { 195 .initialize = cris_initialize_tcg, 196 .restore_state_to_opc = cris_restore_state_to_opc, 197 198 #ifndef CONFIG_USER_ONLY 199 .tlb_fill = cris_cpu_tlb_fill, 200 .cpu_exec_interrupt = cris_cpu_exec_interrupt, 201 .cpu_exec_halt = cris_cpu_has_work, 202 .do_interrupt = cris_cpu_do_interrupt, 203 #endif /* !CONFIG_USER_ONLY */ 204 }; 205 206 static void crisv8_cpu_class_init(ObjectClass *oc, void *data) 207 { 208 CPUClass *cc = CPU_CLASS(oc); 209 CRISCPUClass *ccc = CRIS_CPU_CLASS(oc); 210 211 ccc->vr = 8; 212 cc->gdb_read_register = crisv10_cpu_gdb_read_register; 213 cc->tcg_ops = &crisv10_tcg_ops; 214 } 215 216 static void crisv9_cpu_class_init(ObjectClass *oc, void *data) 217 { 218 CPUClass *cc = CPU_CLASS(oc); 219 CRISCPUClass *ccc = CRIS_CPU_CLASS(oc); 220 221 ccc->vr = 9; 222 cc->gdb_read_register = crisv10_cpu_gdb_read_register; 223 cc->tcg_ops = &crisv10_tcg_ops; 224 } 225 226 static void crisv10_cpu_class_init(ObjectClass *oc, void *data) 227 { 228 CPUClass *cc = CPU_CLASS(oc); 229 CRISCPUClass *ccc = CRIS_CPU_CLASS(oc); 230 231 ccc->vr = 10; 232 cc->gdb_read_register = crisv10_cpu_gdb_read_register; 233 cc->tcg_ops = &crisv10_tcg_ops; 234 } 235 236 static void crisv11_cpu_class_init(ObjectClass *oc, void *data) 237 { 238 CPUClass *cc = CPU_CLASS(oc); 239 CRISCPUClass *ccc = CRIS_CPU_CLASS(oc); 240 241 ccc->vr = 11; 242 cc->gdb_read_register = crisv10_cpu_gdb_read_register; 243 cc->tcg_ops = &crisv10_tcg_ops; 244 } 245 246 static void crisv17_cpu_class_init(ObjectClass *oc, void *data) 247 { 248 CPUClass *cc = CPU_CLASS(oc); 249 CRISCPUClass *ccc = CRIS_CPU_CLASS(oc); 250 251 ccc->vr = 17; 252 cc->gdb_read_register = crisv10_cpu_gdb_read_register; 253 cc->tcg_ops = &crisv10_tcg_ops; 254 } 255 256 static void crisv32_cpu_class_init(ObjectClass *oc, void *data) 257 { 258 CPUClass *cc = CPU_CLASS(oc); 259 CRISCPUClass *ccc = CRIS_CPU_CLASS(oc); 260 261 ccc->vr = 32; 262 cc->tcg_ops = &crisv32_tcg_ops; 263 } 264 265 static void cris_cpu_class_init(ObjectClass *oc, void *data) 266 { 267 DeviceClass *dc = DEVICE_CLASS(oc); 268 CPUClass *cc = CPU_CLASS(oc); 269 CRISCPUClass *ccc = CRIS_CPU_CLASS(oc); 270 ResettableClass *rc = RESETTABLE_CLASS(oc); 271 272 device_class_set_parent_realize(dc, cris_cpu_realizefn, 273 &ccc->parent_realize); 274 275 resettable_class_set_parent_phases(rc, NULL, cris_cpu_reset_hold, NULL, 276 &ccc->parent_phases); 277 278 cc->class_by_name = cris_cpu_class_by_name; 279 cc->has_work = cris_cpu_has_work; 280 cc->mmu_index = cris_cpu_mmu_index; 281 cc->dump_state = cris_cpu_dump_state; 282 cc->set_pc = cris_cpu_set_pc; 283 cc->get_pc = cris_cpu_get_pc; 284 cc->gdb_read_register = cris_cpu_gdb_read_register; 285 cc->gdb_write_register = cris_cpu_gdb_write_register; 286 #ifndef CONFIG_USER_ONLY 287 dc->vmsd = &vmstate_cris_cpu; 288 cc->sysemu_ops = &cris_sysemu_ops; 289 #endif 290 291 cc->gdb_num_core_regs = 49; 292 cc->gdb_stop_before_watchpoint = true; 293 294 cc->disas_set_info = cris_disas_set_info; 295 } 296 297 #define DEFINE_CRIS_CPU_TYPE(cpu_model, initfn) \ 298 { \ 299 .parent = TYPE_CRIS_CPU, \ 300 .class_init = initfn, \ 301 .name = CRIS_CPU_TYPE_NAME(cpu_model), \ 302 } 303 304 static const TypeInfo cris_cpu_model_type_infos[] = { 305 { 306 .name = TYPE_CRIS_CPU, 307 .parent = TYPE_CPU, 308 .instance_size = sizeof(CRISCPU), 309 .instance_align = __alignof(CRISCPU), 310 .instance_init = cris_cpu_initfn, 311 .abstract = true, 312 .class_size = sizeof(CRISCPUClass), 313 .class_init = cris_cpu_class_init, 314 }, 315 DEFINE_CRIS_CPU_TYPE("crisv8", crisv8_cpu_class_init), 316 DEFINE_CRIS_CPU_TYPE("crisv9", crisv9_cpu_class_init), 317 DEFINE_CRIS_CPU_TYPE("crisv10", crisv10_cpu_class_init), 318 DEFINE_CRIS_CPU_TYPE("crisv11", crisv11_cpu_class_init), 319 DEFINE_CRIS_CPU_TYPE("crisv17", crisv17_cpu_class_init), 320 DEFINE_CRIS_CPU_TYPE("crisv32", crisv32_cpu_class_init), 321 }; 322 323 DEFINE_TYPES(cris_cpu_model_type_infos) 324