]>
Commit | Line | Data |
---|---|---|
41868f84 DH |
1 | /* |
2 | * CPU models for s390x | |
3 | * | |
4 | * Copyright 2016 IBM Corp. | |
5 | * | |
6 | * Author(s): David Hildenbrand <dahi@linux.vnet.ibm.com> | |
7 | * | |
8 | * This work is licensed under the terms of the GNU GPL, version 2 or (at | |
9 | * your option) any later version. See the COPYING file in the top-level | |
10 | * directory. | |
11 | */ | |
12 | ||
13 | #include "qemu/osdep.h" | |
14 | #include "cpu.h" | |
6c064de1 | 15 | #include "gen-features.h" |
41868f84 | 16 | #include "qapi/error.h" |
0754f604 | 17 | #include "qapi/visitor.h" |
41868f84 DH |
18 | #ifndef CONFIG_USER_ONLY |
19 | #include "sysemu/arch_init.h" | |
20 | #endif | |
21 | ||
6c064de1 DH |
22 | #define CPUDEF_INIT(_type, _gen, _ec_ga, _mha_pow, _hmfai, _name, _desc) \ |
23 | { \ | |
24 | .name = _name, \ | |
25 | .type = _type, \ | |
26 | .gen = _gen, \ | |
27 | .ec_ga = _ec_ga, \ | |
28 | .mha_pow = _mha_pow, \ | |
29 | .hmfai = _hmfai, \ | |
30 | .desc = _desc, \ | |
31 | .base_init = { S390_FEAT_LIST_GEN ## _gen ## _GA ## _ec_ga ## _BASE }, \ | |
32 | .default_init = { S390_FEAT_LIST_GEN ## _gen ## _GA ## _ec_ga ## _DEFAULT }, \ | |
33 | .full_init = { S390_FEAT_LIST_GEN ## _gen ## _GA ## _ec_ga ## _FULL }, \ | |
34 | } | |
35 | ||
36 | /* | |
37 | * CPU definiton list in order of release. For now, base features of a | |
38 | * following release are always a subset of base features of the previous | |
39 | * release. Same is correct for the other feature sets. | |
40 | * A BC release always follows the corresponding EC release. | |
41 | */ | |
42 | static S390CPUDef s390_cpu_defs[] = { | |
43 | CPUDEF_INIT(0x2064, 7, 1, 38, 0x00000000U, "z900", "IBM zSeries 900 GA1"), | |
44 | CPUDEF_INIT(0x2064, 7, 2, 38, 0x00000000U, "z900.2", "IBM zSeries 900 GA2"), | |
45 | CPUDEF_INIT(0x2064, 7, 3, 38, 0x00000000U, "z900.3", "IBM zSeries 900 GA3"), | |
46 | CPUDEF_INIT(0x2066, 7, 3, 38, 0x00000000U, "z800", "IBM zSeries 800 GA1"), | |
47 | CPUDEF_INIT(0x2084, 8, 1, 38, 0x00000000U, "z990", "IBM zSeries 990 GA1"), | |
48 | CPUDEF_INIT(0x2084, 8, 2, 38, 0x00000000U, "z990.2", "IBM zSeries 990 GA2"), | |
49 | CPUDEF_INIT(0x2084, 8, 3, 38, 0x00000000U, "z990.3", "IBM zSeries 990 GA3"), | |
50 | CPUDEF_INIT(0x2086, 8, 3, 38, 0x00000000U, "z890", "IBM zSeries 880 GA1"), | |
51 | CPUDEF_INIT(0x2084, 8, 4, 38, 0x00000000U, "z990.4", "IBM zSeries 990 GA4"), | |
52 | CPUDEF_INIT(0x2086, 8, 4, 38, 0x00000000U, "z890.2", "IBM zSeries 880 GA2"), | |
53 | CPUDEF_INIT(0x2084, 8, 5, 38, 0x00000000U, "z990.5", "IBM zSeries 990 GA5"), | |
54 | CPUDEF_INIT(0x2086, 8, 5, 38, 0x00000000U, "z890.3", "IBM zSeries 880 GA3"), | |
55 | CPUDEF_INIT(0x2094, 9, 1, 40, 0x00000000U, "z9EC", "IBM System z9 EC GA1"), | |
56 | CPUDEF_INIT(0x2094, 9, 2, 40, 0x00000000U, "z9EC.2", "IBM System z9 EC GA2"), | |
57 | CPUDEF_INIT(0x2096, 9, 2, 40, 0x00000000U, "z9BC", "IBM System z9 BC GA1"), | |
58 | CPUDEF_INIT(0x2094, 9, 3, 40, 0x00000000U, "z9EC.3", "IBM System z9 EC GA3"), | |
59 | CPUDEF_INIT(0x2096, 9, 3, 40, 0x00000000U, "z9BC.2", "IBM System z9 BC GA2"), | |
60 | CPUDEF_INIT(0x2097, 10, 1, 43, 0x00000000U, "z10EC", "IBM System z10 EC GA1"), | |
61 | CPUDEF_INIT(0x2097, 10, 2, 43, 0x00000000U, "z10EC.2", "IBM System z10 EC GA2"), | |
62 | CPUDEF_INIT(0x2098, 10, 2, 43, 0x00000000U, "z10BC", "IBM System z10 BC GA1"), | |
63 | CPUDEF_INIT(0x2097, 10, 3, 43, 0x00000000U, "z10EC.3", "IBM System z10 EC GA3"), | |
64 | CPUDEF_INIT(0x2098, 10, 3, 43, 0x00000000U, "z10BC.2", "IBM System z10 BC GA2"), | |
65 | CPUDEF_INIT(0x2817, 11, 1, 44, 0x08000000U, "z196", "IBM zEnterprise 196 GA1"), | |
66 | CPUDEF_INIT(0x2817, 11, 2, 44, 0x08000000U, "z196.2", "IBM zEnterprise 196 GA2"), | |
67 | CPUDEF_INIT(0x2818, 11, 2, 44, 0x08000000U, "z114", "IBM zEnterprise 114 GA1"), | |
68 | CPUDEF_INIT(0x2827, 12, 1, 44, 0x08000000U, "zEC12", "IBM zEnterprise EC12 GA1"), | |
69 | CPUDEF_INIT(0x2827, 12, 2, 44, 0x08000000U, "zEC12.2", "IBM zEnterprise EC12 GA2"), | |
70 | CPUDEF_INIT(0x2828, 12, 2, 44, 0x08000000U, "zBC12", "IBM zEnterprise BC12 GA1"), | |
71 | CPUDEF_INIT(0x2964, 13, 1, 47, 0x08000000U, "z13", "IBM z13 GA1"), | |
72 | CPUDEF_INIT(0x2964, 13, 2, 47, 0x08000000U, "z13.2", "IBM z13 GA2"), | |
73 | CPUDEF_INIT(0x2965, 13, 2, 47, 0x08000000U, "z13s", "IBM z13s GA1"), | |
74 | }; | |
75 | ||
7c72ac49 DH |
76 | bool s390_has_feat(S390Feat feat) |
77 | { | |
78 | static S390CPU *cpu; | |
79 | ||
80 | if (!cpu) { | |
81 | cpu = S390_CPU(qemu_get_cpu(0)); | |
82 | } | |
83 | ||
84 | if (!cpu || !cpu->model) { | |
85 | #ifdef CONFIG_KVM | |
86 | if (kvm_enabled()) { | |
87 | if (feat == S390_FEAT_VECTOR) { | |
88 | return kvm_check_extension(kvm_state, | |
89 | KVM_CAP_S390_VECTOR_REGISTERS); | |
90 | } | |
91 | if (feat == S390_FEAT_RUNTIME_INSTRUMENTATION) { | |
92 | return kvm_s390_get_ri(); | |
93 | } | |
94 | } | |
95 | #endif | |
96 | return 0; | |
97 | } | |
98 | return test_bit(feat, cpu->model->features); | |
99 | } | |
100 | ||
41868f84 DH |
101 | struct S390PrintCpuListInfo { |
102 | FILE *f; | |
103 | fprintf_function print; | |
104 | }; | |
105 | ||
106 | static void print_cpu_model_list(ObjectClass *klass, void *opaque) | |
107 | { | |
108 | struct S390PrintCpuListInfo *info = opaque; | |
109 | S390CPUClass *scc = S390_CPU_CLASS(klass); | |
110 | char *name = g_strdup(object_class_get_name(klass)); | |
111 | const char *details = ""; | |
112 | ||
113 | if (scc->is_static) { | |
114 | details = "(static, migration-safe)"; | |
115 | } else if (scc->is_migration_safe) { | |
116 | details = "(migration-safe)"; | |
117 | } | |
118 | ||
119 | /* strip off the -s390-cpu */ | |
120 | g_strrstr(name, "-" TYPE_S390_CPU)[0] = 0; | |
121 | (*info->print)(info->f, "s390 %-15s %-35s %s\n", name, scc->desc, | |
122 | details); | |
123 | g_free(name); | |
124 | } | |
125 | ||
126 | void s390_cpu_list(FILE *f, fprintf_function print) | |
127 | { | |
128 | struct S390PrintCpuListInfo info = { | |
129 | .f = f, | |
130 | .print = print, | |
131 | }; | |
0754f604 DH |
132 | S390FeatGroup group; |
133 | S390Feat feat; | |
41868f84 DH |
134 | |
135 | object_class_foreach(print_cpu_model_list, TYPE_S390_CPU, false, &info); | |
0754f604 DH |
136 | |
137 | (*print)(f, "\nRecognized feature flags:\n"); | |
138 | for (feat = 0; feat < S390_FEAT_MAX; feat++) { | |
139 | const S390FeatDef *def = s390_feat_def(feat); | |
140 | ||
141 | (*print)(f, "%-20s %-50s\n", def->name, def->desc); | |
142 | } | |
143 | ||
144 | (*print)(f, "\nRecognized feature groups:\n"); | |
145 | for (group = 0; group < S390_FEAT_GROUP_MAX; group++) { | |
146 | const S390FeatGroupDef *def = s390_feat_group_def(group); | |
147 | ||
148 | (*print)(f, "%-20s %-50s\n", def->name, def->desc); | |
149 | } | |
41868f84 DH |
150 | } |
151 | ||
152 | #ifndef CONFIG_USER_ONLY | |
153 | static void create_cpu_model_list(ObjectClass *klass, void *opaque) | |
154 | { | |
155 | CpuDefinitionInfoList **cpu_list = opaque; | |
156 | CpuDefinitionInfoList *entry; | |
157 | CpuDefinitionInfo *info; | |
158 | char *name = g_strdup(object_class_get_name(klass)); | |
159 | S390CPUClass *scc = S390_CPU_CLASS(klass); | |
160 | ||
161 | /* strip off the -s390-cpu */ | |
162 | g_strrstr(name, "-" TYPE_S390_CPU)[0] = 0; | |
163 | info = g_malloc0(sizeof(*info)); | |
164 | info->name = name; | |
165 | info->has_migration_safe = true; | |
166 | info->migration_safe = scc->is_migration_safe; | |
167 | info->q_static = scc->is_static; | |
168 | ||
169 | ||
170 | entry = g_malloc0(sizeof(*entry)); | |
171 | entry->value = info; | |
172 | entry->next = *cpu_list; | |
173 | *cpu_list = entry; | |
174 | } | |
175 | ||
176 | CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp) | |
177 | { | |
178 | CpuDefinitionInfoList *list = NULL; | |
179 | ||
180 | object_class_foreach(create_cpu_model_list, TYPE_S390_CPU, false, &list); | |
181 | ||
182 | return list; | |
183 | } | |
184 | #endif | |
185 | ||
186 | void s390_realize_cpu_model(CPUState *cs, Error **errp) | |
187 | { | |
188 | S390CPUClass *xcc = S390_CPU_GET_CLASS(cs); | |
189 | ||
190 | if (xcc->kvm_required && !kvm_enabled()) { | |
191 | error_setg(errp, "CPU definition requires KVM"); | |
192 | return; | |
193 | } | |
194 | } | |
195 | ||
0754f604 DH |
196 | static void get_feature(Object *obj, Visitor *v, const char *name, |
197 | void *opaque, Error **errp) | |
198 | { | |
199 | S390Feat feat = (S390Feat) opaque; | |
200 | S390CPU *cpu = S390_CPU(obj); | |
201 | bool value; | |
202 | ||
203 | if (!cpu->model) { | |
204 | error_setg(errp, "Details about the host CPU model are not available, " | |
205 | "features cannot be queried."); | |
206 | return; | |
207 | } | |
208 | ||
209 | value = test_bit(feat, cpu->model->features); | |
210 | visit_type_bool(v, name, &value, errp); | |
211 | } | |
212 | ||
213 | static void set_feature(Object *obj, Visitor *v, const char *name, | |
214 | void *opaque, Error **errp) | |
215 | { | |
216 | S390Feat feat = (S390Feat) opaque; | |
217 | DeviceState *dev = DEVICE(obj); | |
218 | S390CPU *cpu = S390_CPU(obj); | |
219 | bool value; | |
220 | ||
221 | if (dev->realized) { | |
222 | error_setg(errp, "Attempt to set property '%s' on '%s' after " | |
223 | "it was realized", name, object_get_typename(obj)); | |
224 | return; | |
225 | } else if (!cpu->model) { | |
226 | error_setg(errp, "Details about the host CPU model are not available, " | |
227 | "features cannot be changed."); | |
228 | return; | |
229 | } | |
230 | ||
231 | visit_type_bool(v, name, &value, errp); | |
232 | if (*errp) { | |
233 | return; | |
234 | } | |
235 | if (value) { | |
236 | if (!test_bit(feat, cpu->model->def->full_feat)) { | |
237 | error_setg(errp, "Feature '%s' is not available for CPU model '%s'," | |
238 | " it was introduced with later models.", | |
239 | name, cpu->model->def->name); | |
240 | return; | |
241 | } | |
242 | set_bit(feat, cpu->model->features); | |
243 | } else { | |
244 | clear_bit(feat, cpu->model->features); | |
245 | } | |
246 | } | |
247 | ||
248 | static void get_feature_group(Object *obj, Visitor *v, const char *name, | |
249 | void *opaque, Error **errp) | |
250 | { | |
251 | S390FeatGroup group = (S390FeatGroup) opaque; | |
252 | const S390FeatGroupDef *def = s390_feat_group_def(group); | |
253 | S390CPU *cpu = S390_CPU(obj); | |
254 | S390FeatBitmap tmp; | |
255 | bool value; | |
256 | ||
257 | if (!cpu->model) { | |
258 | error_setg(errp, "Details about the host CPU model are not available, " | |
259 | "features cannot be queried."); | |
260 | return; | |
261 | } | |
262 | ||
263 | /* a group is enabled if all features are enabled */ | |
264 | bitmap_and(tmp, cpu->model->features, def->feat, S390_FEAT_MAX); | |
265 | value = bitmap_equal(tmp, def->feat, S390_FEAT_MAX); | |
266 | visit_type_bool(v, name, &value, errp); | |
267 | } | |
268 | ||
269 | static void set_feature_group(Object *obj, Visitor *v, const char *name, | |
270 | void *opaque, Error **errp) | |
271 | { | |
272 | S390FeatGroup group = (S390FeatGroup) opaque; | |
273 | const S390FeatGroupDef *def = s390_feat_group_def(group); | |
274 | DeviceState *dev = DEVICE(obj); | |
275 | S390CPU *cpu = S390_CPU(obj); | |
276 | bool value; | |
277 | ||
278 | if (dev->realized) { | |
279 | error_setg(errp, "Attempt to set property '%s' on '%s' after " | |
280 | "it was realized", name, object_get_typename(obj)); | |
281 | return; | |
282 | } else if (!cpu->model) { | |
283 | error_setg(errp, "Details about the host CPU model are not available, " | |
284 | "features cannot be changed."); | |
285 | return; | |
286 | } | |
287 | ||
288 | visit_type_bool(v, name, &value, errp); | |
289 | if (*errp) { | |
290 | return; | |
291 | } | |
292 | if (value) { | |
293 | /* groups are added in one shot, so an intersect is sufficient */ | |
294 | if (!bitmap_intersects(def->feat, cpu->model->def->full_feat, | |
295 | S390_FEAT_MAX)) { | |
296 | error_setg(errp, "Group '%s' is not available for CPU model '%s'," | |
297 | " it was introduced with later models.", | |
298 | name, cpu->model->def->name); | |
299 | return; | |
300 | } | |
301 | bitmap_or(cpu->model->features, cpu->model->features, def->feat, | |
302 | S390_FEAT_MAX); | |
303 | } else { | |
304 | bitmap_andnot(cpu->model->features, cpu->model->features, def->feat, | |
305 | S390_FEAT_MAX); | |
306 | } | |
307 | } | |
308 | ||
309 | void s390_cpu_model_register_props(Object *obj) | |
310 | { | |
311 | S390FeatGroup group; | |
312 | S390Feat feat; | |
313 | ||
314 | for (feat = 0; feat < S390_FEAT_MAX; feat++) { | |
315 | const S390FeatDef *def = s390_feat_def(feat); | |
316 | object_property_add(obj, def->name, "bool", get_feature, | |
317 | set_feature, NULL, (void *) feat, NULL); | |
318 | object_property_set_description(obj, def->name, def->desc , NULL); | |
319 | } | |
320 | for (group = 0; group < S390_FEAT_GROUP_MAX; group++) { | |
321 | const S390FeatGroupDef *def = s390_feat_group_def(group); | |
322 | object_property_add(obj, def->name, "bool", get_feature_group, | |
323 | set_feature_group, NULL, (void *) group, NULL); | |
324 | object_property_set_description(obj, def->name, def->desc , NULL); | |
325 | } | |
326 | } | |
327 | ||
6c064de1 DH |
328 | static void s390_cpu_model_initfn(Object *obj) |
329 | { | |
ad5afd07 DH |
330 | S390CPU *cpu = S390_CPU(obj); |
331 | S390CPUClass *xcc = S390_CPU_GET_CLASS(cpu); | |
332 | ||
333 | cpu->model = g_malloc0(sizeof(*cpu->model)); | |
334 | /* copy the model, so we can modify it */ | |
335 | cpu->model->def = xcc->cpu_def; | |
336 | if (xcc->is_static) { | |
337 | /* base model - features will never change */ | |
338 | bitmap_copy(cpu->model->features, cpu->model->def->base_feat, | |
339 | S390_FEAT_MAX); | |
340 | } else { | |
341 | /* latest model - features can change */ | |
342 | bitmap_copy(cpu->model->features, | |
343 | cpu->model->def->default_feat, S390_FEAT_MAX); | |
344 | } | |
6c064de1 DH |
345 | } |
346 | ||
41868f84 DH |
347 | #ifdef CONFIG_KVM |
348 | static void s390_host_cpu_model_initfn(Object *obj) | |
349 | { | |
350 | } | |
351 | #endif | |
352 | ||
353 | static void s390_qemu_cpu_model_initfn(Object *obj) | |
354 | { | |
ad5afd07 DH |
355 | S390CPU *cpu = S390_CPU(obj); |
356 | ||
357 | cpu->model = g_malloc0(sizeof(*cpu->model)); | |
358 | /* TCG emulates a z900 */ | |
359 | cpu->model->def = &s390_cpu_defs[0]; | |
360 | bitmap_copy(cpu->model->features, cpu->model->def->default_feat, | |
361 | S390_FEAT_MAX); | |
41868f84 DH |
362 | } |
363 | ||
364 | static void s390_cpu_model_finalize(Object *obj) | |
365 | { | |
ad5afd07 DH |
366 | S390CPU *cpu = S390_CPU(obj); |
367 | ||
368 | g_free(cpu->model); | |
369 | cpu->model = NULL; | |
41868f84 DH |
370 | } |
371 | ||
6efadc90 DH |
372 | static bool get_is_migration_safe(Object *obj, Error **errp) |
373 | { | |
374 | return S390_CPU_GET_CLASS(obj)->is_migration_safe; | |
375 | } | |
376 | ||
377 | static bool get_is_static(Object *obj, Error **errp) | |
378 | { | |
379 | return S390_CPU_GET_CLASS(obj)->is_static; | |
380 | } | |
381 | ||
382 | static char *get_description(Object *obj, Error **errp) | |
383 | { | |
384 | return g_strdup(S390_CPU_GET_CLASS(obj)->desc); | |
385 | } | |
386 | ||
387 | void s390_cpu_model_class_register_props(ObjectClass *oc) | |
388 | { | |
389 | object_class_property_add_bool(oc, "migration-safe", get_is_migration_safe, | |
390 | NULL, NULL); | |
391 | object_class_property_add_bool(oc, "static", get_is_static, | |
392 | NULL, NULL); | |
393 | object_class_property_add_str(oc, "description", get_description, NULL, | |
394 | NULL); | |
395 | } | |
396 | ||
41868f84 DH |
397 | #ifdef CONFIG_KVM |
398 | static void s390_host_cpu_model_class_init(ObjectClass *oc, void *data) | |
399 | { | |
400 | S390CPUClass *xcc = S390_CPU_CLASS(oc); | |
401 | ||
402 | xcc->kvm_required = true; | |
403 | xcc->desc = "KVM only: All recognized features"; | |
404 | } | |
405 | #endif | |
406 | ||
6c064de1 DH |
407 | static void s390_base_cpu_model_class_init(ObjectClass *oc, void *data) |
408 | { | |
409 | S390CPUClass *xcc = S390_CPU_CLASS(oc); | |
410 | ||
411 | /* all base models are migration safe */ | |
412 | xcc->cpu_def = (const S390CPUDef *) data; | |
413 | xcc->is_migration_safe = true; | |
414 | xcc->is_static = true; | |
415 | xcc->desc = xcc->cpu_def->desc; | |
416 | } | |
417 | ||
418 | static void s390_cpu_model_class_init(ObjectClass *oc, void *data) | |
419 | { | |
420 | S390CPUClass *xcc = S390_CPU_CLASS(oc); | |
421 | ||
422 | /* model that can change between QEMU versions */ | |
423 | xcc->cpu_def = (const S390CPUDef *) data; | |
424 | xcc->is_migration_safe = true; | |
425 | xcc->desc = xcc->cpu_def->desc; | |
426 | } | |
427 | ||
41868f84 DH |
428 | static void s390_qemu_cpu_model_class_init(ObjectClass *oc, void *data) |
429 | { | |
430 | S390CPUClass *xcc = S390_CPU_CLASS(oc); | |
431 | ||
432 | xcc->is_migration_safe = true; | |
433 | xcc->desc = g_strdup_printf("QEMU Virtual CPU version %s", | |
434 | qemu_hw_version()); | |
435 | } | |
436 | ||
437 | #define S390_CPU_TYPE_SUFFIX "-" TYPE_S390_CPU | |
438 | #define S390_CPU_TYPE_NAME(name) (name S390_CPU_TYPE_SUFFIX) | |
439 | ||
440 | /* Generate type name for a cpu model. Caller has to free the string. */ | |
441 | static char *s390_cpu_type_name(const char *model_name) | |
442 | { | |
443 | return g_strdup_printf(S390_CPU_TYPE_NAME("%s"), model_name); | |
444 | } | |
445 | ||
6c064de1 DH |
446 | /* Generate type name for a base cpu model. Caller has to free the string. */ |
447 | static char *s390_base_cpu_type_name(const char *model_name) | |
448 | { | |
449 | return g_strdup_printf(S390_CPU_TYPE_NAME("%s-base"), model_name); | |
450 | } | |
451 | ||
41868f84 DH |
452 | ObjectClass *s390_cpu_class_by_name(const char *name) |
453 | { | |
454 | char *typename = s390_cpu_type_name(name); | |
455 | ObjectClass *oc; | |
456 | ||
457 | oc = object_class_by_name(typename); | |
458 | g_free(typename); | |
459 | return oc; | |
460 | } | |
461 | ||
462 | static const TypeInfo qemu_s390_cpu_type_info = { | |
463 | .name = S390_CPU_TYPE_NAME("qemu"), | |
464 | .parent = TYPE_S390_CPU, | |
465 | .instance_init = s390_qemu_cpu_model_initfn, | |
466 | .instance_finalize = s390_cpu_model_finalize, | |
467 | .class_init = s390_qemu_cpu_model_class_init, | |
468 | }; | |
469 | ||
470 | #ifdef CONFIG_KVM | |
471 | static const TypeInfo host_s390_cpu_type_info = { | |
472 | .name = S390_CPU_TYPE_NAME("host"), | |
473 | .parent = TYPE_S390_CPU, | |
474 | .instance_init = s390_host_cpu_model_initfn, | |
475 | .instance_finalize = s390_cpu_model_finalize, | |
476 | .class_init = s390_host_cpu_model_class_init, | |
477 | }; | |
478 | #endif | |
479 | ||
480 | static void register_types(void) | |
481 | { | |
6c064de1 DH |
482 | int i; |
483 | ||
484 | /* init all bitmaps from gnerated data initially */ | |
485 | for (i = 0; i < ARRAY_SIZE(s390_cpu_defs); i++) { | |
486 | s390_init_feat_bitmap(s390_cpu_defs[i].base_init, | |
487 | s390_cpu_defs[i].base_feat); | |
488 | s390_init_feat_bitmap(s390_cpu_defs[i].default_init, | |
489 | s390_cpu_defs[i].default_feat); | |
490 | s390_init_feat_bitmap(s390_cpu_defs[i].full_init, | |
491 | s390_cpu_defs[i].full_feat); | |
492 | } | |
493 | ||
494 | for (i = 0; i < ARRAY_SIZE(s390_cpu_defs); i++) { | |
495 | char *base_name = s390_base_cpu_type_name(s390_cpu_defs[i].name); | |
496 | TypeInfo ti_base = { | |
497 | .name = base_name, | |
498 | .parent = TYPE_S390_CPU, | |
499 | .instance_init = s390_cpu_model_initfn, | |
500 | .instance_finalize = s390_cpu_model_finalize, | |
501 | .class_init = s390_base_cpu_model_class_init, | |
502 | .class_data = (void *) &s390_cpu_defs[i], | |
503 | }; | |
504 | char *name = s390_cpu_type_name(s390_cpu_defs[i].name); | |
505 | TypeInfo ti = { | |
506 | .name = name, | |
507 | .parent = TYPE_S390_CPU, | |
508 | .instance_init = s390_cpu_model_initfn, | |
509 | .instance_finalize = s390_cpu_model_finalize, | |
510 | .class_init = s390_cpu_model_class_init, | |
511 | .class_data = (void *) &s390_cpu_defs[i], | |
512 | }; | |
513 | ||
514 | type_register_static(&ti_base); | |
515 | type_register_static(&ti); | |
516 | g_free(base_name); | |
517 | g_free(name); | |
518 | } | |
519 | ||
41868f84 DH |
520 | type_register_static(&qemu_s390_cpu_type_info); |
521 | #ifdef CONFIG_KVM | |
522 | type_register_static(&host_s390_cpu_type_info); | |
523 | #endif | |
524 | } | |
525 | ||
526 | type_init(register_types) |