/[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-RC5/dev_c7200.c revision 6 by dpavlin, Sat Oct 6 16:09:07 2007 UTC upstream/dynamips-0.2.8-RC1/dev_c7200.c revision 11 by dpavlin, Sat Oct 6 16:33:40 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"  #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_c7200_mpfpga.h"
28  #include "dev_vtty.h"  #include "dev_vtty.h"
29  #include "registry.h"  #include "registry.h"
30  #include "net.h"  #include "net.h"
# Line 88  static m_uint16_t eeprom_cpu_npeg1_data[ Line 93  static m_uint16_t eeprom_cpu_npeg1_data[
93     0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,     0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
94  };  };
95    
96    /* NPE-G2 */
97    static m_uint16_t eeprom_cpu_npeg2_data[64] = {
98       0x04FF, 0x4004, 0xCA41, 0x0201, 0x8744, 0x19BC, 0x0182, 0x4928,
99       0x5901, 0x42FF, 0xFFC1, 0x8B43, 0x534A, 0x3039, 0x3435, 0x3239,
100       0x3237, 0x0400, 0x0201, 0x851C, 0x1DA2, 0x01CB, 0x864E, 0x5045,
101       0x2D47, 0x3280, 0x0000, 0x0000, 0x8956, 0x3031, 0x2DFF, 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, 0xFFFF,
105       0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x15FF,
106    };
107    
108  /*  /*
109   * CPU EEPROM array.   * CPU EEPROM array.
110   */   */
# Line 100  static struct cisco_eeprom c7200_cpu_eep Line 117  static struct cisco_eeprom c7200_cpu_eep
117     { "npe-300", eeprom_cpu_npe300_data, sizeof(eeprom_cpu_npe300_data)/2 },     { "npe-300", eeprom_cpu_npe300_data, sizeof(eeprom_cpu_npe300_data)/2 },
118     { "npe-400", eeprom_cpu_npe400_data, sizeof(eeprom_cpu_npe400_data)/2 },     { "npe-400", eeprom_cpu_npe400_data, sizeof(eeprom_cpu_npe400_data)/2 },
119     { "npe-g1" , eeprom_cpu_npeg1_data , sizeof(eeprom_cpu_npeg1_data)/2 },     { "npe-g1" , eeprom_cpu_npeg1_data , sizeof(eeprom_cpu_npeg1_data)/2 },
120       { "npe-g2" , eeprom_cpu_npeg2_data , sizeof(eeprom_cpu_npeg2_data)/2 },
121     { NULL, NULL, 0 },     { NULL, NULL, 0 },
122  };  };
123    
# Line 160  static struct cisco_eeprom c7200_pem_eep Line 178  static struct cisco_eeprom c7200_pem_eep
178  /* ======================================================================== */  /* ======================================================================== */
179  /* Port Adapter Drivers                                                     */  /* Port Adapter Drivers                                                     */
180  /* ======================================================================== */  /* ======================================================================== */
181  static struct c7200_pa_driver *pa_drivers[] = {  static struct cisco_card_driver *pa_drivers[] = {
182     &dev_c7200_io_fe_driver,     &dev_c7200_iocard_fe_driver,
183       &dev_c7200_iocard_2fe_driver,
184       &dev_c7200_iocard_ge_e_driver,
185     &dev_c7200_pa_fe_tx_driver,     &dev_c7200_pa_fe_tx_driver,
186       &dev_c7200_pa_2fe_tx_driver,
187       &dev_c7200_pa_ge_driver,
188     &dev_c7200_pa_4e_driver,     &dev_c7200_pa_4e_driver,
189     &dev_c7200_pa_8e_driver,     &dev_c7200_pa_8e_driver,
190     &dev_c7200_pa_4t_driver,     &dev_c7200_pa_4t_driver,
# Line 188  DECLARE_NPE(npe225); Line 210  DECLARE_NPE(npe225);
210  DECLARE_NPE(npe300);  DECLARE_NPE(npe300);
211  DECLARE_NPE(npe400);  DECLARE_NPE(npe400);
212  DECLARE_NPE(npeg1);  DECLARE_NPE(npeg1);
213    DECLARE_NPE(npeg2);
214    
215  static struct c7200_npe_driver npe_drivers[] = {  static struct c7200_npe_driver npe_drivers[] = {
216     { "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,
217     { "npe-150" , c7200_init_npe150, 256, 1, C7200_NVRAM_ADDR, 0, 5,  0, 6 },       C7200_NVRAM_ADDR, TRUE, 0, 5,  0, 6 },
218     { "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,
219     { "npe-200" , c7200_init_npe200, 256, 1, C7200_NVRAM_ADDR, 0, 5,  0, 6 },       C7200_NVRAM_ADDR, TRUE, 0, 5,  0, 6 },
220     { "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,
221     { "npe-300" , c7200_init_npe300, 256, 1, C7200_NVRAM_ADDR, 2, 16, 1, 0 },       C7200_NVRAM_ADDR, TRUE, 2, 16, 1, 0 },
222     { "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,
223     { "npe-g1"  , c7200_init_npeg1, 1024, 0,       C7200_NVRAM_ADDR, TRUE, 0, 5,  0, 6 },
224       C7200_NPEG1_NVRAM_ADDR, 17, 16, 16, 0 },     { "npe-225" , C7200_NPE_FAMILY_MIPS, c7200_init_npe225, 256, 1,
225     { NULL      , NULL },       C7200_NVRAM_ADDR, TRUE, 2, 16, 1, 0 },
226       { "npe-300" , C7200_NPE_FAMILY_MIPS, c7200_init_npe300, 256, 1,
227         C7200_NVRAM_ADDR, TRUE, 2, 16, 1, 0 },
228       { "npe-400" , C7200_NPE_FAMILY_MIPS, c7200_init_npe400, 512, 1,
229         C7200_NVRAM_ADDR, TRUE, 2, 16, 1, 0 },
230       { "npe-g1"  , C7200_NPE_FAMILY_MIPS, c7200_init_npeg1, 1024, 0,
231         C7200_G1_NVRAM_ADDR, FALSE, 17, 16, 16, 0 },
232       { "npe-g2"  , C7200_NPE_FAMILY_PPC , c7200_init_npeg2, 1024, 0,
233         C7200_G2_NVRAM_ADDR, FALSE, 17, 16, 16, 0 },
234       { NULL, -1, NULL, -1, -1, 0, -1, -1, -1, -1 },
235  };  };
236    
237  /* ======================================================================== */  /* ======================================================================== */
238  /* Cisco 7200 router instances                                              */  /* Cisco 7200 router instances                                              */
239  /* ======================================================================== */  /* ======================================================================== */
240    
241    /* Initialize default parameters for a C7200 */
242    static void c7200_init_defaults(c7200_t *router);
243    
244  /* Directly extract the configuration from the NVRAM device */  /* Directly extract the configuration from the NVRAM device */
245  ssize_t c7200_nvram_extract_config(vm_instance_t *vm,char **buffer)  static ssize_t c7200_nvram_extract_config(vm_instance_t *vm,u_char **buffer)
246  {    {  
247     u_char *base_ptr,*ios_ptr,*cfg_ptr,*end_ptr;     u_char *base_ptr,*ios_ptr,*cfg_ptr,*end_ptr;
248     m_uint32_t start,end,nvlen,clen;     m_uint32_t start,end,nvlen,clen;
# Line 271  ssize_t c7200_nvram_extract_config(vm_in Line 306  ssize_t c7200_nvram_extract_config(vm_in
306  }  }
307    
308  /* Directly push the IOS configuration to the NVRAM device */  /* Directly push the IOS configuration to the NVRAM device */
309  int c7200_nvram_push_config(vm_instance_t *vm,char *buffer,size_t len)  static int c7200_nvram_push_config(vm_instance_t *vm,u_char *buffer,size_t len)
310  {    {  
311     u_char *base_ptr,*ios_ptr,*cfg_ptr;     u_char *base_ptr,*ios_ptr,*cfg_ptr;
312     m_uint32_t cfg_addr,cfg_offset;     m_uint32_t cfg_addr,cfg_offset;
# Line 356  static int c7200_burn_mac_addr(c7200_t * Line 391  static int c7200_burn_mac_addr(c7200_t *
391  static void c7200_free_hw_ressources(c7200_t *router)  static void c7200_free_hw_ressources(c7200_t *router)
392  {  {
393     /* Shutdown all Port Adapters */     /* Shutdown all Port Adapters */
394     c7200_pa_shutdown_all(router);     vm_slot_shutdown_all(router->vm);
395    
396     /* Inactivate the PCMCIA bus */     /* Inactivate the PCMCIA bus */
397     router->pcmcia_bus = NULL;     router->pcmcia_bus = NULL;
# Line 369  static void c7200_free_hw_ressources(c72 Line 404  static void c7200_free_hw_ressources(c72
404  }  }
405    
406  /* Create a new router instance */  /* Create a new router instance */
407  c7200_t *c7200_create_instance(char *name,int instance_id)  static int c7200_create_instance(vm_instance_t *vm)
408  {  {
409     c7200_t *router;     c7200_t *router;
410    
411     if (!(router = malloc(sizeof(*router)))) {     if (!(router = malloc(sizeof(*router)))) {
412        fprintf(stderr,"C7200 '%s': Unable to create new instance!\n",name);        fprintf(stderr,"C7200 '%s': Unable to create new instance!\n",vm->name);
413        return NULL;        return(-1);
414     }     }
     
    memset(router,0,sizeof(*router));  
415    
416     if (!(router->vm = vm_create(name,instance_id,VM_TYPE_C7200))) {     memset(router,0,sizeof(*router));
417        fprintf(stderr,"C7200 '%s': unable to create VM instance!\n",name);     router->vm = vm;
418        goto err_vm;     vm->hw_data = router;
419     }     vm->elf_machine_id = C7200_ELF_MACHINE_ID;
420    
421     c7200_init_defaults(router);     c7200_init_defaults(router);
422     router->vm->hw_data = router;     return(0);
    router->vm->elf_machine_id = C7200_ELF_MACHINE_ID;  
    return router;  
   
  err_vm:  
    free(router);  
    return NULL;  
423  }  }
424    
425  /* Free resources used by a router instance */  /* Free resources used by a router instance */
426  static int c7200_free_instance(void *data,void *arg)  static int c7200_delete_instance(vm_instance_t *vm)
427  {  {
428     vm_instance_t *vm = data;     c7200_t *router = VM_C7200(vm);
    c7200_t *router;  
429     int i;     int i;
430    
431     if (vm->type == VM_TYPE_C7200) {     /* Stop all CPUs */
432        router = VM_C7200(vm);     if (vm->cpu_group != NULL) {
433          vm_stop(vm);
434    
435        /* Stop all CPUs */        if (cpu_group_sync_state(vm->cpu_group) == -1) {
436        if (vm->cpu_group != NULL) {           vm_error(vm,"unable to sync with system CPUs.\n");
437           vm_stop(vm);           return(FALSE);
   
          if (cpu_group_sync_state(vm->cpu_group) == -1) {  
             vm_error(vm,"unable to sync with system CPUs.\n");  
             return(FALSE);  
          }  
438        }        }
439       }
440    
441        /* Remove NIO bindings */     /* Remove NIO bindings */
442        for(i=0;i<C7200_MAX_PA_BAYS;i++)     for(i=0;i<vm->nr_slots;i++)
443           c7200_pa_remove_all_nio_bindings(router,i);        vm_slot_remove_all_nio_bindings(vm,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);  
444    
445        /* Free the router structure */     /* Free specific HW resources */
446        free(router);     c7200_free_hw_ressources(router);
       return(TRUE);  
    }  
447    
448     return(FALSE);     /* Free EEPROMs */
449  }     cisco_eeprom_free(&router->cpu_eeprom);
450       cisco_eeprom_free(&router->mp_eeprom);
451       cisco_eeprom_free(&router->pem_eeprom);
452    
453  /* Delete a router instance */     /* Free all resources used by VM */
454  int c7200_delete_instance(char *name)     vm_free(vm);
 {  
    return(registry_delete_if_unused(name,OBJ_TYPE_VM,  
                                     c7200_free_instance,NULL));  
 }  
455    
456  /* Delete all router instances */     /* Free the router structure */
457  int c7200_delete_all_instances(void)     free(router);
458  {     return(TRUE);
    return(registry_delete_type(OBJ_TYPE_VM,c7200_free_instance,NULL));  
459  }  }
460    
461  /* Save configuration of a C7200 instance */  /* Save configuration of a C7200 instance */
462  void c7200_save_config(c7200_t *router,FILE *fd)  static void c7200_save_config(vm_instance_t *vm,FILE *fd)
463  {  {
464     vm_instance_t *vm = router->vm;     c7200_t *router = VM_C7200(vm);
    struct c7200_nio_binding *nb;  
    struct c7200_pa_bay *bay;  
    int i;  
   
    /* General settings */  
    fprintf(fd,"c7200 create %s %u\n",vm->name,vm->instance_id);  
465    
466     fprintf(fd,"c7200 set_npe %s %s\n",vm->name,router->npe_driver->npe_type);     fprintf(fd,"c7200 set_npe %s %s\n",vm->name,router->npe_driver->npe_type);
467     fprintf(fd,"c7200 set_midplane %s %s\n",vm->name,router->midplane_type);     fprintf(fd,"c7200 set_midplane %s %s\n\n",vm->name,router->midplane_type);
468    }
469    
470     /* VM configuration */  /* Set EEPROM for the specified slot */
471     vm_save_config(vm,fd);  int c7200_set_slot_eeprom(c7200_t *router,u_int slot,
472                              struct cisco_eeprom *eeprom)
473    {
474       if (slot >= C7200_MAX_PA_BAYS)
475          return(-1);
476    
477     /* Port Adapter settings */     switch(slot) {
478     for(i=0;i<C7200_MAX_PA_BAYS;i++) {        /* Group 1: bays 0, 1, 3, 4 */
479        if (!(bay = c7200_pa_get_info(router,i)))        case 0:
480           continue;           router->pa_eeprom_g1.eeprom[0] = eeprom;
481             break;
482        if (bay->dev_type) {        case 1:
483           fprintf(fd,"c7200 add_pa_binding %s %u %s\n",           router->pa_eeprom_g1.eeprom[1] = eeprom;
484                   vm->name,i,bay->dev_type);           break;
485        }        case 3:
486             router->pa_eeprom_g1.eeprom[2] = eeprom;
487             break;
488          case 4:
489             router->pa_eeprom_g1.eeprom[3] = eeprom;
490             break;
491    
492        for(nb=bay->nio_list;nb;nb=nb->next) {        /* Group 2: bays 2, 5, 6 */
493           fprintf(fd,"c7200 add_nio_binding %s %u %u %s\n",        case 2:
494                   vm->name,i,nb->port_id,nb->nio->name);           router->pa_eeprom_g2.eeprom[0] = eeprom;
495        }           break;        
496          case 5:
497             router->pa_eeprom_g2.eeprom[1] = eeprom;
498             break;
499          case 6:
500             router->pa_eeprom_g2.eeprom[2] = eeprom;
501             break;
502     }     }
503    
504     fprintf(fd,"\n");     return(0);
505  }  }
506    
507  /* Save configurations of all C7200 instances */  /* Get slot/port corresponding to specified network IRQ */
508  static void c7200_reg_save_config(registry_entry_t *entry,void *opt,int *err)  static inline void
509    c7200_net_irq_get_slot_port(u_int irq,u_int *slot,u_int *port)
510  {  {
511     vm_instance_t *vm = entry->data;     irq -= C7200_NETIO_IRQ_BASE;
512     c7200_t *router = VM_C7200(vm);     *port = irq & C7200_NETIO_IRQ_PORT_MASK;
513       *slot = irq >> C7200_NETIO_IRQ_PORT_BITS;
    if (vm->type == VM_TYPE_C7200)  
       c7200_save_config(router,(FILE *)opt);  
514  }  }
515    
516  void c7200_save_config_all(FILE *fd)  /* Get network IRQ for specified slot/port */
517    u_int c7200_net_irq_for_slot_port(u_int slot,u_int port)
518  {  {
519     registry_foreach_type(OBJ_TYPE_VM,c7200_reg_save_config,fd,NULL);     u_int irq;
520    
521       irq = (slot << C7200_NETIO_IRQ_PORT_BITS) + port;
522       irq += C7200_NETIO_IRQ_BASE;
523    
524       return(irq);
525  }  }
526    
527  /* Set NPE eeprom definition */  /* Set NPE eeprom definition */
# Line 540  static int c7200_pem_set_eeprom(c7200_t Line 562  static int c7200_pem_set_eeprom(c7200_t
562     return(0);     return(0);
563  }  }
564    
 /* Set PA EEPROM definition */  
 int c7200_pa_set_eeprom(c7200_t *router,u_int pa_bay,  
                         const struct cisco_eeprom *eeprom)  
 {  
    if (pa_bay >= C7200_MAX_PA_BAYS) {  
       vm_error(router->vm,"c7200_pa_set_eeprom: invalid PA Bay %u.\n",pa_bay);  
       return(-1);  
    }  
   
    if (cisco_eeprom_copy(&router->pa_bay[pa_bay].eeprom,eeprom) == -1) {  
       vm_error(router->vm,"c7200_pa_set_eeprom: no memory.\n");  
       return(-1);  
    }  
   
    return(0);  
 }  
   
 /* Unset PA EEPROM definition (empty bay) */  
 int c7200_pa_unset_eeprom(c7200_t *router,u_int pa_bay)  
 {  
    if (pa_bay >= C7200_MAX_PA_BAYS) {  
       vm_error(router->vm,"c7200_pa_set_eeprom: invalid PA Bay %u.\n",pa_bay);  
       return(-1);  
    }  
     
    cisco_eeprom_free(&router->pa_bay[pa_bay].eeprom);  
    return(0);  
 }  
   
 /* Check if a bay has a port adapter */  
 int c7200_pa_check_eeprom(c7200_t *router,u_int pa_bay)  
 {  
    if (!pa_bay || (pa_bay >= C7200_MAX_PA_BAYS))  
       return(FALSE);  
   
    return(cisco_eeprom_valid(&router->pa_bay[pa_bay].eeprom));  
 }  
   
 /* Get bay info */  
 struct c7200_pa_bay *c7200_pa_get_info(c7200_t *router,u_int pa_bay)  
 {  
    if (pa_bay >= C7200_MAX_PA_BAYS)  
       return NULL;  
   
    return(&router->pa_bay[pa_bay]);  
 }  
   
 /* Get PA type */  
 char *c7200_pa_get_type(c7200_t *router,u_int pa_bay)  
 {  
    struct c7200_pa_bay *bay;  
   
    bay = c7200_pa_get_info(router,pa_bay);  
    return((bay != NULL) ? bay->dev_type : NULL);  
 }  
   
 /* Get driver info about the specified slot */  
 void *c7200_pa_get_drvinfo(c7200_t *router,u_int pa_bay)  
 {  
    struct c7200_pa_bay *bay;  
   
    bay = c7200_pa_get_info(router,pa_bay);  
    return((bay != NULL) ? bay->drv_info : NULL);  
 }  
   
 /* Set driver info for the specified slot */  
 int c7200_pa_set_drvinfo(c7200_t *router,u_int pa_bay,void *drv_info)  
 {  
    struct c7200_pa_bay *bay;  
   
    if (!(bay = c7200_pa_get_info(router,pa_bay)))  
       return(-1);  
   
    bay->drv_info = drv_info;  
    return(0);  
 }  
   
 /* Get a PA driver */  
 static struct c7200_pa_driver *c7200_pa_get_driver(char *dev_type)  
 {  
    int i;  
   
    for(i=0;pa_drivers[i];i++)  
       if (!strcmp(pa_drivers[i]->dev_type,dev_type))  
          return pa_drivers[i];  
   
    return NULL;  
 }  
   
 /* Add a PA binding */  
 int c7200_pa_add_binding(c7200_t *router,char *dev_type,u_int pa_bay)  
 {    
    struct c7200_pa_driver *pa_driver;  
    struct c7200_pa_bay *bay;  
   
    if (!(bay = c7200_pa_get_info(router,pa_bay)))  
       return(-1);  
   
    /* check that this bay is empty */  
    if (bay->dev_type != NULL) {  
       vm_error(router->vm,"a PA already exists in slot %u.\n",pa_bay);  
       return(-1);  
    }  
   
    /* find the PA driver */  
    if (!(pa_driver = c7200_pa_get_driver(dev_type))) {  
       vm_error(router->vm,"unknown PA type '%s'.\n",dev_type);  
       return(-1);  
    }  
   
    bay->dev_type = pa_driver->dev_type;  
    bay->pa_driver = pa_driver;  
    return(0);    
 }  
   
 /* Remove a PA binding */  
 int c7200_pa_remove_binding(c7200_t *router,u_int pa_bay)  
 {    
    struct c7200_pa_bay *bay;  
   
    if (!(bay = c7200_pa_get_info(router,pa_bay)))  
       return(-1);  
   
    /* stop if this bay is still active */  
    if (bay->drv_info != NULL) {  
       vm_error(router->vm,"slot %u still active.\n",pa_bay);  
       return(-1);  
    }  
   
    /* check that this bay is not empty */  
    if (bay->dev_type == NULL) {  
       vm_error(router->vm,"slot %u is empty.\n",pa_bay);  
       return(-1);  
    }  
     
    /* remove all NIOs bindings */  
    c7200_pa_remove_all_nio_bindings(router,pa_bay);  
   
    bay->dev_type  = NULL;  
    bay->pa_driver = NULL;  
    return(0);  
 }  
   
 /* Find a NIO binding */  
 struct c7200_nio_binding *  
 c7200_pa_find_nio_binding(c7200_t *router,u_int pa_bay,u_int port_id)  
 {    
    struct c7200_nio_binding *nb;  
    struct c7200_pa_bay *bay;  
   
    if (!(bay = c7200_pa_get_info(router,pa_bay)))  
       return NULL;  
   
    for(nb=bay->nio_list;nb;nb=nb->next)  
       if (nb->port_id == port_id)  
          return nb;  
   
    return NULL;  
 }  
   
 /* Add a network IO binding */  
 int c7200_pa_add_nio_binding(c7200_t *router,u_int pa_bay,u_int port_id,  
                              char *nio_name)  
 {  
    struct c7200_nio_binding *nb;  
    struct c7200_pa_bay *bay;  
    netio_desc_t *nio;  
   
    if (!(bay = c7200_pa_get_info(router,pa_bay)))  
       return(-1);  
   
    /* check that a NIO is not already bound to this port */  
    if (c7200_pa_find_nio_binding(router,pa_bay,port_id) != NULL) {  
       vm_error(router->vm,"a NIO already exists for interface %u/%u\n",  
                pa_bay,port_id);  
       return(-1);  
    }  
   
    /* acquire a reference on the NIO object */  
    if (!(nio = netio_acquire(nio_name))) {  
       vm_error(router->vm,"unable to find NIO '%s'.\n",nio_name);  
       return(-1);  
    }  
   
    /* create a new binding */  
    if (!(nb = malloc(sizeof(*nb)))) {  
       vm_error(router->vm,"unable to create NIO binding "  
                "for interface %u/%u.\n",pa_bay,port_id);  
       netio_release(nio_name);  
       return(-1);  
    }  
   
    memset(nb,0,sizeof(*nb));  
    nb->nio       = nio;  
    nb->port_id   = port_id;  
    nb->next      = bay->nio_list;  
    if (nb->next) nb->next->prev = nb;  
    bay->nio_list = nb;  
    return(0);  
 }  
   
 /* Remove a NIO binding */  
 int c7200_pa_remove_nio_binding(c7200_t *router,u_int pa_bay,u_int port_id)  
 {  
    struct c7200_nio_binding *nb;  
    struct c7200_pa_bay *bay;  
     
    if (!(bay = c7200_pa_get_info(router,pa_bay)))  
       return(-1);  
   
    if (!(nb = c7200_pa_find_nio_binding(router,pa_bay,port_id)))  
       return(-1);   /* no nio binding for this slot/port */  
   
    /* tell the PA driver to stop using this NIO */  
    if (bay->pa_driver)  
       bay->pa_driver->pa_unset_nio(router,pa_bay,port_id);  
   
    /* remove this entry from the double linked list */  
    if (nb->next)  
       nb->next->prev = nb->prev;  
   
    if (nb->prev) {  
       nb->prev->next = nb->next;  
    } else {  
       bay->nio_list = nb->next;  
    }  
   
    /* unreference NIO object */  
    netio_release(nb->nio->name);  
    free(nb);  
    return(0);  
 }  
   
 /* Remove all NIO bindings for the specified PA */  
 int c7200_pa_remove_all_nio_bindings(c7200_t *router,u_int pa_bay)  
 {    
    struct c7200_nio_binding *nb,*next;  
    struct c7200_pa_bay *bay;  
   
    if (!(bay = c7200_pa_get_info(router,pa_bay)))  
       return(-1);  
   
    for(nb=bay->nio_list;nb;nb=next) {  
       next = nb->next;  
   
       /* tell the PA driver to stop using this NIO */  
       if (bay->pa_driver)  
          bay->pa_driver->pa_unset_nio(router,pa_bay,nb->port_id);  
   
       /* unreference NIO object */  
       netio_release(nb->nio->name);  
       free(nb);  
    }  
   
    bay->nio_list = NULL;  
    return(0);  
 }  
   
 /* Enable a Network IO descriptor for a Port Adapter */  
 int c7200_pa_enable_nio(c7200_t *router,u_int pa_bay,u_int port_id)  
 {  
    struct c7200_nio_binding *nb;  
    struct c7200_pa_bay *bay;  
   
    if (!(bay = c7200_pa_get_info(router,pa_bay)))  
       return(-1);  
   
    /* check that we have an NIO binding for this interface */  
    if (!(nb = c7200_pa_find_nio_binding(router,pa_bay,port_id)))  
       return(-1);  
   
    /* check that the driver is defined and successfully initialized */  
    if (!bay->pa_driver || !bay->drv_info)  
       return(-1);  
   
    return(bay->pa_driver->pa_set_nio(router,pa_bay,port_id,nb->nio));  
 }  
   
 /* Disable Network IO descriptor of a Port Adapter */  
 int c7200_pa_disable_nio(c7200_t *router,u_int pa_bay,u_int port_id)  
 {  
    struct c7200_pa_bay *bay;  
   
    if (!(bay = c7200_pa_get_info(router,pa_bay)))  
       return(-1);  
   
    /* check that the driver is defined and successfully initialized */  
    if (!bay->pa_driver || !bay->drv_info)  
       return(-1);  
   
    return(bay->pa_driver->pa_unset_nio(router,pa_bay,port_id));  
 }  
   
 /* Enable all NIO of the specified PA */  
 int c7200_pa_enable_all_nio(c7200_t *router,u_int pa_bay)  
 {  
    struct c7200_nio_binding *nb;  
    struct c7200_pa_bay *bay;  
   
    if (!(bay = c7200_pa_get_info(router,pa_bay)))  
       return(-1);  
   
    /* check that the driver is defined and successfully initialized */  
    if (!bay->pa_driver || !bay->drv_info)  
       return(-1);  
   
    for(nb=bay->nio_list;nb;nb=nb->next)  
       bay->pa_driver->pa_set_nio(router,pa_bay,nb->port_id,nb->nio);  
   
    return(0);  
 }  
   
 /* Disable all NIO of the specified PA */  
 int c7200_pa_disable_all_nio(c7200_t *router,u_int pa_bay)  
 {  
    struct c7200_nio_binding *nb;  
    struct c7200_pa_bay *bay;  
   
    if (!(bay = c7200_pa_get_info(router,pa_bay)))  
       return(-1);  
   
    /* check that the driver is defined and successfully initialized */  
    if (!bay->pa_driver || !bay->drv_info)  
       return(-1);  
   
    for(nb=bay->nio_list;nb;nb=nb->next)  
       bay->pa_driver->pa_unset_nio(router,pa_bay,nb->port_id);  
   
    return(0);  
 }  
   
 /* Initialize a Port Adapter */  
 int c7200_pa_init(c7200_t *router,u_int pa_bay)  
 {    
    struct c7200_pa_bay *bay;  
    size_t len;  
   
    if (!(bay = c7200_pa_get_info(router,pa_bay)))  
       return(-1);  
   
    /* Check that a device type is defined for this bay */  
    if (!bay->dev_type || !bay->pa_driver) {  
       vm_error(router->vm,"trying to init empty slot %u.\n",pa_bay);  
       return(-1);  
    }  
   
    /* Allocate device name */  
    len = strlen(bay->dev_type) + 10;  
    if (!(bay->dev_name = malloc(len))) {  
       vm_error(router->vm,"unable to allocate device name.\n");  
       return(-1);  
    }  
   
    snprintf(bay->dev_name,len,"%s(%u)",bay->dev_type,pa_bay);  
   
    /* Initialize PA driver */  
    if (bay->pa_driver->pa_init(router,bay->dev_name,pa_bay) == 1) {  
       vm_error(router->vm,"unable to initialize PA %u.\n",pa_bay);  
       return(-1);  
    }  
   
    /* Enable all NIO */  
    c7200_pa_enable_all_nio(router,pa_bay);  
    return(0);  
 }  
   
 /* Shutdown a Port Adapter */  
 int c7200_pa_shutdown(c7200_t *router,u_int pa_bay)  
 {  
    struct c7200_pa_bay *bay;  
   
    if (!(bay = c7200_pa_get_info(router,pa_bay)))  
       return(-1);  
   
    /* Check that a device type is defined for this bay */    
    if (!bay->dev_type || !bay->pa_driver) {  
       vm_error(router->vm,"trying to shut down an empty bay %u.\n",pa_bay);  
       return(-1);  
    }  
   
    /* Disable all NIO */  
    c7200_pa_disable_all_nio(router,pa_bay);  
   
    /* Shutdown the PA driver */  
    if (bay->drv_info && (bay->pa_driver->pa_shutdown(router,pa_bay) == -1)) {  
       vm_error(router->vm,"unable to shutdown PA %u.\n",pa_bay);  
       return(-1);  
    }  
   
    free(bay->dev_name);  
    bay->dev_name = NULL;  
    bay->drv_info = NULL;  
    return(0);  
 }  
   
 /* Shutdown all PA of a router */  
 int c7200_pa_shutdown_all(c7200_t *router)  
 {  
    int i;  
   
    for(i=0;i<C7200_MAX_PA_BAYS;i++) {  
       if (!router->pa_bay[i].dev_type)  
          continue;  
   
       c7200_pa_shutdown(router,i);  
    }  
   
    return(0);  
 }  
   
 /* Show info about all NMs */  
 int c7200_pa_show_all_info(c7200_t *router)  
 {  
    struct c7200_pa_bay *bay;  
    int i;  
   
    for(i=0;i<C7200_MAX_PA_BAYS;i++) {  
       if (!(bay = c7200_pa_get_info(router,i)) || !bay->pa_driver)  
          continue;  
   
       if (bay->pa_driver->pa_show_info != NULL)  
          bay->pa_driver->pa_show_info(router,i);  
    }  
   
    return(0);  
 }  
   
 /* Maximum number of tokens in a PA description */  
 #define PA_DESC_MAX_TOKENS  8  
   
 /* Create a Port Adapter (command line) */  
 int c7200_cmd_pa_create(c7200_t *router,char *str)  
 {  
    char *tokens[PA_DESC_MAX_TOKENS];  
    int i,count,res;  
    u_int pa_bay;  
   
    /* A port adapter description is like "1:PA-FE-TX" */  
    if ((count = m_strsplit(str,':',tokens,PA_DESC_MAX_TOKENS)) != 2) {  
       vm_error(router->vm,"unable to parse PA description '%s'.\n",str);  
       return(-1);  
    }  
   
    /* Parse the PA bay id */  
    pa_bay = atoi(tokens[0]);  
   
    /* Add this new PA to the current PA list */  
    res = c7200_pa_add_binding(router,tokens[1],pa_bay);  
   
    /* The complete array was cleaned by strsplit */  
    for(i=0;i<PA_DESC_MAX_TOKENS;i++)  
       free(tokens[i]);  
   
    return(res);  
 }  
   
 /* Add a Network IO descriptor binding (command line) */  
 int c7200_cmd_add_nio(c7200_t *router,char *str)  
 {  
    char *tokens[PA_DESC_MAX_TOKENS];  
    int i,count,nio_type,res=-1;  
    u_int pa_bay,port_id;  
    netio_desc_t *nio;  
    char nio_name[128];  
   
    /* A port adapter description is like "1:3:tap:tap0" */  
    if ((count = m_strsplit(str,':',tokens,PA_DESC_MAX_TOKENS)) < 3) {  
       vm_error(router->vm,"unable to parse NIO description '%s'.\n",str);  
       return(-1);  
    }  
   
    /* Parse the PA bay */  
    pa_bay = atoi(tokens[0]);  
   
    /* Parse the PA port id */  
    port_id = atoi(tokens[1]);  
   
    /* Autogenerate a NIO name */  
    snprintf(nio_name,sizeof(nio_name),"c7200-i%u/%u/%u",  
             router->vm->instance_id,pa_bay,port_id);  
   
    /* Create the Network IO descriptor */  
    nio = NULL;  
    nio_type = netio_get_type(tokens[2]);  
   
    switch(nio_type) {  
       case NETIO_TYPE_UNIX:  
          if (count != 5) {  
             vm_error(router->vm,  
                      "invalid number of arguments for UNIX NIO '%s'\n",str);  
             goto done;  
          }  
   
          nio = netio_desc_create_unix(nio_name,tokens[3],tokens[4]);  
          break;  
   
       case NETIO_TYPE_VDE:  
          if (count != 5) {  
             vm_error(router->vm,  
                      "invalid number of arguments for VDE NIO '%s'\n",str);  
             goto done;  
          }  
   
          nio = netio_desc_create_vde(nio_name,tokens[3],tokens[4]);  
          break;  
   
       case NETIO_TYPE_TAP:  
          if (count != 4) {  
             vm_error(router->vm,  
                      "invalid number of arguments for TAP NIO '%s'\n",str);  
             goto done;  
          }  
   
          nio = netio_desc_create_tap(nio_name,tokens[3]);  
          break;  
   
       case NETIO_TYPE_UDP:  
          if (count != 6) {  
             vm_error(router->vm,  
                      "invalid number of arguments for UDP NIO '%s'\n",str);  
             goto done;  
          }  
   
          nio = netio_desc_create_udp(nio_name,atoi(tokens[3]),  
                                      tokens[4],atoi(tokens[5]));  
          break;  
   
       case NETIO_TYPE_TCP_CLI:  
          if (count != 5) {  
             vm_error(router->vm,  
                      "invalid number of arguments for TCP CLI NIO '%s'\n",str);  
             goto done;  
          }  
   
          nio = netio_desc_create_tcp_cli(nio_name,tokens[3],tokens[4]);  
          break;  
   
       case NETIO_TYPE_TCP_SER:  
          if (count != 4) {  
             vm_error(router->vm,  
                      "invalid number of arguments for TCP SER NIO '%s'\n",str);  
             goto done;  
          }  
   
          nio = netio_desc_create_tcp_ser(nio_name,tokens[3]);  
          break;  
   
       case NETIO_TYPE_NULL:  
          nio = netio_desc_create_null(nio_name);  
          break;  
   
 #ifdef LINUX_ETH  
       case NETIO_TYPE_LINUX_ETH:  
          if (count != 4) {  
             vm_error(router->vm,  
                      "invalid number of arguments for Linux Eth NIO '%s'\n",  
                      str);  
             goto done;  
          }  
           
          nio = netio_desc_create_lnxeth(nio_name,tokens[3]);  
          break;  
 #endif  
   
 #ifdef GEN_ETH  
       case NETIO_TYPE_GEN_ETH:  
          if (count != 4) {  
             vm_error(router->vm,"invalid number of "  
                      "arguments for Generic Eth NIO '%s'\n",str);  
             goto done;  
          }  
           
          nio = netio_desc_create_geneth(nio_name,tokens[3]);  
          break;  
 #endif  
   
       default:  
          vm_error(router->vm,"unknown NETIO type '%s'\n",tokens[2]);  
          goto done;  
    }  
   
    if (!nio) {  
       fprintf(stderr,"c7200_cmd_add_nio: unable to create NETIO "  
               "descriptor for PA bay %u\n",pa_bay);  
       goto done;  
    }  
   
    if (c7200_pa_add_nio_binding(router,pa_bay,port_id,nio_name) == -1) {  
       vm_error(router->vm,"unable to add NETIO binding for slot %u\n",pa_bay);  
       netio_release(nio_name);  
       netio_delete(nio_name);  
       goto done;  
    }  
     
    netio_release(nio_name);  
    res = 0;  
   
  done:  
    /* The complete array was cleaned by strsplit */  
    for(i=0;i<PA_DESC_MAX_TOKENS;i++)  
       free(tokens[i]);  
   
    return(res);  
 }  
   
 /* Show the list of available PA drivers */  
 void c7200_pa_show_drivers(void)  
 {  
    int i;  
   
    printf("Available C7200 Port Adapter drivers:\n");  
   
    for(i=0;pa_drivers[i];i++) {  
       printf("  * %s %s\n",  
              pa_drivers[i]->dev_type,  
              !pa_drivers[i]->supported ? "(NOT WORKING)" : "");  
    }  
     
    printf("\n");  
 }  
   
565  /* Get an NPE driver */  /* Get an NPE driver */
566  struct c7200_npe_driver *c7200_npe_get_driver(char *npe_type)  struct c7200_npe_driver *c7200_npe_get_driver(char *npe_type)
567  {  {
# Line 1196  int c7200_npe_set_type(c7200_t *router,c Line 597  int c7200_npe_set_type(c7200_t *router,c
597        return(-1);        return(-1);
598     }     }
599    
600       /* Use a C7200-IO-FE by default in slot 0 if an I/O card is required */
601       if (driver->iocard_required) {
602          vm_slot_add_binding(router->vm,"C7200-IO-FE",0,0);
603          vm_slot_set_flag(router->vm,0,0,CISCO_CARD_FLAG_OVERRIDE);
604       }
605     return(0);     return(0);
606  }  }
607    
608  /* Show the list of available NPE drivers */  /* Show the list of available NPE drivers */
609  void c7200_npe_show_drivers(void)  static void c7200_npe_show_drivers(void)
610  {  {
611     int i;     int i;
612    
# Line 1318  static int c7200_init_dual_gt64120(c7200 Line 724  static int c7200_init_dual_gt64120(c7200
724     return(0);     return(0);
725  }  }
726    
727    /* Create the two main PCI busses for a MV64460 based system */
728    static int c7200_init_mv64460(c7200_t *router)
729    {
730       vm_instance_t *vm = router->vm;
731    
732       vm->pci_bus[0] = pci_bus_create("MB0/MB1",3);
733       vm->pci_bus[1] = pci_bus_create("MB2",0);
734    
735       if (!vm->pci_bus[0] || !vm->pci_bus[1]) {
736          vm_error(vm,"unable to create PCI data.\n");
737          return(-1);
738       }
739    
740       return(dev_mv64460_init(vm,"mv64460",C7200_G2_MV64460_ADDR,0x10000));
741    }
742    
743  /* Create the PA PCI busses */  /* Create the PA PCI busses */
744  static int c7200_pa_create_pci_busses(c7200_t *router)  static int c7200_pa_create_pci_busses(c7200_t *router)
745  {    {  
# Line 1340  static int c7200_pa_create_pci_busses(c7 Line 762  static int c7200_pa_create_pci_busses(c7
762  static int c7200_pa_init_pci_bridge(c7200_t *router,u_int pa_bay,  static int c7200_pa_init_pci_bridge(c7200_t *router,u_int pa_bay,
763                                      struct pci_bus *pci_bus,int pci_device)                                      struct pci_bus *pci_bus,int pci_device)
764  {  {
765       struct pci_bus *pa_bus;
766    
767       pa_bus = router->vm->slots_pci_bus[pa_bay];
768    
769     switch(router->midplane_version) {     switch(router->midplane_version) {
770        case 0:        case 0:
771        case 1:        case 1:
772           dev_dec21050_init(pci_bus,pci_device,router->pa_bay[pa_bay].pci_map);           dev_dec21050_init(pci_bus,pci_device,pa_bus);
773           break;           break;
774        default:        default:
775           dev_dec21150_init(pci_bus,pci_device,router->pa_bay[pa_bay].pci_map);           dev_dec21150_init(pci_bus,pci_device,pa_bus);
776     }     }
777     return(0);     return(0);
778  }  }
# Line 1393  int c7200_init_npe100(c7200_t *router) Line 819  int c7200_init_npe100(c7200_t *router)
819     int i;     int i;
820    
821     /* Set the processor type: R4600 */     /* Set the processor type: R4600 */
822     mips64_set_prid(vm->boot_cpu,MIPS_PRID_R4600);     mips64_set_prid(CPU_MIPS64(vm->boot_cpu),MIPS_PRID_R4600);
823    
824     /* Initialize the Galileo GT-64010 system controller */     /* Initialize the Galileo GT-64010 system controller */
825     if (c7200_init_gt64010(router) == -1)     if (c7200_init_gt64010(router) == -1)
# Line 1417  int c7200_init_npe100(c7200_t *router) Line 843  int c7200_init_npe100(c7200_t *router)
843     dev_dec21050_init(vm->pci_bus[0],4,vm->pci_bus_pool[25]);     dev_dec21050_init(vm->pci_bus[0],4,vm->pci_bus_pool[25]);
844    
845     /* Map the PA PCI busses */     /* Map the PA PCI busses */
846     router->pa_bay[0].pci_map = vm->pci_bus[0];     vm->slots_pci_bus[0] = vm->pci_bus[0];
847    
848     for(i=1;i<C7200_MAX_PA_BAYS;i++)     for(i=1;i<C7200_MAX_PA_BAYS;i++)
849        router->pa_bay[i].pci_map = vm->pci_bus_pool[i];        vm->slots_pci_bus[i] = vm->pci_bus_pool[i];
850    
851     /* PCI bridges for PA Bays 1 to 6 */     /* PCI bridges for PA Bays 1 to 6 */
852     c7200_pa_init_pci_bridge(router,1,vm->pci_bus_pool[24],1);     c7200_pa_init_pci_bridge(router,1,vm->pci_bus_pool[24],1);
# Line 1441  int c7200_init_npe150(c7200_t *router) Line 867  int c7200_init_npe150(c7200_t *router)
867     int i;     int i;
868    
869     /* Set the processor type: R4700 */     /* Set the processor type: R4700 */
870     mips64_set_prid(vm->boot_cpu,MIPS_PRID_R4700);     mips64_set_prid(CPU_MIPS64(vm->boot_cpu),MIPS_PRID_R4700);
871    
872     /* Initialize the Galileo GT-64010 system controller */     /* Initialize the Galileo GT-64010 system controller */
873     if (c7200_init_gt64010(router) == -1)     if (c7200_init_gt64010(router) == -1)
# Line 1465  int c7200_init_npe150(c7200_t *router) Line 891  int c7200_init_npe150(c7200_t *router)
891     dev_dec21050_init(vm->pci_bus[0],4,vm->pci_bus_pool[25]);     dev_dec21050_init(vm->pci_bus[0],4,vm->pci_bus_pool[25]);
892    
893     /* Map the PA PCI busses */       /* Map the PA PCI busses */  
894     router->pa_bay[0].pci_map = vm->pci_bus[0];     vm->slots_pci_bus[0] = vm->pci_bus[0];
895    
896     for(i=1;i<C7200_MAX_PA_BAYS;i++)     for(i=1;i<C7200_MAX_PA_BAYS;i++)
897        router->pa_bay[i].pci_map = vm->pci_bus_pool[i];        vm->slots_pci_bus[i] = vm->pci_bus_pool[i];
898    
899     /* PCI bridges for PA Bays 1 to 6 */     /* PCI bridges for PA Bays 1 to 6 */
900     c7200_pa_init_pci_bridge(router,1,vm->pci_bus_pool[24],1);     c7200_pa_init_pci_bridge(router,1,vm->pci_bus_pool[24],1);
# Line 1497  int c7200_init_npe175(c7200_t *router) Line 923  int c7200_init_npe175(c7200_t *router)
923     int i;     int i;
924    
925     /* Set the processor type: R5271 */     /* Set the processor type: R5271 */
926     mips64_set_prid(vm->boot_cpu,MIPS_PRID_R527x);     mips64_set_prid(CPU_MIPS64(vm->boot_cpu),MIPS_PRID_R527x);
927    
928     /* Initialize the Galileo GT-64120 PCI controller */     /* Initialize the Galileo GT-64120 PCI controller */
929     if (c7200_init_gt64120(router) == -1)     if (c7200_init_gt64120(router) == -1)
# Line 1518  int c7200_init_npe175(c7200_t *router) Line 944  int c7200_init_npe175(c7200_t *router)
944    
945     /* Map the PA PCI busses */     /* Map the PA PCI busses */
946     for(i=0;i<C7200_MAX_PA_BAYS;i++)     for(i=0;i<C7200_MAX_PA_BAYS;i++)
947        router->pa_bay[i].pci_map = vm->pci_bus_pool[i];        vm->slots_pci_bus[i] = vm->pci_bus_pool[i];
948    
949     /* PCI bridges for PA Bays 1 to 6 */     /* PCI bridges for PA Bays 1 to 6 */
950     c7200_pa_init_pci_bridge(router,1,vm->pci_bus[0],7);     c7200_pa_init_pci_bridge(router,1,vm->pci_bus[0],7);
# Line 1542  int c7200_init_npe200(c7200_t *router) Line 968  int c7200_init_npe200(c7200_t *router)
968     int i;     int i;
969    
970     /* Set the processor type: R5000 */     /* Set the processor type: R5000 */
971     mips64_set_prid(vm->boot_cpu,MIPS_PRID_R5000);     mips64_set_prid(CPU_MIPS64(vm->boot_cpu),MIPS_PRID_R5000);
972    
973     /* Initialize the Galileo GT-64010 PCI controller */     /* Initialize the Galileo GT-64010 PCI controller */
974     if (c7200_init_gt64010(router) == -1)     if (c7200_init_gt64010(router) == -1)
# Line 1566  int c7200_init_npe200(c7200_t *router) Line 992  int c7200_init_npe200(c7200_t *router)
992     dev_dec21050_init(vm->pci_bus[0],4,vm->pci_bus_pool[25]);     dev_dec21050_init(vm->pci_bus[0],4,vm->pci_bus_pool[25]);
993    
994     /* Map the PA PCI busses */     /* Map the PA PCI busses */
995     router->pa_bay[0].pci_map = vm->pci_bus[0];     vm->slots_pci_bus[0] = vm->pci_bus[0];
996    
997     for(i=1;i<C7200_MAX_PA_BAYS;i++)     for(i=1;i<C7200_MAX_PA_BAYS;i++)
998        router->pa_bay[i].pci_map = vm->pci_bus_pool[i];        vm->slots_pci_bus[i] = vm->pci_bus_pool[i];
999    
1000     /* PCI bridges for PA Bays 1 to 6 */     /* PCI bridges for PA Bays 1 to 6 */
1001     c7200_pa_init_pci_bridge(router,1,vm->pci_bus_pool[24],1);     c7200_pa_init_pci_bridge(router,1,vm->pci_bus_pool[24],1);
# Line 1598  int c7200_init_npe225(c7200_t *router) Line 1024  int c7200_init_npe225(c7200_t *router)
1024     int i;     int i;
1025    
1026     /* Set the processor type: R5271 */     /* Set the processor type: R5271 */
1027     mips64_set_prid(vm->boot_cpu,MIPS_PRID_R527x);     mips64_set_prid(CPU_MIPS64(vm->boot_cpu),MIPS_PRID_R527x);
1028    
1029     /* Initialize the Galileo GT-64120 PCI controller */     /* Initialize the Galileo GT-64120 PCI controller */
1030     if (c7200_init_gt64120(router) == -1)     if (c7200_init_gt64120(router) == -1)
# Line 1619  int c7200_init_npe225(c7200_t *router) Line 1045  int c7200_init_npe225(c7200_t *router)
1045    
1046     /* Map the PA PCI busses */     /* Map the PA PCI busses */
1047     for(i=0;i<C7200_MAX_PA_BAYS;i++)     for(i=0;i<C7200_MAX_PA_BAYS;i++)
1048        router->pa_bay[i].pci_map = vm->pci_bus_pool[i];        vm->slots_pci_bus[i] = vm->pci_bus_pool[i];
1049    
1050     /* PCI bridges for PA Bays 1 to 6 */     /* PCI bridges for PA Bays 1 to 6 */
1051     c7200_pa_init_pci_bridge(router,1,vm->pci_bus[0],7);     c7200_pa_init_pci_bridge(router,1,vm->pci_bus[0],7);
# Line 1642  int c7200_init_npe300(c7200_t *router) Line 1068  int c7200_init_npe300(c7200_t *router)
1068     int i;     int i;
1069    
1070     /* Set the processor type: R7000 */     /* Set the processor type: R7000 */
1071     mips64_set_prid(vm->boot_cpu,MIPS_PRID_R7000);     mips64_set_prid(CPU_MIPS64(vm->boot_cpu),MIPS_PRID_R7000);
1072    
1073     /* 32 Mb of I/O memory */     /* 32 Mb of I/O memory */
1074     vm->iomem_size = 32;     vm->iomem_size = 32;
1075     dev_ram_init(vm,"iomem",vm->ram_mmap,TRUE,NULL,C7200_IOMEM_ADDR,32*1048576);     dev_ram_init(vm,"iomem",vm->ram_mmap,TRUE,NULL,vm->sparse_mem,
1076                    C7200_IOMEM_ADDR,32*1048576);
1077    
1078     /* Initialize the two Galileo GT-64120 system controllers */     /* Initialize the two Galileo GT-64120 system controllers */
1079     if (c7200_init_dual_gt64120(router) == -1)     if (c7200_init_dual_gt64120(router) == -1)
# Line 1675  int c7200_init_npe300(c7200_t *router) Line 1102  int c7200_init_npe300(c7200_t *router)
1102    
1103     /* Map the PA PCI busses */     /* Map the PA PCI busses */
1104     for(i=0;i<C7200_MAX_PA_BAYS;i++)     for(i=0;i<C7200_MAX_PA_BAYS;i++)
1105        router->pa_bay[i].pci_map = vm->pci_bus_pool[i];        vm->slots_pci_bus[i] = vm->pci_bus_pool[i];
1106    
1107     /* PCI bridges for PA Bays 1 to 6 */     /* PCI bridges for PA Bays 1 to 6 */
1108     c7200_pa_init_pci_bridge(router,1,vm->pci_bus_pool[24],1);     c7200_pa_init_pci_bridge(router,1,vm->pci_bus_pool[24],1);
# Line 1695  int c7200_init_npe400(c7200_t *router) Line 1122  int c7200_init_npe400(c7200_t *router)
1122     int i;     int i;
1123    
1124     /* Set the processor type: R7000 */     /* Set the processor type: R7000 */
1125     mips64_set_prid(vm->boot_cpu,MIPS_PRID_R7000);     mips64_set_prid(CPU_MIPS64(vm->boot_cpu),MIPS_PRID_R7000);
1126    
1127     /*     /*
1128      * 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 1703  int c7200_init_npe400(c7200_t *router) Line 1130  int c7200_init_npe400(c7200_t *router)
1130     if (vm->ram_size > C7200_BASE_RAM_LIMIT) {     if (vm->ram_size > C7200_BASE_RAM_LIMIT) {
1131        vm->iomem_size = vm->ram_size - C7200_BASE_RAM_LIMIT;        vm->iomem_size = vm->ram_size - C7200_BASE_RAM_LIMIT;
1132        vm->ram_size = C7200_BASE_RAM_LIMIT;        vm->ram_size = C7200_BASE_RAM_LIMIT;
1133        dev_ram_init(vm,"ram1",vm->ram_mmap,TRUE,NULL,        dev_ram_init(vm,"ram1",vm->ram_mmap,TRUE,NULL,vm->sparse_mem,
1134                     C7200_IOMEM_ADDR,vm->iomem_size*1048576);                     C7200_IOMEM_ADDR,vm->iomem_size*1048576);
1135     }     }
1136    
# Line 1726  int c7200_init_npe400(c7200_t *router) Line 1153  int c7200_init_npe400(c7200_t *router)
1153    
1154     /* Map the PA PCI busses */     /* Map the PA PCI busses */
1155     for(i=0;i<C7200_MAX_PA_BAYS;i++)     for(i=0;i<C7200_MAX_PA_BAYS;i++)
1156        router->pa_bay[i].pci_map = vm->pci_bus_pool[i];        vm->slots_pci_bus[i] = vm->pci_bus_pool[i];
1157    
1158     /* PCI bridges for PA Bays 1 to 6 */     /* PCI bridges for PA Bays 1 to 6 */
1159     c7200_pa_init_pci_bridge(router,1,vm->pci_bus[0],7);     c7200_pa_init_pci_bridge(router,1,vm->pci_bus[0],7);
# Line 1746  int c7200_init_npeg1(c7200_t *router) Line 1173  int c7200_init_npeg1(c7200_t *router)
1173     int i;     int i;
1174    
1175     /* Just some tests */     /* Just some tests */
1176     mips64_set_prid(vm->boot_cpu,MIPS_PRID_BCM1250);     mips64_set_prid(CPU_MIPS64(vm->boot_cpu),MIPS_PRID_BCM1250);
1177     vm->pci_bus[0] = pci_bus_create("HT/PCI bus",0);     vm->pci_bus[0] = pci_bus_create("HT/PCI bus",0);
1178    
1179     /* SB-1 System control devices */     /* SB-1 System control devices */
# Line 1781  int c7200_init_npeg1(c7200_t *router) Line 1208  int c7200_init_npeg1(c7200_t *router)
1208     c7200_create_io_pci_bridge(router,vm->pci_bus_pool[0]);     c7200_create_io_pci_bridge(router,vm->pci_bus_pool[0]);
1209    
1210     /* Map the PA PCI busses */     /* Map the PA PCI busses */
1211     router->pa_bay[0].pci_map = vm->pci_bus[0];     vm->slots_pci_bus[0] = vm->pci_bus[0];
1212    
1213     for(i=1;i<C7200_MAX_PA_BAYS;i++)     for(i=1;i<C7200_MAX_PA_BAYS;i++)
1214        router->pa_bay[i].pci_map = vm->pci_bus_pool[i];        vm->slots_pci_bus[i] = vm->pci_bus_pool[i];
1215    
1216       /* PCI bridges for PA Bays 1 to 6 */
1217       c7200_pa_init_pci_bridge(router,1,vm->pci_bus_pool[24],1);
1218       c7200_pa_init_pci_bridge(router,3,vm->pci_bus_pool[24],2);
1219       c7200_pa_init_pci_bridge(router,5,vm->pci_bus_pool[24],3);
1220    
1221       c7200_pa_init_pci_bridge(router,2,vm->pci_bus_pool[25],1);
1222       c7200_pa_init_pci_bridge(router,4,vm->pci_bus_pool[25],2);
1223       c7200_pa_init_pci_bridge(router,6,vm->pci_bus_pool[25],3);
1224       return(0);
1225    }
1226    
1227    /* Initialize an NPE-G2 board (XXX not working) */
1228    int c7200_init_npeg2(c7200_t *router)
1229    {    
1230       vm_instance_t *vm = router->vm;
1231       int i;
1232    
1233       /* Set the processor type: PowerPC G4 */
1234       ppc32_set_pvr(CPU_PPC32(vm->boot_cpu),0x80040201);
1235    
1236       /* Initialize the PA PCI busses */
1237       if (c7200_pa_create_pci_busses(router) == -1)
1238          return(-1);
1239    
1240       /* Create PCI bus for PA Bay 0 (I/O Card, PCMCIA, Interfaces) */
1241       vm->pci_bus_pool[0] = pci_bus_create("PA Slot 0",-1);
1242    
1243       /* PCI bridge for I/O card device on MB0 */
1244       dev_plx6520cb_init(vm->pci_bus[1],3,vm->pci_bus_pool[0]);
1245    
1246       /* Create PCI busses for PA Bays 1,3,5 and PA Bays 2,4,6 */
1247       vm->pci_bus_pool[24] = pci_bus_create("PA Slots 1,3,5",-1);
1248       vm->pci_bus_pool[25] = pci_bus_create("PA Slots 2,4,6",-1);
1249    
1250       dev_plx6520cb_init(vm->pci_bus[0],1,vm->pci_bus_pool[24]);
1251       dev_plx6520cb_init(vm->pci_bus[0],2,vm->pci_bus_pool[25]);
1252    
1253       /* Create the hidden "I/O" PCI bridge for PCMCIA controller */
1254       c7200_create_io_pci_bridge(router,vm->pci_bus_pool[0]);
1255    
1256       /* Map the PA PCI busses */
1257       vm->slots_pci_bus[0] = vm->pci_bus_pool[0];
1258    
1259       for(i=1;i<C7200_MAX_PA_BAYS;i++)
1260          vm->slots_pci_bus[i] = vm->pci_bus_pool[i];
1261    
1262     /* PCI bridges for PA Bays 1 to 6 */     /* PCI bridges for PA Bays 1 to 6 */
1263     c7200_pa_init_pci_bridge(router,1,vm->pci_bus_pool[24],1);     c7200_pa_init_pci_bridge(router,1,vm->pci_bus_pool[24],1);
# Line 1821  void c7200_show_hardware(c7200_t *router Line 1294  void c7200_show_hardware(c7200_t *router
1294  }  }
1295    
1296  /* Initialize default parameters for a C7200 */  /* Initialize default parameters for a C7200 */
1297  void c7200_init_defaults(c7200_t *router)  static void c7200_init_defaults(c7200_t *router)
1298  {  {
1299     vm_instance_t *vm = router->vm;     vm_instance_t *vm = router->vm;
1300     n_eth_addr_t *m;     n_eth_addr_t *m;
1301     m_uint16_t pid;     m_uint16_t pid;
1302    
1303       /* Set platform slots characteristics */
1304       vm->nr_slots   = C7200_MAX_PA_BAYS;
1305       vm->slots_type = CISCO_CARD_TYPE_PA;
1306       vm->slots_drivers = pa_drivers;
1307    
1308     pid = (m_uint16_t)getpid();     pid = (m_uint16_t)getpid();
1309    
1310     /* Generate a chassis MAC address based on the instance ID */     /* Generate a chassis MAC address based on the instance ID */
# Line 1838  void c7200_init_defaults(c7200_t *router Line 1316  void c7200_init_defaults(c7200_t *router
1316     m->eth_addr_byte[4] = 0x00;     m->eth_addr_byte[4] = 0x00;
1317     m->eth_addr_byte[5] = 0x00;     m->eth_addr_byte[5] = 0x00;
1318    
1319     c7200_init_eeprom_groups(router);     c7200_init_sys_eeprom_groups(router);
1320       c7200_init_mp_eeprom_groups(router);
1321     c7200_npe_set_type(router,C7200_DEFAULT_NPE_TYPE);     c7200_npe_set_type(router,C7200_DEFAULT_NPE_TYPE);
1322     c7200_midplane_set_type(router,C7200_DEFAULT_MIDPLANE);     c7200_midplane_set_type(router,C7200_DEFAULT_MIDPLANE);
1323    
# Line 1853  void c7200_init_defaults(c7200_t *router Line 1332  void c7200_init_defaults(c7200_t *router
1332    
1333     vm->pcmcia_disk_size[0] = C7200_DEFAULT_DISK0_SIZE;     vm->pcmcia_disk_size[0] = C7200_DEFAULT_DISK0_SIZE;
1334     vm->pcmcia_disk_size[1] = C7200_DEFAULT_DISK1_SIZE;     vm->pcmcia_disk_size[1] = C7200_DEFAULT_DISK1_SIZE;
   
    /* Enable NVRAM operations to load/store configs */  
    vm->nvram_extract_config = c7200_nvram_extract_config;  
    vm->nvram_push_config = c7200_nvram_push_config;  
1335  }  }
1336    
1337  /* Run the checklist */  /* Run the checklist */
1338  int c7200_checklist(c7200_t *router)  static int c7200_checklist(c7200_t *router)
1339  {  {
1340     struct vm_instance *vm = router->vm;     struct vm_instance *vm = router->vm;
1341     int res = 0;     int res = 0;
# Line 1876  int c7200_checklist(c7200_t *router) Line 1351  int c7200_checklist(c7200_t *router)
1351     return(res);     return(res);
1352  }  }
1353    
1354  /* Initialize the C7200 Platform */  /* Initialize Port Adapters */
1355  int c7200_init_platform(c7200_t *router)  static int c7200_init_platform_pa(c7200_t *router)
1356    {
1357       return(vm_slot_init_all(router->vm));
1358    }
1359    
1360    /* Initialize the C7200 Platform (MIPS) */
1361    static int c7200m_init_platform(c7200_t *router)
1362  {  {
1363     struct vm_instance *vm = router->vm;     struct vm_instance *vm = router->vm;
1364     struct c7200_pa_bay *pa_bay;     cpu_mips_t *cpu0;
1365     cpu_mips_t *cpu0;     cpu_gen_t *gen0;
1366     int i;     vm_obj_t *obj;
1367    
1368     /* Copy config register setup into "active" config register */     /* Copy config register setup into "active" config register */
1369     vm->conf_reg = vm->conf_reg_setup;     vm->conf_reg = vm->conf_reg_setup;
# Line 1903  int c7200_init_platform(c7200_t *router) Line 1384  int c7200_init_platform(c7200_t *router)
1384     vm->cpu_group = cpu_group_create("System CPU");     vm->cpu_group = cpu_group_create("System CPU");
1385    
1386     /* Initialize the virtual MIPS processor */     /* Initialize the virtual MIPS processor */
1387     if (!(cpu0 = cpu_create(vm,0))) {     if (!(gen0 = cpu_create(vm,CPU_TYPE_MIPS64,0))) {
1388        vm_error(vm,"unable to create CPU0!\n");        vm_error(vm,"unable to create CPU0!\n");
1389        return(-1);        return(-1);
1390     }     }
1391    
1392       cpu0 = CPU_MIPS64(gen0);
1393    
1394     /* Add this CPU to the system CPU group */     /* Add this CPU to the system CPU group */
1395     cpu_group_add(vm->cpu_group,cpu0);     cpu_group_add(vm->cpu_group,gen0);
1396     vm->boot_cpu = cpu0;     vm->boot_cpu = gen0;
1397    
1398       /* Initialize the IRQ routing vectors */
1399       vm->set_irq = mips64_vm_set_irq;
1400       vm->clear_irq = mips64_vm_clear_irq;
1401    
1402     /* Mark the Network IO interrupt as high priority */     /* Mark the Network IO interrupt as high priority */
1403     cpu0->irq_idle_preempt[C7200_NETIO_IRQ] = TRUE;     cpu0->irq_idle_preempt[C7200_NETIO_IRQ] = TRUE;
# Line 1931  int c7200_init_platform(c7200_t *router) Line 1418  int c7200_init_platform(c7200_t *router)
1418     /* Remote emulator control */     /* Remote emulator control */
1419     dev_remote_control_init(vm,0x16000000,0x1000);     dev_remote_control_init(vm,0x16000000,0x1000);
1420    
1421     /* Bootflash */     /* Bootflash (8 Mb) */
1422     dev_bootflash_init(vm,"bootflash",C7200_BOOTFLASH_ADDR,(8 * 1048576));     dev_bootflash_init(vm,"bootflash","c7200-bootflash-8mb",
1423                          C7200_BOOTFLASH_ADDR);
1424    
1425     /* NVRAM and calendar */     /* NVRAM and calendar */
1426     dev_nvram_init(vm,"nvram",router->npe_driver->nvram_addr,     dev_nvram_init(vm,"nvram",router->npe_driver->nvram_addr,
# Line 1941  int c7200_init_platform(c7200_t *router) Line 1429  int c7200_init_platform(c7200_t *router)
1429     /* Bit-bucket zone */     /* Bit-bucket zone */
1430     dev_zero_init(vm,"zero",C7200_BITBUCKET_ADDR,0xc00000);     dev_zero_init(vm,"zero",C7200_BITBUCKET_ADDR,0xc00000);
1431    
1432       /* Initialize the NPE board */
1433       if (router->npe_driver->npe_init(router) == -1)
1434          return(-1);
1435    
1436       /* Initialize RAM */
1437       vm_ram_init(vm,0x00000000ULL);
1438    
1439       /* Initialize ROM */
1440       if (!vm->rom_filename) {
1441          /* use embedded ROM */
1442          dev_rom_init(vm,"rom",C7200_ROM_ADDR,vm->rom_size*1048576,
1443                       mips64_microcode,mips64_microcode_len);
1444       } else {
1445          /* use alternate ROM */
1446          dev_ram_init(vm,"rom",TRUE,TRUE,NULL,FALSE,
1447                       C7200_ROM_ADDR,vm->rom_size*1048576);
1448       }
1449    
1450       /* Byte swapping */
1451       dev_bswap_init(vm,"mem_bswap",C7200_BSWAP_ADDR,1024*1048576,0x00000000ULL);
1452    
1453       /* PCI IO space */
1454       if (!(vm->pci_io_space = pci_io_data_init(vm,C7200_PCI_IO_ADDR)))
1455          return(-1);
1456    
1457       /* Cirrus Logic PD6729 (PCI-to-PCMCIA host adapter) */
1458       dev_clpd6729_init(vm,router->pcmcia_bus,
1459                         router->npe_driver->clpd6729_pci_dev,
1460                         vm->pci_io_space,0x402,0x403);
1461    
1462       /* Initialize the Port Adapters */
1463       if (c7200_init_platform_pa(router) == -1)
1464          return(-1);
1465    
1466       /* Verify the check list */
1467       if (c7200_checklist(router) == -1)
1468          return(-1);
1469    
1470     /* Midplane FPGA */     /* Midplane FPGA */
1471     dev_c7200_mpfpga_init(router,C7200_MPFPGA_ADDR,0x1000);     dev_c7200_mpfpga_init(router,C7200_MPFPGA_ADDR,0x1000);
1472    
1473       if (!(obj = vm_object_find(router->vm,"mp_fpga")))
1474          return(-1);
1475    
1476       router->mpfpga_data = obj->data;
1477    
1478     /* IO FPGA */     /* IO FPGA */
1479     if (dev_c7200_iofpga_init(router,C7200_IOFPGA_ADDR,0x1000) == -1)     if (dev_c7200_iofpga_init(router,C7200_IOFPGA_ADDR,0x1000) == -1)
1480        return(-1);        return(-1);
1481    
1482       /* Show device list */
1483       c7200_show_hardware(router);
1484       return(0);
1485    }
1486    
1487    /* Initialize the C7200 Platform (PowerPC) */
1488    static int c7200p_init_platform(c7200_t *router)
1489    {
1490       struct vm_instance *vm = router->vm;
1491       cpu_ppc_t *cpu0;
1492       cpu_gen_t *gen0;
1493       vm_obj_t *obj;
1494    
1495       /* Copy config register setup into "active" config register */
1496       vm->conf_reg = vm->conf_reg_setup;
1497    
1498       /* Create Console and AUX ports */
1499       vm_init_vtty(vm);
1500    
1501       /* Check that the amount of RAM is valid */
1502       if (vm->ram_size > router->npe_driver->max_ram_size) {
1503          vm_error(vm,"%u is not a valid RAM size for this NPE. "
1504                   "Fallback to %u Mb.\n\n",
1505                   vm->ram_size,router->npe_driver->max_ram_size);
1506      
1507          vm->ram_size = router->npe_driver->max_ram_size;
1508       }
1509    
1510       /* Create a CPU group */
1511       vm->cpu_group = cpu_group_create("System CPU");
1512    
1513       /* Initialize the virtual PowerPC processor */
1514       if (!(gen0 = cpu_create(vm,CPU_TYPE_PPC32,0))) {
1515          vm_error(vm,"unable to create CPU0!\n");
1516          return(-1);
1517       }
1518    
1519       cpu0 = CPU_PPC32(gen0);
1520    
1521       /* Add this CPU to the system CPU group */
1522       cpu_group_add(vm->cpu_group,gen0);
1523       vm->boot_cpu = gen0;
1524    
1525       /* Mark the Network IO interrupt as high priority */
1526       vm->irq_idle_preempt[C7200_NETIO_IRQ] = TRUE;
1527    
1528       /* Copy some parameters from VM to CPU0 (idle PC, ...) */
1529       cpu0->idle_pc = vm->idle_pc;
1530    
1531       if (vm->timer_irq_check_itv)
1532          cpu0->timer_irq_check_itv = vm->timer_irq_check_itv;
1533    
1534       /* Initialize the Marvell MV-64460 system controller */
1535       if (c7200_init_mv64460(router) == -1)
1536          return(-1);
1537    
1538       if (!(obj = vm_object_find(router->vm,"mv64460")))
1539          return(-1);
1540    
1541       router->mv64460_sysctr = obj->data;
1542    
1543       /* Remote emulator control */
1544       dev_remote_control_init(vm,0xf6000000,0x1000);
1545    
1546       /* Bootflash (64 Mb) */
1547       dev_bootflash_init(vm,"bootflash","c7200-bootflash-64mb",
1548                          C7200_G2_BOOTFLASH_ADDR);
1549    
1550       /* NVRAM and calendar */
1551       vm->nvram_size = C7200_G2_NVRAM_SIZE / 1024;
1552       dev_nvram_init(vm,"nvram",router->npe_driver->nvram_addr,
1553                      C7200_G2_NVRAM_SIZE,&vm->conf_reg);
1554    
1555     /* Initialize the NPE board */     /* Initialize the NPE board */
1556     if (router->npe_driver->npe_init(router) == -1)     if (router->npe_driver->npe_init(router) == -1)
1557        return(-1);        return(-1);
# Line 1958  int c7200_init_platform(c7200_t *router) Line 1562  int c7200_init_platform(c7200_t *router)
1562     /* Initialize ROM */     /* Initialize ROM */
1563     if (!vm->rom_filename) {     if (!vm->rom_filename) {
1564        /* use embedded ROM */        /* use embedded ROM */
1565        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,
1566                       ppc32_microcode,ppc32_microcode_len);
1567     } else {     } else {
1568        /* use alternate ROM */        /* use alternate ROM */
1569        dev_ram_init(vm,"rom",TRUE,TRUE,NULL,        dev_ram_init(vm,"rom",TRUE,TRUE,NULL,FALSE,
1570                     C7200_ROM_ADDR,vm->rom_size*1048576);                     C7200_G2_ROM_ADDR,vm->rom_size*1048576);
1571     }     }
1572    
1573       /* Byte swapping */
1574       dev_bswap_init(vm,"mem_bswap",C7200_G2_BSWAP_ADDR,512*1048576,
1575                      0x00000000ULL);
1576    
1577     /* PCI IO space */     /* PCI IO space */
1578     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)))
1579        return(-1);        return(-1);
1580    
1581     /* Cirrus Logic PD6729 (PCI-to-PCMCIA host adapter) */     /* Cirrus Logic PD6729 (PCI-to-PCMCIA host adapter) */
# Line 1974  int c7200_init_platform(c7200_t *router) Line 1583  int c7200_init_platform(c7200_t *router)
1583                       router->npe_driver->clpd6729_pci_dev,                       router->npe_driver->clpd6729_pci_dev,
1584                       vm->pci_io_space,0x402,0x403);                       vm->pci_io_space,0x402,0x403);
1585    
1586     /* Initialize Port Adapters */     /* Initialize the Port Adapters */
1587     for(i=0;i<C7200_MAX_PA_BAYS;i++) {     if (c7200_init_platform_pa(router) == -1)
1588        pa_bay = &router->pa_bay[i];        return(-1);
1589      
1590        if (!pa_bay->dev_type)     /* IO FPGA */
1591           continue;     if (dev_c7200_iofpga_init(router,C7200_G2_IOFPGA_ADDR,0x1000) == -1)
1592          return(-1);
       if (c7200_pa_init(router,i) == -1) {  
          vm_error(vm,"unable to create Port Adapter \"%s\"\n",  
                   pa_bay->dev_type);  
          return(-1);  
       }  
    }  
