Statistics
| Branch: | Revision:

root / target-ppc / translate_init.c @ 173d6cfe

History | View | Annotate | Download (59.1 kB)

1
/*
2
 *  PowerPC CPU initialization for qemu.
3
 * 
4
 *  Copyright (c) 2003-2005 Jocelyn Mayer
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 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, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 */
20

    
21
/* A lot of PowerPC definition have been included here.
22
 * Most of them are not usable for now but have been kept
23
 * inside "#if defined(TODO) ... #endif" statements to make tests easier.
24
 */
25

    
26
//#define PPC_DUMP_CPU
27
//#define PPC_DEBUG_SPR
28

    
29
struct ppc_def_t {
30
    const unsigned char *name;
31
    uint32_t pvr;
32
    uint32_t pvr_mask;
33
    uint32_t insns_flags;
34
    uint32_t flags;
35
    uint64_t msr_mask;
36
};
37

    
38
/* Generic callbacks:
39
 * do nothing but store/retrieve spr value
40
 */
41
static void spr_read_generic (void *opaque, int sprn)
42
{
43
    gen_op_load_spr(sprn);
44
}
45

    
46
static void spr_write_generic (void *opaque, int sprn)
47
{
48
    gen_op_store_spr(sprn);
49
}
50

    
51
/* SPR common to all PPC */
52
/* XER */
53
static void spr_read_xer (void *opaque, int sprn)
54
{
55
    gen_op_load_xer();
56
}
57

    
58
static void spr_write_xer (void *opaque, int sprn)
59
{
60
    gen_op_store_xer();
61
}
62

    
63
/* LR */
64
static void spr_read_lr (void *opaque, int sprn)
65
{
66
    gen_op_load_lr();
67
}
68

    
69
static void spr_write_lr (void *opaque, int sprn)
70
{
71
    gen_op_store_lr();
72
}
73

    
74
/* CTR */
75
static void spr_read_ctr (void *opaque, int sprn)
76
{
77
    gen_op_load_ctr();
78
}
79

    
80
static void spr_write_ctr (void *opaque, int sprn)
81
{
82
    gen_op_store_ctr();
83
}
84

    
85
/* User read access to SPR */
86
/* USPRx */
87
/* UMMCRx */
88
/* UPMCx */
89
/* USIA */
90
/* UDECR */
91
static void spr_read_ureg (void *opaque, int sprn)
92
{
93
    gen_op_load_spr(sprn + 0x10);
94
}
95

    
96
/* SPR common to all non-embedded PPC (ie not 4xx) */
97
/* DECR */
98
static void spr_read_decr (void *opaque, int sprn)
99
{
100
    gen_op_load_decr();
101
}
102

    
103
static void spr_write_decr (void *opaque, int sprn)
104
{
105
    gen_op_store_decr();
106
}
107

    
108
/* SPR common to all non-embedded PPC, except 601 */
109
/* Time base */
110
static void spr_read_tbl (void *opaque, int sprn)
111
{
112
    gen_op_load_tbl();
113
}
114

    
115
static void spr_write_tbl (void *opaque, int sprn)
116
{
117
    gen_op_store_tbl();
118
}
119

    
120
static void spr_read_tbu (void *opaque, int sprn)
121
{
122
    gen_op_load_tbu();
123
}
124

    
125
static void spr_write_tbu (void *opaque, int sprn)
126
{
127
    gen_op_store_tbu();
128
}
129

    
130
/* IBAT0U...IBAT0U */
131
/* IBAT0L...IBAT7L */
132
static void spr_read_ibat (void *opaque, int sprn)
133
{
134
    gen_op_load_ibat(sprn & 1, (sprn - SPR_IBAT0U) / 2);
135
}
136

    
137
static void spr_read_ibat_h (void *opaque, int sprn)
138
{
139
    gen_op_load_ibat(sprn & 1, (sprn - SPR_IBAT4U) / 2);
140
}
141

    
142
static void spr_write_ibatu (void *opaque, int sprn)
143
{
144
    DisasContext *ctx = opaque;
145

    
146
    gen_op_store_ibatu((sprn - SPR_IBAT0U) / 2);
147
    RET_STOP(ctx);
148
}
149

    
150
static void spr_write_ibatu_h (void *opaque, int sprn)
151
{
152
    DisasContext *ctx = opaque;
153

    
154
    gen_op_store_ibatu((sprn - SPR_IBAT4U) / 2);
155
    RET_STOP(ctx);
156
}
157

    
158
static void spr_write_ibatl (void *opaque, int sprn)
159
{
160
    DisasContext *ctx = opaque;
161

    
162
    gen_op_store_ibatl((sprn - SPR_IBAT0L) / 2);
163
    RET_STOP(ctx);
164
}
165

    
166
static void spr_write_ibatl_h (void *opaque, int sprn)
167
{
168
    DisasContext *ctx = opaque;
169

    
170
    gen_op_store_ibatl((sprn - SPR_IBAT4L) / 2);
171
    RET_STOP(ctx);
172
}
173

    
174
/* DBAT0U...DBAT7U */
175
/* DBAT0L...DBAT7L */
176
static void spr_read_dbat (void *opaque, int sprn)
177
{
178
    gen_op_load_dbat(sprn & 1, (sprn - SPR_DBAT0U) / 2);
179
}
180

    
181
static void spr_read_dbat_h (void *opaque, int sprn)
182
{
183
    gen_op_load_dbat(sprn & 1, (sprn - SPR_DBAT4U) / 2);
184
}
185

    
186
static void spr_write_dbatu (void *opaque, int sprn)
187
{
188
    DisasContext *ctx = opaque;
189

    
190
    gen_op_store_dbatu((sprn - SPR_DBAT0U) / 2);
191
    RET_STOP(ctx);
192
}
193

    
194
static void spr_write_dbatu_h (void *opaque, int sprn)
195
{
196
    DisasContext *ctx = opaque;
197

    
198
    gen_op_store_dbatu((sprn - SPR_DBAT4U) / 2);
199
    RET_STOP(ctx);
200
}
201

    
202
static void spr_write_dbatl (void *opaque, int sprn)
203
{
204
    DisasContext *ctx = opaque;
205

    
206
    gen_op_store_dbatl((sprn - SPR_DBAT0L) / 2);
207
    RET_STOP(ctx);
208
}
209

    
210
static void spr_write_dbatl_h (void *opaque, int sprn)
211
{
212
    DisasContext *ctx = opaque;
213

    
214
    gen_op_store_dbatl((sprn - SPR_DBAT4L) / 2);
215
    RET_STOP(ctx);
216
}
217

    
218
/* SDR1 */
219
static void spr_read_sdr1 (void *opaque, int sprn)
220
{
221
    gen_op_load_sdr1();
222
}
223

    
224
static void spr_write_sdr1 (void *opaque, int sprn)
225
{
226
    DisasContext *ctx = opaque;
227

    
228
    gen_op_store_sdr1();
229
    RET_STOP(ctx);
230
}
231

    
232
static void spr_write_pir (void *opaque, int sprn)
233
{
234
    gen_op_store_pir();
235
}
236

    
237
static inline void spr_register (CPUPPCState *env, int num,
238
                                 const unsigned char *name,
239
                                 void (*uea_read)(void *opaque, int sprn),
240
                                 void (*uea_write)(void *opaque, int sprn),
241
                                 void (*oea_read)(void *opaque, int sprn),
242
                                 void (*oea_write)(void *opaque, int sprn),
243
                                 target_ulong initial_value)
