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