/[dynamips]/trunk/dev_c3600.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_c3600.c

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

upstream/dynamips-0.2.6-RC1/dev_c3600.c revision 2 by dpavlin, Sat Oct 6 16:03:58 2007 UTC upstream/dynamips-0.2.7-RC2/dev_c3600.c revision 8 by dpavlin, Sat Oct 6 16:24:54 2007 UTC
# 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 "dynamips.h"  #include "dynamips.h"
17  #include "memory.h"  #include "memory.h"
18  #include "device.h"  #include "device.h"
19  #include "pci_io.h"  #include "pci_io.h"
20    #include "dev_gt.h"
21  #include "cisco_eeprom.h"  #include "cisco_eeprom.h"
22    #include "dev_rom.h"
23  #include "dev_c3600.h"  #include "dev_c3600.h"
24    #include "dev_c3600_iofpga.h"
25  #include "dev_c3600_bay.h"  #include "dev_c3600_bay.h"
26  #include "dev_vtty.h"  #include "dev_vtty.h"
27  #include "registry.h"  #include "registry.h"
# Line 28  Line 31 
31  /* ======================================================================== */  /* ======================================================================== */
32    
33  /* Cisco 3620 mainboard EEPROM */  /* Cisco 3620 mainboard EEPROM */
34  static m_uint16_t eeprom_c3620_mainboard[64] = {  static m_uint16_t eeprom_c3620_mainboard_data[64] = {
35     0x0001, 0x0000, 0x0000, 0x0000, 0x0AFF, 0x7318, 0x5011, 0x0020,     0x0001, 0x0000, 0x0000, 0x0000, 0x0AFF, 0x7318, 0x5011, 0x0020,
36     0x0000, 0x0000, 0xA0FF, 0x9904, 0x19FF, 0xFFFF, 0xFFFF, 0x0002,     0x0000, 0x0000, 0xA0FF, 0x9904, 0x19FF, 0xFFFF, 0xFFFF, 0x0002,
37     0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,     0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
# Line 39  static m_uint16_t eeprom_c3620_mainboard Line 42  static m_uint16_t eeprom_c3620_mainboard
42     0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,     0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
43  };  };
44    
45    struct cisco_eeprom eeprom_c3620_mainboard = {
46       "C3620 Mainboard",
47       eeprom_c3620_mainboard_data,
48       sizeof(eeprom_c3620_mainboard_data)/2,
49    };
50    
51  /* Cisco 3640 mainboard EEPROM */  /* Cisco 3640 mainboard EEPROM */
52  static m_uint16_t eeprom_c3640_mainboard[64] = {  static m_uint16_t eeprom_c3640_mainboard_data[64] = {
53     0x0001, 0x0000, 0x0000, 0x0000, 0x0AFF, 0x7316, 0x8514, 0x0040,     0x0001, 0x0000, 0x0000, 0x0000, 0x0AFF, 0x7316, 0x8514, 0x0040,
54     0x0000, 0x0000, 0xA1FF, 0x0102, 0x22FF, 0xFFFF, 0xFFFF, 0x0002,     0x0000, 0x0000, 0xA1FF, 0x0102, 0x22FF, 0xFFFF, 0xFFFF, 0x0002,
55     0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,     0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
# Line 51  static m_uint16_t eeprom_c3640_mainboard Line 60  static m_uint16_t eeprom_c3640_mainboard
60     0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,     0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
61  };  };
62    
63    struct cisco_eeprom eeprom_c3640_mainboard = {
64       "C3640 Mainboard",
65       eeprom_c3640_mainboard_data,
66       sizeof(eeprom_c3640_mainboard_data)/2,
67    };
68    
69  /* Cisco 3660 backplane EEPROM */  /* Cisco 3660 backplane EEPROM */
70  static m_uint16_t eeprom_c3660_backplane[64] = {  static m_uint16_t eeprom_c3660_backplane_data[64] = {
71     0x04FF, 0x4000, 0xC841, 0x0100, 0xC046, 0x0320, 0x0012, 0x8402,     0x04FF, 0x4000, 0xC841, 0x0100, 0xC046, 0x0320, 0x0012, 0x8402,
72     0x4243, 0x3080, 0x0000, 0x0000, 0x0202, 0xC18B, 0x4841, 0x4430,     0x4243, 0x3080, 0x0000, 0x0000, 0x0202, 0xC18B, 0x4841, 0x4430,
73     0x3434, 0x3431, 0x3135, 0x4A03, 0x0081, 0x0000, 0x0000, 0x0400,     0x3434, 0x3431, 0x3135, 0x4A03, 0x0081, 0x0000, 0x0000, 0x0400,
# Line 63  static m_uint16_t eeprom_c3660_backplane Line 78  static m_uint16_t eeprom_c3660_backplane
78     0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,     0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
79  };  };
80    
81    struct cisco_eeprom eeprom_c3660_backplane = {
82       "C3660 Backplane",
83       eeprom_c3660_backplane_data,
84       sizeof(eeprom_c3660_backplane_data)/2,
85    };
86    
87  /* ======================================================================== */  /* ======================================================================== */
88  /* Chassis Drivers                                                          */  /* Chassis Drivers                                                          */
89  /* ======================================================================== */  /* ======================================================================== */
# Line 71  static int c3640_init(c3600_t *router); Line 92  static int c3640_init(c3600_t *router);
92  static int c3660_init(c3600_t *router);  static int c3660_init(c3600_t *router);
93    
94  static struct c3600_chassis_driver chassis_drivers[] = {  static struct c3600_chassis_driver chassis_drivers[] = {
95     { "3620"  , 3620, 1, c3620_init,     { "3620"  , 3620, 1, c3620_init, &eeprom_c3620_mainboard },
96       eeprom_c3620_mainboard, sizeof(eeprom_c3620_mainboard)/2 },     { "3640"  , 3640, 1, c3640_init, &eeprom_c3640_mainboard },
97     { "3640"  , 3640, 1, c3640_init,     { "3660"  , 3660, 1, c3660_init, &eeprom_c3660_backplane },
98       eeprom_c3640_mainboard, sizeof(eeprom_c3640_mainboard)/2 },     { NULL    , -1,   0, NULL,       NULL },
    { "3660"  , 3660, 1, c3660_init,  
      eeprom_c3660_backplane, sizeof(eeprom_c3660_backplane)/2 },  
   
    { NULL    , -1, 0, NULL },  
99  };  };
100    
101  /* ======================================================================== */  /* ======================================================================== */
# Line 100  static struct c3600_nm_driver *nm_driver Line 117  static struct c3600_nm_driver *nm_driver
117    
118  /* Directly extract the configuration from the NVRAM device */  /* Directly extract the configuration from the NVRAM device */
119  ssize_t c3600_nvram_extract_config(vm_instance_t *vm,char **buffer)  ssize_t c3600_nvram_extract_config(vm_instance_t *vm,char **buffer)
120  {    {
121       u_char *base_ptr,*ios_ptr,*cfg_ptr,*end_ptr;
122       m_uint32_t start,nvlen;
123       m_uint16_t magic1,magic2;
124     struct vdevice *nvram_dev;     struct vdevice *nvram_dev;
125     m_uint32_t start,end,clen,nvlen;     off_t nvram_size;
126     m_uint16_t magic1,magic2;     int fd;
    m_uint64_t addr;  
127    
128     if (!(nvram_dev = dev_get_by_name(vm,"nvram")))     if ((nvram_dev = dev_get_by_name(vm,"nvram")))
129          dev_sync(nvram_dev);
130    
131       fd = vm_mmap_open_file(vm,"nvram",&base_ptr,&nvram_size);
132    
133       if (fd == -1)
134        return(-1);        return(-1);
135    
136     addr = nvram_dev->phys_addr + vm->nvram_rom_space;     ios_ptr = base_ptr + vm->nvram_rom_space;
137     magic1 = physmem_copy_u16_from_vm(vm,addr+0x06);     end_ptr = base_ptr + nvram_size;
138     magic2 = physmem_copy_u16_from_vm(vm,addr+0x08);  
139       if ((ios_ptr + 0x30) >= end_ptr) {
140          vm_error(vm,"NVRAM file too small\n");
141          return(-1);
142       }
143    
144       magic1  = ntohs(*PTR_ADJUST(m_uint16_t *,ios_ptr,0x06));
145       magic2  = ntohs(*PTR_ADJUST(m_uint16_t *,ios_ptr,0x08));
146    
147     if ((magic1 != 0xF0A5) || (magic2 != 0xABCD)) {     if ((magic1 != 0xF0A5) || (magic2 != 0xABCD)) {
148        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 119  ssize_t c3600_nvram_extract_config(vm_in Line 150  ssize_t c3600_nvram_extract_config(vm_in
150        return(-1);        return(-1);
151     }     }
152    
153     start = physmem_copy_u32_from_vm(vm,addr+0x10) + 1;     start = ntohl(*PTR_ADJUST(m_uint32_t *,ios_ptr,0x10)) + 1;
154     end   = physmem_copy_u32_from_vm(vm,addr+0x14);     nvlen = ntohl(*PTR_ADJUST(m_uint32_t *,ios_ptr,0x18));
    nvlen = physmem_copy_u32_from_vm(vm,addr+0x18);  
    clen  = end - start;  
155    
156     if ((clen + 1) != nvlen) {     if (!(*buffer = malloc(nvlen+1))) {
157        vm_error(vm,"invalid configuration size (0x%x)\n",nvlen);        vm_error(vm,"unable to allocate config buffer (%u bytes)\n",nvlen);
158        return(-1);        return(-1);
159     }     }
160    
161     if (!(*buffer = malloc(clen+1))) {     cfg_ptr = ios_ptr + start + 0x08;
162        vm_error(vm,"unable to allocate config buffer (%u bytes)\n",clen);  
163       if ((cfg_ptr + nvlen) > end_ptr) {
164          vm_error(vm,"NVRAM file too small\n");
165        return(-1);        return(-1);
166     }     }
167    
168     physmem_copy_from_vm(vm,*buffer,addr+start+0x08,clen);     memcpy(*buffer,cfg_ptr,nvlen-1);
169     (*buffer)[clen] = 0;     (*buffer)[nvlen-1] = 0;
170     return(clen);     return(nvlen-1);
171  }  }
172    
173  /* Directly push the IOS configuration to the NVRAM device */  /* Directly push the IOS configuration to the NVRAM device */
174  int c3600_nvram_push_config(vm_instance_t *vm,char *buffer,size_t len)  int c3600_nvram_push_config(vm_instance_t *vm,char *buffer,size_t len)
175  {  {
176     struct vdevice *nvram_dev;     u_char *base_ptr,*ios_ptr,*cfg_ptr;
177     m_uint64_t addr,cfg_addr;     m_uint32_t cfg_offset,cklen,tmp;
    m_uint32_t tmp,cfg_offset;  
    m_uint32_t cklen;  
178     m_uint16_t cksum;     m_uint16_t cksum;
179       int fd;
180    
181       fd = vm_mmap_create_file(vm,"nvram",vm->nvram_size*1024,&base_ptr);
182    
183     if (!(nvram_dev = dev_get_by_name(vm,"nvram")))     if (fd == -1)
184        return(-1);        return(-1);
185    
    addr = nvram_dev->phys_addr + vm->nvram_rom_space;  
186     cfg_offset = 0x2c;     cfg_offset = 0x2c;
187     cfg_addr   = addr + cfg_offset;     ios_ptr = base_ptr + vm->nvram_rom_space;
188       cfg_ptr = ios_ptr  + cfg_offset;
189    
190     /* Write IOS tag, uncompressed config... */     /* Write IOS tag, uncompressed config... */
191     physmem_copy_u16_to_vm(vm,addr+0x06,0xF0A5);     *PTR_ADJUST(m_uint16_t *,ios_ptr,0x06) = htons(0xF0A5);
192     physmem_copy_u16_to_vm(vm,addr+0x08,0xABCD);      /* Magic number */     *PTR_ADJUST(m_uint16_t *,ios_ptr,0x08) = htons(0xABCD);
193     physmem_copy_u16_to_vm(vm,addr+0x0a,0x0001);      /* ??? */     *PTR_ADJUST(m_uint16_t *,ios_ptr,0x0a) = htons(0x0001);
194     physmem_copy_u16_to_vm(vm,addr+0x0c,0x0000);      /* Checksum */     *PTR_ADJUST(m_uint16_t *,ios_ptr,0x0c) = htons(0x0000);
195     physmem_copy_u16_to_vm(vm,addr+0x0e,0x0c04);      /* IOS version */     *PTR_ADJUST(m_uint16_t *,ios_ptr,0x0e) = htons(0x0c04);
196    
197     /* Store file contents to NVRAM */     /* Store file contents to NVRAM */
198     physmem_copy_to_vm(vm,buffer,cfg_addr,len);     memcpy(cfg_ptr,buffer,len);
199    
200     /* Write config addresses + size */     /* Write config addresses + size */
201     tmp = cfg_addr - addr - 0x08;     tmp = cfg_offset - 0x08;
202    
203     physmem_copy_u32_to_vm(vm,addr+0x10,tmp);     *PTR_ADJUST(m_uint32_t *,ios_ptr,0x10) = htonl(tmp);
204     physmem_copy_u32_to_vm(vm,addr+0x14,tmp + len);     *PTR_ADJUST(m_uint32_t *,ios_ptr,0x14) = htonl(tmp + len);
205     physmem_copy_u32_to_vm(vm,addr+0x18,len);     *PTR_ADJUST(m_uint32_t *,ios_ptr,0x18) = htonl(len);
206    
207     /* Compute the checksum */     /* Compute the checksum */
208     cklen = nvram_dev->phys_len - (vm->nvram_rom_space + 0x08);     cklen = (vm->nvram_size*1024) - (vm->nvram_rom_space + 0x08);
209     cksum = nvram_cksum(vm,addr+0x08,cklen);     cksum = nvram_cksum((m_uint16_t *)(ios_ptr+0x08),cklen);
210     physmem_copy_u16_to_vm(vm,addr+0x0c,cksum);     *PTR_ADJUST(m_uint16_t *,ios_ptr,0x0c) = htons(cksum);
211    
212       vm_mmap_close_file(fd,base_ptr,vm->nvram_size*1024);
213     return(0);     return(0);
214  }  }
215    
# Line 232  static int c3600_free_instance(void *dat Line 266  static int c3600_free_instance(void *dat
266        /* Shutdown all Network Modules */        /* Shutdown all Network Modules */
267        c3600_nm_shutdown_all(router);        c3600_nm_shutdown_all(router);
268    
269          /* Free mainboard EEPROM */
270          cisco_eeprom_free(&router->mb_eeprom);
271    
272        /* Free all resources used by VM */        /* Free all resources used by VM */
273        vm_free(vm);        vm_free(vm);
274    
# Line 307  void c3600_save_config_all(FILE *fd) Line 344  void c3600_save_config_all(FILE *fd)
344     registry_foreach_type(OBJ_TYPE_VM,c3600_reg_save_config,fd,NULL);     registry_foreach_type(OBJ_TYPE_VM,c3600_reg_save_config,fd,NULL);
345  }  }
346    
347    /* Get slot/port corresponding to specified network IRQ */
348    static inline void
349    c3600_net_irq_get_slot_port(u_int irq,u_int *slot,u_int *port)
350    {
351       irq -= C3600_NETIO_IRQ_BASE;
352       *port = irq & C3600_NETIO_IRQ_PORT_MASK;
353       *slot = irq >> C3600_NETIO_IRQ_PORT_BITS;
354    }
355    
356    /* Get network IRQ for specified slot/port */
357    u_int c3600_net_irq_for_slot_port(u_int slot,u_int port)
358    {
359       u_int irq;
360    
361       irq = (slot << C3600_NETIO_IRQ_PORT_BITS) + port;
362       irq += C3600_NETIO_IRQ_BASE;
363    
364       return(irq);
365    }
366    
367  /* Set NM EEPROM definition */  /* Set NM EEPROM definition */
368  int c3600_nm_set_eeprom(c3600_t *router,u_int nm_bay,  int c3600_nm_set_eeprom(c3600_t *router,u_int nm_bay,
369                          const struct c3600_eeprom *eeprom)                          const struct cisco_eeprom *eeprom)
370  {  {
371     if (nm_bay >= C3600_MAX_NM_BAYS) {     if (nm_bay >= C3600_MAX_NM_BAYS) {
372        vm_error(router->vm,"c3600_nm_set_eeprom: invalid NM Bay %u.\n",nm_bay);        vm_error(router->vm,"c3600_nm_set_eeprom: invalid NM Bay %u.\n",nm_bay);
373        return(-1);        return(-1);
374     }     }
375        
376     /* 3620/3640 */     if (cisco_eeprom_copy(&router->nm_bay[nm_bay].eeprom,eeprom) == -1) {
377     router->nm_bay[nm_bay].eeprom_data = eeprom->data;        vm_error(router->vm,"c3600_nm_set_eeprom: no memory.\n");
378     router->nm_bay[nm_bay].eeprom_data_len = eeprom->len;        return(-1);
379       }
380     /* 3660 */    
    router->c3660_nm_eeprom_def[nm_bay].data = eeprom->data;  
    router->c3660_nm_eeprom_def[nm_bay].data_len = eeprom->len;  
381     return(0);     return(0);
382  }  }
383    
# Line 334  int c3600_nm_unset_eeprom(c3600_t *route Line 389  int c3600_nm_unset_eeprom(c3600_t *route
389        return(-1);        return(-1);
390     }     }
391        
392     /* 3620/3640 */     cisco_eeprom_free(&router->nm_bay[nm_bay].eeprom);
    router->nm_bay[nm_bay].eeprom_data = NULL;  
    router->nm_bay[nm_bay].eeprom_data_len = 0;  
   
    /* 3660 */  
    router->c3660_nm_eeprom_def[nm_bay].data = NULL;  
    router->c3660_nm_eeprom_def[nm_bay].data_len = 0;  
