예제 #1
0
파일: vm.c 프로젝트: ibara/retrobsd
/*
 * Shutdown hardware resources used by a VM.
 * The CPU must have been stopped.
 */
static int vm_hardware_shutdown (vm_instance_t * vm)
{
    //int i;

    if ((vm->status == VM_STATUS_HALTED) || !vm->cpu_group) {
        vm_log (vm, "VM", "trying to shutdown an inactive VM.\n");
        return (-1);
    }

    vm_log (vm, "VM", "shutdown procedure engaged.\n");

    /* Mark the VM as halted */
    vm->status = VM_STATUS_HALTED;

    /* Disable NVRAM operations */
    // vm->nvram_extract_config = NULL;
    //  vm->nvram_push_config = NULL;

    /* Free the object list */
    // vm_object_free_list(vm);

    /* Free resources used by PCI busses */
    //  vm_log(vm,"VM","removing PCI busses.\n");
    //  pci_io_data_remove(vm,vm->pci_io_space);
    //  pci_bus_remove(vm->pci_bus[0]);
    //  pci_bus_remove(vm->pci_bus[1]);
    //  vm->pci_bus[0] = vm->pci_bus[1] = NULL;

    /* Free the PCI bus pool */
    /* for(i=0;i<VM_PCI_POOL_SIZE;i++) {
     * if (vm->pci_bus_pool[i] != NULL) {
     * pci_bus_remove(vm->pci_bus_pool[i]);
     * vm->pci_bus_pool[i] = NULL;
     * }
     * }     */

    /* Remove the IRQ routing vectors */
    vm->set_irq = NULL;
    vm->clear_irq = NULL;

    /* Delete the VTTY for Console and AUX ports */
    vm_log (vm, "VM", "deleting VTTY.\n");
    vm_delete_vtty (vm);

    /* Delete system CPU group */
    vm_log (vm, "VM", "deleting system CPUs.\n");
    cpu_group_delete (vm->cpu_group);
    vm->cpu_group = NULL;
    vm->boot_cpu = NULL;

    vm_log (vm, "VM", "shutdown procedure completed.\n");
    return (0);
}
예제 #2
0
파일: dev_vtty.c 프로젝트: GNS3/dynamips
/* Put char to vtty */
void vtty_put_char(vtty_t *vtty, char ch)
{
   switch(vtty->type) {
      case VTTY_TYPE_NONE:
         break;

      case VTTY_TYPE_TERM:
      case VTTY_TYPE_SERIAL:
         if (write(vtty->fd_array[0],&ch,1) != 1) {
            vm_log(vtty->vm,"VTTY","%s: put char 0x%x failed (%s)\n",
                   vtty->name,(int)ch,strerror(errno));
         }
         break;

      case VTTY_TYPE_TCP:
         fd_pool_send(&vtty->fd_pool,&ch,1,0);
         break;

      default:
         vm_error(vtty->vm,"vtty_put_char: bad vtty type %d\n",vtty->type);
         exit(1);
   }

   /* store char for replay */
   vtty->replay_buffer[vtty->replay_ptr] = ch;

   ++vtty->replay_ptr;
   if (vtty->replay_ptr == VTTY_BUFFER_SIZE)
      vtty->replay_ptr = 0;
}
예제 #3
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;
   }
}
예제 #4
0
/* Boot the ELF image */
static int ppc32_vmtest_boot_elf(vm_instance_t *vm)
{     
   m_uint32_t rom_entry_point;
   cpu_ppc_t *cpu;

   if (!vm->boot_cpu)
      return(-1);

   /* Suspend CPU activity since we will restart directly from ROM */
   vm_suspend(vm);

   /* Check that CPU activity is really suspended */
   if (cpu_group_sync_state(vm->cpu_group) == -1) {
      vm_error(vm,"unable to sync with system CPUs.\n");
      return(-1);
   }

   /* Reset the boot CPU */
   cpu = CPU_PPC32(vm->boot_cpu);
   ppc32_reset(cpu);

   /* Load ROM (ELF image or embedded) */
   cpu = CPU_PPC32(vm->boot_cpu);
   rom_entry_point = (m_uint32_t)PPC32_ROM_START;

   if ((vm->rom_filename != NULL) &&
       (ppc32_load_elf_image(cpu,vm->rom_filename,0,&rom_entry_point) < 0))
   {
      vm_error(vm,"unable to load alternate ROM '%s', "
               "fallback to embedded ROM.\n\n",vm->rom_filename);
      vm->rom_filename = NULL;
   }

   /* Load ELF image */
   if (ppc32_load_elf_image(cpu,vm->ios_image,
                            (vm->ghost_status == VM_GHOST_RAM_USE),
                            &vm->ios_entry_point) < 0)
   {
      vm_error(vm,"failed to load ELF image '%s'.\n",vm->ios_image);
      return(-1);
   }

   /* Launch the simulation */
   printf("\nPPC32_VMTEST '%s': starting simulation (CPU0 IA=0x%8.8x), "
          "JIT %sabled.\n",
          vm->name,cpu->ia,vm->jit_use ? "en":"dis");

   vm_log(vm,"PPC32_VMTEST_BOOT",
          "starting instance (CPU0 IA=0x%8.8x,JIT %s)\n",
          cpu->ia,vm->jit_use ? "on":"off");
   
   /* Start main CPU */
   if (vm->ghost_status != VM_GHOST_RAM_GENERATE) {
      vm->status = VM_STATUS_RUNNING;
      cpu_start(vm->boot_cpu);
   } else {
      vm->status = VM_STATUS_SHUTDOWN;
   }
   return(0);
}
예제 #5
0
/*
 * dev_c7200_pa_8t_init()
 *
 * Add a PA-8T port adapter into specified slot.
 */
