示例#1
0
文件: device.c 项目: futurepr0n/cen64
// Continually cycles the device until setjmp returns.
int device_debug_spin(struct cen64_device *device) {
  struct vr4300_stats vr4300_stats;

  // Prepare stats, set a breakpoint @ VR4300 IPL vector.
  memset(&vr4300_stats, 0, sizeof(vr4300_stats));
  netapi_debug_wait(device->debug_sfd, device);

  if (setjmp(device->bus.unwind_data))
    return 1;

  while (1) {
    unsigned i;

    for (i = 0; i < 2; i++) {
      vr4300_cycle(&device->vr4300);
      rsp_cycle(&device->rsp);
      ai_cycle(&device->ai);
      vi_cycle(&device->vi);

      vr4300_cycle_extra(&device->vr4300, &vr4300_stats);

    }

    vr4300_cycle(&device->vr4300);
    vr4300_cycle_extra(&device->vr4300, &vr4300_stats);
  }

  return 0;
}
示例#2
0
文件: device.c 项目: futurepr0n/cen64
CEN64_THREAD_RETURN_TYPE run_vr4300_thread(void *opaque) {
  struct cen64_device *device = (struct cen64_device *) opaque;

  while (1) {
    unsigned i, j;

    for (i = 0; i < 6250 / 10; i++) {
      for (j = 0; j < 10; j++)
        ai_cycle(&device->ai);

      for (j = 0; j < 15; j++)
        vr4300_cycle(&device->vr4300);
    }

    // Sync up with the RCP thread.
    cen64_mutex_lock(&device->sync_mutex);

    if (!device->other_thread_is_waiting) {
      device->other_thread_is_waiting = true;
      cen64_cv_wait(&device->sync_cv, &device->sync_mutex);
    }

    else {
      device->other_thread_is_waiting = false;
      cen64_mutex_unlock(&device->sync_mutex);
      cen64_cv_signal(&device->sync_cv);
    }
  }

  return CEN64_THREAD_RETURN_VAL;
}
示例#3
0
文件: device.c 项目: futurepr0n/cen64
// Continually cycles the device until setjmp returns.
int device_spin(struct cen64_device *device) {
  if (setjmp(device->bus.unwind_data))
    return 1;

  while (1) {
    unsigned i;

    for (i = 0; i < 2; i++) {
      vr4300_cycle(&device->vr4300);
      rsp_cycle(&device->rsp);
      ai_cycle(&device->ai);
      vi_cycle(&device->vi);

    }

    vr4300_cycle(&device->vr4300);
  }

  return 0;
}
示例#4
0
void * runCen64(void * p) {
  struct bus_controller *bus = (struct bus_controller *) p;
  struct vr4300 vr4300;

  vr4300_init(&vr4300, bus);
  vr4300.pipeline.icrf_latch.pc = 0xFFFFFFFF801E4B10ULL;

  // Prime the pipeline...
  while (vr4300.pipeline.dcwb_latch.common.pc != 0xFFFFFFFF801E4B10ULL ||
        (vr4300.pipeline.dcwb_latch.common.fault ||
        vr4300.pipeline.dcwb_latch.common.killed))
    vr4300_cycle(&vr4300);

  //printf("cmips starts at 0x%.8X... PRIMED!!\n",bus->emu->pc);
  unsigned steps_compld = 0;

  uint8_t *mem_at_wb = malloc(64 * 1024 * 1024);
  uint8_t *mem_at_commit = malloc(64 * 1024 * 1024);

  if (mem_at_wb == NULL || mem_at_commit == NULL) {
    printf("MOAR mammaries required!!\n");
    abort();
  }

  memcpy(mem_at_wb, bus->emu->mem, 64 * 1024 * 1024);
  memcpy(mem_at_commit, bus->emu->mem, 64 * 1024 *1024);

  while (1) {
        int i;

        if(pthread_mutex_lock(&emu_mutex)) {
            puts("mutex failed lock, exiting");
            exit(1);
        }

        for (i = 0; i < 10000; i++) {
#if 0
          //printf(".");
          //fflush(stdout);

          // printf("step_mips, pc: 0x%.8X\n", bus->emu->pc);
          uint32_t cmp_pc = bus->emu->pc;
          step_mips(bus->emu);

          do {
            vr4300_cycle(&vr4300);
          } while(vr4300.pipeline.last_pipe_result.fault ||
                  vr4300.pipeline.last_pipe_result.killed);

          vr4300.pipeline.last_pipe_result.fault = ~0;

          if (cmp_pc != (uint32_t) vr4300.pipeline.last_pipe_result.pc) {
            printf("PC mismatch detected @ %u steps!\n", steps_compld);
            printf("cmips: 0x%.8X, cen64: 0x%.8X\n",
              bus->emu->pc, vr4300.pipeline.last_pipe_result.pc);
            abort();
          }

          size_t ri;
          for (ri = 1; ri < 32; ri++) {
            if ((uint32_t) vr4300.regs[ri] != bus->emu->regs[ri]) {
              printf("GPR[%u] mismatch detected @ 0x%.8X/%u steps!\n", ri, cmp_pc, steps_compld);
              printf("cmips: 0x%.8X, cen64: 0x%.8X\n", bus->emu->regs[ri], vr4300.regs[ri]);
              abort();
            }
          }

#if 0
          else {
            printf("cmips: 0x%.8X, cen64: 0x%.8X\n",
              bus->emu->pc, vr4300.pipeline.last_pipe_result.pc);
          }
#endif

// this is too slow
#if 1
        if (steps_compld > 242180) {
          //memcpy(mem_at_commit, bus->mem, 64 * 1024 * 1024);
          if (steps_compld > 242182 && memcmp(mem_at_commit, bus->emu->mem, 64 * 1024 * 1024)) {
            size_t k;
            bool false_alarm;
            for (k = 0; k < 64 * 1024 * 1024 / 4; k++) {
              uint32_t cm, cm1, cm2;
              memcpy(&cm, mem_at_commit + k * 4, sizeof(cm));
              memcpy(&cm1, mem_at_wb + k * 4, sizeof(cm1));
              memcpy(&cm2, bus->mem + k * 4, sizeof(cm2));
              if (cm != bus->emu->mem[k] && cm1 != bus->emu->mem[k] && cm2 != bus->emu->mem[k]) {
                printf("Memory mismatch detected @ %u steps!\n", steps_compld);
                printf("   -> @addr=0x%.8X ... cmips=0x%.8X, cen64=0x%.8X\n",
                  (unsigned) (k * 4), bus->emu->mem[k], cm);
                false_alarm = false;
                break;
              } else {
                false_alarm = true;
                break;
              }
            }
            if (!false_alarm)
            abort();
          }

          memcpy(mem_at_commit, mem_at_wb, 64 * 1024 * 1024);
          memcpy(mem_at_wb, bus->mem, 64 * 1024 * 1024);
        }
#endif
        steps_compld++;
#else
            vr4300_cycle(&vr4300);
#endif
        }

        if(pthread_mutex_unlock(&emu_mutex)) {
            puts("mutex failed unlock, exiting");
            exit(1);
        }
  }