393     return(0);     return(0);
394  }  }
395    
# Line 350  int c3600_nm_check_eeprom(c3600_t *route Line 399  int c3600_nm_check_eeprom(c3600_t *route
399     if (nm_bay >= C3600_MAX_NM_BAYS)     if (nm_bay >= C3600_MAX_NM_BAYS)
400        return(FALSE);        return(FALSE);
401    
402     return((router->nm_bay[nm_bay].eeprom_data != NULL) ? TRUE : FALSE);     return(cisco_eeprom_valid(&router->nm_bay[nm_bay].eeprom));
403  }  }
404    
405  /* Get bay info */  /* Get bay info */
# Line 671  int c3600_nm_init(c3600_t *router,u_int Line 720  int c3600_nm_init(c3600_t *router,u_int
720     snprintf(bay->dev_name,len,"%s(%u)",bay->dev_type,nm_bay);     snprintf(bay->dev_name,len,"%s(%u)",bay->dev_type,nm_bay);
721    
722     /* Initialize NM driver */     /* Initialize NM driver */
723     if (bay->nm_driver->nm_init(router,bay->dev_name,nm_bay) == 1) {     if (bay->nm_driver->nm_init(router,bay->dev_name,nm_bay) == -1) {
724        vm_error(router->vm,"unable to initialize NM %u.\n",nm_bay);        vm_error(router->vm,"unable to initialize NM %u.\n",nm_bay);
725        return(-1);        return(-1);
726     }     }
# Line 950  struct c3600_chassis_driver *c3600_chass Line 999  struct c3600_chassis_driver *c3600_chass
999  }  }
1000    
1001  /* Set the base MAC address of the chassis */  /* Set the base MAC address of the chassis */
1002  static int c3600_burn_mac_addr(m_uint16_t *data,size_t data_len,  static int c3600_burn_mac_addr(c3600_t *router,n_eth_addr_t *addr)
                                n_eth_addr_t *addr)  
