/[dynamips]/trunk/dev_c7200.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/dev_c7200.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

upstream/dynamips-0.2.6-RC1/dev_c7200.c revision 2 by dpavlin, Sat Oct 6 16:03:58 2007 UTC upstream/dynamips-0.2.7-RC1/dev_c7200.c revision 7 by dpavlin, Sat Oct 6 16:23:47 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   * Cisco 7200 (Predator) simulation platform.   * Cisco router simulation platform.
3   * Copyright (c) 2005,2006 Christophe Fillot (cf@utc.fr)   * Copyright (c) 2005,2006 Christophe Fillot (cf@utc.fr)
4   *   *
5   * Generic Cisco 7200 routines and definitions (EEPROM,...).   * Generic Cisco 7200 routines and definitions (EEPROM,...).
# Line 12  Line 12 
12  #include <sys/types.h>  #include <sys/types.h>
13  #include <assert.h>  #include <assert.h>
14    
15  #include "mips64.h"  #include "cpu.h"
16    #include "vm.h"
17  #include "dynamips.h"  #include "dynamips.h"
18  #include "memory.h"  #include "memory.h"
19    #include "ppc32_mem.h"
20  #include "device.h"  #include "device.h"
21  #include "pci_io.h"  #include "pci_io.h"
22    #include "dev_gt.h"
23    #include "dev_mv64460.h"
24  #include "cisco_eeprom.h"  #include "cisco_eeprom.h"
25    #include "dev_rom.h"
26  #include "dev_c7200.h"  #include "dev_c7200.h"
27  #include "dev_vtty.h"  #include "dev_vtty.h"
28  #include "registry.h"  #include "registry.h"
# Line 87  static m_uint16_t eeprom_cpu_npeg1_data[ Line 92  static m_uint16_t eeprom_cpu_npeg1_data[
92     0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,     0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
93  };  };
94    
95    /* NPE-G2 */
96    static m_uint16_t eeprom_cpu_npeg2_data[64] = {
97       0x04FF, 0x4004, 0xCA41, 0x0201, 0x8744, 0x19BC, 0x0182, 0x4928,
98       0x5901, 0x42FF, 0xFFC1, 0x8B43, 0x534A, 0x3039, 0x3435, 0x3239,
99       0x3237, 0x0400, 0x0201, 0x851C, 0x1DA2, 0x01CB, 0x864E, 0x5045,
100       0x2D47, 0x3280, 0x0000, 0x0000, 0x8956, 0x3031, 0x2DFF, 0xFFFF,
101       0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
102       0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
103       0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
104       0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x15FF,
105    };
106    
107  /*  /*
108   * CPU EEPROM array.   * CPU EEPROM array.
109   */   */
110  static struct c7200_eeprom c7200_cpu_eeprom[] = {  static struct cisco_eeprom c7200_cpu_eeprom[] = {
111     { "npe-100", eeprom_cpu_npe100_data, sizeof(eeprom_cpu_npe100_data)/2 },     { "npe-100", eeprom_cpu_npe100_data, sizeof(eeprom_cpu_npe100_data)/2 },
112     { "npe-150", eeprom_cpu_npe150_data, sizeof(eeprom_cpu_npe150_data)/2 },     { "npe-150", eeprom_cpu_npe150_data, sizeof(eeprom_cpu_npe150_data)/2 },
113     { "npe-175", eeprom_cpu_npe175_data, sizeof(eeprom_cpu_npe175_data)/2 },     { "npe-175", eeprom_cpu_npe175_data, sizeof(eeprom_cpu_npe175_data)/2 },
# Line 99  static struct c7200_eeprom c7200_cpu_eep Line 116  static struct c7200_eeprom c7200_cpu_eep
116     { "npe-300", eeprom_cpu_npe300_data, sizeof(eeprom_cpu_npe300_data)/2 },     { "npe-300", eeprom_cpu_npe300_data, sizeof(eeprom_cpu_npe300_data)/2 },
117     { "npe-400", eeprom_cpu_npe400_data, sizeof(eeprom_cpu_npe400_data)/2 },     { "npe-400", eeprom_cpu_npe400_data, sizeof(eeprom_cpu_npe400_data)/2 },
118     { "npe-g1" , eeprom_cpu_npeg1_data , sizeof(eeprom_cpu_npeg1_data)/2 },     { "npe-g1" , eeprom_cpu_npeg1_data , sizeof(eeprom_cpu_npeg1_data)/2 },
119       { "npe-g2" , eeprom_cpu_npeg2_data , sizeof(eeprom_cpu_npeg2_data)/2 },
120     { NULL, NULL, 0 },     { NULL, NULL, 0 },
121  };  };
122    
# Line 125  static m_uint16_t eeprom_vxr_midplane_da Line 143  static m_uint16_t eeprom_vxr_midplane_da
143  /*  /*
144   * Midplane EEPROM array.   * Midplane EEPROM array.
145   */   */
146  static struct c7200_eeprom c7200_midplane_eeprom[] = {  static struct cisco_eeprom c7200_midplane_eeprom[] = {
147     { "std", eeprom_midplane_data, sizeof(eeprom_midplane_data)/2 },     { "std", eeprom_midplane_data, sizeof(eeprom_midplane_data)/2 },
148     { "vxr", eeprom_vxr_midplane_data, sizeof(eeprom_vxr_midplane_data)/2 },     { "vxr", eeprom_vxr_midplane_data, sizeof(eeprom_vxr_midplane_data)/2 },
149     { NULL, NULL, 0 },     { NULL, NULL, 0 },
# Line 150  static m_uint16_t eeprom_pem_npe225_data Line 168  static m_uint16_t eeprom_pem_npe225_data
168  /*  /*
169   * PEM EEPROM array.   * PEM EEPROM array.
170   */   */
171  static struct c7200_eeprom c7200_pem_eeprom[] = {  static struct cisco_eeprom c7200_pem_eeprom[] = {
172     { "npe-175", eeprom_pem_npe175_data, sizeof(eeprom_pem_npe175_data)/2 },     { "npe-175", eeprom_pem_npe175_data, sizeof(eeprom_pem_npe175_data)/2 },
173     { "npe-225", eeprom_pem_npe225_data, sizeof(eeprom_pem_npe225_data)/2 },     { "npe-225", eeprom_pem_npe225_data, sizeof(eeprom_pem_npe225_data)/2 },
174     { NULL, NULL, 0 },     { NULL, NULL, 0 },
# Line 160  static struct c7200_eeprom c7200_pem_eep Line 178  static struct c7200_eeprom c7200_pem_eep
178  /* Port Adapter Drivers                                                     */  /* Port Adapter Drivers                                                     */
179  /* ======================================================================== */  /* ======================================================================== */
180  static struct c7200_pa_driver *pa_drivers[] = {  static struct c7200_pa_driver *pa_drivers[] = {
181     &dev_c7200_io_fe_driver,     &dev_c7200_iocard_fe_driver,
182       &dev_c7200_iocard_2fe_driver,
183       &dev_c7200_iocard_ge_e_driver,
184     &dev_c7200_pa_fe_tx_driver,     &dev_c7200_pa_fe_tx_driver,
185       &dev_c7200_pa_2fe_tx_driver,
186       &dev_c7200_pa_ge_driver,
187     &dev_c7200_pa_4e_driver,     &dev_c7200_pa_4e_driver,
188     &dev_c7200_pa_8e_driver,     &dev_c7200_pa_8e_driver,
189     &dev_c7200_pa_4t_driver,     &dev_c7200_pa_4t_driver,
190     &dev_c7200_pa_8t_driver,     &dev_c7200_pa_8t_driver,
191     &dev_c7200_pa_a1_driver,     &dev_c7200_pa_a1_driver,
192     &dev_c7200_pa_pos_oc3_driver,     &dev_c7200_pa_pos_oc3_driver,
193     &dev_c7200_pa_4b_driver,     &dev_c7200_pa_4b_driver,  
194       &dev_c7200_pa_mc8te1_driver,
195     NULL,     NULL,
196  };  };
197    
# Line 186  DECLARE_NPE(npe225); Line 209  DECLARE_NPE(npe225);
209  DECLARE_NPE(npe300);  DECLARE_NPE(npe300);
210  DECLARE_NPE(npe400);  DECLARE_NPE(npe400);
211  DECLARE_NPE(npeg1);  DECLARE_NPE(npeg1);
212    DECLARE_NPE(npeg2);
213    
214  static struct c7200_npe_driver npe_drivers[] = {  static struct c7200_npe_driver npe_drivers[] = {
215     { "npe-100" , c7200_init_npe100, 256, 1, C7200_NVRAM_ADDR, 0, 5,  0, 6 },     { "npe-100" , C7200_NPE_FAMILY_MIPS, c7200_init_npe100, 256, 1,
216     { "npe-150" , c7200_init_npe150, 256, 1, C7200_NVRAM_ADDR, 0, 5,  0, 6 },       C7200_NVRAM_ADDR, TRUE, 0, 5,  0, 6 },
217     { "npe-175" , c7200_init_npe175, 256, 1, C7200_NVRAM_ADDR, 2, 16, 1, 0 },     { "npe-150" , C7200_NPE_FAMILY_MIPS, c7200_init_npe150, 256, 1,
218     { "npe-200" , c7200_init_npe200, 256, 1, C7200_NVRAM_ADDR, 0, 5,  0, 6 },       C7200_NVRAM_ADDR, TRUE, 0, 5,  0, 6 },
219     { "npe-225" , c7200_init_npe225, 256, 1, C7200_NVRAM_ADDR, 2, 16, 1, 0 },     { "npe-175" , C7200_NPE_FAMILY_MIPS, c7200_init_npe175, 256, 1,
220     { "npe-300" , c7200_init_npe300, 256, 1, C7200_NVRAM_ADDR, 2, 16, 1, 0 },       C7200_NVRAM_ADDR, TRUE, 2, 16, 1, 0 },
221     { "npe-400" , c7200_init_npe400, 512, 1, C7200_NVRAM_ADDR, 2, 16, 1, 0 },     { "npe-200" , C7200_NPE_FAMILY_MIPS, c7200_init_npe200, 256, 1,
222     { "npe-g1"  , c7200_init_npeg1, 1024, 0,       C7200_NVRAM_ADDR, TRUE, 0, 5,  0, 6 },
223       C7200_NPEG1_NVRAM_ADDR, 17, 16, 16, 0 },     { "npe-225" , C7200_NPE_FAMILY_MIPS, c7200_init_npe225, 256, 1,
224     { NULL      , NULL },       C7200_NVRAM_ADDR, TRUE, 2, 16, 1, 0 },
225  };     { "npe-300" , C7200_NPE_FAMILY_MIPS, c7200_init_npe300, 256, 1,
226         C7200_NVRAM_ADDR, TRUE, 2, 16, 1, 0 },
227  /* ======================================================================== */     { "npe-400" , C7200_NPE_FAMILY_MIPS, c7200_init_npe400, 512, 1,
228  /* Empty EEPROM for PAs                                                     */       C7200_NVRAM_ADDR, TRUE, 2, 16, 1, 0 },
229  /* ======================================================================== */     { "npe-g1"  , C7200_NPE_FAMILY_MIPS, c7200_init_npeg1, 1024, 0,
230  static const m_uint16_t eeprom_pa_empty[64] = {       C7200_G1_NVRAM_ADDR, FALSE, 17, 16, 16, 0 },
231     0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,     { "npe-g2"  , C7200_NPE_FAMILY_PPC , c7200_init_npeg2, 1024, 0,
232     0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,       C7200_G2_NVRAM_ADDR, FALSE, 17, 16, 16, 0 },
233     0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,     { NULL, -1, NULL, -1, -1, 0, -1, -1, -1, -1 },
    0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,  
234  };  };
235    
236  /* ======================================================================== */  /* ======================================================================== */
# Line 217  static const m_uint16_t eeprom_pa_empty[ Line 240  static const m_uint16_t eeprom_pa_empty[
240  /* Directly extract the configuration from the NVRAM device */  /* Directly extract the configuration from the NVRAM device */
241  ssize_t c7200_nvram_extract_config(vm_instance_t *vm,char **buffer)  ssize_t c7200_nvram_extract_config(vm_instance_t *vm,char **buffer)
242  {    {  
243       u_char *base_ptr,*ios_ptr,*cfg_ptr,*end_ptr;
244       m_uint32_t start,end,nvlen,clen;
245       m_uint16_t magic1,magic2;
246     struct vdevice *nvram_dev;     struct vdevice *nvram_dev;
247     m_uint32_t start,end,clen,nvlen;     m_uint64_t nvram_addr;
248     m_uint16_t magic1,magic2;     off_t nvram_size;
249     m_uint64_t addr;     int fd;
250    
251       if ((nvram_dev = dev_get_by_name(vm,"nvram")))
252          dev_sync(nvram_dev);
253    
254     if (!(nvram_dev = dev_get_by_name(vm,"nvram")))     fd = vm_mmap_open_file(vm,"nvram",&base_ptr,&nvram_size);
255    
256       if (fd == -1)
257        return(-1);        return(-1);
258    
259     addr = nvram_dev->phys_addr + vm->nvram_rom_space;     nvram_addr = VM_C7200(vm)->npe_driver->nvram_addr;
260     magic1 = physmem_copy_u16_from_vm(vm,addr+0x06);     ios_ptr = base_ptr + vm->nvram_rom_space;
261     magic2 = physmem_copy_u16_from_vm(vm,addr+0x08);     end_ptr = base_ptr + nvram_size;
262    
263       if ((ios_ptr + 0x30) >= end_ptr) {
264          vm_error(vm,"NVRAM file too small\n");
265          return(-1);
266       }
267    
268       magic1  = ntohs(*PTR_ADJUST(m_uint16_t *,ios_ptr,0x06));
269       magic2  = ntohs(*PTR_ADJUST(m_uint16_t *,ios_ptr,0x08));
270    
271     if ((magic1 != 0xF0A5) || (magic2 != 0xABCD)) {     if ((magic1 != 0xF0A5) || (magic2 != 0xABCD)) {
272        vm_error(vm,"unable to find IOS magic numbers (0x%x,0x%x)!\n",        vm_error(vm,"unable to find IOS magic numbers (0x%x,0x%x)!\n",
# Line 235  ssize_t c7200_nvram_extract_config(vm_in Line 274  ssize_t c7200_nvram_extract_config(vm_in
274        return(-1);        return(-1);
275     }     }
276    
277     start = physmem_copy_u32_from_vm(vm,addr+0x10) + 1;     start = ntohl(*PTR_ADJUST(m_uint32_t *,ios_ptr,0x10)) + 1;
278     end   = physmem_copy_u32_from_vm(vm,addr+0x14);     end   = ntohl(*PTR_ADJUST(m_uint32_t *,ios_ptr,0x14));
279     nvlen = physmem_copy_u32_from_vm(vm,addr+0x18);     nvlen = ntohl(*PTR_ADJUST(m_uint32_t *,ios_ptr,0x18));
280     clen  = end - start;     clen  = end - start;
281    
282     if ((clen + 1) != nvlen) {     if ((clen + 1) != nvlen) {
# Line 245  ssize_t c7200_nvram_extract_config(vm_in Line 284  ssize_t c7200_nvram_extract_config(vm_in
284        return(-1);        return(-1);
285     }     }
286    
287     if ((start <= nvram_dev->phys_addr) || (end <= nvram_dev->phys_addr) ||     if (!(*buffer = malloc(clen+1))) {
288         (end <= start))        vm_error(vm,"unable to allocate config buffer (%u bytes)\n",clen);
    {  
       vm_error(vm,"invalid configuration markers (start=0x%x,end=0x%x)\n",  
                start,end);  
289        return(-1);        return(-1);
290     }     }
291    
292     if (!(*buffer = malloc(clen+1))) {     cfg_ptr = base_ptr + (start - nvram_addr);
293        vm_error(vm,"unable to allocate config buffer (%u bytes)\n",clen);  
294       if ((start < nvram_addr) || ((cfg_ptr + clen) > end_ptr)) {
295          vm_error(vm,"NVRAM file too small\n");
296        return(-1);        return(-1);
297     }     }
298    
299     physmem_copy_from_vm(vm,*buffer,start,clen);     memcpy(*buffer,cfg_ptr,clen);
300     (*buffer)[clen] = 0;     (*buffer)[clen] = 0;
301     return(clen);     return(clen);
302  }  }
303    
304  /* Directly push the IOS configuration to the NVRAM device */  /* Directly push the IOS configuration to the NVRAM device */
305  int c7200_nvram_push_config(vm_instance_t *vm,char *buffer,size_t len)  int c7200_nvram_push_config(vm_instance_t *vm,char *buffer,size_t len)
306  {  {  
307     struct vdevice *nvram_dev;     u_char *base_ptr,*ios_ptr,*cfg_ptr;
308     m_uint64_t addr,cfg_addr;     m_uint32_t cfg_addr,cfg_offset;
309     m_uint32_t cklen;     m_uint32_t nvram_addr,cklen;
310     m_uint16_t cksum;     m_uint16_t cksum;
311       int fd;
312    
313     if (!(nvram_dev = dev_get_by_name(vm,"nvram")))     fd = vm_mmap_create_file(vm,"nvram",vm->nvram_size*1024,&base_ptr);
314    
315       if (fd == -1)
316        return(-1);        return(-1);
317    
318     addr = nvram_dev->phys_addr + vm->nvram_rom_space;     cfg_offset = 0x2c;
319     cfg_addr = addr + 0x2c;     ios_ptr = base_ptr + vm->nvram_rom_space;
320       cfg_ptr = ios_ptr  + cfg_offset;
321    
322       nvram_addr = VM_C7200(vm)->npe_driver->nvram_addr;
323       cfg_addr = nvram_addr + vm->nvram_rom_space + cfg_offset;
324    
325     /* Write IOS tag, uncompressed config... */     /* Write IOS tag, uncompressed config... */
326     physmem_copy_u16_to_vm(vm,addr+0x06,0xF0A5);     *PTR_ADJUST(m_uint16_t *,ios_ptr,0x06) = htons(0xF0A5);
327     physmem_copy_u16_to_vm(vm,addr+0x08,0xABCD);      /* Magic number */     *PTR_ADJUST(m_uint16_t *,ios_ptr,0x08) = htons(0xABCD);
328     physmem_copy_u16_to_vm(vm,addr+0x0a,0x0001);      /* ??? */     *PTR_ADJUST(m_uint16_t *,ios_ptr,0x0a) = htons(0x0001);
329     physmem_copy_u16_to_vm(vm,addr+0x0c,0x0000);      /* zero */     *PTR_ADJUST(m_uint16_t *,ios_ptr,0x0c) = htons(0x0000);
330     physmem_copy_u16_to_vm(vm,addr+0x0e,0x0000);      /* IOS version */     *PTR_ADJUST(m_uint16_t *,ios_ptr,0x0e) = htons(0x0000);
331    
332     /* Store file contents to NVRAM */     /* Store file contents to NVRAM */
333     physmem_copy_to_vm(vm,buffer,cfg_addr,len);     memcpy(cfg_ptr,buffer,len);
334    
335     /* Write config addresses + size */     /* Write config addresses + size */
336     physmem_copy_u32_to_vm(vm,addr+0x10,cfg_addr);     *PTR_ADJUST(m_uint32_t *,ios_ptr,0x10) = htonl(cfg_addr);
337     physmem_copy_u32_to_vm(vm,addr+0x14,cfg_addr + len);     *PTR_ADJUST(m_uint32_t *,ios_ptr,0x14) = htonl(cfg_addr + len);
338     physmem_copy_u32_to_vm(vm,addr+0x18,len);     *PTR_ADJUST(m_uint32_t *,ios_ptr,0x18) = htonl(len);
339    
340     /* Compute the checksum */     /* Compute the checksum */
341     cklen = nvram_dev->phys_len - (vm->nvram_rom_space + 0x08);     cklen = (vm->nvram_size*1024) - (vm->nvram_rom_space + 0x08);
342     cksum = nvram_cksum(vm,addr+0x08,cklen);     cksum = nvram_cksum((m_uint16_t *)(ios_ptr+0x08),cklen);
343     physmem_copy_u16_to_vm(vm,addr+0x0c,cksum);     *PTR_ADJUST(m_uint16_t *,ios_ptr,0x0c) = htons(cksum);
    return(0);  
 }  
   
 /* Find an EEPROM in the specified array */  
 struct c7200_eeprom *c7200_get_eeprom(struct c7200_eeprom *eeproms,char *name)  
 {  
    int i;  
   
    for(i=0;eeproms[i].name;i++)  
       if (!strcmp(eeproms[i].name,name))  
          return(&eeproms[i]);  
344    
345     return NULL;     vm_mmap_close_file(fd,base_ptr,vm->nvram_size*1024);
346       return(0);
347  }  }
348    
349  /* Get an EEPROM for a given NPE model */  /* Get an EEPROM for a given NPE model */
350  struct c7200_eeprom *c7200_get_cpu_eeprom(char *npe_name)  static const struct cisco_eeprom *c7200_get_cpu_eeprom(char *npe_name)
351  {  {
352     return(c7200_get_eeprom(c7200_cpu_eeprom,npe_name));     return(cisco_eeprom_find(c7200_cpu_eeprom,npe_name));
353  }  }
354    
355  /* Get an EEPROM for a given midplane model */  /* Get an EEPROM for a given midplane model */
356  struct c7200_eeprom *c7200_get_midplane_eeprom(char *midplane_name)  static const struct cisco_eeprom *
357    c7200_get_midplane_eeprom(char *midplane_name)
358  {  {
359     return(c7200_get_eeprom(c7200_midplane_eeprom,midplane_name));     return(cisco_eeprom_find(c7200_midplane_eeprom,midplane_name));
360  }  }
361    
362  /* Get a PEM EEPROM for a given NPE model */  /* Get a PEM EEPROM for a given NPE model */
363  struct c7200_eeprom *c7200_get_pem_eeprom(char *npe_name)  static const struct cisco_eeprom *c7200_get_pem_eeprom(char *npe_name)
364  {  {
365     return(c7200_get_eeprom(c7200_pem_eeprom,npe_name));     return(cisco_eeprom_find(c7200_pem_eeprom,npe_name));
366  }  }
367    
368  /* Set the base MAC address of the chassis */  /* Set the base MAC address of the chassis */
369  static int c7200_burn_mac_addr(m_uint16_t *data,size_t data_len,  static int c7200_burn_mac_addr(c7200_t *router,n_eth_addr_t *addr)
                                n_eth_addr_t *addr)  
370  {  {
371     m_uint8_t eeprom_ver;     m_uint8_t eeprom_ver;
372    
373     /* Read EEPROM format version */     /* Read EEPROM format version */
374     cisco_eeprom_get_byte(data,data_len,0,&eeprom_ver);     cisco_eeprom_get_byte(&router->mp_eeprom,0,&eeprom_ver);
375    
376     if (eeprom_ver != 1) {     if (eeprom_ver != 1) {
377        fprintf(stderr,"c7200_burn_mac_addr: unable to handle "        vm_error(router->vm,"c7200_burn_mac_addr: unable to handle "
378                "EEPROM version %u\n",eeprom_ver);                "EEPROM version %u\n",eeprom_ver);
379        return(-1);        return(-1);
380     }     }
381    
382     cisco_eeprom_set_region(data,data_len,12,addr->eth_addr_byte,6);     cisco_eeprom_set_region(&router->mp_eeprom,12,addr->eth_addr_byte,6);
383     return(0);     return(0);
384  }  }
385    
# Line 418  static int c7200_free_instance(void *dat Line 453  static int c7200_free_instance(void *dat
453        /* Free specific HW resources */        /* Free specific HW resources */
454        c7200_free_hw_ressources(router);        c7200_free_hw_ressources(router);
455    
456          /* Free EEPROMs */
457          cisco_eeprom_free(&router->cpu_eeprom);
458          cisco_eeprom_free(&router->mp_eeprom);
459          cisco_eeprom_free(&router->pem_eeprom);
460    
461        /* Free all resources used by VM */        /* Free all resources used by VM */
462        vm_free(vm);        vm_free(vm);
463    
# Line 496  void c7200_save_config_all(FILE *fd) Line 536  void c7200_save_config_all(FILE *fd)
536  /* Set NPE eeprom definition */  /* Set NPE eeprom definition */
537  static int c7200_npe_set_eeprom(c7200_t *router)  static int c7200_npe_set_eeprom(c7200_t *router)
538  {  {
539     struct c7200_eeprom *eeprom;     const struct cisco_eeprom *eeprom;
540    
541     if (!(eeprom = c7200_get_cpu_eeprom(router->npe_driver->npe_type))) {     if (!(eeprom = c7200_get_cpu_eeprom(router->npe_driver->npe_type))) {
542        vm_error(router->vm,"unknown NPE \"%s\" (internal error)!\n",        vm_error(router->vm,"unknown NPE \"%s\" (internal error)!\n",
# Line 504  static int c7200_npe_set_eeprom(c7200_t Line 544  static int c7200_npe_set_eeprom(c7200_t
544        return(-1);        return(-1);
545     }     }
546    
547     router->cpu_eeprom.data = eeprom->data;     if (cisco_eeprom_copy(&router->cpu_eeprom,eeprom) == -1) {
548     router->cpu_eeprom.data_len = eeprom->len;        vm_error(router->vm,"unable to set NPE EEPROM.\n");
549          return(-1);
550       }
551    
552     return(0);     return(0);
553  }  }
554    
555  /* Set PEM eeprom definition */  /* Set PEM eeprom definition */
556  static int c7200_pem_set_eeprom(c7200_t *router)  static int c7200_pem_set_eeprom(c7200_t *router)
557  {  {
558     struct c7200_eeprom *eeprom;     const struct cisco_eeprom *eeprom;
559    
560     if (!(eeprom = c7200_get_pem_eeprom(router->npe_driver->npe_type))) {     if (!(eeprom = c7200_get_pem_eeprom(router->npe_driver->npe_type))) {
561        vm_error(router->vm,"no PEM EEPROM found for NPE type \"%s\"!\n",        vm_error(router->vm,"no PEM EEPROM found for NPE type \"%s\"!\n",
# Line 520  static int c7200_pem_set_eeprom(c7200_t Line 563  static int c7200_pem_set_eeprom(c7200_t
563        return(-1);        return(-1);
564     }     }
565    
566     router->pem_eeprom.data = eeprom->data;     if (cisco_eeprom_copy(&router->pem_eeprom,eeprom) == -1) {
567     router->pem_eeprom.data_len = eeprom->len;        vm_error(router->vm,"unable to set PEM EEPROM.\n");
568          return(-1);
569       }
570    
571     return(0);     return(0);
572  }  }
573    
574  /* Set PA EEPROM definition */  /* Set PA EEPROM definition */
575  int c7200_pa_set_eeprom(c7200_t *router,u_int pa_bay,  int c7200_pa_set_eeprom(c7200_t *router,u_int pa_bay,
576                          const struct c7200_eeprom *eeprom)                          const struct cisco_eeprom *eeprom)
577  {  {
578     if (pa_bay >= C7200_MAX_PA_BAYS) {     if (pa_bay >= C7200_MAX_PA_BAYS) {
579        vm_error(router->vm,"c7200_pa_set_eeprom: invalid PA Bay %u.\n",pa_bay);        vm_error(router->vm,"c7200_pa_set_eeprom: invalid PA Bay %u.\n",pa_bay);
580        return(-1);        return(-1);
581     }     }
582      
583     router->pa_bay[pa_bay].eeprom.data = eeprom->data;     if (cisco_eeprom_copy(&router->pa_bay[pa_bay].eeprom,eeprom) == -1) {
584     router->pa_bay[pa_bay].eeprom.data_len = eeprom->len;        vm_error(router->vm,"c7200_pa_set_eeprom: no memory.\n");
585          return(-1);
586       }
587    
588     return(0);     return(0);
589  }  }
590    
# Line 547  int c7200_pa_unset_eeprom(c7200_t *route Line 596  int c7200_pa_unset_eeprom(c7200_t *route
596        return(-1);        return(-1);
597     }     }
598        
599     router->pa_bay[pa_bay].eeprom.data = (m_uint16_t *)eeprom_pa_empty;     cisco_eeprom_free(&router->pa_bay[pa_bay].eeprom);
    router->pa_bay[pa_bay].eeprom.data_len = sizeof(eeprom_pa_empty)/2;  
600     return(0);     return(0);
601  }  }
602    
603  /* Check if a bay has a port adapter */  /* Check if a bay has a port adapter */
604  int c7200_pa_check_eeprom(c7200_t *router,u_int pa_bay)  int c7200_pa_check_eeprom(c7200_t *router,u_int pa_bay)
605  {  {
606     struct nmc93c46_eeprom_def *def;     if (pa_bay >= C7200_MAX_PA_BAYS)
607          return(FALSE);
    if (!pa_bay || (pa_bay >= C7200_MAX_PA_BAYS))  
       return(0);  
   
    def = &router->pa_bay[pa_bay].eeprom;  
     
    if (def->data == eeprom_pa_empty)  
       return(0);  
608    
609     return(1);     return(cisco_eeprom_valid(&router->pa_bay[pa_bay].eeprom));
610  }  }
611    
612  /* Get bay info */  /* Get bay info */
# Line 1208  void c7200_npe_show_drivers(void) Line 1249  void c7200_npe_show_drivers(void)
1249  /* Set Midplane type */  /* Set Midplane type */
1250  int c7200_midplane_set_type(c7200_t *router,char *midplane_type)  int c7200_midplane_set_type(c7200_t *router,char *midplane_type)
1251  {  {
1252     struct c7200_eeprom *eeprom;     const struct cisco_eeprom *eeprom;
1253     m_uint8_t version;     m_uint8_t version;
1254    
1255     if (router->vm->status == VM_STATUS_RUNNING) {     if (router->vm->status == VM_STATUS_RUNNING) {
# Line 1222  int c7200_midplane_set_type(c7200_t *rou Line 1263  int c7200_midplane_set_type(c7200_t *rou
1263        return(-1);        return(-1);
1264     }     }
1265    
1266     memcpy(router->mp_eeprom_data,eeprom->data,eeprom->len << 1);     /* Copy the midplane EEPROM */
1267       if (cisco_eeprom_copy(&router->mp_eeprom,eeprom) == -1) {
1268          vm_error(router->vm,"unable to set midplane EEPROM.\n");
1269          return(-1);
1270       }
1271    
1272     /* Set the chassis base MAC address */     /* Set the chassis base MAC address */
1273     c7200_burn_mac_addr(router->mp_eeprom_data,sizeof(router->mp_eeprom_data),     c7200_burn_mac_addr(router,&router->mac_addr);
                        &router->mac_addr);  
   
    router->mp_eeprom.data = router->mp_eeprom_data;  
    router->mp_eeprom.data_len = eeprom->len;  
    router->midplane_type = eeprom->name;  
1274    
1275     /* Get the midplane version */     /* Get the midplane version */
1276     cisco_eeprom_get_byte(router->mp_eeprom.data,router->mp_eeprom.data_len*2,     cisco_eeprom_get_byte(&router->mp_eeprom,2,&version);
1277                           2,&version);     router->midplane_version = version;  
1278     router->midplane_version = version;     router->midplane_type = eeprom->name;
1279     return(0);     return(0);
1280  }  }
1281    
# Line 1248  int c7200_midplane_set_mac_addr(c7200_t Line 1288  int c7200_midplane_set_mac_addr(c7200_t
1288     }     }
1289    
1290     /* Set the chassis base MAC address */     /* Set the chassis base MAC address */
1291     c7200_burn_mac_addr(router->mp_eeprom_data,sizeof(router->mp_eeprom_data),     c7200_burn_mac_addr(router,&router->mac_addr);
                        &router->mac_addr);  
1292     return(0);     return(0);
1293  }  }
1294    
# Line 1310  static int c7200_init_dual_gt64120(c7200 Line 1349  static int c7200_init_dual_gt64120(c7200
1349     return(0);     return(0);
1350  }  }
1351    
1352    /* Create the two main PCI busses for a MV64460 based system */
1353    static int c7200_init_mv64460(c7200_t *router)
1354    {
1355       vm_instance_t *vm = router->vm;
1356    
1357       vm->pci_bus[0] = pci_bus_create("MB0/MB1",3);
1358       vm->pci_bus[1] = pci_bus_create("MB2",0);
1359    
1360       if (!vm->pci_bus[0] || !vm->pci_bus[1]) {
1361          vm_error(vm,"unable to create PCI data.\n");
1362          return(-1);
1363       }
1364    
1365       return(dev_mv64460_init(vm,"mv64460",C7200_G2_MV64460_ADDR,0x10000));
1366    }
1367    
1368  /* Create the PA PCI busses */  /* Create the PA PCI busses */
1369  static int c7200_pa_create_pci_busses(c7200_t *router)  static int c7200_pa_create_pci_busses(c7200_t *router)
1370  {    {  
# Line 1385  int c7200_init_npe100(c7200_t *router) Line 1440  int c7200_init_npe100(c7200_t *router)
1440     int i;     int i;
1441    
1442     /* Set the processor type: R4600 */     /* Set the processor type: R4600 */
1443     mips64_set_prid(vm->boot_cpu,MIPS_PRID_R4600);     mips64_set_prid(CPU_MIPS64(vm->boot_cpu),MIPS_PRID_R4600);
1444    
1445     /* Initialize the Galileo GT-64010 system controller */     /* Initialize the Galileo GT-64010 system controller */
1446     if (c7200_init_gt64010(router) == -1)     if (c7200_init_gt64010(router) == -1)
# Line 1433  int c7200_init_npe150(c7200_t *router) Line 1488  int c7200_init_npe150(c7200_t *router)
1488     int i;     int i;
1489    
1490     /* Set the processor type: R4700 */     /* Set the processor type: R4700 */
1491     mips64_set_prid(vm->boot_cpu,MIPS_PRID_R4700);     mips64_set_prid(CPU_MIPS64(vm->boot_cpu),MIPS_PRID_R4700);
1492    
1493     /* Initialize the Galileo GT-64010 system controller */     /* Initialize the Galileo GT-64010 system controller */
1494     if (c7200_init_gt64010(router) == -1)     if (c7200_init_gt64010(router) == -1)
# Line 1489  int c7200_init_npe175(c7200_t *router) Line 1544  int c7200_init_npe175(c7200_t *router)
1544     int i;     int i;
1545    
1546     /* Set the processor type: R5271 */     /* Set the processor type: R5271 */
1547     mips64_set_prid(vm->boot_cpu,MIPS_PRID_R527x);     mips64_set_prid(CPU_MIPS64(vm->boot_cpu),MIPS_PRID_R527x);
1548    
1549     /* Initialize the Galileo GT-64120 PCI controller */     /* Initialize the Galileo GT-64120 PCI controller */
1550     if (c7200_init_gt64120(router) == -1)     if (c7200_init_gt64120(router) == -1)
# Line 1534  int c7200_init_npe200(c7200_t *router) Line 1589  int c7200_init_npe200(c7200_t *router)
1589     int i;     int i;
1590    
1591     /* Set the processor type: R5000 */     /* Set the processor type: R5000 */
1592     mips64_set_prid(vm->boot_cpu,MIPS_PRID_R5000);     mips64_set_prid(CPU_MIPS64(vm->boot_cpu),MIPS_PRID_R5000);
1593    
1594     /* Initialize the Galileo GT-64010 PCI controller */     /* Initialize the Galileo GT-64010 PCI controller */
1595     if (c7200_init_gt64010(router) == -1)     if (c7200_init_gt64010(router) == -1)
# Line 1590  int c7200_init_npe225(c7200_t *router) Line 1645  int c7200_init_npe225(c7200_t *router)
1645     int i;     int i;
1646    
1647     /* Set the processor type: R5271 */     /* Set the processor type: R5271 */
1648     mips64_set_prid(vm->boot_cpu,MIPS_PRID_R527x);     mips64_set_prid(CPU_MIPS64(vm->boot_cpu),MIPS_PRID_R527x);
1649    
1650     /* Initialize the Galileo GT-64120 PCI controller */     /* Initialize the Galileo GT-64120 PCI controller */
1651     if (c7200_init_gt64120(router) == -1)     if (c7200_init_gt64120(router) == -1)
# Line 1634  int c7200_init_npe300(c7200_t *router) Line 1689  int c7200_init_npe300(c7200_t *router)
1689     int i;     int i;
1690    
1691     /* Set the processor type: R7000 */     /* Set the processor type: R7000 */
1692     mips64_set_prid(vm->boot_cpu,MIPS_PRID_R7000);     mips64_set_prid(CPU_MIPS64(vm->boot_cpu),MIPS_PRID_R7000);
1693    
1694     /* 32 Mb of I/O memory */     /* 32 Mb of I/O memory */
1695     vm->iomem_size = 32;     vm->iomem_size = 32;
1696     dev_ram_init(vm,"iomem",vm->ram_mmap,C7200_IOMEM_ADDR,32*1048576);     dev_ram_init(vm,"iomem",vm->ram_mmap,TRUE,NULL,vm->sparse_mem,
1697                    C7200_IOMEM_ADDR,32*1048576);
1698    
1699     /* Initialize the two Galileo GT-64120 system controllers */     /* Initialize the two Galileo GT-64120 system controllers */
1700     if (c7200_init_dual_gt64120(router) == -1)     if (c7200_init_dual_gt64120(router) == -1)
# Line 1687  int c7200_init_npe400(c7200_t *router) Line 1743  int c7200_init_npe400(c7200_t *router)
1743     int i;     int i;
1744    
1745     /* Set the processor type: R7000 */     /* Set the processor type: R7000 */
1746     mips64_set_prid(vm->boot_cpu,MIPS_PRID_R7000);     mips64_set_prid(CPU_MIPS64(vm->boot_cpu),MIPS_PRID_R7000);
1747    
1748     /*     /*
1749      * Add supplemental memory (as "iomem") if we have more than 256 Mb.      * Add supplemental memory (as "iomem") if we have more than 256 Mb.
# Line 1695  int c7200_init_npe400(c7200_t *router) Line 1751  int c7200_init_npe400(c7200_t *router)
1751     if (vm->ram_size > C7200_BASE_RAM_LIMIT) {     if (vm->ram_size > C7200_BASE_RAM_LIMIT) {
1752        vm->iomem_size = vm->ram_size - C7200_BASE_RAM_LIMIT;        vm->iomem_size = vm->ram_size - C7200_BASE_RAM_LIMIT;
1753        vm->ram_size = C7200_BASE_RAM_LIMIT;        vm->ram_size = C7200_BASE_RAM_LIMIT;
1754        dev_ram_init(vm,"ram1",vm->ram_mmap,        dev_ram_init(vm,"ram1",vm->ram_mmap,TRUE,NULL,vm->sparse_mem,
1755                     C7200_IOMEM_ADDR,vm->iomem_size*1048576);                     C7200_IOMEM_ADDR,vm->iomem_size*1048576);
1756     }     }
1757    
# Line 1738  int c7200_init_npeg1(c7200_t *router) Line 1794  int c7200_init_npeg1(c7200_t *router)
1794     int i;     int i;
1795    
1796     /* Just some tests */     /* Just some tests */
1797     mips64_set_prid(vm->boot_cpu,MIPS_PRID_BCM1250);     mips64_set_prid(CPU_MIPS64(vm->boot_cpu),MIPS_PRID_BCM1250);
1798     vm->pci_bus[0] = pci_bus_create("HT/PCI bus",0);     vm->pci_bus[0] = pci_bus_create("HT/PCI bus",0);
1799    
1800     /* SB-1 System control devices */     /* SB-1 System control devices */
# Line 1789  int c7200_init_npeg1(c7200_t *router) Line 1845  int c7200_init_npeg1(c7200_t *router)
1845     return(0);     return(0);
1846  }  }
1847    
1848    /* Initialize an NPE-G2 board (XXX not working) */
1849    int c7200_init_npeg2(c7200_t *router)
1850    {    
1851       vm_instance_t *vm = router->vm;
1852       int i;
1853    
1854       /* Set the processor type: PowerPC G4 */
1855       ppc32_set_pvr(CPU_PPC32(vm->boot_cpu),0x80040201);
1856    
1857       /* Initialize the PA PCI busses */
1858       if (c7200_pa_create_pci_busses(router) == -1)
1859          return(-1);
1860    
1861       /* Create PCI bus for PA Bay 0 (I/O Card, PCMCIA, Interfaces) */
1862       vm->pci_bus_pool[0] = pci_bus_create("PA Slot 0",-1);
1863    
1864       /* PCI bridge for I/O card device on MB0 */
1865       dev_plx6520cb_init(vm->pci_bus[1],3,vm->pci_bus_pool[0]);
1866    
1867       /* Create PCI busses for PA Bays 1,3,5 and PA Bays 2,4,6 */
1868       vm->pci_bus_pool[24] = pci_bus_create("PA Slots 1,3,5",-1);
1869       vm->pci_bus_pool[25] = pci_bus_create("PA Slots 2,4,6",-1);
1870    
1871       dev_plx6520cb_init(vm->pci_bus[0],1,vm->pci_bus_pool[24]);
1872       dev_plx6520cb_init(vm->pci_bus[0],2,vm->pci_bus_pool[25]);
1873    
1874       /* Create the hidden "I/O" PCI bridge for PCMCIA controller */
1875       c7200_create_io_pci_bridge(router,vm->pci_bus_pool[0]);
1876    
1877       /* Map the PA PCI busses */
1878       router->pa_bay[0].pci_map = vm->pci_bus_pool[0];
1879    
1880       for(i=1;i<C7200_MAX_PA_BAYS;i++)
1881          router->pa_bay[i].pci_map = vm->pci_bus_pool[i];
1882    
1883       /* PCI bridges for PA Bays 1 to 6 */
1884       c7200_pa_init_pci_bridge(router,1,vm->pci_bus_pool[24],1);
1885       c7200_pa_init_pci_bridge(router,3,vm->pci_bus_pool[24],2);
1886       c7200_pa_init_pci_bridge(router,5,vm->pci_bus_pool[24],3);
1887    
1888       c7200_pa_init_pci_bridge(router,2,vm->pci_bus_pool[25],1);
1889       c7200_pa_init_pci_bridge(router,4,vm->pci_bus_pool[25],2);
1890       c7200_pa_init_pci_bridge(router,6,vm->pci_bus_pool[25],3);
1891       return(0);
1892    }
1893    
1894  /* Show C7200 hardware info */  /* Show C7200 hardware info */
1895  void c7200_show_hardware(c7200_t *router)  void c7200_show_hardware(c7200_t *router)
1896  {  {
# Line 1823  void c7200_init_defaults(c7200_t *router Line 1925  void c7200_init_defaults(c7200_t *router
1925    
1926     /* Generate a chassis MAC address based on the instance ID */     /* Generate a chassis MAC address based on the instance ID */
1927     m = &router->mac_addr;     m = &router->mac_addr;
1928     m->eth_addr_byte[0] = 0xCA;     m->eth_addr_byte[0] = vm_get_mac_addr_msb(vm);
1929     m->eth_addr_byte[1] = vm->instance_id & 0xFF;     m->eth_addr_byte[1] = vm->instance_id & 0xFF;
1930     m->eth_addr_byte[2] = pid >> 8;     m->eth_addr_byte[2] = pid >> 8;
1931     m->eth_addr_byte[3] = pid & 0xFF;     m->eth_addr_byte[3] = pid & 0xFF;
# Line 1845  void c7200_init_defaults(c7200_t *router Line 1947  void c7200_init_defaults(c7200_t *router
1947    
1948     vm->pcmcia_disk_size[0] = C7200_DEFAULT_DISK0_SIZE;     vm->pcmcia_disk_size[0] = C7200_DEFAULT_DISK0_SIZE;
1949     vm->pcmcia_disk_size[1] = C7200_DEFAULT_DISK1_SIZE;     vm->pcmcia_disk_size[1] = C7200_DEFAULT_DISK1_SIZE;
1950    
1951       /* Enable NVRAM operations to load/store configs */
1952       vm->nvram_extract_config = c7200_nvram_extract_config;
1953       vm->nvram_push_config = c7200_nvram_push_config;
1954  }  }
1955    
1956  /* Run the checklist */  /* Run the checklist */
1957  int c7200_checklist(c7200_t *router)  static int c7200_checklist(c7200_t *router)
1958  {  {
1959     struct vm_instance *vm = router->vm;     struct vm_instance *vm = router->vm;
1960     int res = 0;     int res = 0;
# Line 1864  int c7200_checklist(c7200_t *router) Line 1970  int c7200_checklist(c7200_t *router)
1970     return(res);     return(res);
1971  }  }
1972    
1973  /* Initialize the C7200 Platform */  /* Initialize Port Adapters */
1974  int c7200_init_platform(c7200_t *router)  static int c7200_init_platform_pa(c7200_t *router)
1975  {  {
1976     struct vm_instance *vm = router->vm;     vm_instance_t *vm = router->vm;
1977     struct c7200_pa_bay *pa_bay;     struct c7200_pa_bay *pa_bay;
    cpu_mips_t *cpu0;  
1978     int i;     int i;
1979    
1980       /* Initialize Port Adapters */
1981       for(i=0;i<C7200_MAX_PA_BAYS;i++) {
1982          pa_bay = &router->pa_bay[i];
1983    
1984          if (!pa_bay->dev_type)
1985             continue;
1986    
1987          if (c7200_pa_init(router,i) == -1) {
1988             vm_error(vm,"unable to create Port Adapter \"%s\"\n",
1989                      pa_bay->dev_type);
1990             return(-1);
1991          }
1992       }
1993    
1994       /*
1995        * By default, initialize a C7200-IO-FE in slot 0 if nothing found.
1996        * We only do that for NPEs that require an IO card (all excepted G1/G2).
1997        */
1998       if (router->npe_driver->iocard_required && !router->pa_bay[0].drv_info) {
1999          c7200_pa_add_binding(router,"C7200-IO-FE",0);
2000          c7200_pa_init(router,0);
2001       }
2002    
2003       return(0);
2004    }
2005    
2006    /* Initialize the C7200 Platform (MIPS) */
2007    static int c7200m_init_platform(c7200_t *router)
2008    {
2009       struct vm_instance *vm = router->vm;
2010       cpu_mips_t *cpu0;
2011       cpu_gen_t *gen0;
2012    
2013     /* Copy config register setup into "active" config register */     /* Copy config register setup into "active" config register */
2014     vm->conf_reg = vm->conf_reg_setup;     vm->conf_reg = vm->conf_reg_setup;
2015    
# Line 1891  int c7200_init_platform(c7200_t *router) Line 2029  int c7200_init_platform(c7200_t *router)
2029     vm->cpu_group = cpu_group_create("System CPU");     vm->cpu_group = cpu_group_create("System CPU");
2030    
2031     /* Initialize the virtual MIPS processor */     /* Initialize the virtual MIPS processor */
2032     if (!(cpu0 = cpu_create(vm,0))) {     if (!(gen0 = cpu_create(vm,CPU_TYPE_MIPS64,0))) {
2033        vm_error(vm,"unable to create CPU0!\n");        vm_error(vm,"unable to create CPU0!\n");
2034        return(-1);        return(-1);
2035     }     }
2036    
2037       cpu0 = CPU_MIPS64(gen0);
2038    
2039     /* Add this CPU to the system CPU group */     /* Add this CPU to the system CPU group */
2040     cpu_group_add(vm->cpu_group,cpu0);     cpu_group_add(vm->cpu_group,gen0);
2041     vm->boot_cpu = cpu0;     vm->boot_cpu = gen0;
2042    
2043       /* Initialize the IRQ routing vectors */
2044       vm->set_irq = mips64_vm_set_irq;
2045       vm->clear_irq = mips64_vm_clear_irq;
2046    
2047     /* Mark the Network IO interrupt as high priority */     /* Mark the Network IO interrupt as high priority */
2048     cpu0->irq_idle_preempt[C7200_NETIO_IRQ] = TRUE;     cpu0->irq_idle_preempt[C7200_NETIO_IRQ] = TRUE;
2049       cpu0->irq_idle_preempt[C7200_GT64K_IRQ] = TRUE;
2050    
2051     /* Copy some parameters from VM to CPU0 (idle PC, ...) */     /* Copy some parameters from VM to CPU0 (idle PC, ...) */
2052     cpu0->idle_pc = vm->idle_pc;     cpu0->idle_pc = vm->idle_pc;
# Line 1928  int c7200_init_platform(c7200_t *router) Line 2073  int c7200_init_platform(c7200_t *router)
2073     /* Bit-bucket zone */     /* Bit-bucket zone */
2074     dev_zero_init(vm,"zero",C7200_BITBUCKET_ADDR,0xc00000);     dev_zero_init(vm,"zero",C7200_BITBUCKET_ADDR,0xc00000);
2075    
2076       /* Initialize the NPE board */
2077       if (router->npe_driver->npe_init(router) == -1)
2078          return(-1);
2079    
2080       /* Initialize RAM */
2081       vm_ram_init(vm,0x00000000ULL);
2082    
2083       /* Initialize ROM */
2084       if (!vm->rom_filename) {
2085          /* use embedded ROM */
2086          dev_rom_init(vm,"rom",C7200_ROM_ADDR,vm->rom_size*1048576,
2087                       mips64_microcode,mips64_microcode_len);
2088       } else {
2089          /* use alternate ROM */
2090          dev_ram_init(vm,"rom",TRUE,TRUE,NULL,FALSE,
2091                       C7200_ROM_ADDR,vm->rom_size*1048576);
2092       }
2093    
2094       /* Byte swapping */
2095       dev_bswap_init(vm,"mem_bswap",C7200_BSWAP_ADDR,512*1048576,0x00000000ULL);
2096    
2097       /* PCI IO space */
2098       if (!(vm->pci_io_space = pci_io_data_init(vm,C7200_PCI_IO_ADDR)))
2099          return(-1);
2100    
2101       /* Cirrus Logic PD6729 (PCI-to-PCMCIA host adapter) */
2102       dev_clpd6729_init(vm,router->pcmcia_bus,
2103                         router->npe_driver->clpd6729_pci_dev,
2104                         vm->pci_io_space,0x402,0x403);
2105    
2106       /* Initialize the Port Adapters */
2107       if (c7200_init_platform_pa(router) == -1)
2108          return(-1);
2109    
2110       /* Verify the check list */
2111       if (c7200_checklist(router) == -1)
2112          return(-1);
2113    
2114     /* Midplane FPGA */     /* Midplane FPGA */
2115     dev_c7200_mpfpga_init(router,C7200_MPFPGA_ADDR,0x1000);     dev_c7200_mpfpga_init(router,C7200_MPFPGA_ADDR,0x1000);
2116    
# Line 1935  int c7200_init_platform(c7200_t *router) Line 2118  int c7200_init_platform(c7200_t *router)
2118     if (dev_c7200_iofpga_init(router,C7200_IOFPGA_ADDR,0x1000) == -1)     if (dev_c7200_iofpga_init(router,C7200_IOFPGA_ADDR,0x1000) == -1)
2119        return(-1);        return(-1);
2120    
2121       /* Show device list */
2122       c7200_show_hardware(router);
2123       return(0);
2124    }
2125    
2126    /* Initialize the C7200 Platform (PowerPC) */
2127    static int c7200p_init_platform(c7200_t *router)
2128    {
2129       struct vm_instance *vm = router->vm;
2130       vm_obj_t *obj;
2131       cpu_ppc_t *cpu0;
2132       cpu_gen_t *gen0;
2133    
2134       /* Copy config register setup into "active" config register */
2135       vm->conf_reg = vm->conf_reg_setup;
2136    
2137       /* Create Console and AUX ports */
2138       vm_init_vtty(vm);
2139    
2140       /* Check that the amount of RAM is valid */
2141       if (vm->ram_size > router->npe_driver->max_ram_size) {
2142          vm_error(vm,"%u is not a valid RAM size for this NPE. "
2143                   "Fallback to %u Mb.\n\n",
2144                   vm->ram_size,router->npe_driver->max_ram_size);
2145      
2146          vm->ram_size = router->npe_driver->max_ram_size;
2147       }
2148    
2149       /* Create a CPU group */
2150       vm->cpu_group = cpu_group_create("System CPU");
2151    
2152       /* Initialize the virtual PowerPC processor */
2153       if (!(gen0 = cpu_create(vm,CPU_TYPE_PPC32,0))) {
2154          vm_error(vm,"unable to create CPU0!\n");
2155          return(-1);
2156       }
2157    
2158       cpu0 = CPU_PPC32(gen0);
2159    
2160       /* Add this CPU to the system CPU group */
2161       cpu_group_add(vm->cpu_group,gen0);
2162       vm->boot_cpu = gen0;
2163    
2164       /* Mark the Network IO interrupt as high priority */
2165       cpu0->irq_idle_preempt[C7200_NETIO_IRQ] = TRUE;
2166    
2167       /* Copy some parameters from VM to CPU0 (idle PC, ...) */
2168       cpu0->idle_pc = vm->idle_pc;
2169    
2170       if (vm->timer_irq_check_itv)
2171          cpu0->timer_irq_check_itv = vm->timer_irq_check_itv;
2172    
2173       /* Initialize the Marvell MV-64460 system controller */
2174       if (c7200_init_mv64460(router) == -1)
2175          return(-1);
2176    
2177       if (!(obj = vm_object_find(router->vm,"mv64460")))
2178          return(-1);
2179    
2180       router->mv64460_sysctr = obj->data;
2181    
2182       /* Remote emulator control */
2183       dev_remote_control_init(vm,0xf6000000,0x1000);
2184    
2185       /* Bootflash */
2186       dev_bootflash_init(vm,"bootflash",C7200_G2_BOOTFLASH_ADDR,(64 * 1048576));
2187    
2188       /* NVRAM and calendar */
2189       vm->nvram_size = C7200_G2_NVRAM_SIZE / 1024;
2190       dev_nvram_init(vm,"nvram",router->npe_driver->nvram_addr,
2191                      C7200_G2_NVRAM_SIZE,&vm->conf_reg);
2192    
2193     /* Initialize the NPE board */     /* Initialize the NPE board */
2194     if (router->npe_driver->npe_init(router) == -1)     if (router->npe_driver->npe_init(router) == -1)
2195        return(-1);        return(-1);
2196    
2197     /* Initialize RAM */     /* Initialize RAM */
2198     dev_ram_init(vm,"ram",vm->ram_mmap,0x00000000ULL,vm->ram_size*1048576);     vm_ram_init(vm,0x00000000ULL);
2199    
2200     /* Initialize ROM */     /* Initialize ROM */
2201     if (!vm->rom_filename) {     if (!vm->rom_filename) {
2202        /* use embedded ROM */        /* use embedded ROM */
2203        dev_rom_init(vm,"rom",C7200_ROM_ADDR,vm->rom_size*1048576);        dev_rom_init(vm,"rom",C7200_G2_ROM_ADDR,vm->rom_size*1048576,
2204                       ppc32_microcode,ppc32_microcode_len);
2205     } else {     } else {
2206        /* use alternate ROM */        /* use alternate ROM */
2207        dev_ram_init(vm,"rom",TRUE,C7200_ROM_ADDR,vm->rom_size*1048576);        dev_ram_init(vm,"rom",TRUE,TRUE,NULL,FALSE,
2208                       C7200_G2_ROM_ADDR,vm->rom_size*1048576);
2209     }     }
2210    
2211       /* Byte swapping */
2212       dev_bswap_init(vm,"mem_bswap",C7200_G2_BSWAP_ADDR,512*1048576,
2213                      0x00000000ULL);
2214    
2215     /* PCI IO space */     /* PCI IO space */
2216     if (!(vm->pci_io_space = pci_io_data_init(vm,C7200_PCI_IO_ADDR)))     if (!(vm->pci_io_space = pci_io_data_init(vm,C7200_G2_PCI_IO_ADDR)))
2217        return(-1);        return(-1);
2218    
2219     /* Cirrus Logic PD6729 (PCI-to-PCMCIA host adapter) */     /* Cirrus Logic PD6729 (PCI-to-PCMCIA host adapter) */
# Line 1960  int c7200_init_platform(c7200_t *router) Line 2221  int c7200_init_platform(c7200_t *router)
2221                       router->npe_driver->clpd6729_pci_dev,                       router->npe_driver->clpd6729_pci_dev,
2222                       vm->pci_io_space,0x402,0x403);                       vm->pci_io_space,0x402,0x403);
2223    
2224     /* Initialize Port Adapters */     /* Initialize the Port Adapters */
2225     for(i=0;i<C7200_MAX_PA_BAYS;i++) {     if (c7200_init_platform_pa(router) == -1)
2226        pa_bay = &router->pa_bay[i];        return(-1);
2227      
2228        if (!pa_bay->dev_type)     /* IO FPGA */
2229           continue;     if (dev_c7200_iofpga_init(router,C7200_G2_IOFPGA_ADDR,0x1000) == -1)
2230          return(-1);
2231    
2232        if (c7200_pa_init(router,i) == -1) {     /* MP FPGA */
2233           vm_error(vm,"unable to create Port Adapter \"%s\"\n",     if (dev_c7200_mpfpga_init(router,C7200_G2_MPFPGA_ADDR,0x10000) == -1)
2234                    pa_bay->dev_type);        return(-1);
          return(-1);  
       }  
    }  
