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

📄 dev_gt.c

📁 思科路由器仿真器,用来仿7200系列得,可以在电脑上模拟路由器
💻 C
📖 第 1 页 / 共 5 页
字号:
      case GT_MPSC_CHR10:         if (op_type == MTS_READ)            *data = channel->chr[9] | 0x20;         else            channel->chr[9] = *data;         break;      default:         /* unknown/unmanaged register */         return(FALSE);   }   return(TRUE);}/* Set NIO for a MPSC channel */int dev_gt96100_mpsc_set_nio(struct gt_data *d,u_int chan_id,netio_desc_t *nio){   struct mpsc_channel *channel;   if (chan_id >= GT_MPSC_CHANNELS)      return(-1);   channel = &d->mpsc[chan_id];   if (channel->nio != NULL)      return(-1);   channel->nio = nio;   netio_rxl_add(nio,(netio_rx_handler_t)gt_sdma_handle_rx_pkt,                 d,(void *)chan_id);   return(0);}/* Unset NIO for a MPSC channel */int dev_gt96100_mpsc_unset_nio(struct gt_data *d,u_int chan_id){      struct mpsc_channel *channel;   if (chan_id >= GT_MPSC_CHANNELS)      return(-1);   channel = &d->mpsc[chan_id];   if (channel->nio != NULL) {      netio_rxl_remove(channel->nio);      channel->nio = NULL;   }   return(0);}/* Set a VTTY for a MPSC channel */int dev_gt96100_mpsc_set_vtty(struct gt_data *d,u_int chan_id,vtty_t *vtty){   struct mpsc_channel *channel;   if (chan_id >= GT_MPSC_CHANNELS)      return(-1);   channel = &d->mpsc[chan_id];   if (channel->vtty != NULL)      return(-1);   channel->vtty = vtty;   return(0);}/* Unset a VTTY for a MPSC channel */int dev_gt96100_mpsc_unset_vtty(struct gt_data *d,u_int chan_id){      struct mpsc_channel *channel;   if (chan_id >= GT_MPSC_CHANNELS)      return(-1);   channel = &d->mpsc[chan_id];   if (channel->vtty != NULL) {      channel->vtty = NULL;   }   return(0);}/* ======================================================================== *//* Ethernet                                                                 *//* ======================================================================== *//* Trigger/clear Ethernet interrupt if one or both port have pending events */static void gt_eth_set_int_status(struct gt_data *d){   /* Compute Ether0 summary */   if (d->eth_ports[0].icr & GT_ICR_INT_SUM) {      d->ser_cause_reg |= GT_SCR_ETH0_SUM;      d->int_high_cause_reg |= GT_IHCR_ETH0_SUM;   } else {      d->ser_cause_reg &= ~GT_SCR_ETH0_SUM;      d->int_high_cause_reg &= ~GT_IHCR_ETH0_SUM;   }   /* Compute Ether1 summary */   if (d->eth_ports[1].icr & GT_ICR_INT_SUM) {      d->ser_cause_reg |= GT_SCR_ETH1_SUM;      d->int_high_cause_reg |= GT_IHCR_ETH1_SUM;   } else {      d->ser_cause_reg &= ~GT_SCR_ETH1_SUM;      d->int_high_cause_reg &= ~GT_IHCR_ETH1_SUM;   }   gt96k_update_irq_status(d);}/* Update the Ethernet port interrupt status */static void gt_eth_update_int_status(struct gt_data *d,struct eth_port *port){   if (port->icr & port->imr & GT_ICR_MASK) {      port->icr |= GT_ICR_INT_SUM;   } else {      port->icr &= ~GT_ICR_INT_SUM;   }   gt_eth_set_int_status(d);}/* Read a MII register */static m_uint32_t gt_mii_read(struct gt_data *d){   m_uint8_t port,reg;   m_uint32_t res = 0;   port = (d->smi_reg & GT_SMIR_PHYAD_MASK) >> GT_SMIR_PHYAD_SHIFT;   reg  = (d->smi_reg & GT_SMIR_REGAD_MASK) >> GT_SMIR_REGAD_SHIFT;#if DEBUG_MII   GT_LOG(d,"MII: port 0x%4.4x, reg 0x%2.2x: reading.\n",port,reg);#endif   if ((port < GT_ETH_PORTS) && (reg < 32)) {      res = d->mii_regs[port][reg];      switch(reg) {         case 0x00:            res &= ~0x8200; /* clear reset bit and autoneg restart */            break;         case 0x01:#if 0            if (d->ports[port].nio && bcm5600_mii_port_status(d,port))               d->mii_output = 0x782C;            else               d->mii_output = 0;#endif            res = 0x782c;            break;         case 0x02:            res = 0x40;            break;         case 0x03:            res = 0x61d4;            break;         case 0x04:            res = 0x1E1;            break;         case 0x05:            res = 0x41E1;            break;         default:            res = 0;      }   }   /* Mark the data as ready */   res |= GT_SMIR_RVALID_FLAG;   return(res);}/* Write a MII register */static void gt_mii_write(struct gt_data *d){   m_uint8_t port,reg;   m_uint16_t isolation;   port = (d->smi_reg & GT_SMIR_PHYAD_MASK) >> GT_SMIR_PHYAD_SHIFT;   reg  = (d->smi_reg & GT_SMIR_REGAD_MASK) >> GT_SMIR_REGAD_SHIFT;   if ((port < GT_ETH_PORTS) && (reg < 32))   {#if DEBUG_MII      GT_LOG(d,"MII: port 0x%4.4x, reg 0x%2.2x: writing 0x%4.4x\n",             port,reg,d->smi_reg & GT_SMIR_DATA_MASK);#endif      /* Check if PHY isolation status is changing */      if (reg == 0) {         isolation = (d->smi_reg ^ d->mii_regs[port][reg]) & 0x400;         if (isolation) {#if DEBUG_MII            GT_LOG(d,"MII: port 0x%4.4x: generating IRQ\n",port);#endif            d->eth_ports[port].icr |= GT_ICR_MII_STC;            gt_eth_update_int_status(d,&d->eth_ports[port]);         }      }      d->mii_regs[port][reg] = d->smi_reg & GT_SMIR_DATA_MASK;   }}/* Handle registers of Ethernet ports */static int gt_eth_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 gt_data *d = dev->priv_data;   struct eth_port *port = NULL;   u_int queue;   if ((offset < 0x80000) || (offset >= 0x90000))      return(FALSE);   /* Determine the Ethernet port */   if ((offset >= 0x84800) && (offset < 0x88800))      port = &d->eth_ports[0];   else if ((offset >= 0x88800) && (offset < 0x8c800))      port = &d->eth_ports[1];   switch(offset) {      /* SMI register */      case 0x80810:         if (op_type == MTS_WRITE) {            d->smi_reg = *data;            if (!(d->smi_reg & GT_SMIR_OPCODE_READ))               gt_mii_write(d);         } else {            *data = 0;            if (d->smi_reg & GT_SMIR_OPCODE_READ)               *data = gt_mii_read(d);         }         break;      /* ICR: Interrupt Cause Register */      case 0x84850:      case 0x88850:         if (op_type == MTS_READ) {            *data = port->icr;         } else {            port->icr &= *data;            gt_eth_update_int_status(d,port);         }         break;      /* IMR: Interrupt Mask Register */      case 0x84858:      case 0x88858:         if (op_type == MTS_READ) {            *data = port->imr;         } else {            port->imr = *data;            gt_eth_update_int_status(d,port);         }         break;      /* PCR: Port Configuration Register */      case 0x84800:      case 0x88800:         if (op_type == MTS_READ)            *data = port->pcr;         else            port->pcr = *data;         break;      /* PCXR: Port Configuration Extend Register */      case 0x84808:      case 0x88808:         if (op_type == MTS_READ) {            *data = port->pcxr;            *data |= GT_PCXR_SPEED;         } else            port->pcxr = *data;         break;               /* PCMR: Port Command Register */      case 0x84810:      case 0x88810:         if (op_type == MTS_READ)            *data = port->pcmr;         else            port->pcmr = *data;         break;      /* Port Status Register */      case 0x84818:      case 0x88818:         if (op_type == MTS_READ)            *data = 0x0F;         break;      /* First RX descriptor */      case 0x84880:      case 0x88880:      case 0x84884:      case 0x88884:      case 0x84888:      case 0x88888:      case 0x8488C:      case 0x8888C:         queue = (offset >> 2) & 0x03;         if (op_type == MTS_READ)            *data = port->rx_start[queue];         else            port->rx_start[queue] = *data;         break;      /* Current RX descriptor */      case 0x848A0:      case 0x888A0:      case 0x848A4:      case 0x888A4:      case 0x848A8:      case 0x888A8:      case 0x848AC:      case 0x888AC:         queue = (offset >> 2) & 0x03;         if (op_type == MTS_READ)            *data = port->rx_current[queue];         else            port->rx_current[queue] = *data;         break;      /* Current TX descriptor */      case 0x848E0:      case 0x888E0:      case 0x848E4:      case 0x888E4:         queue = (offset >> 2) & 0x01;         if (op_type == MTS_READ)            *data = port->tx_current[queue];         else            port->tx_current[queue] = *data;         break;      /* Hash Table Pointer */      case 0x84828:      case 0x88828:         if (op_type == MTS_READ)            *data = port->ht_addr;         else            port->ht_addr = *data;         break;      /* SDCR: SDMA Configuration Register */      case 0x84840:      case 0x88840:         if (op_type == MTS_READ)            *data = port->sdcr;         else            port->sdcr = *data;         break;      /* SDCMR: SDMA Command Register */      case 0x84848:      case 0x88848:         if (op_type == MTS_WRITE) {            /* Start RX DMA */            if (*data & GT_SDCMR_ERD) {               port->sdcmr |= GT_SDCMR_ERD;               port->sdcmr &= ~GT_SDCMR_AR;            }            /* Abort RX DMA */            if (*data & GT_SDCMR_AR)               port->sdcmr &= ~GT_SDCMR_ERD;            /* Start TX High */            if (*data & GT_SDCMR_TXDH) {               port->sdcmr |= GT_SDCMR_TXDH;               port->sdcmr &= ~GT_SDCMR_STDH;            }            /* Start TX Low */            if (*data & GT_SDCMR_TXDL) {               port->sdcmr |= GT_SDCMR_TXDL;               port->sdcmr &= ~GT_SDCMR_STDL;            }            /* Stop TX High */            if (*data & GT_SDCMR_STDH) {               port->sdcmr &= ~GT_SDCMR_TXDH;               port->sdcmr |= GT_SDCMR_STDH;            }            /* Stop TX Low */            if (*data & GT_SDCMR_STDL) {               port->sdcmr &= ~GT_SDCMR_TXDL;               port->sdcmr |= GT_SDCMR_STDL;            }         } else {            *data = port->sdcmr;         }         break;      case 0x85800:      case 0x89800:         if (op_type == MTS_READ) {            *data = port->rx_bytes;            port->rx_bytes = 0;         }         break;      case 0x85804:      case 0x89804:         if (op_type == MTS_READ) {            *data = port->tx_bytes;            port->tx_bytes = 0;         }         break;      case 0x85808:      case 0x89808:         if (op_type == MTS_READ) {            *data = port->rx_frames;            port->rx_frames = 0;         }         break;      case 0x8580C:      case 0x8980C:         if (op_type == MTS_READ) {            *data = port->tx_frames;            port->tx_frames = 0;         }         break;#if DEBUG_UNKNOWN      default:         if (op_type == MTS_READ) {            cpu_log(cpu,"GT96100/ETH",                    "read access to unknown register 0x%x, pc=0x%llx\n",                    offset,cpu_get_pc(cpu));         } else {            cpu_log(cpu,"GT96100/ETH",

⌨️ 快捷键说明

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