1003  {  {
1004     m_uint8_t eeprom_ver;     m_uint8_t eeprom_ver;
1005     size_t offset;     size_t offset;
1006    
1007     /* Read EEPROM format version */     /* Read EEPROM format version */
1008     cisco_eeprom_get_byte(data,data_len,0,&eeprom_ver);     cisco_eeprom_get_byte(&router->mb_eeprom,0,&eeprom_ver);
1009    
1010     switch(eeprom_ver) {     switch(eeprom_ver) {
1011        case 0:        case 0:
1012           cisco_eeprom_set_region(data,data_len,2,addr->eth_addr_byte,6);           cisco_eeprom_set_region(&router->mb_eeprom,2,addr->eth_addr_byte,6);
1013           break;           break;
1014    
1015        case 4:        case 4:
1016           if (!cisco_eeprom_v4_find_field(data,data_len,0xC3,&offset)) {           if (!cisco_eeprom_v4_find_field(&router->mb_eeprom,0xC3,&offset)) {
1017              cisco_eeprom_set_region(data,data_len,offset,              cisco_eeprom_set_region(&router->mb_eeprom,offset,
1018                                      addr->eth_addr_byte,6);                                      addr->eth_addr_byte,6);
1019           }           }
1020           break;           break;
1021    
1022        default:        default:
1023           fprintf(stderr,"c3600_burn_mac_addr: unable to handle "           vm_error(router->vm,"c3600_burn_mac_addr: unable to handle "
1024                   "EEPROM version %u\n",eeprom_ver);                    "EEPROM version %u\n",eeprom_ver);
1025           return(-1);           return(-1);
1026     }     }
1027    
# Line 989  int c3600_chassis_set_mac_addr(c3600_t * Line 1037  int c3600_chassis_set_mac_addr(c3600_t *
1037     }     }
1038    
1039     /* Set the chassis base MAC address */     /* Set the chassis base MAC address */
1040     c3600_burn_mac_addr(router->mb_eeprom_data,sizeof(router->mb_eeprom_data),     c3600_burn_mac_addr(router,&router->mac_addr);
                        &router->mac_addr);  