2235    
2236     /* By default, initialize a C7200-IO-FE in slot 0 if nothing found */     /* If we have nothing in slot 0, the console is handled by the MV64460 */
2237     if (!router->pa_bay[0].drv_info) {     if (!c7200_pa_check_eeprom(router,0)) {
2238        c7200_pa_add_binding(router,"C7200-IO-FE",0);        vm_log(vm,"CONSOLE","console managed by NPE-G2 board\n");
2239        c7200_pa_init(router,0);        mv64460_sdma_bind_vtty(router->mv64460_sysctr,0,vm->vtty_con);
2240          mv64460_sdma_bind_vtty(router->mv64460_sysctr,1,vm->vtty_aux);
2241     }     }
2242    
    /* Enable NVRAM operations to load/store configs */  
    vm->nvram_extract_config = c7200_nvram_extract_config;  
    vm->nvram_push_config = c7200_nvram_push_config;  
   
    /* Verify the check list */  
    if (c7200_checklist(router) == -1)  
       return(-1);  
   
2243     /* Show device list */     /* Show device list */
2244     c7200_show_hardware(router);     c7200_show_hardware(router);
2245     return(0);     return(0);
2246  }  }
2247    
2248  /* Boot the IOS image */  /* Boot the IOS image (MIPS) */
2249  int c7200_boot_ios(c7200_t *router)  static int c7200m_boot_ios(c7200_t *router)
2250  {    {  
2251     vm_instance_t *vm = router->vm;     vm_instance_t *vm = router->vm;
2252       cpu_mips_t *cpu;
2253    
2254     if (!vm->boot_cpu)     if (!vm->boot_cpu)
2255        return(-1);        return(-1);
# Line 2011  int c7200_boot_ios(c7200_t *router) Line 2264  int c7200_boot_ios(c7200_t *router)
2264     }     }
2265    
2266     /* Reset the boot CPU */     /* Reset the boot CPU */
2267     mips64_reset(vm->boot_cpu);     cpu = CPU_MIPS64(vm->boot_cpu);
2268       mips64_reset(cpu);
2269    
2270     /* Load IOS image */     /* Load IOS image */
2271     if (mips64_load_elf_image(vm->boot_cpu,vm->ios_image,     if (mips64_load_elf_image(cpu,vm->ios_image,
2272                               &vm->ios_entry_point) < 0)                               (vm->ghost_status == VM_GHOST_RAM_USE),
2273                                 &vm->ios_entry_point) < 0)
2274     {     {
2275        vm_error(vm,"failed to load Cisco IOS image '%s'.\n",vm->ios_image);        vm_error(vm,"failed to load Cisco IOS image '%s'.\n",vm->ios_image);
2276        return(-1);        return(-1);
# Line 2024  int c7200_boot_ios(c7200_t *router) Line 2279  int c7200_boot_ios(c7200_t *router)
2279     /* Launch the simulation */     /* Launch the simulation */
2280     printf("\nC7200 '%s': starting simulation (CPU0 PC=0x%llx), "     printf("\nC7200 '%s': starting simulation (CPU0 PC=0x%llx), "
2281            "JIT %sabled.\n",            "JIT %sabled.\n",
2282            vm->name,vm->boot_cpu->pc,vm->jit_use ? "en":"dis");            vm->name,cpu->pc,vm->jit_use ? "en":"dis");
2283    
2284     vm_log(vm,"C7200_BOOT",     vm_log(vm,"C7200_BOOT",
2285            "starting instance (CPU0 PC=0x%llx,idle_pc=0x%llx,JIT %s)\n",            "starting instance (CPU0 PC=0x%llx,idle_pc=0x%llx,JIT %s)\n",
2286            vm->boot_cpu->pc,vm->boot_cpu->idle_pc,vm->jit_use ? "on":"off");            cpu->pc,cpu->idle_pc,vm->jit_use ? "on":"off");
2287        
2288     /* Start main CPU */     /* Start main CPU */
2289     vm->status = VM_STATUS_RUNNING;     if (vm->ghost_status != VM_GHOST_RAM_GENERATE) {
2290     cpu_start(vm->boot_cpu);        vm->status = VM_STATUS_RUNNING;
2291          cpu_start(vm->boot_cpu);
2292       } else {
2293          vm->status = VM_STATUS_SHUTDOWN;
2294       }
2295     return(0);     return(0);
2296  }  }
2297    
2298  /* Initialize a Cisco 7200 instance */  /* Boot the IOS image (PowerPC) */
2299  int c7200_init_instance(c7200_t *router)  static int c7200p_boot_ios(c7200_t *router)
2300    {  
2301       vm_instance_t *vm = router->vm;
2302       cpu_ppc_t *cpu;
2303    
2304       if (!vm->boot_cpu)
2305          return(-1);
2306    
2307       /* Suspend CPU activity since we will restart directly from ROM */
2308       vm_suspend(vm);
2309    
2310       /* Check that CPU activity is really suspended */
2311       if (cpu_group_sync_state(vm->cpu_group) == -1) {
2312          vm_error(vm,"unable to sync with system CPUs.\n");
2313          return(-1);
2314       }
2315    
2316       /* Reset the boot CPU */
2317       cpu = CPU_PPC32(vm->boot_cpu);
2318       ppc32_reset(cpu);
2319    
2320       /* Load IOS image */
2321       if (ppc32_load_elf_image(cpu,vm->ios_image,
2322                                (vm->ghost_status == VM_GHOST_RAM_USE),
2323                                &vm->ios_entry_point) < 0)
2324       {
2325          vm_error(vm,"failed to load Cisco IOS image '%s'.\n",vm->ios_image);
2326          return(-1);
2327       }
2328    
2329       /* Launch the simulation */
2330       printf("\nC7200P '%s': starting simulation (CPU0 IA=0x%8.8x), "
2331              "JIT %sabled.\n",
2332              vm->name,cpu->ia,vm->jit_use ? "en":"dis");
2333    
2334       vm_log(vm,"C7200P_BOOT",
2335              "starting instance (CPU0 IA=0x%8.8x,idle_pc=0x%8.8x,JIT %s)\n",
2336              cpu->ia,cpu->idle_pc,vm->jit_use ? "on":"off");
2337      
2338       /* Start main CPU */
2339       if (vm->ghost_status != VM_GHOST_RAM_GENERATE) {
2340          vm->status = VM_STATUS_RUNNING;
2341          cpu_start(vm->boot_cpu);
2342       } else {
2343          vm->status = VM_STATUS_SHUTDOWN;
2344       }
2345       return(0);
2346    }
2347    
2348    /* Initialize a Cisco 7200 instance (MIPS) */
2349    static int c7200m_init_instance(c7200_t *router)
2350  {  {
2351     vm_instance_t *vm = router->vm;     vm_instance_t *vm = router->vm;
2352     m_uint32_t rom_entry_point;     m_uint32_t rom_entry_point;
2353     cpu_mips_t *cpu0;     cpu_mips_t *cpu0;
2354    
2355     /* Initialize the C7200 platform */     /* Initialize the C7200 platform */
2356     if (c7200_init_platform(router) == -1) {     if (c7200m_init_platform(router) == -1) {
2357        vm_error(vm,"unable to initialize the platform hardware.\n");        vm_error(vm,"unable to initialize the platform hardware.\n");
2358        return(-1);        return(-1);
2359     }     }
# Line 2056  int c7200_init_instance(c7200_t *router) Line 2365  int c7200_init_instance(c7200_t *router)
2365     }     }
2366    
2367     /* Load ROM (ELF image or embedded) */     /* Load ROM (ELF image or embedded) */
2368     cpu0 = vm->boot_cpu;     cpu0 = CPU_MIPS64(vm->boot_cpu);
2369     rom_entry_point = (m_uint32_t)MIPS_ROM_PC;     rom_entry_point = (m_uint32_t)MIPS_ROM_PC;
2370        
2371     if ((vm->rom_filename != NULL) &&     if ((vm->rom_filename != NULL) &&
2372         (mips64_load_elf_image(cpu0,vm->rom_filename,&rom_entry_point) < 0))         (mips64_load_elf_image(cpu0,vm->rom_filename,0,&rom_entry_point) < 0))
2373     {     {
2374        vm_error(vm,"unable to load alternate ROM '%s', "        vm_error(vm,"unable to load alternate ROM '%s', "
2375                 "fallback to embedded ROM.\n\n",vm->rom_filename);                 "fallback to embedded ROM.\n\n",vm->rom_filename);
# Line 2073  int c7200_init_instance(c7200_t *router) Line 2382  int c7200_init_instance(c7200_t *router)
2382        cpu0->sym_trace = 1;        cpu0->sym_trace = 1;
2383     }     }
2384    
2385     return(c7200_boot_ios(router));     return(c7200m_boot_ios(router));
2386    }
2387    
2388    /* Set an IRQ */
2389    static void c7200p_set_irq(vm_instance_t *vm,u_int irq)
2390    {
2391       c7200_t *router = VM_C7200(vm);
2392       cpu_ppc_t *cpu0 = CPU_PPC32(vm->boot_cpu);
2393      
2394       switch(irq) {
2395          case C7200_VTIMER_IRQ:
2396             ppc32_trigger_timer_irq(cpu0);
2397             break;
2398          case C7200_DUART_IRQ:
2399             dev_mv64460_set_gpp_intr(router->mv64460_sysctr,10);
2400             break;
2401          case C7200_NETIO_IRQ:
2402             dev_mv64460_set_gpp_intr(router->mv64460_sysctr,24);
2403             break;
2404          case C7200_PA_MGMT_IRQ:
2405             dev_mv64460_set_gpp_intr(router->mv64460_sysctr,20);
2406             break;
2407          case C7200_OIR_IRQ:
2408             dev_mv64460_set_gpp_intr(router->mv64460_sysctr,0);
2409             break;
2410       }
2411    
2412       if (cpu0->irq_idle_preempt[irq])
2413          cpu_idle_break_wait(cpu0->gen);
2414    }
2415    
2416    /* Clear an IRQ */
2417    static void c7200p_clear_irq(vm_instance_t *vm,u_int irq)
2418    {
2419       c7200_t *router = VM_C7200(vm);
2420    
2421       switch(irq) {
2422          case C7200_DUART_IRQ:
2423             dev_mv64460_clear_gpp_intr(router->mv64460_sysctr,10);
2424             break;
2425          case C7200_NETIO_IRQ:
2426             dev_mv64460_clear_gpp_intr(router->mv64460_sysctr,24);
2427             break;
2428          case C7200_PA_MGMT_IRQ:
2429             dev_mv64460_clear_gpp_intr(router->mv64460_sysctr,20);
2430             break;
2431          case C7200_OIR_IRQ:
2432             dev_mv64460_clear_gpp_intr(router->mv64460_sysctr,0);
2433             break;
2434       }
2435    }
2436    
2437    /* Initialize a Cisco 7200 instance (PowerPC) */
2438    static int c7200p_init_instance(c7200_t *router)
2439    {
2440       vm_instance_t *vm = router->vm;
2441       m_uint32_t rom_entry_point;
2442       cpu_ppc_t *cpu0;
2443       int i;
2444    
2445       /* Initialize the C7200 platform */
2446       if (c7200p_init_platform(router) == -1) {
2447          vm_error(vm,"unable to initialize the platform hardware.\n");
2448          return(-1);
2449       }
2450    
2451       /* Load ROM (ELF image or embedded) */
2452       cpu0 = CPU_PPC32(vm->boot_cpu);
2453       rom_entry_point = (m_uint32_t)PPC32_ROM_START;
2454    
2455       if ((vm->rom_filename != NULL) &&
2456           (ppc32_load_elf_image(cpu0,vm->rom_filename,0,&rom_entry_point) < 0))
2457       {
2458          vm_error(vm,"unable to load alternate ROM '%s', "
2459                   "fallback to embedded ROM.\n\n",vm->rom_filename);
2460          vm->rom_filename = NULL;
2461       }
2462    
2463       /* Initialize the MMU (TEST) */
2464       for(i=0;i<PPC32_SR_NR;i++)
2465          cpu0->sr[i] = i << 16;
2466    
2467       ppc32_set_sdr1(cpu0,((vm->ram_size - 2) * 1048576) + 0x1F);
2468       ppc32_init_page_table(cpu0);
2469       ppc32_map_zone(cpu0,cpu0->sr[C7200_G2_BOOTFLASH_ADDR >> 28],
2470                      C7200_G2_BOOTFLASH_ADDR,C7200_G2_BOOTFLASH_ADDR,
2471                      64*1048576,0,0x02);
2472    
2473       ppc32_map_zone(cpu0,cpu0->sr[0xD8000000 >> 28],
2474                      0xD8000000,0xD8000000,0x400000,0,0x02);
2475       ppc32_map_zone(cpu0,cpu0->sr[0xDC000000 >> 28],
2476                      0xDC000000,0xDC000000,0x400000,0,0x02);
2477    
2478       /* INST */
2479       cpu0->bat[PPC32_IBAT_IDX][0].reg[0] = 0x00003FFE;
2480       cpu0->bat[PPC32_IBAT_IDX][0].reg[1] = 0x00000003;
2481    
2482       cpu0->bat[PPC32_IBAT_IDX][3].reg[0] = 0xF0001FFE;
2483       cpu0->bat[PPC32_IBAT_IDX][3].reg[1] = 0xF0000003;
2484    
2485       /* DATA */
2486       cpu0->bat[PPC32_DBAT_IDX][0].reg[0] = 0x00003FFE;
2487       cpu0->bat[PPC32_DBAT_IDX][0].reg[1] = 0x00000003;
2488    
2489       cpu0->bat[PPC32_DBAT_IDX][3].reg[0] = 0xF0001FFE;
2490       cpu0->bat[PPC32_DBAT_IDX][3].reg[1] = 0xF0000003;
2491    
2492       /* IRQ routing */
2493       vm->set_irq = c7200p_set_irq;
2494       vm->clear_irq = c7200p_clear_irq;
2495    
2496       return(c7200p_boot_ios(router));
2497    }
2498    
2499    /* Initialize a Cisco 7200 instance */
2500    int c7200_init_instance(c7200_t *router)
2501    {
2502       switch(router->npe_driver->npe_family) {
2503          case C7200_NPE_FAMILY_MIPS:
2504             return(c7200m_init_instance(router));
2505    
2506          case C7200_NPE_FAMILY_PPC:
2507             return(c7200p_init_instance(router));
2508            
2509          default:
2510             vm_error(router->vm,"unsupported NPE family %d",
2511                      router->npe_driver->npe_family);
2512             return(-1);
2513       }
2514  }  }
2515    
2516  /* Stop a Cisco 7200 instance */  /* Stop a Cisco 7200 instance */

Legend:
Removed from v.2  
changed lines
  Added in v.7

  ViewVC Help
Powered by ViewVC 1.1.26