]> Git Repo - qemu.git/blob - target-mips/machine.c
target-arm: Set CPU has_el3 prop during virt init
[qemu.git] / target-mips / machine.c
1 #include "hw/hw.h"
2 #include "hw/boards.h"
3
4 #include "cpu.h"
5
6 static void save_tc(QEMUFile *f, TCState *tc)
7 {
8     int i;
9
10     /* Save active TC */
11     for(i = 0; i < 32; i++)
12         qemu_put_betls(f, &tc->gpr[i]);
13     qemu_put_betls(f, &tc->PC);
14     for(i = 0; i < MIPS_DSP_ACC; i++)
15         qemu_put_betls(f, &tc->HI[i]);
16     for(i = 0; i < MIPS_DSP_ACC; i++)
17         qemu_put_betls(f, &tc->LO[i]);
18     for(i = 0; i < MIPS_DSP_ACC; i++)
19         qemu_put_betls(f, &tc->ACX[i]);
20     qemu_put_betls(f, &tc->DSPControl);
21     qemu_put_sbe32s(f, &tc->CP0_TCStatus);
22     qemu_put_sbe32s(f, &tc->CP0_TCBind);
23     qemu_put_betls(f, &tc->CP0_TCHalt);
24     qemu_put_betls(f, &tc->CP0_TCContext);
25     qemu_put_betls(f, &tc->CP0_TCSchedule);
26     qemu_put_betls(f, &tc->CP0_TCScheFBack);
27     qemu_put_sbe32s(f, &tc->CP0_Debug_tcstatus);
28     qemu_put_betls(f, &tc->CP0_UserLocal);
29 }
30
31 static void save_fpu(QEMUFile *f, CPUMIPSFPUContext *fpu)
32 {
33     int i;
34
35     for(i = 0; i < 32; i++)
36         qemu_put_be64s(f, &fpu->fpr[i].d);
37     qemu_put_s8s(f, &fpu->fp_status.float_detect_tininess);
38     qemu_put_s8s(f, &fpu->fp_status.float_rounding_mode);
39     qemu_put_s8s(f, &fpu->fp_status.float_exception_flags);
40     qemu_put_be32s(f, &fpu->fcr0);
41     qemu_put_be32s(f, &fpu->fcr31);
42 }
43
44 void cpu_save(QEMUFile *f, void *opaque)
45 {
46     CPUMIPSState *env = opaque;
47     int i;
48
49     /* Save active TC */
50     save_tc(f, &env->active_tc);
51
52     /* Save active FPU */
53     save_fpu(f, &env->active_fpu);
54
55     /* Save MVP */
56     qemu_put_sbe32s(f, &env->mvp->CP0_MVPControl);
57     qemu_put_sbe32s(f, &env->mvp->CP0_MVPConf0);
58     qemu_put_sbe32s(f, &env->mvp->CP0_MVPConf1);
59
60     /* Save TLB */
61     qemu_put_be32s(f, &env->tlb->nb_tlb);
62     qemu_put_be32s(f, &env->tlb->tlb_in_use);
63     for(i = 0; i < MIPS_TLB_MAX; i++) {
64         uint16_t flags = ((env->tlb->mmu.r4k.tlb[i].EHINV << 15) |
65                           (env->tlb->mmu.r4k.tlb[i].RI1 << 14) |
66                           (env->tlb->mmu.r4k.tlb[i].RI0 << 13) |
67                           (env->tlb->mmu.r4k.tlb[i].XI1 << 12) |
68                           (env->tlb->mmu.r4k.tlb[i].XI0 << 11) |
69                           (env->tlb->mmu.r4k.tlb[i].G << 10) |
70                           (env->tlb->mmu.r4k.tlb[i].C0 << 7) |
71                           (env->tlb->mmu.r4k.tlb[i].C1 << 4) |
72                           (env->tlb->mmu.r4k.tlb[i].V0 << 3) |
73                           (env->tlb->mmu.r4k.tlb[i].V1 << 2) |
74                           (env->tlb->mmu.r4k.tlb[i].D0 << 1) |
75                           (env->tlb->mmu.r4k.tlb[i].D1 << 0));
76         uint8_t asid;
77
78         qemu_put_betls(f, &env->tlb->mmu.r4k.tlb[i].VPN);
79         qemu_put_be32s(f, &env->tlb->mmu.r4k.tlb[i].PageMask);
80         asid = env->tlb->mmu.r4k.tlb[i].ASID;
81         qemu_put_8s(f, &asid);
82         qemu_put_be16s(f, &flags);
83         qemu_put_betls(f, &env->tlb->mmu.r4k.tlb[i].PFN[0]);
84         qemu_put_betls(f, &env->tlb->mmu.r4k.tlb[i].PFN[1]);
85     }
86
87     /* Save CPU metastate */
88     qemu_put_be32s(f, &env->current_tc);
89     qemu_put_be32s(f, &env->current_fpu);
90     qemu_put_sbe32s(f, &env->error_code);
91     qemu_put_be32s(f, &env->hflags);
92     qemu_put_betls(f, &env->btarget);
93     i = env->bcond;
94     qemu_put_sbe32s(f, &i);
95
96     /* Save remaining CP1 registers */
97     qemu_put_sbe32s(f, &env->CP0_Index);
98     qemu_put_sbe32s(f, &env->CP0_Random);
99     qemu_put_sbe32s(f, &env->CP0_VPEControl);
100     qemu_put_sbe32s(f, &env->CP0_VPEConf0);
101     qemu_put_sbe32s(f, &env->CP0_VPEConf1);
102     qemu_put_betls(f, &env->CP0_YQMask);
103     qemu_put_betls(f, &env->CP0_VPESchedule);
104     qemu_put_betls(f, &env->CP0_VPEScheFBack);
105     qemu_put_sbe32s(f, &env->CP0_VPEOpt);
106     qemu_put_betls(f, &env->CP0_EntryLo0);
107     qemu_put_betls(f, &env->CP0_EntryLo1);
108     qemu_put_betls(f, &env->CP0_Context);
109     qemu_put_sbe32s(f, &env->CP0_PageMask);
110     qemu_put_sbe32s(f, &env->CP0_PageGrain);
111     qemu_put_sbe32s(f, &env->CP0_Wired);
112     qemu_put_sbe32s(f, &env->CP0_SRSConf0);
113     qemu_put_sbe32s(f, &env->CP0_SRSConf1);
114     qemu_put_sbe32s(f, &env->CP0_SRSConf2);
115     qemu_put_sbe32s(f, &env->CP0_SRSConf3);
116     qemu_put_sbe32s(f, &env->CP0_SRSConf4);
117     qemu_put_sbe32s(f, &env->CP0_HWREna);
118     qemu_put_betls(f, &env->CP0_BadVAddr);
119     qemu_put_be32s(f, &env->CP0_BadInstr);
120     qemu_put_be32s(f, &env->CP0_BadInstrP);
121     qemu_put_sbe32s(f, &env->CP0_Count);
122     qemu_put_betls(f, &env->CP0_EntryHi);
123     qemu_put_sbe32s(f, &env->CP0_Compare);
124     qemu_put_sbe32s(f, &env->CP0_Status);
125     qemu_put_sbe32s(f, &env->CP0_IntCtl);
126     qemu_put_sbe32s(f, &env->CP0_SRSCtl);
127     qemu_put_sbe32s(f, &env->CP0_SRSMap);
128     qemu_put_sbe32s(f, &env->CP0_Cause);
129     qemu_put_betls(f, &env->CP0_EPC);
130     qemu_put_sbe32s(f, &env->CP0_PRid);
131     qemu_put_sbe32s(f, &env->CP0_EBase);
132     qemu_put_sbe32s(f, &env->CP0_Config0);
133     qemu_put_sbe32s(f, &env->CP0_Config1);
134     qemu_put_sbe32s(f, &env->CP0_Config2);
135     qemu_put_sbe32s(f, &env->CP0_Config3);
136     qemu_put_sbe32s(f, &env->CP0_Config6);
137     qemu_put_sbe32s(f, &env->CP0_Config7);
138     qemu_put_betls(f, &env->lladdr);
139     for(i = 0; i < 8; i++)
140         qemu_put_betls(f, &env->CP0_WatchLo[i]);
141     for(i = 0; i < 8; i++)
142         qemu_put_sbe32s(f, &env->CP0_WatchHi[i]);
143     qemu_put_betls(f, &env->CP0_XContext);
144     qemu_put_sbe32s(f, &env->CP0_Framemask);
145     qemu_put_sbe32s(f, &env->CP0_Debug);
146     qemu_put_betls(f, &env->CP0_DEPC);
147     qemu_put_sbe32s(f, &env->CP0_Performance0);
148     qemu_put_sbe32s(f, &env->CP0_TagLo);
149     qemu_put_sbe32s(f, &env->CP0_DataLo);
150     qemu_put_sbe32s(f, &env->CP0_TagHi);
151     qemu_put_sbe32s(f, &env->CP0_DataHi);
152     qemu_put_betls(f, &env->CP0_ErrorEPC);
153     qemu_put_sbe32s(f, &env->CP0_DESAVE);
154     for (i = 0; i < MIPS_KSCRATCH_NUM; i++) {
155         qemu_put_betls(f, &env->CP0_KScratch[i]);
156     }
157
158     /* Save inactive TC state */
159     for (i = 0; i < MIPS_SHADOW_SET_MAX; i++)
160         save_tc(f, &env->tcs[i]);
161     for (i = 0; i < MIPS_FPU_MAX; i++)
162         save_fpu(f, &env->fpus[i]);
163 }
164
165 static void load_tc(QEMUFile *f, TCState *tc, int version_id)
166 {
167     int i;
168
169     /* Save active TC */
170     for(i = 0; i < 32; i++)
171         qemu_get_betls(f, &tc->gpr[i]);
172     qemu_get_betls(f, &tc->PC);
173     for(i = 0; i < MIPS_DSP_ACC; i++)
174         qemu_get_betls(f, &tc->HI[i]);
175     for(i = 0; i < MIPS_DSP_ACC; i++)
176         qemu_get_betls(f, &tc->LO[i]);
177     for(i = 0; i < MIPS_DSP_ACC; i++)
178         qemu_get_betls(f, &tc->ACX[i]);
179     qemu_get_betls(f, &tc->DSPControl);
180     qemu_get_sbe32s(f, &tc->CP0_TCStatus);
181     qemu_get_sbe32s(f, &tc->CP0_TCBind);
182     qemu_get_betls(f, &tc->CP0_TCHalt);
183     qemu_get_betls(f, &tc->CP0_TCContext);
184     qemu_get_betls(f, &tc->CP0_TCSchedule);
185     qemu_get_betls(f, &tc->CP0_TCScheFBack);
186     qemu_get_sbe32s(f, &tc->CP0_Debug_tcstatus);
187     if (version_id >= 4) {
188         qemu_get_betls(f, &tc->CP0_UserLocal);
189     }
190 }
191
192 static void load_fpu(QEMUFile *f, CPUMIPSFPUContext *fpu)
193 {
194     int i;
195
196     for(i = 0; i < 32; i++)
197         qemu_get_be64s(f, &fpu->fpr[i].d);
198     qemu_get_s8s(f, &fpu->fp_status.float_detect_tininess);
199     qemu_get_s8s(f, &fpu->fp_status.float_rounding_mode);
200     qemu_get_s8s(f, &fpu->fp_status.float_exception_flags);
201     qemu_get_be32s(f, &fpu->fcr0);
202     qemu_get_be32s(f, &fpu->fcr31);
203 }
204
205 int cpu_load(QEMUFile *f, void *opaque, int version_id)
206 {
207     CPUMIPSState *env = opaque;
208     MIPSCPU *cpu = mips_env_get_cpu(env);
209     int i;
210
211     if (version_id < 3) {
212         return -EINVAL;
213     }
214
215     /* Load active TC */
216     load_tc(f, &env->active_tc, version_id);
217
218     /* Load active FPU */
219     load_fpu(f, &env->active_fpu);
220
221     /* Load MVP */
222     qemu_get_sbe32s(f, &env->mvp->CP0_MVPControl);
223     qemu_get_sbe32s(f, &env->mvp->CP0_MVPConf0);
224     qemu_get_sbe32s(f, &env->mvp->CP0_MVPConf1);
225
226     /* Load TLB */
227     qemu_get_be32s(f, &env->tlb->nb_tlb);
228     qemu_get_be32s(f, &env->tlb->tlb_in_use);
229     for(i = 0; i < MIPS_TLB_MAX; i++) {
230         uint16_t flags;
231         uint8_t asid;
232
233         qemu_get_betls(f, &env->tlb->mmu.r4k.tlb[i].VPN);
234         qemu_get_be32s(f, &env->tlb->mmu.r4k.tlb[i].PageMask);
235         qemu_get_8s(f, &asid);
236         env->tlb->mmu.r4k.tlb[i].ASID = asid;
237         qemu_get_be16s(f, &flags);
238         env->tlb->mmu.r4k.tlb[i].G = (flags >> 10) & 1;
239         env->tlb->mmu.r4k.tlb[i].C0 = (flags >> 7) & 3;
240         env->tlb->mmu.r4k.tlb[i].C1 = (flags >> 4) & 3;
241         env->tlb->mmu.r4k.tlb[i].V0 = (flags >> 3) & 1;
242         env->tlb->mmu.r4k.tlb[i].V1 = (flags >> 2) & 1;
243         env->tlb->mmu.r4k.tlb[i].D0 = (flags >> 1) & 1;
244         env->tlb->mmu.r4k.tlb[i].D1 = (flags >> 0) & 1;
245         if (version_id >= 5) {
246             env->tlb->mmu.r4k.tlb[i].EHINV = (flags >> 15) & 1;
247             env->tlb->mmu.r4k.tlb[i].RI1 = (flags >> 14) & 1;
248             env->tlb->mmu.r4k.tlb[i].RI0 = (flags >> 13) & 1;
249             env->tlb->mmu.r4k.tlb[i].XI1 = (flags >> 12) & 1;
250             env->tlb->mmu.r4k.tlb[i].XI0 = (flags >> 11) & 1;
251         }
252         qemu_get_betls(f, &env->tlb->mmu.r4k.tlb[i].PFN[0]);
253         qemu_get_betls(f, &env->tlb->mmu.r4k.tlb[i].PFN[1]);
254     }
255
256     /* Load CPU metastate */
257     qemu_get_be32s(f, &env->current_tc);
258     qemu_get_be32s(f, &env->current_fpu);
259     qemu_get_sbe32s(f, &env->error_code);
260     qemu_get_be32s(f, &env->hflags);
261     qemu_get_betls(f, &env->btarget);
262     qemu_get_sbe32s(f, &i);
263     env->bcond = i;
264
265     /* Load remaining CP1 registers */
266     qemu_get_sbe32s(f, &env->CP0_Index);
267     qemu_get_sbe32s(f, &env->CP0_Random);
268     qemu_get_sbe32s(f, &env->CP0_VPEControl);
269     qemu_get_sbe32s(f, &env->CP0_VPEConf0);
270     qemu_get_sbe32s(f, &env->CP0_VPEConf1);
271     qemu_get_betls(f, &env->CP0_YQMask);
272     qemu_get_betls(f, &env->CP0_VPESchedule);
273     qemu_get_betls(f, &env->CP0_VPEScheFBack);
274     qemu_get_sbe32s(f, &env->CP0_VPEOpt);
275     qemu_get_betls(f, &env->CP0_EntryLo0);
276     qemu_get_betls(f, &env->CP0_EntryLo1);
277     qemu_get_betls(f, &env->CP0_Context);
278     qemu_get_sbe32s(f, &env->CP0_PageMask);
279     qemu_get_sbe32s(f, &env->CP0_PageGrain);
280     qemu_get_sbe32s(f, &env->CP0_Wired);
281     qemu_get_sbe32s(f, &env->CP0_SRSConf0);
282     qemu_get_sbe32s(f, &env->CP0_SRSConf1);
283     qemu_get_sbe32s(f, &env->CP0_SRSConf2);
284     qemu_get_sbe32s(f, &env->CP0_SRSConf3);
285     qemu_get_sbe32s(f, &env->CP0_SRSConf4);
286     qemu_get_sbe32s(f, &env->CP0_HWREna);
287     qemu_get_betls(f, &env->CP0_BadVAddr);
288     qemu_get_sbe32s(f, &env->CP0_Count);
289     qemu_get_betls(f, &env->CP0_EntryHi);
290     qemu_get_sbe32s(f, &env->CP0_Compare);
291     qemu_get_sbe32s(f, &env->CP0_Status);
292     qemu_get_sbe32s(f, &env->CP0_IntCtl);
293     qemu_get_sbe32s(f, &env->CP0_SRSCtl);
294     qemu_get_sbe32s(f, &env->CP0_SRSMap);
295     qemu_get_sbe32s(f, &env->CP0_Cause);
296     qemu_get_betls(f, &env->CP0_EPC);
297     qemu_get_sbe32s(f, &env->CP0_PRid);
298     qemu_get_sbe32s(f, &env->CP0_EBase);
299     qemu_get_sbe32s(f, &env->CP0_Config0);
300     qemu_get_sbe32s(f, &env->CP0_Config1);
301     qemu_get_sbe32s(f, &env->CP0_Config2);
302     qemu_get_sbe32s(f, &env->CP0_Config3);
303     qemu_get_sbe32s(f, &env->CP0_Config6);
304     qemu_get_sbe32s(f, &env->CP0_Config7);
305     qemu_get_betls(f, &env->lladdr);
306     for(i = 0; i < 8; i++)
307         qemu_get_betls(f, &env->CP0_WatchLo[i]);
308     for(i = 0; i < 8; i++)
309         qemu_get_sbe32s(f, &env->CP0_WatchHi[i]);
310     qemu_get_betls(f, &env->CP0_XContext);
311     qemu_get_sbe32s(f, &env->CP0_Framemask);
312     qemu_get_sbe32s(f, &env->CP0_Debug);
313     qemu_get_betls(f, &env->CP0_DEPC);
314     qemu_get_sbe32s(f, &env->CP0_Performance0);
315     qemu_get_sbe32s(f, &env->CP0_TagLo);
316     qemu_get_sbe32s(f, &env->CP0_DataLo);
317     qemu_get_sbe32s(f, &env->CP0_TagHi);
318     qemu_get_sbe32s(f, &env->CP0_DataHi);
319     qemu_get_betls(f, &env->CP0_ErrorEPC);
320     qemu_get_sbe32s(f, &env->CP0_DESAVE);
321     if (version_id >= 5) {
322         qemu_get_be32s(f, &env->CP0_BadInstr);
323         qemu_get_be32s(f, &env->CP0_BadInstrP);
324         for (i = 0; i < MIPS_KSCRATCH_NUM; i++) {
325             qemu_get_betls(f, &env->CP0_KScratch[i]);
326         }
327     }
328
329     /* Load inactive TC state */
330     for (i = 0; i < MIPS_SHADOW_SET_MAX; i++) {
331         load_tc(f, &env->tcs[i], version_id);
332     }
333     for (i = 0; i < MIPS_FPU_MAX; i++)
334         load_fpu(f, &env->fpus[i]);
335
336     /* XXX: ensure compatibility for halted bit ? */
337     tlb_flush(CPU(cpu), 1);
338     return 0;
339 }
This page took 0.042262 seconds and 4 git commands to generate.