File:  [Qemu by Fabrice Bellard] / qemu / target-ppc / translate_init.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 16:37:52 2018 UTC (3 years, 7 months ago) by root
Branches: qemu, MAIN
CVS tags: qemu0072, HEAD
qemu 0.7.2

    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