244
{
245
    ppc_spr_t *spr;
246

    
247
    spr = &env->spr_cb[num];
248
    if (spr->name != NULL ||env-> spr[num] != 0x00000000 ||
249
        spr->uea_read != NULL || spr->uea_write != NULL ||
250
        spr->oea_read != NULL || spr->oea_write != NULL) {
251
        printf("Error: Trying to register SPR %d (%03x) twice !\n", num, num);
252
        exit(1);
253
    }
254
#if defined(PPC_DEBUG_SPR)
255
    printf("*** register spr %d (%03x) %s val %08llx\n", num, num, name,
256
           (unsigned long long)initial_value);
257
#endif
258
    spr->name = name;
259
    spr->uea_read = uea_read;
260
    spr->uea_write = uea_write;
261
    spr->oea_read = oea_read;
262
    spr->oea_write = oea_write;
263
    env->spr[num] = initial_value;
264
}
265

    
266
/* Generic PowerPC SPRs */
267
static void gen_spr_generic (CPUPPCState *env)
268
{
269
    /* Integer processing */
270
    spr_register(env, SPR_XER, "XER",
271
                 &spr_read_xer, &spr_write_xer,
272
                 &spr_read_xer, &spr_write_xer,
273
                 0x00000000);
274
    /* Branch contol */
275
    spr_register(env, SPR_LR, "LR",
276
                 &spr_read_lr, &spr_write_lr,
277
                 &spr_read_lr, &spr_write_lr,
278
                 0x00000000);
279
    spr_register(env, SPR_CTR, "CTR",
280
                 &spr_read_ctr, &spr_write_ctr,
281
                 &spr_read_ctr, &spr_write_ctr,
282
                 0x00000000);
283
    /* Interrupt processing */
284
    spr_register(env, SPR_SRR0, "SRR0",
285
                 SPR_NOACCESS, SPR_NOACCESS,
286
                 &spr_read_generic, &spr_write_generic,
287
                 0x00000000);
288
    spr_register(env, SPR_SRR1, "SRR1",
289
                 SPR_NOACCESS, SPR_NOACCESS,
290
                 &spr_read_generic, &spr_write_generic,
291
                 0x00000000);
292
    /* Processor control */
293
    spr_register(env, SPR_SPRG0, "SPRG0",
294
                 SPR_NOACCESS, SPR_NOACCESS,
295
                 &spr_read_generic, &spr_write_generic,
296
                 0x00000000);
297
    spr_register(env, SPR_SPRG1, "SPRG1",
298
                 SPR_NOACCESS, SPR_NOACCESS,
299
                 &spr_read_generic, &spr_write_generic,
300
                 0x00000000);
301
    spr_register(env, SPR_SPRG2, "SPRG2",
302
                 SPR_NOACCESS, SPR_NOACCESS,
303
                 &spr_read_generic, &spr_write_generic,
304
                 0x00000000);
305
    spr_register(env, SPR_SPRG3, "SPRG3",
306
                 SPR_NOACCESS, SPR_NOACCESS,
307
                 &spr_read_generic, &spr_write_generic,
308
                 0x00000000);
309
}
310

    
311
/* SPR common to all non-embedded PowerPC, including 601 */
312
static void gen_spr_ne_601 (CPUPPCState *env)
313
{
314
    /* Exception processing */
315
    spr_register(env, SPR_DSISR, "DSISR",
316
                 SPR_NOACCESS, SPR_NOACCESS,
317
                 &spr_read_generic, &spr_write_generic,
318
                 0x00000000);
319
    spr_register(env, SPR_DAR, "DAR",
320
                 SPR_NOACCESS, SPR_NOACCESS,
321
                 &spr_read_generic, &spr_write_generic,
322
                 0x00000000);
323
    /* Timer */
324
    spr_register(env, SPR_DECR, "DECR",
325
                 SPR_NOACCESS, SPR_NOACCESS,
326
                 &spr_read_decr, &spr_write_decr,
327
                 0x00000000);
328
    /* Memory management */
329
    spr_register(env, SPR_SDR1, "SDR1",
330
                 SPR_NOACCESS, SPR_NOACCESS,
331
                 &spr_read_sdr1, &spr_write_sdr1,
332
                 0x00000000);
333
}
334

    
335
/* BATs 0-3 */
336
static void gen_low_BATs (CPUPPCState *env)
337
{
338
    spr_register(env, SPR_IBAT0U, "IBAT0U",
339
                 SPR_NOACCESS, SPR_NOACCESS,
340
                 &spr_read_ibat, &spr_write_ibatu,
341
                 0x00000000);
342
    spr_register(env, SPR_IBAT0L, "IBAT0L",
343
                 SPR_NOACCESS, SPR_NOACCESS,
344
                 &spr_read_ibat, &spr_write_ibatl,
345
                 0x00000000);
346
    spr_register(env, SPR_IBAT1U, "IBAT1U",
347
                 SPR_NOACCESS, SPR_NOACCESS,
348
                 &spr_read_ibat, &spr_write_ibatu,
349
                 0x00000000);
350
    spr_register(env, SPR_IBAT1L, "IBAT1L",
351
                 SPR_NOACCESS, SPR_NOACCESS,
352
                 &spr_read_ibat, &spr_write_ibatl,
353
                 0x00000000);
354
    spr_register(env, SPR_IBAT2U, "IBAT2U",
355
                 SPR_NOACCESS, SPR_NOACCESS,
356
                 &spr_read_ibat, &spr_write_ibatu,
357
                 0x00000000);
358
    spr_register(env, SPR_IBAT2L, "IBAT2L",
359
                 SPR_NOACCESS, SPR_NOACCESS,
360
                 &spr_read_ibat, &spr_write_ibatl,
361
                 0x00000000);
362
    spr_register(env, SPR_IBAT3U, "IBAT3U",
363
                 SPR_NOACCESS, SPR_NOACCESS,
364
                 &spr_read_ibat, &spr_write_ibatu,
365
                 0x00000000);
366
    spr_register(env, SPR_IBAT3L, "IBAT3L",
367
                 SPR_NOACCESS, SPR_NOACCESS,
368
                 &spr_read_ibat, &spr_write_ibatl,
369
                 0x00000000);
370
    spr_register(env, SPR_DBAT0U, "DBAT0U",
371
                 SPR_NOACCESS, SPR_NOACCESS,
372
                 &spr_read_dbat, &spr_write_dbatu,
373
                 0x00000000);
374
    spr_register(env, SPR_DBAT0L, "DBAT0L",
375
                 SPR_NOACCESS, SPR_NOACCESS,
376
                 &spr_read_dbat, &spr_write_dbatl,
377
                 0x00000000);
378
    spr_register(env, SPR_DBAT1U, "DBAT1U",
379
                 SPR_NOACCESS, SPR_NOACCESS,
380
                 &spr_read_dbat, &spr_write_dbatu,
381
                 0x00000000);
382
    spr_register(env, SPR_DBAT1L, "DBAT1L",
383
                 SPR_NOACCESS, SPR_NOACCESS,
384
                 &spr_read_dbat, &spr_write_dbatl,
385
                 0x00000000);
386
    spr_register(env, SPR_DBAT2U, "DBAT2U",
387
                 SPR_NOACCESS, SPR_NOACCESS,
388
                 &spr_read_dbat, &spr_write_dbatu,
389
                 0x00000000);
390
    spr_register(env, SPR_DBAT2L, "DBAT2L",
391
                 SPR_NOACCESS, SPR_NOACCESS,
392
                 &spr_read_dbat, &spr_write_dbatl,
393
                 0x00000000);
394
    spr_register(env, SPR_DBAT3U, "DBAT3U",
395
                 SPR_NOACCESS, SPR_NOACCESS,
396
                 &spr_read_dbat, &spr_write_dbatu,
397
                 0x00000000);
398
    spr_register(env, SPR_DBAT3L, "DBAT3L",
399
                 SPR_NOACCESS, SPR_NOACCESS,
400
                 &spr_read_dbat, &spr_write_dbatl,
401
                 0x00000000);
402
    env->nb_BATs = 4;
403
}
404

    
405
/* BATs 4-7 */
406
static void gen_high_BATs (CPUPPCState *env)
407
{
408
    spr_register(env, SPR_IBAT4U, "IBAT4U",
409
                 SPR_NOACCESS, SPR_NOACCESS,
410
                 &spr_read_ibat_h, &spr_write_ibatu_h,
411
                 0x00000000);
412
    spr_register(env, SPR_IBAT4L, "IBAT4L",
413
                 SPR_NOACCESS, SPR_NOACCESS,
414
                 &spr_read_ibat_h, &spr_write_ibatl_h,
415
                 0x00000000);
416
    spr_register(env, SPR_IBAT5U, "IBAT5U",
417
                 SPR_NOACCESS, SPR_NOACCESS,
418
                 &spr_read_ibat_h, &spr_write_ibatu_h,
419
                 0x00000000);
420
    spr_register(env, SPR_IBAT5L, "IBAT5L",
421
                 SPR_NOACCESS, SPR_NOACCESS,
422
                 &spr_read_ibat_h, &spr_write_ibatl_h,
423
                 0x00000000);
424
    spr_register(env, SPR_IBAT6U, "IBAT6U",
425
                 SPR_NOACCESS, SPR_NOACCESS,
426
                 &spr_read_ibat_h, &spr_write_ibatu_h,
427
                 0x00000000);
428
    spr_register(env, SPR_IBAT6L, "IBAT6L",
429
                 SPR_NOACCESS, SPR_NOACCESS,
430
                 &spr_read_ibat_h, &spr_write_ibatl_h,
431
                 0x00000000);
432
    spr_register(env, SPR_IBAT7U, "IBAT7U",
433
                 SPR_NOACCESS, SPR_NOACCESS,
434
                 &spr_read_ibat_h, &spr_write_ibatu_h,
435
                 0x00000000);
436
    spr_register(env, SPR_IBAT7L, "IBAT7L",
437
                 SPR_NOACCESS, SPR_NOACCESS,
438
                 &spr_read_ibat_h, &spr_write_ibatl_h,
439
                 0x00000000);
440
    spr_register(env, SPR_DBAT4U, "DBAT4U",
441
                 SPR_NOACCESS, SPR_NOACCESS,
442
                 &spr_read_dbat_h, &spr_write_dbatu_h,
443
                 0x00000000);
444
    spr_register(env, SPR_DBAT4L, "DBAT4L",
445
                 SPR_NOACCESS, SPR_NOACCESS,
446
                 &spr_read_dbat_h, &spr_write_dbatl_h,
447
                 0x00000000);
448
    spr_register(env, SPR_DBAT5U, "DBAT5U",
449
                 SPR_NOACCESS, SPR_NOACCESS,
450
                 &spr_read_dbat_h, &spr_write_dbatu_h,
451
                 0x00000000);
452
    spr_register(env, SPR_DBAT5L, "DBAT5L",
453
                 SPR_NOACCESS, SPR_NOACCESS,
454
                 &spr_read_dbat_h, &spr_write_dbatl_h,
455
                 0x00000000);
456
    spr_register(env, SPR_DBAT6U, "DBAT6U",
457
                 SPR_NOACCESS, SPR_NOACCESS,
458
                 &spr_read_dbat_h, &spr_write_dbatu_h,
459
                 0x00000000);
460
    spr_register(env, SPR_DBAT6L, "DBAT6L",
461
                 SPR_NOACCESS, SPR_NOACCESS,
462
                 &spr_read_dbat_h, &spr_write_dbatl_h,
463
                 0x00000000);
464
    spr_register(env, SPR_DBAT7U, "DBAT7U",
465
                 SPR_NOACCESS, SPR_NOACCESS,
466
                 &spr_read_dbat_h, &spr_write_dbatu_h,
467
                 0x00000000);
468
    spr_register(env, SPR_DBAT7L, "DBAT7L",
469
                 SPR_NOACCESS, SPR_NOACCESS,
470
                 &spr_read_dbat_h, &spr_write_dbatl_h,
471
                 0x00000000);
472
    env->nb_BATs = 8;
473
}
474

    
475
/* Generic PowerPC time base */
476
static void gen_tbl (CPUPPCState *env)
477
{
478
    spr_register(env, SPR_VTBL,  "TBL",
479
                 &spr_read_tbl, SPR_NOACCESS,
480
                 &spr_read_tbl, SPR_NOACCESS,
481
                 0x00000000);
482
    spr_register(env, SPR_TBL,   "TBL",
483
                 SPR_NOACCESS, SPR_NOACCESS,
484
                 SPR_NOACCESS, &spr_write_tbl,
485
                 0x00000000);
486
    spr_register(env, SPR_VTBU,  "TBU",
487
                 &spr_read_tbu, SPR_NOACCESS,
488
                 &spr_read_tbu, SPR_NOACCESS,
489
                 0x00000000);
490
    spr_register(env, SPR_TBU,   "TBU",
491
                 SPR_NOACCESS, SPR_NOACCESS,
492
                 SPR_NOACCESS, &spr_write_tbu,
493
                 0x00000000);
494
}
495

    
496
/* SPR common to all 7xx PowerPC implementations */
497
static void gen_spr_7xx (CPUPPCState *env)
498
{
499
    /* Breakpoints */
500
    /* XXX : not implemented */
501
    spr_register(env, SPR_DABR, "DABR",
502
                 SPR_NOACCESS, SPR_NOACCESS,
503
                 &spr_read_generic, &spr_write_generic,
504
                 0x00000000);
505
    /* XXX : not implemented */
506
    spr_register(env, SPR_IABR, "IABR",
507
                 SPR_NOACCESS, SPR_NOACCESS,
508
                 &spr_read_generic, &spr_write_generic,
509
                 0x00000000);
510
    /* Cache management */
511
    /* XXX : not implemented */
512
    spr_register(env, SPR_ICTC, "ICTC",
513
                 SPR_NOACCESS, SPR_NOACCESS,
514
                 &spr_read_generic, &spr_write_generic,
515
                 0x00000000);
516
    /* Performance monitors */
517
    /* XXX : not implemented */
518
    spr_register(env, SPR_MMCR0, "MMCR0",
519
                 SPR_NOACCESS, SPR_NOACCESS,
520
                 &spr_read_generic, &spr_write_generic,
521
                 0x00000000);
522
    /* XXX : not implemented */
523
    spr_register(env, SPR_MMCR1, "MMCR1",
524
                 SPR_NOACCESS, SPR_NOACCESS,
525
                 &spr_read_generic, &spr_write_generic,
526
                 0x00000000);
527
    /* XXX : not implemented */
528
    spr_register(env, SPR_PMC1, "PMC1",
529
                 SPR_NOACCESS, SPR_NOACCESS,
530
                 &spr_read_generic, &spr_write_generic,
531
                 0x00000000);
532
    /* XXX : not implemented */
533
    spr_register(env, SPR_PMC2, "PMC2",
534
                 SPR_NOACCESS, SPR_NOACCESS,
535
                 &spr_read_generic, &spr_write_generic,
536
                 0x00000000);
537
    /* XXX : not implemented */
538
    spr_register(env, SPR_PMC3, "PMC3",
539
                 SPR_NOACCESS, SPR_NOACCESS,
540
                 &spr_read_generic, &spr_write_generic,
541
                 0x00000000);
542
    /* XXX : not implemented */
543
    spr_register(env, SPR_PMC4, "PMC4",
544
                 SPR_NOACCESS, SPR_NOACCESS,
545
                 &spr_read_generic, &spr_write_generic,
546
                 0x00000000);
547
    /* XXX : not implemented */
548
    spr_register(env, SPR_SIA, "SIA",
549
                 SPR_NOACCESS, SPR_NOACCESS,
550
                 &spr_read_generic, SPR_NOACCESS,
551
                 0x00000000);
552
    spr_register(env, SPR_UMMCR0, "UMMCR0",
553
                 &spr_read_ureg, SPR_NOACCESS,
554
                 &spr_read_ureg, SPR_NOACCESS,
555
                 0x00000000);
556
    spr_register(env, SPR_UMMCR1, "UMMCR1",
557
                 &spr_read_ureg, SPR_NOACCESS,
558
                 &spr_read_ureg, SPR_NOACCESS,
559
                 0x00000000);
560
    spr_register(env, SPR_UPMC1, "UPMC1",
561
                 &spr_read_ureg, SPR_NOACCESS,
562
                 &spr_read_ureg, SPR_NOACCESS,
563
                 0x00000000);
564
    spr_register(env, SPR_UPMC2, "UPMC2",
565
                 &spr_read_ureg, SPR_NOACCESS,
566
                 &spr_read_ureg, SPR_NOACCESS,
567
                 0x00000000);
568
    spr_register(env, SPR_UPMC3, "UPMC3",
569
                 &spr_read_ureg, SPR_NOACCESS,
570
                 &spr_read_ureg, SPR_NOACCESS,
571
                 0x00000000);
572
    spr_register(env, SPR_UPMC4, "UPMC4",
573
                 &spr_read_ureg, SPR_NOACCESS,
574
                 &spr_read_ureg, SPR_NOACCESS,
575
                 0x00000000);
576
    spr_register(env, SPR_USIA, "USIA",
577
                 &spr_read_ureg, SPR_NOACCESS,
578
                 &spr_read_ureg, SPR_NOACCESS,
579
                 0x00000000);
580
    /* Thermal management */
581
    /* XXX : not implemented */
582
    spr_register(env, SPR_THRM1, "THRM1",
583
                 SPR_NOACCESS, SPR_NOACCESS,
584
                 &spr_read_generic, &spr_write_generic,
585
                 0x00000000);
586
    /* XXX : not implemented */
587
    spr_register(env, SPR_THRM2, "THRM2",
588
                 SPR_NOACCESS, SPR_NOACCESS,
589
                 &spr_read_generic, &spr_write_generic,
590
                 0x00000000);
591
    /* XXX : not implemented */
592
    spr_register(env, SPR_THRM3, "THRM3",
593
                 SPR_NOACCESS, SPR_NOACCESS,
594
                 &spr_read_generic, &spr_write_generic,
595
                 0x00000000);
596
    /* External access control */
597
    /* XXX : not implemented */
598
    spr_register(env, SPR_EAR, "EAR",
599
                 SPR_NOACCESS, SPR_NOACCESS,
600
                 &spr_read_generic, &spr_write_generic,
601
                 0x00000000);
602
}
603

    
604
/* SPR specific to PowerPC 604 implementation */
605
static void gen_spr_604 (CPUPPCState *env)
606
{
607
    /* Processor identification */
608
    spr_register(env, SPR_PIR, "PIR",
609
                 SPR_NOACCESS, SPR_NOACCESS,
610
                 &spr_read_generic, &spr_write_pir,
611
                 0x00000000);
612
    /* Breakpoints */
613
    /* XXX : not implemented */
614
    spr_register(env, SPR_IABR, "IABR",
615
                 SPR_NOACCESS, SPR_NOACCESS,
616
                 &spr_read_generic, &spr_write_generic,
617
                 0x00000000);
618
    /* XXX : not implemented */
619
    spr_register(env, SPR_DABR, "DABR",
620
                 SPR_NOACCESS, SPR_NOACCESS,
621
                 &spr_read_generic, &spr_write_generic,
622
                 0x00000000);
623
    /* Performance counters */
624
    /* XXX : not implemented */
625
    spr_register(env, SPR_MMCR0, "MMCR0",
626
                 SPR_NOACCESS, SPR_NOACCESS,
627
                 &spr_read_generic, &spr_write_generic,
628
                 0x00000000);
629
    /* XXX : not implemented */
630
    spr_register(env, SPR_MMCR1, "MMCR1",
631
                 SPR_NOACCESS, SPR_NOACCESS,
632
                 &spr_read_generic, &spr_write_generic,
633
                 0x00000000);
634
    /* XXX : not implemented */
635
    spr_register(env, SPR_PMC1, "PMC1",
636
                 SPR_NOACCESS, SPR_NOACCESS,
637
                 &spr_read_generic, &spr_write_generic,
638
                 0x00000000);
639
    /* XXX : not implemented */
640
    spr_register(env, SPR_PMC2, "PMC2",
641
                 SPR_NOACCESS, SPR_NOACCESS,
642
                 &spr_read_generic, &spr_write_generic,
643
                 0x00000000);
644
    /* XXX : not implemented */
645
    spr_register(env, SPR_PMC3, "PMC3",
646
                 SPR_NOACCESS, SPR_NOACCESS,
647
                 &spr_read_generic, &spr_write_generic,
648
                 0x00000000);
649
    /* XXX : not implemented */
650
    spr_register(env, SPR_PMC4, "PMC4",
651
                 SPR_NOACCESS, SPR_NOACCESS,
652
                 &spr_read_generic, &spr_write_generic,
653
                 0x00000000);
654
    /* XXX : not implemented */
655
    spr_register(env, SPR_SIA, "SIA",
656
                 SPR_NOACCESS, SPR_NOACCESS,
657
                 &spr_read_generic, SPR_NOACCESS,
658
                 0x00000000);
659
    /* XXX : not implemented */
660
    spr_register(env, SPR_SDA, "SDA",
661
                 SPR_NOACCESS, SPR_NOACCESS,
662
                 &spr_read_generic, SPR_NOACCESS,
663
                 0x00000000);
664
    /* External access control */
665
    /* XXX : not implemented */
666
    spr_register(env, SPR_EAR, "EAR",
667
                 SPR_NOACCESS, SPR_NOACCESS,
668
                 &spr_read_generic, &spr_write_generic,
669
                 0x00000000);
670
}
671

    
672
// XXX: TODO (64 bits PPC sprs)
673
/*
674
 * ASR => SPR 280 (64 bits)
675
 * FPECR => SPR 1022 (?)
676
 * VRSAVE => SPR 256 (Altivec)
677
 * SCOMC => SPR 276 (64 bits ?)
678
 * SCOMD => SPR 277 (64 bits ?)
679
 * HSPRG0 => SPR 304 (hypervisor)
680
 * HSPRG1 => SPR 305 (hypervisor)
681
 * HDEC => SPR 310 (hypervisor)
682
 * HIOR => SPR 311 (hypervisor)
683
 * RMOR => SPR 312 (970)
684
 * HRMOR => SPR 313 (hypervisor)
685
 * HSRR0 => SPR 314 (hypervisor)
686
 * HSRR1 => SPR 315 (hypervisor)
687
 * LPCR => SPR 316 (970)
688
 * LPIDR => SPR 317 (970)
689
 * ... and more (thermal management, performance counters, ...)
690
 */
