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

📄 dev_pa_a1.c

📁 思科路由器仿真器,用来仿7200系列得,可以在电脑上模拟路由器-Cisco router simulator, used to fake a 7200 series can be simulated
💻 C
📖 第 1 页 / 共 4 页
字号:
/*   * Cisco C7200 (Predator) Simulation Platform. * Copyright (C) 2005,2006 Christophe Fillot.  All rights reserved. * * PA-A1 ATM interface based on TI1570 and PLX 9060-ES. * * EEPROM types: *   - 0x17: PA-A1-OC3MM *   - 0x2C: PA-A1-OC3SM *   - 0x2D: PA-A1-OC3UTP * * IOS command: "sh controller atm2/0" *  * Manuals: * * Texas Instruments TNETA1570 ATM segmentation and reassembly device * with integrated 64-bit PCI-host interface * http://focus.ti.com/docs/prod/folders/print/tneta1570.html * * PLX 9060-ES * http://www.plxtech.com/products/io_accelerators/PCI9060/default.htm * * TODO:  *   - RX error handling and RX AAL5-related stuff *   - HEC and AAL5 CRC fields. * * Cell trains for faster NETIO communications ? */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <errno.h>#include "crc.h"#include "atm.h"#include "mips64.h"#include "dynamips.h"#include "memory.h"#include "device.h"#include "ptask.h"#include "dev_c7200.h"/* Debugging flags */#define DEBUG_ACCESS     0#define DEBUG_UNKNOWN    0#define DEBUG_TRANSMIT   0#define DEBUG_RECEIVE    0#define DEBUG_TX_DMA     0/* PCI vendor/product codes */#define TI1570_PCI_VENDOR_ID       0x104c#define TI1570_PCI_PRODUCT_ID      0xa001#define PLX_9060ES_PCI_VENDOR_ID   0x10b5#define PLX_9060ES_PCI_PRODUCT_ID  0x906e/* Number of buffers transmitted at each TX DMA ring scan pass */#define TI1570_TXDMA_PASS_COUNT  16/* TI1570 Internal Registers (p.58 of doc) */#define TI1570_REG_CONFIG          0x0000  /* Configuration registers */#define TI1570_REG_STATUS          0x0001  /* Status register */#define TI1570_REG_IMASK           0x0002  /* Interrupt-mask register */#define TI1570_REG_RGT_RAT         0x0003  /* RGT + RAT cycle-counter */#define TI1570_REG_RX_UNKNOWN      0x0004  /* RX Unknown Register */#define TI1570_REG_TX_CRING_SIZE   0x0005  /* TX Completion ring sizes */#define TI1570_REG_RX_CRING_SIZE   0x0006  /* RX Completion ring sizes */#define TI1570_REG_TX_PSR_SIZE     0x0007  /* TX Pkt-seg ring size + FIFO */#define TI1570_REG_HEC_AAL5_DISC   0x0008  /* HEC err + AAL5 CPCS discard */#define TI1570_REG_UNK_PROTO_CNT   0x0009  /* Unknown-protocols counter */#define TI1570_REG_RX_ATM_COUNT    0x000A  /* ATM-cells-received counter */#define TI1570_REG_TX_ATM_COUNT    0x000B  /* ATM-cells-tranmitted counter */#define TI1570_REG_TX_RX_FIFO      0x000C  /* TX/RX FIFO occupancy, VCI mask */#define TI1570_REG_SCHED_SIZE      0x000D  /* Scheduler Table size */#define TI1570_REG_SOFT_RESET      0x000E  /* Software Reset */#define TI1570_REG_TCR_WOI_ADDR    0x0080  /* TX Compl. Ring w/o IRQ addr. */#define TI1570_REG_TCR_WI_ADDR     0x0081  /* TX Compl. Ring w/ IRQ addr. */#define TI1570_REG_RCR_WOI_ADDR    0x0082  /* RX Compl. Ring w/o IRQ addr. */#define TI1570_REG_RCR_WI_ADDR     0x0083  /* RX Compl. Ring w/ IRQ addr. *//* TI1570 configuration register (p.59) */#define TI1570_CFG_EN_RAT          0x00000001  /* Reassembly Aging */#define TI1570_CFG_BP_SEL          0x00000002  /* IRQ on packet or buffer */#define TI1570_CFG_EN_RX           0x00000010  /* RX enable */#define TI1570_CFG_EN_TX           0x00000020  /* TX enable */#define TI1570_CFG_SMALL_MAP       0x00000040  /* Small map *//* TI1570 status register (p.61) */#define TI1570_STAT_CP_TX          0x00000001  /* Transmit completion ring */#define TI1570_STAT_RX_IRR         0x00000040  /* Receive unknown reg set */#define TI1570_STAT_CP_RX          0x00000080  /* Receive completion ring */#define TI1570_STAT_TX_FRZ         0x00000100  /* TX Freeze */#define TI1570_STAT_RX_FRZ         0x00000200  /* RX Freeze *//* Mask for RX/TX completion-ring sizes */#define TI1570_TCR_SIZE_MASK       0x00001FFF  /* TX compl. ring size mask */#define TI1570_RCR_SIZE_MASK       0x000003FF  /* RX compl. ring size mask *//* TI1750 TX packet segmentation ring register */#define TI1570_PSR_SIZE_MASK       0x000000FF  /* pkt-seg ring size *//* Total size of the TI1570 Control Memory */#define TI1570_CTRL_MEM_SIZE       0x100000/* Offsets of the TI1570 structures (p.66) */#define TI1570_TX_SCHED_OFFSET          0x0000  /* TX scheduler table */#define TI1570_INTERNAL_REGS_OFFSET     0x3200  /* Internal Registers */#define TI1570_FREE_BUFFERS_OFFSET      0x3800  /* Free-Buffer Pointers */#define TI1570_RX_DMA_PTR_TABLE_OFFSET  0x4000  /* RX VPI/VCI pointer table */#define TI1570_TX_DMA_TABLE_OFFSET      0x8000  /* TX DMA state table */#define TI1570_RX_DMA_TABLE_OFFSET      0x10000 /* RX DMA state table *//* TX scheduler table */#define TI1570_TX_SCHED_ENTRY_COUNT  6200#define TI1570_TX_SCHED_ENTRY_MASK   0x3FF   /* Entry mask */#define TI1570_TX_SCHED_E0_SHIFT     0       /* Shift for entry 0 */#define TI1570_TX_SCHED_E1_SHIFT     16      /* Shift for entry 0 *//* TX DMA state table */#define TI1570_TX_DMA_ACT            0x80000000  /* ACTive (word 0) */#define TI1570_TX_DMA_SOP            0x40000000  /* Start of Packet (SOP) */#define TI1570_TX_DMA_EOP            0x20000000  /* End of Packet (EOP) */#define TI1570_TX_DMA_ABORT          0x10000000  /* Abort */#define TI1570_TX_DMA_TCR_SELECT     0x02000000  /* TX comp. ring selection */#define TI1570_TX_DMA_AAL_TYPE_MASK  0x0C000000  /* AAL-type mask */#define TI1570_TX_DMA_AAL_TRWPTI     0x00000000  /* Transp. AAL w/ PTI set */#define TI1570_TX_DMA_AAL_AAL5       0x04000000  /* AAL5 */#define TI1570_TX_DMA_AAL_TRWOPTI    0x08000000  /* Transp. AAL w/o PTI set */#define TI1570_TX_DMA_OFFSET_MASK    0x00FF0000#define TI1570_TX_DMA_OFFSET_SHIFT   16#define TI1570_TX_DMA_DCOUNT_MASK    0x0000FFFF#define TI1570_TX_DMA_ON                 0x80000000   /* DMA state (word 3) */#define TI1570_TX_DMA_RING_OFFSET_MASK   0x3FFFFF00#define TI1570_TX_DMA_RING_OFFSET_SHIFT  8#define TI1570_TX_DMA_RING_INDEX_MASK    0x000000FF#define TI1570_TX_DMA_RING_AAL5_LEN_MASK 0x0000FFFFtypedef struct ti1570_tx_dma_entry ti1570_tx_dma_entry_t;struct ti1570_tx_dma_entry {   m_uint32_t ctrl_buf;      /* Ctrl, Buffer Offset, Buffer data-byte count */   m_uint32_t cb_addr;       /* Current Buffer Address */   m_uint32_t atm_hdr;       /* 4-byte ATM header */   m_uint32_t dma_state;     /* DMA state + Packet segmentation ring address */   m_uint32_t nb_addr;       /* Next Buffer address */   m_uint32_t sb_addr;       /* Start of Buffer address */   m_uint32_t aal5_crc;      /* Partial AAL5-transmit CRC */   m_uint32_t aal5_ctrl;     /* AAL5-control field and length field */};/* TX Packet-Segmentation Rings */#define TI1570_TX_RING_OWN       0x80000000   /* If set, packet is ready */#define TI1570_TX_RING_PTR_MASK  0x3FFFFFFF   /* Buffer pointer *//* TX Data Buffers */#define TI1570_TX_BUFFER_RDY     0x80000000   /* If set, buffer is ready */#define TI1570_TX_BUFFER_SOP     0x40000000   /* First buffer of packet */#define TI1570_TX_BUFFER_EOP     0x20000000   /* Last buffer of packet */#define TI1570_TX_BUFFER_ABORT   0x10000000   /* Abort */#define TI1570_TX_BUFFER_OFFSET_MASK   0x00FF0000#define TI1570_TX_BUFFER_OFFSET_SHIFT  16#define TI1570_TX_BUFFER_DCOUNT_MASK   0x0000FFFFtypedef struct ti1570_tx_buffer ti1570_tx_buffer_t;struct ti1570_tx_buffer {   m_uint32_t ctrl_buf;      /* Ctrl, Buffer offset, Buffer data-byte count */   m_uint32_t nb_addr;       /* Start-of-next buffer pointer */   m_uint32_t atm_hdr;       /* 4-byte ATM header */   m_uint32_t aal5_ctrl;     /* PCS-UU/CPI field (AAL5 control field) */};/* TX completion-ring */#define TI1570_TCR_OWN    0x80000000   /* OWNner bit */#define TI1570_TCR_ABORT  0x40000000   /* Abort *//* RX VPI/VCI DMA pointer table */#define TI1570_RX_VPI_ENABLE         0x80000000  /* VPI enabled ? */#define TI1570_RX_BASE_PTR_MASK      0x7FFF0000  /* Base pointer mask */#define TI1570_RX_BASE_PTR_SHIFT     16          /* Base pointer shift */#define TI1570_RX_VCI_RANGE_MASK     0x0000FFFF  /* Valid VCI range *//* RX DMA state table (p.36) */#define TI1570_RX_DMA_ACT            0x80000000  /* ACTive (word 0) */#define TI1570_RX_DMA_RCR_SELECT     0x20000000  /* RX comp. ring selection */#define TI1570_RX_DMA_WAIT_EOP       0x10000000  /* Wait for EOP */#define TI1570_RX_DMA_AAL_TYPE_MASK  0x0C000000  /* AAL-type mask */#define TI1570_RX_DMA_AAL_PTI        0x00000000  /* PTI based tr. AAL pkt */#define TI1570_RX_DMA_AAL_AAL5       0x04000000  /* AAL5 */#define TI1570_RX_DMA_AAL_CNT        0x08000000  /* Cnt based tr. AAL pkt */#define TI1570_RX_DMA_FIFO           0x02000000  /* FIFO used for free bufs */#define TI1570_RX_DMA_TR_CNT_MASK    0xFFFF0000  /* Cnt-based Tr-AAL */#define TI1570_RX_DMA_TR_CNT_SHIFT   16#define TI1570_RX_DMA_CB_LEN_MASK    0x0000FFFF  /* Current buffer length */#define TI1570_RX_DMA_ON             0x80000000  /* DMA state (word 6) */#define TI1570_RX_DMA_FILTER         0x40000000  /* Filter */#define TI1570_RX_DMA_FB_PTR_MASK    0x3FFFFFFF  /* Free-buffer ptr mask */#define TI1570_RX_DMA_FB_INDEX_MASK  0x000000FF  /* Index with Free-buf ring */typedef struct ti1570_rx_dma_entry ti1570_rx_dma_entry_t;struct ti1570_rx_dma_entry {   m_uint32_t ctrl;          /* Control field, EFCN cell cnt, pkt length */   m_uint32_t cb_addr;       /* Current Buffer Address */   m_uint32_t sb_addr;       /* Start of Buffer address */   m_uint32_t cb_len;        /* Transp-AAL pkt counter, current buf length */   m_uint32_t sp_ptr;        /* Start-of-packet pointer */   m_uint32_t aal5_crc;      /* Partial AAL5-receive CRC */   m_uint32_t fbr_entry;     /* Free-buffer ring-pointer table entry */   m_uint32_t timeout;       /* Timeout value, current timeout count */};/* RX free-buffer ring pointer table entry (p.39) */#define TI1570_RX_FBR_PTR_MASK       0xFFFFFFFC#define TI1570_RX_FBR_BS_MASK        0xFFFF0000  /* Buffer size mask */#define TI1570_RX_FBR_BS_SHIFT       16#define TI1570_RX_FBR_RS_MASK        0x0000FC00  /* Ring size mask */#define TI1570_RX_FBR_RS_SHIFT       10#define TI1570_RX_FBR_IDX_MASK       0x000003FF  /* Current index mask */typedef struct ti1570_rx_fbr_entry ti1570_rx_fbr_entry_t;struct ti1570_rx_fbr_entry {   m_uint32_t fbr_ptr;       /* RX free-buffer ring pointer */   m_uint32_t ring_size;     /* Ring size and buffer size */};/* RX buffer pointer (p.41) */#define TI1570_RX_BUFPTR_OWN    0x80000000   /* If set, buffer is ready */#define TI1570_RX_BUFPTR_MASK   0x3FFFFFFF   /* Buffer address mask *//* RX data buffer (p.42) */#define TI1570_RX_BUFFER_SOP    0x80000000   /* Start-of-Packet buffer */#define TI1570_RX_BUFFER_EOP    0x40000000   /* End-of-Packet buffer */typedef struct ti1570_rx_buffer ti1570_rx_buffer_t;struct ti1570_rx_buffer {   m_uint32_t reserved;      /* Reserved, not used by the TI1570 */   m_uint32_t ctrl;          /* Control field, Start of next buffer pointer */   m_uint32_t atm_hdr;       /* ATM header */   m_uint32_t user;          /* User-defined value */};/* Internal structure to hold free buffer info */typedef struct ti1570_rx_buf_holder ti1570_rx_buf_holder_t;struct ti1570_rx_buf_holder {   m_uint32_t buf_addr;   m_uint32_t buf_size;   ti1570_rx_buffer_t rx_buf;};/* RX completion ring entry */#define TI1570_RCR_PKT_OVFLW    0x80000000   /* Packet overflow (word 0) */#define TI1570_RCR_CRC_ERROR    0x40000000   /* CRC error */#define TI1570_RCR_BUF_STARV    0x20000000   /* Buffer starvation */#define TI1570_RCR_TIMEOUT      0x10000000   /* Reassembly timeout */#define TI1570_RCR_ABORT        0x08000000   /* Abort condition */#define TI1570_RCR_AAL5         0x04000000   /* AAL5 indicator */#define TI1570_RCR_VALID        0x80000000   /* Start-ptr valid (word 2) */#define TI1570_RCR_OWN          0x80000000   /* Buffer ready (word 4) */#define TI1570_RCR_ERROR        0x40000000   /* Error entry */typedef struct ti1570_rcr_entry ti1570_rcr_entry_t;struct ti1570_rcr_entry {   m_uint32_t atm_hdr;       /* ATM header */   m_uint32_t error;         /* Error Indicator + Congestion cell count */   m_uint32_t sp_addr;       /* Start of packet */   m_uint32_t aal5_trailer;  /* AAL5 trailer */   m_uint32_t fbr_entry;     /* Free-buffer ring-pointer table entry */   m_uint32_t res[3];        /* Reserved, not used by the TI1570 */};/* TI1570 Data */struct pa_a1_data {   char *name;   /* Control Memory pointer */   m_uint32_t *ctrl_mem_ptr;   /* TI1570 internal registers */   m_uint32_t *iregs;      /* TX FIFO cell */   m_uint8_t txfifo_cell[ATM_CELL_SIZE];   m_uint32_t txfifo_avail,txfifo_pos;   /* TX Scheduler table */   m_uint32_t *tx_sched_table;   /* TX DMA state table */   ti1570_tx_dma_entry_t *tx_dma_table;   /* TX/RX completion ring current position */   m_uint32_t tcr_wi_pos,tcr_woi_pos;   m_uint32_t rcr_wi_pos,rcr_woi_pos;   /* RX VPI/VCI DMA pointer table */   m_uint32_t *rx_vpi_vci_dma_table;   /* RX DMA state table */   ti1570_rx_dma_entry_t *rx_dma_table;   /* RX Free-buffer ring pointer table */   ti1570_rx_fbr_entry_t *rx_fbr_table;   /* Virtual device */   struct vdevice *dev;   /* PCI device information */   struct pci_device *pci_dev_ti,*pci_dev_plx;   /* Virtual machine */   vm_instance_t *vm;   /* NetIO descriptor */   netio_desc_t *nio;   /* TX ring scanner task id */   ptask_id_t tx_tid;};/* Log a TI1570 message */#define TI1570_LOG(d,msg...) vm_log((d)->vm,(d)->name,msg)/* Reset the TI1570 (forward declaration) */static void ti1570_reset(struct pa_a1_data *d,int clear_ctrl_mem);/* * dev_pa_a1_access() */void *dev_pa_a1_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 pa_a1_data *d = dev->priv_data;   if (op_type == MTS_READ)      *data = 0;#if DEBUG_ACCESS   if (op_type == MTS_READ) {      cpu_log(cpu,"TI1570","read  access to offset = 0x%x, pc = 0x%llx\n",              offset,cpu->pc);   } else {      cpu_log(cpu,"TI1570","write access to vaddr = 0x%x, pc = 0x%llx, "              "val = 0x%llx\n",offset,cpu->pc,*data);   }#endif      /* Specific cases */   switch(offset) {      case 0x3238:         TI1570_LOG(d,"reset issued.\n");         ti1570_reset(d,FALSE);         break;      case 0x18000c:         if (op_type == MTS_READ) {            *data = 0xa6;            return NULL;         }         break;   }   /* Control Memory access */   if (offset < TI1570_CTRL_MEM_SIZE) {      if (op_type == MTS_READ)         *data = d->ctrl_mem_ptr[offset >> 2];      else         d->ctrl_mem_ptr[offset >> 2] = *data;      return NULL;   }   /* Unknown offset */#if DEBUG_UNKNOWN   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;}/* Fetch a TX data buffer from host memory */static void ti1570_read_tx_buffer(struct pa_a1_data *d,m_uint32_t addr,                                  ti1570_tx_buffer_t *tx_buf){   physmem_copy_from_vm(d->vm,tx_buf,addr,sizeof(ti1570_tx_buffer_t));   /* byte-swapping */   tx_buf->ctrl_buf  = vmtoh32(tx_buf->ctrl_buf);   tx_buf->nb_addr   = vmtoh32(tx_buf->nb_addr);   tx_buf->atm_hdr   = vmtoh32(tx_buf->atm_hdr);   tx_buf->aal5_ctrl = vmtoh32(tx_buf->aal5_ctrl);}/* Acquire a TX buffer */static int ti1570_acquire_tx_buffer(struct pa_a1_data *d,                                       ti1570_tx_dma_entry_t *tde,                                    m_uint32_t buf_addr){   ti1570_tx_buffer_t tx_buf;   m_uint32_t buf_offset;#if DEBUG_TRANSMIT   TI1570_LOG(d,"ti1570_acquire_tx_buffer: acquiring buffer at address 0x%x\n",              buf_addr);

⌨️ 快捷键说明

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