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

📄 dev_c7200_pos.c

📁 思科路由器仿真器,用来仿7200系列得,可以在电脑上模拟路由器-Cisco router simulator, used to fake a 7200 series can be simulated
💻 C
📖 第 1 页 / 共 2 页
字号:
/*   * Cisco C7200 (Predator) Simulation Platform. * Copyright (C) 2005-2006 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). It basically works, * on NPE-400. There is something strange with the buffer addresses in TX ring, * preventing this driver working with platforms using SRAM. */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <errno.h>#include <pthread.h>#include <assert.h>#include "mips64.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   1#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#define POS_OC3_TXDESC_ADDR_MASK  0x3fffffff  /* Buffer address (?) *//* 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;   /* 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_mips_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->pc);   } else {      if (offset != 0x404)         cpu_log(cpu,d->name,"write access to vaddr = 0x%x, pc = 0x%llx, "                 "val = 0x%llx\n",offset,cpu->pc,*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->pc,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->pc,op_size);         }#endif   }   return NULL;}/* * pos_rx_access() */static void *dev_pos_rx_access(cpu_mips_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->pc);   } else {      cpu_log(cpu,d->name,"write access to vaddr = 0x%x, pc = 0x%llx, "              "val = 0x%llx\n",offset,cpu->pc,*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->pc,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->pc,op_size);         }#endif   }   return NULL;}/* * pos_tx_access() */static void *dev_pos_tx_access(cpu_mips_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->pc);   } else {      cpu_log(cpu,d->tx_name,"write access to vaddr = 0x%x, pc = 0x%llx, "              "val = 0x%llx\n",offset,cpu->pc,*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->pc,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->pc,op_size);         }#endif   }   return NULL;}/* * pos_cs_access() */static void *dev_pos_cs_access(cpu_mips_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->pc);   } else {      cpu_log(cpu,d->cs_name,"write access to vaddr = 0x%x, pc = 0x%llx, "              "val = 0x%llx\n",offset,cpu->pc,*data);   }#endif   switch(offset) {      case 0x300000:      case 0x300004:      case 0x30001c:         if (op_type == MTS_READ)            *data = 0x00000FFF;                  break;      case 0x300008:         if (op_type == MTS_READ)            *data = 0x000007F;               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->pc,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->pc,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   POS_LOG(d,"copying %d bytes at 0x%x\n",cp_len,rxd->rdes[1]);#endif         /* copy packet data to the VM physical RAM */   physmem_copy_to_vm(d->vm,*pkt,rxd->rdes[1],cp_len);         *pkt += cp_len;   *pkt_len -= cp_len;   return(cp_len);}/* * Put a packet in the RX ring. */static void dev_pos_oc3_receive_pkt(struct pos_oc3_data *d,                                    u_char *pkt,ssize_t pkt_len){   m_uint32_t rx_start,rxdn_addr,rxdn_rdes0;   struct rx_desc rxd0,rxdn,*rxdc;   ssize_t cp_len,tot_len = pkt_len;   u_char *pkt_ptr = pkt;

⌨️ 快捷键说明

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