691

    
692
static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def)
693
{
694
    /* Default MMU definitions */
695
    env->nb_BATs = -1;
696
    env->nb_tlb = 0;
697
    env->nb_ways = 0;
698
    /* XXX: missing:
699
     * 32 bits PPC:
700
     * - MPC5xx(x)
701
     * - MPC8xx(x)
702
     * - RCPU (MPC5xx)
703
     */
704
    spr_register(env, SPR_PVR, "PVR",
705
                 SPR_NOACCESS, SPR_NOACCESS,
706
                 &spr_read_generic, SPR_NOACCESS,
707
                 def->pvr);
708
    switch (def->pvr & def->pvr_mask) {
709
    case CPU_PPC_604:     /* PPC 604                       */
710
    case CPU_PPC_604E:    /* PPC 604e                      */
711
    case CPU_PPC_604R:    /* PPC 604r                      */
712
        gen_spr_generic(env);
713
        gen_spr_ne_601(env);
714
        /* Memory management */
715
        gen_low_BATs(env);
716
        /* Time base */
717
        gen_tbl(env);
718
        gen_spr_604(env);
719
        /* Hardware implementation registers */
720
        /* XXX : not implemented */
721
        spr_register(env, SPR_HID0, "HID0",
722
                     SPR_NOACCESS, SPR_NOACCESS,
723
                     &spr_read_generic, &spr_write_generic,
724
                     0x00000000);
725
        /* XXX : not implemented */
726
        spr_register(env, SPR_HID1, "HID1",
727
                     SPR_NOACCESS, SPR_NOACCESS,
728
                     &spr_read_generic, &spr_write_generic,
729
                     0x00000000);
730
        break;
731

    
732
    case CPU_PPC_74x:     /* PPC 740 / 750                 */
733
    case CPU_PPC_74xP:    /* PPC 740P / 750P               */
734
    case CPU_PPC_750CXE:  /* IBM PPC 750cxe                */
735
        gen_spr_generic(env);
736
        gen_spr_ne_601(env);
737
        /* Memory management */
738
        gen_low_BATs(env);
739
        /* Time base */
740
        gen_tbl(env);
741
        gen_spr_7xx(env);
742
        /* XXX : not implemented */
743
        spr_register(env, SPR_L2CR, "L2CR",
744
                     SPR_NOACCESS, SPR_NOACCESS,
745
                     &spr_read_generic, &spr_write_generic,
746
                     0x00000000);
747
        /* Hardware implementation registers */
748
        /* XXX : not implemented */
749
        spr_register(env, SPR_HID0, "HID0",
750
                     SPR_NOACCESS, SPR_NOACCESS,
751
                     &spr_read_generic, &spr_write_generic,
752
                     0x00000000);
753
        /* XXX : not implemented */
754
        spr_register(env, SPR_HID1, "HID1",
755
                     SPR_NOACCESS, SPR_NOACCESS,
756
                     &spr_read_generic, &spr_write_generic,
757
                     0x00000000);
758
        break;
759

    
760
    case CPU_PPC_750FX:   /* IBM PPC 750 FX                */
761
    case CPU_PPC_750GX:   /* IBM PPC 750 GX                */
762
        gen_spr_generic(env);
763
        gen_spr_ne_601(env);
764
        /* Memory management */
765
        gen_low_BATs(env);
766
        /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
767
        gen_high_BATs(env);
768
        /* Time base */
769
        gen_tbl(env);
770
        gen_spr_7xx(env);
771
        /* XXX : not implemented */
772
        spr_register(env, SPR_L2CR, "L2CR",
773
                     SPR_NOACCESS, SPR_NOACCESS,
774
                     &spr_read_generic, &spr_write_generic,
775
                     0x00000000);
776
        /* Hardware implementation registers */
777
        /* XXX : not implemented */
778
        spr_register(env, SPR_HID0, "HID0",
779
                     SPR_NOACCESS, SPR_NOACCESS,
780
                     &spr_read_generic, &spr_write_generic,
781
                     0x00000000);
782
        /* XXX : not implemented */
783
        spr_register(env, SPR_HID1, "HID1",
784
                 SPR_NOACCESS, SPR_NOACCESS,
785
                     &spr_read_generic, &spr_write_generic,
786
                     0x00000000);
787
        /* XXX : not implemented */
788
        spr_register(env, SPR_750_HID2, "HID2",
789
                     SPR_NOACCESS, SPR_NOACCESS,
790
                     &spr_read_generic, &spr_write_generic,
791
                     0x00000000);
792
        break;
793

    
794
    default:
795
        gen_spr_generic(env);
796
        break;
797
    }
798
    if (env->nb_BATs == -1)
799
        env->nb_BATs = 4;
800
}
801

    
802
#if defined(PPC_DUMP_CPU)
803
static void dump_sprs (CPUPPCState *env)
804
{
805
    ppc_spr_t *spr;
806
    uint32_t pvr = env->spr[SPR_PVR];
807
    uint32_t sr, sw, ur, uw;
808
    int i, j, n;
809

    
810
    printf("* SPRs for PVR=%08x\n", pvr);
811
    for (i = 0; i < 32; i++) {
812
        for (j = 0; j < 32; j++) {
813
            n = (i << 5) | j;
814
            spr = &env->spr_cb[n];
815
            sw = spr->oea_write != NULL && spr->oea_write != SPR_NOACCESS;
816
            sr = spr->oea_read != NULL && spr->oea_read != SPR_NOACCESS;
817
            uw = spr->uea_write != NULL && spr->uea_write != SPR_NOACCESS;
818
            ur = spr->uea_read != NULL && spr->uea_read != SPR_NOACCESS;
819
            if (sw || sr || uw || ur) {
820
                printf("%4d (%03x) %8s s%c%c u%c%c\n",
821
                       (i << 5) | j, (i << 5) | j, spr->name,
822
                       sw ? 'w' : '-', sr ? 'r' : '-',
823
                       uw ? 'w' : '-', ur ? 'r' : '-');
824
            }
825
        }
826
    }
827
    fflush(stdout);
828
    fflush(stderr);
829
}
830
#endif
831

    
832
/*****************************************************************************/
833
#include <stdlib.h>
834
#include <string.h>
835

    
836
int fflush (FILE *stream);
837

    
838
/* Opcode types */
839
enum {
840
    PPC_DIRECT   = 0, /* Opcode routine        */
841
    PPC_INDIRECT = 1, /* Indirect opcode table */
842
};
843

    
844
static inline int is_indirect_opcode (void *handler)
845
{
846
    return ((unsigned long)handler & 0x03) == PPC_INDIRECT;
847
}
848

    
849
static inline opc_handler_t **ind_table(void *handler)
850
{
851
    return (opc_handler_t **)((unsigned long)handler & ~3);
852
}
853

    
854
/* Instruction table creation */
855
/* Opcodes tables creation */
856
static void fill_new_table (opc_handler_t **table, int len)
857
{
858
    int i;
859

    
860
    for (i = 0; i < len; i++)
861
        table[i] = &invalid_handler;
862
}
863

    
864
static int create_new_table (opc_handler_t **table, unsigned char idx)
865
{
866
    opc_handler_t **tmp;
867

    
868
    tmp = malloc(0x20 * sizeof(opc_handler_t));
869
    if (tmp == NULL)
870
        return -1;
871
    fill_new_table(tmp, 0x20);
872
    table[idx] = (opc_handler_t *)((unsigned long)tmp | PPC_INDIRECT);
873

    
874
    return 0;
875
}
876

    
877
static int insert_in_table (opc_handler_t **table, unsigned char idx,
878
                            opc_handler_t *handler)
