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

📄 dev_mpc860.c

📁 思科路由器仿真器,用来仿7200系列得,可以在电脑上模拟路由器
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * Cisco router simulation platform. * Copyright (c) 2005,2006 Christophe Fillot (cf@utc.fr) * * MPC860 internal devices. */#include <stdio.h>#include <stdlib.h>#include <string.h>#include "utils.h"#include "net.h"#include "cpu.h"#include "vm.h"#include "dynamips.h"#include "memory.h"#include "device.h"#include "net_io.h"#include "dev_mpc860.h"/* Debugging flags */#define DEBUG_ACCESS    0#define DEBUG_UNKNOWN   1#define DEBUG_IDMA      0#define DEBUG_SPI       0#define DEBUG_SCC       0#define DEBUG_FEC       1#define MPC860_TXRING_PASS_COUNT  16/* Dual-Port RAM */#define MPC860_DPRAM_OFFSET   0x2000#define MPC860_DPRAM_SIZE     0x2000#define MPC860_DPRAM_END      (MPC860_DPRAM_OFFSET + MPC860_DPRAM_SIZE)/* MPC860 registers */#define MPC860_REG_SWSR       0x000e  /* Software Service Register */#define MPC860_REG_SIPEND     0x0010  /* SIU Interrupt Pending Register */#define MPC860_REG_SIMASK     0x0014  /* SIU Interrupt Mask Register */#define MPC860_REG_PIPR       0x00f0  /* PCMCIA Interface Input Pins Reg. */#define MPC860_REG_TBSCR      0x0200  /* Timebase Status and Control Reg. */#define MPC860_REG_PISCR      0x0240  /* Periodic Int. Status and Ctrl Reg. */#define MPC860_REG_IDSR1      0x0910  /* IDMA1 Status Register */#define MPC860_REG_IDMR1      0x0914  /* IDMA1 Mask Register */#define MPC860_REG_IDSR2      0x0918  /* IDMA2 Status Register */#define MPC860_REG_IDMR2      0x091c  /* IDMA2 Mask Register */#define MPC860_REG_CICR       0x0940  /* CPM Int Config Register */#define MPC860_REG_CIPR       0x0944  /* CPM Int Pending Register */#define MPC860_REG_CIMR       0x0948  /* CPM Int Mask Register */#define MPC860_REG_PCSO       0x0964  /* Port C Special Options Register */#define MPC860_REG_PCDAT      0x0966  /* Port C Data Register */#define MPC860_REG_CPCR       0x09c0  /* CP Command Register */#define MPC860_REG_SCC_BASE   0x0a00  /* SCC register base */#define MPC860_REG_SPMODE     0x0aa0  /* SPI Mode Register */#define MPC860_REG_SPIE       0x0aa6  /* SPI Event Register */#define MPC860_REG_SPIM       0x0aaa  /* SPI Mask Register */#define MPC860_REG_SPCOM      0x0aad  /* SPI Command Register */#define MPC860_REG_PBDAT      0x0ac4  /* Port B Data Register */#define MPC860_REG_FEC_BASE   0x0e00  /* FEC register base */#define MPC860_REG_FEC_END    0x0f84  /* FEC register end *//* ======================================================================== *//* CICR (CPM Interrupt Config Register) */#define MPC860_CICR_IRL_MASK    0x0000E000  /* Interrupt Level */#define MPC860_CICR_IRL_SHIFT   13#define MPC860_CICR_IEN         0x00000080  /* Interrupt Enable *//* CIPR (CPM Interrupt Pending Register) */#define MPC860_CIPR_PC15      0x80000000#define MPC860_CIPR_SCC1      0x40000000#define MPC860_CIPR_SCC2      0x20000000#define MPC860_CIPR_SCC3      0x10000000#define MPC860_CIPR_SCC4      0x08000000#define MPC860_CIPR_PC14      0x04000000#define MPC860_CIPR_TIMER1    0x02000000#define MPC860_CIPR_PC13      0x01000000#define MPC860_CIPR_PC12      0x00800000#define MPC860_CIPR_SDMA      0x00400000#define MPC860_CIPR_IDMA1     0x00200000#define MPC860_CIPR_IDMA2     0x00100000#define MPC860_CIPR_TIMER2    0x00040000#define MPC860_CIPR_RTT       0x00020000#define MPC860_CIPR_I2C       0x00010000#define MPC860_CIPR_PC11      0x00008000#define MPC860_CIPR_PC10      0x00004000#define MPC860_CIPR_TIMER3    0x00001000#define MPC860_CIPR_PC9       0x00000800#define MPC860_CIPR_PC8       0x00000400#define MPC860_CIPR_PC7       0x00000200#define MPC860_CIPR_TIMER4    0x00000080#define MPC860_CIPR_PC6       0x00000040#define MPC860_CIPR_SPI       0x00000020#define MPC860_CIPR_SMC1      0x00000010#define MPC860_CIPR_SMC2      0x00000008#define MPC860_CIPR_PC5       0x00000004#define MPC860_CIPR_PC4       0x00000002/* CPCR (CP Command Register) */#define MPC860_CPCR_RST       0x8000    /* CP reset command */#define MPC860_CPCR_FLG       0x0001    /* Command Semaphore Flag */#define MPC860_CPCR_CHNUM_MASK    0x00F0  /* Channel Number */#define MPC860_CPCR_CHNUM_SHIFT   4#define MPC860_CPCR_OPCODE_MASK   0x0F00  /* Opcode */#define MPC860_CPCR_OPCODE_SHIFT  8/* CP channels */#define MPC860_CHAN_SCC1          0x00#define MPC860_CHAN_I2C_IDMA1     0x01#define MPC860_CHAN_SCC2          0x04#define MPC860_CHAN_SPI_IDMA2_RT  0x05#define MPC860_CHAN_SCC3          0x08#define MPC860_CHAN_SMC1          0x09#define MPC860_CHAN_SCC4          0x0c#define MPC860_CHAN_SMC2_PIP      0x0d/* ======================================================================== *//* IDMA Status Register */#define MPC860_IDSR_OB        0x0001    /* Out of Buffers */#define MPC860_IDSR_DONE      0x0002    /* Buffer chain done */#define MPC860_IDSR_AD        0x0004    /* Auxiliary done *//* Offsets of IDMA channels (from DPRAM base) */#define MPC860_IDMA1_BASE     0x1cc0#define MPC860_IDMA2_BASE     0x1dc0/* Size of an IDMA buffer descriptor */#define MPC860_IDMA_BD_SIZE   16/* IDMA Buffer Descriptor Control Word */#define MPC860_IDMA_CTRL_V    0x8000    /* Valid Bit */#define MPC860_IDMA_CTRL_W    0x2000    /* Wrap */#define MPC860_IDMA_CTRL_I    0x1000    /* Interrupt for this BD */#define MPC860_IDMA_CTRL_L    0x0800    /* Last buffer of chain */#define MPC860_IDMA_CTRL_CM   0x0200    /* Continuous mode *//* IDMA buffer descriptor */struct mpc860_idma_bd {   m_uint16_t offset;      /* Offset in DPRAM memory */   m_uint16_t ctrl;        /* Control Word */   m_uint8_t  dfcr,sfcr;   /* Src/Dst Function code registers */   m_uint32_t buf_len;     /* Buffer Length */   m_uint32_t src_bp;      /* Source buffer pointer */   m_uint32_t dst_bp;      /* Destination buffer pointer */};/* ======================================================================== *//* SPI Mode Register (SPMODE) */#define MPC860_SPMODE_LOOP  0x4000 /* Loop mode */#define MPC860_SPMODE_CI    0x2000 /* Clock Invert */#define MPC860_SPMODE_CP    0x1000 /* Clock Phase */#define MPC860_SPMODE_DIV16 0x0800 /* Divide by 16 (SPI clock generator) */#define MPC860_SPMODE_REV   0x0400 /* Reverse Data */#define MPC860_SPMODE_MS    0x0200 /* Master/Slave mode select */#define MPC860_SPMODE_EN    0x0100 /* Enable SPI */#define MPC860_SPMODE_LEN_MASK   0x00F0  /* Data length (4 - 11 bits) */#define MPC860_SPMODE_LEN_SHIFT  4#define MPC860_SPMODE_PM_MASK    0x000F  /* Prescale Modulus Select *//* SPI Event/Mask Registers (SPIE/SPIM) */#define MPC860_SPIE_MME   0x20   /* MultiMaster Error */#define MPC860_SPIE_TXE   0x10   /* TX Error */#define MPC860_SPIE_BSY   0x04   /* Busy (no RX buffer available) */#define MPC860_SPIE_TXB   0x02   /* TX Buffer */#define MPC860_SPIE_RXB   0x01   /* RX Buffer *//* SPI Command Register (SPCOM) */#define MPC860_SPCOM_STR  0x80   /* Start Transmit *//* Offsets of SPI parameters (from DPRAM base) */#define MPC860_SPI_BASE        0x1d80#define MPC860_SPI_BASE_ADDR   0x1dac/* Size of an SPI buffer descriptor */#define MPC860_SPI_BD_SIZE  8/* SPI RX Buffer Descriptor Control Word */#define MPC860_SPI_RXBD_CTRL_E    0x8000    /* Empty */#define MPC860_SPI_RXBD_CTRL_W    0x2000    /* Wrap */#define MPC860_SPI_RXBD_CTRL_I    0x1000    /* Interrupt */#define MPC860_SPI_RXBD_CTRL_L    0x0800    /* Last */#define MPC860_SPI_RXBD_CTRL_CM   0x0200    /* Continuous Mode */#define MPC860_SPI_RXBD_CTRL_OV   0x0002    /* Overrun */#define MPC860_SPI_RXBD_CTRL_ME   0x0001    /* MultiMaster Error *//* SPI TX Buffer Descriptor Control Word */#define MPC860_SPI_TXBD_CTRL_R    0x8000    /* Ready Bit */#define MPC860_SPI_TXBD_CTRL_W    0x2000    /* Wrap */#define MPC860_SPI_TXBD_CTRL_I    0x1000    /* Interrupt */#define MPC860_SPI_TXBD_CTRL_L    0x0800    /* Last */#define MPC860_SPI_TXBD_CTRL_CM   0x0200    /* Continuous Mode */#define MPC860_SPI_TXBD_CTRL_UN   0x0002    /* Underrun */#define MPC860_SPI_TXBD_CTRL_ME   0x0001    /* MultiMaster Error *//* SPI buffer descriptor */struct mpc860_spi_bd {   m_uint16_t offset;     /* Offset in DPRAM memory */   m_uint16_t ctrl;       /* Control Word */   m_uint16_t buf_len;    /* Buffer Length */   m_uint32_t bp;         /* Buffer Pointer */};/* ======================================================================== *//* Number of SCC channels */#define MPC860_SCC_NR_CHAN   4/* Maximum buffer size for SCC */#define MPC860_SCC_MAX_PKT_SIZE  32768/* Offsets of SCC channels (from DPRAM base) */#define MPC860_SCC1_BASE   0x1c00#define MPC860_SCC2_BASE   0x1d00#define MPC860_SCC3_BASE   0x1e00#define MPC860_SCC4_BASE   0x1f00/* GSMR Low register */#define MPC860_GSMRL_MODE_MASK   0x0000000F/* SCC Modes */#define MPC860_SCC_MODE_HDLC    0x00#define MPC860_SCC_MODE_UART    0x04#define MPC860_SCC_MODE_BISYNC  0x08#define MPC860_SCC_MODE_ETH     0x0c/* SCC Event (SCCE) register */#define MPC860_SCCE_TXB    0x0002   /* TX buffer sent */#define MPC860_SCCE_RXB    0x0001   /* RX buffer ready *//* Size of an SCC buffer descriptor */#define MPC860_SCC_BD_SIZE  8/* SCC RX Buffer Descriptor Control Word */#define MPC860_SCC_RXBD_CTRL_E    0x8000    /* Empty */#define MPC860_SCC_RXBD_CTRL_W    0x2000    /* Wrap */#define MPC860_SCC_RXBD_CTRL_I    0x1000    /* Interrupt */#define MPC860_SCC_RXBD_CTRL_L    0x0800    /* Last */#define MPC860_SCC_RXBD_CTRL_F    0x0400    /* First */#define MPC860_SCC_RXBD_CTRL_CM   0x0200    /* Continuous Mode */#define MPC860_SCC_RXBD_CTRL_OV   0x0002    /* Overrun *//* SCC TX Buffer Descriptor Control Word */#define MPC860_SCC_TXBD_CTRL_R    0x8000    /* Ready Bit */#define MPC860_SCC_TXBD_CTRL_W    0x2000    /* Wrap */#define MPC860_SCC_TXBD_CTRL_I    0x1000    /* Interrupt */#define MPC860_SCC_TXBD_CTRL_L    0x0800    /* Last */#define MPC860_SCC_TXBD_CTRL_TC   0x0400    /* Send TX CRC */#define MPC860_SCC_TXBD_CTRL_CM   0x0200    /* Continuous Mode */#define MPC860_SCC_TXBD_CTRL_UN   0x0002    /* Underrun *//* SCC buffer descriptor */struct mpc860_scc_bd {   m_uint16_t offset;     /* Offset in DPRAM memory */   m_uint16_t ctrl;       /* Control Word */   m_uint16_t buf_len;    /* Buffer Length */   m_uint32_t bp;         /* Buffer Pointer */};/* ======================================================================== *//* FEC Ethernet Control Register */#define MPC860_ECNTRL_FEC_PIN_MUX  0x00000004   /* FEC enable */#define MPC860_ECNTRL_ETHER_EN     0x00000002   /* Ethernet Enable */#define MPC860_ECNTRL_RESET        0x00000001   /* Reset Ethernet controller *//* FEC Interrupt Vector Register */#define MPC860_IVEC_ILEVEL_MASK    0xE0000000   /* Interrupt Level */#define MPC860_IVEC_ILEVEL_SHIFT   29/* FEC Interrupt Event Register */#define MPC860_IEVENT_HBERR    0x80000000   /* Hearbeat Error */#define MPC860_IEVENT_BABR     0x40000000   /* Babbling Receive Error */#define MPC860_IEVENT_BABT     0x20000000   /* Babbling Transmit Error */#define MPC860_IEVENT_GRA      0x10000000   /* Graceful Stop Complete */#define MPC860_IEVENT_TFINT    0x08000000   /* Transmit Frame Interrupt */#define MPC860_IEVENT_TXB      0x04000000   /* Transmit Buffer Interrupt */#define MPC860_IEVENT_RFINT    0x02000000   /* Receive Frame Interrupt */#define MPC860_IEVENT_RXB      0x01000000   /* Receive Buffer Interrupt */#define MPC860_IEVENT_MII      0x00800000   /* MII Interrupt */#define MPC860_IEVENT_EBERR    0x00400000   /* Ethernet Bus Error *//* MII data register */#define MPC860_MII_OP_MASK     0x30000000   /* Opcode (10:read,11:write) */#define MPC860_MII_OP_SHIFT    28#define MPC860_MII_PHY_MASK    0x0F800000   /* PHY device */#define MPC860_MII_PHY_SHIFT   23#define MPC860_MII_REG_MASK    0x007C0000   /* PHY device */#define MPC860_MII_REG_SHIFT   18/* Size of an FEC buffer descriptor */#define MPC860_FEC_BD_SIZE  8/* Maximum packet size for FEC */#define MPC860_FEC_MAX_PKT_SIZE   2048/* FEC RX Buffer Descriptor Control Word */#define MPC860_FEC_RXBD_CTRL_E    0x8000    /* Empty */#define MPC860_FEC_RXBD_CTRL_RO1  0x4000    /* For software use */#define MPC860_FEC_RXBD_CTRL_W    0x2000    /* Wrap */#define MPC860_FEC_RXBD_CTRL_RO2  0x1000    /* For software use */#define MPC860_FEC_RXBD_CTRL_L    0x0800    /* Last */#define MPC860_FEC_RXBD_CTRL_M    0x0100    /* Miss */#define MPC860_FEC_RXBD_CTRL_BC   0x0080    /* Broadcast DA */#define MPC860_FEC_RXBD_CTRL_MC   0x0040    /* Multicast DA */#define MPC860_FEC_RXBD_CTRL_LG   0x0020    /* RX Frame length violation */#define MPC860_FEC_RXBD_CTRL_NO   0x0010    /* RX non-octet aligned frame */#define MPC860_FEC_RXBD_CTRL_SH   0x0008    /* Short Frame */#define MPC860_FEC_RXBD_CTRL_CR   0x0004    /* RX CRC Error */#define MPC860_FEC_RXBD_CTRL_OV   0x0002    /* Overrun */#define MPC860_FEC_RXBD_CTRL_TR   0x0001    /* Truncated Frame *//* FEC TX Buffer Descriptor Control Word */#define MPC860_FEC_TXBD_CTRL_R    0x8000    /* Ready Bit */#define MPC860_FEC_TXBD_CTRL_TO1  0x4000    /* For software use */#define MPC860_FEC_TXBD_CTRL_W    0x2000    /* Wrap */#define MPC860_FEC_TXBD_CTRL_TO2  0x1000    /* For software use */#define MPC860_FEC_TXBD_CTRL_L    0x0800    /* Last */#define MPC860_FEC_TXBD_CTRL_TC   0x0400    /* Send TX CRC */#define MPC860_FEC_TXBD_CTRL_DEF  0x0200    /* Defer Indication */#define MPC860_FEC_TXBD_CTRL_HB   0x0100    /* Heartbeat Error */#define MPC860_FEC_TXBD_CTRL_LC   0x0080    /* Late Collision */#define MPC860_FEC_TXBD_CTRL_RL   0x0040    /* Retranmission Limit */#define MPC860_FEC_TXBD_CTRL_UN   0x0002    /* Underrun */#define MPC860_FEC_TXBD_CTRL_CSL  0x0001    /* Carrier Sense Lost *//* FEC buffer descriptor */struct mpc860_fec_bd {   m_uint32_t bd_addr;    /* Address in external memory */   m_uint16_t ctrl;       /* Control Word */   m_uint16_t buf_len;    /* Buffer Length */   m_uint32_t bp;         /* Buffer Pointer */};/* ======================================================================== */struct mpc860_scc_chan {   netio_desc_t *nio;   /* General SCC mode register (high and low parts) */   m_uint32_t gsmr_hi,gsmr_lo;   /* Protocol-Specific mode register */   m_uint32_t psmr;   /* SCC Event and Mask registers */   m_uint16_t scce,sccm;   /* TX packet */   u_char tx_pkt[MPC860_SCC_MAX_PKT_SIZE];};/* MPC860 private data */struct mpc860_data {   char *name;   vm_obj_t vm_obj;   struct vdevice dev;   struct pci_device *pci_dev;   vm_instance_t *vm;   /* SIU Interrupt Pending Register and Interrupt Mask Register */   m_uint32_t sipend,simask;   /* CPM Interrupt Configuration Register */   m_uint32_t cicr;   /* CPM Interrupt Pending Register and Interrupt Mask Register */   m_uint32_t cipr,cimr;   /* IDMA status and mask registers */   m_uint8_t idsr[2],idmr[2];   /* Port B Data Register */   m_uint32_t pbdat,pcdat;   /* SPI callback for TX data */   mpc860_spi_tx_callback_t spi_tx_callback;   void *spi_user_arg;   /* SCC channels */   struct mpc860_scc_chan scc_chan[MPC860_SCC_NR_CHAN];   /* FEC (Fast Ethernet Controller) */   m_uint32_t fec_rdes_start,fec_xdes_start;   m_uint32_t fec_rdes_current,fec_xdes_current;   m_uint32_t fec_rbuf_size;   /* FEC Interrupt Event/Mask registers */   m_uint32_t fec_ievent,fec_imask,fec_ivec;   m_uint32_t fec_ecntrl;   /* FEC NetIO */   netio_desc_t *fec_nio;   /* FEC MII registers */   m_uint32_t fec_mii_data;   m_uint16_t fec_mii_regs[32];   /* Dual-Port RAM */   m_uint8_t dpram[MPC860_DPRAM_SIZE];};/* Log a MPC message */#define MPC_LOG(d,msg...) vm_log((d)->vm,(d)->name,msg)/* ======================================================================== *//* DPRAM access routines */static inline m_uint8_t dpram_r8(struct mpc860_data *d,m_uint16_t offset){   return(d->dpram[offset]);}static inline void dpram_w8(struct mpc860_data *d,m_uint16_t offset,                            m_uint8_t val){      d->dpram[offset] = val;}static inline m_uint16_t dpram_r16(struct mpc860_data *d,m_uint16_t offset){   m_uint16_t val;   val = (m_uint16_t)d->dpram[offset] << 8;   val |= d->dpram[offset+1];   return(val);}static inline void dpram_w16(struct mpc860_data *d,m_uint16_t offset,                             m_uint16_t val){     d->dpram[offset]   = val >> 8;   d->dpram[offset+1] = val & 0xFF;}static inline m_uint32_t dpram_r32(struct mpc860_data *d,m_uint16_t offset){   m_uint32_t val;   val =  d->dpram[offset]   << 24;   val |= d->dpram[offset+1] << 16;   val |= d->dpram[offset+2] << 8;   val |= d->dpram[offset+3];   return(val);}static inline void dpram_w32(struct mpc860_data *d,m_uint16_t offset,                             m_uint32_t val){   d->dpram[offset]   = val >> 24;   d->dpram[offset+1] = val >> 16;   d->dpram[offset+2] = val >> 8;   d->dpram[offset+3] = val;}/* ======================================================================== *//* Update interrupt status */static void mpc860_update_irq_status(struct mpc860_data *d){   cpu_ppc_t *cpu = CPU_PPC32(d->vm->boot_cpu);   cpu->irq_pending = d->sipend & d->simask;   cpu->irq_check = cpu->irq_pending;}/* Map level to SIU Interrupt Pending Register bit */static inline u_int mpc860_get_siu_lvl(u_int level){   return(16 + ((7 - level) << 1));}/* Update CPM interrupt status */static void mpc860_update_cpm_int_status(struct mpc860_data *d){   u_int level,siu_bit;   level = (d->cicr & MPC860_CICR_IRL_MASK) >> MPC860_CICR_IRL_SHIFT;   siu_bit = mpc860_get_siu_lvl(level);   if ((d->cipr & d->cimr) && (d->cicr & MPC860_CICR_IEN))      mpc860_set_pending_irq(d,siu_bit);   else      mpc860_clear_pending_irq(d,siu_bit);}/* ======================================================================== *//* IDMA                                                                     *//* ======================================================================== */

⌨️ 快捷键说明

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