static int dev_c7200_pa_8t_init(vm_instance_t *vm,struct cisco_card *card)
{
   struct pa8t_data *data;
   u_int slot = card->slot_id;

   /* Allocate the private data structure for the PA-8T */
   if (!(data = malloc(sizeof(*data)))) {
      vm_log(vm,"%s: out of memory\n",card->dev_name);
      return(-1);
   }

   /* Set the PCI bus */
   card->pci_bus = vm->slots_pci_bus[slot];

   /* Set the EEPROM */
   cisco_card_set_eeprom(vm,card,cisco_eeprom_find_pa("PA-8T"));
   c7200_set_slot_eeprom(VM_C7200(vm),slot,&card->eeprom);

   /* Create the 1st Mueslix chip */
   data->mueslix[0] = dev_mueslix_init(vm,card->dev_name,1,
                                       card->pci_bus,0,
                                       c7200_net_irq_for_slot_port(slot,0));
   if (!data->mueslix[0]) return(-1);

   /* Create the 2nd Mueslix chip */
   data->mueslix[1] = dev_mueslix_init(vm,card->dev_name,1,
                                       card->pci_bus,1,
                                       c7200_net_irq_for_slot_port(slot,1));
   if (!data->mueslix[1]) return(-1);

   /* Store device info into the router structure */
   card->drv_info = data;
   return(0);
}
예제 #6
0
파일: dev_c1700.c 프로젝트: GNS3/dynamips
/* Boot the IOS image */
static int c1700_boot_ios(c1700_t *router)
{   
   vm_instance_t *vm = router->vm;
   cpu_ppc_t *cpu;

   if (!vm->boot_cpu)
      return(-1);

   /* Suspend CPU activity since we will restart directly from ROM */
   vm_suspend(vm);

   /* Check that CPU activity is really suspended */
   if (cpu_group_sync_state(vm->cpu_group) == -1) {
      vm_error(vm,"unable to sync with system CPUs.\n");
      return(-1);
   }

   /* Reset the boot CPU */
   cpu = CPU_PPC32(vm->boot_cpu);
   ppc32_reset(cpu);

   /* Adjust stack pointer */
   cpu->gpr[1] |= 0x80000000;

   /* Load BAT registers */
   printf("Loading BAT registers\n");
   ppc32_load_bat_array(cpu,bat_array);
   cpu->msr |= PPC32_MSR_IR|PPC32_MSR_DR;

   /* IRQ routing */
   vm->set_irq = c1700_set_irq;
   vm->clear_irq = c1700_clear_irq;

   /* Load IOS image */
   if (ppc32_load_elf_image(cpu,vm->ios_image,
                            (vm->ghost_status == VM_GHOST_RAM_USE),
                            &vm->ios_entry_point) < 0) 
   {
      vm_error(vm,"failed to load Cisco IOS image '%s'.\n",vm->ios_image);
      return(-1);
   }

   /* Launch the simulation */
   printf("\nC1700 '%s': starting simulation (CPU0 IA=0x%8.8x), "
          "JIT %sabled.\n",
          vm->name,cpu->ia,vm->jit_use ? "en":"dis");

   vm_log(vm,"C1700_BOOT",
          "starting instance (CPU0 PC=0x%8.8x,idle_pc=0x%8.8x,JIT %s)\n",
          cpu->ia,cpu->idle_pc,vm->jit_use ? "on":"off");

   /* Start main CPU */
   if (vm->ghost_status != VM_GHOST_RAM_GENERATE) {
      vm->status = VM_STATUS_RUNNING;
      cpu_start(vm->boot_cpu);
   } else {
      vm->status = VM_STATUS_SHUTDOWN;
   }
   return(0);
}
/* Clear a Network IRQ for the specified slot/port */
void dev_c3600_iofpga_net_clear_irq(struct c3600_iofpga_data *d,
                                    u_int slot,u_int port)
{
   struct net_irq_distrib *irq_dist;

#if DEBUG_NET_IRQ
   vm_log(d->router->vm,"IO_FPGA","clearing NetIRQ for slot %u port %u\n",
          slot,port);
#endif

   irq_dist = &net_irq_dist[slot];

   switch(c3600_chassis_get_id(d->router)) {
      case 3620:
      case 3640:
         d->net_irq_status[0] &= ~(1 << (irq_dist->c3620_c3640_offset + port));
         dev_c3620_c3640_iofpga_net_update_irq(d);
         break;
      case 3660:
         d->net_irq_status[irq_dist->c3660_reg] &=
            ~(1 << (irq_dist->c3660_offset + port));
         dev_c3660_iofpga_net_update_irq(d);
         break;
   }
}
예제 #8
0
/* Physical memory dump (32-bit words) */
void physmem_dump_vm(vm_instance_t *vm,m_uint64_t paddr,m_uint32_t u32_count)
{
   m_uint32_t i;

   for(i=0;i<u32_count;i++) {
      vm_log(vm,"physmem_dump","0x%8.8llx: 0x%8.8x\n",
             paddr+(i<<2),physmem_copy_u32_from_vm(vm,paddr+(i<<2)));
   }
}
예제 #9
0
파일: dev_vtty.c 프로젝트: GNS3/dynamips
/* Accept a TCP connection */
static int vtty_tcp_conn_accept(vtty_t *vtty, int nsock)
{
   int fd,*fd_slot;
   u_int i;
   
   if (fd_pool_get_free_slot(&vtty->fd_pool,&fd_slot) < 0) {
      vm_error(vtty->vm,"unable to create a new VTTY TCP connection\n");
      return(-1);
   }
   
   if ((fd = accept(vtty->fd_array[nsock],NULL,NULL)) < 0) {
      vm_error(vtty->vm,"vtty_tcp_conn_accept: accept on port %d failed %s\n",
              vtty->tcp_port,strerror(errno));
      return(-1);
   }

   /* Register the new FD */
   *fd_slot = fd;

   vm_log(vtty->vm,"VTTY","%s is now connected (accept_fd=%d,conn_fd=%d)\n",
          vtty->name,vtty->fd_array[nsock],fd);

   /* Adapt Telnet settings */
   if (vtty->terminal_support) {      
      vtty_telnet_do_ttype(fd);
      vtty_telnet_will_echo(fd);
      vtty_telnet_will_suppress_go_ahead(fd);
      vtty_telnet_dont_linemode(fd);
      vtty->input_state = VTTY_INPUT_TEXT;
   }

   if (telnet_message_ok == 1) {
      fd_printf(fd,0,
                "Connected to Dynamips VM \"%s\" (ID %u, type %s) - %s\r\n"
                "Press ENTER to get the prompt.\r\n", 
                vtty->vm->name, vtty->vm->instance_id, vm_get_type(vtty->vm),
                vtty->name);
      /* replay old text */
      for (i = vtty->replay_ptr; i < VTTY_BUFFER_SIZE; i++) {
         if (vtty->replay_buffer[i] != 0) {
            send(fd,&vtty->replay_buffer[i],VTTY_BUFFER_SIZE-i,0);
            break;
         }
      }
      for (i = 0; i < vtty->replay_ptr; i++) {
         if (vtty->replay_buffer[i] != 0) {
            send(fd,&vtty->replay_buffer[i],vtty->replay_ptr-i,0);
            break;
         }
      }
      /* warn if not running */
      if (vtty->vm->status != VM_STATUS_RUNNING)
         fd_printf(fd,0,"\r\n!!! WARNING - VM is not running, will be unresponsive (status=%d) !!!\r\n",vtty->vm->status);
      vtty_flush(vtty);
   }
   return(0);
}
예제 #10
0
파일: dev_vtty.c 프로젝트: GNS3/dynamips
/* Wait for a TCP connection */
static int vtty_tcp_conn_wait(vtty_t *vtty)
{
    struct sockaddr_in serv;
    int i;
    int one = 1;
    
    for(i=0;i<VTTY_MAX_FD;i++)
        vtty->fd_array[i] = -1;
    
    if ((vtty->fd_array[0] = socket(PF_INET,SOCK_STREAM,0)) < 0) {
        perror("vtty_tcp_waitcon: socket");
        return(-1);
    }
    
    if (setsockopt(vtty->fd_array[0],SOL_SOCKET,SO_REUSEADDR,&one,sizeof(one)) < 0) {
        perror("vtty_tcp_waitcon: setsockopt(SO_REUSEADDR)");
        goto error;
    }
    
    if (setsockopt(vtty->fd_array[0],SOL_SOCKET,SO_KEEPALIVE,&one,sizeof(one)) < 0) {
        perror("vtty_tcp_waitcon: setsockopt(SO_KEEPALIVE)");
        goto error;
    }
    
    // Send telnet packets asap. Dont wait to fill packets up
    if (setsockopt(vtty->fd_array[0],SOL_TCP,TCP_NODELAY,&one,sizeof(one)) < 0)
    {
        perror("vtty_tcp_waitcon: setsockopt(TCP_NODELAY)");
        goto error;
    }
    
    memset(&serv,0,sizeof(serv));
    serv.sin_family = AF_INET;
    serv.sin_addr.s_addr = htonl(INADDR_ANY);
    serv.sin_port = htons(vtty->tcp_port);
    
    if (bind(vtty->fd_array[0],(struct sockaddr *)&serv,sizeof(serv)) < 0) {
        perror("vtty_tcp_waitcon: bind");
        goto error;
    }
    
    if (listen(vtty->fd_array[0],1) < 0) {
        perror("vtty_tcp_waitcon: listen");
        goto error;
    }
    
    vm_log(vtty->vm,"VTTY","%s: waiting connection on tcp port %d (FD %d)\n",
           vtty->name,vtty->tcp_port,vtty->fd_array[0]);
    
    return(1);
    
error:
    close(vtty->fd_array[0]);
    vtty->fd_array[0] = -1;
    return(-1);
}
예제 #11
0
/* Clear a Network IRQ for the specified slot/port */
void dev_c2600_iofpga_net_clear_irq(struct c2600_iofpga_data *d,
                                    u_int slot,u_int port)
{
#if DEBUG_NET_IRQ
   vm_log(d->router->vm,"IO_FPGA","clearing NetIRQ for slot %u port %u\n",
          slot,port);
#endif
   d->net_irq_status &= ~(1 << (net_irq_dist[slot] + port));
   dev_c2600_iofpga_net_update_irq(d);
}
예제 #12
0
/*
 *   Log a message with sprintf-style formatting 
 */
