|
|
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.