/[gxemul]/trunk/src/cpus/cpu_ppc.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/src/cpus/cpu_ppc.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 22 by dpavlin, Mon Oct 8 16:19:37 2007 UTC revision 26 by dpavlin, Mon Oct 8 16:20:10 2007 UTC
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: cpu_ppc.c,v 1.45 2006/01/24 21:26:01 debug Exp $   *  $Id: cpu_ppc.c,v 1.59 2006/06/24 21:47:23 debug Exp $
29   *   *
30   *  PowerPC/POWER CPU emulation.   *  PowerPC/POWER CPU emulation.
31   */   */
# Line 95  int ppc_cpu_new(struct cpu *cpu, struct Line 95  int ppc_cpu_new(struct cpu *cpu, struct
95          cpu->cd.ppc.bits = cpu->cd.ppc.cpu_type.bits;          cpu->cd.ppc.bits = cpu->cd.ppc.cpu_type.bits;
96          cpu->cd.ppc.spr[SPR_PVR] = cpu->cd.ppc.cpu_type.pvr;          cpu->cd.ppc.spr[SPR_PVR] = cpu->cd.ppc.cpu_type.pvr;
97    
98            /*  cpu->cd.ppc.msr = PPC_MSR_IR | PPC_MSR_DR |
99                PPC_MSR_SF | PPC_MSR_FP;  */
100    
101          cpu->cd.ppc.spr[SPR_IBAT0U] = 0x00001ffc | BAT_Vs;          cpu->cd.ppc.spr[SPR_IBAT0U] = 0x00001ffc | BAT_Vs;
102          cpu->cd.ppc.spr[SPR_IBAT0L] = 0x00000000 | BAT_PP_RW;          cpu->cd.ppc.spr[SPR_IBAT0L] = 0x00000000 | BAT_PP_RW;
103          cpu->cd.ppc.spr[SPR_IBAT1U] = 0xc0001ffc | BAT_Vs;          cpu->cd.ppc.spr[SPR_IBAT1U] = 0xc0001ffc | BAT_Vs;
# Line 126  int ppc_cpu_new(struct cpu *cpu, struct Line 129  int ppc_cpu_new(struct cpu *cpu, struct
129                      ppc_invalidate_code_translation;                      ppc_invalidate_code_translation;
130          }          }
131    
132          cpu->translate_address = ppc_translate_address;          cpu->translate_v2p = ppc_translate_v2p;
133    
134          /*  Only show name and caches etc for CPU nr 0 (in SMP machines):  */          /*  Only show name and caches etc for CPU nr 0 (in SMP machines):  */
135          if (cpu_id == 0) {          if (cpu_id == 0) {
# Line 291  void ppc_exception(struct cpu *cpu, int Line 294  void ppc_exception(struct cpu *cpu, int
294                  cpu->cd.ppc.spr[SPR_SRR1] = (cpu->cd.ppc.msr & 0x87c0ffff);                  cpu->cd.ppc.spr[SPR_SRR1] = (cpu->cd.ppc.msr & 0x87c0ffff);
295    
296          if (!quiet_mode)          if (!quiet_mode)
297                  fatal("[ PPC Exception 0x%x; pc=0x%llx ]\n", exception_nr,                  fatal("[ PPC Exception 0x%x; pc=0x%"PRIx64" ]\n", exception_nr,
298                      (long long)cpu->pc);                      (long long)cpu->pc);
299    
300          /*  Disable External Interrupts, Recoverable Interrupt Mode,          /*  Disable External Interrupts, Recoverable Interrupt Mode,
# Line 331  void ppc_cpu_register_dump(struct cpu *c Line 334  void ppc_cpu_register_dump(struct cpu *c
334    
335                  debug("cpu%i: pc  = 0x", x);                  debug("cpu%i: pc  = 0x", x);
336                  if (bits32)                  if (bits32)
337                          debug("%08x", (int)cpu->pc);                          debug("%08"PRIx32, (uint32_t)cpu->pc);
338                  else                  else
339                          debug("%016llx", (long long)cpu->pc);                          debug("%016"PRIx64, (uint64_t)cpu->pc);
340                  debug("  <%s>\n", symbol != NULL? symbol : " no symbol ");                  debug("  <%s>\n", symbol != NULL? symbol : " no symbol ");
341    
342                  debug("cpu%i: lr  = 0x", x);                  debug("cpu%i: lr  = 0x", x);
343                  if (bits32)                  if (bits32)
344                          debug("%08x", (int)cpu->cd.ppc.spr[SPR_LR]);                          debug("%08"PRIx32, (uint32_t)cpu->cd.ppc.spr[SPR_LR]);
345                  else                  else
346                          debug("%016llx", (long long)cpu->cd.ppc.spr[SPR_LR]);                          debug("%016"PRIx64, (uint64_t)cpu->cd.ppc.spr[SPR_LR]);
347                  debug("  cr  = 0x%08x", (int)cpu->cd.ppc.cr);                  debug("  cr  = 0x%08"PRIx32, (uint32_t)cpu->cd.ppc.cr);
348    
349                  if (bits32)                  if (bits32)
350                          debug("  ");                          debug("  ");
# Line 349  void ppc_cpu_register_dump(struct cpu *c Line 352  void ppc_cpu_register_dump(struct cpu *c
352                          debug("\ncpu%i: ", x);                          debug("\ncpu%i: ", x);
353                  debug("ctr = 0x", x);                  debug("ctr = 0x", x);
354                  if (bits32)                  if (bits32)
355                          debug("%08x", (int)cpu->cd.ppc.spr[SPR_CTR]);                          debug("%08"PRIx32, (uint32_t)cpu->cd.ppc.spr[SPR_CTR]);
356                  else                  else
357                          debug("%016llx", (long long)cpu->cd.ppc.spr[SPR_CTR]);                          debug("%016"PRIx64, (uint64_t)cpu->cd.ppc.spr[SPR_CTR]);
358    
359                  debug("  xer = 0x", x);                  debug("  xer = 0x", x);
360                  if (bits32)                  if (bits32)
361                          debug("%08x\n", (int)cpu->cd.ppc.spr[SPR_XER]);                          debug("%08"PRIx32, (uint32_t)cpu->cd.ppc.spr[SPR_XER]);
362                  else                  else
363                          debug("%016llx\n", (long long)cpu->cd.ppc.spr[SPR_XER]);                          debug("%016"PRIx64, (uint64_t)cpu->cd.ppc.spr[SPR_XER]);
364    
365                    debug("\n");
366    
367                  if (bits32) {                  if (bits32) {
368                          /*  32-bit:  */                          /*  32-bit:  */
# Line 594  void ppc_cpu_register_match(struct machi Line 599  void ppc_cpu_register_match(struct machi
599    
600    
601  /*  /*
602     *  ppc_cpu_tlbdump():
603     *
604     *  Not currently used for PPC.
605     */
606    void ppc_cpu_tlbdump(struct machine *m, int x, int rawflag)
607    {
608    }
609    
610    
611    static void add_response_word(struct cpu *cpu, char *r, uint64_t value,
612            size_t maxlen, int len)
613    {
614            char *format = (len == 4)? "%08"PRIx64 : "%016"PRIx64;
615            if (len == 4)
616                    value &= 0xffffffffULL;
617            if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
618                    if (len == 4) {
619                            value = ((value & 0xff) << 24) +
620                                    ((value & 0xff00) << 8) +
621                                    ((value & 0xff0000) >> 8) +
622                                    ((value & 0xff000000) >> 24);
623                    } else {
624                            value = ((value & 0xff) << 56) +
625                                    ((value & 0xff00) << 40) +
626                                    ((value & 0xff0000) << 24) +
627                                    ((value & 0xff000000ULL) << 8) +
628                                    ((value & 0xff00000000ULL) >> 8) +
629                                    ((value & 0xff0000000000ULL) >> 24) +
630                                    ((value & 0xff000000000000ULL) >> 40) +
631                                    ((value & 0xff00000000000000ULL) >> 56);
632                    }
633            }
634            snprintf(r + strlen(r), maxlen - strlen(r), format, (uint64_t)value);
635    }
636    
637    
638    /*
639     *  ppc_cpu_gdb_stub():
640     *
641     *  Execute a "remote GDB" command. Returns a newly allocated response string
642     *  on success, NULL on failure.
643     */
644    char *ppc_cpu_gdb_stub(struct cpu *cpu, char *cmd)
645    {
646            if (strcmp(cmd, "g") == 0) {
647                    int i;
648                    char *r;
649                    size_t wlen = cpu->is_32bit?
650                        sizeof(uint32_t) : sizeof(uint64_t);
651                    size_t len = 1 + 76 * wlen;
652                    r = malloc(len);
653                    if (r == NULL) {
654                            fprintf(stderr, "out of memory\n");
655                            exit(1);
656                    }
657                    r[0] = '\0';
658                    for (i=0; i<128; i++)
659                            add_response_word(cpu, r, i, len, wlen);
660                    return r;
661            }
662    
663            if (cmd[0] == 'p') {
664                    int regnr = strtol(cmd + 1, NULL, 16);
665                    size_t wlen = cpu->is_32bit?
666                        sizeof(uint32_t) : sizeof(uint64_t);
667                    size_t len = 2 * wlen + 1;
668                    char *r = malloc(len);
669                    r[0] = '\0';
670                    if (regnr >= 0 && regnr <= 31) {
671                            add_response_word(cpu, r,
672                                cpu->cd.ppc.gpr[regnr], len, wlen);
673                    } else if (regnr == 0x40) {
674                            add_response_word(cpu, r, cpu->pc, len, wlen);
675                    } else if (regnr == 0x42) {
676                            add_response_word(cpu, r, cpu->cd.ppc.cr, len, wlen);
677                    } else if (regnr == 0x43) {
678                            add_response_word(cpu, r, cpu->cd.ppc.spr[SPR_LR],
679                                len, wlen);
680                    } else if (regnr == 0x44) {
681                            add_response_word(cpu, r, cpu->cd.ppc.spr[SPR_CTR],
682                                len, wlen);
683                    } else if (regnr == 0x45) {
684                            add_response_word(cpu, r, cpu->cd.ppc.spr[SPR_XER],
685                                len, wlen);
686                    } else {
687                            /*  Unimplemented:  */
688                            add_response_word(cpu, r, 0xcc000 + regnr, len, wlen);
689                    }
690                    return r;
691            }
692    
693            fatal("ppc_cpu_gdb_stub(): TODO\n");
694            return NULL;
695    }
696    
697    
698    /*
699   *  ppc_cpu_interrupt():   *  ppc_cpu_interrupt():
700   *   *
701   *  0..31 are used as BeBox interrupt numbers, 32..47 = ISA,   *  0..31 are used as BeBox interrupt numbers, 32..47 = ISA,
# Line 648  int ppc_cpu_interrupt_ack(struct cpu *cp Line 750  int ppc_cpu_interrupt_ack(struct cpu *cp
750   *  cpu->pc for relative addresses.   *  cpu->pc for relative addresses.
751   */   */
752  int ppc_cpu_disassemble_instr(struct cpu *cpu, unsigned char *instr,  int ppc_cpu_disassemble_instr(struct cpu *cpu, unsigned char *instr,
753          int running, uint64_t dumpaddr, int bintrans)          int running, uint64_t dumpaddr)
754  {  {
755          int hi6, xo, lev, rt, rs, ra, rb, imm, sh, me, rc, l_bit, oe_bit;          int hi6, xo, lev, rt, rs, ra, rb, imm, sh, me, rc, l_bit, oe_bit;
756          int spr, aa_bit, lk_bit, bf, bh, bi, bo, mb, nb, bt, ba, bb, fpreg;          int spr, aa_bit, lk_bit, bf, bh, bi, bo, mb, nb, bt, ba, bb, fpreg;
# Line 942  int ppc_cpu_disassemble_instr(struct cpu Line 1044  int ppc_cpu_disassemble_instr(struct cpu
1044          case PPC_HI6_30:          case PPC_HI6_30:
1045                  xo = (iword >> 2) & 7;                  xo = (iword >> 2) & 7;
1046                  switch (xo) {                  switch (xo) {
1047                    case PPC_30_RLDICL:
1048                  case PPC_30_RLDICR:                  case PPC_30_RLDICR:
1049                    case PPC_30_RLDIMI:     /*  mb, not me  */
1050                            mnem = NULL;
1051                            switch (xo) {
1052                            case PPC_30_RLDICL: mnem = "rldicl"; break;
1053                            case PPC_30_RLDICR: mnem = "rldicr"; break;
1054                            case PPC_30_RLDIMI: mnem = "rldimi"; break;
1055                            }
1056                          rs = (iword >> 21) & 31;                          rs = (iword >> 21) & 31;
1057                          ra = (iword >> 16) & 31;                          ra = (iword >> 16) & 31;
1058                          sh = ((iword >> 11) & 31) | ((iword & 2) << 4);                          sh = ((iword >> 11) & 31) | ((iword & 2) << 4);
1059                          me = ((iword >> 6) & 31) | (iword & 0x20);                          me = ((iword >> 6) & 31) | (iword & 0x20);
1060                          rc = iword & 1;                          rc = iword & 1;
1061                          debug("rldicr%s\tr%i,r%i,%i,%i",                          debug("%s%s\tr%i,r%i,%i,%i",
1062                              rc?".":"", ra, rs, sh, me);                              mnem, rc?".":"", ra, rs, sh, me);
1063                          break;                          break;
1064                  default:                  default:
1065                          debug("unimplemented hi6_30, xo = 0x%x", xo);                          debug("unimplemented hi6_30, xo = 0x%x", xo);
# Line 1116  int ppc_cpu_disassemble_instr(struct cpu Line 1226  int ppc_cpu_disassemble_instr(struct cpu
1226                  case PPC_31_WRTEEI:                  case PPC_31_WRTEEI:
1227                          debug("wrteei\t%i", iword & 0x8000? 1 : 0);                          debug("wrteei\t%i", iword & 0x8000? 1 : 0);
1228                          break;                          break;
1229                    case PPC_31_MTMSRD:
1230                            /*  TODO: Just a guess based on MTMSR  */
1231                            rs = (iword >> 21) & 31;
1232                            l_bit = (iword >> 16) & 1;
1233                            debug("mtmsrd\tr%i", rs);
1234                            if (l_bit)
1235                                    debug(",%i", l_bit);
1236                            break;
1237                  case PPC_31_ADDZE:                  case PPC_31_ADDZE:
1238                  case PPC_31_ADDZEO:                  case PPC_31_ADDZEO:
1239                          rt = (iword >> 21) & 31;                          rt = (iword >> 21) & 31;
# Line 1336  int ppc_cpu_disassemble_instr(struct cpu Line 1454  int ppc_cpu_disassemble_instr(struct cpu
1454                          debug("%s\tr%i,r%i", mnem, ra, rb);                          debug("%s\tr%i,r%i", mnem, ra, rb);
1455                          break;                          break;
1456                  case PPC_31_SLW:                  case PPC_31_SLW:
1457                    case PPC_31_SLD:
1458                  case PPC_31_SRAW:                  case PPC_31_SRAW:
1459                  case PPC_31_SRW:                  case PPC_31_SRW:
1460                  case PPC_31_AND:                  case PPC_31_AND:
1461                  case PPC_31_ANDC:                  case PPC_31_ANDC:
1462                  case PPC_31_NOR:                  case PPC_31_NOR:
1463                    case PPC_31_EQV:
1464                  case PPC_31_OR:                  case PPC_31_OR:
1465                  case PPC_31_ORC:                  case PPC_31_ORC:
1466                  case PPC_31_XOR:                  case PPC_31_XOR:
# Line 1355  int ppc_cpu_disassemble_instr(struct cpu Line 1475  int ppc_cpu_disassemble_instr(struct cpu
1475                                  switch (xo) {                                  switch (xo) {
1476                                  case PPC_31_SLW:  mnem =                                  case PPC_31_SLW:  mnem =
1477                                          power? "sl" : "slw"; break;                                          power? "sl" : "slw"; break;
1478                                    case PPC_31_SLD:  mnem = "sld"; break;
1479                                  case PPC_31_SRAW:  mnem =                                  case PPC_31_SRAW:  mnem =
1480                                          power? "sra" : "sraw"; break;                                          power? "sra" : "sraw"; break;
1481                                  case PPC_31_SRW:  mnem =                                  case PPC_31_SRW:  mnem =
# Line 1363  int ppc_cpu_disassemble_instr(struct cpu Line 1484  int ppc_cpu_disassemble_instr(struct cpu
1484                                  case PPC_31_NAND: mnem = "nand"; break;                                  case PPC_31_NAND: mnem = "nand"; break;
1485                                  case PPC_31_ANDC: mnem = "andc"; break;                                  case PPC_31_ANDC: mnem = "andc"; break;
1486                                  case PPC_31_NOR:  mnem = "nor"; break;                                  case PPC_31_NOR:  mnem = "nor"; break;
1487                                    case PPC_31_EQV:  mnem = "eqv"; break;
1488                                  case PPC_31_OR:   mnem = "or"; break;                                  case PPC_31_OR:   mnem = "or"; break;
1489                                  case PPC_31_ORC:  mnem = "orc"; break;                                  case PPC_31_ORC:  mnem = "orc"; break;
1490                                  case PPC_31_XOR:  mnem = "xor"; break;                                  case PPC_31_XOR:  mnem = "xor"; break;
# Line 1447  int ppc_cpu_disassemble_instr(struct cpu Line 1569  int ppc_cpu_disassemble_instr(struct cpu
1569                          debug("%s%s\tr%i,r%i,%i", mnem,                          debug("%s%s\tr%i,r%i,%i", mnem,
1570                              rc? "." : "", ra, rs, sh);                              rc? "." : "", ra, rs, sh);
1571                          break;                          break;
1572                    case PPC_31_DSSALL:
1573                            debug("dssall");
1574                            break;
1575                  case PPC_31_EIEIO:                  case PPC_31_EIEIO:
1576                          debug("%s", power? "eieio?" : "eieio");                          debug("%s", power? "eieio?" : "eieio");
1577                          break;                          break;
# Line 1469  int ppc_cpu_disassemble_instr(struct cpu Line 1594  int ppc_cpu_disassemble_instr(struct cpu
1594                          }                          }
1595                          debug("%s%s\tr%i,r%i", mnem, rc? "." : "", ra, rs);                          debug("%s%s\tr%i,r%i", mnem, rc? "." : "", ra, rs);
1596                          break;                          break;
                 case 359:  
                         debug("TODO: ALTIVEC 359");  
                         break;  
1597                  case PPC_31_LVX:                  case PPC_31_LVX:
1598                          debug("lvx\tTODO: ALTIVEC");                  case PPC_31_LVXL:
                         break;  
1599                  case PPC_31_STVX:                  case PPC_31_STVX:
                         debug("stvx\tTODO: ALTIVEC");  
                         break;  
1600                  case PPC_31_STVXL:                  case PPC_31_STVXL:
1601                          debug("stvxl\tTODO: ALTIVEC");                          rs = (iword >> 21) & 31;        /*  vs for stores,  */
1602                            ra = (iword >> 16) & 31;        /*  rs=vl for loads  */
1603                            rb = (iword >> 11) & 31;
1604                            rc = iword & 1;
1605                            switch (xo) {
1606                            case PPC_31_LVX:   mnem = "lvx";  break;
1607                            case PPC_31_LVXL:  mnem = "lvxl"; break;
1608                            case PPC_31_STVX:  mnem = "stvx";  break;
1609                            case PPC_31_STVXL: mnem = "stvxl"; break;
1610                            }
1611                            debug("%s%s\tv%i,r%i,r%i", mnem, rc? "." : "",
1612                                rs, ra, rb);
1613                          break;                          break;
1614                  default:                  default:
1615                          debug("unimplemented hi6_31, xo = 0x%x", xo);                          debug("unimplemented hi6_31, xo = 0x%x", xo);
# Line 1852  void update_cr0(struct cpu *cpu, uint64_ Line 1982  void update_cr0(struct cpu *cpu, uint64_
1982    
1983  #include "tmp_ppc_tail.c"  #include "tmp_ppc_tail.c"
1984    
1985    

Legend:
Removed from v.22  
changed lines
  Added in v.26

  ViewVC Help
Powered by ViewVC 1.1.26