예제 #1
0
파일: ata.c 프로젝트: bntmorgan/ramooflax
static int __dev_ata_data(ata_t *ata, io_insn_t *io)
{
   ata_dev_t *disk  = &ata->devices[0];
   int        rc;

   debug(DEV_ATA, "ata data\n");

   if(ata->cmd != ATA_READ_SECTOR_CMD && ata->cmd != ATA_WRITE_SECTOR_CMD)
      return dev_io_proxify(io);

   rc = dev_io_proxify(io);
   if(rc == VM_DONE)
   {
      disk->lba++;
      disk->cnt--;
   }

   return rc;
}
예제 #2
0
파일: ata.c 프로젝트: bntmorgan/ramooflax
/*
** ATA Command/Register access dispatcher
*/
int dev_ata(ata_t *ata, io_insn_t *io)
{
   if(!io->in)
      ata->last_out = io->port;

   if(io->port == ATA_STATUS_REG(ata->base))
   {
      if(io->in)
	 return __dev_ata_status(ata, io);
      else
	 return dev_io_proxify_filter(io, __dev_ata_cmd_filter, ata);
   }

   if(io->port == ATA_ALT_STATUS_REG(ata->base))
   {
      if(io->in)
	 return __dev_ata_alt_status(ata, io);
      else
	 goto __proxify;
   }

   if(io->port == ATA_DEVICE_REG(ata->base))
      return __dev_ata_device(ata, io);

   if(io->port == ATA_DATA_REG(ata->base))
      return __dev_ata_data(ata, io);

   if(io->port == ATA_SECT_CNT_REG(ata->base))
      return dev_io_proxify_filter(io, __dev_ata_scnt_filter, ata);

   if(io->port == ATA_LBA_LOW_REG(ata->base) ||
      io->port == ATA_LBA_MID_REG(ata->base) ||
      io->port == ATA_LBA_HIGH_REG(ata->base))
      return dev_io_proxify_filter(io, __dev_ata_lba_filter, ata);

   if(io->port == ATA_ERR_REG(ata->base))
   {
      if(io->in)
	 debug(DEV_ATA, "ata err\n");
      else
	 debug(DEV_ATA, "ata feat\n");

      goto __proxify;
   }

   debug(DEV_ATA, "ata ???\n");

__proxify:
   return dev_io_proxify(io);
}
예제 #3
0
int dev_access()
{
   io_insn_t io;

   __io_init(&io);

#ifdef CONFIG_HAS_NET
   if(io.port == PCI_CONFIG_ADDR || io.port == PCI_CONFIG_DATA)
      return dev_pci(&io);
#endif

   if(io.port == PS2_SYS_CTRL_PORT_A)
      return dev_ps2(&info->vm.dev.ps2, &io);

   if(range(io.port, KBD_START_PORT, KBD_END_PORT))
      return dev_kbd(&info->vm.dev.kbd, &io);

   if(range(io.port, COM1_START_PORT, COM1_END_PORT))
      return dev_uart(&info->vm.dev.uart, &io);

   return dev_io_proxify(&io);
}
예제 #4
0
파일: ata.c 프로젝트: bntmorgan/ramooflax
static int __dev_ata_device(ata_t *ata, io_insn_t *io)
{
   ata_dev_reg_t dev;
   int           rc;
   io_size_t     sz = {.available = sizeof(ata_dev_reg_t)};

   if(io->in)
      return dev_io_proxify(io);
   else
   {
      /* check crazy io (should not happen) */
      if((io->sz * io->cnt) > sizeof(ata_dev_reg_t))
      {
	 debug(DEV_ATA, "unsupported ata dev access\n");
	 return VM_FAIL;
      }

      rc = dev_io_insn(io, (void*)&dev.raw, &sz);
      if(rc != VM_DONE)
	 return rc;

      ata->dev_head = dev;
      debug(DEV_ATA, "ata device [%s]\n", dev.dev ? "SLAVE":"MASTER");
      return dev_io_native(io, &dev.raw);
   }
}

static int __fake_ata_status(ata_t *ata)
{
   if(ata->last_out == ATA_CMD_REG(ata->base))
      info->vm.cpu.gpr->rax.blow = 1;
   else if(ata->last_out == ATA_DEVICE_REG(ata->base))
      info->vm.cpu.gpr->rax.blow = 0;
   else
   {
      debug(DEV_ATA, "can't fake status for previous out(0x%x)\n", ata->last_out);
      return VM_FAIL;
   }

   return VM_DONE;
}

static int __dev_ata_status(ata_t *ata, io_insn_t *io)
{
   if(!__rmode() && __ata_guest_want_slave(ata))
   {
      debug(DEV_ATA, "ata fake status\n");
      return __fake_ata_status(ata);
   }

   debug(DEV_ATA, "ata status\n");
   return dev_io_proxify(io);
}

static int __dev_ata_alt_status(ata_t *ata, io_insn_t *io)
{
   if(!__rmode() && __ata_guest_want_slave(ata))
   {
      debug(DEV_ATA, "ata fake ALT status\n");
      return __fake_ata_status(ata);
   }

   debug(DEV_ATA, "ata ALT status\n");
   return dev_io_proxify(io);
}

static int __dev_ata_lba_filter(void *device, void *arg)
{
   ata_t     *ata  = (ata_t*)arg;
   ata_dev_t *disk = &ata->devices[0];
   uint8_t    lba  = *(uint8_t*)device;
   uint8_t    idx  = ata->last_out - ATA_LBA_LOW_REG(ata->base);

   if(idx > 2)
   {
      debug(DEV_ATA, "unknown (internal) LBA index access (%d)\n", idx);
      return VM_FAIL;
   }

   disk->lba_r[idx] = lba;
   debug(DEV_ATA, "ata lba[%d] = 0x%x\n", idx, lba);
   return VM_DONE;
}