|
|
1.1 ! root 1: /* ! 2: * QEMU Motorola 68k CPU ! 3: * ! 4: * Copyright (c) 2012 SUSE LINUX Products GmbH ! 5: * ! 6: * This library is free software; you can redistribute it and/or ! 7: * modify it under the terms of the GNU Lesser General Public ! 8: * License as published by the Free Software Foundation; either ! 9: * version 2.1 of the License, or (at your option) any later version. ! 10: * ! 11: * This library is distributed in the hope that it will be useful, ! 12: * but WITHOUT ANY WARRANTY; without even the implied warranty of ! 13: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ! 14: * Lesser General Public License for more details. ! 15: * ! 16: * You should have received a copy of the GNU Lesser General Public ! 17: * License along with this library; if not, see ! 18: * <http://www.gnu.org/licenses/lgpl-2.1.html> ! 19: */ ! 20: ! 21: #include "cpu.h" ! 22: #include "qemu-common.h" ! 23: ! 24: ! 25: static void m68k_set_feature(CPUM68KState *env, int feature) ! 26: { ! 27: env->features |= (1u << feature); ! 28: } ! 29: ! 30: /* CPUClass::reset() */ ! 31: static void m68k_cpu_reset(CPUState *s) ! 32: { ! 33: M68kCPU *cpu = M68K_CPU(s); ! 34: M68kCPUClass *mcc = M68K_CPU_GET_CLASS(cpu); ! 35: CPUM68KState *env = &cpu->env; ! 36: ! 37: if (qemu_loglevel_mask(CPU_LOG_RESET)) { ! 38: qemu_log("CPU Reset (CPU %d)\n", env->cpu_index); ! 39: log_cpu_state(env, 0); ! 40: } ! 41: ! 42: mcc->parent_reset(s); ! 43: ! 44: memset(env, 0, offsetof(CPUM68KState, breakpoints)); ! 45: #if !defined(CONFIG_USER_ONLY) ! 46: env->sr = 0x2700; ! 47: #endif ! 48: m68k_switch_sp(env); ! 49: /* ??? FP regs should be initialized to NaN. */ ! 50: env->cc_op = CC_OP_FLAGS; ! 51: /* TODO: We should set PC from the interrupt vector. */ ! 52: env->pc = 0; ! 53: tlb_flush(env, 1); ! 54: } ! 55: ! 56: /* CPU models */ ! 57: ! 58: static void m5206_cpu_initfn(Object *obj) ! 59: { ! 60: M68kCPU *cpu = M68K_CPU(obj); ! 61: CPUM68KState *env = &cpu->env; ! 62: ! 63: m68k_set_feature(env, M68K_FEATURE_CF_ISA_A); ! 64: } ! 65: ! 66: static void m5208_cpu_initfn(Object *obj) ! 67: { ! 68: M68kCPU *cpu = M68K_CPU(obj); ! 69: CPUM68KState *env = &cpu->env; ! 70: ! 71: m68k_set_feature(env, M68K_FEATURE_CF_ISA_A); ! 72: m68k_set_feature(env, M68K_FEATURE_CF_ISA_APLUSC); ! 73: m68k_set_feature(env, M68K_FEATURE_BRAL); ! 74: m68k_set_feature(env, M68K_FEATURE_CF_EMAC); ! 75: m68k_set_feature(env, M68K_FEATURE_USP); ! 76: } ! 77: ! 78: static void cfv4e_cpu_initfn(Object *obj) ! 79: { ! 80: M68kCPU *cpu = M68K_CPU(obj); ! 81: CPUM68KState *env = &cpu->env; ! 82: ! 83: m68k_set_feature(env, M68K_FEATURE_CF_ISA_A); ! 84: m68k_set_feature(env, M68K_FEATURE_CF_ISA_B); ! 85: m68k_set_feature(env, M68K_FEATURE_BRAL); ! 86: m68k_set_feature(env, M68K_FEATURE_CF_FPU); ! 87: m68k_set_feature(env, M68K_FEATURE_CF_EMAC); ! 88: m68k_set_feature(env, M68K_FEATURE_USP); ! 89: } ! 90: ! 91: static void any_cpu_initfn(Object *obj) ! 92: { ! 93: M68kCPU *cpu = M68K_CPU(obj); ! 94: CPUM68KState *env = &cpu->env; ! 95: ! 96: m68k_set_feature(env, M68K_FEATURE_CF_ISA_A); ! 97: m68k_set_feature(env, M68K_FEATURE_CF_ISA_B); ! 98: m68k_set_feature(env, M68K_FEATURE_CF_ISA_APLUSC); ! 99: m68k_set_feature(env, M68K_FEATURE_BRAL); ! 100: m68k_set_feature(env, M68K_FEATURE_CF_FPU); ! 101: /* MAC and EMAC are mututally exclusive, so pick EMAC. ! 102: It's mostly backwards compatible. */ ! 103: m68k_set_feature(env, M68K_FEATURE_CF_EMAC); ! 104: m68k_set_feature(env, M68K_FEATURE_CF_EMAC_B); ! 105: m68k_set_feature(env, M68K_FEATURE_USP); ! 106: m68k_set_feature(env, M68K_FEATURE_EXT_FULL); ! 107: m68k_set_feature(env, M68K_FEATURE_WORD_INDEX); ! 108: } ! 109: ! 110: typedef struct M68kCPUInfo { ! 111: const char *name; ! 112: void (*instance_init)(Object *obj); ! 113: } M68kCPUInfo; ! 114: ! 115: static const M68kCPUInfo m68k_cpus[] = { ! 116: { .name = "m5206", .instance_init = m5206_cpu_initfn }, ! 117: { .name = "m5208", .instance_init = m5208_cpu_initfn }, ! 118: { .name = "cfv4e", .instance_init = cfv4e_cpu_initfn }, ! 119: { .name = "any", .instance_init = any_cpu_initfn }, ! 120: }; ! 121: ! 122: static void m68k_cpu_initfn(Object *obj) ! 123: { ! 124: M68kCPU *cpu = M68K_CPU(obj); ! 125: CPUM68KState *env = &cpu->env; ! 126: ! 127: cpu_exec_init(env); ! 128: } ! 129: ! 130: static void m68k_cpu_class_init(ObjectClass *c, void *data) ! 131: { ! 132: M68kCPUClass *mcc = M68K_CPU_CLASS(c); ! 133: CPUClass *cc = CPU_CLASS(c); ! 134: ! 135: mcc->parent_reset = cc->reset; ! 136: cc->reset = m68k_cpu_reset; ! 137: } ! 138: ! 139: static void register_cpu_type(const M68kCPUInfo *info) ! 140: { ! 141: TypeInfo type_info = { ! 142: .name = info->name, ! 143: .parent = TYPE_M68K_CPU, ! 144: .instance_init = info->instance_init, ! 145: }; ! 146: ! 147: type_register_static(&type_info); ! 148: } ! 149: ! 150: static const TypeInfo m68k_cpu_type_info = { ! 151: .name = TYPE_M68K_CPU, ! 152: .parent = TYPE_CPU, ! 153: .instance_size = sizeof(M68kCPU), ! 154: .instance_init = m68k_cpu_initfn, ! 155: .abstract = true, ! 156: .class_size = sizeof(M68kCPUClass), ! 157: .class_init = m68k_cpu_class_init, ! 158: }; ! 159: ! 160: static void m68k_cpu_register_types(void) ! 161: { ! 162: int i; ! 163: ! 164: type_register_static(&m68k_cpu_type_info); ! 165: for (i = 0; i < ARRAY_SIZE(m68k_cpus); i++) { ! 166: register_cpu_type(&m68k_cpus[i]); ! 167: } ! 168: } ! 169: ! 170: type_init(m68k_cpu_register_types)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.