|
|
1.1 root 1: /*
2: * PowerPC CPU initialization for qemu.
3: *
4: * Copyright (c) 2003-2005 Jocelyn Mayer
5: *
6: * This library is free software; you can redistribute it and/or
7: * modify it under the terms of the GNU Lesser General Public
8: * License as published by the Free Software Foundation; either
9: * version 2 of the License, or (at your option) any later version.
10: *
11: * This library is distributed in the hope that it will be useful,
12: * but WITHOUT ANY WARRANTY; without even the implied warranty of
13: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14: * Lesser General Public License for more details.
15: *
16: * You should have received a copy of the GNU Lesser General Public
17: * License along with this library; if not, write to the Free Software
18: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19: */
20:
21: /* A lot of PowerPC definition have been included here.
22: * Most of them are not usable for now but have been kept
23: * inside "#if defined(TODO) ... #endif" statements to make tests easier.
24: */
25:
26: //#define PPC_DUMP_CPU
27: //#define PPC_DEBUG_SPR
28:
29: struct ppc_def_t {
30: const unsigned char *name;
31: uint32_t pvr;
32: uint32_t pvr_mask;
33: uint32_t insns_flags;
34: uint32_t flags;
35: uint64_t msr_mask;
36: };
37:
38: /* Generic callbacks:
39: * do nothing but store/retrieve spr value
40: */
41: static void spr_read_generic (void *opaque, int sprn)
42: {
43: gen_op_load_spr(sprn);
44: }
45:
46: static void spr_write_generic (void *opaque, int sprn)
47: {
48: gen_op_store_spr(sprn);
49: }
50:
51: /* SPR common to all PPC */
52: /* XER */
53: static void spr_read_xer (void *opaque, int sprn)
54: {
55: gen_op_load_xer();
56: }
57:
58: static void spr_write_xer (void *opaque, int sprn)
59: {
60: gen_op_store_xer();
61: }
62:
63: /* LR */
64: static void spr_read_lr (void *opaque, int sprn)
65: {
66: gen_op_load_lr();
67: }
68:
69: static void spr_write_lr (void *opaque, int sprn)
70: {
71: gen_op_store_lr();
72: }
73:
74: /* CTR */
75: static void spr_read_ctr (void *opaque, int sprn)
76: {
77: gen_op_load_ctr();
78: }
79:
80: static void spr_write_ctr (void *opaque, int sprn)
81: {
82: gen_op_store_ctr();
83: }
84:
85: /* User read access to SPR */
86: /* USPRx */
87: /* UMMCRx */
88: /* UPMCx */
89: /* USIA */
90: /* UDECR */
91: static void spr_read_ureg (void *opaque, int sprn)
92: {
93: gen_op_load_spr(sprn + 0x10);
94: }
95:
96: /* SPR common to all non-embedded PPC (ie not 4xx) */
97: /* DECR */
98: static void spr_read_decr (void *opaque, int sprn)
99: {
100: gen_op_load_decr();
101: }
102:
103: static void spr_write_decr (void *opaque, int sprn)
104: {
105: gen_op_store_decr();
106: }
107:
108: /* SPR common to all non-embedded PPC, except 601 */
109: /* Time base */
110: static void spr_read_tbl (void *opaque, int sprn)
111: {
112: gen_op_load_tbl();
113: }
114:
115: static void spr_write_tbl (void *opaque, int sprn)
116: {
117: gen_op_store_tbl();
118: }
119:
120: static void spr_read_tbu (void *opaque, int sprn)
121: {
122: gen_op_load_tbu();
123: }
124:
125: static void spr_write_tbu (void *opaque, int sprn)
126: {
127: gen_op_store_tbu();
128: }
129:
130: /* IBAT0U...IBAT0U */
131: /* IBAT0L...IBAT7L */
132: static void spr_read_ibat (void *opaque, int sprn)
133: {
134: gen_op_load_ibat(sprn & 1, (sprn - SPR_IBAT0U) / 2);
135: }
136:
137: static void spr_read_ibat_h (void *opaque, int sprn)
138: {
139: gen_op_load_ibat(sprn & 1, (sprn - SPR_IBAT4U) / 2);
140: }
141:
142: static void spr_write_ibatu (void *opaque, int sprn)
143: {
144: DisasContext *ctx = opaque;
145:
146: gen_op_store_ibatu((sprn - SPR_IBAT0U) / 2);
147: RET_STOP(ctx);
148: }
149:
150: static void spr_write_ibatu_h (void *opaque, int sprn)
151: {
152: DisasContext *ctx = opaque;
153:
154: gen_op_store_ibatu((sprn - SPR_IBAT4U) / 2);
155: RET_STOP(ctx);
156: }
157:
158: static void spr_write_ibatl (void *opaque, int sprn)
159: {
160: DisasContext *ctx = opaque;
161:
162: gen_op_store_ibatl((sprn - SPR_IBAT0L) / 2);
163: RET_STOP(ctx);
164: }
165:
166: static void spr_write_ibatl_h (void *opaque, int sprn)
167: {
168: DisasContext *ctx = opaque;
169:
170: gen_op_store_ibatl((sprn - SPR_IBAT4L) / 2);
171: RET_STOP(ctx);
172: }
173:
174: /* DBAT0U...DBAT7U */
175: /* DBAT0L...DBAT7L */
176: static void spr_read_dbat (void *opaque, int sprn)
177: {
178: gen_op_load_dbat(sprn & 1, (sprn - SPR_DBAT0U) / 2);
179: }
180:
181: static void spr_read_dbat_h (void *opaque, int sprn)
182: {
183: gen_op_load_dbat(sprn & 1, (sprn - SPR_DBAT4U) / 2);
184: }
185:
186: static void spr_write_dbatu (void *opaque, int sprn)
187: {
188: DisasContext *ctx = opaque;
189:
190: gen_op_store_dbatu((sprn - SPR_DBAT0U) / 2);
191: RET_STOP(ctx);
192: }
193:
194: static void spr_write_dbatu_h (void *opaque, int sprn)
195: {
196: DisasContext *ctx = opaque;
197:
198: gen_op_store_dbatu((sprn - SPR_DBAT4U) / 2);
199: RET_STOP(ctx);
200: }
201:
202: static void spr_write_dbatl (void *opaque, int sprn)
203: {
204: DisasContext *ctx = opaque;
205:
206: gen_op_store_dbatl((sprn - SPR_DBAT0L) / 2);
207: RET_STOP(ctx);
208: }
209:
210: static void spr_write_dbatl_h (void *opaque, int sprn)
211: {
212: DisasContext *ctx = opaque;
213:
214: gen_op_store_dbatl((sprn - SPR_DBAT4L) / 2);
215: RET_STOP(ctx);
216: }
217:
218: /* SDR1 */
219: static void spr_read_sdr1 (void *opaque, int sprn)
220: {
221: gen_op_load_sdr1();
222: }
223:
224: static void spr_write_sdr1 (void *opaque, int sprn)
225: {
226: DisasContext *ctx = opaque;
227:
228: gen_op_store_sdr1();
229: RET_STOP(ctx);
230: }
231:
232: static void spr_write_pir (void *opaque, int sprn)
233: {
234: gen_op_store_pir();
235: }
236:
237: static inline void spr_register (CPUPPCState *env, int num,
238: const unsigned char *name,
239: void (*uea_read)(void *opaque, int sprn),
240: void (*uea_write)(void *opaque, int sprn),
241: void (*oea_read)(void *opaque, int sprn),
242: void (*oea_write)(void *opaque, int sprn),
243: target_ulong initial_value)
244: {
245: ppc_spr_t *spr;
246:
247: spr = &env->spr_cb[num];
248: if (spr->name != NULL ||env-> spr[num] != 0x00000000 ||
249: spr->uea_read != NULL || spr->uea_write != NULL ||
250: spr->oea_read != NULL || spr->oea_write != NULL) {
251: printf("Error: Trying to register SPR %d (%03x) twice !\n", num, num);
252: exit(1);
253: }
254: #if defined(PPC_DEBUG_SPR)
255: printf("*** register spr %d (%03x) %s val %08llx\n", num, num, name,
256: (unsigned long long)initial_value);
257: #endif
258: spr->name = name;
259: spr->uea_read = uea_read;
260: spr->uea_write = uea_write;
261: spr->oea_read = oea_read;
262: spr->oea_write = oea_write;
263: env->spr[num] = initial_value;
264: }
265:
266: /* Generic PowerPC SPRs */
267: static void gen_spr_generic (CPUPPCState *env)
268: {
269: /* Integer processing */
270: spr_register(env, SPR_XER, "XER",
271: &spr_read_xer, &spr_write_xer,
272: &spr_read_xer, &spr_write_xer,
273: 0x00000000);
274: /* Branch contol */
275: spr_register(env, SPR_LR, "LR",
276: &spr_read_lr, &spr_write_lr,
277: &spr_read_lr, &spr_write_lr,
278: 0x00000000);
279: spr_register(env, SPR_CTR, "CTR",
280: &spr_read_ctr, &spr_write_ctr,
281: &spr_read_ctr, &spr_write_ctr,
282: 0x00000000);
283: /* Interrupt processing */
284: spr_register(env, SPR_SRR0, "SRR0",
285: SPR_NOACCESS, SPR_NOACCESS,
286: &spr_read_generic, &spr_write_generic,
287: 0x00000000);
288: spr_register(env, SPR_SRR1, "SRR1",
289: SPR_NOACCESS, SPR_NOACCESS,
290: &spr_read_generic, &spr_write_generic,
291: 0x00000000);
292: /* Processor control */
293: spr_register(env, SPR_SPRG0, "SPRG0",
294: SPR_NOACCESS, SPR_NOACCESS,
295: &spr_read_generic, &spr_write_generic,
296: 0x00000000);
297: spr_register(env, SPR_SPRG1, "SPRG1",
298: SPR_NOACCESS, SPR_NOACCESS,
299: &spr_read_generic, &spr_write_generic,
300: 0x00000000);
301: spr_register(env, SPR_SPRG2, "SPRG2",
302: SPR_NOACCESS, SPR_NOACCESS,
303: &spr_read_generic, &spr_write_generic,
304: 0x00000000);
305: spr_register(env, SPR_SPRG3, "SPRG3",
306: SPR_NOACCESS, SPR_NOACCESS,
307: &spr_read_generic, &spr_write_generic,
308: 0x00000000);
309: }
310:
311: /* SPR common to all non-embedded PowerPC, including 601 */
312: static void gen_spr_ne_601 (CPUPPCState *env)
313: {
314: /* Exception processing */
315: spr_register(env, SPR_DSISR, "DSISR",
316: SPR_NOACCESS, SPR_NOACCESS,
317: &spr_read_generic, &spr_write_generic,
318: 0x00000000);
319: spr_register(env, SPR_DAR, "DAR",
320: SPR_NOACCESS, SPR_NOACCESS,
321: &spr_read_generic, &spr_write_generic,
322: 0x00000000);
323: /* Timer */
324: spr_register(env, SPR_DECR, "DECR",
325: SPR_NOACCESS, SPR_NOACCESS,
326: &spr_read_decr, &spr_write_decr,
327: 0x00000000);
328: /* Memory management */
329: spr_register(env, SPR_SDR1, "SDR1",
330: SPR_NOACCESS, SPR_NOACCESS,
331: &spr_read_sdr1, &spr_write_sdr1,
332: 0x00000000);
333: }
334:
335: /* BATs 0-3 */
336: static void gen_low_BATs (CPUPPCState *env)
337: {
338: spr_register(env, SPR_IBAT0U, "IBAT0U",
339: SPR_NOACCESS, SPR_NOACCESS,
340: &spr_read_ibat, &spr_write_ibatu,
341: 0x00000000);
342: spr_register(env, SPR_IBAT0L, "IBAT0L",
343: SPR_NOACCESS, SPR_NOACCESS,
344: &spr_read_ibat, &spr_write_ibatl,
345: 0x00000000);
346: spr_register(env, SPR_IBAT1U, "IBAT1U",
347: SPR_NOACCESS, SPR_NOACCESS,
348: &spr_read_ibat, &spr_write_ibatu,
349: 0x00000000);
350: spr_register(env, SPR_IBAT1L, "IBAT1L",
351: SPR_NOACCESS, SPR_NOACCESS,
352: &spr_read_ibat, &spr_write_ibatl,
353: 0x00000000);
354: spr_register(env, SPR_IBAT2U, "IBAT2U",
355: SPR_NOACCESS, SPR_NOACCESS,
356: &spr_read_ibat, &spr_write_ibatu,
357: 0x00000000);
358: spr_register(env, SPR_IBAT2L, "IBAT2L",
359: SPR_NOACCESS, SPR_NOACCESS,
360: &spr_read_ibat, &spr_write_ibatl,
361: 0x00000000);
362: spr_register(env, SPR_IBAT3U, "IBAT3U",
363: SPR_NOACCESS, SPR_NOACCESS,
364: &spr_read_ibat, &spr_write_ibatu,
365: 0x00000000);
366: spr_register(env, SPR_IBAT3L, "IBAT3L",
367: SPR_NOACCESS, SPR_NOACCESS,
368: &spr_read_ibat, &spr_write_ibatl,
369: 0x00000000);
370: spr_register(env, SPR_DBAT0U, "DBAT0U",
371: SPR_NOACCESS, SPR_NOACCESS,
372: &spr_read_dbat, &spr_write_dbatu,
373: 0x00000000);
374: spr_register(env, SPR_DBAT0L, "DBAT0L",
375: SPR_NOACCESS, SPR_NOACCESS,
376: &spr_read_dbat, &spr_write_dbatl,
377: 0x00000000);
378: spr_register(env, SPR_DBAT1U, "DBAT1U",
379: SPR_NOACCESS, SPR_NOACCESS,
380: &spr_read_dbat, &spr_write_dbatu,
381: 0x00000000);
382: spr_register(env, SPR_DBAT1L, "DBAT1L",
383: SPR_NOACCESS, SPR_NOACCESS,
384: &spr_read_dbat, &spr_write_dbatl,
385: 0x00000000);
386: spr_register(env, SPR_DBAT2U, "DBAT2U",
387: SPR_NOACCESS, SPR_NOACCESS,
388: &spr_read_dbat, &spr_write_dbatu,
389: 0x00000000);
390: spr_register(env, SPR_DBAT2L, "DBAT2L",
391: SPR_NOACCESS, SPR_NOACCESS,
392: &spr_read_dbat, &spr_write_dbatl,
393: 0x00000000);
394: spr_register(env, SPR_DBAT3U, "DBAT3U",
395: SPR_NOACCESS, SPR_NOACCESS,
396: &spr_read_dbat, &spr_write_dbatu,
397: 0x00000000);
398: spr_register(env, SPR_DBAT3L, "DBAT3L",
399: SPR_NOACCESS, SPR_NOACCESS,
400: &spr_read_dbat, &spr_write_dbatl,
401: 0x00000000);
402: env->nb_BATs = 4;
403: }
404:
405: /* BATs 4-7 */
406: static void gen_high_BATs (CPUPPCState *env)
407: {
408: spr_register(env, SPR_IBAT4U, "IBAT4U",
409: SPR_NOACCESS, SPR_NOACCESS,
410: &spr_read_ibat_h, &spr_write_ibatu_h,
411: 0x00000000);
412: spr_register(env, SPR_IBAT4L, "IBAT4L",
413: SPR_NOACCESS, SPR_NOACCESS,
414: &spr_read_ibat_h, &spr_write_ibatl_h,
415: 0x00000000);
416: spr_register(env, SPR_IBAT5U, "IBAT5U",
417: SPR_NOACCESS, SPR_NOACCESS,
418: &spr_read_ibat_h, &spr_write_ibatu_h,
419: 0x00000000);
420: spr_register(env, SPR_IBAT5L, "IBAT5L",
421: SPR_NOACCESS, SPR_NOACCESS,
422: &spr_read_ibat_h, &spr_write_ibatl_h,
423: 0x00000000);
424: spr_register(env, SPR_IBAT6U, "IBAT6U",
425: SPR_NOACCESS, SPR_NOACCESS,
426: &spr_read_ibat_h, &spr_write_ibatu_h,
427: 0x00000000);
428: spr_register(env, SPR_IBAT6L, "IBAT6L",
429: SPR_NOACCESS, SPR_NOACCESS,
430: &spr_read_ibat_h, &spr_write_ibatl_h,
431: 0x00000000);
432: spr_register(env, SPR_IBAT7U, "IBAT7U",
433: SPR_NOACCESS, SPR_NOACCESS,
434: &spr_read_ibat_h, &spr_write_ibatu_h,
435: 0x00000000);
436: spr_register(env, SPR_IBAT7L, "IBAT7L",
437: SPR_NOACCESS, SPR_NOACCESS,
438: &spr_read_ibat_h, &spr_write_ibatl_h,
439: 0x00000000);
440: spr_register(env, SPR_DBAT4U, "DBAT4U",
441: SPR_NOACCESS, SPR_NOACCESS,
442: &spr_read_dbat_h, &spr_write_dbatu_h,
443: 0x00000000);
444: spr_register(env, SPR_DBAT4L, "DBAT4L",
445: SPR_NOACCESS, SPR_NOACCESS,
446: &spr_read_dbat_h, &spr_write_dbatl_h,
447: 0x00000000);
448: spr_register(env, SPR_DBAT5U, "DBAT5U",
449: SPR_NOACCESS, SPR_NOACCESS,
450: &spr_read_dbat_h, &spr_write_dbatu_h,
451: 0x00000000);
452: spr_register(env, SPR_DBAT5L, "DBAT5L",
453: SPR_NOACCESS, SPR_NOACCESS,
454: &spr_read_dbat_h, &spr_write_dbatl_h,
455: 0x00000000);
456: spr_register(env, SPR_DBAT6U, "DBAT6U",
457: SPR_NOACCESS, SPR_NOACCESS,
458: &spr_read_dbat_h, &spr_write_dbatu_h,
459: 0x00000000);
460: spr_register(env, SPR_DBAT6L, "DBAT6L",
461: SPR_NOACCESS, SPR_NOACCESS,
462: &spr_read_dbat_h, &spr_write_dbatl_h,
463: 0x00000000);
464: spr_register(env, SPR_DBAT7U, "DBAT7U",
465: SPR_NOACCESS, SPR_NOACCESS,
466: &spr_read_dbat_h, &spr_write_dbatu_h,
467: 0x00000000);
468: spr_register(env, SPR_DBAT7L, "DBAT7L",
469: SPR_NOACCESS, SPR_NOACCESS,
470: &spr_read_dbat_h, &spr_write_dbatl_h,
471: 0x00000000);
472: env->nb_BATs = 8;
473: }
474:
475: /* Generic PowerPC time base */
476: static void gen_tbl (CPUPPCState *env)
477: {
478: spr_register(env, SPR_VTBL, "TBL",
479: &spr_read_tbl, SPR_NOACCESS,
480: &spr_read_tbl, SPR_NOACCESS,
481: 0x00000000);
482: spr_register(env, SPR_TBL, "TBL",
483: SPR_NOACCESS, SPR_NOACCESS,
484: SPR_NOACCESS, &spr_write_tbl,
485: 0x00000000);
486: spr_register(env, SPR_VTBU, "TBU",
487: &spr_read_tbu, SPR_NOACCESS,
488: &spr_read_tbu, SPR_NOACCESS,
489: 0x00000000);
490: spr_register(env, SPR_TBU, "TBU",
491: SPR_NOACCESS, SPR_NOACCESS,
492: SPR_NOACCESS, &spr_write_tbu,
493: 0x00000000);
494: }
495:
496: /* SPR common to all 7xx PowerPC implementations */
497: static void gen_spr_7xx (CPUPPCState *env)
498: {
499: /* Breakpoints */
500: /* XXX : not implemented */
501: spr_register(env, SPR_DABR, "DABR",
502: SPR_NOACCESS, SPR_NOACCESS,
503: &spr_read_generic, &spr_write_generic,
504: 0x00000000);
505: /* XXX : not implemented */
506: spr_register(env, SPR_IABR, "IABR",
507: SPR_NOACCESS, SPR_NOACCESS,
508: &spr_read_generic, &spr_write_generic,
509: 0x00000000);
510: /* Cache management */
511: /* XXX : not implemented */
512: spr_register(env, SPR_ICTC, "ICTC",
513: SPR_NOACCESS, SPR_NOACCESS,
514: &spr_read_generic, &spr_write_generic,
515: 0x00000000);
516: /* Performance monitors */
517: /* XXX : not implemented */
518: spr_register(env, SPR_MMCR0, "MMCR0",
519: SPR_NOACCESS, SPR_NOACCESS,
520: &spr_read_generic, &spr_write_generic,
521: 0x00000000);
522: /* XXX : not implemented */
523: spr_register(env, SPR_MMCR1, "MMCR1",
524: SPR_NOACCESS, SPR_NOACCESS,
525: &spr_read_generic, &spr_write_generic,
526: 0x00000000);
527: /* XXX : not implemented */
528: spr_register(env, SPR_PMC1, "PMC1",
529: SPR_NOACCESS, SPR_NOACCESS,
530: &spr_read_generic, &spr_write_generic,
531: 0x00000000);
532: /* XXX : not implemented */
533: spr_register(env, SPR_PMC2, "PMC2",
534: SPR_NOACCESS, SPR_NOACCESS,
535: &spr_read_generic, &spr_write_generic,
536: 0x00000000);
537: /* XXX : not implemented */
538: spr_register(env, SPR_PMC3, "PMC3",
539: SPR_NOACCESS, SPR_NOACCESS,
540: &spr_read_generic, &spr_write_generic,
541: 0x00000000);
542: /* XXX : not implemented */
543: spr_register(env, SPR_PMC4, "PMC4",
544: SPR_NOACCESS, SPR_NOACCESS,
545: &spr_read_generic, &spr_write_generic,
546: 0x00000000);
547: /* XXX : not implemented */
548: spr_register(env, SPR_SIA, "SIA",
549: SPR_NOACCESS, SPR_NOACCESS,
550: &spr_read_generic, SPR_NOACCESS,
551: 0x00000000);
552: spr_register(env, SPR_UMMCR0, "UMMCR0",
553: &spr_read_ureg, SPR_NOACCESS,
554: &spr_read_ureg, SPR_NOACCESS,
555: 0x00000000);
556: spr_register(env, SPR_UMMCR1, "UMMCR1",
557: &spr_read_ureg, SPR_NOACCESS,
558: &spr_read_ureg, SPR_NOACCESS,
559: 0x00000000);
560: spr_register(env, SPR_UPMC1, "UPMC1",
561: &spr_read_ureg, SPR_NOACCESS,
562: &spr_read_ureg, SPR_NOACCESS,
563: 0x00000000);
564: spr_register(env, SPR_UPMC2, "UPMC2",
565: &spr_read_ureg, SPR_NOACCESS,
566: &spr_read_ureg, SPR_NOACCESS,
567: 0x00000000);
568: spr_register(env, SPR_UPMC3, "UPMC3",
569: &spr_read_ureg, SPR_NOACCESS,
570: &spr_read_ureg, SPR_NOACCESS,
571: 0x00000000);
572: spr_register(env, SPR_UPMC4, "UPMC4",
573: &spr_read_ureg, SPR_NOACCESS,
574: &spr_read_ureg, SPR_NOACCESS,
575: 0x00000000);
576: spr_register(env, SPR_USIA, "USIA",
577: &spr_read_ureg, SPR_NOACCESS,
578: &spr_read_ureg, SPR_NOACCESS,
579: 0x00000000);
580: /* Thermal management */
581: /* XXX : not implemented */
582: spr_register(env, SPR_THRM1, "THRM1",
583: SPR_NOACCESS, SPR_NOACCESS,
584: &spr_read_generic, &spr_write_generic,
585: 0x00000000);
586: /* XXX : not implemented */
587: spr_register(env, SPR_THRM2, "THRM2",
588: SPR_NOACCESS, SPR_NOACCESS,
589: &spr_read_generic, &spr_write_generic,
590: 0x00000000);
591: /* XXX : not implemented */
592: spr_register(env, SPR_THRM3, "THRM3",
593: SPR_NOACCESS, SPR_NOACCESS,
594: &spr_read_generic, &spr_write_generic,
595: 0x00000000);
596: /* External access control */
597: /* XXX : not implemented */
598: spr_register(env, SPR_EAR, "EAR",
599: SPR_NOACCESS, SPR_NOACCESS,
600: &spr_read_generic, &spr_write_generic,
601: 0x00000000);
602: }
603:
604: /* SPR specific to PowerPC 604 implementation */
605: static void gen_spr_604 (CPUPPCState *env)
606: {
607: /* Processor identification */
608: spr_register(env, SPR_PIR, "PIR",
609: SPR_NOACCESS, SPR_NOACCESS,
610: &spr_read_generic, &spr_write_pir,
611: 0x00000000);
612: /* Breakpoints */
613: /* XXX : not implemented */
614: spr_register(env, SPR_IABR, "IABR",
615: SPR_NOACCESS, SPR_NOACCESS,
616: &spr_read_generic, &spr_write_generic,
617: 0x00000000);
618: /* XXX : not implemented */
619: spr_register(env, SPR_DABR, "DABR",
620: SPR_NOACCESS, SPR_NOACCESS,
621: &spr_read_generic, &spr_write_generic,
622: 0x00000000);
623: /* Performance counters */
624: /* XXX : not implemented */
625: spr_register(env, SPR_MMCR0, "MMCR0",
626: SPR_NOACCESS, SPR_NOACCESS,
627: &spr_read_generic, &spr_write_generic,
628: 0x00000000);
629: /* XXX : not implemented */
630: spr_register(env, SPR_MMCR1, "MMCR1",
631: SPR_NOACCESS, SPR_NOACCESS,
632: &spr_read_generic, &spr_write_generic,
633: 0x00000000);
634: /* XXX : not implemented */
635: spr_register(env, SPR_PMC1, "PMC1",
636: SPR_NOACCESS, SPR_NOACCESS,
637: &spr_read_generic, &spr_write_generic,
638: 0x00000000);
639: /* XXX : not implemented */
640: spr_register(env, SPR_PMC2, "PMC2",
641: SPR_NOACCESS, SPR_NOACCESS,
642: &spr_read_generic, &spr_write_generic,
643: 0x00000000);
644: /* XXX : not implemented */
645: spr_register(env, SPR_PMC3, "PMC3",
646: SPR_NOACCESS, SPR_NOACCESS,
647: &spr_read_generic, &spr_write_generic,
648: 0x00000000);
649: /* XXX : not implemented */
650: spr_register(env, SPR_PMC4, "PMC4",
651: SPR_NOACCESS, SPR_NOACCESS,
652: &spr_read_generic, &spr_write_generic,
653: 0x00000000);
654: /* XXX : not implemented */
655: spr_register(env, SPR_SIA, "SIA",
656: SPR_NOACCESS, SPR_NOACCESS,
657: &spr_read_generic, SPR_NOACCESS,
658: 0x00000000);
659: /* XXX : not implemented */
660: spr_register(env, SPR_SDA, "SDA",
661: SPR_NOACCESS, SPR_NOACCESS,
662: &spr_read_generic, SPR_NOACCESS,
663: 0x00000000);
664: /* External access control */
665: /* XXX : not implemented */
666: spr_register(env, SPR_EAR, "EAR",
667: SPR_NOACCESS, SPR_NOACCESS,
668: &spr_read_generic, &spr_write_generic,
669: 0x00000000);
670: }
671:
672: // XXX: TODO (64 bits PPC sprs)
673: /*
674: * ASR => SPR 280 (64 bits)
675: * FPECR => SPR 1022 (?)
676: * VRSAVE => SPR 256 (Altivec)
677: * SCOMC => SPR 276 (64 bits ?)
678: * SCOMD => SPR 277 (64 bits ?)
679: * HSPRG0 => SPR 304 (hypervisor)
680: * HSPRG1 => SPR 305 (hypervisor)
681: * HDEC => SPR 310 (hypervisor)
682: * HIOR => SPR 311 (hypervisor)
683: * RMOR => SPR 312 (970)
684: * HRMOR => SPR 313 (hypervisor)
685: * HSRR0 => SPR 314 (hypervisor)
686: * HSRR1 => SPR 315 (hypervisor)
687: * LPCR => SPR 316 (970)
688: * LPIDR => SPR 317 (970)
689: * ... and more (thermal management, performance counters, ...)
690: */
691:
692: static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def)
693: {
694: /* Default MMU definitions */
695: env->nb_BATs = -1;
696: env->nb_tlb = 0;
697: env->nb_ways = 0;
698: /* XXX: missing:
699: * 32 bits PPC:
700: * - MPC5xx(x)
701: * - MPC8xx(x)
702: * - RCPU (MPC5xx)
703: */
704: spr_register(env, SPR_PVR, "PVR",
705: SPR_NOACCESS, SPR_NOACCESS,
706: &spr_read_generic, SPR_NOACCESS,
707: def->pvr);
708: switch (def->pvr & def->pvr_mask) {
709: case CPU_PPC_604: /* PPC 604 */
710: case CPU_PPC_604E: /* PPC 604e */
711: case CPU_PPC_604R: /* PPC 604r */
712: gen_spr_generic(env);
713: gen_spr_ne_601(env);
714: /* Memory management */
715: gen_low_BATs(env);
716: /* Time base */
717: gen_tbl(env);
718: gen_spr_604(env);
719: /* Hardware implementation registers */
720: /* XXX : not implemented */
721: spr_register(env, SPR_HID0, "HID0",
722: SPR_NOACCESS, SPR_NOACCESS,
723: &spr_read_generic, &spr_write_generic,
724: 0x00000000);
725: /* XXX : not implemented */
726: spr_register(env, SPR_HID1, "HID1",
727: SPR_NOACCESS, SPR_NOACCESS,
728: &spr_read_generic, &spr_write_generic,
729: 0x00000000);
730: break;
731:
732: case CPU_PPC_74x: /* PPC 740 / 750 */
733: case CPU_PPC_74xP: /* PPC 740P / 750P */
734: case CPU_PPC_750CXE: /* IBM PPC 750cxe */
735: gen_spr_generic(env);
736: gen_spr_ne_601(env);
737: /* Memory management */
738: gen_low_BATs(env);
739: /* Time base */
740: gen_tbl(env);
741: gen_spr_7xx(env);
742: /* XXX : not implemented */
743: spr_register(env, SPR_L2CR, "L2CR",
744: SPR_NOACCESS, SPR_NOACCESS,
745: &spr_read_generic, &spr_write_generic,
746: 0x00000000);
747: /* Hardware implementation registers */
748: /* XXX : not implemented */
749: spr_register(env, SPR_HID0, "HID0",
750: SPR_NOACCESS, SPR_NOACCESS,
751: &spr_read_generic, &spr_write_generic,
752: 0x00000000);
753: /* XXX : not implemented */
754: spr_register(env, SPR_HID1, "HID1",
755: SPR_NOACCESS, SPR_NOACCESS,
756: &spr_read_generic, &spr_write_generic,
757: 0x00000000);
758: break;
759:
760: case CPU_PPC_750FX: /* IBM PPC 750 FX */
761: case CPU_PPC_750GX: /* IBM PPC 750 GX */
762: gen_spr_generic(env);
763: gen_spr_ne_601(env);
764: /* Memory management */
765: gen_low_BATs(env);
766: /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
767: gen_high_BATs(env);
768: /* Time base */
769: gen_tbl(env);
770: gen_spr_7xx(env);
771: /* XXX : not implemented */
772: spr_register(env, SPR_L2CR, "L2CR",
773: SPR_NOACCESS, SPR_NOACCESS,
774: &spr_read_generic, &spr_write_generic,
775: 0x00000000);
776: /* Hardware implementation registers */
777: /* XXX : not implemented */
778: spr_register(env, SPR_HID0, "HID0",
779: SPR_NOACCESS, SPR_NOACCESS,
780: &spr_read_generic, &spr_write_generic,
781: 0x00000000);
782: /* XXX : not implemented */
783: spr_register(env, SPR_HID1, "HID1",
784: SPR_NOACCESS, SPR_NOACCESS,
785: &spr_read_generic, &spr_write_generic,
786: 0x00000000);
787: /* XXX : not implemented */
788: spr_register(env, SPR_750_HID2, "HID2",
789: SPR_NOACCESS, SPR_NOACCESS,
790: &spr_read_generic, &spr_write_generic,
791: 0x00000000);
792: break;
793:
794: default:
795: gen_spr_generic(env);
796: break;
797: }
798: if (env->nb_BATs == -1)
799: env->nb_BATs = 4;
800: }
801:
802: #if defined(PPC_DUMP_CPU)
803: static void dump_sprs (CPUPPCState *env)
804: {
805: ppc_spr_t *spr;
806: uint32_t pvr = env->spr[SPR_PVR];
807: uint32_t sr, sw, ur, uw;
808: int i, j, n;
809:
810: printf("* SPRs for PVR=%08x\n", pvr);
811: for (i = 0; i < 32; i++) {
812: for (j = 0; j < 32; j++) {
813: n = (i << 5) | j;
814: spr = &env->spr_cb[n];
815: sw = spr->oea_write != NULL && spr->oea_write != SPR_NOACCESS;
816: sr = spr->oea_read != NULL && spr->oea_read != SPR_NOACCESS;
817: uw = spr->uea_write != NULL && spr->uea_write != SPR_NOACCESS;
818: ur = spr->uea_read != NULL && spr->uea_read != SPR_NOACCESS;
819: if (sw || sr || uw || ur) {
820: printf("%4d (%03x) %8s s%c%c u%c%c\n",
821: (i << 5) | j, (i << 5) | j, spr->name,
822: sw ? 'w' : '-', sr ? 'r' : '-',
823: uw ? 'w' : '-', ur ? 'r' : '-');
824: }
825: }
826: }
827: fflush(stdout);
828: fflush(stderr);
829: }
830: #endif
831:
832: /*****************************************************************************/
833: #include <stdlib.h>
834: #include <string.h>
835:
836: int fflush (FILE *stream);
837:
838: /* Opcode types */
839: enum {
840: PPC_DIRECT = 0, /* Opcode routine */
841: PPC_INDIRECT = 1, /* Indirect opcode table */
842: };
843:
844: static inline int is_indirect_opcode (void *handler)
845: {
846: return ((unsigned long)handler & 0x03) == PPC_INDIRECT;
847: }
848:
849: static inline opc_handler_t **ind_table(void *handler)
850: {
851: return (opc_handler_t **)((unsigned long)handler & ~3);
852: }
853:
854: /* Instruction table creation */
855: /* Opcodes tables creation */
856: static void fill_new_table (opc_handler_t **table, int len)
857: {
858: int i;
859:
860: for (i = 0; i < len; i++)
861: table[i] = &invalid_handler;
862: }
863:
864: static int create_new_table (opc_handler_t **table, unsigned char idx)
865: {
866: opc_handler_t **tmp;
867:
868: tmp = malloc(0x20 * sizeof(opc_handler_t));
869: if (tmp == NULL)
870: return -1;
871: fill_new_table(tmp, 0x20);
872: table[idx] = (opc_handler_t *)((unsigned long)tmp | PPC_INDIRECT);
873:
874: return 0;
875: }
876:
877: static int insert_in_table (opc_handler_t **table, unsigned char idx,
878: opc_handler_t *handler)
879: {
880: if (table[idx] != &invalid_handler)
881: return -1;
882: table[idx] = handler;
883:
884: return 0;
885: }
886:
887: static int register_direct_insn (opc_handler_t **ppc_opcodes,
888: unsigned char idx, opc_handler_t *handler)
889: {
890: if (insert_in_table(ppc_opcodes, idx, handler) < 0) {
891: printf("*** ERROR: opcode %02x already assigned in main "
892: "opcode table\n", idx);
893: return -1;
894: }
895:
896: return 0;
897: }
898:
899: static int register_ind_in_table (opc_handler_t **table,
900: unsigned char idx1, unsigned char idx2,
901: opc_handler_t *handler)
902: {
903: if (table[idx1] == &invalid_handler) {
904: if (create_new_table(table, idx1) < 0) {
905: printf("*** ERROR: unable to create indirect table "
906: "idx=%02x\n", idx1);
907: return -1;
908: }
909: } else {
910: if (!is_indirect_opcode(table[idx1])) {
911: printf("*** ERROR: idx %02x already assigned to a direct "
912: "opcode\n", idx1);
913: return -1;
914: }
915: }
916: if (handler != NULL &&
917: insert_in_table(ind_table(table[idx1]), idx2, handler) < 0) {
918: printf("*** ERROR: opcode %02x already assigned in "
919: "opcode table %02x\n", idx2, idx1);
920: return -1;
921: }
922:
923: return 0;
924: }
925:
926: static int register_ind_insn (opc_handler_t **ppc_opcodes,
927: unsigned char idx1, unsigned char idx2,
928: opc_handler_t *handler)
929: {
930: int ret;
931:
932: ret = register_ind_in_table(ppc_opcodes, idx1, idx2, handler);
933:
934: return ret;
935: }
936:
937: static int register_dblind_insn (opc_handler_t **ppc_opcodes,
938: unsigned char idx1, unsigned char idx2,
939: unsigned char idx3, opc_handler_t *handler)
940: {
941: if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) {
942: printf("*** ERROR: unable to join indirect table idx "
943: "[%02x-%02x]\n", idx1, idx2);
944: return -1;
945: }
946: if (register_ind_in_table(ind_table(ppc_opcodes[idx1]), idx2, idx3,
947: handler) < 0) {
948: printf("*** ERROR: unable to insert opcode "
949: "[%02x-%02x-%02x]\n", idx1, idx2, idx3);
950: return -1;
951: }
952:
953: return 0;
954: }
955:
956: static int register_insn (opc_handler_t **ppc_opcodes, opcode_t *insn)
957: {
958: if (insn->opc2 != 0xFF) {
959: if (insn->opc3 != 0xFF) {
960: if (register_dblind_insn(ppc_opcodes, insn->opc1, insn->opc2,
961: insn->opc3, &insn->handler) < 0)
962: return -1;
963: } else {
964: if (register_ind_insn(ppc_opcodes, insn->opc1,
965: insn->opc2, &insn->handler) < 0)
966: return -1;
967: }
968: } else {
969: if (register_direct_insn(ppc_opcodes, insn->opc1, &insn->handler) < 0)
970: return -1;
971: }
972:
973: return 0;
974: }
975:
976: static int test_opcode_table (opc_handler_t **table, int len)
977: {
978: int i, count, tmp;
979:
980: for (i = 0, count = 0; i < len; i++) {
981: /* Consistency fixup */
982: if (table[i] == NULL)
983: table[i] = &invalid_handler;
984: if (table[i] != &invalid_handler) {
985: if (is_indirect_opcode(table[i])) {
986: tmp = test_opcode_table(ind_table(table[i]), 0x20);
987: if (tmp == 0) {
988: free(table[i]);
989: table[i] = &invalid_handler;
990: } else {
991: count++;
992: }
993: } else {
994: count++;
995: }
996: }
997: }
998:
999: return count;
1000: }
1001:
1002: static void fix_opcode_tables (opc_handler_t **ppc_opcodes)
1003: {
1004: if (test_opcode_table(ppc_opcodes, 0x40) == 0)
1005: printf("*** WARNING: no opcode defined !\n");
1006: }
1007:
1008: /*****************************************************************************/
1009: static int create_ppc_opcodes (CPUPPCState *env, ppc_def_t *def)
1010: {
1011: opcode_t *opc, *start, *end;
1012:
1013: fill_new_table(env->opcodes, 0x40);
1014: #if defined(PPC_DUMP_CPU)
1015: printf("* PPC instructions for PVR %08x: %s\n", def->pvr, def->name);
1016: #endif
1017: if (&opc_start < &opc_end) {
1018: start = &opc_start;
1019: end = &opc_end;
1020: } else {
1021: start = &opc_end;
1022: end = &opc_start;
1023: }
1024: for (opc = start + 1; opc != end; opc++) {
1025: if ((opc->handler.type & def->insns_flags) != 0) {
1026: if (register_insn(env->opcodes, opc) < 0) {
1027: printf("*** ERROR initializing PPC instruction "
1028: "0x%02x 0x%02x 0x%02x\n", opc->opc1, opc->opc2,
1029: opc->opc3);
1030: return -1;
1031: }
1032: #if defined(PPC_DUMP_CPU)
1033: if (opc1 != 0x00) {
1034: if (opc->opc3 == 0xFF) {
1035: if (opc->opc2 == 0xFF) {
1036: printf(" %02x -- -- (%2d ----) : %s\n",
1037: opc->opc1, opc->opc1, opc->oname);
1038: } else {
1039: printf(" %02x %02x -- (%2d %4d) : %s\n",
1040: opc->opc1, opc->opc2, opc->opc1, opc->opc2,
1041: opc->oname);
1042: }
1043: } else {
1044: printf(" %02x %02x %02x (%2d %4d) : %s\n",
1045: opc->opc1, opc->opc2, opc->opc3,
1046: opc->opc1, (opc->opc3 << 5) | opc->opc2,
1047: opc->oname);
1048: }
1049: }
1050: #endif
1051: }
1052: }
1053: fix_opcode_tables(env->opcodes);
1054: fflush(stdout);
1055: fflush(stderr);
1056:
1057: return 0;
1058: }
1059:
1060: int cpu_ppc_register (CPUPPCState *env, ppc_def_t *def)
1061: {
1062: env->msr_mask = def->msr_mask;
1063: env->flags = def->flags;
1064: if (create_ppc_opcodes(env, def) < 0) {
1065: printf("Error creating opcodes table\n");
1066: fflush(stdout);
1067: fflush(stderr);
1068: return -1;
1069: }
1070: init_ppc_proc(env, def);
1071: #if defined(PPC_DUMP_CPU)
1072: dump_sprs(env);
1073: #endif
1074: fflush(stdout);
1075: fflush(stderr);
1076:
1077: return 0;
1078: }
1079:
1080: CPUPPCState *cpu_ppc_init(void)
1081: {
1082: CPUPPCState *env;
1083:
1084: env = qemu_mallocz(sizeof(CPUPPCState));
1085: if (!env)
1086: return NULL;
1.1.1.2 ! root 1087: cpu_exec_init(env);
1.1 root 1088: tlb_flush(env, 1);
1089: #if defined (DO_SINGLE_STEP) && 0
1090: /* Single step trace mode */
1091: msr_se = 1;
1092: msr_be = 1;
1093: #endif
1094: msr_fp = 1; /* Allow floating point exceptions */
1095: msr_me = 1; /* Allow machine check exceptions */
1096: #if defined(CONFIG_USER_ONLY)
1097: msr_pr = 1;
1098: #else
1099: env->nip = 0xFFFFFFFC;
1100: #endif
1101: do_compute_hflags(env);
1102: env->reserve = -1;
1103: return env;
1104: }
1105:
1106: void cpu_ppc_close(CPUPPCState *env)
1107: {
1108: /* Should also remove all opcode tables... */
1109: free(env);
1110: }
1111:
1112: /*****************************************************************************/
1113: /* PowerPC CPU definitions */
1114: static ppc_def_t ppc_defs[] =
1115: {
1116: /* Embedded PPC */
1117: #if defined (TODO)
1118: /* PPC 401 */
1119: {
1120: .name = "401",
1121: .pvr = CPU_PPC_401,
1122: .pvr_mask = 0xFFFF0000,
1123: .insns_flags = PPC_INSNS_401,
1124: .flags = PPC_FLAGS_401,
1125: .msr_mask = xxx,
1126: },
1127: #endif
1128: #if defined (TODO)
1129: /* IOP480 (401 microcontroler) */
1130: {
1131: .name = "iop480",
1132: .pvr = CPU_PPC_IOP480,
1133: .pvr_mask = 0xFFFF0000,
1134: .insns_flags = PPC_INSNS_401,
1135: .flags = PPC_FLAGS_401,
1136: .msr_mask = xxx,
1137: },
1138: #endif
1139: #if defined (TODO)
1140: /* PPC 403 GA */
1141: {
1142: .name = "403ga",
1143: .pvr = CPU_PPC_403GA,
1144: .pvr_mask = 0xFFFFFF00,
1145: .insns_flags = PPC_INSNS_403,
1146: .flags = PPC_FLAGS_403,
1147: .msr_mask = 0x000000000007D23D,
1148: },
1149: #endif
1150: #if defined (TODO)
1151: /* PPC 403 GB */
1152: {
1153: .name = "403gb",
1154: .pvr = CPU_PPC_403GB,
1155: .pvr_mask = 0xFFFFFF00,
1156: .insns_flags = PPC_INSNS_403,
1157: .flags = PPC_FLAGS_403,
1158: .msr_mask = 0x000000000007D23D,
1159: },
1160: #endif
1161: #if defined (TODO)
1162: /* PPC 403 GC */
1163: {
1164: .name = "403gc",
1165: .pvr = CPU_PPC_403GC,
1166: .pvr_mask = 0xFFFFFF00,
1167: .insns_flags = PPC_INSNS_403,
1168: .flags = PPC_FLAGS_403,
1169: .msr_mask = 0x000000000007D23D,
1170: },
1171: #endif
1172: #if defined (TODO)
1173: /* PPC 403 GCX */
1174: {
1175: .name = "403gcx",
1176: .pvr = CPU_PPC_403GCX,
1177: .pvr_mask = 0xFFFFFF00,
1178: .insns_flags = PPC_INSNS_403,
1179: .flags = PPC_FLAGS_403,
1180: .msr_mask = 0x000000000007D23D,
1181: },
1182: #endif
1183: #if defined (TODO)
1184: /* PPC 405 CR */
1185: {
1186: .name = "405cr",
1187: .pvr = CPU_PPC_405,
1188: .pvr_mask = 0xFFFF0000,
1189: .insns_flags = PPC_INSNS_405,
1190: .flags = PPC_FLAGS_405,
1191: .msr_mask = 0x00000000020EFF30,
1192: },
1193: #endif
1194: #if defined (TODO)
1195: /* PPC 405 GP */
1196: {
1197: .name = "405gp",
1198: .pvr = CPU_PPC_405,
1199: .pvr_mask = 0xFFFF0000,
1200: .insns_flags = PPC_INSNS_405,
1201: .flags = PPC_FLAGS_405,
1202: .msr_mask = 0x00000000020EFF30,
1203: },
1204: #endif
1205: #if defined (TODO)
1206: /* PPC 405 EP */
1207: {
1208: .name = "405ep",
1209: .pvr = CPU_PPC_405EP,
1210: .pvr_mask = 0xFFFF0000,
1211: .insns_flags = PPC_INSNS_405,
1212: .flags = PPC_FLAGS_405,
1213: .msr_mask = 0x00000000020EFF30,
1214: },
1215: #endif
1216: #if defined (TODO)
1217: /* PPC 405 GPR */
1218: {
1219: .name = "405gpr",
1220: .pvr = CPU_PPC_405GPR,
1221: .pvr_mask = 0xFFFF0000,
1222: .insns_flags = PPC_INSNS_405,
1223: .flags = PPC_FLAGS_405,
1224: .msr_mask = 0x00000000020EFF30,
1225: },
1226: #endif
1227: #if defined (TODO)
1228: /* PPC 405 D2 */
1229: {
1230: .name = "405d2",
1231: .pvr = CPU_PPC_405D2,
1232: .pvr_mask = 0xFFFF0000,
1233: .insns_flags = PPC_INSNS_405,
1234: .flags = PPC_FLAGS_405,
1235: .msr_mask = 0x00000000020EFF30,
1236: },
1237: #endif
1238: #if defined (TODO)
1239: /* PPC 405 D4 */
1240: {
1241: .name = "405d4",
1242: .pvr = CPU_PPC_405D4,
1243: .pvr_mask = 0xFFFF0000,
1244: .insns_flags = PPC_INSNS_405,
1245: .flags = PPC_FLAGS_405,
1246: .msr_mask = 0x00000000020EFF30,
1247: },
1248: #endif
1249: #if defined (TODO)
1250: /* Npe405 H */
1251: {
1252: .name = "Npe405H",
1253: .pvr = CPU_PPC_NPE405H,
1254: .pvr_mask = 0xFFFF0000,
1255: .insns_flags = PPC_INSNS_405,
1256: .flags = PPC_FLAGS_405,
1257: .msr_mask = 0x00000000020EFF30,
1258: },
1259: #endif
1260: #if defined (TODO)
1261: /* Npe405 L */
1262: {
1263: .name = "Npe405L",
1264: .pvr = CPU_PPC_NPE405L,
1265: .pvr_mask = 0xFFFF0000,
1266: .insns_flags = PPC_INSNS_405,
1267: .flags = PPC_FLAGS_405,
1268: .msr_mask = 0x00000000020EFF30,
1269: },
1270: #endif
1271: #if defined (TODO)
1272: /* STB03xx */
1273: {
1274: .name = "STB03",
1275: .pvr = CPU_PPC_STB03,
1276: .pvr_mask = 0xFFFF0000,
1277: .insns_flags = PPC_INSNS_405,
1278: .flags = PPC_FLAGS_405,
1279: .msr_mask = 0x00000000020EFF30,
1280: },
1281: #endif
1282: #if defined (TODO)
1283: /* STB04xx */
1284: {
1285: .name = "STB04",
1286: .pvr = CPU_PPC_STB04,
1287: .pvr_mask = 0xFFFF0000,
1288: .insns_flags = PPC_INSNS_405,
1289: .flags = PPC_FLAGS_405,
1290: .msr_mask = 0x00000000020EFF30,
1291: },
1292: #endif
1293: #if defined (TODO)
1294: /* STB25xx */
1295: {
1296: .name = "STB25",
1297: .pvr = CPU_PPC_STB25,
1298: .pvr_mask = 0xFFFF0000,
1299: .insns_flags = PPC_INSNS_405,
1300: .flags = PPC_FLAGS_405,
1301: .msr_mask = 0x00000000020EFF30,
1302: },
1303: #endif
1304: #if defined (TODO)
1305: /* PPC 440 EP */
1306: {
1307: .name = "440ep",
1308: .pvr = CPU_PPC_440EP,
1309: .pvr_mask = 0xFFFF0000,
1310: .insns_flags = PPC_INSNS_440,
1311: .flags = PPC_FLAGS_440,
1312: .msr_mask = 0x000000000006D630,
1313: },
1314: #endif
1315: #if defined (TODO)
1316: /* PPC 440 GP */
1317: {
1318: .name = "440gp",
1319: .pvr = CPU_PPC_440GP,
1320: .pvr_mask = 0xFFFFFF00,
1321: .insns_flags = PPC_INSNS_440,
1322: .flags = PPC_FLAGS_440,
1323: .msr_mask = 0x000000000006D630,
1324: },
1325: #endif
1326: #if defined (TODO)
1327: /* PPC 440 GX */
1328: {
1329: .name = "440gx",
1330: .pvr = CPU_PPC_440GX,
1331: .pvr_mask = 0xFFFF0000,
1332: .insns_flags = PPC_INSNS_405,
1333: .flags = PPC_FLAGS_440,
1334: .msr_mask = 0x000000000006D630,
1335: },
1336: #endif
1337:
1338: /* 32 bits "classic" powerpc */
1339: #if defined (TODO)
1340: /* PPC 601 */
1341: {
1342: .name = "601",
1343: .pvr = CPU_PPC_601,
1344: .pvr_mask = 0xFFFF0000,
1345: .insns_flags = PPC_INSNS_601,
1346: .flags = PPC_FLAGS_601,
1347: .msr_mask = 0x000000000000FD70,
1348: },
1349: #endif
1350: #if defined (TODO)
1351: /* PPC 602 */
1352: {
1353: .name = "602",
1354: .pvr = CPU_PPC_602,
1355: .pvr_mask = 0xFFFF0000,
1356: .insns_flags = PPC_INSNS_602,
1357: .flags = PPC_FLAGS_602,
1358: .msr_mask = 0x0000000000C7FF73,
1359: },
1360: #endif
1361: #if defined (TODO)
1362: /* PPC 603 */
1363: {
1364: .name = "603",
1365: .pvr = CPU_PPC_603,
1366: .pvr_mask = 0xFFFF0000,
1367: .insns_flags = PPC_INSNS_603,
1368: .flags = PPC_FLAGS_603,
1369: .msr_mask = 0x000000000007FF73,
1370: },
1371: #endif
1372: #if defined (TODO)
1373: /* PPC 603e */
1374: {
1375: .name = "603e",
1376: .pvr = CPU_PPC_603E,
1377: .pvr_mask = 0xFFFF0000,
1378: .insns_flags = PPC_INSNS_603,
1379: .flags = PPC_FLAGS_603,
1380: .msr_mask = 0x000000000007FF73,
1381: },
1382: {
1383: .name = "Stretch",
1384: .pvr = CPU_PPC_603E,
1385: .pvr_mask = 0xFFFF0000,
1386: .insns_flags = PPC_INSNS_603,
1387: .flags = PPC_FLAGS_603,
1388: .msr_mask = 0x000000000007FF73,
1389: },
1390: #endif
1391: #if defined (TODO)
1392: /* PPC 603ev */
1393: {
1394: .name = "603ev",
1395: .pvr = CPU_PPC_603EV,
1396: .pvr_mask = 0xFFFFF000,
1397: .insns_flags = PPC_INSNS_603,
1398: .flags = PPC_FLAGS_603,
1399: .msr_mask = 0x000000000007FF73,
1400: },
1401: #endif
1402: #if defined (TODO)
1403: /* PPC 603r */
1404: {
1405: .name = "603r",
1406: .pvr = CPU_PPC_603R,
1407: .pvr_mask = 0xFFFFF000,
1408: .insns_flags = PPC_INSNS_603,
1409: .flags = PPC_FLAGS_603,
1410: .msr_mask = 0x000000000007FF73,
1411: },
1412: {
1413: .name = "Goldeneye",
1414: .pvr = CPU_PPC_603R,
1415: .pvr_mask = 0xFFFFF000,
1416: .insns_flags = PPC_INSNS_603,
1417: .flags = PPC_FLAGS_603,
1418: .msr_mask = 0x000000000007FF73,
1419: },
1420: #endif
1421: #if defined (TODO)
1422: /* XXX: TODO: according to Motorola UM, this is a derivative to 603e */
1423: {
1424: .name = "G2",
1425: .pvr = CPU_PPC_G2,
1426: .pvr_mask = 0xFFFF0000,
1427: .insns_flags = PPC_INSNS_G2,
1428: .flags = PPC_FLAGS_G2,
1429: .msr_mask = 0x000000000006FFF2,
1430: },
1431: { /* Same as G2, with LE mode support */
1432: .name = "G2le",
1433: .pvr = CPU_PPC_G2LE,
1434: .pvr_mask = 0xFFFF0000,
1435: .insns_flags = PPC_INSNS_G2,
1436: .flags = PPC_FLAGS_G2,
1437: .msr_mask = 0x000000000007FFF3,
1438: },
1439: #endif
1440: /* PPC 604 */
1441: {
1442: .name = "604",
1443: .pvr = CPU_PPC_604,
1444: .pvr_mask = 0xFFFF0000,
1445: .insns_flags = PPC_INSNS_604,
1446: .flags = PPC_FLAGS_604,
1447: .msr_mask = 0x000000000005FF77,
1448: },
1449: /* PPC 604e */
1450: {
1451: .name = "604e",
1452: .pvr = CPU_PPC_604E,
1453: .pvr_mask = 0xFFFF0000,
1454: .insns_flags = PPC_INSNS_604,
1455: .flags = PPC_FLAGS_604,
1456: .msr_mask = 0x000000000005FF77,
1457: },
1458: /* PPC 604r */
1459: {
1460: .name = "604r",
1461: .pvr = CPU_PPC_604R,
1462: .pvr_mask = 0xFFFF0000,
1463: .insns_flags = PPC_INSNS_604,
1464: .flags = PPC_FLAGS_604,
1465: .msr_mask = 0x000000000005FF77,
1466: },
1467: /* generic G3 */
1468: {
1469: .name = "G3",
1470: .pvr = CPU_PPC_74x,
1471: .pvr_mask = 0xFFFFF000,
1472: .insns_flags = PPC_INSNS_7x0,
1473: .flags = PPC_FLAGS_7x0,
1474: .msr_mask = 0x000000000007FF77,
1475: },
1476: #if defined (TODO)
1477: /* MPC740 (G3) */
1478: {
1479: .name = "740",
1480: .pvr = CPU_PPC_74x,
1481: .pvr_mask = 0xFFFFF000,
1482: .insns_flags = PPC_INSNS_7x0,
1483: .flags = PPC_FLAGS_7x0,
1484: .msr_mask = 0x000000000007FF77,
1485: },
1486: {
1487: .name = "Arthur",
1488: .pvr = CPU_PPC_74x,
1489: .pvr_mask = 0xFFFFF000,
1490: .insns_flags = PPC_INSNS_7x0,
1491: .flags = PPC_FLAGS_7x0,
1492: .msr_mask = 0x000000000007FF77,
1493: },
1494: #endif
1495: #if defined (TODO)
1496: /* MPC745 (G3) */
1497: {
1498: .name = "745",
1499: .pvr = CPU_PPC_74x,
1500: .pvr_mask = 0xFFFFF000,
1501: .insns_flags = PPC_INSNS_7x5,
1502: .flags = PPC_FLAGS_7x5,
1503: .msr_mask = 0x000000000007FF77,
1504: },
1505: {
1506: .name = "Goldfinger",
1507: .pvr = CPU_PPC_74x,
1508: .pvr_mask = 0xFFFFF000,
1509: .insns_flags = PPC_INSNS_7x5,
1510: .flags = PPC_FLAGS_7x5,
1511: .msr_mask = 0x000000000007FF77,
1512: },
1513: #endif
1514: /* MPC750 (G3) */
1515: {
1516: .name = "750",
1517: .pvr = CPU_PPC_74x,
1518: .pvr_mask = 0xFFFFF000,
1519: .insns_flags = PPC_INSNS_7x0,
1520: .flags = PPC_FLAGS_7x0,
1521: .msr_mask = 0x000000000007FF77,
1522: },
1523: #if defined (TODO)
1524: /* MPC755 (G3) */
1525: {
1526: .name = "755",
1527: .pvr = CPU_PPC_755,
1528: .pvr_mask = 0xFFFFF000,
1529: .insns_flags = PPC_INSNS_7x5,
1530: .flags = PPC_FLAGS_7x5,
1531: .msr_mask = 0x000000000007FF77,
1532: },
1533: #endif
1534: #if defined (TODO)
1535: /* MPC740P (G3) */
1536: {
1537: .name = "740p",
1538: .pvr = CPU_PPC_74xP,
1539: .pvr_mask = 0xFFFFF000,
1540: .insns_flags = PPC_INSNS_7x0,
1541: .flags = PPC_FLAGS_7x0,
1542: .msr_mask = 0x000000000007FF77,
1543: },
1544: {
1545: .name = "Conan/Doyle",
1546: .pvr = CPU_PPC_74xP,
1547: .pvr_mask = 0xFFFFF000,
1548: .insns_flags = PPC_INSNS_7x0,
1549: .flags = PPC_FLAGS_7x0,
1550: .msr_mask = 0x000000000007FF77,
1551: },
1552: #endif
1553: #if defined (TODO)
1554: /* MPC745P (G3) */
1555: {
1556: .name = "745p",
1557: .pvr = CPU_PPC_74xP,
1558: .pvr_mask = 0xFFFFF000,
1559: .insns_flags = PPC_INSNS_7x5,
1560: .flags = PPC_FLAGS_7x5,
1561: .msr_mask = 0x000000000007FF77,
1562: },
1563: #endif
1564: /* MPC750P (G3) */
1565: {
1566: .name = "750p",
1567: .pvr = CPU_PPC_74xP,
1568: .pvr_mask = 0xFFFFF000,
1569: .insns_flags = PPC_INSNS_7x0,
1570: .flags = PPC_FLAGS_7x0,
1571: .msr_mask = 0x000000000007FF77,
1572: },
1573: #if defined (TODO)
1574: /* MPC755P (G3) */
1575: {
1576: .name = "755p",
1577: .pvr = CPU_PPC_74xP,
1578: .pvr_mask = 0xFFFFF000,
1579: .insns_flags = PPC_INSNS_7x5,
1580: .flags = PPC_FLAGS_7x5,
1581: .msr_mask = 0x000000000007FF77,
1582: },
1583: #endif
1584: /* IBM 750CXe (G3 embedded) */
1585: {
1586: .name = "750cxe",
1587: .pvr = CPU_PPC_750CXE,
1588: .pvr_mask = 0xFFFFF000,
1589: .insns_flags = PPC_INSNS_7x0,
1590: .flags = PPC_FLAGS_7x0,
1591: .msr_mask = 0x000000000007FF77,
1592: },
1593: /* IBM 750FX (G3 embedded) */
1594: {
1595: .name = "750fx",
1596: .pvr = CPU_PPC_750FX,
1597: .pvr_mask = 0xFFFF0000,
1598: .insns_flags = PPC_INSNS_7x0,
1599: .flags = PPC_FLAGS_7x0,
1600: .msr_mask = 0x000000000007FF77,
1601: },
1602: /* IBM 750GX (G3 embedded) */
1603: {
1604: .name = "750gx",
1605: .pvr = CPU_PPC_750GX,
1606: .pvr_mask = 0xFFFF0000,
1607: .insns_flags = PPC_INSNS_7x0,
1608: .flags = PPC_FLAGS_7x0,
1609: .msr_mask = 0x000000000007FF77,
1610: },
1611: #if defined (TODO)
1612: /* generic G4 */
1613: {
1614: .name = "G4",
1615: .pvr = CPU_PPC_7400,
1616: .pvr_mask = 0xFFFF0000,
1617: .insns_flags = PPC_INSNS_74xx,
1618: .flags = PPC_FLAGS_74xx,
1619: .msr_mask = 0x000000000205FF77,
1620: },
1621: #endif
1622: #if defined (TODO)
1623: /* PPC 7400 (G4) */
1624: {
1625: .name = "7400",
1626: .pvr = CPU_PPC_7400,
1627: .pvr_mask = 0xFFFF0000,
1628: .insns_flags = PPC_INSNS_74xx,
1629: .flags = PPC_FLAGS_74xx,
1630: .msr_mask = 0x000000000205FF77,
1631: },
1632: {
1633: .name = "Max",
1634: .pvr = CPU_PPC_7400,
1635: .pvr_mask = 0xFFFF0000,
1636: .insns_flags = PPC_INSNS_74xx,
1637: .flags = PPC_FLAGS_74xx,
1638: .msr_mask = 0x000000000205FF77,
1639: },
1640: #endif
1641: #if defined (TODO)
1642: /* PPC 7410 (G4) */
1643: {
1644: .name = "7410",
1645: .pvr = CPU_PPC_7410,
1646: .pvr_mask = 0xFFFF0000,
1647: .insns_flags = PPC_INSNS_74xx,
1648: .flags = PPC_FLAGS_74xx,
1649: .msr_mask = 0x000000000205FF77,
1650: },
1651: {
1652: .name = "Nitro",
1653: .pvr = CPU_PPC_7410,
1654: .pvr_mask = 0xFFFF0000,
1655: .insns_flags = PPC_INSNS_74xx,
1656: .flags = PPC_FLAGS_74xx,
1657: .msr_mask = 0x000000000205FF77,
1658: },
1659: #endif
1660: /* XXX: 7441 */
1661: /* XXX: 7445 */
1662: /* XXX: 7447 */
1663: /* XXX: 7447A */
1664: #if defined (TODO)
1665: /* PPC 7450 (G4) */
1666: {
1667: .name = "7450",
1668: .pvr = CPU_PPC_7450,
1669: .pvr_mask = 0xFFFF0000,
1670: .insns_flags = PPC_INSNS_74xx,
1671: .flags = PPC_FLAGS_74xx,
1672: .msr_mask = 0x000000000205FF77,
1673: },
1674: {
1675: .name = "Vger",
1676: .pvr = CPU_PPC_7450,
1677: .pvr_mask = 0xFFFF0000,
1678: .insns_flags = PPC_INSNS_74xx,
1679: .flags = PPC_FLAGS_74xx,
1680: .msr_mask = 0x000000000205FF77,
1681: },
1682: #endif
1683: /* XXX: 7451 */
1684: #if defined (TODO)
1685: /* PPC 7455 (G4) */
1686: {
1687: .name = "7455",
1688: .pvr = CPU_PPC_7455,
1689: .pvr_mask = 0xFFFF0000,
1690: .insns_flags = PPC_INSNS_74xx,
1691: .flags = PPC_FLAGS_74xx,
1692: .msr_mask = 0x000000000205FF77,
1693: },
1694: {
1695: .name = "Apollo 6",
1696: .pvr = CPU_PPC_7455,
1697: .pvr_mask = 0xFFFF0000,
1698: .insns_flags = PPC_INSNS_74xx,
1699: .flags = PPC_FLAGS_74xx,
1700: .msr_mask = 0x000000000205FF77,
1701: },
1702: #endif
1703: #if defined (TODO)
1704: /* PPC 7457 (G4) */
1705: {
1706: .name = "7457",
1707: .pvr = CPU_PPC_7457,
1708: .pvr_mask = 0xFFFF0000,
1709: .insns_flags = PPC_INSNS_74xx,
1710: .flags = PPC_FLAGS_74xx,
1711: .msr_mask = 0x000000000205FF77,
1712: },
1713: {
1714: .name = "Apollo 7",
1715: .pvr = CPU_PPC_7457,
1716: .pvr_mask = 0xFFFF0000,
1717: .insns_flags = PPC_INSNS_74xx,
1718: .flags = PPC_FLAGS_74xx,
1719: .msr_mask = 0x000000000205FF77,
1720: },
1721: #endif
1722: #if defined (TODO)
1723: /* PPC 7457A (G4) */
1724: {
1725: .name = "7457A",
1726: .pvr = CPU_PPC_7457A,
1727: .pvr_mask = 0xFFFF0000,
1728: .insns_flags = PPC_INSNS_74xx,
1729: .flags = PPC_FLAGS_74xx,
1730: .msr_mask = 0x000000000205FF77,
1731: },
1732: {
1733: .name = "Apollo 7 PM",
1734: .pvr = CPU_PPC_7457A,
1735: .pvr_mask = 0xFFFF0000,
1736: .insns_flags = PPC_INSNS_74xx,
1737: .flags = PPC_FLAGS_74xx,
1738: .msr_mask = 0x000000000205FF77,
1739: },
1740: #endif
1741: /* 64 bits PPC */
1742: #if defined (TODO)
1743: /* PPC 620 */
1744: {
1745: .name = "620",
1746: .pvr = CPU_PPC_620,
1747: .pvr_mask = 0xFFFF0000,
1748: .insns_flags = PPC_INSNS_620,
1749: .flags = PPC_FLAGS_620,
1750: .msr_mask = 0x800000000005FF73,
1751: },
1752: #endif
1753: #if defined (TODO)
1754: /* PPC 630 (POWER3) */
1755: {
1756: .name = "630",
1757: .pvr = CPU_PPC_630,
1758: .pvr_mask = 0xFFFF0000,
1759: .insns_flags = PPC_INSNS_630,
1760: .flags = PPC_FLAGS_630,
1761: .msr_mask = xxx,
1762: }
1763: {
1764: .name = "POWER3",
1765: .pvr = CPU_PPC_630,
1766: .pvr_mask = 0xFFFF0000,
1767: .insns_flags = PPC_INSNS_630,
1768: .flags = PPC_FLAGS_630,
1769: .msr_mask = xxx,
1770: }
1771: #endif
1772: #if defined (TODO)
1773: /* PPC 631 (Power 3+)*/
1774: {
1775: .name = "631",
1776: .pvr = CPU_PPC_631,
1777: .pvr_mask = 0xFFFF0000,
1778: .insns_flags = PPC_INSNS_631,
1779: .flags = PPC_FLAGS_631,
1780: .msr_mask = xxx,
1781: },
1782: {
1783: .name = "POWER3+",
1784: .pvr = CPU_PPC_631,
1785: .pvr_mask = 0xFFFF0000,
1786: .insns_flags = PPC_INSNS_631,
1787: .flags = PPC_FLAGS_631,
1788: .msr_mask = xxx,
1789: },
1790: #endif
1791: #if defined (TODO)
1792: /* POWER4 */
1793: {
1794: .name = "POWER4",
1795: .pvr = CPU_PPC_POWER4,
1796: .pvr_mask = 0xFFFF0000,
1797: .insns_flags = PPC_INSNS_POWER4,
1798: .flags = PPC_FLAGS_POWER4,
1799: .msr_mask = xxx,
1800: },
1801: #endif
1802: #if defined (TODO)
1803: /* POWER4p */
1804: {
1805: .name = "POWER4+",
1806: .pvr = CPU_PPC_POWER4P,
1807: .pvr_mask = 0xFFFF0000,
1808: .insns_flags = PPC_INSNS_POWER4,
1809: .flags = PPC_FLAGS_POWER4,
1810: .msr_mask = xxx,
1811: },
1812: #endif
1813: #if defined (TODO)
1814: /* POWER5 */
1815: {
1816: .name = "POWER5",
1817: .pvr = CPU_PPC_POWER5,
1818: .pvr_mask = 0xFFFF0000,
1819: .insns_flags = PPC_INSNS_POWER5,
1820: .flags = PPC_FLAGS_POWER5,
1821: .msr_mask = xxx,
1822: },
1823: #endif
1824: #if defined (TODO)
1825: /* POWER5+ */
1826: {
1827: .name = "POWER5+",
1828: .pvr = CPU_PPC_POWER5P,
1829: .pvr_mask = 0xFFFF0000,
1830: .insns_flags = PPC_INSNS_POWER5,
1831: .flags = PPC_FLAGS_POWER5,
1832: .msr_mask = xxx,
1833: },
1834: #endif
1835: #if defined (TODO)
1836: /* PPC 970 */
1837: {
1838: .name = "970",
1839: .pvr = CPU_PPC_970,
1840: .pvr_mask = 0xFFFF0000,
1841: .insns_flags = PPC_INSNS_970,
1842: .flags = PPC_FLAGS_970,
1843: .msr_mask = 0x900000000204FF36,
1844: },
1845: #endif
1846: #if defined (TODO)
1847: /* PPC 970FX (G5) */
1848: {
1849: .name = "970fx",
1850: .pvr = CPU_PPC_970FX,
1851: .pvr_mask = 0xFFFF0000,
1852: .insns_flags = PPC_INSNS_970FX,
1853: .flags = PPC_FLAGS_970FX,
1854: .msr_mask = 0x800000000204FF36,
1855: },
1856: #endif
1857: #if defined (TODO)
1858: /* RS64 (Apache/A35) */
1859: /* This one seems to support the whole POWER2 instruction set
1860: * and the PowerPC 64 one.
1861: */
1862: {
1863: .name = "RS64",
1864: .pvr = CPU_PPC_RS64,
1865: .pvr_mask = 0xFFFF0000,
1866: .insns_flags = PPC_INSNS_RS64,
1867: .flags = PPC_FLAGS_RS64,
1868: .msr_mask = xxx,
1869: },
1870: {
1871: .name = "Apache",
1872: .pvr = CPU_PPC_RS64,
1873: .pvr_mask = 0xFFFF0000,
1874: .insns_flags = PPC_INSNS_RS64,
1875: .flags = PPC_FLAGS_RS64,
1876: .msr_mask = xxx,
1877: },
1878: {
1879: .name = "A35",
1880: .pvr = CPU_PPC_RS64,
1881: .pvr_mask = 0xFFFF0000,
1882: .insns_flags = PPC_INSNS_RS64,
1883: .flags = PPC_FLAGS_RS64,
1884: .msr_mask = xxx,
1885: },
1886: #endif
1887: #if defined (TODO)
1888: /* RS64-II (NorthStar/A50) */
1889: {
1890: .name = "RS64-II",
1891: .pvr = CPU_PPC_RS64II,
1892: .pvr_mask = 0xFFFF0000,
1893: .insns_flags = PPC_INSNS_RS64,
1894: .flags = PPC_FLAGS_RS64,
1895: .msr_mask = xxx,
1896: },
1897: {
1898: .name = "NortStar",
1899: .pvr = CPU_PPC_RS64II,
1900: .pvr_mask = 0xFFFF0000,
1901: .insns_flags = PPC_INSNS_RS64,
1902: .flags = PPC_FLAGS_RS64,
1903: .msr_mask = xxx,
1904: },
1905: {
1906: .name = "A50",
1907: .pvr = CPU_PPC_RS64II,
1908: .pvr_mask = 0xFFFF0000,
1909: .insns_flags = PPC_INSNS_RS64,
1910: .flags = PPC_FLAGS_RS64,
1911: .msr_mask = xxx,
1912: },
1913: #endif
1914: #if defined (TODO)
1915: /* RS64-III (Pulsar) */
1916: {
1917: .name = "RS64-III",
1918: .pvr = CPU_PPC_RS64III,
1919: .pvr_mask = 0xFFFF0000,
1920: .insns_flags = PPC_INSNS_RS64,
1921: .flags = PPC_FLAGS_RS64,
1922: .msr_mask = xxx,
1923: },
1924: {
1925: .name = "Pulsar",
1926: .pvr = CPU_PPC_RS64III,
1927: .pvr_mask = 0xFFFF0000,
1928: .insns_flags = PPC_INSNS_RS64,
1929: .flags = PPC_FLAGS_RS64,
1930: .msr_mask = xxx,
1931: },
1932: #endif
1933: #if defined (TODO)
1934: /* RS64-IV (IceStar/IStar/SStar) */
1935: {
1936: .name = "RS64-IV",
1937: .pvr = CPU_PPC_RS64IV,
1938: .pvr_mask = 0xFFFF0000,
1939: .insns_flags = PPC_INSNS_RS64,
1940: .flags = PPC_FLAGS_RS64,
1941: .msr_mask = xxx,
1942: },
1943: {
1944: .name = "IceStar",
1945: .pvr = CPU_PPC_RS64IV,
1946: .pvr_mask = 0xFFFF0000,
1947: .insns_flags = PPC_INSNS_RS64,
1948: .flags = PPC_FLAGS_RS64,
1949: .msr_mask = xxx,
1950: },
1951: {
1952: .name = "IStar",
1953: .pvr = CPU_PPC_RS64IV,
1954: .pvr_mask = 0xFFFF0000,
1955: .insns_flags = PPC_INSNS_RS64,
1956: .flags = PPC_FLAGS_RS64,
1957: .msr_mask = xxx,
1958: },
1959: {
1960: .name = "SStar",
1961: .pvr = CPU_PPC_RS64IV,
1962: .pvr_mask = 0xFFFF0000,
1963: .insns_flags = PPC_INSNS_RS64,
1964: .flags = PPC_FLAGS_RS64,
1965: .msr_mask = xxx,
1966: },
1967: #endif
1968: /* POWER */
1969: #if defined (TODO)
1970: /* Original POWER */
1971: {
1972: .name = "POWER",
1973: .pvr = CPU_POWER,
1974: .pvr_mask = 0xFFFF0000,
1975: .insns_flags = PPC_INSNS_POWER,
1976: .flags = PPC_FLAGS_POWER,
1977: .msr_mask = xxx,
1978: },
1979: #endif
1980: #if defined (TODO)
1981: /* POWER2 */
1982: {
1983: .name = "POWER2",
1984: .pvr = CPU_POWER2,
1985: .pvr_mask = 0xFFFF0000,
1986: .insns_flags = PPC_INSNS_POWER,
1987: .flags = PPC_FLAGS_POWER,
1988: .msr_mask = xxx,
1989: },
1990: #endif
1991: /* Generic PowerPCs */
1992: #if defined (TODO)
1993: {
1994: .name = "ppc64",
1995: .pvr = CPU_PPC_970,
1996: .pvr_mask = 0xFFFF0000,
1997: .insns_flags = PPC_INSNS_PPC64,
1998: .flags = PPC_FLAGS_PPC64,
1999: .msr_mask = 0xA00000000204FF36,
2000: },
2001: #endif
2002: {
2003: .name = "ppc32",
2004: .pvr = CPU_PPC_604,
2005: .pvr_mask = 0xFFFF0000,
2006: .insns_flags = PPC_INSNS_PPC32,
2007: .flags = PPC_FLAGS_PPC32,
2008: .msr_mask = 0x000000000005FF77,
2009: },
2010: /* Fallback */
2011: {
2012: .name = "ppc",
2013: .pvr = CPU_PPC_604,
2014: .pvr_mask = 0xFFFF0000,
2015: .insns_flags = PPC_INSNS_PPC32,
2016: .flags = PPC_FLAGS_PPC32,
2017: .msr_mask = 0x000000000005FF77,
2018: },
2019: };
2020:
2021: int ppc_find_by_name (const unsigned char *name, ppc_def_t **def)
2022: {
2023: int i, ret;
2024:
2025: ret = -1;
2026: *def = NULL;
2027: for (i = 0; strcmp(ppc_defs[i].name, "ppc") != 0; i++) {
2028: if (strcasecmp(name, ppc_defs[i].name) == 0) {
2029: *def = &ppc_defs[i];
2030: ret = 0;
2031: break;
2032: }
2033: }
2034:
2035: return ret;
2036: }
2037:
2038: int ppc_find_by_pvr (uint32_t pvr, ppc_def_t **def)
2039: {
2040: int i, ret;
2041:
2042: ret = -1;
2043: *def = NULL;
2044: for (i = 0; ppc_defs[i].name != NULL; i++) {
2045: if ((pvr & ppc_defs[i].pvr_mask) ==
2046: (ppc_defs[i].pvr & ppc_defs[i].pvr_mask)) {
2047: *def = &ppc_defs[i];
2048: ret = 0;
2049: break;
2050: }
2051: }
2052:
2053: return ret;
2054: }
2055:
2056: void ppc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
2057: {
2058: int i;
2059:
2060: for (i = 0; ; i++) {
2061: (*cpu_fprintf)(f, "PowerPC '%s' PVR %08x mask %08x\n",
2062: ppc_defs[i].name,
2063: ppc_defs[i].pvr, ppc_defs[i].pvr_mask);
2064: if (strcmp(ppc_defs[i].name, "ppc") == 0)
2065: break;
2066: }
2067: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.