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

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

unix.superglobalmegacorp.com