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

📄 dev_gt.c

📁 思科路由器仿真器,用来仿7200系列得,可以在电脑上模拟路由器-Cisco router simulator, used to fake a 7200 series can be simulated
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * Cisco 7200 (Predator) simulation platform. * Copyright (c) 2005,2006 Christophe Fillot (cf@utc.fr) * * Galileo GT64010/GT64120A/GT96100A system controller. * * The DMA stuff is not complete, only "normal" transfers are working * (source and destination addresses incrementing). * * Also, these transfers are "instantaneous" from a CPU point-of-view: when * a channel is enabled, the transfer is immediately done. So, this is not  * very realistic. */#include <stdio.h>#include <stdlib.h>#include <string.h>#include "utils.h"#include "net.h"#include "mips64.h"#include "dynamips.h"#include "memory.h"#include "device.h"#include "net_io.h"#include "ptask.h"#include "dev_gt.h"/* Debugging flags */#define DEBUG_UNKNOWN   0#define DEBUG_DMA       0#define DEBUG_MII       0#define DEBUG_ETH_TX    0#define DEBUG_ETH_RX    0#define DEBUG_ETH_HASH  0/* PCI identification */#define PCI_VENDOR_GALILEO           0x11ab  /* Galileo Technology */#define PCI_PRODUCT_GALILEO_GT64010  0x0146  /* GT-64010 */#define PCI_PRODUCT_GALILEO_GT64011  0x4146  /* GT-64011 */#define PCI_PRODUCT_GALILEO_GT64120  0x4620  /* GT-64120 */#define PCI_PRODUCT_GALILEO_GT96100  0x9653  /* GT-96100 *//* === Global definitions === *//* Interrupt High Cause Register */#define GT_IHCR_ETH0_SUM     0x00000001#define GT_IHCR_ETH1_SUM     0x00000002#define GT_IHCR_SDMA_SUM     0x00000010/* Serial Cause Register */#define GT_SCR_ETH0_SUM      0x00000001#define GT_SCR_ETH1_SUM      0x00000002#define GT_SCR_SDMA_SUM      0x00000010/* === DMA definitions === */#define GT_DMA_CHANNELS   4#define GT_DMA_FLYBY_ENABLE  0x00000001  /* FlyBy Enable */  #define GT_DMA_FLYBY_RDWR    0x00000002  /* SDRAM Read/Write (FlyBy) */#define GT_DMA_SRC_DIR       0x0000000c  /* Source Direction */#define GT_DMA_DST_DIR       0x00000030  /* Destination Direction */#define GT_DMA_DATA_LIMIT    0x000001c0  /* Data Transfer Limit */#define GT_DMA_CHAIN_MODE    0x00000200  /* Chained Mode */#define GT_DMA_INT_MODE      0x00000400  /* Interrupt Mode */#define GT_DMA_TRANS_MODE    0x00000800  /* Transfer Mode */#define GT_DMA_CHAN_ENABLE   0x00001000  /* Channel Enable */#define GT_DMA_FETCH_NEXT    0x00002000  /* Fetch Next Record */#define GT_DMA_ACT_STATUS    0x00004000  /* DMA Activity Status */#define GT_DMA_SDA           0x00008000  /* Source/Destination Alignment */#define GT_DMA_MDREQ         0x00010000  /* Mask DMA Requests */#define GT_DMA_CDE           0x00020000  /* Close Descriptor Enable */#define GT_DMA_EOTE          0x00040000  /* End-of-Transfer (EOT) Enable */#define GT_DMA_EOTIE         0x00080000  /* EOT Interrupt Enable */#define GT_DMA_ABORT         0x00100000  /* Abort DMA Transfer */#define GT_DMA_SLP           0x00600000  /* Override Source Address */#define GT_DMA_DLP           0x01800000  /* Override Dest Address */#define GT_DMA_RLP           0x06000000  /* Override Record Address */#define GT_DMA_REQ_SRC       0x10000000  /* DMA Request Source *//* Galileo DMA channel */struct dma_channel {   m_uint32_t byte_count;   m_uint32_t src_addr;   m_uint32_t dst_addr;   m_uint32_t cdptr;   m_uint32_t nrptr;   m_uint32_t ctrl;};/* === Ethernet definitions === */#define GT_ETH_PORTS     2#define GT_MAX_PKT_SIZE  2048/* SMI register */#define GT_SMIR_DATA_MASK      0x0000FFFF#define GT_SMIR_PHYAD_MASK     0x001F0000    /* PHY Device Address */#define GT_SMIR_PHYAD_SHIFT    16#define GT_SMIR_REGAD_MASK     0x03e00000    /* PHY Device Register Address */#define GT_SMIR_REGAD_SHIFT    21#define GT_SMIR_OPCODE_MASK    0x04000000    /* Opcode (0: write, 1: read) */#define GT_SMIR_OPCODE_READ    0x04000000#define GT_SMIR_RVALID_FLAG    0x08000000    /* Read Valid */#define GT_SMIR_BUSY_FLAG      0x10000000    /* Busy: 1=op in progress *//* PCR: Port Configuration Register */#define GT_PCR_PM              0x00000001    /* Promiscuous mode */#define GT_PCR_RBM             0x00000002    /* Reject broadcast mode */#define GT_PCR_PBF             0x00000004    /* Pass bad frames */#define GT_PCR_EN              0x00000080    /* Port Enabled/Disabled */#define GT_PCR_LPBK            0x00000300    /* Loopback mode */#define GT_PCR_FC              0x00000400    /* Force collision */#define GT_PCR_HS              0x00001000    /* Hash size */#define GT_PCR_HM              0x00002000    /* Hash mode */#define GT_PCR_HDM             0x00004000    /* Hash default mode */#define GT_PCR_HD              0x00008000    /* Duplex Mode */#define GT_PCR_ISL             0x70000000    /* ISL enabled (0x06) */#define GT_PCR_ACCS            0x80000000    /* Accelerate Slot Time *//* PCXR: Port Configuration Extend Register */#define GT_PCXR_IGMP           0x00000001    /* IGMP packet capture */#define GT_PCXR_SPAN           0x00000002    /* BPDU packet capture */#define GT_PCXR_PAR            0x00000004    /* Partition Enable */#define GT_PCXR_PRIOTX         0x00000038    /* Priority weight for TX */#define GT_PCXR_PRIORX         0x000000C0    /* Priority weight for RX */#define GT_PCXR_PRIORX_OV      0x00000100    /* Prio RX override */#define GT_PCXR_DPLX_EN        0x00000200    /* Autoneg for Duplex */#define GT_PCXR_FCTL_EN        0x00000400    /* Autoneg for 802.3x */#define GT_PCXR_FLP            0x00000800    /* Force Link Pass */#define GT_PCXR_FCTL           0x00001000    /* Flow Control Mode */#define GT_PCXR_MFL            0x0000C000    /* Maximum Frame Length */#define GT_PCXR_MIB_CLR_MODE   0x00010000    /* MIB counters clear mode */#define GT_PCXR_SPEED          0x00040000    /* Port Speed */#define GT_PCXR_SPEED_EN       0x00080000    /* Autoneg for Speed */#define GT_PCXR_RMII_EN        0x00100000    /* RMII Enable */#define GT_PCXR_DSCP_EN        0x00200000    /* DSCP decoding enable *//* PCMR: Port Command Register */#define GT_PCMR_FJ             0x00008000    /* Force Jam / Flow Control *//* PSR: Port Status Register */#define GT_PSR_SPEED           0x00000001    /* Speed: 10/100 Mb/s (100=>1)*/#define GT_PSR_DUPLEX          0x00000002    /* Duplex (1: full) */#define GT_PSR_FCTL            0x00000004    /* Flow Control Mode */#define GT_PSR_LINK            0x00000008    /* Link Up/Down */#define GT_PSR_PAUSE           0x00000010    /* Flow-control disabled state */#define GT_PSR_TXLOW           0x00000020    /* TX Low priority status */#define GT_PSR_TXHIGH          0x00000040    /* TX High priority status */#define GT_PSR_TXINP           0x00000080    /* TX in Progress *//* SDCR: SDMA Configuration Register */#define GT_SDCR_RC             0x0000003c    /* Retransmit count */#define GT_SDCR_BLMR           0x00000040    /* Big/Little Endian RX mode */#define GT_SDCR_BLMT           0x00000080    /* Big/Litlle Endian TX mode */#define GT_SDCR_POVR           0x00000100    /* PCI override */#define GT_SDCR_RIFB           0x00000200    /* RX IRQ on frame boundary */#define GT_SDCR_BSZ            0x00003000    /* Burst size *//* SDCMR: SDMA Command Register */#define GT_SDCMR_ERD           0x00000080    /* Enable RX DMA */#define GT_SDCMR_AR            0x00008000    /* Abort Receive */#define GT_SDCMR_STDH          0x00010000    /* Stop TX High */#define GT_SDCMR_STDL          0x00020000    /* Stop TX Low */#define GT_SDCMR_TXDH          0x00800000    /* Start TX High */#define GT_SDCMR_TXDL          0x01000000    /* Start TX Low */#define GT_SDCMR_AT            0x80000000    /* Abort Transmit *//* ICR: Interrupt Cause Register */#define GT_ICR_RXBUF           0x00000001    /* RX Buffer returned to host */#define GT_ICR_TXBUFH          0x00000004    /* TX Buffer High */#define GT_ICR_TXBUFL          0x00000008    /* TX Buffer Low */#define GT_ICR_TXENDH          0x00000040    /* TX End High */#define GT_ICR_TXENDL          0x00000080    /* TX End Low */#define GT_ICR_RXERR           0x00000100    /* RX Error */#define GT_ICR_TXERRH          0x00000400    /* TX Error High */#define GT_ICR_TXERRL          0x00000800    /* TX Error Low */#define GT_ICR_RXOVR           0x00001000    /* RX Overrun */#define GT_ICR_TXUDR           0x00002000    /* TX Underrun */#define GT_ICR_RXBUFQ0         0x00010000    /* RX Buffer in Prio Queue 0 */#define GT_ICR_RXBUFQ1         0x00020000    /* RX Buffer in Prio Queue 1 */#define GT_ICR_RXBUFQ2         0x00040000    /* RX Buffer in Prio Queue 2 */#define GT_ICR_RXBUFQ3         0x00080000    /* RX Buffer in Prio Queue 3 */#define GT_ICR_RXERRQ0         0x00010000    /* RX Error in Prio Queue 0 */#define GT_ICR_RXERRQ1         0x00020000    /* RX Error in Prio Queue 1 */#define GT_ICR_RXERRQ2         0x00040000    /* RX Error in Prio Queue 2 */#define GT_ICR_RXERRQ3         0x00080000    /* RX Error in Prio Queue 3 */#define GT_ICR_MII_STC         0x10000000    /* MII PHY Status Change */#define GT_ICR_SMI_DONE        0x20000000    /* SMI Command Done */#define GT_ICR_INT_SUM         0x80000000    /* Ethernet Interrupt Summary */#define GT_ICR_MASK            0x7FFFFFFF/* Ethernet hash entry */#define GT_HTE_VALID           0x00000001    /* Valid entry */#define GT_HTE_SKIP            0x00000002    /* Skip entry in a chain */#define GT_HTE_RD              0x00000004    /* 0: Discard, 1: Receive */#define GT_HTE_ADDR_MASK       0x7fffffffffff8ULL#define GT_HTE_HOPNUM          12            /* Hash Table Hop Number */enum {   GT_HTLOOKUP_MISS,   GT_HTLOOKUP_MATCH,   GT_HTLOOKUP_HOP_EXCEEDED,};/* TX Descriptor */#define GT_TXDESC_OWN          0x80000000    /* Ownership */#define GT_TXDESC_AM           0x40000000    /* Auto-mode */#define GT_TXDESC_EI           0x00800000    /* Enable Interrupt */#define GT_TXDESC_GC           0x00400000    /* Generate CRC */#define GT_TXDESC_P            0x00040000    /* Padding */#define GT_TXDESC_F            0x00020000    /* First buffer of packet */#define GT_TXDESC_L            0x00010000    /* Last buffer of packet */#define GT_TXDESC_ES           0x00008000    /* Error Summary */#define GT_TXDESC_RC           0x00003c00    /* Retransmit Count */#define GT_TXDESC_COL          0x00000200    /* Collision */#define GT_TXDESC_RL           0x00000100    /* Retransmit Limit Error */#define GT_TXDESC_UR           0x00000040    /* Underrun Error */#define GT_TXDESC_LC           0x00000020    /* Late Collision Error */#define GT_TXDESC_BC_MASK      0xFFFF0000    /* Number of bytes to transmit */#define GT_TXDESC_BC_SHIFT     16/* RX Descriptor */#define GT_RXDESC_OWN          0x80000000    /* Ownership */#define GT_RXDESC_AM           0x40000000    /* Auto-mode */#define GT_RXDESC_EI           0x00800000    /* Enable Interrupt */#define GT_RXDESC_F            0x00020000    /* First buffer of packet */#define GT_RXDESC_L            0x00010000    /* Last buffer of packet */#define GT_RXDESC_ES           0x00008000    /* Error Summary */#define GT_RXDESC_IGMP         0x00004000    /* IGMP packet detected */#define GT_RXDESC_HE           0x00002000    /* Hash Table Expired */#define GT_RXDESC_M            0x00001000    /* Missed Frame */#define GT_RXDESC_FT           0x00000800    /* Frame Type (802.3/Ethernet) */#define GT_RXDESC_SF           0x00000100    /* Short Frame Error */#define GT_RXDESC_MFL          0x00000080    /* Maximum Frame Length Error */#define GT_RXDESC_OR           0x00000040    /* Overrun Error */#define GT_RXDESC_COL          0x00000010    /* Collision */#define GT_RXDESC_CE           0x00000001    /* CRC Error */#define GT_RXDESC_BC_MASK      0x0000FFFF    /* Byte count */#define GT_RXDESC_BS_MASK      0xFFFF0000    /* Buffer size */#define GT_RXDESC_BS_SHIFT     16/* RX/TX descriptor */struct eth_desc {   m_uint32_t buf_size;   m_uint32_t cmd_stat;   m_uint32_t next_ptr;   m_uint32_t buf_ptr;};/* Galileo Ethernet port */struct eth_port {   netio_desc_t *nio;   /* First and Current RX descriptors (4 queues) */   m_uint32_t rx_start[4],rx_current[4];   /* Current TX descriptors (2 queues) */   m_uint32_t tx_current[2];   /* Port registers */   m_uint32_t pcr,pcxr,pcmr,psr;      /* SDMA registers */   m_uint32_t sdcr,sdcmr;   /* Interrupt register */   m_uint32_t icr,imr;   /* Hash Table pointer */   m_uint32_t ht_addr;   /* Ethernet MIB counters */   m_uint32_t rx_bytes,tx_bytes,rx_frames,tx_frames;};/* Galileo GT64xxx/GT96xxx system controller */struct gt_data {   char *name;   vm_obj_t vm_obj;   struct vdevice dev;   struct pci_device *pci_dev;   vm_instance_t *vm;   struct pci_bus *bus[2];   struct dma_channel dma[GT_DMA_CHANNELS];   m_uint32_t int_cause_reg;   m_uint32_t int_mask_reg;   /* Ethernet ports (GT-96100) */   u_int eth_irq;   ptask_id_t eth_tx_tid;   struct eth_port eth_ports[GT_ETH_PORTS];   m_uint32_t smi_reg;   m_uint16_t mii_regs[32][32];};/* Log a GT message */#define GT_LOG(d,msg...) vm_log((d)->vm,(d)->name,msg)/* Update the interrupt status */static void gt_update_irq_status(struct gt_data *gt_data){   if (gt_data->pci_dev) {      if (gt_data->int_cause_reg & gt_data->int_mask_reg)         pci_dev_trigger_irq(gt_data->vm,gt_data->pci_dev);      else         pci_dev_clear_irq(gt_data->vm,gt_data->pci_dev);   }}/* Fetch a DMA record (chained mode) */static void gt_dma_fetch_rec(vm_instance_t *vm,struct dma_channel *channel){   m_uint32_t ptr; #if DEBUG_DMA   vm_log(vm,"GT_DMA","fetching record at address 0x%x\n",channel->nrptr);#endif   /* fetch the record from RAM */   ptr = channel->nrptr;   channel->byte_count = swap32(physmem_copy_u32_from_vm(vm,ptr));   channel->src_addr   = swap32(physmem_copy_u32_from_vm(vm,ptr+0x04));   channel->dst_addr   = swap32(physmem_copy_u32_from_vm(vm,ptr+0x08));   channel->nrptr      = swap32(physmem_copy_u32_from_vm(vm,ptr+0x0c));      /* clear the "fetch next record bit" */   channel->ctrl &= ~GT_DMA_FETCH_NEXT;}/* Handle control register of a DMA channel */static void gt_dma_handle_ctrl(struct gt_data *gt_data,int chan_id){   struct dma_channel *channel = &gt_data->dma[chan_id];   vm_instance_t *vm = gt_data->vm;   int done;   if (channel->ctrl & GT_DMA_FETCH_NEXT) {      if (channel->nrptr == 0) {         vm_log(vm,"GT_DMA","trying to load a NULL DMA record...\n");         return;      }      gt_dma_fetch_rec(vm,channel);   }   if (channel->ctrl & GT_DMA_CHAN_ENABLE)    {      do {         done = TRUE;#if DEBUG_DMA         vm_log(vm,"GT_DMA",                "starting transfer from 0x%x to 0x%x (size=%u bytes)\n",                channel->src_addr,channel->dst_addr,                channel->byte_count & 0xFFFF);#endif         physmem_dma_transfer(vm,channel->src_addr,channel->dst_addr,                              channel->byte_count & 0xFFFF);         /* chained mode */         if (!(channel->ctrl & GT_DMA_CHAIN_MODE)) {            if (channel->nrptr) {               gt_dma_fetch_rec(vm,channel);               done = FALSE;            }         }      }while(!done);#if DEBUG_DMA      vm_log(vm,"GT_DMA","finished transfer.\n");#endif      /* Trigger DMA interrupt */      gt_data->int_cause_reg |= 1 << (4 + chan_id);      gt_update_irq_status(gt_data);   }}#define DMA_REG(ch,reg_name) \   if (op_type == MTS_WRITE) \      gt_data->dma[ch].reg_name = swap32(*data); \   else \      *data = swap32(gt_data->dma[ch].reg_name);/* Handle a DMA channel */static int gt_dma_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 gt_data *gt_data = dev->priv_data;   switch(offset) {      /* DMA Source Address */      case 0x810: DMA_REG(0,src_addr); return(1);      case 0x814: DMA_REG(1,src_addr); return(1);      case 0x818: DMA_REG(2,src_addr); return(1);      case 0x81c: DMA_REG(3,src_addr); return(1);      /* DMA Destination Address */      case 0x820: DMA_REG(0,dst_addr); return(1);      case 0x824: DMA_REG(1,dst_addr); return(1);      case 0x828: DMA_REG(2,dst_addr); return(1);      case 0x82c: DMA_REG(3,dst_addr); return(1);      /* DMA Next Record Pointer */      case 0x830:         gt_data->dma[0].cdptr = *data;         DMA_REG(0,nrptr);         return(1);      case 0x834:         gt_data->dma[1].cdptr = *data;         DMA_REG(1,nrptr);         return(1);      case 0x838:         gt_data->dma[2].cdptr = *data;         DMA_REG(2,nrptr);         return(1);         case 0x83c:          gt_data->dma[3].cdptr = *data;         DMA_REG(3,nrptr);         return(1);      /* DMA Channel Control */      case 0x840:         DMA_REG(0,ctrl);         if (op_type == MTS_WRITE)             gt_dma_handle_ctrl(gt_data,0);         return(1);      case 0x844:         DMA_REG(1,ctrl);         if (op_type == MTS_WRITE)             gt_dma_handle_ctrl(gt_data,1);         return(1);      case 0x848:         DMA_REG(2,ctrl);         if (op_type == MTS_WRITE)             gt_dma_handle_ctrl(gt_data,2);         return(1);      case 0x84c:         DMA_REG(3,ctrl);         if (op_type == MTS_WRITE)             gt_dma_handle_ctrl(gt_data,3);         return(1);   }   return(0);}/* * dev_gt64010_access() */void *dev_gt64010_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 gt_data *gt_data = dev->priv_data;	   if (op_type == MTS_READ)      *data = 0;   if (gt_dma_access(cpu,dev,offset,op_size,op_type,data) != 0)      return NULL;   switch(offset) {      /* ===== DRAM Settings (completely faked, 128 Mb) ===== */      case 0x008:    /* ras10_low */         if (op_type == MTS_READ)            *data = swap32(0x000);         break;      case 0x010:    /* ras10_high */         if (op_type == MTS_READ)            *data = swap32(0x7F);         break;      case 0x018:    /* ras32_low */         if (op_type == MTS_READ)            *data = swap32(0x080);

⌨️ 快捷键说明

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