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

📄 dev_c7200_pos.c

📁 思科路由器仿真器,用来仿7200系列得,可以在电脑上模拟路由器
💻 C
📖 第 1 页 / 共 2 页
字号:
/*   * Cisco router Simulation Platform. * Copyright (c) 2005-2007 Christophe Fillot.  All rights reserved. * * EEPROM types: *   - 0x95: PA-POS-OC3SMI *   - 0x96: PA-POS-OC3MM * * Just an experimentation (I don't have any PA-POS-OC3). */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <errno.h>#include <pthread.h>#include <assert.h>#include "cpu.h"#include "vm.h"#include "dynamips.h"#include "memory.h"#include "device.h"#include "net.h"#include "net_io.h"#include "ptask.h"#include "dev_c7200.h"#include "dev_plx.h"/* Debugging flags */#define DEBUG_ACCESS    0#define DEBUG_UNKNOWN   0#define DEBUG_TRANSMIT  0#define DEBUG_RECEIVE   0/* PCI vendor/product codes */#define POS_OC3_PCI_VENDOR_ID    0x10b5#define POS_OC3_PCI_PRODUCT_ID   0x9060/* Maximum packet size */#define POS_OC3_MAX_PKT_SIZE  8192/* RX descriptors */#define POS_OC3_RXDESC_OWN        0x80000000  /* Ownership */#define POS_OC3_RXDESC_WRAP       0x40000000  /* Wrap ring */#define POS_OC3_RXDESC_CONT       0x08000000  /* Packet continues */#define POS_OC3_RXDESC_LEN_MASK   0x1fff/* TX descriptors */#define POS_OC3_TXDESC_OWN        0x80000000  /* Ownership */#define POS_OC3_TXDESC_WRAP       0x40000000  /* Wrap ring */#define POS_OC3_TXDESC_CONT       0x08000000  /* Packet continues */#define POS_OC3_TXDESC_LEN_MASK   0x1fff/* RX Descriptor */struct rx_desc {   m_uint32_t rdes[2];};/* TX Descriptor */struct tx_desc {   m_uint32_t tdes[2];};/* PA-POS-OC3 Data */struct pos_oc3_data {   char *name;   /* IRQ clearing count */   u_int irq_clearing_count;   /* Control register #1 */   m_uint16_t ctrl_reg1;   /* CRC size */   u_int crc_size;   /* physical addresses for start and end of RX/TX rings */   m_uint32_t rx_start,rx_end,tx_start,tx_end;     /* physical addresses of current RX and TX descriptors */   m_uint32_t rx_current,tx_current;   /* Virtual machine */   vm_instance_t *vm;   /* Virtual devices */   char *rx_name,*tx_name,*cs_name;   vm_obj_t *rx_obj,*tx_obj,*cs_obj;   struct vdevice rx_dev,tx_dev,cs_dev;   /* PCI device information */   struct vdevice dev;   struct pci_device *pci_dev;   /* NetIO descriptor */   netio_desc_t *nio;   /* TX ring scanner task id */   ptask_id_t tx_tid;};/* Log a PA-POS-OC3 message */#define POS_LOG(d,msg...) vm_log((d)->vm,(d)->name,msg)/* * pos_access() */static void *dev_pos_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 pos_oc3_data *d = dev->priv_data;   if (op_type == MTS_READ)      *data = 0;#if DEBUG_ACCESS   if (op_type == MTS_READ) {      cpu_log(cpu,d->name,"read  access to offset = 0x%x, pc = 0x%llx\n",              offset,cpu_get_pc(cpu));   } else {      if (offset != 0x404)         cpu_log(cpu,d->name,"write access to vaddr = 0x%x, pc = 0x%llx, "                 "val = 0x%llx\n",offset,cpu_get_pc(cpu),*data);   }#endif   switch(offset) {      case 0x404:         if (op_type == MTS_READ)            *data = 0xFFFFFFFF;         break;      case 0x406:         if (op_type == MTS_READ)            *data = 0xFFFFFFFF;         break;      case 0x407:         if (op_type == MTS_READ)            *data = 0xFFFFFFFF;         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 unknown addr 0x%x, value=0x%llx, "                    "pc=0x%llx (size=%u)\n",                    offset,*data,cpu_get_pc(cpu),op_size);         }#endif   }   return NULL;}/* * pos_rx_access() */static void *dev_pos_rx_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 pos_oc3_data *d = dev->priv_data;   if (op_type == MTS_READ)      *data = 0;#if DEBUG_ACCESS   if (op_type == MTS_READ) {      cpu_log(cpu,d->name,"read  access to offset = 0x%x, pc = 0x%llx\n",              offset,cpu_get_pc(cpu));   } else {      cpu_log(cpu,d->name,"write access to vaddr = 0x%x, pc = 0x%llx, "              "val = 0x%llx\n",offset,cpu_get_pc(cpu),*data);   }#endif   switch(offset) {      case 0x04:         if (op_type == MTS_READ)            *data = d->rx_start;         else            d->rx_start = *data;         break;      case 0x08:         if (op_type == MTS_READ)            *data = d->rx_current;         else            d->rx_current = *data;         break;#if DEBUG_UNKNOWN      default:         if (op_type == MTS_READ) {            cpu_log(cpu,d->rx_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->rx_name,                    "write to unknown addr 0x%x, value=0x%llx, "                    "pc=0x%llx (size=%u)\n",                    offset,*data,cpu_get_pc(cpu),op_size);         }#endif   }   return NULL;}/* * pos_tx_access() */static void *dev_pos_tx_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 pos_oc3_data *d = dev->priv_data;   if (op_type == MTS_READ)      *data = 0;#if DEBUG_ACCESS   if (op_type == MTS_READ) {      cpu_log(cpu,d->tx_name,"read  access to offset = 0x%x, pc = 0x%llx\n",              offset,cpu_get_pc(cpu));   } else {      cpu_log(cpu,d->tx_name,"write access to vaddr = 0x%x, pc = 0x%llx, "              "val = 0x%llx\n",offset,cpu_get_pc(cpu),*data);   }#endif   switch(offset) {     case 0x04:         if (op_type == MTS_READ)            *data = d->tx_start;         else            d->tx_start = *data;         break;      case 0x08:         if (op_type == MTS_READ)            *data = d->tx_current;         else            d->tx_current = *data;         break;#if DEBUG_UNKNOWN      default:         if (op_type == MTS_READ) {            cpu_log(cpu,d->tx_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->tx_name,                    "write to unknown addr 0x%x, value=0x%llx, "                    "pc=0x%llx (size=%u)\n",                    offset,*data,cpu_get_pc(cpu),op_size);         }#endif   }   return NULL;}/* * pos_cs_access() */static void *dev_pos_cs_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 pos_oc3_data *d = dev->priv_data;   if (op_type == MTS_READ)      *data = 0;#if DEBUG_ACCESS   if (op_type == MTS_READ) {      cpu_log(cpu,d->cs_name,"read  access to offset = 0x%x, pc = 0x%llx\n",              offset,cpu_get_pc(cpu));   } else {      cpu_log(cpu,d->cs_name,"write access to vaddr = 0x%x, pc = 0x%llx, "              "val = 0x%llx\n",offset,cpu_get_pc(cpu),*data);   }#endif   switch(offset) {      case 0x300000:      case 0x300004:      case 0x30001c:         if (op_type == MTS_READ) {            *data = 0x00000FFF;            /* Add a delay before clearing the IRQ */            if (++d->irq_clearing_count == 20) {               pci_dev_clear_irq(d->vm,d->pci_dev);               d->irq_clearing_count = 0;            }         }              break;      case 0x300008:         if (op_type == MTS_READ)            *data = 0x000007F;               break;      case 0x300028:         if (op_type == MTS_READ) {            *data = d->ctrl_reg1;         } else {            d->ctrl_reg1 = *data;            switch(*data) {               case 0x06:                  d->crc_size = 2;                  break;               case 0x07:                  d->crc_size = 4;                  break;               default:                  d->crc_size = 2;                  cpu_log(cpu,d->cs_name,                          "unknown value 0x%4.4llx written in ctrl_reg1\n",                          *data);            }            cpu_log(cpu,d->cs_name,"CRC size set to 0x%4.4x\n",d->crc_size);         }         break;#if DEBUG_UNKNOWN      default:         if (op_type == MTS_READ) {            cpu_log(cpu,d->cs_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->cs_name,                    "write to unknown addr 0x%x, value=0x%llx, "                    "pc=0x%llx (size=%u)\n",                    offset,*data,cpu_get_pc(cpu),op_size);         }#endif   }   return NULL;}/* * Get the address of the next RX descriptor. */static m_uint32_t rxdesc_get_next(struct pos_oc3_data *d,m_uint32_t rxd_addr,                                  struct rx_desc *rxd){   m_uint32_t nrxd_addr;   if (rxd->rdes[0] & POS_OC3_RXDESC_WRAP)      nrxd_addr = d->rx_start;   else      nrxd_addr = rxd_addr + sizeof(struct rx_desc);   return(nrxd_addr);}/* Read an RX descriptor */static void rxdesc_read(struct pos_oc3_data *d,m_uint32_t rxd_addr,                        struct rx_desc *rxd){#if DEBUG_RECEIVE   POS_LOG(d,"reading RX descriptor at address 0x%x\n",rxd_addr);#endif   /* get the next descriptor from VM physical RAM */   physmem_copy_from_vm(d->vm,rxd,rxd_addr,sizeof(struct rx_desc));   /* byte-swapping */   rxd->rdes[0] = vmtoh32(rxd->rdes[0]);   rxd->rdes[1] = vmtoh32(rxd->rdes[1]);}/*  * Try to acquire the specified RX descriptor. Returns TRUE if we have it. * It assumes that the byte-swapping is done. */static inline int rxdesc_acquire(m_uint32_t rdes0){   return(rdes0 & POS_OC3_RXDESC_OWN);}/* Put a packet in buffer of a descriptor */static ssize_t rxdesc_put_pkt(struct pos_oc3_data *d,struct rx_desc *rxd,                              u_char **pkt,ssize_t *pkt_len){   ssize_t len,cp_len;   len = rxd->rdes[0] & POS_OC3_RXDESC_LEN_MASK;   /* compute the data length to copy */   cp_len = m_min(len,*pkt_len);#if DEBUG_RECEIVE

⌨️ 快捷键说明

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