1041     return(0);     return(0);
1042  }  }
1043    
# Line 1012  int c3600_chassis_set_type(c3600_t *rout Line 1059  int c3600_chassis_set_type(c3600_t *rout
1059     router->chassis_driver = driver;     router->chassis_driver = driver;
1060    
1061     /* Copy the mainboard EEPROM */     /* Copy the mainboard EEPROM */
1062     memcpy(router->mb_eeprom_data,driver->mb_eeprom,driver->mb_eeprom_len << 1);     if (cisco_eeprom_copy(&router->mb_eeprom,driver->eeprom) == -1) {
1063          vm_error(router->vm,"unable to set chassis EEPROM '%s'.\n",chassis_type);
1064          return(-1);
1065       }
1066    
1067     /* Set the chassis base MAC address */     /* Set the chassis base MAC address */
1068     c3600_burn_mac_addr(router->mb_eeprom_data,sizeof(router->mb_eeprom_data),     c3600_burn_mac_addr(router,&router->mac_addr);
                        &router->mac_addr);  
   
    router->mb_eeprom.data = router->mb_eeprom_data;  
    router->mb_eeprom.data_len = driver->mb_eeprom_len;  
1069     return(0);     return(0);
1070  }  }
1071    
# Line 1084  static int c3620_init(c3600_t *router) Line 1130  static int c3620_init(c3600_t *router)
1130     int i;     int i;
1131    
1132     /* Set the processor type: R4700 */     /* Set the processor type: R4700 */
1133     mips64_set_prid(vm->boot_cpu,MIPS_PRID_R4700);     mips64_set_prid(CPU_MIPS64(vm->boot_cpu),MIPS_PRID_R4700);
1134    
1135     /* Initialize the Galileo GT-64010 PCI controller */     /* Initialize the Galileo GT-64010 PCI controller */
1136     if (c3600_init_gt64010(router) == -1)     if (c3600_init_gt64010(router) == -1)
# Line 1106  static int c3640_init(c3600_t *router) Line 1152  static int c3640_init(c3600_t *router)
1152     int i;     int i;
1153    
1154     /* Set the processor type: R4700 */     /* Set the processor type: R4700 */
1155     mips64_set_prid(vm->boot_cpu,MIPS_PRID_R4700);     mips64_set_prid(CPU_MIPS64(vm->boot_cpu),MIPS_PRID_R4700);
1156    
1157     /* Initialize the Galileo GT-64010 PCI controller */     /* Initialize the Galileo GT-64010 PCI controller */
1158     if (c3600_init_gt64010(router) == -1)     if (c3600_init_gt64010(router) == -1)
# Line 1141  static int c3660_init(c3600_t *router) Line 1187  static int c3660_init(c3600_t *router)
1187     int i;     int i;
1188    
1189     /* Set the processor type: R5271 */     /* Set the processor type: R5271 */
1190     mips64_set_prid(vm->boot_cpu,MIPS_PRID_R527x);     mips64_set_prid(CPU_MIPS64(vm->boot_cpu),MIPS_PRID_R527x);
1191    
1192     /* Initialize the Galileo GT-64120 PCI controller */     /* Initialize the Galileo GT-64120 PCI controller */
1193     if (c3600_init_gt64120(router) == -1)     if (c3600_init_gt64120(router) == -1)
# Line 1208  void c3600_init_defaults(c3600_t *router Line 1254  void c3600_init_defaults(c3600_t *router
1254    
1255     /* Generate a chassis MAC address based on the instance ID */     /* Generate a chassis MAC address based on the instance ID */
1256     m = &router->mac_addr;     m = &router->mac_addr;
1257     m->eth_addr_byte[0] = 0xCC;     m->eth_addr_byte[0] = vm_get_mac_addr_msb(vm);
1258     m->eth_addr_byte[1] = vm->instance_id & 0xFF;     m->eth_addr_byte[1] = vm->instance_id & 0xFF;
1259     m->eth_addr_byte[2] = pid >> 8;     m->eth_addr_byte[2] = pid >> 8;
1260     m->eth_addr_byte[3] = pid & 0xFF;     m->eth_addr_byte[3] = pid & 0xFF;
# Line 1222  void c3600_init_defaults(c3600_t *router Line 1268  void c3600_init_defaults(c3600_t *router
1268     vm->ram_size          = C3600_DEFAULT_RAM_SIZE;     vm->ram_size          = C3600_DEFAULT_RAM_SIZE;
1269     vm->rom_size          = C3600_DEFAULT_ROM_SIZE;     vm->rom_size          = C3600_DEFAULT_ROM_SIZE;
1270     vm->nvram_size        = C3600_DEFAULT_NVRAM_SIZE;     vm->nvram_size        = C3600_DEFAULT_NVRAM_SIZE;
1271     vm->conf_reg          = C3600_DEFAULT_CONF_REG;     vm->conf_reg_setup    = C3600_DEFAULT_CONF_REG;
1272     vm->clock_divisor     = C3600_DEFAULT_CLOCK_DIV;     vm->clock_divisor     = C3600_DEFAULT_CLOCK_DIV;
1273     vm->nvram_rom_space   = C3600_NVRAM_ROM_RES_SIZE;     vm->nvram_rom_space   = C3600_NVRAM_ROM_RES_SIZE;
1274     router->nm_iomem_size = C3600_DEFAULT_IOMEM_SIZE;     router->nm_iomem_size = C3600_DEFAULT_IOMEM_SIZE;
1275    
1276     vm->pcmcia_disk_size[0] = C3600_DEFAULT_DISK0_SIZE;     vm->pcmcia_disk_size[0] = C3600_DEFAULT_DISK0_SIZE;
1277     vm->pcmcia_disk_size[1] = C3600_DEFAULT_DISK1_SIZE;     vm->pcmcia_disk_size[1] = C3600_DEFAULT_DISK1_SIZE;
1278    
1279       /* Enable NVRAM operations to load/store configs */
1280       vm->nvram_extract_config = c3600_nvram_extract_config;
1281       vm->nvram_push_config = c3600_nvram_push_config;
1282  }  }
1283    
1284  /* Initialize the C3600 Platform */  /* Initialize the C3600 Platform */
# Line 1237  int c3600_init_platform(c3600_t *router) Line 1287  int c3600_init_platform(c3600_t *router)
1287     vm_instance_t *vm = router->vm;     vm_instance_t *vm = router->vm;
1288     struct c3600_nm_bay *nm_bay;     struct c3600_nm_bay *nm_bay;
1289     cpu_mips_t *cpu;     cpu_mips_t *cpu;
1290       cpu_gen_t *gen;
1291       vm_obj_t *obj;
1292     int i;     int i;
1293    
1294     /* Copy config register setup into "active" config register */     /* Copy config register setup into "active" config register */
# Line 1249  int c3600_init_platform(c3600_t *router) Line 1301  int c3600_init_platform(c3600_t *router)
1301     vm->cpu_group = cpu_group_create("System CPU");     vm->cpu_group = cpu_group_create("System CPU");
1302    
1303     /* Initialize the virtual MIPS processor */     /* Initialize the virtual MIPS processor */
1304     if (!(cpu = cpu_create(vm,0))) {     if (!(gen = cpu_create(vm,CPU_TYPE_MIPS64,0))) {
1305        vm_error(vm,"unable to create CPU!\n");        vm_error(vm,"unable to create CPU!\n");
1306        return(-1);        return(-1);
1307     }     }
1308    
1309       cpu = CPU_MIPS64(gen);
1310    
1311     /* Add this CPU to the system CPU group */     /* Add this CPU to the system CPU group */
1312     cpu_group_add(vm->cpu_group,cpu);     cpu_group_add(vm->cpu_group,gen);
1313     vm->boot_cpu = cpu;     vm->boot_cpu = gen;
1314    
1315       /* Initialize the IRQ routing vectors */
1316       vm->set_irq = mips64_vm_set_irq;
1317       vm->clear_irq = mips64_vm_clear_irq;
1318    
1319     /* Mark the Network IO interrupt as high priority */     /* Mark the Network IO interrupt as high priority */
1320     cpu->irq_idle_preempt[C3600_NETIO_IRQ] = TRUE;     cpu->irq_idle_preempt[C3600_NETIO_IRQ] = TRUE;
1321       cpu->irq_idle_preempt[C3600_GT64K_IRQ] = TRUE;
1322     cpu->irq_idle_preempt[C3600_DUART_IRQ] = TRUE;     cpu->irq_idle_preempt[C3600_DUART_IRQ] = TRUE;
1323    
1324     /* Copy some parameters from VM to CPU (idle PC, ...) */     /* Copy some parameters from VM to CPU (idle PC, ...) */
# Line 1291  int c3600_init_platform(c3600_t *router) Line 1350  int c3600_init_platform(c3600_t *router)
1350     if (dev_c3600_iofpga_init(router,C3600_IOFPGA_ADDR,0x40000) == -1)     if (dev_c3600_iofpga_init(router,C3600_IOFPGA_ADDR,0x40000) == -1)
1351        return(-1);        return(-1);
1352    
1353       if (!(obj = vm_object_find(router->vm,"io_fpga")))
1354          return(-1);
1355    
1356       router->iofpga_data = obj->data;
1357    
1358     /* PCI IO space */     /* PCI IO space */
1359     if (!(vm->pci_io_space = pci_io_data_init(vm,C3600_PCI_IO_ADDR)))     if (!(vm->pci_io_space = pci_io_data_init(vm,C3600_PCI_IO_ADDR)))
1360        return(-1);        return(-1);
# Line 1300  int c3600_init_platform(c3600_t *router) Line 1364  int c3600_init_platform(c3600_t *router)
1364        return(-1);        return(-1);
1365    
1366     /* Initialize RAM */     /* Initialize RAM */
1367     dev_ram_init(vm,"ram",vm->ram_mmap,0x00000000ULL,vm->ram_size*1048576);     vm_ram_init(vm,0x00000000ULL);
1368    
1369     /* Initialize ROM */     /* Initialize ROM */
1370     if (!vm->rom_filename) {     if (!vm->rom_filename) {
1371        /* use embedded ROM */        /* use embedded ROM */
1372        dev_rom_init(vm,"rom",C3600_ROM_ADDR,vm->rom_size*1048576);        dev_rom_init(vm,"rom",C3600_ROM_ADDR,vm->rom_size*1048576,
1373                       mips64_microcode,mips64_microcode_len);
1374     } else {     } else {
1375        /* use alternate ROM */        /* use alternate ROM */
1376        dev_ram_init(vm,"rom",TRUE,C3600_ROM_ADDR,vm->rom_size*1048576);        dev_ram_init(vm,"rom",TRUE,TRUE,NULL,FALSE,
1377                       C3600_ROM_ADDR,vm->rom_size*1048576);
1378     }     }
1379    
1380     /* Initialize the NS16552 DUART */     /* Initialize the NS16552 DUART */
# Line 1332  int c3600_init_platform(c3600_t *router) Line 1398  int c3600_init_platform(c3600_t *router)
1398        }        }
1399     }     }
1400    
    /* Enable NVRAM operations to load/store configs */  
    vm->nvram_extract_config = c3600_nvram_extract_config;  
    vm->nvram_push_config = c3600_nvram_push_config;  
   
