Arm Linux EABI syscall support.
[qemu] / target-ppc / translate_init.c
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 }