]> git.proxmox.com Git - mirror_qemu.git/blame - target-ppc/translate_init.c
preliminary patch to support more PowerPC CPUs (Jocelyn Mayer)
[mirror_qemu.git] / target-ppc / translate_init.c
CommitLineData
3fc6c082
FB
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
29struct 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 */
41static void spr_read_generic (void *opaque, int sprn)
42{
43 gen_op_load_spr(sprn);
44}
45
46static 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 */
53static void spr_read_xer (void *opaque, int sprn)
54{
55 gen_op_load_xer();
56}
57
58static void spr_write_xer (void *opaque, int sprn)
59{
60 gen_op_store_xer();
61}
62
63/* LR */
64static void spr_read_lr (void *opaque, int sprn)
65{
66 gen_op_load_lr();
67}
68
69static void spr_write_lr (void *opaque, int sprn)
70{
71 gen_op_store_lr();
72}
73
74/* CTR */
75static void spr_read_ctr (void *opaque, int sprn)
76{
77 gen_op_load_ctr();
78}
79
80static 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 */
91static 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 */
98static void spr_read_decr (void *opaque, int sprn)
99{
100 gen_op_load_decr();
101}
102
103static 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 */
110static void spr_read_tbl (void *opaque, int sprn)
111{
112 gen_op_load_tbl();
113}
114
115static void spr_write_tbl (void *opaque, int sprn)
116{
117 gen_op_store_tbl();
118}
119
120static void spr_read_tbu (void *opaque, int sprn)
121{
122 gen_op_load_tbu();
123}
124
125static void spr_write_tbu (void *opaque, int sprn)
126{
127 gen_op_store_tbu();
128}
129
130/* IBAT0U...IBAT0U */
131/* IBAT0L...IBAT7L */
132static void spr_read_ibat (void *opaque, int sprn)
133{
134 gen_op_load_ibat(sprn & 1, (sprn - SPR_IBAT0U) / 2);
135}
136
137static void spr_read_ibat_h (void *opaque, int sprn)
138{
139 gen_op_load_ibat(sprn & 1, (sprn - SPR_IBAT4U) / 2);
140}
141
142static 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
150static 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
158static 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
166static 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 */
176static void spr_read_dbat (void *opaque, int sprn)
177{
178 gen_op_load_dbat(sprn & 1, (sprn - SPR_DBAT0U) / 2);
179}
180
181static void spr_read_dbat_h (void *opaque, int sprn)
182{
183 gen_op_load_dbat(sprn & 1, (sprn - SPR_DBAT4U) / 2);
184}
185
186static 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
194static 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
202static 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
210static 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 */
219static void spr_read_sdr1 (void *opaque, int sprn)
220{
221 gen_op_load_sdr1();
222}
223
224static 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
232static void spr_write_pir (void *opaque, int sprn)
233{
234 gen_op_store_pir();
235}
236
237static 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 */
267static 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 */
312static 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 */
336static 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 */
406static 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 */
476static 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 */
497static 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 */
605static 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
692static 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)
803static 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
836int fflush (FILE *stream);
837
838/* Opcode types */
839enum {
840 PPC_DIRECT = 0, /* Opcode routine */
841 PPC_INDIRECT = 1, /* Indirect opcode table */
842};
843
844static inline int is_indirect_opcode (void *handler)
845{
846 return ((unsigned long)handler & 0x03) == PPC_INDIRECT;
847}
848
849static 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 */
856static 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
864static 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
877static 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
887static 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
899static 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
926static 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
937static 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
956static 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
976static 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
1002static 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/*****************************************************************************/
1009static 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
1060int 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
1080CPUPPCState *cpu_ppc_init(void)
1081{
1082 CPUPPCState *env;
1083
1084 cpu_exec_init();
1085
1086 env = qemu_mallocz(sizeof(CPUPPCState));
1087 if (!env)
1088 return NULL;
1089 tlb_flush(env, 1);
1090#if defined (DO_SINGLE_STEP) && 0
1091 /* Single step trace mode */
1092 msr_se = 1;
1093 msr_be = 1;
1094#endif
1095 msr_fp = 1; /* Allow floating point exceptions */
1096 msr_me = 1; /* Allow machine check exceptions */
1097#if defined(CONFIG_USER_ONLY)
1098 msr_pr = 1;
1099#else
1100 env->nip = 0xFFFFFFFC;
1101#endif
1102 do_compute_hflags(env);
1103 env->reserve = -1;
1104 cpu_single_env = env;
1105 return env;
1106}
1107
1108void cpu_ppc_close(CPUPPCState *env)
1109{
1110 /* Should also remove all opcode tables... */
1111 free(env);
1112}
1113
1114/*****************************************************************************/
1115/* PowerPC CPU definitions */
1116static ppc_def_t ppc_defs[] =
1117{
1118 /* Embedded PPC */
1119#if defined (TODO)
1120 /* PPC 401 */
1121 {
1122 .name = "401",
1123 .pvr = CPU_PPC_401,
1124 .pvr_mask = 0xFFFF0000,
1125 .insns_flags = PPC_INSNS_401,
1126 .flags = PPC_FLAGS_401,
1127 .msr_mask = xxx,
1128 },
1129#endif
1130#if defined (TODO)
1131 /* IOP480 (401 microcontroler) */
1132 {
1133 .name = "iop480",
1134 .pvr = CPU_PPC_IOP480,
1135 .pvr_mask = 0xFFFF0000,
1136 .insns_flags = PPC_INSNS_401,
1137 .flags = PPC_FLAGS_401,
1138 .msr_mask = xxx,
1139 },
1140#endif
1141#if defined (TODO)
1142 /* PPC 403 GA */
1143 {
1144 .name = "403ga",
1145 .pvr = CPU_PPC_403GA,
1146 .pvr_mask = 0xFFFFFF00,
1147 .insns_flags = PPC_INSNS_403,
1148 .flags = PPC_FLAGS_403,
1149 .msr_mask = 0x000000000007D23D,
1150 },
1151#endif
1152#if defined (TODO)
1153 /* PPC 403 GB */
1154 {
1155 .name = "403gb",
1156 .pvr = CPU_PPC_403GB,
1157 .pvr_mask = 0xFFFFFF00,
1158 .insns_flags = PPC_INSNS_403,
1159 .flags = PPC_FLAGS_403,
1160 .msr_mask = 0x000000000007D23D,
1161 },
1162#endif
1163#if defined (TODO)
1164 /* PPC 403 GC */
1165 {
1166 .name = "403gc",
1167 .pvr = CPU_PPC_403GC,
1168 .pvr_mask = 0xFFFFFF00,
1169 .insns_flags = PPC_INSNS_403,
1170 .flags = PPC_FLAGS_403,
1171 .msr_mask = 0x000000000007D23D,
1172 },
1173#endif
1174#if defined (TODO)
1175 /* PPC 403 GCX */
1176 {
1177 .name = "403gcx",
1178 .pvr = CPU_PPC_403GCX,
1179 .pvr_mask = 0xFFFFFF00,
1180 .insns_flags = PPC_INSNS_403,
1181 .flags = PPC_FLAGS_403,
1182 .msr_mask = 0x000000000007D23D,
1183 },
1184#endif
1185#if defined (TODO)
1186 /* PPC 405 CR */
1187 {
1188 .name = "405cr",
1189 .pvr = CPU_PPC_405,
1190 .pvr_mask = 0xFFFF0000,
1191 .insns_flags = PPC_INSNS_405,
1192 .flags = PPC_FLAGS_405,
1193 .msr_mask = 0x00000000020EFF30,
1194 },
1195#endif
1196#if defined (TODO)
1197 /* PPC 405 GP */
1198 {
1199 .name = "405gp",
1200 .pvr = CPU_PPC_405,
1201 .pvr_mask = 0xFFFF0000,
1202 .insns_flags = PPC_INSNS_405,
1203 .flags = PPC_FLAGS_405,
1204 .msr_mask = 0x00000000020EFF30,
1205 },
1206#endif
1207#if defined (TODO)
1208 /* PPC 405 EP */
1209 {
1210 .name = "405ep",
1211 .pvr = CPU_PPC_405EP,
1212 .pvr_mask = 0xFFFF0000,
1213 .insns_flags = PPC_INSNS_405,
1214 .flags = PPC_FLAGS_405,
1215 .msr_mask = 0x00000000020EFF30,
1216 },
1217#endif
1218#if defined (TODO)
1219 /* PPC 405 GPR */
1220 {
1221 .name = "405gpr",
1222 .pvr = CPU_PPC_405GPR,
1223 .pvr_mask = 0xFFFF0000,
1224 .insns_flags = PPC_INSNS_405,
1225 .flags = PPC_FLAGS_405,
1226 .msr_mask = 0x00000000020EFF30,
1227 },
1228#endif
1229#if defined (TODO)
1230 /* PPC 405 D2 */
1231 {
1232 .name = "405d2",
1233 .pvr = CPU_PPC_405D2,
1234 .pvr_mask = 0xFFFF0000,
1235 .insns_flags = PPC_INSNS_405,
1236 .flags = PPC_FLAGS_405,
1237 .msr_mask = 0x00000000020EFF30,
1238 },
1239#endif
1240#if defined (TODO)
1241 /* PPC 405 D4 */
1242 {
1243 .name = "405d4",
1244 .pvr = CPU_PPC_405D4,
1245 .pvr_mask = 0xFFFF0000,
1246 .insns_flags = PPC_INSNS_405,
1247 .flags = PPC_FLAGS_405,
1248 .msr_mask = 0x00000000020EFF30,
1249 },
1250#endif
1251#if defined (TODO)
1252 /* Npe405 H */
1253 {
1254 .name = "Npe405H",
1255 .pvr = CPU_PPC_NPE405H,
1256 .pvr_mask = 0xFFFF0000,
1257 .insns_flags = PPC_INSNS_405,
1258 .flags = PPC_FLAGS_405,
1259 .msr_mask = 0x00000000020EFF30,
1260 },
1261#endif
1262#if defined (TODO)
1263 /* Npe405 L */
1264 {
1265 .name = "Npe405L",
1266 .pvr = CPU_PPC_NPE405L,
1267 .pvr_mask = 0xFFFF0000,
1268 .insns_flags = PPC_INSNS_405,
1269 .flags = PPC_FLAGS_405,
1270 .msr_mask = 0x00000000020EFF30,
1271 },
1272#endif
1273#if defined (TODO)
1274 /* STB03xx */
1275 {
1276 .name = "STB03",
1277 .pvr = CPU_PPC_STB03,
1278 .pvr_mask = 0xFFFF0000,
1279 .insns_flags = PPC_INSNS_405,
1280 .flags = PPC_FLAGS_405,
1281 .msr_mask = 0x00000000020EFF30,
1282 },
1283#endif
1284#if defined (TODO)
1285 /* STB04xx */
1286 {
1287 .name = "STB04",
1288 .pvr = CPU_PPC_STB04,
1289 .pvr_mask = 0xFFFF0000,
1290 .insns_flags = PPC_INSNS_405,
1291 .flags = PPC_FLAGS_405,
1292 .msr_mask = 0x00000000020EFF30,
1293 },
1294#endif
1295#if defined (TODO)
1296 /* STB25xx */
1297 {
1298 .name = "STB25",
1299 .pvr = CPU_PPC_STB25,
1300 .pvr_mask = 0xFFFF0000,
1301 .insns_flags = PPC_INSNS_405,
1302 .flags = PPC_FLAGS_405,
1303 .msr_mask = 0x00000000020EFF30,
1304 },
1305#endif
1306#if defined (TODO)
1307 /* PPC 440 EP */
1308 {
1309 .name = "440ep",
1310 .pvr = CPU_PPC_440EP,
1311 .pvr_mask = 0xFFFF0000,
1312 .insns_flags = PPC_INSNS_440,
1313 .flags = PPC_FLAGS_440,
1314 .msr_mask = 0x000000000006D630,
1315 },
1316#endif
1317#if defined (TODO)
1318 /* PPC 440 GP */
1319 {
1320 .name = "440gp",
1321 .pvr = CPU_PPC_440GP,
1322 .pvr_mask = 0xFFFFFF00,
1323 .insns_flags = PPC_INSNS_440,
1324 .flags = PPC_FLAGS_440,
1325 .msr_mask = 0x000000000006D630,
1326 },
1327#endif
1328#if defined (TODO)
1329 /* PPC 440 GX */
1330 {
1331 .name = "440gx",
1332 .pvr = CPU_PPC_440GX,
1333 .pvr_mask = 0xFFFF0000,
1334 .insns_flags = PPC_INSNS_405,
1335 .flags = PPC_FLAGS_440,
1336 .msr_mask = 0x000000000006D630,
1337 },
1338#endif
1339
1340 /* 32 bits "classic" powerpc */
1341#if defined (TODO)
1342 /* PPC 601 */
1343 {
1344 .name = "601",
1345 .pvr = CPU_PPC_601,
1346 .pvr_mask = 0xFFFF0000,
1347 .insns_flags = PPC_INSNS_601,
1348 .flags = PPC_FLAGS_601,
1349 .msr_mask = 0x000000000000FD70,
1350 },
1351#endif
1352#if defined (TODO)
1353 /* PPC 602 */
1354 {
1355 .name = "602",
1356 .pvr = CPU_PPC_602,
1357 .pvr_mask = 0xFFFF0000,
1358 .insns_flags = PPC_INSNS_602,
1359 .flags = PPC_FLAGS_602,
1360 .msr_mask = 0x0000000000C7FF73,
1361 },
1362#endif
1363#if defined (TODO)
1364 /* PPC 603 */
1365 {
1366 .name = "603",
1367 .pvr = CPU_PPC_603,
1368 .pvr_mask = 0xFFFF0000,
1369 .insns_flags = PPC_INSNS_603,
1370 .flags = PPC_FLAGS_603,
1371 .msr_mask = 0x000000000007FF73,
1372 },
1373#endif
1374#if defined (TODO)
1375 /* PPC 603e */
1376 {
1377 .name = "603e",
1378 .pvr = CPU_PPC_603E,
1379 .pvr_mask = 0xFFFF0000,
1380 .insns_flags = PPC_INSNS_603,
1381 .flags = PPC_FLAGS_603,
1382 .msr_mask = 0x000000000007FF73,
1383 },
1384 {
1385 .name = "Stretch",
1386 .pvr = CPU_PPC_603E,
1387 .pvr_mask = 0xFFFF0000,
1388 .insns_flags = PPC_INSNS_603,
1389 .flags = PPC_FLAGS_603,
1390 .msr_mask = 0x000000000007FF73,
1391 },
1392#endif
1393#if defined (TODO)
1394 /* PPC 603ev */
1395 {
1396 .name = "603ev",
1397 .pvr = CPU_PPC_603EV,
1398 .pvr_mask = 0xFFFFF000,
1399 .insns_flags = PPC_INSNS_603,
1400 .flags = PPC_FLAGS_603,
1401 .msr_mask = 0x000000000007FF73,
1402 },
1403#endif
1404#if defined (TODO)
1405 /* PPC 603r */
1406 {
1407 .name = "603r",
1408 .pvr = CPU_PPC_603R,
1409 .pvr_mask = 0xFFFFF000,
1410 .insns_flags = PPC_INSNS_603,
1411 .flags = PPC_FLAGS_603,
1412 .msr_mask = 0x000000000007FF73,
1413 },
1414 {
1415 .name = "Goldeneye",
1416 .pvr = CPU_PPC_603R,
1417 .pvr_mask = 0xFFFFF000,
1418 .insns_flags = PPC_INSNS_603,
1419 .flags = PPC_FLAGS_603,
1420 .msr_mask = 0x000000000007FF73,
1421 },
1422#endif
1423#if defined (TODO)
1424 /* XXX: TODO: according to Motorola UM, this is a derivative to 603e */
1425 {
1426 .name = "G2",
1427 .pvr = CPU_PPC_G2,
1428 .pvr_mask = 0xFFFF0000,
1429 .insns_flags = PPC_INSNS_G2,
1430 .flags = PPC_FLAGS_G2,
1431 .msr_mask = 0x000000000006FFF2,
1432 },
1433 { /* Same as G2, with LE mode support */
1434 .name = "G2le",
1435 .pvr = CPU_PPC_G2LE,
1436 .pvr_mask = 0xFFFF0000,
1437 .insns_flags = PPC_INSNS_G2,
1438 .flags = PPC_FLAGS_G2,
1439 .msr_mask = 0x000000000007FFF3,
1440 },
1441#endif
1442 /* PPC 604 */
1443 {
1444 .name = "604",
1445 .pvr = CPU_PPC_604,
1446 .pvr_mask = 0xFFFF0000,
1447 .insns_flags = PPC_INSNS_604,
1448 .flags = PPC_FLAGS_604,
1449 .msr_mask = 0x000000000005FF77,
1450 },
1451 /* PPC 604e */
1452 {
1453 .name = "604e",
1454 .pvr = CPU_PPC_604E,
1455 .pvr_mask = 0xFFFF0000,
1456 .insns_flags = PPC_INSNS_604,
1457 .flags = PPC_FLAGS_604,
1458 .msr_mask = 0x000000000005FF77,
1459 },
1460 /* PPC 604r */
1461 {
1462 .name = "604r",
1463 .pvr = CPU_PPC_604R,
1464 .pvr_mask = 0xFFFF0000,
1465 .insns_flags = PPC_INSNS_604,
1466 .flags = PPC_FLAGS_604,
1467 .msr_mask = 0x000000000005FF77,
1468 },
1469 /* generic G3 */
1470 {
1471 .name = "G3",
1472 .pvr = CPU_PPC_74x,
1473 .pvr_mask = 0xFFFFF000,
1474 .insns_flags = PPC_INSNS_7x0,
1475 .flags = PPC_FLAGS_7x0,
1476 .msr_mask = 0x000000000007FF77,
1477 },
1478#if defined (TODO)
1479 /* MPC740 (G3) */
1480 {
1481 .name = "740",
1482 .pvr = CPU_PPC_74x,
1483 .pvr_mask = 0xFFFFF000,
1484 .insns_flags = PPC_INSNS_7x0,
1485 .flags = PPC_FLAGS_7x0,
1486 .msr_mask = 0x000000000007FF77,
1487 },
1488 {
1489 .name = "Arthur",
1490 .pvr = CPU_PPC_74x,
1491 .pvr_mask = 0xFFFFF000,
1492 .insns_flags = PPC_INSNS_7x0,
1493 .flags = PPC_FLAGS_7x0,
1494 .msr_mask = 0x000000000007FF77,
1495 },
1496#endif
1497#if defined (TODO)
1498 /* MPC745 (G3) */
1499 {
1500 .name = "745",
1501 .pvr = CPU_PPC_74x,
1502 .pvr_mask = 0xFFFFF000,
1503 .insns_flags = PPC_INSNS_7x5,
1504 .flags = PPC_FLAGS_7x5,
1505 .msr_mask = 0x000000000007FF77,
1506 },
1507 {
1508 .name = "Goldfinger",
1509 .pvr = CPU_PPC_74x,
1510 .pvr_mask = 0xFFFFF000,
1511 .insns_flags = PPC_INSNS_7x5,
1512 .flags = PPC_FLAGS_7x5,
1513 .msr_mask = 0x000000000007FF77,
1514 },
1515#endif
1516 /* MPC750 (G3) */
1517 {
1518 .name = "750",
1519 .pvr = CPU_PPC_74x,
1520 .pvr_mask = 0xFFFFF000,
1521 .insns_flags = PPC_INSNS_7x0,
1522 .flags = PPC_FLAGS_7x0,
1523 .msr_mask = 0x000000000007FF77,
1524 },
1525#if defined (TODO)
1526 /* MPC755 (G3) */
1527 {
1528 .name = "755",
1529 .pvr = CPU_PPC_755,
1530 .pvr_mask = 0xFFFFF000,
1531 .insns_flags = PPC_INSNS_7x5,
1532 .flags = PPC_FLAGS_7x5,
1533 .msr_mask = 0x000000000007FF77,
1534 },
1535#endif
1536#if defined (TODO)
1537 /* MPC740P (G3) */
1538 {
1539 .name = "740p",
1540 .pvr = CPU_PPC_74xP,
1541 .pvr_mask = 0xFFFFF000,
1542 .insns_flags = PPC_INSNS_7x0,
1543 .flags = PPC_FLAGS_7x0,
1544 .msr_mask = 0x000000000007FF77,
1545 },
1546 {
1547 .name = "Conan/Doyle",
1548 .pvr = CPU_PPC_74xP,
1549 .pvr_mask = 0xFFFFF000,
1550 .insns_flags = PPC_INSNS_7x0,
1551 .flags = PPC_FLAGS_7x0,
1552 .msr_mask = 0x000000000007FF77,
1553 },
1554#endif
1555#if defined (TODO)
1556 /* MPC745P (G3) */
1557 {
1558 .name = "745p",
1559 .pvr = CPU_PPC_74xP,
1560 .pvr_mask = 0xFFFFF000,
1561 .insns_flags = PPC_INSNS_7x5,
1562 .flags = PPC_FLAGS_7x5,
1563 .msr_mask = 0x000000000007FF77,
1564 },
1565#endif
1566 /* MPC750P (G3) */
1567 {
1568 .name = "750p",
1569 .pvr = CPU_PPC_74xP,
1570 .pvr_mask = 0xFFFFF000,
1571 .insns_flags = PPC_INSNS_7x0,
1572 .flags = PPC_FLAGS_7x0,
1573 .msr_mask = 0x000000000007FF77,
1574 },
1575#if defined (TODO)
1576 /* MPC755P (G3) */
1577 {
1578 .name = "755p",
1579 .pvr = CPU_PPC_74xP,
1580 .pvr_mask = 0xFFFFF000,
1581 .insns_flags = PPC_INSNS_7x5,
1582 .flags = PPC_FLAGS_7x5,
1583 .msr_mask = 0x000000000007FF77,
1584 },
1585#endif
1586 /* IBM 750CXe (G3 embedded) */
1587 {
1588 .name = "750cxe",
1589 .pvr = CPU_PPC_750CXE,
1590 .pvr_mask = 0xFFFFF000,
1591 .insns_flags = PPC_INSNS_7x0,
1592 .flags = PPC_FLAGS_7x0,
1593 .msr_mask = 0x000000000007FF77,
1594 },
1595 /* IBM 750FX (G3 embedded) */
1596 {
1597 .name = "750fx",
1598 .pvr = CPU_PPC_750FX,
1599 .pvr_mask = 0xFFFF0000,
1600 .insns_flags = PPC_INSNS_7x0,
1601 .flags = PPC_FLAGS_7x0,
1602 .msr_mask = 0x000000000007FF77,
1603 },
1604 /* IBM 750GX (G3 embedded) */
1605 {
1606 .name = "750gx",
1607 .pvr = CPU_PPC_750GX,
1608 .pvr_mask = 0xFFFF0000,
1609 .insns_flags = PPC_INSNS_7x0,
1610 .flags = PPC_FLAGS_7x0,
1611 .msr_mask = 0x000000000007FF77,
1612 },
1613#if defined (TODO)
1614 /* generic G4 */
1615 {
1616 .name = "G4",
1617 .pvr = CPU_PPC_7400,
1618 .pvr_mask = 0xFFFF0000,
1619 .insns_flags = PPC_INSNS_74xx,
1620 .flags = PPC_FLAGS_74xx,
1621 .msr_mask = 0x000000000205FF77,
1622 },
1623#endif
1624#if defined (TODO)
1625 /* PPC 7400 (G4) */
1626 {
1627 .name = "7400",
1628 .pvr = CPU_PPC_7400,
1629 .pvr_mask = 0xFFFF0000,
1630 .insns_flags = PPC_INSNS_74xx,
1631 .flags = PPC_FLAGS_74xx,
1632 .msr_mask = 0x000000000205FF77,
1633 },
1634 {
1635 .name = "Max",
1636 .pvr = CPU_PPC_7400,
1637 .pvr_mask = 0xFFFF0000,
1638 .insns_flags = PPC_INSNS_74xx,
1639 .flags = PPC_FLAGS_74xx,
1640 .msr_mask = 0x000000000205FF77,
1641 },
1642#endif
1643#if defined (TODO)
1644 /* PPC 7410 (G4) */
1645 {
1646 .name = "7410",
1647 .pvr = CPU_PPC_7410,
1648 .pvr_mask = 0xFFFF0000,
1649 .insns_flags = PPC_INSNS_74xx,
1650 .flags = PPC_FLAGS_74xx,
1651 .msr_mask = 0x000000000205FF77,
1652 },
1653 {
1654 .name = "Nitro",
1655 .pvr = CPU_PPC_7410,
1656 .pvr_mask = 0xFFFF0000,
1657 .insns_flags = PPC_INSNS_74xx,
1658 .flags = PPC_FLAGS_74xx,
1659 .msr_mask = 0x000000000205FF77,
1660 },
1661#endif
1662 /* XXX: 7441 */
1663 /* XXX: 7445 */
1664 /* XXX: 7447 */
1665 /* XXX: 7447A */
1666#if defined (TODO)
1667 /* PPC 7450 (G4) */
1668 {
1669 .name = "7450",
1670 .pvr = CPU_PPC_7450,
1671 .pvr_mask = 0xFFFF0000,
1672 .insns_flags = PPC_INSNS_74xx,
1673 .flags = PPC_FLAGS_74xx,
1674 .msr_mask = 0x000000000205FF77,
1675 },
1676 {
1677 .name = "Vger",
1678 .pvr = CPU_PPC_7450,
1679 .pvr_mask = 0xFFFF0000,
1680 .insns_flags = PPC_INSNS_74xx,
1681 .flags = PPC_FLAGS_74xx,
1682 .msr_mask = 0x000000000205FF77,
1683 },
1684#endif
1685 /* XXX: 7451 */
1686#if defined (TODO)
1687 /* PPC 7455 (G4) */
1688 {
1689 .name = "7455",
1690 .pvr = CPU_PPC_7455,
1691 .pvr_mask = 0xFFFF0000,
1692 .insns_flags = PPC_INSNS_74xx,
1693 .flags = PPC_FLAGS_74xx,
1694 .msr_mask = 0x000000000205FF77,
1695 },
1696 {
1697 .name = "Apollo 6",
1698 .pvr = CPU_PPC_7455,
1699 .pvr_mask = 0xFFFF0000,
1700 .insns_flags = PPC_INSNS_74xx,
1701 .flags = PPC_FLAGS_74xx,
1702 .msr_mask = 0x000000000205FF77,
1703 },
1704#endif
1705#if defined (TODO)
1706 /* PPC 7457 (G4) */
1707 {
1708 .name = "7457",
1709 .pvr = CPU_PPC_7457,
1710 .pvr_mask = 0xFFFF0000,
1711 .insns_flags = PPC_INSNS_74xx,
1712 .flags = PPC_FLAGS_74xx,
1713 .msr_mask = 0x000000000205FF77,
1714 },
1715 {
1716 .name = "Apollo 7",
1717 .pvr = CPU_PPC_7457,
1718 .pvr_mask = 0xFFFF0000,
1719 .insns_flags = PPC_INSNS_74xx,
1720 .flags = PPC_FLAGS_74xx,
1721 .msr_mask = 0x000000000205FF77,
1722 },
1723#endif
1724#if defined (TODO)
1725 /* PPC 7457A (G4) */
1726 {
1727 .name = "7457A",
1728 .pvr = CPU_PPC_7457A,
1729 .pvr_mask = 0xFFFF0000,
1730 .insns_flags = PPC_INSNS_74xx,
1731 .flags = PPC_FLAGS_74xx,
1732 .msr_mask = 0x000000000205FF77,
1733 },
1734 {
1735 .name = "Apollo 7 PM",
1736 .pvr = CPU_PPC_7457A,
1737 .pvr_mask = 0xFFFF0000,
1738 .insns_flags = PPC_INSNS_74xx,
1739 .flags = PPC_FLAGS_74xx,
1740 .msr_mask = 0x000000000205FF77,
1741 },
1742#endif
1743 /* 64 bits PPC */
1744#if defined (TODO)
1745 /* PPC 620 */
1746 {
1747 .name = "620",
1748 .pvr = CPU_PPC_620,
1749 .pvr_mask = 0xFFFF0000,
1750 .insns_flags = PPC_INSNS_620,
1751 .flags = PPC_FLAGS_620,
1752 .msr_mask = 0x800000000005FF73,
1753 },
1754#endif
1755#if defined (TODO)
1756 /* PPC 630 (POWER3) */
1757 {
1758 .name = "630",
1759 .pvr = CPU_PPC_630,
1760 .pvr_mask = 0xFFFF0000,
1761 .insns_flags = PPC_INSNS_630,
1762 .flags = PPC_FLAGS_630,
1763 .msr_mask = xxx,
1764 }
1765 {
1766 .name = "POWER3",
1767 .pvr = CPU_PPC_630,
1768 .pvr_mask = 0xFFFF0000,
1769 .insns_flags = PPC_INSNS_630,
1770 .flags = PPC_FLAGS_630,
1771 .msr_mask = xxx,
1772 }
1773#endif
1774#if defined (TODO)
1775 /* PPC 631 (Power 3+)*/
1776 {
1777 .name = "631",
1778 .pvr = CPU_PPC_631,
1779 .pvr_mask = 0xFFFF0000,
1780 .insns_flags = PPC_INSNS_631,
1781 .flags = PPC_FLAGS_631,
1782 .msr_mask = xxx,
1783 },
1784 {
1785 .name = "POWER3+",
1786 .pvr = CPU_PPC_631,
1787 .pvr_mask = 0xFFFF0000,
1788 .insns_flags = PPC_INSNS_631,
1789 .flags = PPC_FLAGS_631,
1790 .msr_mask = xxx,
1791 },
1792#endif
1793#if defined (TODO)
1794 /* POWER4 */
1795 {
1796 .name = "POWER4",
1797 .pvr = CPU_PPC_POWER4,
1798 .pvr_mask = 0xFFFF0000,
1799 .insns_flags = PPC_INSNS_POWER4,
1800 .flags = PPC_FLAGS_POWER4,
1801 .msr_mask = xxx,
1802 },
1803#endif
1804#if defined (TODO)
1805 /* POWER4p */
1806 {
1807 .name = "POWER4+",
1808 .pvr = CPU_PPC_POWER4P,
1809 .pvr_mask = 0xFFFF0000,
1810 .insns_flags = PPC_INSNS_POWER4,
1811 .flags = PPC_FLAGS_POWER4,
1812 .msr_mask = xxx,
1813 },
1814#endif
1815#if defined (TODO)
1816 /* POWER5 */
1817 {
1818 .name = "POWER5",
1819 .pvr = CPU_PPC_POWER5,
1820 .pvr_mask = 0xFFFF0000,
1821 .insns_flags = PPC_INSNS_POWER5,
1822 .flags = PPC_FLAGS_POWER5,
1823 .msr_mask = xxx,
1824 },
1825#endif
1826#if defined (TODO)
1827 /* POWER5+ */
1828 {
1829 .name = "POWER5+",
1830 .pvr = CPU_PPC_POWER5P,
1831 .pvr_mask = 0xFFFF0000,
1832 .insns_flags = PPC_INSNS_POWER5,
1833 .flags = PPC_FLAGS_POWER5,
1834 .msr_mask = xxx,
1835 },
1836#endif
1837#if defined (TODO)
1838 /* PPC 970 */
1839 {
1840 .name = "970",
1841 .pvr = CPU_PPC_970,
1842 .pvr_mask = 0xFFFF0000,
1843 .insns_flags = PPC_INSNS_970,
1844 .flags = PPC_FLAGS_970,
1845 .msr_mask = 0x900000000204FF36,
1846 },
1847#endif
1848#if defined (TODO)
1849 /* PPC 970FX (G5) */
1850 {
1851 .name = "970fx",
1852 .pvr = CPU_PPC_970FX,
1853 .pvr_mask = 0xFFFF0000,
1854 .insns_flags = PPC_INSNS_970FX,
1855 .flags = PPC_FLAGS_970FX,
1856 .msr_mask = 0x800000000204FF36,
1857 },
1858#endif
1859#if defined (TODO)
1860 /* RS64 (Apache/A35) */
1861 /* This one seems to support the whole POWER2 instruction set
1862 * and the PowerPC 64 one.
1863 */
1864 {
1865 .name = "RS64",
1866 .pvr = CPU_PPC_RS64,
1867 .pvr_mask = 0xFFFF0000,
1868 .insns_flags = PPC_INSNS_RS64,
1869 .flags = PPC_FLAGS_RS64,
1870 .msr_mask = xxx,
1871 },
1872 {
1873 .name = "Apache",
1874 .pvr = CPU_PPC_RS64,
1875 .pvr_mask = 0xFFFF0000,
1876 .insns_flags = PPC_INSNS_RS64,
1877 .flags = PPC_FLAGS_RS64,
1878 .msr_mask = xxx,
1879 },
1880 {
1881 .name = "A35",
1882 .pvr = CPU_PPC_RS64,
1883 .pvr_mask = 0xFFFF0000,
1884 .insns_flags = PPC_INSNS_RS64,
1885 .flags = PPC_FLAGS_RS64,
1886 .msr_mask = xxx,
1887 },
1888#endif
1889#if defined (TODO)
1890 /* RS64-II (NorthStar/A50) */
1891 {
1892 .name = "RS64-II",
1893 .pvr = CPU_PPC_RS64II,
1894 .pvr_mask = 0xFFFF0000,
1895 .insns_flags = PPC_INSNS_RS64,
1896 .flags = PPC_FLAGS_RS64,
1897 .msr_mask = xxx,
1898 },
1899 {
1900 .name = "NortStar",
1901 .pvr = CPU_PPC_RS64II,
1902 .pvr_mask = 0xFFFF0000,
1903 .insns_flags = PPC_INSNS_RS64,
1904 .flags = PPC_FLAGS_RS64,
1905 .msr_mask = xxx,
1906 },
1907 {
1908 .name = "A50",
1909 .pvr = CPU_PPC_RS64II,
1910 .pvr_mask = 0xFFFF0000,
1911 .insns_flags = PPC_INSNS_RS64,
1912 .flags = PPC_FLAGS_RS64,
1913 .msr_mask = xxx,
1914 },
1915#endif
1916#if defined (TODO)
1917 /* RS64-III (Pulsar) */
1918 {
1919 .name = "RS64-III",
1920 .pvr = CPU_PPC_RS64III,
1921 .pvr_mask = 0xFFFF0000,
1922 .insns_flags = PPC_INSNS_RS64,
1923 .flags = PPC_FLAGS_RS64,
1924 .msr_mask = xxx,
1925 },
1926 {
1927 .name = "Pulsar",
1928 .pvr = CPU_PPC_RS64III,
1929 .pvr_mask = 0xFFFF0000,
1930 .insns_flags = PPC_INSNS_RS64,
1931 .flags = PPC_FLAGS_RS64,
1932 .msr_mask = xxx,
1933 },
1934#endif
1935#if defined (TODO)
1936 /* RS64-IV (IceStar/IStar/SStar) */
1937 {
1938 .name = "RS64-IV",
1939 .pvr = CPU_PPC_RS64IV,
1940 .pvr_mask = 0xFFFF0000,
1941 .insns_flags = PPC_INSNS_RS64,
1942 .flags = PPC_FLAGS_RS64,
1943 .msr_mask = xxx,
1944 },
1945 {
1946 .name = "IceStar",
1947 .pvr = CPU_PPC_RS64IV,
1948 .pvr_mask = 0xFFFF0000,
1949 .insns_flags = PPC_INSNS_RS64,
1950 .flags = PPC_FLAGS_RS64,
1951 .msr_mask = xxx,
1952 },
1953 {
1954 .name = "IStar",
1955 .pvr = CPU_PPC_RS64IV,
1956 .pvr_mask = 0xFFFF0000,
1957 .insns_flags = PPC_INSNS_RS64,
1958 .flags = PPC_FLAGS_RS64,
1959 .msr_mask = xxx,
1960 },
1961 {
1962 .name = "SStar",
1963 .pvr = CPU_PPC_RS64IV,
1964 .pvr_mask = 0xFFFF0000,
1965 .insns_flags = PPC_INSNS_RS64,
1966 .flags = PPC_FLAGS_RS64,
1967 .msr_mask = xxx,
1968 },
1969#endif
1970 /* POWER */
1971#if defined (TODO)
1972 /* Original POWER */
1973 {
1974 .name = "POWER",
1975 .pvr = CPU_POWER,
1976 .pvr_mask = 0xFFFF0000,
1977 .insns_flags = PPC_INSNS_POWER,
1978 .flags = PPC_FLAGS_POWER,
1979 .msr_mask = xxx,
1980 },
1981#endif
1982#if defined (TODO)
1983 /* POWER2 */
1984 {
1985 .name = "POWER2",
1986 .pvr = CPU_POWER2,
1987 .pvr_mask = 0xFFFF0000,
1988 .insns_flags = PPC_INSNS_POWER,
1989 .flags = PPC_FLAGS_POWER,
1990 .msr_mask = xxx,
1991 },
1992#endif
1993 /* Generic PowerPCs */
1994#if defined (TODO)
1995 {
1996 .name = "ppc64",
1997 .pvr = CPU_PPC_970,
1998 .pvr_mask = 0xFFFF0000,
1999 .insns_flags = PPC_INSNS_PPC64,
2000 .flags = PPC_FLAGS_PPC64,
2001 .msr_mask = 0xA00000000204FF36,
2002 },
2003#endif
2004 {
2005 .name = "ppc32",
2006 .pvr = CPU_PPC_604,
2007 .pvr_mask = 0xFFFF0000,
2008 .insns_flags = PPC_INSNS_PPC32,
2009 .flags = PPC_FLAGS_PPC32,
2010 .msr_mask = 0x000000000005FF77,
2011 },
2012 /* Fallback */
2013 {
2014 .name = "ppc",
2015 .pvr = CPU_PPC_604,
2016 .pvr_mask = 0xFFFF0000,
2017 .insns_flags = PPC_INSNS_PPC32,
2018 .flags = PPC_FLAGS_PPC32,
2019 .msr_mask = 0x000000000005FF77,
2020 },
2021};
2022
2023int ppc_find_by_name (const unsigned char *name, ppc_def_t **def)
2024{
2025 int i, ret;
2026
2027 ret = -1;
2028 *def = NULL;
2029 for (i = 0; strcmp(ppc_defs[i].name, "ppc") != 0; i++) {
2030 if (strcasecmp(name, ppc_defs[i].name) == 0) {
2031 *def = &ppc_defs[i];
2032 ret = 0;
2033 break;
2034 }
2035 }
2036
2037 return ret;
2038}
2039
2040int ppc_find_by_pvr (uint32_t pvr, ppc_def_t **def)
2041{
2042 int i, ret;
2043
2044 ret = -1;
2045 *def = NULL;
2046 for (i = 0; ppc_defs[i].name != NULL; i++) {
2047 if ((pvr & ppc_defs[i].pvr_mask) ==
2048 (ppc_defs[i].pvr & ppc_defs[i].pvr_mask)) {
2049 *def = &ppc_defs[i];
2050 ret = 0;
2051 break;
2052 }
2053 }
2054
2055 return ret;
2056}
2057
2058void ppc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
2059{
2060 int i;
2061
2062 for (i = 0; ; i++) {
2063 (*cpu_fprintf)(f, "PowerPC '%s' PVR %08x mask %08x\n",
2064 ppc_defs[i].name,
2065 ppc_defs[i].pvr, ppc_defs[i].pvr_mask);
2066 if (strcmp(ppc_defs[i].name, "ppc") == 0)
2067 break;
2068 }
2069}