Пример #1
0
/* DMA transfer operation */
void physmem_dma_transfer(vm_instance_t *vm,m_uint64_t src,m_uint64_t dst,
                          size_t len)
{
   m_uint64_t dummy;
   u_char *sptr,*dptr;
   size_t clen,sl,dl;

   while(len > 0) {
      sptr = physmem_get_hptr(vm,src,0,MTS_READ,&dummy);
      dptr = physmem_get_hptr(vm,dst,0,MTS_WRITE,&dummy);

      if (!sptr || !dptr) {
         vm_log(vm,"DMA","unable to transfer from 0x%llx to 0x%llx\n",src,dst);
         return;
      }

      sl = VM_PAGE_SIZE - (src & VM_PAGE_IMASK);
      dl = VM_PAGE_SIZE - (dst & VM_PAGE_IMASK);
      clen = m_min(sl,dl);
      clen = m_min(clen,len);

      memcpy(dptr,sptr,clen);

      src += clen;
      dst += clen;
      len -= clen;
   }
}
Пример #2
0
/* Copy a memory block to VM physical RAM from real host */
void physmem_copy_to_vm(vm_instance_t *vm,void *real_buffer,
                        m_uint64_t paddr,size_t len)
{
   m_uint64_t dummy;
   m_uint32_t r;
   u_char *ptr;

   while(len > 0) {
      r = m_min(VM_PAGE_SIZE - (paddr & VM_PAGE_IMASK), len);
      ptr = physmem_get_hptr(vm,paddr,0,MTS_WRITE,&dummy);
      
      if (likely(ptr != NULL)) {
         memcpy(ptr,real_buffer,r);
      } else {
         r = m_min(len,4);
         switch(r) {
            case 4:
               physmem_copy_u32_to_vm(vm,paddr,
                                      htovm32(*(m_uint32_t *)real_buffer));
               break;
            case 2:
               physmem_copy_u16_to_vm(vm,paddr,
                                      htovm16(*(m_uint16_t *)real_buffer));
               break;
            case 1:
               physmem_copy_u8_to_vm(vm,paddr,*(m_uint8_t *)real_buffer);
               break;
         }
      }

      real_buffer += r;
      paddr += r;
      len -= r;
   }
}
Пример #3
0
/* Copy a 16-bit word to the VM physical RAM from real host */
void physmem_copy_u8_to_vm(vm_instance_t *vm,m_uint64_t paddr,m_uint8_t val)
{
   m_uint64_t tmp = val;
   m_uint8_t *ptr;

   if ((ptr = physmem_get_hptr(vm,paddr,1,MTS_WRITE,&tmp)) != NULL)   
      *ptr = val;
}
Пример #4
0
/* Copy a 16-bit word to the VM physical RAM from real host */
void physmem_copy_u16_to_vm(vm_instance_t *vm,m_uint64_t paddr,m_uint16_t val)
{
   m_uint64_t tmp = val;
   m_uint16_t *ptr;

   if ((ptr = physmem_get_hptr(vm,paddr,2,MTS_WRITE,&tmp)) != NULL)   
      *ptr = htovm16(val);
}
Пример #5
0
/* Copy a byte from the VM physical RAM to real host */
m_uint8_t physmem_copy_u8_from_vm(vm_instance_t *vm,m_uint64_t paddr)
{
   m_uint64_t tmp = 0;
   m_uint8_t *ptr;

   if ((ptr = physmem_get_hptr(vm,paddr,1,MTS_READ,&tmp)) != NULL)
      return(*ptr);

   return(tmp);
}
Пример #6
0
/*
 * MIPS64 fetch->decode->dispatch main loop
 */
void *mips_cpu_fdd (cpu_mips_t * cpu)
{
    mips_insn_t insn = 0;
    int res;

    cpu->cpu_thread_running = TRUE;
    current_cpu = cpu;

    mips_init_host_alarm ();

start_cpu:
    for (;;) {
        if (unlikely (cpu->state != CPU_STATE_RUNNING))
            break;

        if (unlikely ((cpu->pause_request) & CPU_INTERRUPT_EXIT)) {
            cpu->state = CPU_STATE_PAUSING;
            break;
        }

        /* Reset "zero register" (for safety) */
        cpu->gpr[0] = 0;

        /* Check IRQ */
        if (unlikely (cpu->irq_pending)) {
            mips_trigger_irq (cpu);
            continue;
        }
        /* Fetch  the instruction */
        res = mips_fetch_instruction (cpu, cpu->pc, &insn);

        if (cpu->vm->trace_address == cpu->pc) {
            /* Trace address. */
            printf ("*** %08x: %08x ", cpu->pc, insn);
            print_insn_mips (cpu->pc, insn, stdout);
            printf ("\n");
            dumpregs (cpu);
        }

        if (unlikely (res == 1)) {
            /*exception when fetching instruction */
            printf ("%08x: exception when fetching instruction\n", cpu->pc);
            if (cpu->pc == 0)
                exit(-1);
            continue;
        }
        if (unlikely ((cpu->vm->mipsy_debug_mode)
                && ((cpu_hit_breakpoint (cpu->vm, cpu->pc) == SUCCESS)
                    || (cpu->vm->gdb_interact_sock == -1)
                    || (cpu->vm->mipsy_break_nexti == MIPS_BREAKANYCPU)))) {
            if (mips_debug (cpu->vm, 1)) {
                continue;
            }
        }
        if (cpu->vm->debug_level > 2 || (cpu->vm->debug_level > 1 &&
            (cpu->cp0.reg[MIPS_CP0_STATUS] & MIPS_CP0_STATUS_UM) &&
            ! (cpu->cp0.reg[MIPS_CP0_STATUS] & MIPS_CP0_STATUS_EXL)))
        {
            /* Print instructions in user mode. */
            printf ("%08x:       %08x        ", cpu->pc, insn);
            print_insn_mips (cpu->pc, insn, stdout);
            printf ("\n");
            fflush (stdout);
#if 0
            m_uint32_t dummy;
            unsigned char *p = physmem_get_hptr (cpu->vm, 0x00010000, 0, MTS_READ, &dummy);
            if (p) {
                unsigned nbytes;
                for (nbytes=0x40; nbytes>0; p+=16, nbytes-=16) {
                    printf ("%08x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
                        (unsigned) p, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],
                        p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]);
                }
            }
#endif
        }
        res = mips_exec_single_instruction (cpu, insn);

        /* Normal flow ? */
        if (likely (!res))
            cpu->pc += sizeof (mips_insn_t);
    }

    while (cpu->cpu_thread_running) {
        switch (cpu->state) {
        case CPU_STATE_RUNNING:
            cpu->state = CPU_STATE_RUNNING;
            goto start_cpu;

        case CPU_STATE_HALTED:
            cpu->cpu_thread_running = FALSE;
            break;
        case CPU_STATE_RESTARTING:
            cpu->state = CPU_STATE_RESTARTING;
            /*Just waiting for cpu restart. */
            break;
        case CPU_STATE_PAUSING:
            /*main loop must wait for me. heihei :) */
            mips_main_loop_wait (cpu, 0);
            cpu->state = CPU_STATE_RUNNING;
            cpu->pause_request &= ~CPU_INTERRUPT_EXIT;
            /*start cpu again */
            goto start_cpu;

        }
    }
    return NULL;
}