Annotation of qemu/target-ppc/translate_init.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com