Statistics
| Branch: | Revision:

root / target-mips / machine.c @ df2943ba

History | View | Annotate | Download (10.6 kB)

1
#include "hw/hw.h"
2
#include "hw/boards.h"
3

    
4
#include "exec-all.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
}
29

    
30
static void save_fpu(QEMUFile *f, CPUMIPSFPUContext *fpu)
31
{
32
    int i;
33

    
34
    for(i = 0; i < 32; i++)
35
        qemu_put_be64s(f, &fpu->fpr[i].d);
36
    qemu_put_s8s(f, &fpu->fp_status.float_detect_tininess);
37
    qemu_put_s8s(f, &fpu->fp_status.float_rounding_mode);
38
    qemu_put_s8s(f, &fpu->fp_status.float_exception_flags);
39
    qemu_put_be32s(f, &fpu->fcr0);
40
    qemu_put_be32s(f, &fpu->fcr31);
41
}
42

    
43
void cpu_save(QEMUFile *f, void *opaque)
44
{
45
    CPUState *env = opaque;
46
    int i;
47

    
48
    /* Save active TC */
49
    save_tc(f, &env->active_tc);
50

    
51
    /* Save active FPU */
52
    save_fpu(f, &env->active_fpu);
53

    
54
    /* Save MVP */
55
    qemu_put_sbe32s(f, &env->mvp->CP0_MVPControl);
56
    qemu_put_sbe32s(f, &env->mvp->CP0_MVPConf0);
57
    qemu_put_sbe32s(f, &env->mvp->CP0_MVPConf1);
58

    
59
    /* Save TLB */
60
    qemu_put_be32s(f, &env->tlb->nb_tlb);
61
    qemu_put_be32s(f, &env->tlb->tlb_in_use);
62
    for(i = 0; i < MIPS_TLB_MAX; i++) {
63
        uint16_t flags = ((env->tlb->mmu.r4k.tlb[i].G << 10) |
64
                          (env->tlb->mmu.r4k.tlb[i].C0 << 7) |
65
                          (env->tlb->mmu.r4k.tlb[i].C1 << 4) |
66
                          (env->tlb->mmu.r4k.tlb[i].V0 << 3) |
67
                          (env->tlb->mmu.r4k.tlb[i].V1 << 2) |
68
                          (env->tlb->mmu.r4k.tlb[i].D0 << 1) |
69
                          (env->tlb->mmu.r4k.tlb[i].D1 << 0));
70
        uint8_t asid;
71

    
72
        qemu_put_betls(f, &env->tlb->mmu.r4k.tlb[i].VPN);
73
        qemu_put_be32s(f, &env->tlb->mmu.r4k.tlb[i].PageMask);
74
        asid = env->tlb->mmu.r4k.tlb[i].ASID;
75
        qemu_put_8s(f, &asid);
76
        qemu_put_be16s(f, &flags);
77
        qemu_put_betls(f, &env->tlb->mmu.r4k.tlb[i].PFN[0]);
78
        qemu_put_betls(f, &env->tlb->mmu.r4k.tlb[i].PFN[1]);
79
    }
80

    
81
    /* Save CPU metastate */
82
    qemu_put_be32s(f, &env->current_tc);
83
    qemu_put_be32s(f, &env->current_fpu);
84
    qemu_put_sbe32s(f, &env->error_code);
85
    qemu_put_be32s(f, &env->hflags);
86
    qemu_put_betls(f, &env->btarget);
87
    i = env->bcond;
88
    qemu_put_sbe32s(f, &i);
89

    
90
    /* Save remaining CP1 registers */
91
    qemu_put_sbe32s(f, &env->CP0_Index);
92
    qemu_put_sbe32s(f, &env->CP0_Random);
93
    qemu_put_sbe32s(f, &env->CP0_VPEControl);
94
    qemu_put_sbe32s(f, &env->CP0_VPEConf0);
95
    qemu_put_sbe32s(f, &env->CP0_VPEConf1);
96
    qemu_put_betls(f, &env->CP0_YQMask);
97
    qemu_put_betls(f, &env->CP0_VPESchedule);
98
    qemu_put_betls(f, &env->CP0_VPEScheFBack);
99
    qemu_put_sbe32s(f, &env->CP0_VPEOpt);
100
    qemu_put_betls(f, &env->CP0_EntryLo0);
101
    qemu_put_betls(f, &env->CP0_EntryLo1);
102
    qemu_put_betls(f, &env->CP0_Context);
103
    qemu_put_sbe32s(f, &env->CP0_PageMask);
104
    qemu_put_sbe32s(f, &env->CP0_PageGrain);
105
    qemu_put_sbe32s(f, &env->CP0_Wired);
106
    qemu_put_sbe32s(f, &env->CP0_SRSConf0);
107
    qemu_put_sbe32s(f, &env->CP0_SRSConf1);
108
    qemu_put_sbe32s(f, &env->CP0_SRSConf2);
109
    qemu_put_sbe32s(f, &env->CP0_SRSConf3);
110
    qemu_put_sbe32s(f, &env->CP0_SRSConf4);
111
    qemu_put_sbe32s(f, &env->CP0_HWREna);
112
    qemu_put_betls(f, &env->CP0_BadVAddr);
113
    qemu_put_sbe32s(f, &env->CP0_Count);
114
    qemu_put_betls(f, &env->CP0_EntryHi);
115
    qemu_put_sbe32s(f, &env->CP0_Compare);
116
    qemu_put_sbe32s(f, &env->CP0_Status);
117
    qemu_put_sbe32s(f, &env->CP0_IntCtl);
118
    qemu_put_sbe32s(f, &env->CP0_SRSCtl);
119
    qemu_put_sbe32s(f, &env->CP0_SRSMap);
120
    qemu_put_sbe32s(f, &env->CP0_Cause);
121
    qemu_put_betls(f, &env->CP0_EPC);
122
    qemu_put_sbe32s(f, &env->CP0_PRid);
123
    qemu_put_sbe32s(f, &env->CP0_EBase);
124
    qemu_put_sbe32s(f, &env->CP0_Config0);
125
    qemu_put_sbe32s(f, &env->CP0_Config1);
126
    qemu_put_sbe32s(f, &env->CP0_Config2);
127
    qemu_put_sbe32s(f, &env->CP0_Config3);
128
    qemu_put_sbe32s(f, &env->CP0_Config6);
129
    qemu_put_sbe32s(f, &env->CP0_Config7);
130
    qemu_put_betls(f, &env->lladdr);
131
    for(i = 0; i < 8; i++)
132
        qemu_put_betls(f, &env->CP0_WatchLo[i]);
133
    for(i = 0; i < 8; i++)
134
        qemu_put_sbe32s(f, &env->CP0_WatchHi[i]);
135
    qemu_put_betls(f, &env->CP0_XContext);
136
    qemu_put_sbe32s(f, &env->CP0_Framemask);
137
    qemu_put_sbe32s(f, &env->CP0_Debug);
138
    qemu_put_betls(f, &env->CP0_DEPC);
139
    qemu_put_sbe32s(f, &env->CP0_Performance0);
140
    qemu_put_sbe32s(f, &env->CP0_TagLo);
141
    qemu_put_sbe32s(f, &env->CP0_DataLo);
142
    qemu_put_sbe32s(f, &env->CP0_TagHi);
143
    qemu_put_sbe32s(f, &env->CP0_DataHi);
144
    qemu_put_betls(f, &env->CP0_ErrorEPC);
145
    qemu_put_sbe32s(f, &env->CP0_DESAVE);
146

    
147
    /* Save inactive TC state */
148
    for (i = 0; i < MIPS_SHADOW_SET_MAX; i++)
149
        save_tc(f, &env->tcs[i]);
150
    for (i = 0; i < MIPS_FPU_MAX; i++)
151
        save_fpu(f, &env->fpus[i]);
152
}
153

    
154
static void load_tc(QEMUFile *f, TCState *tc)
155
{
156
    int i;
157

    
158
    /* Save active TC */
159
    for(i = 0; i < 32; i++)
160
        qemu_get_betls(f, &tc->gpr[i]);
161
    qemu_get_betls(f, &tc->PC);
162
    for(i = 0; i < MIPS_DSP_ACC; i++)
163
        qemu_get_betls(f, &tc->HI[i]);
164
    for(i = 0; i < MIPS_DSP_ACC; i++)
165
        qemu_get_betls(f, &tc->LO[i]);
166
    for(i = 0; i < MIPS_DSP_ACC; i++)
167
        qemu_get_betls(f, &tc->ACX[i]);
168
    qemu_get_betls(f, &tc->DSPControl);
169
    qemu_get_sbe32s(f, &tc->CP0_TCStatus);
170
    qemu_get_sbe32s(f, &tc->CP0_TCBind);
171
    qemu_get_betls(f, &tc->CP0_TCHalt);
172
    qemu_get_betls(f, &tc->CP0_TCContext);
173
    qemu_get_betls(f, &tc->CP0_TCSchedule);
174
    qemu_get_betls(f, &tc->CP0_TCScheFBack);
175
    qemu_get_sbe32s(f, &tc->CP0_Debug_tcstatus);
176
}
177

    
178
static void load_fpu(QEMUFile *f, CPUMIPSFPUContext *fpu)
179
{
180
    int i;
181

    
182
    for(i = 0; i < 32; i++)
183
        qemu_get_be64s(f, &fpu->fpr[i].d);
184
    qemu_get_s8s(f, &fpu->fp_status.float_detect_tininess);
185
    qemu_get_s8s(f, &fpu->fp_status.float_rounding_mode);
186
    qemu_get_s8s(f, &fpu->fp_status.float_exception_flags);
187
    qemu_get_be32s(f, &fpu->fcr0);
188
    qemu_get_be32s(f, &fpu->fcr31);
189
}
190

    
191
int cpu_load(QEMUFile *f, void *opaque, int version_id)
192
{
193
    CPUState *env = opaque;
194
    int i;
195

    
196
    if (version_id != 3)
197
        return -EINVAL;
198

    
199
    /* Load active TC */
200
    load_tc(f, &env->active_tc);
201

    
202
    /* Load active FPU */
203
    load_fpu(f, &env->active_fpu);
204

    
205
    /* Load MVP */
206
    qemu_get_sbe32s(f, &env->mvp->CP0_MVPControl);
207
    qemu_get_sbe32s(f, &env->mvp->CP0_MVPConf0);
208
    qemu_get_sbe32s(f, &env->mvp->CP0_MVPConf1);
209

    
210
    /* Load TLB */
211
    qemu_get_be32s(f, &env->tlb->nb_tlb);
212
    qemu_get_be32s(f, &env->tlb->tlb_in_use);
213
    for(i = 0; i < MIPS_TLB_MAX; i++) {
214
        uint16_t flags;
215
        uint8_t asid;
216

    
217
        qemu_get_betls(f, &env->tlb->mmu.r4k.tlb[i].VPN);
218
        qemu_get_be32s(f, &env->tlb->mmu.r4k.tlb[i].PageMask);
219
        qemu_get_8s(f, &asid);
220
        env->tlb->mmu.r4k.tlb[i].ASID = asid;
221
        qemu_get_be16s(f, &flags);
222
        env->tlb->mmu.r4k.tlb[i].G = (flags >> 10) & 1;
223
        env->tlb->mmu.r4k.tlb[i].C0 = (flags >> 7) & 3;
224
        env->tlb->mmu.r4k.tlb[i].C1 = (flags >> 4) & 3;
225
        env->tlb->mmu.r4k.tlb[i].V0 = (flags >> 3) & 1;
226
        env->tlb->mmu.r4k.tlb[i].V1 = (flags >> 2) & 1;
227
        env->tlb->mmu.r4k.tlb[i].D0 = (flags >> 1) & 1;
228
        env->tlb->mmu.r4k.tlb[i].D1 = (flags >> 0) & 1;
229
        qemu_get_betls(f, &env->tlb->mmu.r4k.tlb[i].PFN[0]);
230
        qemu_get_betls(f, &env->tlb->mmu.r4k.tlb[i].PFN[1]);
231
    }
232

    
233
    /* Load CPU metastate */
234
    qemu_get_be32s(f, &env->current_tc);
235
    qemu_get_be32s(f, &env->current_fpu);
236
    qemu_get_sbe32s(f, &env->error_code);
237
    qemu_get_be32s(f, &env->hflags);
238
    qemu_get_betls(f, &env->btarget);
239
    qemu_get_sbe32s(f, &i);
240
    env->bcond = i;
241

    
242
    /* Load remaining CP1 registers */
243
    qemu_get_sbe32s(f, &env->CP0_Index);
244
    qemu_get_sbe32s(f, &env->CP0_Random);
245
    qemu_get_sbe32s(f, &env->CP0_VPEControl);
246
    qemu_get_sbe32s(f, &env->CP0_VPEConf0);
247
    qemu_get_sbe32s(f, &env->CP0_VPEConf1);
248
    qemu_get_betls(f, &env->CP0_YQMask);
249
    qemu_get_betls(f, &env->CP0_VPESchedule);
250
    qemu_get_betls(f, &env->CP0_VPEScheFBack);
251
    qemu_get_sbe32s(f, &env->CP0_VPEOpt);
252
    qemu_get_betls(f, &env->CP0_EntryLo0);
253
    qemu_get_betls(f, &env->CP0_EntryLo1);
254
    qemu_get_betls(f, &env->CP0_Context);
255
    qemu_get_sbe32s(f, &env->CP0_PageMask);
256
    qemu_get_sbe32s(f, &env->CP0_PageGrain);
257
    qemu_get_sbe32s(f, &env->CP0_Wired);
258
    qemu_get_sbe32s(f, &env->CP0_SRSConf0);
259
    qemu_get_sbe32s(f, &env->CP0_SRSConf1);
260
    qemu_get_sbe32s(f, &env->CP0_SRSConf2);
261
    qemu_get_sbe32s(f, &env->CP0_SRSConf3);
262
    qemu_get_sbe32s(f, &env->CP0_SRSConf4);
263
    qemu_get_sbe32s(f, &env->CP0_HWREna);
264
    qemu_get_betls(f, &env->CP0_BadVAddr);
265
    qemu_get_sbe32s(f, &env->CP0_Count);
266
    qemu_get_betls(f, &env->CP0_EntryHi);
267
    qemu_get_sbe32s(f, &env->CP0_Compare);
268
    qemu_get_sbe32s(f, &env->CP0_Status);
269
    qemu_get_sbe32s(f, &env->CP0_IntCtl);
270
    qemu_get_sbe32s(f, &env->CP0_SRSCtl);
271
    qemu_get_sbe32s(f, &env->CP0_SRSMap);
272
    qemu_get_sbe32s(f, &env->CP0_Cause);
273
    qemu_get_betls(f, &env->CP0_EPC);
274
    qemu_get_sbe32s(f, &env->CP0_PRid);
275
    qemu_get_sbe32s(f, &env->CP0_EBase);
276
    qemu_get_sbe32s(f, &env->CP0_Config0);
277
    qemu_get_sbe32s(f, &env->CP0_Config1);
278
    qemu_get_sbe32s(f, &env->CP0_Config2);
279
    qemu_get_sbe32s(f, &env->CP0_Config3);
280
    qemu_get_sbe32s(f, &env->CP0_Config6);
281
    qemu_get_sbe32s(f, &env->CP0_Config7);
282
    qemu_get_betls(f, &env->lladdr);
283
    for(i = 0; i < 8; i++)
284
        qemu_get_betls(f, &env->CP0_WatchLo[i]);
285
    for(i = 0; i < 8; i++)
286
        qemu_get_sbe32s(f, &env->CP0_WatchHi[i]);
287
    qemu_get_betls(f, &env->CP0_XContext);
288
    qemu_get_sbe32s(f, &env->CP0_Framemask);
289
    qemu_get_sbe32s(f, &env->CP0_Debug);
290
    qemu_get_betls(f, &env->CP0_DEPC);
291
    qemu_get_sbe32s(f, &env->CP0_Performance0);
292
    qemu_get_sbe32s(f, &env->CP0_TagLo);
293
    qemu_get_sbe32s(f, &env->CP0_DataLo);
294
    qemu_get_sbe32s(f, &env->CP0_TagHi);
295
    qemu_get_sbe32s(f, &env->CP0_DataHi);
296
    qemu_get_betls(f, &env->CP0_ErrorEPC);
297
    qemu_get_sbe32s(f, &env->CP0_DESAVE);
298

    
299
    /* Load inactive TC state */
300
    for (i = 0; i < MIPS_SHADOW_SET_MAX; i++)
301
        load_tc(f, &env->tcs[i]);
302
    for (i = 0; i < MIPS_FPU_MAX; i++)
303
        load_fpu(f, &env->fpus[i]);
304

    
305
    /* XXX: ensure compatiblity for halted bit ? */
306
    tlb_flush(env, 1);
307
    return 0;
308
}