root / target-unicore32 / cpu.c @ 088383e3
History | View | Annotate | Download (4 kB)
1 | ae0f5e9e | Andreas Färber | /*
|
---|---|---|---|
2 | ae0f5e9e | Andreas Färber | * QEMU UniCore32 CPU
|
3 | ae0f5e9e | Andreas Färber | *
|
4 | d48813dd | Guan Xuetao | * Copyright (c) 2010-2012 Guan Xuetao
|
5 | ae0f5e9e | Andreas Färber | * Copyright (c) 2012 SUSE LINUX Products GmbH
|
6 | ae0f5e9e | Andreas Färber | *
|
7 | ae0f5e9e | Andreas Färber | * This program is free software; you can redistribute it and/or modify
|
8 | ae0f5e9e | Andreas Färber | * it under the terms of the GNU General Public License version 2 as
|
9 | ae0f5e9e | Andreas Färber | * published by the Free Software Foundation.
|
10 | ae0f5e9e | Andreas Färber | *
|
11 | ae0f5e9e | Andreas Färber | * Contributions from 2012-04-01 on are considered under GPL version 2,
|
12 | ae0f5e9e | Andreas Färber | * or (at your option) any later version.
|
13 | ae0f5e9e | Andreas Färber | */
|
14 | ae0f5e9e | Andreas Färber | |
15 | 3993c6bd | Andreas Färber | #include "cpu.h" |
16 | ae0f5e9e | Andreas Färber | #include "qemu-common.h" |
17 | 88e28512 | Andreas Färber | #include "migration/vmstate.h" |
18 | ae0f5e9e | Andreas Färber | |
19 | 8df9082d | Andreas Färber | static inline void set_feature(CPUUniCore32State *env, int feature) |
20 | 8df9082d | Andreas Färber | { |
21 | 8df9082d | Andreas Färber | env->features |= feature; |
22 | 8df9082d | Andreas Färber | } |
23 | 8df9082d | Andreas Färber | |
24 | ae0f5e9e | Andreas Färber | /* CPU models */
|
25 | ae0f5e9e | Andreas Färber | |
26 | d89e1218 | Andreas Färber | static ObjectClass *uc32_cpu_class_by_name(const char *cpu_model) |
27 | d89e1218 | Andreas Färber | { |
28 | d89e1218 | Andreas Färber | ObjectClass *oc; |
29 | eeb266de | Andreas Färber | char *typename;
|
30 | d89e1218 | Andreas Färber | |
31 | d89e1218 | Andreas Färber | if (cpu_model == NULL) { |
32 | d89e1218 | Andreas Färber | return NULL; |
33 | d89e1218 | Andreas Färber | } |
34 | d89e1218 | Andreas Färber | |
35 | eeb266de | Andreas Färber | typename = g_strdup_printf("%s-" TYPE_UNICORE32_CPU, cpu_model);
|
36 | eeb266de | Andreas Färber | oc = object_class_by_name(typename); |
37 | eeb266de | Andreas Färber | g_free(typename); |
38 | 4933908a | Andreas Färber | if (oc != NULL && (!object_class_dynamic_cast(oc, TYPE_UNICORE32_CPU) || |
39 | 4933908a | Andreas Färber | object_class_is_abstract(oc))) { |
40 | d89e1218 | Andreas Färber | oc = NULL;
|
41 | d89e1218 | Andreas Färber | } |
42 | d89e1218 | Andreas Färber | return oc;
|
43 | d89e1218 | Andreas Färber | } |
44 | d89e1218 | Andreas Färber | |
45 | ae0f5e9e | Andreas Färber | typedef struct UniCore32CPUInfo { |
46 | ae0f5e9e | Andreas Färber | const char *name; |
47 | ae0f5e9e | Andreas Färber | void (*instance_init)(Object *obj);
|
48 | ae0f5e9e | Andreas Färber | } UniCore32CPUInfo; |
49 | ae0f5e9e | Andreas Färber | |
50 | ae0f5e9e | Andreas Färber | static void unicore_ii_cpu_initfn(Object *obj) |
51 | ae0f5e9e | Andreas Färber | { |
52 | ae0f5e9e | Andreas Färber | UniCore32CPU *cpu = UNICORE32_CPU(obj); |
53 | ae0f5e9e | Andreas Färber | CPUUniCore32State *env = &cpu->env; |
54 | ae0f5e9e | Andreas Färber | |
55 | d48813dd | Guan Xuetao | env->cp0.c0_cpuid = 0x4d000863;
|
56 | d48813dd | Guan Xuetao | env->cp0.c0_cachetype = 0x0d152152;
|
57 | d48813dd | Guan Xuetao | env->cp0.c1_sys = 0x2000;
|
58 | d48813dd | Guan Xuetao | env->cp0.c2_base = 0x0;
|
59 | d48813dd | Guan Xuetao | env->cp0.c3_faultstatus = 0x0;
|
60 | d48813dd | Guan Xuetao | env->cp0.c4_faultaddr = 0x0;
|
61 | d48813dd | Guan Xuetao | env->ucf64.xregs[UC32_UCF64_FPSCR] = 0;
|
62 | 8df9082d | Andreas Färber | |
63 | 8df9082d | Andreas Färber | set_feature(env, UC32_HWCAP_CMOV); |
64 | 8df9082d | Andreas Färber | set_feature(env, UC32_HWCAP_UCF64); |
65 | ae0f5e9e | Andreas Färber | } |
66 | ae0f5e9e | Andreas Färber | |
67 | ae0f5e9e | Andreas Färber | static void uc32_any_cpu_initfn(Object *obj) |
68 | ae0f5e9e | Andreas Färber | { |
69 | ae0f5e9e | Andreas Färber | UniCore32CPU *cpu = UNICORE32_CPU(obj); |
70 | ae0f5e9e | Andreas Färber | CPUUniCore32State *env = &cpu->env; |
71 | ae0f5e9e | Andreas Färber | |
72 | ae0f5e9e | Andreas Färber | env->cp0.c0_cpuid = 0xffffffff;
|
73 | d48813dd | Guan Xuetao | env->ucf64.xregs[UC32_UCF64_FPSCR] = 0;
|
74 | 8df9082d | Andreas Färber | |
75 | 8df9082d | Andreas Färber | set_feature(env, UC32_HWCAP_CMOV); |
76 | 8df9082d | Andreas Färber | set_feature(env, UC32_HWCAP_UCF64); |
77 | ae0f5e9e | Andreas Färber | } |
78 | ae0f5e9e | Andreas Färber | |
79 | ae0f5e9e | Andreas Färber | static const UniCore32CPUInfo uc32_cpus[] = { |
80 | ae0f5e9e | Andreas Färber | { .name = "UniCore-II", .instance_init = unicore_ii_cpu_initfn },
|
81 | ae0f5e9e | Andreas Färber | { .name = "any", .instance_init = uc32_any_cpu_initfn },
|
82 | ae0f5e9e | Andreas Färber | }; |
83 | ae0f5e9e | Andreas Färber | |
84 | 088383e3 | Andreas Färber | static void uc32_cpu_realizefn(DeviceState *dev, Error **errp) |
85 | 088383e3 | Andreas Färber | { |
86 | 088383e3 | Andreas Färber | UniCore32CPU *cpu = UNICORE32_CPU(dev); |
87 | 088383e3 | Andreas Färber | UniCore32CPUClass *ucc = UNICORE32_CPU_GET_CLASS(dev); |
88 | 088383e3 | Andreas Färber | |
89 | 088383e3 | Andreas Färber | qemu_init_vcpu(&cpu->env); |
90 | 088383e3 | Andreas Färber | |
91 | 088383e3 | Andreas Färber | ucc->parent_realize(dev, errp); |
92 | 088383e3 | Andreas Färber | } |
93 | 088383e3 | Andreas Färber | |
94 | ae0f5e9e | Andreas Färber | static void uc32_cpu_initfn(Object *obj) |
95 | ae0f5e9e | Andreas Färber | { |
96 | ae0f5e9e | Andreas Färber | UniCore32CPU *cpu = UNICORE32_CPU(obj); |
97 | ae0f5e9e | Andreas Färber | CPUUniCore32State *env = &cpu->env; |
98 | ae0f5e9e | Andreas Färber | |
99 | ae0f5e9e | Andreas Färber | cpu_exec_init(env); |
100 | ae0f5e9e | Andreas Färber | |
101 | d48813dd | Guan Xuetao | #ifdef CONFIG_USER_ONLY
|
102 | ae0f5e9e | Andreas Färber | env->uncached_asr = ASR_MODE_USER; |
103 | ae0f5e9e | Andreas Färber | env->regs[31] = 0; |
104 | d48813dd | Guan Xuetao | #else
|
105 | d48813dd | Guan Xuetao | env->uncached_asr = ASR_MODE_PRIV; |
106 | d48813dd | Guan Xuetao | env->regs[31] = 0x03000000; |
107 | d48813dd | Guan Xuetao | #endif
|
108 | ae0f5e9e | Andreas Färber | |
109 | ae0f5e9e | Andreas Färber | tlb_flush(env, 1);
|
110 | ae0f5e9e | Andreas Färber | } |
111 | ae0f5e9e | Andreas Färber | |
112 | 88e28512 | Andreas Färber | static const VMStateDescription vmstate_uc32_cpu = { |
113 | 88e28512 | Andreas Färber | .name = "cpu",
|
114 | 88e28512 | Andreas Färber | .unmigratable = 1,
|
115 | 88e28512 | Andreas Färber | }; |
116 | 88e28512 | Andreas Färber | |
117 | d89e1218 | Andreas Färber | static void uc32_cpu_class_init(ObjectClass *oc, void *data) |
118 | d89e1218 | Andreas Färber | { |
119 | 88e28512 | Andreas Färber | DeviceClass *dc = DEVICE_CLASS(oc); |
120 | d89e1218 | Andreas Färber | CPUClass *cc = CPU_CLASS(oc); |
121 | 088383e3 | Andreas Färber | UniCore32CPUClass *ucc = UNICORE32_CPU_CLASS(oc); |
122 | 088383e3 | Andreas Färber | |
123 | 088383e3 | Andreas Färber | ucc->parent_realize = dc->realize; |
124 | 088383e3 | Andreas Färber | dc->realize = uc32_cpu_realizefn; |
125 | d89e1218 | Andreas Färber | |
126 | d89e1218 | Andreas Färber | cc->class_by_name = uc32_cpu_class_by_name; |
127 | 88e28512 | Andreas Färber | dc->vmsd = &vmstate_uc32_cpu; |
128 | d89e1218 | Andreas Färber | } |
129 | d89e1218 | Andreas Färber | |
130 | ae0f5e9e | Andreas Färber | static void uc32_register_cpu_type(const UniCore32CPUInfo *info) |
131 | ae0f5e9e | Andreas Färber | { |
132 | ae0f5e9e | Andreas Färber | TypeInfo type_info = { |
133 | ae0f5e9e | Andreas Färber | .parent = TYPE_UNICORE32_CPU, |
134 | ae0f5e9e | Andreas Färber | .instance_init = info->instance_init, |
135 | ae0f5e9e | Andreas Färber | }; |
136 | ae0f5e9e | Andreas Färber | |
137 | eeb266de | Andreas Färber | type_info.name = g_strdup_printf("%s-" TYPE_UNICORE32_CPU, info->name);
|
138 | 87fb5811 | Andreas Färber | type_register(&type_info); |
139 | eeb266de | Andreas Färber | g_free((void *)type_info.name);
|
140 | ae0f5e9e | Andreas Färber | } |
141 | ae0f5e9e | Andreas Färber | |
142 | ae0f5e9e | Andreas Färber | static const TypeInfo uc32_cpu_type_info = { |
143 | ae0f5e9e | Andreas Färber | .name = TYPE_UNICORE32_CPU, |
144 | ae0f5e9e | Andreas Färber | .parent = TYPE_CPU, |
145 | ae0f5e9e | Andreas Färber | .instance_size = sizeof(UniCore32CPU),
|
146 | ae0f5e9e | Andreas Färber | .instance_init = uc32_cpu_initfn, |
147 | ae0f5e9e | Andreas Färber | .abstract = true,
|
148 | ae0f5e9e | Andreas Färber | .class_size = sizeof(UniCore32CPUClass),
|
149 | d89e1218 | Andreas Färber | .class_init = uc32_cpu_class_init, |
150 | ae0f5e9e | Andreas Färber | }; |
151 | ae0f5e9e | Andreas Färber | |
152 | ae0f5e9e | Andreas Färber | static void uc32_cpu_register_types(void) |
153 | ae0f5e9e | Andreas Färber | { |
154 | ae0f5e9e | Andreas Färber | int i;
|
155 | ae0f5e9e | Andreas Färber | |
156 | ae0f5e9e | Andreas Färber | type_register_static(&uc32_cpu_type_info); |
157 | ae0f5e9e | Andreas Färber | for (i = 0; i < ARRAY_SIZE(uc32_cpus); i++) { |
158 | ae0f5e9e | Andreas Färber | uc32_register_cpu_type(&uc32_cpus[i]); |
159 | ae0f5e9e | Andreas Färber | } |
160 | ae0f5e9e | Andreas Färber | } |
161 | ae0f5e9e | Andreas Färber | |
162 | ae0f5e9e | Andreas Färber | type_init(uc32_cpu_register_types) |