1401     /* Show device list */     /* Show device list */
1402     c3600_show_hardware(router);     c3600_show_hardware(router);
1403     return(0);     return(0);
# Line 1345  int c3600_init_platform(c3600_t *router) Line 1407  int c3600_init_platform(c3600_t *router)
1407  int c3600_boot_ios(c3600_t *router)  int c3600_boot_ios(c3600_t *router)
1408  {    {  
1409     vm_instance_t *vm = router->vm;     vm_instance_t *vm = router->vm;
1410       cpu_mips_t *cpu;
1411    
1412     if (!vm->boot_cpu)     if (!vm->boot_cpu)
1413        return(-1);        return(-1);
# Line 1359  int c3600_boot_ios(c3600_t *router) Line 1422  int c3600_boot_ios(c3600_t *router)
1422     }     }
1423    
1424     /* Reset the boot CPU */     /* Reset the boot CPU */
1425     mips64_reset(vm->boot_cpu);     cpu = CPU_MIPS64(vm->boot_cpu);
1426       mips64_reset(cpu);
1427    
1428     /* Load IOS image */     /* Load IOS image */
1429     if (mips64_load_elf_image(vm->boot_cpu,vm->ios_image,     if (mips64_load_elf_image(cpu,vm->ios_image,
1430                                 (vm->ghost_status == VM_GHOST_RAM_USE),
1431                               &vm->ios_entry_point) < 0)                               &vm->ios_entry_point) < 0)
1432     {     {
1433        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);
# Line 1372  int c3600_boot_ios(c3600_t *router) Line 1437  int c3600_boot_ios(c3600_t *router)
1437     /* Launch the simulation */     /* Launch the simulation */
1438     printf("\nC3600 '%s': starting simulation (CPU0 PC=0x%llx), "     printf("\nC3600 '%s': starting simulation (CPU0 PC=0x%llx), "
1439            "JIT %sabled.\n",            "JIT %sabled.\n",
1440            vm->name,vm->boot_cpu->pc,vm->jit_use ? "en":"dis");            vm->name,cpu->pc,vm->jit_use ? "en":"dis");
1441    
1442     vm_log(vm,"C3600_BOOT",     vm_log(vm,"C3600_BOOT",
1443            "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",
1444            vm->boot_cpu->pc,vm->boot_cpu->idle_pc,vm->jit_use ? "on":"off");            cpu->pc,cpu->idle_pc,vm->jit_use ? "on":"off");
1445    
1446     /* Start main CPU */     /* Start main CPU */
1447     vm->status = VM_STATUS_RUNNING;     if (vm->ghost_status != VM_GHOST_RAM_GENERATE) {
1448     cpu_start(vm->boot_cpu);        vm->status = VM_STATUS_RUNNING;
1449          cpu_start(vm->boot_cpu);
1450       } else {
1451          vm->status = VM_STATUS_SHUTDOWN;
1452       }
1453     return(0);     return(0);
1454  }  }
1455    
1456    /* Set an IRQ */
1457    static void c3600_set_irq(vm_instance_t *vm,u_int irq)
1458    {
1459       c3600_t *router = VM_C3600(vm);
1460       cpu_mips_t *cpu0 = CPU_MIPS64(vm->boot_cpu);
1461       u_int slot,port;
1462    
1463       switch(irq) {
1464          case 0 ... 7:
1465             mips64_set_irq(cpu0,irq);
1466    
1467             if (cpu0->irq_idle_preempt[irq])
1468                cpu_idle_break_wait(cpu0->gen);
1469             break;
1470    
1471          case C3600_NETIO_IRQ_BASE ... C3600_NETIO_IRQ_END:
1472             c3600_net_irq_get_slot_port(irq,&slot,&port);
1473             dev_c3600_iofpga_net_set_irq(router->iofpga_data,slot,port);
1474             break;
1475       }
1476    }
1477    
1478    /* Clear an IRQ */
1479    static void c3600_clear_irq(vm_instance_t *vm,u_int irq)
1480    {
1481       c3600_t *router = VM_C3600(vm);
1482       cpu_mips_t *cpu0 = CPU_MIPS64(vm->boot_cpu);
1483       u_int slot,port;
1484    
1485       switch(irq) {
1486          case 0 ... 7:
1487             mips64_clear_irq(cpu0,irq);
1488             break;
1489    
1490          case C3600_NETIO_IRQ_BASE ... C3600_NETIO_IRQ_END:
1491             c3600_net_irq_get_slot_port(irq,&slot,&port);
1492             dev_c3600_iofpga_net_clear_irq(router->iofpga_data,slot,port);
1493             break;
1494       }
1495    }
1496    
1497  /* Initialize a Cisco 3600 instance */  /* Initialize a Cisco 3600 instance */
1498  int c3600_init_instance(c3600_t *router)  int c3600_init_instance(c3600_t *router)
1499  {    {  
# Line 1402  int c3600_init_instance(c3600_t *router) Line 1512  int c3600_init_instance(c3600_t *router)
1512        return(-1);        return(-1);
1513     }     }
1514    
1515       /* IRQ routing */
1516       vm->set_irq = c3600_set_irq;
1517       vm->clear_irq = c3600_clear_irq;
1518    
1519     /* Load IOS configuration file */     /* Load IOS configuration file */
1520     if (vm->ios_config != NULL) {     if (vm->ios_config != NULL) {
1521        vm_nvram_push_config(vm,vm->ios_config);        vm_nvram_push_config(vm,vm->ios_config);
# Line 1409  int c3600_init_instance(c3600_t *router) Line 1523  int c3600_init_instance(c3600_t *router)
1523     }     }
1524    
1525     /* Load ROM (ELF image or embedded) */     /* Load ROM (ELF image or embedded) */
1526     cpu0 = vm->boot_cpu;     cpu0 = CPU_MIPS64(vm->boot_cpu);
1527     rom_entry_point = (m_uint32_t)MIPS_ROM_PC;     rom_entry_point = (m_uint32_t)MIPS_ROM_PC;
1528    
1529     if ((vm->rom_filename != NULL) &&     if ((vm->rom_filename != NULL) &&
1530         (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))
1531     {     {
1532        vm_error(vm,"unable to load alternate ROM '%s', "        vm_error(vm,"unable to load alternate ROM '%s', "
1533                 "fallback to embedded ROM.\n\n",vm->rom_filename);                 "fallback to embedded ROM.\n\n",vm->rom_filename);

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

  ViewVC Help
Powered by ViewVC 1.1.26