📄 dev_c7200.c
字号:
/* * Cisco 7200 (Predator) simulation platform. * Copyright (c) 2005,2006 Christophe Fillot (cf@utc.fr) * * Generic Cisco 7200 routines and definitions (EEPROM,...). */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/types.h>#include <assert.h>#include "mips64.h"#include "dynamips.h"#include "memory.h"#include "device.h"#include "pci_io.h"#include "dev_gt.h"#include "cisco_eeprom.h"#include "dev_c7200.h"#include "dev_vtty.h"#include "registry.h"#include "net.h"/* ======================================================================== *//* CPU EEPROM definitions *//* ======================================================================== *//* NPE-100 */static m_uint16_t eeprom_cpu_npe100_data[16] = { 0x0135, 0x0203, 0xffff, 0xffff, 0x4906, 0x0004, 0x0000, 0x0000, 0x6000, 0x0000, 0x9901, 0x0600, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,};/* NPE-150 */static m_uint16_t eeprom_cpu_npe150_data[16] = { 0x0115, 0x0203, 0xffff, 0xffff, 0x4906, 0x0004, 0x0000, 0x0000, 0x6000, 0x0000, 0x9901, 0x0600, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,};/* NPE-175 */static m_uint16_t eeprom_cpu_npe175_data[16] = { 0x01C2, 0x0203, 0xffff, 0xffff, 0x4906, 0x0004, 0x0000, 0x0000, 0x6000, 0x0000, 0x9901, 0x0600, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,};/* NPE-200 */static m_uint16_t eeprom_cpu_npe200_data[16] = { 0x0169, 0x0200, 0xffff, 0xffff, 0x4909, 0x8902, 0x0000, 0x0000, 0x6800, 0x0000, 0x9710, 0x2200, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,};/* NPE-225 (same as NPE-175) */static m_uint16_t eeprom_cpu_npe225_data[16] = { 0x01C2, 0x0203, 0xffff, 0xffff, 0x4906, 0x0004, 0x0000, 0x0000, 0x6000, 0x0000, 0x9901, 0x0600, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,};/* NPE-300 */static m_uint16_t eeprom_cpu_npe300_data[16] = { 0x01AE, 0x0402, 0xffff, 0xffff, 0x490D, 0x5108, 0x0000, 0x0000, 0x5000, 0x0000, 0x0012, 0x1000, 0x0000, 0xFFFF, 0xFFFF, 0xFF00,};/* NPE-400 */static m_uint16_t eeprom_cpu_npe400_data[64] = { 0x04FF, 0x4001, 0xF841, 0x0100, 0xC046, 0x0320, 0x001F, 0xC802, 0x8249, 0x14BC, 0x0242, 0x4230, 0xC18B, 0x3131, 0x3131, 0x3131, 0x3131, 0x0000, 0x0004, 0x0002, 0x0285, 0x1C0F, 0xF602, 0xCB87, 0x4E50, 0x452D, 0x3430, 0x3080, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,};/* NPE-G1 */static m_uint16_t eeprom_cpu_npeg1_data[64] = { 0x04FF, 0x4003, 0x5B41, 0x0200, 0xC046, 0x0320, 0x0049, 0xD00B, 0x8249, 0x1B4C, 0x0B42, 0x4130, 0xC18B, 0x3131, 0x3131, 0x3131, 0x3131, 0x0000, 0x0004, 0x0002, 0x0985, 0x1C13, 0xDA09, 0xCB86, 0x4E50, 0x452D, 0x4731, 0x8000, 0x0000, 0x00FF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,};/* * CPU EEPROM array. */static struct cisco_eeprom c7200_cpu_eeprom[] = { { "npe-100", eeprom_cpu_npe100_data, sizeof(eeprom_cpu_npe100_data)/2 }, { "npe-150", eeprom_cpu_npe150_data, sizeof(eeprom_cpu_npe150_data)/2 }, { "npe-175", eeprom_cpu_npe175_data, sizeof(eeprom_cpu_npe175_data)/2 }, { "npe-200", eeprom_cpu_npe200_data, sizeof(eeprom_cpu_npe200_data)/2 }, { "npe-225", eeprom_cpu_npe225_data, sizeof(eeprom_cpu_npe225_data)/2 }, { "npe-300", eeprom_cpu_npe300_data, sizeof(eeprom_cpu_npe300_data)/2 }, { "npe-400", eeprom_cpu_npe400_data, sizeof(eeprom_cpu_npe400_data)/2 }, { "npe-g1" , eeprom_cpu_npeg1_data , sizeof(eeprom_cpu_npeg1_data)/2 }, { NULL, NULL, 0 },};/* ======================================================================== *//* Midplane EEPROM definitions *//* ======================================================================== *//* Standard Midplane EEPROM contents */static m_uint16_t eeprom_midplane_data[32] = { 0x0106, 0x0101, 0xffff, 0xffff, 0x4906, 0x0303, 0xFFFF, 0xFFFF, 0xFFFF, 0x0400, 0x0000, 0x0000, 0x4C09, 0x10B0, 0xFFFF, 0x00FF, 0x0000, 0x0000, 0x6335, 0x8B28, 0x631D, 0x0000, 0x608E, 0x6D1C, 0x62BB, 0x0000, 0x6335, 0x8B28, 0x0000, 0x0000, 0x6335, 0x8B28,};/* VXR Midplane EEPROM contents */static m_uint16_t eeprom_vxr_midplane_data[32] = { 0x0106, 0x0201, 0xffff, 0xffff, 0x4906, 0x0303, 0xFFFF, 0xFFFF, 0xFFFF, 0x0400, 0x0000, 0x0000, 0x4C09, 0x10B0, 0xFFFF, 0x00FF, 0x0000, 0x0000, 0x6335, 0x8B28, 0x631D, 0x0000, 0x608E, 0x6D1C, 0x62BB, 0x0000, 0x6335, 0x8B28, 0x0000, 0x0000, 0x6335, 0x8B28,};/* * Midplane EEPROM array. */static struct cisco_eeprom c7200_midplane_eeprom[] = { { "std", eeprom_midplane_data, sizeof(eeprom_midplane_data)/2 }, { "vxr", eeprom_vxr_midplane_data, sizeof(eeprom_vxr_midplane_data)/2 }, { NULL, NULL, 0 },};/* ======================================================================== *//* PEM EEPROM definitions (for NPE-175 and NPE-225) *//* ======================================================================== *//* NPE-175 */static m_uint16_t eeprom_pem_npe175_data[16] = { 0x01C3, 0x0100, 0xFFFF, 0xFFFF, 0x490D, 0x8A04, 0x0000, 0x0000, 0x5000, 0x0000, 0x9906, 0x0400, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF,};/* NPE-225 */static m_uint16_t eeprom_pem_npe225_data[16] = { 0x01D5, 0x0100, 0xFFFF, 0xFFFF, 0x490D, 0x8A04, 0x0000, 0x0000, 0x5000, 0x0000, 0x9906, 0x0400, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF,};/* * PEM EEPROM array. */static struct cisco_eeprom c7200_pem_eeprom[] = { { "npe-175", eeprom_pem_npe175_data, sizeof(eeprom_pem_npe175_data)/2 }, { "npe-225", eeprom_pem_npe225_data, sizeof(eeprom_pem_npe225_data)/2 }, { NULL, NULL, 0 },};/* ======================================================================== *//* Port Adapter Drivers *//* ======================================================================== */static struct c7200_pa_driver *pa_drivers[] = { &dev_c7200_io_fe_driver, &dev_c7200_pa_fe_tx_driver, &dev_c7200_pa_4e_driver, &dev_c7200_pa_8e_driver, &dev_c7200_pa_4t_driver, &dev_c7200_pa_8t_driver, &dev_c7200_pa_a1_driver, &dev_c7200_pa_pos_oc3_driver, &dev_c7200_pa_4b_driver, &dev_c7200_pa_mc8te1_driver, NULL,};/* ======================================================================== *//* NPE Drivers *//* ======================================================================== */#define DECLARE_NPE(type) \ int (c7200_init_##type)(c7200_t *router) DECLARE_NPE(npe100);DECLARE_NPE(npe150);DECLARE_NPE(npe175);DECLARE_NPE(npe200);DECLARE_NPE(npe225);DECLARE_NPE(npe300);DECLARE_NPE(npe400);DECLARE_NPE(npeg1);static struct c7200_npe_driver npe_drivers[] = { { "npe-100" , c7200_init_npe100, 256, 1, C7200_NVRAM_ADDR, 0, 5, 0, 6 }, { "npe-150" , c7200_init_npe150, 256, 1, C7200_NVRAM_ADDR, 0, 5, 0, 6 }, { "npe-175" , c7200_init_npe175, 256, 1, C7200_NVRAM_ADDR, 2, 16, 1, 0 }, { "npe-200" , c7200_init_npe200, 256, 1, C7200_NVRAM_ADDR, 0, 5, 0, 6 }, { "npe-225" , c7200_init_npe225, 256, 1, C7200_NVRAM_ADDR, 2, 16, 1, 0 }, { "npe-300" , c7200_init_npe300, 256, 1, C7200_NVRAM_ADDR, 2, 16, 1, 0 }, { "npe-400" , c7200_init_npe400, 512, 1, C7200_NVRAM_ADDR, 2, 16, 1, 0 }, { "npe-g1" , c7200_init_npeg1, 1024, 0, C7200_NPEG1_NVRAM_ADDR, 17, 16, 16, 0 }, { NULL , NULL },};/* ======================================================================== *//* Cisco 7200 router instances *//* ======================================================================== *//* Directly extract the configuration from the NVRAM device */ssize_t c7200_nvram_extract_config(vm_instance_t *vm,char **buffer){ u_char *base_ptr,*ios_ptr,*cfg_ptr,*end_ptr; m_uint32_t start,end,nvlen,clen; m_uint16_t magic1,magic2; struct vdevice *nvram_dev; m_uint64_t nvram_addr; off_t nvram_size; int fd; if ((nvram_dev = dev_get_by_name(vm,"nvram"))) dev_sync(nvram_dev); fd = vm_mmap_open_file(vm,"nvram",&base_ptr,&nvram_size); if (fd == -1) return(-1); nvram_addr = VM_C7200(vm)->npe_driver->nvram_addr; ios_ptr = base_ptr + vm->nvram_rom_space; end_ptr = base_ptr + nvram_size; if ((ios_ptr + 0x30) >= end_ptr) { vm_error(vm,"NVRAM file too small\n"); return(-1); } magic1 = ntohs(*PTR_ADJUST(m_uint16_t *,ios_ptr,0x06)); magic2 = ntohs(*PTR_ADJUST(m_uint16_t *,ios_ptr,0x08)); if ((magic1 != 0xF0A5) || (magic2 != 0xABCD)) { vm_error(vm,"unable to find IOS magic numbers (0x%x,0x%x)!\n", magic1,magic2); return(-1); } start = ntohl(*PTR_ADJUST(m_uint32_t *,ios_ptr,0x10)) + 1; end = ntohl(*PTR_ADJUST(m_uint32_t *,ios_ptr,0x14)); nvlen = ntohl(*PTR_ADJUST(m_uint32_t *,ios_ptr,0x18)); clen = end - start; if ((clen + 1) != nvlen) { vm_error(vm,"invalid configuration size (0x%x)\n",nvlen); return(-1); } if (!(*buffer = malloc(clen+1))) { vm_error(vm,"unable to allocate config buffer (%u bytes)\n",clen); return(-1); } cfg_ptr = base_ptr + (start - nvram_addr); if ((start < nvram_addr) || ((cfg_ptr + clen) > end_ptr)) { vm_error(vm,"NVRAM file too small\n"); return(-1); } memcpy(*buffer,cfg_ptr,clen); (*buffer)[clen] = 0; return(clen);}/* Directly push the IOS configuration to the NVRAM device */int c7200_nvram_push_config(vm_instance_t *vm,char *buffer,size_t len){ u_char *base_ptr,*ios_ptr,*cfg_ptr; m_uint32_t cfg_addr,cfg_offset; m_uint32_t nvram_addr,cklen; m_uint16_t cksum; int fd; fd = vm_mmap_create_file(vm,"nvram",vm->nvram_size*1024,&base_ptr); if (fd == -1) return(-1); cfg_offset = 0x2c; ios_ptr = base_ptr + vm->nvram_rom_space; cfg_ptr = ios_ptr + cfg_offset; nvram_addr = VM_C7200(vm)->npe_driver->nvram_addr; cfg_addr = nvram_addr + vm->nvram_rom_space + cfg_offset; /* Write IOS tag, uncompressed config... */ *PTR_ADJUST(m_uint16_t *,ios_ptr,0x06) = htons(0xF0A5); *PTR_ADJUST(m_uint16_t *,ios_ptr,0x08) = htons(0xABCD); *PTR_ADJUST(m_uint16_t *,ios_ptr,0x0a) = htons(0x0001); *PTR_ADJUST(m_uint16_t *,ios_ptr,0x0c) = htons(0x0000); *PTR_ADJUST(m_uint16_t *,ios_ptr,0x0e) = htons(0x0000); /* Store file contents to NVRAM */ memcpy(cfg_ptr,buffer,len); /* Write config addresses + size */ *PTR_ADJUST(m_uint32_t *,ios_ptr,0x10) = htonl(cfg_addr); *PTR_ADJUST(m_uint32_t *,ios_ptr,0x14) = htonl(cfg_addr + len); *PTR_ADJUST(m_uint32_t *,ios_ptr,0x18) = htonl(len); /* Compute the checksum */ cklen = (vm->nvram_size*1024) - (vm->nvram_rom_space + 0x08); cksum = nvram_cksum((m_uint16_t *)(ios_ptr+0x08),cklen); *PTR_ADJUST(m_uint16_t *,ios_ptr,0x0c) = htons(cksum); vm_mmap_close_file(fd,base_ptr,vm->nvram_size*1024); return(0);}/* Get an EEPROM for a given NPE model */static const struct cisco_eeprom *c7200_get_cpu_eeprom(char *npe_name){ return(cisco_eeprom_find(c7200_cpu_eeprom,npe_name));}/* Get an EEPROM for a given midplane model */static const struct cisco_eeprom *c7200_get_midplane_eeprom(char *midplane_name){ return(cisco_eeprom_find(c7200_midplane_eeprom,midplane_name));}/* Get a PEM EEPROM for a given NPE model */static const struct cisco_eeprom *c7200_get_pem_eeprom(char *npe_name){ return(cisco_eeprom_find(c7200_pem_eeprom,npe_name));}/* Set the base MAC address of the chassis */static int c7200_burn_mac_addr(c7200_t *router,n_eth_addr_t *addr){ m_uint8_t eeprom_ver; /* Read EEPROM format version */ cisco_eeprom_get_byte(&router->mp_eeprom,0,&eeprom_ver); if (eeprom_ver != 1) { vm_error(router->vm,"c7200_burn_mac_addr: unable to handle " "EEPROM version %u\n",eeprom_ver); return(-1); } cisco_eeprom_set_region(&router->mp_eeprom,12,addr->eth_addr_byte,6); return(0);}/* Free specific hardware resources used by C7200 */static void c7200_free_hw_ressources(c7200_t *router){ /* Shutdown all Port Adapters */ c7200_pa_shutdown_all(router); /* Inactivate the PCMCIA bus */ router->pcmcia_bus = NULL; /* Remove the hidden I/O bridge */ if (router->io_pci_bridge != NULL) { pci_bridge_remove(router->io_pci_bridge); router->io_pci_bridge = NULL; }}/* Create a new router instance */c7200_t *c7200_create_instance(char *name,int instance_id){ c7200_t *router; if (!(router = malloc(sizeof(*router)))) { fprintf(stderr,"C7200 '%s': Unable to create new instance!\n",name); return NULL; } memset(router,0,sizeof(*router)); if (!(router->vm = vm_create(name,instance_id,VM_TYPE_C7200))) { fprintf(stderr,"C7200 '%s': unable to create VM instance!\n",name); goto err_vm; } c7200_init_defaults(router); router->vm->hw_data = router; router->vm->elf_machine_id = C7200_ELF_MACHINE_ID; return router; err_vm: free(router); return NULL;}/* Free resources used by a router instance */static int c7200_free_instance(void *data,void *arg){ vm_instance_t *vm = data; c7200_t *router; int i; if (vm->type == VM_TYPE_C7200) { router = VM_C7200(vm); /* Stop all CPUs */ if (vm->cpu_group != NULL) { vm_stop(vm); if (cpu_group_sync_state(vm->cpu_group) == -1) { vm_error(vm,"unable to sync with system CPUs.\n"); return(FALSE); } } /* Remove NIO bindings */ for(i=0;i<C7200_MAX_PA_BAYS;i++) c7200_pa_remove_all_nio_bindings(router,i); /* Free specific HW resources */ c7200_free_hw_ressources(router); /* Free EEPROMs */ cisco_eeprom_free(&router->cpu_eeprom); cisco_eeprom_free(&router->mp_eeprom); cisco_eeprom_free(&router->pem_eeprom); /* Free all resources used by VM */ vm_free(vm); /* Free the router structure */ free(router); return(TRUE); } return(FALSE);}/* Delete a router instance */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -