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

📄 dev_i8254x.c

📁 思科路由器仿真器,用来仿7200系列得,可以在电脑上模拟路由器
💻 C
📖 第 1 页 / 共 3 页
字号:
{   switch(d->mii_state) {      case 0:   /* reset */         d->mii_phy = 0;         d->mii_reg = 0;         d->mii_data_pos = 15;         d->mii_data = 0;      case 1:   /* idle */         if (!d->mii_bit)            d->mii_state = 2;         else            d->mii_state = 1;         break;      case 2:   /* start */         d->mii_state = d->mii_bit ? 3 : 0;         break;      case 3:   /* opcode */         d->mii_state = d->mii_bit ? 4 : 5;         break;      case 4:   /* read: opcode "10" */         if (!d->mii_bit) {            d->mii_opcode = MII_OPCODE_READ;            d->mii_state = 6;         } else {            d->mii_state = 0;         }         break;      case 5:   /* write: opcode "01" */         if (d->mii_bit) {            d->mii_opcode = MII_OPCODE_WRITE;            d->mii_state = 6;         } else {            d->mii_state = 0;         }         break;      case 6 ... 10:   /* phy */         d->mii_phy <<= 1;         d->mii_phy |= d->mii_bit;         d->mii_state++;         break;      case 11 ... 15:  /* reg */         d->mii_reg <<= 1;         d->mii_reg |= d->mii_bit;         d->mii_state++;         break;      case 16 ... 17:  /* ta */         if (d->mii_opcode == MII_OPCODE_READ)            d->mii_state = 18;         else            d->mii_state++;         break;      case 18:         if (d->mii_opcode == MII_OPCODE_READ) {            d->mii_data = mii_reg_read(d);            d->mii_state++;         }      case 19 ... 35:         if (d->mii_opcode == MII_OPCODE_READ) {            d->mii_bit = (d->mii_data >> d->mii_data_pos) & 0x1;         } else {            d->mii_data |= d->mii_bit << d->mii_data_pos;         }         if (!d->mii_data_pos) {            if (d->mii_opcode == MII_OPCODE_WRITE)               mii_reg_write(d);            d->mii_state = 0;         } else {            d->mii_state++;         }                 d->mii_data_pos--;         break;      default:         printf("MII: impossible state %u!\n",d->mii_state);   }}/* Update the interrupt status */static inline void dev_i8254x_update_irq_status(struct i8254x_data *d){   if (d->icr & d->imr)      pci_dev_trigger_irq(d->vm,d->pci_dev);   else       pci_dev_clear_irq(d->vm,d->pci_dev);}/* Compute RX buffer size */static inline void dev_i8254x_set_rx_buf_size(struct i8254x_data *d){   m_uint32_t bsize;   bsize = (d->rctl & I8254X_RCTL_BSIZE_MASK) >> I8254X_RCTL_BSIZE_SHIFT;   if (!(d->rctl & I8254X_RCTL_BSEX)) {      /* Standard buffer sizes */      switch(bsize) {         case 0:            d->rx_buf_size = 2048;            break;         case 1:            d->rx_buf_size = 1024;            break;         case 2:            d->rx_buf_size = 512;            break;         case 3:            d->rx_buf_size = 256;            break;      }   } else {      /* Extended buffer sizes */      switch(bsize) {         case 0:            d->rx_buf_size = 0;  /* invalid */            break;         case 1:            d->rx_buf_size = 16384;            break;         case 2:            d->rx_buf_size = 8192;            break;         case 3:            d->rx_buf_size = 4096;            break;      }   }}/* * dev_i8254x_access() */void *dev_i8254x_access(cpu_gen_t *cpu,struct vdevice *dev,                        m_uint32_t offset,u_int op_size,u_int op_type,                        m_uint64_t *data){   struct i8254x_data *d = dev->priv_data;   if (op_type == MTS_READ)      *data = 0x0;#if DEBUG_ACCESS   if (op_type == MTS_READ) {      cpu_log(cpu,d->name,"read  access to offset=0x%x, pc=0x%llx, size=%u\n",              offset,cpu_get_pc(cpu),op_size);   } else {      cpu_log(cpu,d->name,"write access to offset=0x%x, pc=0x%llx, "              "val=0x%llx, size=%u\n",offset,cpu_get_pc(cpu),*data,op_size);   }#endif   LVG_LOCK(d);   switch(offset) {#if 0 /* TODO */      case 0x180:         if (op_type == MTS_READ)            *data = 0xFFFFFFFF; //0xDC004020; //1 << 31;         break;#endif      /* Link is Up and Full Duplex */      case I8254X_REG_STATUS:         if (op_type == MTS_READ)            *data = I8254X_STATUS_LU | I8254X_STATUS_FD;         break;      /* Device Control Register */      case I8254X_REG_CTRL:         if (op_type == MTS_WRITE)            d->ctrl = *data;         else            *data = d->ctrl;         break;      /* Extended Device Control Register */      case I8254X_REG_CTRLEXT:         if (op_type == MTS_WRITE) {            /* MDIO clock set ? */            if (!(d->ctrl_ext & I8254X_CTRLEXT_SDP6_DATA) &&                 (*data & I8254X_CTRLEXT_SDP6_DATA))              {               if (*data & I8254X_CTRLEXT_SDP7_IODIR)                  d->mii_bit = (*data & I8254X_CTRLEXT_SDP7_DATA) ? 1 : 0;               mii_access(d);            }            d->ctrl_ext = *data;         } else {            *data = d->ctrl_ext;            if (!(d->ctrl_ext & I8254X_CTRLEXT_SDP7_IODIR)) {               if (d->mii_bit)                  *data |= I8254X_CTRLEXT_SDP7_DATA;               else                  *data &= ~I8254X_CTRLEXT_SDP7_DATA;            }                    }         break;      /* XXX */      case I8254X_REG_MDIC:         if (op_type == MTS_READ)            *data = 1 << 28;         break;      /*        * Interrupt Cause Read Register.       *       * Notice: a read clears all interrupt bits.       */      case I8254X_REG_ICR:         if (op_type == MTS_READ) {            *data = d->icr;            d->icr = 0;            if (d->rx_irq_cnt > 0) {               d->icr |= I8254X_ICR_RXT0;               d->rx_irq_cnt--;            }            dev_i8254x_update_irq_status(d);         }         break;      /* Interrupt Cause Set Register */      case I8254X_REG_ICS:         if (op_type == MTS_WRITE) {            d->icr |= *data;            dev_i8254x_update_irq_status(d);         }         break;      /* Interrupt Mask Set/Read Register */      case I8254X_REG_IMS:         if (op_type == MTS_WRITE) {            d->imr |= *data;            dev_i8254x_update_irq_status(d);         } else {            *data = d->imr;         }         break;      /* Interrupt Mask Clear Register */      case I8254X_REG_IMC:         if (op_type == MTS_WRITE) {            d->imr &= ~(*data);            dev_i8254x_update_irq_status(d);         }         break;      /* Receive Control Register */      case I8254X_REG_RCTL:         if (op_type == MTS_READ) {            *data = d->rctl;         } else {            d->rctl = *data;            dev_i8254x_set_rx_buf_size(d);         }         break;      /* Transmit Control Register */      case I8254X_REG_TCTL:         if (op_type == MTS_READ)            *data = d->tctl;         else            d->tctl = *data;         break;      /* RX Descriptor Base Address Low */      case I8254X_REG_RDBAL:      case I82542_REG_RDBAL:         if (op_type == MTS_WRITE) {            d->rx_addr &= 0xFFFFFFFF00000000ULL;            d->rx_addr |= (m_uint32_t)(*data);         } else {            *data = (m_uint32_t)d->rx_addr;         }         break;      /* RX Descriptor Base Address High */      case I8254X_REG_RDBAH:      case I82542_REG_RDBAH:         if (op_type == MTS_WRITE) {            d->rx_addr &= 0x00000000FFFFFFFFULL;            d->rx_addr |= *data << 32;         } else {            *data = d->rx_addr >> 32;         }         break;      /* TX Descriptor Base Address Low */      case I8254X_REG_TDBAL:      case I82542_REG_TDBAL:         if (op_type == MTS_WRITE) {            d->tx_addr &= 0xFFFFFFFF00000000ULL;            d->tx_addr |= (m_uint32_t)(*data);         } else {            *data = (m_uint32_t)d->tx_addr;         }         break;      /* TX Descriptor Base Address High */      case I8254X_REG_TDBAH:      case I82542_REG_TDBAH:         if (op_type == MTS_WRITE) {            d->tx_addr &= 0x00000000FFFFFFFFULL;            d->tx_addr |= *data << 32;         } else {            *data = d->tx_addr >> 32;         }         break;            /* RX Descriptor Length */      case I8254X_REG_RDLEN:      case I82542_REG_RDLEN:         if (op_type == MTS_WRITE)            d->rdlen = *data & 0xFFF80;         else            *data = d->rdlen;         break;      /* TX Descriptor Length */      case I8254X_REG_TDLEN:      case I82542_REG_TDLEN:         if (op_type == MTS_WRITE)            d->tdlen = *data & 0xFFF80;         else            *data = d->tdlen;         break;               /* RX Descriptor Head */      case I82542_REG_RDH:      case I8254X_REG_RDH:         if (op_type == MTS_WRITE)            d->rdh = *data & 0xFFFF;         else            *data = d->rdh;         break;      /* RX Descriptor Tail */      case I8254X_REG_RDT:      case I82542_REG_RDT:         if (op_type == MTS_WRITE)            d->rdt = *data & 0xFFFF;         else            *data = d->rdt;         break;      /* TX Descriptor Head */      case I82542_REG_TDH:      case I8254X_REG_TDH:         if (op_type == MTS_WRITE)            d->tdh = *data & 0xFFFF;         else            *data = d->tdh;         break;      /* TX Descriptor Tail */      case I82542_REG_TDT:      case I8254X_REG_TDT:         if (op_type == MTS_WRITE)            d->tdt = *data & 0xFFFF;         else            *data = d->tdt;         break;      /* Flow Control Address Low */      case I8254X_REG_FCAL:         if (op_type == MTS_WRITE)            d->fcal = *data;

⌨️ 快捷键说明

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