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

📄 dev_c7200_iofpga.c

📁 思科路由器仿真器,用来仿7200系列得,可以在电脑上模拟路由器
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Cisco router simulation platform. * Copyright (c) 2005,2006 Christophe Fillot (cf@utc.fr) * * Cisco 7200 I/O FPGA: *   - Simulates a NMC93C46 Serial EEPROM as CPU and Midplane EEPROM. *   - Simulates a DALLAS DS1620 for Temperature Sensors. *   - Simulates voltage sensors. *   - Simulates console and AUX ports (SCN2681). */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/types.h>#include <termios.h>#include <fcntl.h>#include <pthread.h>#include "ptask.h"#include "cpu.h"#include "vm.h"#include "dynamips.h"#include "memory.h"#include "device.h"#include "dev_vtty.h"#include "nmc93cX6.h"#include "ds1620.h"#include "dev_c7200.h"/* Debugging flags */#define DEBUG_UNKNOWN  1#define DEBUG_ACCESS   0#define DEBUG_LED      0#define DEBUG_IO_CTL   0#define DEBUG_ENVM     0/* DUART RX/TX status (SRA/SRB) */#define DUART_RX_READY  0x01#define DUART_TX_READY  0x04/* DUART RX/TX Interrupt Status/Mask */#define DUART_TXRDYA  0x01#define DUART_RXRDYA  0x02#define DUART_TXRDYB  0x10#define DUART_RXRDYB  0x20/* Definitions for CPU and Midplane Serial EEPROMs */#define DO2_DATA_OUT_MIDPLANE	 7#define DO1_DATA_OUT_CPU	 6#define CS2_CHIP_SEL_MIDPLANE	 5#define SK2_CLOCK_MIDPLANE 	 4#define DI2_DATA_IN_MIDPLANE	 3#define CS1_CHIP_SEL_CPU	 2#define SK1_CLOCK_CPU	 	 1#define DI1_DATA_IN_CPU		 0/* Definitions for PEM (NPE-B) Serial EEPROM */#define DO1_DATA_OUT_PEM   3#define DI1_DATA_IN_PEM    2#define CS1_CHIP_SEL_PEM   1#define SK1_CLOCK_PEM      0/* Pack the NVRAM */#define NVRAM_PACKED   0x04/* 4 temperature sensors in a C7200 */#define C7200_TEMP_SENSORS  4#define C7200_DEFAULT_TEMP  22    /* default temperature: 22癈 *//* Voltages */#define C7200_A2D_SAMPLES   9/* * A2D MUX Select definitions. */#define C7200_MUX_PS0     0x00   /* Power Supply 0 */#define C7200_MUX_PS1     0x02   /* Power Supply 1 */#define C7200_MUX_P3V     0x04   /* +3V */#define C7200_MUX_P12V    0x08   /* +12V */#define C7200_MUX_P5V     0x0a   /* +5V */#define C7200_MUX_N12V    0x0c   /* -12V *//* Analog To Digital Converters samples */#define C7200_A2D_PS0     1150#define C7200_A2D_PS1     1150/* Voltage Samples */#define C7200_A2D_P3V     1150#define C7200_A2D_P12V    1150#define C7200_A2D_P5V     1150#define C7200_A2D_N12V    1150/* IO FPGA structure */struct iofpga_data {   vm_obj_t vm_obj;   struct vdevice dev;   c7200_t *router;   /* Lock test */   pthread_mutex_t lock;   /* Periodic task to trigger dummy DUART IRQ */   ptask_id_t duart_irq_tid;   /* DUART & Console Management */   u_int duart_isr,duart_imr,duart_irq_seq;      /* IO control register */   u_int io_ctrl_reg;   /* Temperature Control */   u_int temp_cfg_reg[C7200_TEMP_SENSORS];   u_int temp_deg_reg[C7200_TEMP_SENSORS];   u_int temp_clk_low;   u_int temp_cmd;   u_int temp_cmd_pos;   u_int temp_data;   u_int temp_data_pos;   /* Voltages */   u_int mux;   /* NPE-G2 environmental part */   m_uint32_t envm_r0,envm_r1,envm_r2;};#define IOFPGA_LOCK(d)   pthread_mutex_lock(&(d)->lock)#define IOFPGA_UNLOCK(d) pthread_mutex_unlock(&(d)->lock)/* CPU EEPROM definition */static const struct nmc93cX6_eeprom_def eeprom_cpu_def = {   SK1_CLOCK_CPU, CS1_CHIP_SEL_CPU,    DI1_DATA_IN_CPU, DO1_DATA_OUT_CPU,};/* Midplane EEPROM definition */static const struct nmc93cX6_eeprom_def eeprom_midplane_def = {   SK2_CLOCK_MIDPLANE, CS2_CHIP_SEL_MIDPLANE,    DI2_DATA_IN_MIDPLANE, DO2_DATA_OUT_MIDPLANE,};/* PEM (NPE-B) EEPROM definition */static const struct nmc93cX6_eeprom_def eeprom_pem_def = {   SK1_CLOCK_PEM, CS1_CHIP_SEL_PEM, DI1_DATA_IN_PEM, DO1_DATA_OUT_PEM,};/* IOFPGA manages simultaneously CPU and Midplane EEPROM */static const struct nmc93cX6_group eeprom_cpu_midplane = {   EEPROM_TYPE_NMC93C46, 2, 0,    EEPROM_DORD_NORMAL,   EEPROM_DOUT_HIGH,   EEPROM_DEBUG_DISABLED,   "CPU and Midplane EEPROM",   { &eeprom_cpu_def, &eeprom_midplane_def }, };/*  * IOFPGA manages also PEM EEPROM (for NPE-B) * PEM stands for "Power Entry Module": * http://www.cisco.com/en/US/products/hw/routers/ps341/products_field_notice09186a00801cb26d.shtml */static const struct nmc93cX6_group eeprom_pem_npeb = {   EEPROM_TYPE_NMC93C46, 1, 0,   EEPROM_DORD_NORMAL,   EEPROM_DOUT_HIGH,   EEPROM_DEBUG_DISABLED,   "PEM (NPE-B) EEPROM",    { &eeprom_pem_def },};/* Reset DS1620 */static void temp_reset(struct iofpga_data *d){   d->temp_cmd_pos = 0;   d->temp_cmd = 0;   d->temp_data_pos = 0;   d->temp_data = 0;}/* Write the temperature control data */static void temp_write_ctrl(struct iofpga_data *d,u_char val){   switch(val) {      case DS1620_RESET_ON:         temp_reset(d);         break;      case DS1620_CLK_LOW:         d->temp_clk_low = 1;         break;      case DS1620_CLK_HIGH:         d->temp_clk_low = 0;         break;   }}/* Read a temperature control data */static u_int temp_read_data(struct iofpga_data *d){   u_int i,data = 0;   switch(d->temp_cmd) {      case DS1620_READ_CONFIG:         for(i=0;i<C7200_TEMP_SENSORS;i++)            data |= ((d->temp_cfg_reg[i] >> d->temp_data_pos) & 1) << i;         d->temp_data_pos++;         if (d->temp_data_pos == DS1620_CONFIG_READ_SIZE)            temp_reset(d);         break;      case DS1620_READ_TEMP:         for(i=0;i<C7200_TEMP_SENSORS;i++)            data |= ((d->temp_deg_reg[i] >> d->temp_data_pos) & 1) << i;         d->temp_data_pos++;         if (d->temp_data_pos == DS1620_DATA_READ_SIZE)            temp_reset(d);         break;      default:         vm_log(d->router->vm,"IO_FPGA","temp_sensors: CMD = 0x%x\n",                d->temp_cmd);   }   return(data);}/* Write the temperature data write register */static void temp_write_data(struct iofpga_data *d,u_char val){   if (val == DS1620_ENABLE_READ) {      d->temp_data_pos = 0;      return;   }   if (!d->temp_clk_low)      return;   /* Write a command */   if (d->temp_cmd_pos < DS1620_WRITE_SIZE)   {      if (val == DS1620_DATA_HIGH)         d->temp_cmd |= 1 << d->temp_cmd_pos;      d->temp_cmd_pos++;         if (d->temp_cmd_pos == DS1620_WRITE_SIZE) {         switch(d->temp_cmd) {            case DS1620_START_CONVT:               //printf("temp_sensors: IOS enabled continuous monitoring.\n");               temp_reset(d);               break;            case DS1620_READ_CONFIG:            case DS1620_READ_TEMP:               break;            default:               vm_log(d->router->vm,"IO_FPGA",                      "temp_sensors: IOS sent command 0x%x.\n",                      d->temp_cmd);         }      }   }   else   {      if (val == DS1620_DATA_HIGH)         d->temp_data |= 1 << d->temp_data_pos;      d->temp_data_pos++;   }}/* NPE-G2 environmental monitor reading */static m_uint32_t g2_envm_read(struct iofpga_data *d){   m_uint32_t val = 0;   m_uint32_t p1;   p1 = ((d->envm_r2 & 0xFF) << 8) | d->envm_r0 >> 3;      switch(p1) {      case 0x2a00:     /* CPU Die Temperature */         val = 0x3000;         break;      case 0x4c00:     /* +3.30V */         val = 0x2a9;         break;      case 0x4c01:     /* +1.50V */         val = 0x135;         break;      case 0x4c02:     /* +2.50V */         val = 0x204;         break;      case 0x4c03:     /* +1.80V */         val = 0x173;         break;      case 0x4c04:     /* +1.20V */         val = 0xF7;         break;      case 0x4c05:     /* VDD_CPU */         val = 0x108;         break;      case 0x4800:     /* VDD_MEM */         val = 0x204;         break;      case 0x4801:     /* VTT */         val = 0xF9;         break;      case 0x4802:     /* +3.45V */         val = 0x2c8;         break;      case 0x4803:     /* -11.95V*/         val = 0x260;         break;      case 0x4804:     /* ? */         val = 0x111;         break;      case 0x4805:     /* ? */         val = 0x111;         break;      case 0x4806:     /* +5.15V */         val = 0x3F8;         break;      case 0x4807:     /* +12.15V */         val = 0x33D;         break;#if DEBUG_UNKNOWN      default:         vm_log(d->router->vm,"IO_FPGA","p1 = 0x%8.8x\n",p1);#endif   }   return(htonl(val));}/* Console port input */static void tty_con_input(vtty_t *vtty){   struct iofpga_data *d = vtty->priv_data;   IOFPGA_LOCK(d);   if (d->duart_imr & DUART_RXRDYA) {      d->duart_isr |= DUART_RXRDYA;      vm_set_irq(d->router->vm,C7200_DUART_IRQ);   }   IOFPGA_UNLOCK(d);}/* AUX port input */static void tty_aux_input(vtty_t *vtty){   struct iofpga_data *d = vtty->priv_data;   IOFPGA_LOCK(d);   if (d->duart_imr & DUART_RXRDYB) {      d->duart_isr |= DUART_RXRDYB;      vm_set_irq(d->router->vm,C7200_DUART_IRQ);   }   IOFPGA_UNLOCK(d);}/* IRQ trickery for Console and AUX ports */static int tty_trigger_dummy_irq(struct iofpga_data *d,void *arg){   u_int mask;   IOFPGA_LOCK(d);   d->duart_irq_seq++;      if (d->duart_irq_seq == 2) {      mask = DUART_TXRDYA|DUART_TXRDYB;      if (d->duart_imr & mask) {         d->duart_isr |= DUART_TXRDYA|DUART_TXRDYB;         vm_set_irq(d->router->vm,C7200_DUART_IRQ);      }      d->duart_irq_seq = 0;   }      IOFPGA_UNLOCK(d);   return(0);}/* * dev_c7200_iofpga_access() */void *dev_c7200_iofpga_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 iofpga_data *d = dev->priv_data;   vm_instance_t *vm = d->router->vm;   u_char odata;

⌨️ 快捷键说明

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