879
{
880
    if (table[idx] != &invalid_handler)
881
        return -1;
882
    table[idx] = handler;
883

    
884
    return 0;
885
}
886

    
887
static int register_direct_insn (opc_handler_t **ppc_opcodes,
888
                                 unsigned char idx, opc_handler_t *handler)
889
{
890
    if (insert_in_table(ppc_opcodes, idx, handler) < 0) {
891
        printf("*** ERROR: opcode %02x already assigned in main "
892
                "opcode table\n", idx);
893
        return -1;
894
    }
895

    
896
    return 0;
897
}
898

    
899
static int register_ind_in_table (opc_handler_t **table,
900
                                  unsigned char idx1, unsigned char idx2,
901
                                  opc_handler_t *handler)
902
{
903
    if (table[idx1] == &invalid_handler) {
904
        if (create_new_table(table, idx1) < 0) {
905
            printf("*** ERROR: unable to create indirect table "
906
                    "idx=%02x\n", idx1);
907
            return -1;
908
        }
909
    } else {
910
        if (!is_indirect_opcode(table[idx1])) {
911
            printf("*** ERROR: idx %02x already assigned to a direct "
912
                    "opcode\n", idx1);
913
            return -1;
914
        }
915
    }
916
    if (handler != NULL &&
917
        insert_in_table(ind_table(table[idx1]), idx2, handler) < 0) {
918
        printf("*** ERROR: opcode %02x already assigned in "
919
                "opcode table %02x\n", idx2, idx1);
920
        return -1;
921
    }
922

    
923
    return 0;
924
}
925

    
926
static int register_ind_insn (opc_handler_t **ppc_opcodes,
927
                              unsigned char idx1, unsigned char idx2,
928
                               opc_handler_t *handler)
929
{
930
    int ret;
931

    
932
    ret = register_ind_in_table(ppc_opcodes, idx1, idx2, handler);
933

    
934
    return ret;
935
}
936

    
937
static int register_dblind_insn (opc_handler_t **ppc_opcodes, 
938
                                 unsigned char idx1, unsigned char idx2,
939
                                  unsigned char idx3, opc_handler_t *handler)
940
{
941
    if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) {
942
        printf("*** ERROR: unable to join indirect table idx "
943
                "[%02x-%02x]\n", idx1, idx2);
944
        return -1;
945
    }
946
    if (register_ind_in_table(ind_table(ppc_opcodes[idx1]), idx2, idx3,
947
                              handler) < 0) {
948
        printf("*** ERROR: unable to insert opcode "
949
                "[%02x-%02x-%02x]\n", idx1, idx2, idx3);
950
        return -1;
951
    }
952

    
953
    return 0;