void vm_log_fmt(VMG_ const char *fmt, ...)
{
    /* format the message */
    va_list args;
    va_start(args, fmt);
    char *str = t3vsprintf_alloc(fmt, args);
    va_end(args);

    /* log the message */
    vm_log(vmg_ str, strlen(str));

    /* done with the string */
    t3free(str);
}
예제 #13
0
파일: dev_vtty.c 프로젝트: GNS3/dynamips
/* Delete a virtual tty */
void vtty_delete(vtty_t *vtty)
{
   int i;

   if (vtty != NULL) {
      if (vtty->pprev != NULL) {
         VTTY_LIST_LOCK();
         if (vtty->next)
            vtty->next->pprev = vtty->pprev;
         *(vtty->pprev) = vtty->next;
         VTTY_LIST_UNLOCK();
      }

      switch(vtty->type) {
           case VTTY_TYPE_TCP:
               
               for(i=0;i<vtty->fd_count;i++)
                   if (vtty->fd_array[i] != -1) {
                       vm_log(vtty->vm,"VTTY","%s: closing FD %d\n",vtty->name,vtty->fd_array[i]);
                       close(vtty->fd_array[i]);
                   }

           fd_pool_free(&vtty->fd_pool);
           vtty->fd_count = 0;
           break;
        
           default:
               
               /* We don't close FD 0 since it is stdin */
               if (vtty->fd_array[0] > 0) {
                   vm_log(vtty->vm,"VTTY","%s: closing FD %d\n",vtty->name,vtty->fd_array[0]);
                   close(vtty->fd_array[0]);
               }
       }
      free(vtty);
   }
}
예제 #14
0
/* Remove a device */
void dev_remove (vm_instance_t * vm, struct vdevice *dev)
{
    if (dev == NULL)
        return;

    vm_unbind_device (vm, dev);

    vm_log (vm, "DEVICE",
        "Removal of device %s, fd=%d, host_addr=0x%" LL "x, flags=%d\n",
        dev->name, dev->fd, (m_uint64_t) dev->host_addr, dev->flags);

    if (dev->flags & VDEVICE_FLAG_REMAP) {
        dev_init (dev);
        return;
    }

    if (dev->fd != -1) {
        /* Unmap memory mapped file */
        if (dev->host_addr) {

            vm_log (vm, "MMAP", "unmapping of device '%s', "
                "fd=%d, host_addr=0x%" LL "x, len=0x%x\n",
                dev->name, dev->fd, (m_uint64_t) dev->host_addr,
                dev->phys_len);
            munmap ((void *) dev->host_addr, dev->phys_len);
        }

        close (dev->fd);
    } else {
        /* Use of malloc'ed host memory: free it */
        if (dev->host_addr)
            free ((void *) dev->host_addr);
    }

    /* reinitialize the device to a clean state */
    dev_init (dev);
}
예제 #15
0
파일: dev_c3725.c 프로젝트: GNS3/dynamips
/* Boot the IOS image */
static int c3725_boot_ios(c3725_t *router)
{   
   vm_instance_t *vm = router->vm;
   cpu_mips_t *cpu;

   if (!vm->boot_cpu)
      return(-1);

   /* Suspend CPU activity since we will restart directly from ROM */
   vm_suspend(vm);

   /* Check that CPU activity is really suspended */
   if (cpu_group_sync_state(vm->cpu_group) == -1) {
      vm_error(vm,"unable to sync with system CPUs.\n");
      return(-1);
   }

   /* Reset the boot CPU */
   cpu = CPU_MIPS64(vm->boot_cpu);
   mips64_reset(cpu);

   /* Load IOS image */
   if (mips64_load_elf_image(cpu,vm->ios_image,
                             (vm->ghost_status == VM_GHOST_RAM_USE),
                             &vm->ios_entry_point) < 0) 
   {
      vm_error(vm,"failed to load Cisco IOS image '%s'.\n",vm->ios_image);
      return(-1);
   }

   /* Launch the simulation */
   printf("\nC3725 '%s': starting simulation (CPU0 PC=0x%llx), "
          "JIT %sabled.\n",
          vm->name,cpu->pc,vm->jit_use ? "en":"dis");

   vm_log(vm,"C3725_BOOT",
          "starting instance (CPU0 PC=0x%llx,idle_pc=0x%llx,JIT %s)\n",
          cpu->pc,cpu->idle_pc,vm->jit_use ? "on":"off");

   /* Start main CPU */
   if (vm->ghost_status != VM_GHOST_RAM_GENERATE) {
      vm->status = VM_STATUS_RUNNING;
      cpu_start(vm->boot_cpu);
   } else {
      vm->status = VM_STATUS_SHUTDOWN;
   }
   return(0);
}
예제 #16
0
/* Boot the RAW image */
_unused static int ppc32_vmtest_boot_raw(vm_instance_t *vm)
{   
   cpu_ppc_t *cpu;

   if (!vm->boot_cpu)
      return(-1);

   /* Suspend CPU activity since we will restart directly from ROM */
   vm_suspend(vm);

   /* Check that CPU activity is really suspended */
   if (cpu_group_sync_state(vm->cpu_group) == -1) {
      vm_error(vm,"unable to sync with system CPUs.\n");
      return(-1);
   }

   /* Reset the boot CPU */
   cpu = CPU_PPC32(vm->boot_cpu);
   ppc32_reset(cpu);

   /* Load RAW image */
   if (ppc32_load_raw_image(cpu,vm->ios_image,0xFFF00000) < 0) {
      vm_error(vm,"failed to load RAW image '%s'.\n",vm->ios_image);
      return(-1);
   }

   cpu->ia = 0xFFF00100;
   cpu->gpr[1] = 0x2000;

   /* Launch the simulation */
   printf("\nPPC32_VMTEST '%s': starting simulation (CPU0 IA=0x%8.8x), "
          "JIT %sabled.\n",
          vm->name,cpu->ia,vm->jit_use ? "en":"dis");

   vm_log(vm,"PPC32_VMTEST_BOOT",
          "starting instance (CPU0 IA=0x%8.8x,JIT %s)\n",
          cpu->ia,vm->jit_use ? "on":"off");
   
   /* Start main CPU */
   if (vm->ghost_status != VM_GHOST_RAM_GENERATE) {
      vm->status = VM_STATUS_RUNNING;
      cpu_start(vm->boot_cpu);
   } else {
      vm->status = VM_STATUS_SHUTDOWN;
   }
   return(0);
}
예제 #17
0
파일: vm.c 프로젝트: ShiningDrops/dynamips
/* Shut down all objects of an instance */
void vm_object_free_list(vm_instance_t *vm)
{
   vm_obj_t *obj,*next;

   for(obj=vm->vm_object_list;obj;obj=next) {
      next = obj->next;

      if (obj->shutdown != NULL) {
#if DEBUG_VM
         vm_log(vm,"VM_OBJECT","Shutdown of object \"%s\"\n",obj->name);
#endif
         obj->shutdown(vm,obj->data);
      }
   }

   vm->vm_object_list = NULL;
}
예제 #18
0
/* Stop a test instance */
static int ppc32_vmtest_stop_instance(vm_instance_t *vm)
{
   printf("\nPPC32_VMTEST '%s': stopping simulation.\n",vm->name);
   vm_log(vm,"PPC32_VMTEST_STOP","stopping simulation.\n");

   /* Stop all CPUs */
   if (vm->cpu_group != NULL) {
      vm_stop(vm);
      
      if (cpu_group_sync_state(vm->cpu_group) == -1) {
         vm_error(vm,"unable to sync with system CPUs.\n");
         return(-1);
      }
   }

   /* Free resources that were used during execution to emulate hardware */
   vm_hardware_shutdown(vm);
   return(0);
}
예제 #19
0
파일: dev_c3725.c 프로젝트: GNS3/dynamips
/* Stop a Cisco 3725 instance */
static int c3725_stop_instance(vm_instance_t *vm)
{
   printf("\nC3725 '%s': stopping simulation.\n",vm->name);
   vm_log(vm,"C3725_STOP","stopping simulation.\n");

   /* Stop all CPUs */
   if (vm->cpu_group != NULL) {
      vm_stop(vm);
      
      if (cpu_group_sync_state(vm->cpu_group) == -1) {
         vm_error(vm,"unable to sync with system CPUs.\n");
         return(-1);
      }
   }

   /* Free resources that were used during execution to emulate hardware */
   vm_slot_shutdown_all(vm);
   vm_hardware_shutdown(vm);

   /* Cleanup */   
   VM_C3725(vm)->iofpga_data = NULL;
   VM_C3725(vm)->gt_data = NULL;
   return(0);
}
예제 #20
0
/*
 * dev_remote_control_access()
 */
