/[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 23 by dpavlin, Mon Oct 8 16:19:37 2007 UTC revision 24 by dpavlin, Mon Oct 8 16:19:56 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.58 2006/06/16 18:31:26 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 157  int ppc_cpu_new(struct cpu *cpu, struct Line 160  int ppc_cpu_new(struct cpu *cpu, struct
160          /*  Some default stack pointer value.  TODO: move this?  */          /*  Some default stack pointer value.  TODO: move this?  */
161          cpu->cd.ppc.gpr[1] = machine->physical_ram_in_mb * 1048576 - 4096;          cpu->cd.ppc.gpr[1] = machine->physical_ram_in_mb * 1048576 - 4096;
162    
163            ppc_init_64bit_dummy_tables(cpu);
164    
165          /*          /*
166           *  NOTE/TODO: Ugly hack for OpenFirmware emulation:           *  NOTE/TODO: Ugly hack for OpenFirmware emulation:
167           */           */
# Line 291  void ppc_exception(struct cpu *cpu, int Line 296  void ppc_exception(struct cpu *cpu, int
296                  cpu->cd.ppc.spr[SPR_SRR1] = (cpu->cd.ppc.msr & 0x87c0ffff);                  cpu->cd.ppc.spr[SPR_SRR1] = (cpu->cd.ppc.msr & 0x87c0ffff);
297    
298          if (!quiet_mode)          if (!quiet_mode)
299                  fatal("[ PPC Exception 0x%x; pc=0x%llx ]\n", exception_nr,                  fatal("[ PPC Exception 0x%x; pc=0x%"PRIx64" ]\n", exception_nr,
300                      (long long)cpu->pc);                      (long long)cpu->pc);
301    
302          /*  Disable External Interrupts, Recoverable Interrupt Mode,          /*  Disable External Interrupts, Recoverable Interrupt Mode,
# Line 331  void ppc_cpu_register_dump(struct cpu *c Line 336  void ppc_cpu_register_dump(struct cpu *c
336    
337                  debug("cpu%i: pc  = 0x", x);                  debug("cpu%i: pc  = 0x", x);
338                  if (bits32)                  if (bits32)
339                          debug("%08x", (int)cpu->pc);                          debug("%08"PRIx32, (uint32_t)cpu->pc);
340                  else                  else
341                          debug("%016llx", (long long)cpu->pc);                          debug("%016"PRIx64, (uint64_t)cpu->pc);
342                  debug("  <%s>\n", symbol != NULL? symbol : " no symbol ");                  debug("  <%s>\n", symbol != NULL? symbol : " no symbol ");
343    
344                  debug("cpu%i: lr  = 0x", x);                  debug("cpu%i: lr  = 0x", x);
345                  if (bits32)                  if (bits32)
346                          debug("%08x", (int)cpu->cd.ppc.spr[SPR_LR]);                          debug("%08"PRIx32, (uint32_t)cpu->cd.ppc.spr[SPR_LR]);
347                  else                  else
348                          debug("%016llx", (long long)cpu->cd.ppc.spr[SPR_LR]);                          debug("%016"PRIx64, (uint64_t)cpu->cd.ppc.spr[SPR_LR]);
349                  debug("  cr  = 0x%08x", (int)cpu->cd.ppc.cr);                  debug("  cr  = 0x%08"PRIx32, (uint32_t)cpu->cd.ppc.cr);
350    
351                  if (bits32)                  if (bits32)
352                          debug("  ");                          debug("  ");
# Line 349  void ppc_cpu_register_dump(struct cpu *c Line 354  void ppc_cpu_register_dump(struct cpu *c
354                          debug("\ncpu%i: ", x);                          debug("\ncpu%i: ", x);
355                  debug("ctr = 0x", x);                  debug("ctr = 0x", x);
356                  if (bits32)                  if (bits32)
357                          debug("%08x", (int)cpu->cd.ppc.spr[SPR_CTR]);                          debug("%08"PRIx32, (uint32_t)cpu->cd.ppc.spr[SPR_CTR]);
358                  else                  else
359                          debug("%016llx", (long long)cpu->cd.ppc.spr[SPR_CTR]);                          debug("%016"PRIx64, (uint64_t)cpu->cd.ppc.spr[SPR_CTR]);
360    
361                  debug("  xer = 0x", x);                  debug("  xer = 0x", x);
362                  if (bits32)                  if (bits32)
363                          debug("%08x\n", (int)cpu->cd.ppc.spr[SPR_XER]);                          debug("%08"PRIx32, (uint32_t)cpu->cd.ppc.spr[SPR_XER]);
364                  else                  else
365                          debug("%016llx\n", (long long)cpu->cd.ppc.spr[SPR_XER]);                          debug("%016"PRIx64, (uint64_t)cpu->cd.ppc.spr[SPR_XER]);
366    
367                    debug("\n");
368    
369                  if (bits32) {                  if (bits32) {
370                          /*  32-bit:  */                          /*  32-bit:  */
# Line 594  void ppc_cpu_register_match(struct machi Line 601  void ppc_cpu_register_match(struct machi
601    
602    
603  /*  /*
604     *  ppc_cpu_tlbdump():
605     *
606     *  Not currently used for PPC.
607     */
608    void ppc_cpu_tlbdump(struct machine *m, int x, int rawflag)
609    {
610    }
611    
612    
613    static void add_response_word(struct cpu *cpu, char *r, uint64_t value,
614            size_t maxlen, int len)
615    {
616            char *format = (len == 4)? "%08"PRIx64 : "%016"PRIx64;
617            if (len == 4)
618                    value &= 0xffffffffULL;
619            if (cpu->byte_order == EMUL_LITTLE_ENDIAN) {
620                    if (len == 4) {
621                            value = ((value & 0xff) << 24) +
622                                    ((value & 0xff00) << 8) +
623                                    ((value & 0xff0000) >> 8) +
624                                    ((value & 0xff000000) >> 24);
625                    } else {
626                            value = ((value & 0xff) << 56) +
627                                    ((value & 0xff00) << 40) +
628                                    ((value & 0xff0000) << 24) +
629                                    ((value & 0xff000000ULL) << 8) +
630                                    ((value & 0xff00000000ULL) >> 8) +
631                                    ((value & 0xff0000000000ULL) >> 24) +
632                                    ((value & 0xff000000000000ULL) >> 40) +
633                                    ((value & 0xff00000000000000ULL) >> 56);
634                    }
635            }
636            snprintf(r + strlen(r), maxlen - strlen(r), format, (uint64_t)value);
637    }
638    
639    
640    /*
641     *  ppc_cpu_gdb_stub():
642     *
643     *  Execute a "remote GDB" command. Returns a newly allocated response string
644     *  on success, NULL on failure.
645     */
646    char *ppc_cpu_gdb_stub(struct cpu *cpu, char *cmd)
647    {
648            if (strcmp(cmd, "g") == 0) {
649                    int i;
650                    char *r;
651                    size_t wlen = cpu->is_32bit?
652                        sizeof(uint32_t) : sizeof(uint64_t);
653                    size_t len = 1 + 76 * wlen;
654                    r = malloc(len);
655                    if (r == NULL) {
656                            fprintf(stderr, "out of memory\n");
657                            exit(1);
658                    }
659                    r[0] = '\0';
660                    for (i=0; i<128; i++)
661                            add_response_word(cpu, r, i, len, wlen);
662                    return r;
663            }
664    
665            if (cmd[0] == 'p') {
666                    int regnr = strtol(cmd + 1, NULL, 16);
667                    size_t wlen = cpu->is_32bit?
668                        sizeof(uint32_t) : sizeof(uint64_t);
669                    size_t len = 2 * wlen + 1;
670                    char *r = malloc(len);
671                    r[0] = '\0';
672                    if (regnr >= 0 && regnr <= 31) {
673                            add_response_word(cpu, r,
674                                cpu->cd.ppc.gpr[regnr], len, wlen);
675                    } else if (regnr == 0x40) {
676                            add_response_word(cpu, r, cpu->pc, len, wlen);
677                    } else if (regnr == 0x42) {
678                            add_response_word(cpu, r, cpu->cd.ppc.cr, len, wlen);
679                    } else if (regnr == 0x43) {
680                            add_response_word(cpu, r, cpu->cd.ppc.spr[SPR_LR],
681                                len, wlen);
682                    } else if (regnr == 0x44) {
683                            add_response_word(cpu, r, cpu->cd.ppc.spr[SPR_CTR],
684                                len, wlen);
685                    } else if (regnr == 0x45) {
686                            add_response_word(cpu, r, cpu->cd.ppc.spr[SPR_XER],
687                                len, wlen);
688                    } else {
689                            /*  Unimplemented:  */
690                            add_response_word(cpu, r, 0xcc000 + regnr, len, wlen);
691                    }
692                    return r;
693            }
694    
695            fatal("ppc_cpu_gdb_stub(): TODO\n");
696            return NULL;
697    }
698    
699    
700    /*
701   *  ppc_cpu_interrupt():   *  ppc_cpu_interrupt():
702   *   *
703   *  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 752  int ppc_cpu_interrupt_ack(struct cpu *cp
752   *  cpu->pc for relative addresses.   *  cpu->pc for relative addresses.
753   */   */
754  int ppc_cpu_disassemble_instr(struct cpu *cpu, unsigned char *instr,  int ppc_cpu_disassemble_instr(struct cpu *cpu, unsigned char *instr,
755          int running, uint64_t dumpaddr, int bintrans)          int running, uint64_t dumpaddr)
756  {  {
757          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;
758          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 1046  int ppc_cpu_disassemble_instr(struct cpu
1046          case PPC_HI6_30:          case PPC_HI6_30:
1047                  xo = (iword >> 2) & 7;                  xo = (iword >> 2) & 7;
1048                  switch (xo) {                  switch (xo) {
1049                    case PPC_30_RLDICL:
1050                  case PPC_30_RLDICR:                  case PPC_30_RLDICR:
1051                    case PPC_30_RLDIMI:     /*  mb, not me  */
1052                            mnem = NULL;
1053                            switch (xo) {
1054                            case PPC_30_RLDICL: mnem = "rldicl"; break;
1055                            case PPC_30_RLDICR: mnem = "rldicr"; break;
1056                            case PPC_30_RLDIMI: mnem = "rldimi"; break;
1057                            }
1058                          rs = (iword >> 21) & 31;                          rs = (iword >> 21) & 31;
1059                          ra = (iword >> 16) & 31;                          ra = (iword >> 16) & 31;
1060                          sh = ((iword >> 11) & 31) | ((iword & 2) << 4);                          sh = ((iword >> 11) & 31) | ((iword & 2) << 4);
1061                          me = ((iword >> 6) & 31) | (iword & 0x20);                          me = ((iword >> 6) & 31) | (iword & 0x20);
1062                          rc = iword & 1;                          rc = iword & 1;
1063                          debug("rldicr%s\tr%i,r%i,%i,%i",                          debug("%s%s\tr%i,r%i,%i,%i",
1064                              rc?".":"", ra, rs, sh, me);                              mnem, rc?".":"", ra, rs, sh, me);
1065                          break;                          break;
1066                  default:                  default:
1067                          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 1228  int ppc_cpu_disassemble_instr(struct cpu
1228                  case PPC_31_WRTEEI:                  case PPC_31_WRTEEI:
1229                          debug("wrteei\t%i", iword & 0x8000? 1 : 0);                          debug("wrteei\t%i", iword & 0x8000? 1 : 0);
1230                          break;                          break;
1231                    case PPC_31_MTMSRD:
1232                            /*  TODO: Just a guess based on MTMSR  */
1233                            rs = (iword >> 21) & 31;
1234                            l_bit = (iword >> 16) & 1;
1235                            debug("mtmsrd\tr%i", rs);
1236                            if (l_bit)
1237                                    debug(",%i", l_bit);
1238                            break;
1239                  case PPC_31_ADDZE:                  case PPC_31_ADDZE:
1240                  case PPC_31_ADDZEO:                  case PPC_31_ADDZEO:
1241                          rt = (iword >> 21) & 31;                          rt = (iword >> 21) & 31;
# Line 1336  int ppc_cpu_disassemble_instr(struct cpu Line 1456  int ppc_cpu_disassemble_instr(struct cpu
1456                          debug("%s\tr%i,r%i", mnem, ra, rb);                          debug("%s\tr%i,r%i", mnem, ra, rb);
1457                          break;                          break;
1458                  case PPC_31_SLW:                  case PPC_31_SLW:
1459                    case PPC_31_SLD:
1460                  case PPC_31_SRAW:                  case PPC_31_SRAW:
1461                  case PPC_31_SRW:                  case PPC_31_SRW:
1462                  case PPC_31_AND:                  case PPC_31_AND:
1463                  case PPC_31_ANDC:                  case PPC_31_ANDC:
1464                  case PPC_31_NOR:                  case PPC_31_NOR:
1465                    case PPC_31_EQV:
1466                  case PPC_31_OR:                  case PPC_31_OR:
1467                  case PPC_31_ORC:                  case PPC_31_ORC:
1468                  case PPC_31_XOR:                  case PPC_31_XOR:
# Line 1355  int ppc_cpu_disassemble_instr(struct cpu Line 1477  int ppc_cpu_disassemble_instr(struct cpu
1477                                  switch (xo) {                                  switch (xo) {
1478                                  case PPC_31_SLW:  mnem =                                  case PPC_31_SLW:  mnem =
1479                                          power? "sl" : "slw"; break;                                          power? "sl" : "slw"; break;
1480                                    case PPC_31_SLD:  mnem = "sld"; break;
1481                                  case PPC_31_SRAW:  mnem =                                  case PPC_31_SRAW:  mnem =
1482                                          power? "sra" : "sraw"; break;                                          power? "sra" : "sraw"; break;
1483                                  case PPC_31_SRW:  mnem =                                  case PPC_31_SRW:  mnem =
# Line 1363  int ppc_cpu_disassemble_instr(struct cpu Line 1486  int ppc_cpu_disassemble_instr(struct cpu
1486                                  case PPC_31_NAND: mnem = "nand"; break;                                  case PPC_31_NAND: mnem = "nand"; break;
1487                                  case PPC_31_ANDC: mnem = "andc"; break;                                  case PPC_31_ANDC: mnem = "andc"; break;
1488                                  case PPC_31_NOR:  mnem = "nor"; break;                                  case PPC_31_NOR:  mnem = "nor"; break;
1489                                    case PPC_31_EQV:  mnem = "eqv"; break;
1490                                  case PPC_31_OR:   mnem = "or"; break;                                  case PPC_31_OR:   mnem = "or"; break;
1491                                  case PPC_31_ORC:  mnem = "orc"; break;                                  case PPC_31_ORC:  mnem = "orc"; break;
1492                                  case PPC_31_XOR:  mnem = "xor"; break;                                  case PPC_31_XOR:  mnem = "xor"; break;
# Line 1447  int ppc_cpu_disassemble_instr(struct cpu Line 1571  int ppc_cpu_disassemble_instr(struct cpu
1571                          debug("%s%s\tr%i,r%i,%i", mnem,                          debug("%s%s\tr%i,r%i,%i", mnem,
1572                              rc? "." : "", ra, rs, sh);                              rc? "." : "", ra, rs, sh);
1573                          break;                          break;
1574                    case PPC_31_DSSALL:
1575                            debug("dssall");
1576                            break;
1577                  case PPC_31_EIEIO:                  case PPC_31_EIEIO:
1578                          debug("%s", power? "eieio?" : "eieio");                          debug("%s", power? "eieio?" : "eieio");
1579                          break;                          break;
# Line 1469  int ppc_cpu_disassemble_instr(struct cpu Line 1596  int ppc_cpu_disassemble_instr(struct cpu
1596                          }                          }
1597                          debug("%s%s\tr%i,r%i", mnem, rc? "." : "", ra, rs);                          debug("%s%s\tr%i,r%i", mnem, rc? "." : "", ra, rs);
1598                          break;                          break;
                 case 359:  
                         debug("TODO: ALTIVEC 359");  
                         break;  
1599                  case PPC_31_LVX:                  case PPC_31_LVX:
1600                          debug("lvx\tTODO: ALTIVEC");                  case PPC_31_LVXL:
                         break;  
1601                  case PPC_31_STVX:                  case PPC_31_STVX:
                         debug("stvx\tTODO: ALTIVEC");  
                         break;  
1602                  case PPC_31_STVXL:                  case PPC_31_STVXL:
1603                          debug("stvxl\tTODO: ALTIVEC");                          rs = (iword >> 21) & 31;        /*  vs for stores,  */
1604                            ra = (iword >> 16) & 31;        /*  rs=vl for loads  */
1605                            rb = (iword >> 11) & 31;
1606                            rc = iword & 1;
1607                            switch (xo) {
1608                            case PPC_31_LVX:   mnem = "lvx";  break;
1609                            case PPC_31_LVXL:  mnem = "lvxl"; break;
1610                            case PPC_31_STVX:  mnem = "stvx";  break;
1611                            case PPC_31_STVXL: mnem = "stvxl"; break;
1612                            }
1613                            debug("%s%s\tv%i,r%i,r%i", mnem, rc? "." : "",
1614                                rs, ra, rb);
1615                          break;                          break;
1616                  default:                  default:
1617                          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 1984  void update_cr0(struct cpu *cpu, uint64_
1984    
1985  #include "tmp_ppc_tail.c"  #include "tmp_ppc_tail.c"
1986    
1987    

Legend:
Removed from v.23  
changed lines
  Added in v.24

  ViewVC Help
Powered by ViewVC 1.1.26