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

📄 dev_c6sup1_mpfpga.c

📁 思科路由器仿真器,用来仿7200系列得,可以在电脑上模拟路由器
💻 C
字号:
/*  * Cisco router simulation platform. * Copyright (c) 2007 Christophe Fillot (cf@utc.fr) * * C6k-Sup1a Midplane FPGA. */#include <stdio.h>#include <stdlib.h>#include <string.h>#include "cpu.h"#include "vm.h"#include "dynamips.h"#include "memory.h"#include "device.h"#include "nmc93cX6.h"#include "dev_c6sup1.h"#define DEBUG_UNKNOWN  1#define DEBUG_ACCESS   1#define DEBUG_NET_IRQ  1/*  * Function 0xX000: *   bit 0: 0:present, 1:absent. *   bit 1: power ok (?) */#define SLOT_NOT_PRESENT   0x01#define SLOT_POWER_OK      0x02/*  * Function 0xX200: requires bit 3 to be set to avoid error about power  * convertor failure. */#define SLOT_POWER_CONVERTOR   0x08/* Midplane FPGA private data */struct c6sup1_mpfpga_data {   vm_obj_t vm_obj;   struct vdevice dev;   c6sup1_t *router;   m_uint32_t irq_status;   m_uint32_t intr_enable;   /* Slot/function selector */   u_int slot_sel;   /* Slot status (up/down) */   u_int slot_status[C6SUP1_MAX_SLOTS];};/* === Definitions for "Backplane" EEPROM (Chassis Clock, VTT, ...) ======= */#define EEPROM_BP_DOUT  0      /* reg 0x3c */#define EEPROM_BP_DIN   0      /* reg 0x20 */#define EEPROM_BP_CLK   1/* Chip select (CS) bits */#define EEPROM_BP_CS_CHASSIS   3   /* Chassis (6509,...) */#define EEPROM_BP_CS_CHASSIS2  4   /* Chassis redundant EEPROM ? */#define EEPROM_BP_CS_PS1       5   /* Power Supply #1 */#define EEPROM_BP_CS_PS2       6   /* Power Supply #2 */#define EEPROM_BP_CS_CLK1      7   /* Clock card #1 */#define EEPROM_BP_CS_CLK2      8   /* Clock card #2 */#define EEPROM_BP_CS_VTT1      9   /* VTT #1 */#define EEPROM_BP_CS_VTT2      10  /* VTT #2 */#define EEPROM_BP_CS_VTT3      11  /* VTT #3 */static const struct nmc93cX6_eeprom_def eeprom_bp_def_chassis = {   EEPROM_BP_CLK, EEPROM_BP_CS_CHASSIS, EEPROM_BP_DIN, EEPROM_BP_DOUT,};static const struct nmc93cX6_eeprom_def eeprom_bp_def_chassis2 = {   EEPROM_BP_CLK, EEPROM_BP_CS_CHASSIS2, EEPROM_BP_DIN, EEPROM_BP_DOUT,};static const struct nmc93cX6_eeprom_def eeprom_bp_def_ps1 = {   EEPROM_BP_CLK, EEPROM_BP_CS_PS1, EEPROM_BP_DIN, EEPROM_BP_DOUT,};static const struct nmc93cX6_eeprom_def eeprom_bp_def_ps2 = {   EEPROM_BP_CLK, EEPROM_BP_CS_PS2, EEPROM_BP_DIN, EEPROM_BP_DOUT,};static const struct nmc93cX6_eeprom_def eeprom_bp_def_clk1 = {   EEPROM_BP_CLK, EEPROM_BP_CS_CLK1, EEPROM_BP_DIN, EEPROM_BP_DOUT,};static const struct nmc93cX6_eeprom_def eeprom_bp_def_clk2 = {   EEPROM_BP_CLK, EEPROM_BP_CS_CLK2, EEPROM_BP_DIN, EEPROM_BP_DOUT,};static const struct nmc93cX6_eeprom_def eeprom_bp_def_vtt1 = {   EEPROM_BP_CLK, EEPROM_BP_CS_VTT1, EEPROM_BP_DIN, EEPROM_BP_DOUT,};static const struct nmc93cX6_eeprom_def eeprom_bp_def_vtt2 = {   EEPROM_BP_CLK, EEPROM_BP_CS_VTT2, EEPROM_BP_DIN, EEPROM_BP_DOUT,};static const struct nmc93cX6_eeprom_def eeprom_bp_def_vtt3 = {   EEPROM_BP_CLK, EEPROM_BP_CS_VTT3, EEPROM_BP_DIN, EEPROM_BP_DOUT,};/* Backplane EEPROMs */static const struct nmc93cX6_group eeprom_bp_group = {   EEPROM_TYPE_NMC93C56, 9, 0,    EEPROM_DORD_REVERSED,   EEPROM_DOUT_KEEP,   EEPROM_DEBUG_DISABLED,   "Backplane EEPROMs",   {      &eeprom_bp_def_chassis,      &eeprom_bp_def_chassis2,       &eeprom_bp_def_ps1,      &eeprom_bp_def_ps2,      &eeprom_bp_def_clk1,      &eeprom_bp_def_clk2,      &eeprom_bp_def_vtt1,      &eeprom_bp_def_vtt2,      &eeprom_bp_def_vtt3,   },};/* === Definitions for "Supervisor" EEPROMs (Sup1A,PFC/EARL) ============== */#define EEPROM_SUP_DOUT    0         /* XXX */#define EEPROM_SUP_DIN     2#define EEPROM_SUP_CLK     1#define EEPROM_SUP_CS      3#define EEPROM_EARL_DOUT   2         /* XXX */#define EEPROM_EARL_DIN    9#define EEPROM_EARL_CLK    10#define EEPROM_EARL_CS     8static const struct nmc93cX6_eeprom_def eeprom_sup_def = {   EEPROM_SUP_CLK, EEPROM_SUP_CS, EEPROM_SUP_DIN, EEPROM_SUP_DOUT,};static const struct nmc93cX6_eeprom_def eeprom_earl_def = {   EEPROM_EARL_CLK, EEPROM_EARL_CS, EEPROM_EARL_DIN, EEPROM_EARL_DOUT,};/* Supervisor EEPROMs */static const struct nmc93cX6_group eeprom_sup_group = {   EEPROM_TYPE_NMC93C56, 2, 0,    EEPROM_DORD_REVERSED,   EEPROM_DOUT_KEEP,   EEPROM_DEBUG_DISABLED,   "Supervisor EEPROMs",   { &eeprom_sup_def, &eeprom_earl_def },};/* === Definitions for "Slot" EEPROM ====================================== */#define EEPROM_SLOT_DOUT   0   /* reg 0x4c */#define EEPROM_SLOT_DIN    0   /* reg 0x48 */#define EEPROM_SLOT_CLK    1#define EEPROM_SLOT_CS     3static const struct nmc93cX6_eeprom_def eeprom_slot_def = {   EEPROM_SLOT_CLK, EEPROM_SLOT_CS, EEPROM_SLOT_DIN, EEPROM_SLOT_DOUT,};static const struct nmc93cX6_group eeprom_slot_group = {   EEPROM_TYPE_NMC93C56, 1, 0,    EEPROM_DORD_REVERSED,   EEPROM_DOUT_KEEP,   EEPROM_DEBUG_DISABLED,   "Slot EEPROMs",   { &eeprom_slot_def },};/* ------------------------------------------------------------------------ *//* Update network interrupt status */static inline void dev_c6sup1_mpfpga_net_update_irq(struct c6sup1_mpfpga_data *d){   if (d->irq_status) {      vm_set_irq(d->router->vm,C6SUP1_NETIO_IRQ);   } else {      vm_clear_irq(d->router->vm,C6SUP1_NETIO_IRQ);   }}/* Trigger a Network IRQ for the specified slot/port */void dev_c6sup1_mpfpga_net_set_irq(struct c6sup1_mpfpga_data *d,                                   u_int slot,u_int port){#if DEBUG_NET_IRQ   vm_log(d->router->vm,"MP_FPGA","setting NetIRQ for slot %u port %u\n",          slot,port);#endif   d->irq_status |= 1 << slot;   dev_c6sup1_mpfpga_net_update_irq(d);}/* Clear a Network IRQ for the specified slot/port */void dev_c6sup1_mpfpga_net_clear_irq(struct c6sup1_mpfpga_data *d,                                     u_int slot,u_int port){#if DEBUG_NET_IRQ   vm_log(d->router->vm,"MP_FPGA","clearing NetIRQ for slot %u port %u\n",          slot,port);#endif   d->irq_status &= ~(1 << slot);   dev_c6sup1_mpfpga_net_update_irq(d);}/* * dev_c6sup1_access() */void *dev_c6sup1_mpfpga_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 c6sup1_mpfpga_data *d = dev->priv_data;   struct nmc93cX6_group *grp;   u_int i,slot,func;   if (op_type == MTS_READ)      *data = 0xFFFFFFFF;#if DEBUG_ACCESS   if (op_type == MTS_READ) {      cpu_log(cpu,"MP_FPGA",              "reading reg 0x%x at pc=0x%llx, ra=0x%llx (size=%u)\n",              offset,cpu_get_pc(cpu),CPU_MIPS64(cpu)->gpr[MIPS_GPR_RA],              op_size);   } else {      cpu_log(cpu,"MP_FPGA",              "writing reg 0x%x at pc=0x%llx, ra=0x%llx "              "data=0x%llx (size=%u)\n",              offset,cpu_get_pc(cpu),CPU_MIPS64(cpu)->gpr[MIPS_GPR_RA],              *data,op_size);   }#endif   switch(offset) {      case 0x0c:      case 0x14:      case 0x1c:         if (op_type == MTS_READ)            *data = 0;         break;      case 0x18:         if (op_type == MTS_READ)            *data = 0x8000;         break;      /* 0x3E80 is written regularly here (watchdog ?) */      case 0x20004:         break;      /* Backplane EEPROMs */      case 0x000020:         if (op_type == MTS_WRITE) {            //m_log("EEPROM","write access(BP): data=0x%4.4llx\n",*data);            nmc93cX6_write(&d->router->bp_eeprom_group,(u_int)(*data));         }         break;      /* Supervisor EEPROMs */      case 0x000024:         if (op_type == MTS_WRITE) {            //m_log("EEPROM","write access(SUP): data=0x%4.4llx\n",*data);            nmc93cX6_write(&d->router->sup_eeprom_group,(u_int)(*data));         }         break;      /* Backplane/Supervisor EEPROMs read access */      case 0x00003C:         if (op_type == MTS_READ) {            *data = 0x0000;            /* Backplane EEPROMs */            grp = &d->router->bp_eeprom_group;            for(i=0;i<grp->nr_eeprom;i++) {               if (nmc93cX6_is_active(grp,i))                  *data |= nmc93cX6_get_dout(grp,i);            }            /* Supervisor EEPROMs */            grp = &d->router->sup_eeprom_group;            for(i=0;i<grp->nr_eeprom;i++) {               if (nmc93cX6_is_active(grp,i))                  if (nmc93cX6_get_dout(grp,i))                     *data |= 0xFFFF; //nmc93cX6_get_dout(grp,i);            }         }         break;      /* Slot selection */      case 0x000044:         if (op_type == MTS_WRITE) {            d->slot_sel = *data;            slot = (d->slot_sel & 0xF000) >> 12;            func = (d->slot_sel & 0x0F00) >> 8;            if (slot <= C6SUP1_MAX_SLOTS) {               grp = &d->router->slot_eeprom_group;               grp->eeprom[0] = &d->router->slot_eeprom[slot-1];               /* mark the slot as powered on */               if (func == 0x02) {                  //printf("Marking slot %u as powered ON\n",slot);                  d->slot_status[slot-1] = TRUE;               }            }                       }         break;               /* Slot EEPROM write */      case 0x000048:         if (op_type == MTS_WRITE)            nmc93cX6_write(&d->router->slot_eeprom_group,(u_int)(*data));         break;      /* Slot EEPROM read */       case 0x00004c:         if (op_type == MTS_READ) {            grp = &d->router->slot_eeprom_group;            slot = (d->slot_sel & 0xF000) >> 12;            func = (d->slot_sel & 0x0F00) >> 8;            *data = 0;                        switch(func) {               /* Presence + power ? */               case 0x00:                  *data = SLOT_NOT_PRESENT;                  if (grp->eeprom[0] && grp->eeprom[0]->data) {                     *data = 0;                     /* The SUP slot is always powered */                     if (d->slot_status[slot-1] ||                          (slot == d->router->sup_slot))                        *data |= SLOT_POWER_OK;                  }                  break;               case 0x01:                  *data = 0x0001;                  if (grp->eeprom[0] && grp->eeprom[0]->data) {                     *data = 0x0000;                  }                  break;               /* Power-related */               case 0x02:                  *data = SLOT_POWER_CONVERTOR;                  break;               /* EEPROM reading */               case 0x05:                  if (nmc93cX6_is_active(grp,0))                     *data |= nmc93cX6_get_dout(grp,0);                  break;               default:                  cpu_log(cpu,"MP_FPGA","slot control: unknown func 0x%2.2x\n",                          func);            }         }         break;      /* Slot Identification */      case 0x000004:         if (op_type == MTS_READ)            *data = (d->router->sup_slot << 8) | 0x80;         break;      /* Unknown: EARL interrupt ? */      /* 00:00:27: %CPU_MONITOR-3-PEER_EXCEPTION:         CPU_MONITOR peer has failed due to exception , resetting [0/1] */      case 0x000050:         if (op_type == MTS_READ)            *data = 0; //0xFFFF;         break;      case 0x000074:         if (op_type == MTS_READ)            *data = 0x0000; //0x3FFF;         break;#if DEBUG_UNKNOWN      default:         if (op_type == MTS_READ) {            cpu_log(cpu,"MP_FPGA",                    "read from unknown addr 0x%x, pc=0x%llx (size=%u)\n",                    offset,cpu_get_pc(cpu),op_size);         } else {            cpu_log(cpu,"MP_FPGA",                    "write to unknown addr 0x%x, value=0x%llx, pc=0x%llx "                    "(op_size=%u)\n",offset,*data,cpu_get_pc(cpu),op_size);         }#endif   }	   return NULL;}/* Shutdown the MP FPGA device */static void dev_c6sup1_mpfpga_shutdown(vm_instance_t *vm,struct c6sup1_mpfpga_data *d){   if (d != NULL) {      /* Remove the device */      dev_remove(vm,&d->dev);            /* Free the structure itself */      free(d);   }}/* Initialize EEPROM groups */void c6sup1_init_eeprom_groups(c6sup1_t *router){   struct nmc93cX6_group *grp;   router->bp_eeprom_group = eeprom_bp_group;   router->sup_eeprom_group = eeprom_sup_group;   router->slot_eeprom_group = eeprom_slot_group;   /* XXX */   grp = &router->bp_eeprom_group;   grp->eeprom[0] = cisco_eeprom_find_c6k("C6K-CHASSIS-6509");   grp->eeprom[2] = cisco_eeprom_find_c6k("C6K-POWER-1000W");   grp->eeprom[3] = cisco_eeprom_find_c6k("C6K-POWER-1000W");   grp->eeprom[6] = cisco_eeprom_find_c6k("C6K-VTT");   grp->eeprom[7] = cisco_eeprom_find_c6k("C6K-VTT");   grp->eeprom[8] = cisco_eeprom_find_c6k("C6K-VTT");   grp = &router->sup_eeprom_group;   grp->eeprom[0] = cisco_eeprom_find_c6k("C6K-SUP-SUP1A-2GE");   grp->eeprom[1] = cisco_eeprom_find_c6k("C6K-EARL-PFC1");   cisco_eeprom_copy(&router->slot_eeprom[0],                     cisco_eeprom_find_c6k("C6K-SUP-SUP1A-2GE"));      cisco_eeprom_copy(&router->slot_eeprom[8],                     cisco_eeprom_find_c6k("C6K-LC-WS-X6248"));}/*  * dev_c6sup1_mpfpga_init() */int dev_c6sup1_mpfpga_init(c6sup1_t *router,m_uint64_t paddr,m_uint32_t len){      struct c6sup1_mpfpga_data *d;   /* Allocate private data structure */   if (!(d = malloc(sizeof(*d)))) {      fprintf(stderr,"MP_FPGA: out of memory\n");      return(-1);   }   memset(d,0,sizeof(*d));   d->router = router;      vm_object_init(&d->vm_obj);   d->vm_obj.name = "mp_fpga";   d->vm_obj.data = d;   d->vm_obj.shutdown = (vm_shutdown_t)dev_c6sup1_mpfpga_shutdown;   /* Set device properties */   dev_init(&d->dev);   d->dev.name      = "mp_fpga";   d->dev.phys_addr = paddr;   d->dev.phys_len  = len;   d->dev.handler   = dev_c6sup1_mpfpga_access;   d->dev.priv_data = d;   /* Map this device to the VM */   vm_bind_device(router->vm,&d->dev);   vm_object_add(router->vm,&d->vm_obj);   return(0);}

⌨️ 快捷键说明

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