void *dev_remote_control_access(cpu_gen_t *cpu,struct vdevice *dev,
                                m_uint32_t offset,u_int op_size,u_int op_type,
                                m_uint64_t *data)
{
   vm_instance_t *vm = cpu->vm;
   struct remote_data *d = dev->priv_data;
   struct vdevice *storage_dev;
   size_t len;

   if (op_type == MTS_READ)
      *data = 0;

#if DEBUG_ACCESS
   if (op_type == MTS_READ) {
      cpu_log(cpu,"REMOTE","reading reg 0x%x at pc=0x%llx\n",
              offset,cpu_get_pc(cpu));
   } else {
      cpu_log(cpu,"REMOTE","writing reg 0x%x at pc=0x%llx, data=0x%llx\n",
              offset,cpu_get_pc(cpu),*data);
   }
#endif

   switch(offset) {
      /* ROM Identification tag */
      case 0x000: 
         if (op_type == MTS_READ)
            *data = ROM_ID;
         break;

      /* CPU ID */
      case 0x004: 
         if (op_type == MTS_READ)
            *data = cpu->id;
         break;

      /* Display CPU registers */
      case 0x008:
         if (op_type == MTS_WRITE)
            cpu->reg_dump(cpu);
         break;

      /* Display CPU memory info */
      case 0x00c:
         if (op_type == MTS_WRITE)
            cpu->mmu_dump(cpu);
         break;

      /* Reserved/Unused */
      case 0x010:
         break;

      /* RAM size */
      case 0x014: 
         if (op_type == MTS_READ)
            *data = vm->ram_size;
         break;

      /* ROM size */
      case 0x018: 
         if (op_type == MTS_READ)
            *data = vm->rom_size;
         break;

      /* NVRAM size */
      case 0x01c: 
         if (op_type == MTS_READ)
            *data = vm->nvram_size;
         break;             

      /* IOMEM size */
      case 0x020:
        if (op_type == MTS_READ)
            *data = vm->iomem_size;
         break;

      /* Config Register */
      case 0x024:
         if (op_type == MTS_READ)
            *data = vm->conf_reg;
         break;

      /* ELF entry point */
      case 0x028: 
         if (op_type == MTS_READ)
            *data = vm->ios_entry_point;
         break;      

      /* ELF machine id */
      case 0x02c:
         if (op_type == MTS_READ)
            *data = vm->elf_machine_id;
         break;

      /* Restart IOS Image */
      case 0x030:
         /* not implemented */
         break;

      /* Stop the virtual machine */
      case 0x034:
          // FIXME: WTF is this for?!?!?
         //vm->status = VM_STATUS_SHUTDOWN;
         break;

      /* Debugging/Log message: /!\ physical address */
      case 0x038:
         if (op_type == MTS_WRITE) {
            len = physmem_strlen(vm,*data);
            if (len < sizeof(d->con_buffer)) {
               physmem_copy_from_vm(vm,d->con_buffer,*data,len+1);
               vm_log(vm,"ROM",d->con_buffer);
            }
         }
         break;

      /* Console Buffering */
      case 0x03c:
         if (op_type == MTS_WRITE) {
            if (d->con_buf_pos < (sizeof(d->con_buffer)-1)) {
               d->con_buffer[d->con_buf_pos++] = *data & 0xFF;
               d->con_buffer[d->con_buf_pos] = 0;

               if (d->con_buffer[d->con_buf_pos-1] == '\n') {
                  vm_log(vm,"ROM","%s",d->con_buffer);
                  d->con_buf_pos = 0;
               }
            } else
               d->con_buf_pos = 0;
         }
         break;

      /* Console output */
      case 0x040:
         if (op_type == MTS_WRITE)
            vtty_put_char(vm->vtty_con,(char)*data);
         break;

      /* NVRAM address */
      case 0x044:
         if (op_type == MTS_READ) {
            if ((storage_dev = dev_get_by_name(vm,"nvram")))
               *data = storage_dev->phys_addr;

            if ((storage_dev = dev_get_by_name(vm,"ssa")))
               *data = storage_dev->phys_addr;

            if (cpu->type == CPU_TYPE_MIPS64)
               *data += MIPS_KSEG1_BASE;
         }
         break;

      /* IO memory size for Smart-Init (C3600, others ?) */
      case 0x048:
         if (op_type == MTS_READ)
            *data = vm->nm_iomem_size;
         break;

      /* Cookie position selector */
      case 0x04c:
         if (op_type == MTS_READ)
            *data = d->cookie_pos;
         else
            d->cookie_pos = *data;
         break;
         
      /* Cookie data */
      case 0x050:
         if ((op_type == MTS_READ) && (d->cookie_pos < 64))
            *data = vm->chassis_cookie[d->cookie_pos];
         break;

      /* ROMMON variable */
      case 0x054:
         if (op_type == MTS_WRITE) {
            if (d->var_buf_pos < (sizeof(d->var_buffer)-1)) {
               d->var_buffer[d->var_buf_pos++] = *data & 0xFF;
               d->var_buffer[d->var_buf_pos] = 0;
            } else
               d->var_buf_pos = 0;
         } else {
            if (d->var_buf_pos < (sizeof(d->var_buffer)-1)) {
               *data = d->var_buffer[d->var_buf_pos++];
            } else {
               d->var_buf_pos = 0;
               *data = 0;
            }
         }
         break;

      /* ROMMON variable command */
      case 0x058:
         if (op_type == MTS_WRITE) {
            switch(*data & 0xFF) {
               case ROMMON_SET_VAR:
                  d->var_status = rommon_var_add_str(&vm->rommon_vars,
                                                     d->var_buffer);
                  d->var_buf_pos = 0;
                  break;
               case ROMMON_GET_VAR:
                  d->var_status = rommon_var_get(&vm->rommon_vars,
                                                 d->var_buffer,
                                                 d->var_buffer,
                                                 sizeof(d->var_buffer));
                  d->var_buf_pos = 0;
                  break;
               case ROMMON_CLEAR_VAR_STAT:
                  d->var_buf_pos = 0;
                  break;
               default:
                  d->var_status = -1;
            }
         } else {
            *data = d->var_status;
         }
         break;
   }

   return NULL;
}
예제 #21
0
파일: vm.c 프로젝트: ShiningDrops/dynamips
/* Rename a VM instance */
int vm_rename_instance(vm_instance_t *vm, char *name)
{
   char *old_name;
   char *old_lock_file = NULL;
   FILE *old_lock_fd = NULL;
   glob_t globbuf;
   size_t i;
   char *pattern = NULL;
   char *filename;
   int do_rename = 0;

   if (name == NULL || vm == NULL)
      goto err_invalid; /* invalid argument */

   if (vm->status != VM_STATUS_HALTED)
      goto err_not_stopped; /* VM is not stopped */

   if (strcmp(vm->name, name) == 0)
      return(0); /* same name, done */

   if (registry_exists(name,OBJ_TYPE_VM))
      goto err_exists; /* name already exists */

   old_name = vm->name;
   vm->name = NULL;

   if(!(vm->name = strdup(name)))
      goto err_strdup; /* out of memory */

   /* get new lock */
   do_rename = ( vm_file_naming_type != 1 );
   if (do_rename) {
      old_lock_file = vm->lock_file;
      old_lock_fd = vm->lock_fd;
      vm->lock_file = NULL;
      vm->lock_fd = NULL;

      if (vm_get_lock(vm) == -1)
         goto err_lock;
   }

   if (registry_rename(old_name,name,OBJ_TYPE_VM))
      goto err_registry; /* failed to rename */

   vm_log(vm,"VM","renamed from '%s' to '%s'",old_name,vm->name);

   /* rename files (best effort) */
   if (do_rename) {
      fclose(old_lock_fd);
      unlink(old_lock_file);
      free(old_lock_file);

      vm_close_log(vm);

      if ((pattern = dyn_sprintf("%s_%s_*",vm_get_type(vm),old_name)) == NULL)
         goto skip_rename;

      if (glob(pattern, GLOB_NOSORT, NULL, &globbuf) != 0)
         goto skip_rename;

      for (i = 0; i < globbuf.gl_pathc; i++) {
         if ((filename = dyn_sprintf("%s_%s_%s",vm_get_type(vm),vm->name,globbuf.gl_pathv[i] + strlen(pattern) - 1)) == NULL)
            break; /* out of memory */

         rename(globbuf.gl_pathv[i], filename);
         free(filename);
      }
      globfree(&globbuf);
 skip_rename:
      free(pattern);

      vm_reopen_log(vm);
   }

   free(old_name);
   return(0); // done

 err_registry:
 err_lock:
 err_strdup:
   free(vm->name);
   vm->name = old_name;

   if (do_rename) {
      vm_release_lock(vm,TRUE);
      vm->lock_file = old_lock_file;
      vm->lock_fd = old_lock_fd;
   }
 err_exists:
 err_not_stopped:
 err_invalid:
   return(-1);
}
예제 #22
0
파일: dev_vtty.c 프로젝트: GNS3/dynamips
/* Wait for a TCP connection */
static int vtty_tcp_conn_wait(vtty_t *vtty)
{
    struct addrinfo hints,*res,*res0;
    char port_str[20],*addr,*proto;
    int i, nsock;
    int one = 1;
    
    for(i=0;i<VTTY_MAX_FD;i++)
        vtty->fd_array[i] = -1;
    
    memset(&hints,0,sizeof(hints));
    hints.ai_family = PF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE;
    
    snprintf(port_str,sizeof(port_str),"%d",vtty->tcp_port);
    addr = (binding_addr && strlen(binding_addr)) ? binding_addr : NULL;
    
    if (getaddrinfo(addr,port_str,&hints,&res0) != 0) {
        perror("vtty_tcp_waitcon: getaddrinfo");
        return(-1);
    }
    
    nsock = 0;
    for (res=res0;(res && (nsock < VTTY_MAX_FD));res=res->ai_next)
    {
        if ((res->ai_family != PF_INET) && (res->ai_family != PF_INET6))
            continue;
        
        vtty->fd_array[nsock] = socket(res->ai_family,res->ai_socktype,
                                       res->ai_protocol);
        
        if (vtty->fd_array[nsock] < 0)
            continue;
        
        if (setsockopt(vtty->fd_array[nsock],SOL_SOCKET,SO_REUSEADDR,&one,sizeof(one)) < 0)
            perror("vtty_tcp_waitcon: setsockopt(SO_REUSEADDR)");
        
        if (setsockopt(vtty->fd_array[nsock],SOL_SOCKET,SO_KEEPALIVE,&one,sizeof(one)) < 0)
            perror("vtty_tcp_waitcon: setsockopt(SO_KEEPALIVE)");
        
        // Send telnet packets asap. Dont wait to fill packets up
        if (setsockopt(vtty->fd_array[nsock],SOL_TCP,TCP_NODELAY, &one,sizeof(one)) < 0)
            perror("vtty_tcp_waitcon: setsockopt(TCP_NODELAY)");
        
        if ((bind(vtty->fd_array[nsock],res->ai_addr,res->ai_addrlen) < 0) ||
            (listen(vtty->fd_array[nsock],1) < 0))
        {
            close(vtty->fd_array[nsock]);
            vtty->fd_array[nsock] = -1;
            continue;
        }
        
        proto = (res->ai_family == PF_INET6) ? "IPv6" : "IPv4";
        vm_log(vtty->vm,"VTTY","%s: waiting connection on tcp port %d for protocol %s (FD %d)\n",
               vtty->name,vtty->tcp_port,proto,vtty->fd_array[nsock]);
        
        nsock++;
    }

    freeaddrinfo(res0);
    return(nsock);
}