⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dev_pcmcia_disk.c

📁 思科路由器仿真器,用来仿7200系列得,可以在电脑上模拟路由器-Cisco router simulator, used to fake a 7200 series can be simulated
💻 C
📖 第 1 页 / 共 2 页
字号:
      d->ata_status = ATA_STATUS_RDY|ATA_STATUS_DSC;   }}/* Handle an ATA command */static void ata_handle_cmd(struct pcmcia_disk_data *d){#if DEBUG_ATA   vm_log(d->vm,d->dev.name,"ATA command 0x%2.2x\n",(u_int)d->ata_cmd);#endif   d->data_pos = 0;   switch(d->ata_cmd) {      case ATA_CMD_IDENT_DEVICE:         ata_identify_device(d);         d->ata_cmd_callback = ata_cmd_ident_device_callback;         d->ata_status = ATA_STATUS_RDY|ATA_STATUS_DSC|ATA_STATUS_DRQ;         break;      case ATA_CMD_READ_SECTOR:         d->sect_remaining = d->sect_count;         if (!d->sect_remaining)            d->sect_remaining = 256;         ata_set_sect_pos(d);         disk_read_sector(d,d->sect_pos,d->data_buffer);         d->ata_cmd_callback = ata_cmd_read_callback;         d->ata_status = ATA_STATUS_RDY|ATA_STATUS_DSC|ATA_STATUS_DRQ;         break;      case ATA_CMD_WRITE_SECTOR:         d->sect_remaining = d->sect_count;         if (!d->sect_remaining)            d->sect_remaining = 256;         ata_set_sect_pos(d);         d->ata_cmd_callback = ata_cmd_write_callback;         d->ata_status = ATA_STATUS_RDY|ATA_STATUS_DSC|ATA_STATUS_DRQ;         break;      default:         vm_log(d->vm,d->dev.name,"unhandled ATA command 0x%2.2x\n",                (u_int)d->ata_cmd);   }}/* * dev_pcmcia_disk_access_0() */void *dev_pcmcia_disk_access_0(cpu_mips_t *cpu,struct vdevice *dev,                               m_uint32_t offset,u_int op_size,u_int op_type,                               m_uint64_t *data){   struct pcmcia_disk_data *d = dev->priv_data;   /* Compute the good internal offset */   offset = (offset >> 1) ^ 1;   #if DEBUG_ACCESS   if (op_type == MTS_READ) {      cpu_log(cpu,d->dev.name,              "reading offset 0x%5.5x at pc=0x%llx (size=%u)\n",              offset,cpu->pc,op_size);   } else {      cpu_log(cpu,d->dev.name,              "writing offset 0x%5.5x, data=0x%llx at pc=0x%llx (size=%u)\n",              offset,*data,cpu->pc,op_size);   }#endif   /* Card Information Structure */   if (offset < sizeof(cis_table)) {      if (op_type == MTS_READ)         *data = cis_table[offset];      return NULL;   }         switch(offset) {      case 0x102:     /* Pin Replacement Register */         if (op_type == MTS_READ)            *data = 0x22;         break;      case 0x80001:   /* Sector Count + Sector no */         if (op_type == MTS_READ) {            *data = (d->sect_no << 8) + d->sect_count;         } else {            d->sect_no    = *data >> 8;            d->sect_count = *data & 0xFF;         }         break;      case 0x80002:   /* Cylinder Low + Cylinder High */         if (op_type == MTS_READ) {            *data = (d->cyl_high << 8) + d->cyl_low;         } else {            d->cyl_high = *data >> 8;            d->cyl_low  = *data & 0xFF;         }         break;      case 0x80003:   /* Select Card/Head + Status/Command register */         if (op_type == MTS_READ)            *data = (d->ata_status << 8) + d->head;         else {            d->ata_cmd = *data >> 8;            d->head = *data;            ata_handle_cmd(d);         }                     break;      default:         /* Data buffer access ? */         if ((offset >= d->data_offset) &&              (offset < d->data_offset + (SECTOR_SIZE/2)))         {            if (op_type == MTS_READ) {               *data =  d->data_buffer[(d->data_pos << 1)];               *data += d->data_buffer[(d->data_pos << 1)+1] << 8;            } else {               d->data_buffer[(d->data_pos << 1)]   = *data & 0xFF;               d->data_buffer[(d->data_pos << 1)+1] = *data >> 8;            }                        d->data_pos++;            /* Buffer complete: call the callback function */            if (d->data_pos == (SECTOR_SIZE/2)) {               d->data_pos = 0;                              if (d->ata_cmd_callback)                  d->ata_cmd_callback(d);            }         }   }   return NULL;}/* * dev_pcmcia_disk_access_1() */void *dev_pcmcia_disk_access_1(cpu_mips_t *cpu,struct vdevice *dev,                               m_uint32_t offset,u_int op_size,u_int op_type,                               m_uint64_t *data){   struct pcmcia_disk_data *d = dev->priv_data;   /* Compute the good internal offset */   offset = (offset >> 1) ^ 1;   #if DEBUG_ACCESS   if (op_type == MTS_READ) {      cpu_log(cpu,d->dev.name,              "reading offset 0x%5.5x at pc=0x%llx (size=%u)\n",              offset,cpu->pc,op_size);   } else {      cpu_log(cpu,d->dev.name,              "writing offset 0x%5.5x, data=0x%llx at pc=0x%llx (size=%u)\n",              offset,*data,cpu->pc,op_size);   }#endif         switch(offset) {      case 0x02:   /* Sector Count + Sector no */         if (op_type == MTS_READ) {            *data = (d->sect_no << 8) + d->sect_count;         } else {            d->sect_no    = *data >> 8;            d->sect_count = *data & 0xFF;         }         break;      case 0x04:   /* Cylinder Low + Cylinder High */         if (op_type == MTS_READ) {            *data = (d->cyl_high << 8) + d->cyl_low;         } else {            d->cyl_high = *data >> 8;            d->cyl_low  = *data & 0xFF;         }         break;      case 0x06:   /* Select Card/Head + Status/Command register */         if (op_type == MTS_READ)            *data = (d->ata_status << 8) + d->head;         else {            d->ata_cmd = *data >> 8;            d->head = *data & 0xFF;            ata_handle_cmd(d);         }                     break;      case 0x08:         if (op_type == MTS_READ) {            *data =  d->data_buffer[(d->data_pos << 1)];            *data += d->data_buffer[(d->data_pos << 1)+1] << 8;         } else {            d->data_buffer[(d->data_pos << 1)]   = *data & 0xFF;            d->data_buffer[(d->data_pos << 1)+1] = *data >> 8;         }         d->data_pos++;         /* Buffer complete: call the callback function */         if (d->data_pos == (SECTOR_SIZE/2)) {            d->data_pos = 0;                           if (d->ata_cmd_callback)               d->ata_cmd_callback(d);         }         break;      case 0x0E:         break;   }   return NULL;}/* Shutdown a PCMCIA disk device */void dev_pcmcia_disk_shutdown(vm_instance_t *vm,struct pcmcia_disk_data *d){   if (d != NULL) {      /* Remove the device */      dev_remove(vm,&d->dev);      /* Close disk file */      if (d->fd != -1) close(d->fd);      /* Free filename */      free(d->filename);            /* Free the structure itself */      free(d);   }}/* Initialize a PCMCIA disk */vm_obj_t *dev_pcmcia_disk_init(vm_instance_t *vm,char *name,                               m_uint64_t paddr,m_uint32_t len,                               u_int disk_size,int mode){   struct pcmcia_disk_data *d;   m_uint32_t tot_sect;   /* allocate the private data structure */   if (!(d = malloc(sizeof(*d)))) {      fprintf(stderr,"PCMCIA: unable to create disk device '%s'.\n",name);      return NULL;   }   memset(d,0,sizeof(*d));   vm_object_init(&d->vm_obj);   d->vm = vm;   d->vm_obj.name = name;   d->vm_obj.data = d;   d->vm_obj.shutdown = (vm_shutdown_t)dev_pcmcia_disk_shutdown;   d->fd = -1;   if (!(d->filename = vm_build_filename(vm,name))) {      fprintf(stderr,"PCMCIA: unable to create filename.\n");      goto err_filename;   }   /* Data buffer offset in mapped memory */   d->data_offset = 0x80200;   d->ata_status  = ATA_STATUS_RDY|ATA_STATUS_DSC;   /* Compute the number of cylinders given a disk size in Mb */   tot_sect = ((m_uint64_t)disk_size * 1048576) / SECTOR_SIZE;   d->nr_heads = DISK_NR_HEADS;   d->sects_per_track = DISK_SECTS_PER_TRACK;   d->nr_cylinders = tot_sect / (d->nr_heads * d->sects_per_track);   vm_log(vm,name,"C/H/S settings = %u/%u/%u\n",          d->nr_cylinders,d->nr_heads,d->sects_per_track);   /* Create the disk file */   if (disk_create(d) == -1)      goto err_disk_create;   dev_init(&d->dev);   d->dev.name      = name;   d->dev.priv_data = d;   d->dev.phys_addr = paddr;   d->dev.phys_len  = len;   d->dev.flags     = VDEVICE_FLAG_CACHING;   if (mode == 0)      d->dev.handler = dev_pcmcia_disk_access_0;   else      d->dev.handler = dev_pcmcia_disk_access_1;   /* Map this device to the VM */   vm_bind_device(vm,&d->dev);   vm_object_add(vm,&d->vm_obj);   return(&d->vm_obj); err_disk_create:   free(d->filename); err_filename:   free(d);   return NULL;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -