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