]> git.proxmox.com Git - mirror_qemu.git/blame - target-ppc/translate_init.c
Simple u-boot image loading support.
[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)
26a76461 255 printf("*** register spr %d (%03x) %s val %08" PRIx64 "\n", num, num, name,
3fc6c082
FB
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
3fc6c082
FB
1084 env = qemu_mallocz(sizeof(CPUPPCState));
1085 if (!env)
1086 return NULL;
173d6cfe 1087 cpu_exec_init(env);
3fc6c082
FB
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;
3fc6c082
FB
1103 return env;
1104}
1105
1106void cpu_ppc_close(CPUPPCState *env)
1107{
1108 /* Should also remove all opcode tables... */
1109 free(env);
1110}
1111
1112/*****************************************************************************/
1113/* PowerPC CPU definitions */
1114static 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
2021int 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
2038int 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
2056void 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}