954
}
955

    
956
static int register_insn (opc_handler_t **ppc_opcodes, opcode_t *insn)
957
{
958
    if (insn->opc2 != 0xFF) {
959
        if (insn->opc3 != 0xFF) {
960
            if (register_dblind_insn(ppc_opcodes, insn->opc1, insn->opc2,
961
                                     insn->opc3, &insn->handler) < 0)
962
                return -1;
963
        } else {
964
            if (register_ind_insn(ppc_opcodes, insn->opc1,
965
                                  insn->opc2, &insn->handler) < 0)
966
                return -1;
967
        }
968
    } else {
969
        if (register_direct_insn(ppc_opcodes, insn->opc1, &insn->handler) < 0)
970
            return -1;
971
    }
972

    
973
    return 0;
974
}
975

    
976
static int test_opcode_table (opc_handler_t **table, int len)
977
{
978
    int i, count, tmp;
979

    
980
    for (i = 0, count = 0; i < len; i++) {
981
        /* Consistency fixup */
982
        if (table[i] == NULL)
983
            table[i] = &invalid_handler;
984
        if (table[i] != &invalid_handler) {
985
            if (is_indirect_opcode(table[i])) {
986
                tmp = test_opcode_table(ind_table(table[i]), 0x20);
987
                if (tmp == 0) {
988
                    free(table[i]);
989
                    table[i] = &invalid_handler;
990
                } else {
991
                    count++;
992
                }
993
            } else {
994
                count++;
995
            }
996
        }
997
    }
998

    
999
    return count;
1000
}
1001

    
1002
static void fix_opcode_tables (opc_handler_t **ppc_opcodes)
1003
{
1004
    if (test_opcode_table(ppc_opcodes, 0x40) == 0)
1005
        printf("*** WARNING: no opcode defined !\n");
1006
}
1007

    
1008
/*****************************************************************************/
1009
static int create_ppc_opcodes (CPUPPCState *env, ppc_def_t *def)
1010
{
1011
    opcode_t *opc, *start, *end;
1012

    
1013
    fill_new_table(env->opcodes, 0x40);
1014
#if defined(PPC_DUMP_CPU)
1015
    printf("* PPC instructions for PVR %08x: %s\n", def->pvr, def->name);
1016
#endif
1017
    if (&opc_start < &opc_end) {
1018
        start = &opc_start;
1019
        end = &opc_end;
1020
    } else {
1021
        start = &opc_end;
1022
        end = &opc_start;
1023
    }
1024
    for (opc = start + 1; opc != end; opc++) {
1025
        if ((opc->handler.type & def->insns_flags) != 0) {
1026
            if (register_insn(env->opcodes, opc) < 0) {
1027
                printf("*** ERROR initializing PPC instruction "
1028
                        "0x%02x 0x%02x 0x%02x\n", opc->opc1, opc->opc2,
1029
                        opc->opc3);
1030
                return -1;
1031
            }
1032
#if defined(PPC_DUMP_CPU)
1033
            if (opc1 != 0x00) {
1034
                if (opc->opc3 == 0xFF) {
1035
                    if (opc->opc2 == 0xFF) {
1036
                        printf(" %02x -- -- (%2d ----) : %s\n",
1037
                               opc->opc1, opc->opc1, opc->oname);
1038
                    } else {
1039
                        printf(" %02x %02x -- (%2d %4d) : %s\n",
1040
                               opc->opc1, opc->opc2, opc->opc1, opc->opc2,
1041
                                    opc->oname);
1042
                    }
1043
                } else {
1044
                    printf(" %02x %02x %02x (%2d %4d) : %s\n",
1045
                           opc->opc1, opc->opc2, opc->opc3,
1046
                           opc->opc1, (opc->opc3 << 5) | opc->opc2,
1047
                           opc->oname);
1048
                }
1049
            }
1050
#endif
1051
        }
1052
    }
1053
    fix_opcode_tables(env->opcodes);
1054
    fflush(stdout);
1055
    fflush(stderr);
1056

    
1057
    return 0;
1058
}
1059

    
1060
int cpu_ppc_register (CPUPPCState *env, ppc_def_t *def)
1061
{
1062
    env->msr_mask = def->msr_mask;
1063
    env->flags = def->flags;
1064
    if (create_ppc_opcodes(env, def) < 0) {
1065
        printf("Error creating opcodes table\n");
1066
        fflush(stdout);
1067
        fflush(stderr);
1068
        return -1;
1069
    }
1070
    init_ppc_proc(env, def);
1071
#if defined(PPC_DUMP_CPU)
1072
    dump_sprs(env);
1073
#endif
1074
    fflush(stdout);
1075
    fflush(stderr);
1076

    
1077
    return 0;
1078
}
1079

    
1080
CPUPPCState *cpu_ppc_init(void)
1081
{
1082
    CPUPPCState *env;
1083

    
1084
    env = qemu_mallocz(sizeof(CPUPPCState));
1085
    if (!env)
1086
        return NULL;
1087
    cpu_exec_init(env);
1088
    tlb_flush(env, 1);
1089
#if defined (DO_SINGLE_STEP) && 0
1090
    /* Single step trace mode */
1091
    msr_se = 1;
1092
    msr_be = 1;
1093
#endif
1094
    msr_fp = 1; /* Allow floating point exceptions */
1095
    msr_me = 1; /* Allow machine check exceptions  */
1096
#if defined(CONFIG_USER_ONLY)
1097
    msr_pr = 1;
1098
#else
1099
    env->nip = 0xFFFFFFFC;
1100
#endif
1101
    do_compute_hflags(env);
1102
    env->reserve = -1;
1103
    return env;
1104
}
1105

    
1106
void cpu_ppc_close(CPUPPCState *env)
1107
{
1108
    /* Should also remove all opcode tables... */
1109
    free(env);
1110
}
1111

    
1112
/*****************************************************************************/
1113
/* PowerPC CPU definitions */
1114
static ppc_def_t ppc_defs[] =
1115
{
1116
    /* Embedded PPC */
1117
#if defined (TODO)
1118
    /* PPC 401 */
1119
    {
1120
        .name        = "401",
1121
        .pvr         = CPU_PPC_401,
1122
        .pvr_mask    = 0xFFFF0000,
1123
        .insns_flags = PPC_INSNS_401,
1124
        .flags       = PPC_FLAGS_401,
1125
        .msr_mask    = xxx,
1126
    },
1127
#endif
1128
#if defined (TODO)
1129
    /* IOP480 (401 microcontroler) */
1130
    {
1131
        .name        = "iop480",
1132
        .pvr         = CPU_PPC_IOP480,
1133
        .pvr_mask    = 0xFFFF0000,
1134
        .insns_flags = PPC_INSNS_401,
1135
        .flags       = PPC_FLAGS_401,
1136
        .msr_mask    = xxx,
1137
    },
1138
#endif
1139
#if defined (TODO)
1140
    /* PPC 403 GA */
1141
    {
1142
        .name        = "403ga",
1143
        .pvr         = CPU_PPC_403GA,
1144
        .pvr_mask    = 0xFFFFFF00,
1145
        .insns_flags = PPC_INSNS_403,
1146
        .flags       = PPC_FLAGS_403,
1147
        .msr_mask    = 0x000000000007D23D,
1148
    },
1149
#endif
1150
#if defined (TODO)
1151
    /* PPC 403 GB */
1152
    {
1153
        .name        = "403gb",
1154
        .pvr         = CPU_PPC_403GB,
1155
        .pvr_mask    = 0xFFFFFF00,
1156
        .insns_flags = PPC_INSNS_403,
1157
        .flags       = PPC_FLAGS_403,
1158
        .msr_mask    = 0x000000000007D23D,
1159
    },
1160
#endif
1161
#if defined (TODO)
1162
    /* PPC 403 GC */
1163
    {
1164
        .name        = "403gc",
1165
        .pvr         = CPU_PPC_403GC,
1166
        .pvr_mask    = 0xFFFFFF00,
1167
        .insns_flags = PPC_INSNS_403,
1168
        .flags       = PPC_FLAGS_403,
1169
        .msr_mask    = 0x000000000007D23D,
1170
    },
1171
#endif
1172
#if defined (TODO)
1173
    /* PPC 403 GCX */
1174
    {
1175
        .name        = "403gcx",
1176
        .pvr         = CPU_PPC_403GCX,
1177
        .pvr_mask    = 0xFFFFFF00,
1178
        .insns_flags = PPC_INSNS_403,
1179
        .flags       = PPC_FLAGS_403,
1180
        .msr_mask    = 0x000000000007D23D,
1181
    },
1182
#endif
1183
#if defined (TODO)
1184
    /* PPC 405 CR */
1185
    {
1186
        .name        = "405cr",
1187
        .pvr         = CPU_PPC_405,
1188
        .pvr_mask    = 0xFFFF0000,
1189
        .insns_flags = PPC_INSNS_405,
1190
        .flags       = PPC_FLAGS_405,
1191
        .msr_mask    = 0x00000000020EFF30,
1192
    },
1193
#endif
1194
#if defined (TODO)
1195
    /* PPC 405 GP */
1196
    {
1197
        .name        = "405gp",
1198
        .pvr         = CPU_PPC_405,
1199
        .pvr_mask    = 0xFFFF0000,
1200
        .insns_flags = PPC_INSNS_405,
1201
        .flags       = PPC_FLAGS_405,
1202
        .msr_mask    = 0x00000000020EFF30,
1203
    },
1204
#endif
1205
#if defined (TODO)
1206
    /* PPC 405 EP */
1207
    {
1208
        .name        = "405ep",
1209
        .pvr         = CPU_PPC_405EP,
1210
        .pvr_mask    = 0xFFFF0000,
1211
        .insns_flags = PPC_INSNS_405,
1212
        .flags       = PPC_FLAGS_405,
1213
        .msr_mask    = 0x00000000020EFF30,
1214
    },
1215
#endif
1216
#if defined (TODO)
1217
    /* PPC 405 GPR */
1218
    {
1219
        .name        = "405gpr",
1220
        .pvr         = CPU_PPC_405GPR,
1221
        .pvr_mask    = 0xFFFF0000,
1222
        .insns_flags = PPC_INSNS_405,
1223
        .flags       = PPC_FLAGS_405,
1224
        .msr_mask    = 0x00000000020EFF30,
1225
    },
1226
#endif
1227
#if defined (TODO)
1228
    /* PPC 405 D2 */
1229
    {
1230
        .name        = "405d2",
1231
        .pvr         = CPU_PPC_405D2,
1232
        .pvr_mask    = 0xFFFF0000,
1233
        .insns_flags = PPC_INSNS_405,
1234
        .flags       = PPC_FLAGS_405,
1235
        .msr_mask    = 0x00000000020EFF30,
1236
    },
1237
#endif
1238
#if defined (TODO)
1239
    /* PPC 405 D4 */
1240
    {
1241
        .name        = "405d4",
1242
        .pvr         = CPU_PPC_405D4,
1243
        .pvr_mask    = 0xFFFF0000,
1244
        .insns_flags = PPC_INSNS_405,
1245
        .flags       = PPC_FLAGS_405,
1246
        .msr_mask    = 0x00000000020EFF30,
1247
    },
1248
#endif
1249
#if defined (TODO)
1250
    /* Npe405 H */
1251
    {
1252
        .name        = "Npe405H",
1253
        .pvr         = CPU_PPC_NPE405H,
1254
        .pvr_mask    = 0xFFFF0000,
1255
        .insns_flags = PPC_INSNS_405,
1256
        .flags       = PPC_FLAGS_405,
1257
        .msr_mask    = 0x00000000020EFF30,
1258
    },
1259
#endif
1260
#if defined (TODO)
1261
    /* Npe405 L */
1262
    {
1263
        .name        = "Npe405L",
1264
        .pvr         = CPU_PPC_NPE405L,
1265
        .pvr_mask    = 0xFFFF0000,
1266
        .insns_flags = PPC_INSNS_405,
1267
        .flags       = PPC_FLAGS_405,
1268
        .msr_mask    = 0x00000000020EFF30,
1269
    },
1270
#endif
1271
#if defined (TODO)
1272
    /* STB03xx */
1273
    {
1274
        .name        = "STB03",
1275
        .pvr         = CPU_PPC_STB03,
1276
        .pvr_mask    = 0xFFFF0000,
1277
        .insns_flags = PPC_INSNS_405,
1278
        .flags       = PPC_FLAGS_405,
1279
        .msr_mask    = 0x00000000020EFF30,
1280
    },
1281
#endif
1282
#if defined (TODO)
1283
    /* STB04xx */
1284
    {
1285
        .name        = "STB04",
1286
        .pvr         = CPU_PPC_STB04,
1287
        .pvr_mask    = 0xFFFF0000,
1288
        .insns_flags = PPC_INSNS_405,
1289
        .flags       = PPC_FLAGS_405,
1290
        .msr_mask    = 0x00000000020EFF30,
1291
    },
1292
#endif
1293
#if defined (TODO)
1294
    /* STB25xx */
1295
    {
1296
        .name        = "STB25",
1297
        .pvr         = CPU_PPC_STB25,
1298
        .pvr_mask    = 0xFFFF0000,
1299
        .insns_flags = PPC_INSNS_405,
1300
        .flags       = PPC_FLAGS_405,
1301
        .msr_mask    = 0x00000000020EFF30,
1302
    },
1303
#endif
1304
#if defined (TODO)
1305
    /* PPC 440 EP */
1306
    {
1307
        .name        = "440ep",
1308
        .pvr         = CPU_PPC_440EP,
1309
        .pvr_mask    = 0xFFFF0000,
1310
        .insns_flags = PPC_INSNS_440,
1311
        .flags       = PPC_FLAGS_440,
1312
        .msr_mask    = 0x000000000006D630,
1313
    },
1314
#endif
1315
#if defined (TODO)
1316
    /* PPC 440 GP */
1317
    {
1318
        .name        = "440gp",
1319
        .pvr         = CPU_PPC_440GP,
1320
        .pvr_mask    = 0xFFFFFF00,
1321
        .insns_flags = PPC_INSNS_440,
1322
        .flags       = PPC_FLAGS_440,
1323
        .msr_mask    = 0x000000000006D630,
1324
    },
1325
#endif
1326
#if defined (TODO)
1327
    /* PPC 440 GX */
1328
    {
1329
        .name        = "440gx",
1330
        .pvr         = CPU_PPC_440GX,
1331
        .pvr_mask    = 0xFFFF0000,
1332
        .insns_flags = PPC_INSNS_405,
1333
        .flags       = PPC_FLAGS_440,
1334
        .msr_mask    = 0x000000000006D630,
1335
    },
1336
#endif
1337

    
1338
    /* 32 bits "classic" powerpc */
1339
#if defined (TODO)
1340
    /* PPC 601 */
1341
    {
1342
        .name        = "601",
1343
        .pvr         = CPU_PPC_601,
1344
        .pvr_mask    = 0xFFFF0000,
1345
        .insns_flags = PPC_INSNS_601,
1346
        .flags       = PPC_FLAGS_601,
1347
        .msr_mask    = 0x000000000000FD70,
1348
    },
1349
#endif
1350
#if defined (TODO)
1351
    /* PPC 602 */
1352
    {
1353
        .name        = "602",
1354
        .pvr         = CPU_PPC_602,
1355
        .pvr_mask    = 0xFFFF0000,
1356
        .insns_flags = PPC_INSNS_602,
1357
        .flags       = PPC_FLAGS_602,
1358
        .msr_mask    = 0x0000000000C7FF73,
1359
    },
1360
#endif
1361
#if defined (TODO)
1362
    /* PPC 603 */
1363
    {
1364
        .name        = "603",
1365
        .pvr         = CPU_PPC_603,
1366
        .pvr_mask    = 0xFFFF0000,
1367
        .insns_flags = PPC_INSNS_603,
1368
        .flags       = PPC_FLAGS_603,
1369
        .msr_mask    = 0x000000000007FF73,
1370
    },
1371
#endif
1372
#if defined (TODO)
1373
    /* PPC 603e */
1374
    {
1375
        .name        = "603e",
1376
        .pvr         = CPU_PPC_603E,
1377
        .pvr_mask    = 0xFFFF0000,
1378
        .insns_flags = PPC_INSNS_603,
1379
        .flags       = PPC_FLAGS_603,
1380
        .msr_mask    = 0x000000000007FF73,
1381
    },
1382
    {
1383
        .name        = "Stretch",
1384
        .pvr         = CPU_PPC_603E,
1385
        .pvr_mask    = 0xFFFF0000,
1386
        .insns_flags = PPC_INSNS_603,
1387
        .flags       = PPC_FLAGS_603,
1388
        .msr_mask    = 0x000000000007FF73,
1389
    },
1390
#endif
1391
#if defined (TODO)
1392
    /* PPC 603ev */
1393
    {
1394
        .name        = "603ev",
1395
        .pvr         = CPU_PPC_603EV,
1396
        .pvr_mask    = 0xFFFFF000,
1397
        .insns_flags = PPC_INSNS_603,
1398
        .flags       = PPC_FLAGS_603,
1399
        .msr_mask    = 0x000000000007FF73,
1400
    },
1401
#endif
1402
#if defined (TODO)
1403
    /* PPC 603r */
1404
    {
1405
        .name        = "603r",
1406
        .pvr         = CPU_PPC_603R,
1407
        .pvr_mask    = 0xFFFFF000,
1408
        .insns_flags = PPC_INSNS_603,
1409
        .flags       = PPC_FLAGS_603,
1410
        .msr_mask    = 0x000000000007FF73,
1411
    },
1412
    {
1413
        .name        = "Goldeneye",
1414
        .pvr         = CPU_PPC_603R,
1415
        .pvr_mask    = 0xFFFFF000,
1416
        .insns_flags = PPC_INSNS_603,
1417
        .flags       = PPC_FLAGS_603,
1418
        .msr_mask    = 0x000000000007FF73,
1419
    },
1420
#endif
1421
#if defined (TODO)
1422
    /* XXX: TODO: according to Motorola UM, this is a derivative to 603e */
1423
    {
1424
        .name        = "G2",
1425
        .pvr         = CPU_PPC_G2,
1426
        .pvr_mask    = 0xFFFF0000,
1427
        .insns_flags = PPC_INSNS_G2,
1428
        .flags       = PPC_FLAGS_G2,
1429
        .msr_mask    = 0x000000000006FFF2,
1430
    },
1431
    { /* Same as G2, with LE mode support */
1432
        .name        = "G2le",
1433
        .pvr         = CPU_PPC_G2LE,
1434
        .pvr_mask    = 0xFFFF0000,
1435
        .insns_flags = PPC_INSNS_G2,
1436
        .flags       = PPC_FLAGS_G2,
1437
        .msr_mask    = 0x000000000007FFF3,
1438
    },
1439
#endif
1440
    /* PPC 604 */
1441
    {
1442
        .name        = "604",
1443
        .pvr         = CPU_PPC_604,
1444
        .pvr_mask    = 0xFFFF0000,
1445
        .insns_flags = PPC_INSNS_604,
1446
        .flags       = PPC_FLAGS_604,
1447
        .msr_mask    = 0x000000000005FF77,
1448
    },
1449
    /* PPC 604e */
1450
    {
1451
        .name        = "604e",
1452
        .pvr         = CPU_PPC_604E,
1453
        .pvr_mask    = 0xFFFF0000,
1454
        .insns_flags = PPC_INSNS_604,
1455
        .flags       = PPC_FLAGS_604,
1456
        .msr_mask    = 0x000000000005FF77,
1457
    },
1458
    /* PPC 604r */
1459
    {
1460
        .name        = "604r",
1461
        .pvr         = CPU_PPC_604R,
1462
        .pvr_mask    = 0xFFFF0000,
1463
        .insns_flags = PPC_INSNS_604,
1464
        .flags       = PPC_FLAGS_604,
1465
        .msr_mask    = 0x000000000005FF77,
1466
    },
1467
    /* generic G3 */
1468
    {
1469
        .name        = "G3",
1470
        .pvr         = CPU_PPC_74x,
1471
        .pvr_mask    = 0xFFFFF000,
1472
        .insns_flags = PPC_INSNS_7x0,
1473
        .flags       = PPC_FLAGS_7x0,
1474
        .msr_mask    = 0x000000000007FF77,
1475
    },
1476
#if defined (TODO)
1477
    /* MPC740 (G3) */
1478
    {
1479
        .name        = "740",
1480
        .pvr         = CPU_PPC_74x,
1481
        .pvr_mask    = 0xFFFFF000,
1482
        .insns_flags = PPC_INSNS_7x0,
1483
        .flags       = PPC_FLAGS_7x0,
1484
        .msr_mask    = 0x000000000007FF77,
1485
    },
1486
    {
1487
        .name        = "Arthur",
1488
        .pvr         = CPU_PPC_74x,
1489
        .pvr_mask    = 0xFFFFF000,
1490
        .insns_flags = PPC_INSNS_7x0,
1491
        .flags       = PPC_FLAGS_7x0,
1492
        .msr_mask    = 0x000000000007FF77,
1493
    },
1494
#endif
1495
#if defined (TODO)
1496
    /* MPC745 (G3) */
1497
    {
1498
        .name        = "745",
1499
        .pvr         = CPU_PPC_74x,
1500
        .pvr_mask    = 0xFFFFF000,
1501
        .insns_flags = PPC_INSNS_7x5,
1502
        .flags       = PPC_FLAGS_7x5,
1503
        .msr_mask    = 0x000000000007FF77,
1504
    },
1505
    {
1506
        .name        = "Goldfinger",
1507
        .pvr         = CPU_PPC_74x,
1508
        .pvr_mask    = 0xFFFFF000,
1509
        .insns_flags = PPC_INSNS_7x5,
1510
        .flags       = PPC_FLAGS_7x5,
1511
        .msr_mask    = 0x000000000007FF77,
1512
    },
1513
#endif
1514
    /* MPC750 (G3) */
1515
    {
1516
        .name        = "750",
1517
        .pvr         = CPU_PPC_74x,
1518
        .pvr_mask    = 0xFFFFF000,
1519
        .insns_flags = PPC_INSNS_7x0,
1520
        .flags       = PPC_FLAGS_7x0,
1521
        .msr_mask    = 0x000000000007FF77,
1522
    },
1523
#if defined (TODO)
1524
    /* MPC755 (G3) */
1525
    {
1526
        .name        = "755",
1527
        .pvr         = CPU_PPC_755,
1528
        .pvr_mask    = 0xFFFFF000,
1529
        .insns_flags = PPC_INSNS_7x5,
1530
        .flags       = PPC_FLAGS_7x5,
1531
        .msr_mask    = 0x000000000007FF77,
1532
    },
1533
#endif
1534
#if defined (TODO)
1535
    /* MPC740P (G3) */
1536
    {
1537
        .name        = "740p",
1538
        .pvr         = CPU_PPC_74xP,
1539
        .pvr_mask    = 0xFFFFF000,
1540
        .insns_flags = PPC_INSNS_7x0,
1541
        .flags       = PPC_FLAGS_7x0,
1542
        .msr_mask    = 0x000000000007FF77,
1543
    },
1544
    {
1545
        .name        = "Conan/Doyle",
1546
        .pvr         = CPU_PPC_74xP,
1547
        .pvr_mask    = 0xFFFFF000,
1548
        .insns_flags = PPC_INSNS_7x0,
1549
        .flags       = PPC_FLAGS_7x0,
1550
        .msr_mask    = 0x000000000007FF77,
1551
    },
1552
#endif
1553
#if defined (TODO)
1554
    /* MPC745P (G3) */
1555
    {
1556
        .name        = "745p",
1557
        .pvr         = CPU_PPC_74xP,
1558
        .pvr_mask    = 0xFFFFF000,
1559
        .insns_flags = PPC_INSNS_7x5,
1560
        .flags       = PPC_FLAGS_7x5,
1561
        .msr_mask    = 0x000000000007FF77,
1562
    },
1563
#endif
1564
    /* MPC750P (G3) */
1565
    {
1566
        .name        = "750p",
1567
        .pvr         = CPU_PPC_74xP,
1568
        .pvr_mask    = 0xFFFFF000,
1569
        .insns_flags = PPC_INSNS_7x0,
1570
        .flags       = PPC_FLAGS_7x0,
1571
        .msr_mask    = 0x000000000007FF77,
1572
    },
1573
#if defined (TODO)
1574
    /* MPC755P (G3) */
1575
    {
1576
        .name        = "755p",
1577
        .pvr         = CPU_PPC_74xP,
1578
        .pvr_mask    = 0xFFFFF000,
1579
        .insns_flags = PPC_INSNS_7x5,
1580
        .flags       = PPC_FLAGS_7x5,
1581
        .msr_mask    = 0x000000000007FF77,
1582
    },
1583
#endif
1584
    /* IBM 750CXe (G3 embedded) */
1585
    {
1586
        .name        = "750cxe",
1587
        .pvr         = CPU_PPC_750CXE,
1588
        .pvr_mask    = 0xFFFFF000,
1589
        .insns_flags = PPC_INSNS_7x0,
1590
        .flags       = PPC_FLAGS_7x0,
1591
        .msr_mask    = 0x000000000007FF77,
1592
    },
1593
    /* IBM 750FX (G3 embedded) */
1594
    {
1595
        .name        = "750fx",
1596
        .pvr         = CPU_PPC_750FX,
1597
        .pvr_mask    = 0xFFFF0000,
1598
        .insns_flags = PPC_INSNS_7x0,
1599
        .flags       = PPC_FLAGS_7x0,
1600
        .msr_mask    = 0x000000000007FF77,
1601
    },
1602
    /* IBM 750GX (G3 embedded) */
1603
    {
1604
        .name        = "750gx",
1605
        .pvr         = CPU_PPC_750GX,
1606
        .pvr_mask    = 0xFFFF0000,
1607
        .insns_flags = PPC_INSNS_7x0,
1608
        .flags       = PPC_FLAGS_7x0,
1609
        .msr_mask    = 0x000000000007FF77,
1610
    },
1611
#if defined (TODO)
1612
    /* generic G4 */
1613
    {
1614
        .name        = "G4",
1615
        .pvr         = CPU_PPC_7400,
1616
        .pvr_mask    = 0xFFFF0000,
1617
        .insns_flags = PPC_INSNS_74xx,
1618
        .flags       = PPC_FLAGS_74xx,
1619
        .msr_mask    = 0x000000000205FF77,
1620
    },
1621
#endif
1622
#if defined (TODO)
1623
    /* PPC 7400 (G4) */
1624
    {
1625
        .name        = "7400",
1626
        .pvr         = CPU_PPC_7400,
1627
        .pvr_mask    = 0xFFFF0000,
1628
        .insns_flags = PPC_INSNS_74xx,
1629
        .flags       = PPC_FLAGS_74xx,
1630
        .msr_mask    = 0x000000000205FF77,
1631
    },
1632
    {
1633
        .name        = "Max",
1634
        .pvr         = CPU_PPC_7400,
1635
        .pvr_mask    = 0xFFFF0000,
1636
        .insns_flags = PPC_INSNS_74xx,
1637
        .flags       = PPC_FLAGS_74xx,
1638
        .msr_mask    = 0x000000000205FF77,
1639
    },
1640
#endif
1641
#if defined (TODO)
1642
    /* PPC 7410 (G4) */
1643
    {
1644
        .name        = "7410",
1645
        .pvr         = CPU_PPC_7410,
1646
        .pvr_mask    = 0xFFFF0000,
1647
        .insns_flags = PPC_INSNS_74xx,
1648
        .flags       = PPC_FLAGS_74xx,
1649
        .msr_mask    = 0x000000000205FF77,
1650
    },
1651
    {
1652
        .name        = "Nitro",
1653
        .pvr         = CPU_PPC_7410,
1654
        .pvr_mask    = 0xFFFF0000,
1655
        .insns_flags = PPC_INSNS_74xx,
1656
        .flags       = PPC_FLAGS_74xx,
1657
        .msr_mask    = 0x000000000205FF77,
1658
    },
1659
#endif
1660
    /* XXX: 7441 */
1661
    /* XXX: 7445 */
1662
    /* XXX: 7447 */
1663
    /* XXX: 7447A */
1664
#if defined (TODO)
1665
    /* PPC 7450 (G4) */
1666
    {
1667
        .name        = "7450",
1668
        .pvr         = CPU_PPC_7450,
1669
        .pvr_mask    = 0xFFFF0000,
1670
        .insns_flags = PPC_INSNS_74xx,
1671
        .flags       = PPC_FLAGS_74xx,
1672
        .msr_mask    = 0x000000000205FF77,
1673
    },
1674
    {
1675
        .name        = "Vger",
1676
        .pvr         = CPU_PPC_7450,
1677
        .pvr_mask    = 0xFFFF0000,
1678
        .insns_flags = PPC_INSNS_74xx,
1679
        .flags       = PPC_FLAGS_74xx,
1680
        .msr_mask    = 0x000000000205FF77,
1681
    },
1682
#endif
1683
    /* XXX: 7451 */
1684
#if defined (TODO)
1685
    /* PPC 7455 (G4) */
1686
    {
1687
        .name        = "7455",
1688
        .pvr         = CPU_PPC_7455,
1689
        .pvr_mask    = 0xFFFF0000,
1690
        .insns_flags = PPC_INSNS_74xx,
1691
        .flags       = PPC_FLAGS_74xx,
1692
        .msr_mask    = 0x000000000205FF77,
1693
    },
1694
    {
1695
        .name        = "Apollo 6",
1696
        .pvr         = CPU_PPC_7455,
1697
        .pvr_mask    = 0xFFFF0000,
1698
        .insns_flags = PPC_INSNS_74xx,
1699
        .flags       = PPC_FLAGS_74xx,
1700
        .msr_mask    = 0x000000000205FF77,
1701
    },
1702
#endif
1703
#if defined (TODO)
1704
    /* PPC 7457 (G4) */
1705
    {
1706
        .name        = "7457",
1707
        .pvr         = CPU_PPC_7457,
1708
        .pvr_mask    = 0xFFFF0000,
1709
        .insns_flags = PPC_INSNS_74xx,
1710
        .flags       = PPC_FLAGS_74xx,
1711
        .msr_mask    = 0x000000000205FF77,
1712
    },
1713
    {
1714
        .name        = "Apollo 7",
1715
        .pvr         = CPU_PPC_7457,
1716
        .pvr_mask    = 0xFFFF0000,
1717
        .insns_flags = PPC_INSNS_74xx,
1718
        .flags       = PPC_FLAGS_74xx,
1719
        .msr_mask    = 0x000000000205FF77,
1720
    },
1721
#endif
1722
#if defined (TODO)
1723
    /* PPC 7457A (G4) */
1724
    {
1725
        .name        = "7457A",
1726
        .pvr         = CPU_PPC_7457A,
1727
        .pvr_mask    = 0xFFFF0000,
1728
        .insns_flags = PPC_INSNS_74xx,
1729
        .flags       = PPC_FLAGS_74xx,
1730
        .msr_mask    = 0x000000000205FF77,
1731
    },
1732
    {
1733
        .name        = "Apollo 7 PM",
1734
        .pvr         = CPU_PPC_7457A,
1735
        .pvr_mask    = 0xFFFF0000,
1736
        .insns_flags = PPC_INSNS_74xx,
1737
        .flags       = PPC_FLAGS_74xx,
1738
        .msr_mask    = 0x000000000205FF77,
1739
    },
1740
#endif
1741
    /* 64 bits PPC */
1742
#if defined (TODO)
1743
    /* PPC 620 */
1744
    {
1745
        .name        = "620",
1746
        .pvr         = CPU_PPC_620,
1747
        .pvr_mask    = 0xFFFF0000,
1748
        .insns_flags = PPC_INSNS_620,
1749
        .flags       = PPC_FLAGS_620,
1750
        .msr_mask    = 0x800000000005FF73,
1751
    },
1752
#endif
1753
#if defined (TODO)
1754
    /* PPC 630 (POWER3) */
1755
    {
1756
        .name        = "630",
1757
        .pvr         = CPU_PPC_630,
1758
        .pvr_mask    = 0xFFFF0000,
1759
        .insns_flags = PPC_INSNS_630,
1760
        .flags       = PPC_FLAGS_630,
1761
        .msr_mask    = xxx,
1762
    }
1763
    {
1764
        .name        = "POWER3",
1765
        .pvr         = CPU_PPC_630,
1766
        .pvr_mask    = 0xFFFF0000,
1767
        .insns_flags = PPC_INSNS_630,
1768
        .flags       = PPC_FLAGS_630,
1769
        .msr_mask    = xxx,
1770
    }
1771
#endif
1772
#if defined (TODO)
1773
    /* PPC 631 (Power 3+)*/
1774
    {
1775
        .name        = "631",
1776
        .pvr         = CPU_PPC_631,
1777
        .pvr_mask    = 0xFFFF0000,
1778
        .insns_flags = PPC_INSNS_631,
1779
        .flags       = PPC_FLAGS_631,
1780
        .msr_mask    = xxx,
1781
    },
1782
    {
1783
        .name        = "POWER3+",
1784
        .pvr         = CPU_PPC_631,
1785
        .pvr_mask    = 0xFFFF0000,
1786
        .insns_flags = PPC_INSNS_631,
1787
        .flags       = PPC_FLAGS_631,
1788
        .msr_mask    = xxx,
1789
    },
1790
#endif
1791
#if defined (TODO)
1792
    /* POWER4 */
1793
    {
1794
        .name        = "POWER4",
1795
        .pvr         = CPU_PPC_POWER4,
1796
        .pvr_mask    = 0xFFFF0000,
1797
        .insns_flags = PPC_INSNS_POWER4,
1798
        .flags       = PPC_FLAGS_POWER4,
1799
        .msr_mask    = xxx,
1800
    },
1801
#endif
1802
#if defined (TODO)
1803
    /* POWER4p */
1804
    {
1805
        .name        = "POWER4+",
1806
        .pvr         = CPU_PPC_POWER4P,
1807
        .pvr_mask    = 0xFFFF0000,
1808
        .insns_flags = PPC_INSNS_POWER4,
1809
        .flags       = PPC_FLAGS_POWER4,
1810
        .msr_mask    = xxx,
1811
    },
1812
#endif
1813
#if defined (TODO)
1814
    /* POWER5 */
1815
    {
1816
        .name        = "POWER5",
1817
        .pvr         = CPU_PPC_POWER5,
1818
        .pvr_mask    = 0xFFFF0000,
1819
        .insns_flags = PPC_INSNS_POWER5,
1820
        .flags       = PPC_FLAGS_POWER5,
1821
        .msr_mask    = xxx,
1822
    },
1823
#endif
1824
#if defined (TODO)
1825
    /* POWER5+ */
1826
    {
1827
        .name        = "POWER5+",
1828
        .pvr         = CPU_PPC_POWER5P,
1829
        .pvr_mask    = 0xFFFF0000,
1830
        .insns_flags = PPC_INSNS_POWER5,
1831
        .flags       = PPC_FLAGS_POWER5,
1832
        .msr_mask    = xxx,
1833
    },
1834
#endif
1835
#if defined (TODO)
1836
    /* PPC 970 */
1837
    {
1838
        .name        = "970",
1839
        .pvr         = CPU_PPC_970,
1840
        .pvr_mask    = 0xFFFF0000,
1841
        .insns_flags = PPC_INSNS_970,
1842
        .flags       = PPC_FLAGS_970,
1843
        .msr_mask    = 0x900000000204FF36,
1844
    },
1845
#endif
1846
#if defined (TODO)
1847
    /* PPC 970FX (G5) */
1848
    {
1849
        .name        = "970fx",
1850
        .pvr         = CPU_PPC_970FX,
1851
        .pvr_mask    = 0xFFFF0000,
1852
        .insns_flags = PPC_INSNS_970FX,
1853
        .flags       = PPC_FLAGS_970FX,
1854
        .msr_mask    = 0x800000000204FF36,
1855
    },
1856
#endif
1857
#if defined (TODO)
1858
    /* RS64 (Apache/A35) */
1859
    /* This one seems to support the whole POWER2 instruction set
1860
     * and the PowerPC 64 one.
1861
     */
1862
    {
1863
        .name        = "RS64",
1864
        .pvr         = CPU_PPC_RS64,
1865
        .pvr_mask    = 0xFFFF0000,
1866
        .insns_flags = PPC_INSNS_RS64,
1867
        .flags       = PPC_FLAGS_RS64,
1868
        .msr_mask    = xxx,
1869
    },
1870
    {
1871
        .name        = "Apache",
1872
        .pvr         = CPU_PPC_RS64,
1873
        .pvr_mask    = 0xFFFF0000,
1874
        .insns_flags = PPC_INSNS_RS64,
1875
        .flags       = PPC_FLAGS_RS64,
1876
        .msr_mask    = xxx,
1877
    },
1878
    {
1879
        .name        = "A35",
1880
        .pvr         = CPU_PPC_RS64,
1881
        .pvr_mask    = 0xFFFF0000,
1882
        .insns_flags = PPC_INSNS_RS64,
1883
        .flags       = PPC_FLAGS_RS64,
1884
        .msr_mask    = xxx,
1885
    },
1886
#endif
1887
#if defined (TODO)
1888
    /* RS64-II (NorthStar/A50) */
1889
    {
1890
        .name        = "RS64-II",
1891
        .pvr         = CPU_PPC_RS64II,
1892
        .pvr_mask    = 0xFFFF0000,
1893
        .insns_flags = PPC_INSNS_RS64,
1894
        .flags       = PPC_FLAGS_RS64,
1895
        .msr_mask    = xxx,
1896
    },
1897
    {
1898
        .name        = "NortStar",
1899
        .pvr         = CPU_PPC_RS64II,
1900
        .pvr_mask    = 0xFFFF0000,
1901
        .insns_flags = PPC_INSNS_RS64,
1902
        .flags       = PPC_FLAGS_RS64,
1903
        .msr_mask    = xxx,
1904
    },
1905
    {
1906
        .name        = "A50",
1907
        .pvr         = CPU_PPC_RS64II,
1908
        .pvr_mask    = 0xFFFF0000,
1909
        .insns_flags = PPC_INSNS_RS64,
1910
        .flags       = PPC_FLAGS_RS64,
1911
        .msr_mask    = xxx,
1912
    },
1913
#endif
1914
#if defined (TODO)
1915
    /* RS64-III (Pulsar) */
1916
    {
1917
        .name        = "RS64-III",
1918
        .pvr         = CPU_PPC_RS64III,
1919
        .pvr_mask    = 0xFFFF0000,
1920
        .insns_flags = PPC_INSNS_RS64,
1921
        .flags       = PPC_FLAGS_RS64,
1922
        .msr_mask    = xxx,
1923
    },
1924
    {
1925
        .name        = "Pulsar",
1926
        .pvr         = CPU_PPC_RS64III,
1927
        .pvr_mask    = 0xFFFF0000,
1928
        .insns_flags = PPC_INSNS_RS64,
1929
        .flags       = PPC_FLAGS_RS64,
1930
        .msr_mask    = xxx,
1931
    },
1932
#endif
1933
#if defined (TODO)
1934
    /* RS64-IV (IceStar/IStar/SStar) */
1935
    {
1936
        .name        = "RS64-IV",
1937
        .pvr         = CPU_PPC_RS64IV,
1938
        .pvr_mask    = 0xFFFF0000,
1939
        .insns_flags = PPC_INSNS_RS64,
1940
        .flags       = PPC_FLAGS_RS64,
1941
        .msr_mask    = xxx,
1942
    },
1943
    {
1944
        .name        = "IceStar",
1945
        .pvr         = CPU_PPC_RS64IV,
1946
        .pvr_mask    = 0xFFFF0000,
1947
        .insns_flags = PPC_INSNS_RS64,
1948
        .flags       = PPC_FLAGS_RS64,
1949
        .msr_mask    = xxx,
1950
    },
1951
    {
1952
        .name        = "IStar",
1953
        .pvr         = CPU_PPC_RS64IV,
1954
        .pvr_mask    = 0xFFFF0000,
1955
        .insns_flags = PPC_INSNS_RS64,
1956
        .flags       = PPC_FLAGS_RS64,
1957
        .msr_mask    = xxx,
1958
    },
1959
    {
1960
        .name        = "SStar",
1961
        .pvr         = CPU_PPC_RS64IV,
1962
        .pvr_mask    = 0xFFFF0000,
1963
        .insns_flags = PPC_INSNS_RS64,
1964
        .flags       = PPC_FLAGS_RS64,
1965
        .msr_mask    = xxx,
1966
    },
1967
#endif
1968
    /* POWER */
1969
#if defined (TODO)
1970
    /* Original POWER */
1971
    {
1972
        .name        = "POWER",
1973
        .pvr         = CPU_POWER,
1974
        .pvr_mask    = 0xFFFF0000,
1975
        .insns_flags = PPC_INSNS_POWER,
1976
        .flags       = PPC_FLAGS_POWER,
1977
        .msr_mask    = xxx,
1978
    },
1979
#endif
1980
#if defined (TODO)
1981
    /* POWER2 */
1982
    {
1983
        .name        = "POWER2",
1984
        .pvr         = CPU_POWER2,
1985
        .pvr_mask    = 0xFFFF0000,
1986
        .insns_flags = PPC_INSNS_POWER,
1987
        .flags       = PPC_FLAGS_POWER,
1988
        .msr_mask    = xxx,
1989
    },
1990
#endif
1991
    /* Generic PowerPCs */
1992
#if defined (TODO)
1993
    {
1994
        .name        = "ppc64",
1995
        .pvr         = CPU_PPC_970,
1996
        .pvr_mask    = 0xFFFF0000,
1997
        .insns_flags = PPC_INSNS_PPC64,
1998
        .flags       = PPC_FLAGS_PPC64,
1999
        .msr_mask    = 0xA00000000204FF36,
2000
    },
2001
#endif
2002
    {
2003
        .name        = "ppc32",
2004
        .pvr         = CPU_PPC_604,
2005
        .pvr_mask    = 0xFFFF0000,
2006
        .insns_flags = PPC_INSNS_PPC32,
2007
        .flags       = PPC_FLAGS_PPC32,
2008
        .msr_mask    = 0x000000000005FF77,
2009
    },
2010
    /* Fallback */
2011
    {
2012
        .name        = "ppc",
2013
        .pvr         = CPU_PPC_604,
2014
        .pvr_mask    = 0xFFFF0000,
2015
        .insns_flags = PPC_INSNS_PPC32,
2016
        .flags       = PPC_FLAGS_PPC32,
2017
        .msr_mask    = 0x000000000005FF77,
2018
    },
2019
};
2020

    
2021
int ppc_find_by_name (const unsigned char *name, ppc_def_t **def)
2022
{
2023
    int i, ret;
2024

    
2025
    ret = -1;
2026
    *def = NULL;
2027
    for (i = 0; strcmp(ppc_defs[i].name, "ppc") != 0; i++) {
2028
        if (strcasecmp(name, ppc_defs[i].name) == 0) {
2029
            *def = &ppc_defs[i];
2030
            ret = 0;
2031
            break;
2032
        }
2033
    }
2034

    
2035
    return ret;
2036
}
2037

    
2038
int ppc_find_by_pvr (uint32_t pvr, ppc_def_t **def)
2039
{
2040
    int i, ret;
2041

    
2042
    ret = -1;
2043
    *def = NULL;
2044
    for (i = 0; ppc_defs[i].name != NULL; i++) {
2045
        if ((pvr & ppc_defs[i].pvr_mask) ==
2046
            (ppc_defs[i].pvr & ppc_defs[i].pvr_mask)) {
2047
            *def = &ppc_defs[i];
2048
            ret = 0;
2049
            break;
2050
        }
2051
    }
2052

    
2053
    return ret;
2054
}
2055

    
2056
void ppc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
2057
{
2058
    int i;
2059

    
2060
    for (i = 0; ; i++) {
2061
        (*cpu_fprintf)(f, "PowerPC '%s' PVR %08x mask %08x\n",
2062
                       ppc_defs[i].name,
2063
                       ppc_defs[i].pvr, ppc_defs[i].pvr_mask);
2064
        if (strcmp(ppc_defs[i].name, "ppc") == 0)
2065
            break;
2066
    }
2067
}