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

📄 dev_mpc860.c

📁 思科路由器仿真器,用来仿7200系列得,可以在电脑上模拟路由器
💻 C
📖 第 1 页 / 共 4 页
字号:
      case 0x02:         mpc860_fec_mii_read_access(d,phy,reg);         break;      default:         MPC_LOG(d,"FEC: unknown MII opcode %u\n",op);   }   /* MII access completed */   d->fec_ievent |= MPC860_IEVENT_MII;   mpc860_fec_update_irq_status(d);}/*  * FEC register access (0xE00 to 0xF84). */static int dev_mpc860_fec_access(struct mpc860_data *d,m_uint32_t offset,                                 u_int op_size,u_int op_type,m_uint64_t *data){      switch(offset) {      /* R_DES_START: Beginning of RxBD ring */      case 0xE10:         if (op_type == MTS_READ)            *data = d->fec_rdes_start;         else            d->fec_rdes_start = *data & 0xFFFFFFFC;         break;      /* X_DES_START: Beginning of TxBD ring */      case 0xE14:         if (op_type == MTS_READ)            *data = d->fec_xdes_start;         else            d->fec_xdes_start = *data & 0xFFFFFFFC;         break;      /* R_BUFF_SIZE: Receive Buffer Size */      case 0xE18:         if (op_type == MTS_READ)            *data = d->fec_rbuf_size;         else            d->fec_rbuf_size = *data & 0x7F0;         break;      /* ECNTRL */      case 0xE40:         if (op_type == MTS_READ) {            *data = d->fec_ecntrl;         } else {            if (*data & MPC860_ECNTRL_RESET)               d->fec_ecntrl = 0;            else {               if (!(*data & MPC860_ECNTRL_ETHER_EN)) {                  d->fec_xdes_current = d->fec_xdes_start;                  d->fec_rdes_current = d->fec_rdes_start;               }               d->fec_ecntrl = *data;            }         }         break;      /* IEVENT: Interrupt Event Register */      case 0xE44:         if (op_type == MTS_READ) {            *data = d->fec_ievent;         } else {            d->fec_ievent &= ~(*data);            mpc860_fec_update_irq_status(d);         }         break;      /* IMASK: Interrupt Mask Register */      case 0xE48:         if (op_type == MTS_READ) {            *data = d->fec_imask;         } else {            d->fec_imask = *data;            mpc860_fec_update_irq_status(d);         }         break;      /* IVEC: Interrupt Vector Register */      case 0xE4C:         if (op_type == MTS_READ)            *data = d->fec_ivec;         else            d->fec_ivec = *data;         break;      /* X_DES_ACTIVE: TxBD Active Register */      case 0xE54:         mpc860_fec_handle_tx_ring(d);         //printf("x_des_active set\n");         break;      /* MII_DATA */      case 0xE80:         if (op_type == MTS_READ) {            *data = d->fec_mii_data;         } else {            d->fec_mii_data = *data;            mpc860_fec_mii_access(d);         }         break;   }   return(0);}/* Set NIO for the Fast Ethernet Controller */int mpc860_fec_set_nio(struct mpc860_data *d,netio_desc_t *nio){   /* check that a NIO is not already bound */   if (!d || (d->fec_nio != NULL))      return(-1);   d->fec_nio = nio;   netio_rxl_add(nio,(netio_rx_handler_t)mpc860_fec_handle_rx_pkt,d,NULL);   return(0);}/* Unset NIO of the Fast Ethernet Controller */int mpc860_fec_unset_nio(struct mpc860_data *d){   if (!d)      return(-1);   if (d->fec_nio != NULL) {      netio_rxl_remove(d->fec_nio);      d->fec_nio = NULL;   }   return(0);}/* ======================================================================== */#define MPC860_CP_FOP(chan,op) (((chan) << 4) + (op))/* Execute a command sent through CP Command Register (CPCR) */static void mpc860_exec_cpcr(struct mpc860_data *d,m_uint32_t cpcr){   u_int channel,opcode,fop;   channel = (cpcr >> 4) & 0x0F;   opcode  = (cpcr >> 8) & 0x0F;   fop = MPC860_CP_FOP(channel,opcode);      switch(fop) {      /* SPI - Init RX and TX params */      case MPC860_CP_FOP(MPC860_CHAN_SPI_IDMA2_RT,0):         mpc860_spi_init_rx_tx_params(d);         break;      /* SPI - Init RX params */      case MPC860_CP_FOP(MPC860_CHAN_SPI_IDMA2_RT,1):         mpc860_spi_init_rx_params(d);         break;      /* SPI - Init TX params */      case MPC860_CP_FOP(MPC860_CHAN_SPI_IDMA2_RT,2):         mpc860_spi_init_tx_params(d);         break;      /* SCC1 - Init RX and TX params */      case MPC860_CP_FOP(MPC860_CHAN_SCC1,0):         mpc860_scc_init_rx_tx_params(d,0);         break;      /* SCC1 - Init RX params */      case MPC860_CP_FOP(MPC860_CHAN_SCC1,1):         mpc860_scc_init_rx_params(d,0);         break;      /* SCC1 - Init TX params */      case MPC860_CP_FOP(MPC860_CHAN_SCC1,2):         mpc860_scc_init_tx_params(d,0);         break;      /* SCC2 - Init RX and TX params */      case MPC860_CP_FOP(MPC860_CHAN_SCC2,0):         mpc860_scc_init_rx_tx_params(d,1);         break;      /* SCC2 - Init RX params */      case MPC860_CP_FOP(MPC860_CHAN_SCC2,1):         mpc860_scc_init_rx_params(d,1);         break;      /* SCC2 - Init TX params */      case MPC860_CP_FOP(MPC860_CHAN_SCC2,2):         mpc860_scc_init_tx_params(d,1);         break;      /* SCC3 - Init RX and TX params */      case MPC860_CP_FOP(MPC860_CHAN_SCC3,0):         mpc860_scc_init_rx_tx_params(d,2);         break;      /* SCC3 - Init RX params */      case MPC860_CP_FOP(MPC860_CHAN_SCC3,1):         mpc860_scc_init_rx_params(d,2);         break;      /* SCC3 - Init TX params */      case MPC860_CP_FOP(MPC860_CHAN_SCC3,2):         mpc860_scc_init_tx_params(d,2);         break;      /* SCC4 - Init RX and TX params */      case MPC860_CP_FOP(MPC860_CHAN_SCC4,0):         mpc860_scc_init_rx_tx_params(d,3);         break;      /* SCC4 - Init RX params */      case MPC860_CP_FOP(MPC860_CHAN_SCC4,1):         mpc860_scc_init_rx_params(d,3);         break;      /* SCC4 - Init TX params */      case MPC860_CP_FOP(MPC860_CHAN_SCC4,2):         mpc860_scc_init_tx_params(d,3);         break;      default:         MPC_LOG(d,"CPCR: unknown cmd: channel=0x%4.4x, opcode=0x%4.4x\n",                 channel,opcode);   }}/* * dev_mpc860_access() */void *dev_mpc860_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 mpc860_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 from offset 0x%x, pc=0x%llx (size=%u)\n",              offset,cpu_get_pc(cpu),op_size);   } else {      cpu_log(cpu,d->name,              "write to offset 0x%x, value=0x%llx, pc=0x%llx (size=%u)\n",              offset,*data,cpu_get_pc(cpu),op_size);   }#endif   /* Handle dual-port RAM access */   if ((offset >= MPC860_DPRAM_OFFSET) && (offset < MPC860_DPRAM_END))      return(d->dpram + (offset - MPC860_DPRAM_OFFSET));   /* Handle SCC channels */   if ((offset >= MPC860_REG_SCC_BASE) &&       (offset < (MPC860_REG_SCC_BASE + (4 * 0x20))))    {      dev_mpc860_scc_access(d,offset,op_size,op_type,data);      return NULL;   }            /* Handle Fast Ethernet Controller (FEC) registers */   if ((offset >= MPC860_REG_FEC_BASE) && (offset <= MPC860_REG_FEC_END))   {      dev_mpc860_fec_access(d,offset,op_size,op_type,data);      return NULL;   }   switch(offset) {      /* SWSR - Software Service Register (Watchdog) */      case MPC860_REG_SWSR:         break;      /* SIU Interrupt Pending Register */      case MPC860_REG_SIPEND:         if (op_type == MTS_READ)            *data = d->sipend;         break;      /* SIU Interrupt Mask Register */      case MPC860_REG_SIMASK:         if (op_type == MTS_READ) {            *data = d->simask;         } else {            d->simask = *data;            mpc860_update_irq_status(d);         }         break;      /*        * Cisco 2600:       *   Bit 30: 0=NM in slot 1       */      case MPC860_REG_PIPR:         if (op_type == MTS_READ)            *data = 0x3F00F600;         break;      /* PISCR - Periodic Interrupt Status and Control Register */      case MPC860_REG_PISCR:        if (op_type == MTS_WRITE) {           if (*data & 0x80) {              d->sipend &= ~0x40000000;              mpc860_update_irq_status(d);           }        }        break;      case MPC860_REG_TBSCR:         if (op_type == MTS_READ)            *data = 0x45;         break;      /* IDMA1 Status and Mask Registers */      case MPC860_REG_IDSR1:         if (op_type == MTS_READ) {            *data = d->idsr[0];         } else {            d->idsr[0] &= ~(*data);         }         break;      case MPC860_REG_IDMR1:         if (op_type == MTS_READ)            *data = d->idmr[0];         else            d->idmr[0] = *data;         break;      /* IDMA2 Status and Mask Registers */      case MPC860_REG_IDSR2:         if (op_type == MTS_READ)            *data = d->idsr[1];         else            d->idsr[1] &= ~(*data);         break;      case MPC860_REG_IDMR2:         if (op_type == MTS_READ)            *data = d->idmr[1];         else            d->idmr[1] = *data;         break;      /* CICR - CPM Interrupt Configuration Register */      case MPC860_REG_CICR:         if (op_type == MTS_READ)            *data = d->cicr;         else            d->cicr = *data;                  break;      /* CIPR - CPM Interrupt Pending Register */      case MPC860_REG_CIPR:         if (op_type == MTS_READ)            *data = d->cipr;         else {            d->cipr &= ~(*data);            mpc860_update_cpm_int_status(d);         }         break;      /* CIMR - CPM Interrupt Mask Register */      case MPC860_REG_CIMR:         if (op_type == MTS_READ)            *data = d->cimr;         else {            d->cimr = *data;            mpc860_update_cpm_int_status(d);         }         break;      /* PCSO - Port C Special Options Register */      case MPC860_REG_PCSO:         if (op_type == MTS_WRITE) {            if (*data & 0x01) {#if DEBUG_IDMA               MPC_LOG(d,"activating IDMA0\n");#endif               mpc860_idma_start_channel(d,0);            }         }         break;      /* PCDAT - Port C Data Register */      case MPC860_REG_PCDAT:         if (op_type == MTS_WRITE)            d->pcdat = *data;         else            *data = d->pcdat;         break;      /* PBDAT - Port B Data Register */      case MPC860_REG_PBDAT:         if (op_type == MTS_WRITE)            d->pbdat = *data;         else            *data = d->pbdat;         break;      /* CPCR - CP Command Register */      case MPC860_REG_CPCR:         if (op_type == MTS_WRITE)            mpc860_exec_cpcr(d,(m_uint32_t)(*data));         break;      /* SPCOM - SPI Command Register */      case MPC860_REG_SPCOM:         if ((op_type == MTS_WRITE) && (*data & MPC860_SPCOM_STR))            mpc860_spi_start_tx(d);         break;#if DEBUG_UNKNOWN      default:         if (op_type == MTS_READ) {            cpu_log(cpu,d->name,                    "read from unknown addr 0x%x, pc=0x%llx (size=%u)\n",                    offset,cpu_get_pc(cpu),op_size);         } else {            cpu_log(cpu,d->name,                    "write to addr 0x%x, value=0x%llx, pc=0x%llx (size=%u)\n",                    offset,*data,cpu_get_pc(cpu),op_size);         }#endif   }   return NULL;}/* Set IRQ pending status */void mpc860_set_pending_irq(struct mpc860_data *d,m_uint32_t val){   d->sipend |= 1 << val;   mpc860_update_irq_status(d);}/* Clear a pending IRQ */void mpc860_clear_pending_irq(struct mpc860_data *d,m_uint32_t val){   d->sipend &= ~(1 << val);   mpc860_update_irq_status(d);}/* Shutdown the MPC860 device */void dev_mpc860_shutdown(vm_instance_t *vm,struct mpc860_data *d){   if (d != NULL) {      /* Remove the device */      dev_remove(vm,&d->dev);      /* Free the structure itself */      free(d);   }}/* Create the MPC860 device */int dev_mpc860_init(vm_instance_t *vm,char *name,                    m_uint64_t paddr,m_uint32_t len){   struct mpc860_data *d;   if (!(d = malloc(sizeof(*d)))) {      fprintf(stderr,"mpc860: unable to create device data.\n");      return(-1);   }   memset(d,0,sizeof(*d));   d->name = name;   d->vm = vm;   vm_object_init(&d->vm_obj);   d->vm_obj.name = name;   d->vm_obj.data = d;   d->vm_obj.shutdown = (vm_shutdown_t)dev_mpc860_shutdown;   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.handler   = dev_mpc860_access;      /* Set the default SPI base address */   dpram_w16(d,MPC860_SPI_BASE_ADDR,MPC860_SPI_BASE);   /* Map this device to the VM */   vm_bind_device(vm,&d->dev);   vm_object_add(vm,&d->vm_obj);   return(0);}

⌨️ 快捷键说明

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