1593    
1594     /* By default, initialize a C7200-IO-FE in slot 0 if nothing found */     /* MP FPGA */
1595     if (!router->pa_bay[0].drv_info) {     if (dev_c7200_mpfpga_init(router,C7200_G2_MPFPGA_ADDR,0x10000) == -1)
1596        c7200_pa_add_binding(router,"C7200-IO-FE",0);        return(-1);
       c7200_pa_init(router,0);  
    }  
1597    
1598     /* Verify the check list */     if (!(obj = vm_object_find(router->vm,"mp_fpga")))
    if (c7200_checklist(router) == -1)  
1599        return(-1);        return(-1);
1600    
1601       router->mpfpga_data = obj->data;
1602    
1603       /* If we have nothing in slot 0, the console is handled by the MV64460 */
1604       if (!vm_slot_get_card_ptr(vm,0)) {
1605          vm_log(vm,"CONSOLE","console managed by NPE-G2 board\n");
1606          mv64460_sdma_bind_vtty(router->mv64460_sysctr,0,vm->vtty_con);
1607          mv64460_sdma_bind_vtty(router->mv64460_sysctr,1,vm->vtty_aux);
1608       }
1609    
1610     /* Show device list */     /* Show device list */
1611     c7200_show_hardware(router);     c7200_show_hardware(router);
1612     return(0);     return(0);
1613  }  }
1614    
1615  /* Boot the IOS image */  /* Boot the IOS image (MIPS) */
1616  int c7200_boot_ios(c7200_t *router)  static int c7200m_boot_ios(c7200_t *router)
1617  {    {  
1618     vm_instance_t *vm = router->vm;     vm_instance_t *vm = router->vm;
1619       cpu_mips_t *cpu;
1620    
1621     if (!vm->boot_cpu)     if (!vm->boot_cpu)
1622        return(-1);        return(-1);
# Line 2021  int c7200_boot_ios(c7200_t *router) Line 1631  int c7200_boot_ios(c7200_t *router)
1631     }     }
1632    
1633     /* Reset the boot CPU */     /* Reset the boot CPU */
1634     mips64_reset(vm->boot_cpu);     cpu = CPU_MIPS64(vm->boot_cpu);
1635       mips64_reset(cpu);
1636    
1637     /* Load IOS image */     /* Load IOS image */
1638     if (mips64_load_elf_image(vm->boot_cpu,vm->ios_image,     if (mips64_load_elf_image(cpu,vm->ios_image,
1639                               (vm->ghost_status == VM_GHOST_RAM_USE),                               (vm->ghost_status == VM_GHOST_RAM_USE),
1640                               &vm->ios_entry_point) < 0)                               &vm->ios_entry_point) < 0)
1641     {     {
# Line 2035  int c7200_boot_ios(c7200_t *router) Line 1646  int c7200_boot_ios(c7200_t *router)
1646     /* Launch the simulation */     /* Launch the simulation */
1647     printf("\nC7200 '%s': starting simulation (CPU0 PC=0x%llx), "     printf("\nC7200 '%s': starting simulation (CPU0 PC=0x%llx), "
1648            "JIT %sabled.\n",            "JIT %sabled.\n",
1649            vm->name,vm->boot_cpu->pc,vm->jit_use ? "en":"dis");            vm->name,cpu->pc,vm->jit_use ? "en":"dis");
1650    
1651     vm_log(vm,"C7200_BOOT",     vm_log(vm,"C7200_BOOT",
1652            "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",
1653            vm->boot_cpu->pc,vm->boot_cpu->idle_pc,vm->jit_use ? "on":"off");            cpu->pc,cpu->idle_pc,vm->jit_use ? "on":"off");
1654        
1655     /* Start main CPU */     /* Start main CPU */
1656     if (vm->ghost_status != VM_GHOST_RAM_GENERATE) {     if (vm->ghost_status != VM_GHOST_RAM_GENERATE) {
# Line 2051  int c7200_boot_ios(c7200_t *router) Line 1662  int c7200_boot_ios(c7200_t *router)
1662     return(0);     return(0);
1663  }  }
1664    
1665  /* Initialize a Cisco 7200 instance */  /* Boot the IOS image (PowerPC) */
1666  int c7200_init_instance(c7200_t *router)  static int c7200p_boot_ios(c7200_t *router)
1667    {  
1668       vm_instance_t *vm = router->vm;
1669       cpu_ppc_t *cpu;
1670    
1671       if (!vm->boot_cpu)
1672          return(-1);
1673    
1674       /* Suspend CPU activity since we will restart directly from ROM */
1675       vm_suspend(vm);
1676    
1677       /* Check that CPU activity is really suspended */
1678       if (cpu_group_sync_state(vm->cpu_group) == -1) {
1679          vm_error(vm,"unable to sync with system CPUs.\n");
1680          return(-1);
1681       }
1682    
1683       /* Reset the boot CPU */
1684       cpu = CPU_PPC32(vm->boot_cpu);
1685       ppc32_reset(cpu);
1686    
1687       /* Load IOS image */
1688       if (ppc32_load_elf_image(cpu,vm->ios_image,
1689                                (vm->ghost_status == VM_GHOST_RAM_USE),
1690                                &vm->ios_entry_point) < 0)
1691       {
1692          vm_error(vm,"failed to load Cisco IOS image '%s'.\n",vm->ios_image);
1693          return(-1);
1694       }
1695    
1696       /* Launch the simulation */
1697       printf("\nC7200P '%s': starting simulation (CPU0 IA=0x%8.8x), "
1698              "JIT %sabled.\n",
1699              vm->name,cpu->ia,vm->jit_use ? "en":"dis");
1700    
1701       vm_log(vm,"C7200P_BOOT",
1702              "starting instance (CPU0 IA=0x%8.8x,idle_pc=0x%8.8x,JIT %s)\n",
1703              cpu->ia,cpu->idle_pc,vm->jit_use ? "on":"off");
1704      
1705       /* Start main CPU */
1706       if (vm->ghost_status != VM_GHOST_RAM_GENERATE) {
1707          vm->status = VM_STATUS_RUNNING;
1708          cpu_start(vm->boot_cpu);
1709       } else {
1710          vm->status = VM_STATUS_SHUTDOWN;
1711       }
1712       return(0);
1713    }
1714    
1715    /* Set an IRQ */
1716    static void c7200m_set_irq(vm_instance_t *vm,u_int irq)
1717    {
1718       c7200_t *router = VM_C7200(vm);
1719       cpu_mips_t *cpu0 = CPU_MIPS64(vm->boot_cpu);
1720       u_int slot,port;
1721    
1722       switch(irq) {
1723          case 0 ... 7:
1724             mips64_set_irq(cpu0,irq);
1725    
1726             if (cpu0->irq_idle_preempt[irq])
1727                cpu_idle_break_wait(cpu0->gen);
1728             break;
1729    
1730          case C7200_NETIO_IRQ_BASE ... C7200_NETIO_IRQ_END:
1731             c7200_net_irq_get_slot_port(irq,&slot,&port);
1732             dev_c7200_mpfpga_net_set_irq(router->mpfpga_data,slot,port);
1733             break;
1734       }
1735    }
1736    
1737    /* Clear an IRQ */
1738    static void c7200m_clear_irq(vm_instance_t *vm,u_int irq)
1739    {
1740       c7200_t *router = VM_C7200(vm);
1741       cpu_mips_t *cpu0 = CPU_MIPS64(vm->boot_cpu);
1742       u_int slot,port;
1743    
1744       switch(irq) {
1745          case 0 ... 7:
1746             mips64_clear_irq(cpu0,irq);
1747             break;
1748    
1749          case C7200_NETIO_IRQ_BASE ... C7200_NETIO_IRQ_END:
1750             c7200_net_irq_get_slot_port(irq,&slot,&port);
1751             dev_c7200_mpfpga_net_clear_irq(router->mpfpga_data,slot,port);
1752             break;
1753       }
1754    }
1755    
1756    /* Initialize a Cisco 7200 instance (MIPS) */
1757    static int c7200m_init_instance(c7200_t *router)
1758  {  {
1759     vm_instance_t *vm = router->vm;     vm_instance_t *vm = router->vm;
1760     m_uint32_t rom_entry_point;     m_uint32_t rom_entry_point;
1761     cpu_mips_t *cpu0;     cpu_mips_t *cpu0;
1762    
1763     /* Initialize the C7200 platform */     /* Initialize the C7200 platform */
1764     if (c7200_init_platform(router) == -1) {     if (c7200m_init_platform(router) == -1) {
1765        vm_error(vm,"unable to initialize the platform hardware.\n");        vm_error(vm,"unable to initialize the platform hardware.\n");
1766        return(-1);        return(-1);
1767     }     }
1768    
1769       /* IRQ routing */
1770       vm->set_irq = c7200m_set_irq;
1771       vm->clear_irq = c7200m_clear_irq;
1772    
1773     /* Load IOS configuration file */     /* Load IOS configuration file */
1774     if (vm->ios_config != NULL) {     if (vm->ios_config != NULL) {
1775        vm_nvram_push_config(vm,vm->ios_config);        vm_nvram_push_config(vm,vm->ios_config);
# Line 2071  int c7200_init_instance(c7200_t *router) Line 1777  int c7200_init_instance(c7200_t *router)
1777     }     }
1778    
1779     /* Load ROM (ELF image or embedded) */     /* Load ROM (ELF image or embedded) */
1780     cpu0 = vm->boot_cpu;     cpu0 = CPU_MIPS64(vm->boot_cpu);
1781     rom_entry_point = (m_uint32_t)MIPS_ROM_PC;     rom_entry_point = (m_uint32_t)MIPS_ROM_PC;
1782        
1783     if ((vm->rom_filename != NULL) &&     if ((vm->rom_filename != NULL) &&
# Line 2088  int c7200_init_instance(c7200_t *router) Line 1794  int c7200_init_instance(c7200_t *router)
1794        cpu0->sym_trace = 1;        cpu0->sym_trace = 1;
1795     }     }
1796    
1797     return(c7200_boot_ios(router));     return(c7200m_boot_ios(router));
1798  }  }
1799    
1800  /* Stop a Cisco 7200 instance */  /* Set an IRQ */
1801  int c7200_stop_instance(c7200_t *router)  static void c7200p_set_irq(vm_instance_t *vm,u_int irq)
1802    {
1803       c7200_t *router = VM_C7200(vm);
1804       cpu_ppc_t *cpu0 = CPU_PPC32(vm->boot_cpu);
1805       u_int slot,port;
1806    
1807       switch(irq) {
1808          case C7200_VTIMER_IRQ:
1809             ppc32_trigger_timer_irq(cpu0);
1810             break;
1811          case C7200_DUART_IRQ:
1812             dev_mv64460_set_gpp_intr(router->mv64460_sysctr,10);
1813             break;
1814          case C7200_NETIO_IRQ:
1815             dev_mv64460_set_gpp_intr(router->mv64460_sysctr,24);
1816             break;
1817          case C7200_PA_MGMT_IRQ:
1818             dev_mv64460_set_gpp_intr(router->mv64460_sysctr,20);
1819             break;
1820          case C7200_OIR_IRQ:
1821             dev_mv64460_set_gpp_intr(router->mv64460_sysctr,0);
1822             break;
1823          case C7200_NETIO_IRQ_BASE ... C7200_NETIO_IRQ_END:
1824             c7200_net_irq_get_slot_port(irq,&slot,&port);
1825             dev_c7200_mpfpga_net_set_irq(router->mpfpga_data,slot,port);
1826             break;
1827       }
1828    
1829       if (vm->irq_idle_preempt[irq])
1830          cpu_idle_break_wait(cpu0->gen);
1831    }
1832    
1833    /* Clear an IRQ */
1834    static void c7200p_clear_irq(vm_instance_t *vm,u_int irq)
1835    {
1836       c7200_t *router = VM_C7200(vm);
1837       u_int slot,port;
1838    
1839       switch(irq) {
1840          case C7200_DUART_IRQ:
1841             dev_mv64460_clear_gpp_intr(router->mv64460_sysctr,10);
1842             break;
1843          case C7200_NETIO_IRQ:
1844             dev_mv64460_clear_gpp_intr(router->mv64460_sysctr,24);
1845             break;
1846          case C7200_PA_MGMT_IRQ:
1847             dev_mv64460_clear_gpp_intr(router->mv64460_sysctr,20);
1848             break;
1849          case C7200_OIR_IRQ:
1850             dev_mv64460_clear_gpp_intr(router->mv64460_sysctr,0);
1851             break;
1852          case C7200_NETIO_IRQ_BASE ... C7200_NETIO_IRQ_END:
1853             c7200_net_irq_get_slot_port(irq,&slot,&port);
1854             dev_c7200_mpfpga_net_clear_irq(router->mpfpga_data,slot,port);
1855             break;
1856       }
1857    }
1858    
1859    /* Initialize a Cisco 7200 instance (PowerPC) */
1860    static int c7200p_init_instance(c7200_t *router)
1861  {  {
1862     vm_instance_t *vm = router->vm;     vm_instance_t *vm = router->vm;
1863       m_uint32_t rom_entry_point;
1864       cpu_ppc_t *cpu0;
1865       int i;
1866    
1867       /* Initialize the C7200 platform */
1868       if (c7200p_init_platform(router) == -1) {
1869          vm_error(vm,"unable to initialize the platform hardware.\n");
1870          return(-1);
1871       }
1872    
1873       /* IRQ routing */
1874       vm->set_irq = c7200p_set_irq;
1875       vm->clear_irq = c7200p_clear_irq;
1876    
1877       /* Load ROM (ELF image or embedded) */
1878       cpu0 = CPU_PPC32(vm->boot_cpu);
1879       rom_entry_point = (m_uint32_t)PPC32_ROM_START;
1880    
1881       if ((vm->rom_filename != NULL) &&
1882           (ppc32_load_elf_image(cpu0,vm->rom_filename,0,&rom_entry_point) < 0))
1883       {
1884          vm_error(vm,"unable to load alternate ROM '%s', "
1885                   "fallback to embedded ROM.\n\n",vm->rom_filename);
1886          vm->rom_filename = NULL;
1887       }
1888    
1889       /* Initialize the MMU (TEST) */
1890       for(i=0;i<PPC32_SR_NR;i++)
1891          cpu0->sr[i] = i << 16;
1892    
1893       ppc32_set_sdr1(cpu0,((vm->ram_size - 2) * 1048576) + 0x1F);
1894       ppc32_init_page_table(cpu0);
1895       ppc32_map_zone(cpu0,cpu0->sr[C7200_G2_BOOTFLASH_ADDR >> 28],
1896                      C7200_G2_BOOTFLASH_ADDR,C7200_G2_BOOTFLASH_ADDR,
1897                      64*1048576,0,0x02);
1898    
1899       ppc32_map_zone(cpu0,cpu0->sr[0xD8000000 >> 28],
1900                      0xD8000000,0xD8000000,0x400000,0,0x02);
1901       ppc32_map_zone(cpu0,cpu0->sr[0xDC000000 >> 28],
1902                      0xDC000000,0xDC000000,0x400000,0,0x02);
1903    
1904       /* INST */
1905       cpu0->bat[PPC32_IBAT_IDX][0].reg[0] = 0x00003FFE;
1906       cpu0->bat[PPC32_IBAT_IDX][0].reg[1] = 0x00000003;
1907    
1908       cpu0->bat[PPC32_IBAT_IDX][3].reg[0] = 0xF0001FFE;
1909       cpu0->bat[PPC32_IBAT_IDX][3].reg[1] = 0xF0000003;
1910    
1911       /* DATA */
1912       cpu0->bat[PPC32_DBAT_IDX][0].reg[0] = 0x00003FFE;
1913       cpu0->bat[PPC32_DBAT_IDX][0].reg[1] = 0x00000003;
1914    
1915       cpu0->bat[PPC32_DBAT_IDX][3].reg[0] = 0xF0001FFE;
1916       cpu0->bat[PPC32_DBAT_IDX][3].reg[1] = 0xF0000003;
1917    
1918    
1919       return(c7200p_boot_ios(router));
1920    }
1921    
1922    /* Initialize a Cisco 7200 instance */
1923    static int c7200_init_instance(vm_instance_t *vm)
1924    {
1925       c7200_t *router = VM_C7200(vm);
1926    
1927       switch(router->npe_driver->npe_family) {
1928          case C7200_NPE_FAMILY_MIPS:
1929             return(c7200m_init_instance(router));
1930    
1931          case C7200_NPE_FAMILY_PPC:
1932             return(c7200p_init_instance(router));
1933            
1934          default:
1935             vm_error(router->vm,"unsupported NPE family %d",
1936                      router->npe_driver->npe_family);
1937             return(-1);
1938       }
1939    }
1940    
1941    /* Stop a Cisco 7200 instance */
1942    static int c7200_stop_instance(vm_instance_t *vm)
1943    {
1944     printf("\nC7200 '%s': stopping simulation.\n",vm->name);     printf("\nC7200 '%s': stopping simulation.\n",vm->name);
1945     vm_log(vm,"C7200_STOP","stopping simulation.\n");     vm_log(vm,"C7200_STOP","stopping simulation.\n");
1946    
# Line 2110  int c7200_stop_instance(c7200_t *router) Line 1955  int c7200_stop_instance(c7200_t *router)
1955     }     }
1956    
1957     /* Free resources that were used during execution to emulate hardware */     /* Free resources that were used during execution to emulate hardware */
1958     c7200_free_hw_ressources(router);     c7200_free_hw_ressources(VM_C7200(vm));
1959     vm_hardware_shutdown(vm);     vm_hardware_shutdown(vm);
1960     return(0);     return(0);
1961  }  }
# Line 2149  int c7200_pa_init_online(c7200_t *router Line 1994  int c7200_pa_init_online(c7200_t *router
1994     }     }
1995    
1996     /* Add the new hardware elements */     /* Add the new hardware elements */
1997     if (c7200_pa_init(router,pa_bay) == -1)     if (vm_slot_init(vm,pa_bay) == -1)
1998        return(-1);        return(-1);
1999    
2000     /* Resume normal operations */     /* Resume normal operations */
# Line 2164  int c7200_pa_init_online(c7200_t *router Line 2009  int c7200_pa_init_online(c7200_t *router
2009  int c7200_pa_stop_online(c7200_t *router,u_int pa_bay)  int c7200_pa_stop_online(c7200_t *router,u_int pa_bay)
2010  {    {  
2011     vm_instance_t *vm = router->vm;     vm_instance_t *vm = router->vm;
    struct c7200_pa_bay *bay;  
2012    
2013     if (!pa_bay) {     if (!pa_bay) {
2014        vm_error(vm,"OIR not supported on slot 0.\n");        vm_error(vm,"OIR not supported on slot 0.\n");
2015        return(-1);        return(-1);
2016     }     }
2017    
    if (!(bay = c7200_pa_get_info(router,pa_bay)))  
       return(-1);  
   
2018     /* The PA driver must be initialized */     /* The PA driver must be initialized */
2019     if (!bay->dev_type || !bay->pa_driver) {     if (!vm_slot_get_card_ptr(vm,pa_bay)) {
2020        vm_error(vm,"trying to shut down empty slot %u.\n",pa_bay);        vm_error(vm,"trying to shut down empty slot %u.\n",pa_bay);
2021        return(-1);        return(-1);
2022     }     }
2023    
2024     /* Disable all NIOs to stop traffic forwarding */     /* Disable all NIOs to stop traffic forwarding */
2025     c7200_pa_disable_all_nio(router,pa_bay);     vm_slot_disable_all_nio(vm,pa_bay);
2026    
2027     /* We can safely trigger the OIR event */     /* We can safely trigger the OIR event */
2028     c7200_trigger_oir_event(router,1 << pa_bay);     c7200_trigger_oir_event(router,1 << pa_bay);
# Line 2193  int c7200_pa_stop_online(c7200_t *router Line 2034  int c7200_pa_stop_online(c7200_t *router
2034     vm_suspend(vm);     vm_suspend(vm);
2035    
2036     /* Device removal */     /* Device removal */
2037     c7200_pa_shutdown(router,pa_bay);     vm_slot_shutdown(vm,pa_bay);
2038    
2039     /* Resume normal operations */     /* Resume normal operations */
2040     vm_resume(vm);     vm_resume(vm);
2041     return(0);     return(0);
2042  }  }
2043    
2044    /* Get MAC address MSB */
2045    static u_int c7200_get_mac_addr_msb(void)
2046    {
2047       return(0xCA);
2048    }
2049    
2050    /* Parse specific options for the Cisco 7200 platform */
2051    static int c7200_cli_parse_options(vm_instance_t *vm,int option)
2052    {
2053       c7200_t *router = VM_C7200(vm);
2054    
2055       switch(option) {
2056          /* NPE type */
2057          case 't':
2058             c7200_npe_set_type(router,optarg);
2059             break;
2060    
2061          /* Midplane type */
2062          case 'M':
2063             c7200_midplane_set_type(router,optarg);
2064             break;
2065    
2066          /* Set the base MAC address */
2067          case 'm':
2068             if (!c7200_midplane_set_mac_addr(router,optarg))
2069                printf("MAC address set to '%s'.\n",optarg);
2070             break;
2071    
2072          /* Unknown option */
2073          default:
2074             return(-1);
2075       }
2076    
2077       return(0);
2078    }
2079    
2080    /* Show specific CLI options */
2081    static void c7200_cli_show_options(vm_instance_t *vm)
2082    {
2083       printf("  -t <npe_type>      : Select NPE type (default: \"%s\")\n"
2084              "  -M <midplane>      : Select Midplane (\"std\" or \"vxr\")\n"
2085              "  -p <pa_desc>       : Define a Port Adapter\n"
2086              "  -s <pa_nio>        : Bind a Network IO interface to a "
2087              "Port Adapter\n",
2088              C7200_DEFAULT_NPE_TYPE);
2089    }
2090    
2091    /* Platform definition */
2092    static vm_platform_t c7200_platform = {
2093       "c7200", "C7200", "7200",
2094       c7200_create_instance,
2095       c7200_delete_instance,
2096       c7200_init_instance,
2097       c7200_stop_instance,
2098       c7200_nvram_extract_config,
2099       c7200_nvram_push_config,
2100       c7200_get_mac_addr_msb,
2101       c7200_save_config,
2102       c7200_cli_parse_options,
2103       c7200_cli_show_options,
2104       c7200_npe_show_drivers,
2105    };
2106    
2107    /* Register the c7200 platform */
2108    int c7200_platform_register(void)
2109    {
2110       if (vm_platform_register(&c7200_platform) == -1)
2111          return(-1);
2112    
2113       return(hypervisor_c7200_init(&c7200_platform));
2114    }

Legend:
Removed from v.6  
changed lines
  Added in v.11

  ViewVC Help
Powered by ViewVC 1.1.26