/[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-RC2/dev_c3600.c revision 3 by dpavlin, Sat Oct 6 16:05:34 2007 UTC upstream/dynamips-0.2.7-RC1/dev_c3600.c revision 7 by dpavlin, Sat Oct 6 16:23:47 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_bay.h"  #include "dev_c3600_bay.h"
25  #include "dev_vtty.h"  #include "dev_vtty.h"
# Line 114  static struct c3600_nm_driver *nm_driver Line 116  static struct c3600_nm_driver *nm_driver
116    
117  /* Directly extract the configuration from the NVRAM device */  /* Directly extract the configuration from the NVRAM device */
118  ssize_t c3600_nvram_extract_config(vm_instance_t *vm,char **buffer)  ssize_t c3600_nvram_extract_config(vm_instance_t *vm,char **buffer)
119  {    {
120     struct vdevice *nvram_dev;     u_char *base_ptr,*ios_ptr,*cfg_ptr,*end_ptr;
121     m_uint32_t start,nvlen;     m_uint32_t start,nvlen;
122     m_uint16_t magic1,magic2;     m_uint16_t magic1,magic2;
123     m_uint64_t addr;     struct vdevice *nvram_dev;
124       off_t nvram_size;
125       int fd;
126    
127       if ((nvram_dev = dev_get_by_name(vm,"nvram")))
128          dev_sync(nvram_dev);
129    
130       fd = vm_mmap_open_file(vm,"nvram",&base_ptr,&nvram_size);
131    
132       if (fd == -1)
133          return(-1);
134    
135     if (!(nvram_dev = dev_get_by_name(vm,"nvram")))     ios_ptr = base_ptr + vm->nvram_rom_space;
136       end_ptr = base_ptr + nvram_size;
137    
138       if ((ios_ptr + 0x30) >= end_ptr) {
139          vm_error(vm,"NVRAM file too small\n");
140        return(-1);        return(-1);
141       }
142    
143     addr = nvram_dev->phys_addr + vm->nvram_rom_space;     magic1  = ntohs(*PTR_ADJUST(m_uint16_t *,ios_ptr,0x06));
144     magic1 = physmem_copy_u16_from_vm(vm,addr+0x06);     magic2  = ntohs(*PTR_ADJUST(m_uint16_t *,ios_ptr,0x08));
    magic2 = physmem_copy_u16_from_vm(vm,addr+0x08);  
145    
146     if ((magic1 != 0xF0A5) || (magic2 != 0xABCD)) {     if ((magic1 != 0xF0A5) || (magic2 != 0xABCD)) {
147        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 133  ssize_t c3600_nvram_extract_config(vm_in Line 149  ssize_t c3600_nvram_extract_config(vm_in
149        return(-1);        return(-1);
150     }     }
151    
152     start = physmem_copy_u32_from_vm(vm,addr+0x10) + 1;     start = ntohl(*PTR_ADJUST(m_uint32_t *,ios_ptr,0x10)) + 1;
153     nvlen = physmem_copy_u32_from_vm(vm,addr+0x18);     nvlen = ntohl(*PTR_ADJUST(m_uint32_t *,ios_ptr,0x18));
154    
155     if (nvlen <= 10) {     if (!(*buffer = malloc(nvlen+1))) {
156        vm_error(vm,"invalid configuration size (0x%x)\n",nvlen);        vm_error(vm,"unable to allocate config buffer (%u bytes)\n",nvlen);
157        return(-1);        return(-1);
158     }     }
159    
160     if (!(*buffer = malloc(nvlen+1))) {     cfg_ptr = ios_ptr + start + 0x08;
161        vm_error(vm,"unable to allocate config buffer (%u bytes)\n",nvlen);  
162       if ((cfg_ptr + nvlen) > end_ptr) {
163          vm_error(vm,"NVRAM file too small\n");
164        return(-1);        return(-1);
165     }     }
166    
167     physmem_copy_from_vm(vm,*buffer,addr+start+0x08,nvlen-1);     memcpy(*buffer,cfg_ptr,nvlen-1);
168     (*buffer)[nvlen-1] = 0;     (*buffer)[nvlen-1] = 0;
169     return(nvlen-1);     return(nvlen-1);
170  }  }
# Line 154  ssize_t c3600_nvram_extract_config(vm_in Line 172  ssize_t c3600_nvram_extract_config(vm_in
172  /* Directly push the IOS configuration to the NVRAM device */  /* Directly push the IOS configuration to the NVRAM device */
173  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)
174  {  {
175     struct vdevice *nvram_dev;     u_char *base_ptr,*ios_ptr,*cfg_ptr;
176     m_uint64_t addr,cfg_addr;     m_uint32_t cfg_offset,cklen,tmp;
    m_uint32_t tmp,cfg_offset;  
    m_uint32_t cklen;  
177     m_uint16_t cksum;     m_uint16_t cksum;
178       int fd;
179    
180     if (!(nvram_dev = dev_get_by_name(vm,"nvram")))     fd = vm_mmap_create_file(vm,"nvram",vm->nvram_size*1024,&base_ptr);
181    
182       if (fd == -1)
183        return(-1);        return(-1);
184    
    addr = nvram_dev->phys_addr + vm->nvram_rom_space;  
185     cfg_offset = 0x2c;     cfg_offset = 0x2c;
186     cfg_addr   = addr + cfg_offset;     ios_ptr = base_ptr + vm->nvram_rom_space;
187       cfg_ptr = ios_ptr  + cfg_offset;
188    
189     /* Write IOS tag, uncompressed config... */     /* Write IOS tag, uncompressed config... */
190     physmem_copy_u16_to_vm(vm,addr+0x06,0xF0A5);     *PTR_ADJUST(m_uint16_t *,ios_ptr,0x06) = htons(0xF0A5);
191     physmem_copy_u16_to_vm(vm,addr+0x08,0xABCD);      /* Magic number */     *PTR_ADJUST(m_uint16_t *,ios_ptr,0x08) = htons(0xABCD);
192     physmem_copy_u16_to_vm(vm,addr+0x0a,0x0001);      /* ??? */     *PTR_ADJUST(m_uint16_t *,ios_ptr,0x0a) = htons(0x0001);
193     physmem_copy_u16_to_vm(vm,addr+0x0c,0x0000);      /* Checksum */     *PTR_ADJUST(m_uint16_t *,ios_ptr,0x0c) = htons(0x0000);
194     physmem_copy_u16_to_vm(vm,addr+0x0e,0x0c04);      /* IOS version */     *PTR_ADJUST(m_uint16_t *,ios_ptr,0x0e) = htons(0x0c04);
195    
196     /* Store file contents to NVRAM */     /* Store file contents to NVRAM */
197     physmem_copy_to_vm(vm,buffer,cfg_addr,len);     memcpy(cfg_ptr,buffer,len);
198    
199     /* Write config addresses + size */     /* Write config addresses + size */
200     tmp = cfg_addr - addr - 0x08;     tmp = cfg_offset - 0x08;
201    
202     physmem_copy_u32_to_vm(vm,addr+0x10,tmp);     *PTR_ADJUST(m_uint32_t *,ios_ptr,0x10) = htonl(tmp);
203     physmem_copy_u32_to_vm(vm,addr+0x14,tmp + len);     *PTR_ADJUST(m_uint32_t *,ios_ptr,0x14) = htonl(tmp + len);
204     physmem_copy_u32_to_vm(vm,addr+0x18,len);     *PTR_ADJUST(m_uint32_t *,ios_ptr,0x18) = htonl(len);
205    
206     /* Compute the checksum */     /* Compute the checksum */
207     cklen = nvram_dev->phys_len - (vm->nvram_rom_space + 0x08);     cklen = (vm->nvram_size*1024) - (vm->nvram_rom_space + 0x08);
208     cksum = nvram_cksum(vm,addr+0x08,cklen);     cksum = nvram_cksum((m_uint16_t *)(ios_ptr+0x08),cklen);
209     physmem_copy_u16_to_vm(vm,addr+0x0c,cksum);     *PTR_ADJUST(m_uint16_t *,ios_ptr,0x0c) = htons(cksum);
210    
211       vm_mmap_close_file(fd,base_ptr,vm->nvram_size*1024);
212     return(0);     return(0);
213  }  }
214    
# Line 1088  static int c3620_init(c3600_t *router) Line 1109  static int c3620_init(c3600_t *router)
1109     int i;     int i;
1110    
1111     /* Set the processor type: R4700 */     /* Set the processor type: R4700 */
1112     mips64_set_prid(vm->boot_cpu,MIPS_PRID_R4700);     mips64_set_prid(CPU_MIPS64(vm->boot_cpu),MIPS_PRID_R4700);
1113    
1114     /* Initialize the Galileo GT-64010 PCI controller */     /* Initialize the Galileo GT-64010 PCI controller */
1115     if (c3600_init_gt64010(router) == -1)     if (c3600_init_gt64010(router) == -1)
# Line 1110  static int c3640_init(c3600_t *router) Line 1131  static int c3640_init(c3600_t *router)
1131     int i;     int i;
1132    
1133     /* Set the processor type: R4700 */     /* Set the processor type: R4700 */
1134     mips64_set_prid(vm->boot_cpu,MIPS_PRID_R4700);     mips64_set_prid(CPU_MIPS64(vm->boot_cpu),MIPS_PRID_R4700);
1135    
1136     /* Initialize the Galileo GT-64010 PCI controller */     /* Initialize the Galileo GT-64010 PCI controller */
1137     if (c3600_init_gt64010(router) == -1)     if (c3600_init_gt64010(router) == -1)
# Line 1145  static int c3660_init(c3600_t *router) Line 1166  static int c3660_init(c3600_t *router)
1166     int i;     int i;
1167    
1168     /* Set the processor type: R5271 */     /* Set the processor type: R5271 */
1169     mips64_set_prid(vm->boot_cpu,MIPS_PRID_R527x);     mips64_set_prid(CPU_MIPS64(vm->boot_cpu),MIPS_PRID_R527x);
1170    
1171     /* Initialize the Galileo GT-64120 PCI controller */     /* Initialize the Galileo GT-64120 PCI controller */
1172     if (c3600_init_gt64120(router) == -1)     if (c3600_init_gt64120(router) == -1)
# Line 1212  void c3600_init_defaults(c3600_t *router Line 1233  void c3600_init_defaults(c3600_t *router
1233    
1234     /* Generate a chassis MAC address based on the instance ID */     /* Generate a chassis MAC address based on the instance ID */
1235     m = &router->mac_addr;     m = &router->mac_addr;
1236     m->eth_addr_byte[0] = 0xCC;     m->eth_addr_byte[0] = vm_get_mac_addr_msb(vm);
1237     m->eth_addr_byte[1] = vm->instance_id & 0xFF;     m->eth_addr_byte[1] = vm->instance_id & 0xFF;
1238     m->eth_addr_byte[2] = pid >> 8;     m->eth_addr_byte[2] = pid >> 8;
1239     m->eth_addr_byte[3] = pid & 0xFF;     m->eth_addr_byte[3] = pid & 0xFF;
# Line 1226  void c3600_init_defaults(c3600_t *router Line 1247  void c3600_init_defaults(c3600_t *router
1247     vm->ram_size          = C3600_DEFAULT_RAM_SIZE;     vm->ram_size          = C3600_DEFAULT_RAM_SIZE;
1248     vm->rom_size          = C3600_DEFAULT_ROM_SIZE;     vm->rom_size          = C3600_DEFAULT_ROM_SIZE;
1249     vm->nvram_size        = C3600_DEFAULT_NVRAM_SIZE;     vm->nvram_size        = C3600_DEFAULT_NVRAM_SIZE;
1250     vm->conf_reg          = C3600_DEFAULT_CONF_REG;     vm->conf_reg_setup    = C3600_DEFAULT_CONF_REG;
1251     vm->clock_divisor     = C3600_DEFAULT_CLOCK_DIV;     vm->clock_divisor     = C3600_DEFAULT_CLOCK_DIV;
1252     vm->nvram_rom_space   = C3600_NVRAM_ROM_RES_SIZE;     vm->nvram_rom_space   = C3600_NVRAM_ROM_RES_SIZE;
1253     router->nm_iomem_size = C3600_DEFAULT_IOMEM_SIZE;     router->nm_iomem_size = C3600_DEFAULT_IOMEM_SIZE;
1254    
1255     vm->pcmcia_disk_size[0] = C3600_DEFAULT_DISK0_SIZE;     vm->pcmcia_disk_size[0] = C3600_DEFAULT_DISK0_SIZE;
1256     vm->pcmcia_disk_size[1] = C3600_DEFAULT_DISK1_SIZE;     vm->pcmcia_disk_size[1] = C3600_DEFAULT_DISK1_SIZE;
1257    
1258       /* Enable NVRAM operations to load/store configs */
1259       vm->nvram_extract_config = c3600_nvram_extract_config;
1260       vm->nvram_push_config = c3600_nvram_push_config;
1261  }  }
1262    
1263  /* Initialize the C3600 Platform */  /* Initialize the C3600 Platform */
# Line 1241  int c3600_init_platform(c3600_t *router) Line 1266  int c3600_init_platform(c3600_t *router)
1266     vm_instance_t *vm = router->vm;     vm_instance_t *vm = router->vm;
1267     struct c3600_nm_bay *nm_bay;     struct c3600_nm_bay *nm_bay;
1268     cpu_mips_t *cpu;     cpu_mips_t *cpu;
1269       cpu_gen_t *gen;
1270     int i;     int i;
1271    
1272     /* Copy config register setup into "active" config register */     /* Copy config register setup into "active" config register */
# Line 1253  int c3600_init_platform(c3600_t *router) Line 1279  int c3600_init_platform(c3600_t *router)
1279     vm->cpu_group = cpu_group_create("System CPU");     vm->cpu_group = cpu_group_create("System CPU");
1280    
1281     /* Initialize the virtual MIPS processor */     /* Initialize the virtual MIPS processor */
1282     if (!(cpu = cpu_create(vm,0))) {     if (!(gen = cpu_create(vm,CPU_TYPE_MIPS64,0))) {
1283        vm_error(vm,"unable to create CPU!\n");        vm_error(vm,"unable to create CPU!\n");
1284        return(-1);        return(-1);
1285     }     }
1286    
1287       cpu = CPU_MIPS64(gen);
1288    
1289     /* Add this CPU to the system CPU group */     /* Add this CPU to the system CPU group */
1290     cpu_group_add(vm->cpu_group,cpu);     cpu_group_add(vm->cpu_group,gen);
1291     vm->boot_cpu = cpu;     vm->boot_cpu = gen;
1292    
1293       /* Initialize the IRQ routing vectors */
1294       vm->set_irq = mips64_vm_set_irq;
1295       vm->clear_irq = mips64_vm_clear_irq;
1296    
1297     /* Mark the Network IO interrupt as high priority */     /* Mark the Network IO interrupt as high priority */
1298     cpu->irq_idle_preempt[C3600_NETIO_IRQ] = TRUE;     cpu->irq_idle_preempt[C3600_NETIO_IRQ] = TRUE;
1299       cpu->irq_idle_preempt[C3600_GT64K_IRQ] = TRUE;
1300     cpu->irq_idle_preempt[C3600_DUART_IRQ] = TRUE;     cpu->irq_idle_preempt[C3600_DUART_IRQ] = TRUE;
1301    
1302     /* Copy some parameters from VM to CPU (idle PC, ...) */     /* Copy some parameters from VM to CPU (idle PC, ...) */
# Line 1304  int c3600_init_platform(c3600_t *router) Line 1337  int c3600_init_platform(c3600_t *router)
1337        return(-1);        return(-1);
1338    
1339     /* Initialize RAM */     /* Initialize RAM */
1340     dev_ram_init(vm,"ram",vm->ram_mmap,0x00000000ULL,vm->ram_size*1048576);     vm_ram_init(vm,0x00000000ULL);
1341    
1342     /* Initialize ROM */     /* Initialize ROM */
1343     if (!vm->rom_filename) {     if (!vm->rom_filename) {
1344        /* use embedded ROM */        /* use embedded ROM */
1345        dev_rom_init(vm,"rom",C3600_ROM_ADDR,vm->rom_size*1048576);        dev_rom_init(vm,"rom",C3600_ROM_ADDR,vm->rom_size*1048576,
1346                       mips64_microcode,mips64_microcode_len);
1347     } else {     } else {
1348        /* use alternate ROM */        /* use alternate ROM */
1349        dev_ram_init(vm,"rom",TRUE,C3600_ROM_ADDR,vm->rom_size*1048576);        dev_ram_init(vm,"rom",TRUE,TRUE,NULL,FALSE,
1350                       C3600_ROM_ADDR,vm->rom_size*1048576);
1351     }     }
1352    
1353     /* Initialize the NS16552 DUART */     /* Initialize the NS16552 DUART */
# Line 1336  int c3600_init_platform(c3600_t *router) Line 1371  int c3600_init_platform(c3600_t *router)
1371        }        }
1372     }     }
1373    
    /* Enable NVRAM operations to load/store configs */  
    vm->nvram_extract_config = c3600_nvram_extract_config;  
    vm->nvram_push_config = c3600_nvram_push_config;  
   
1374     /* Show device list */     /* Show device list */
1375     c3600_show_hardware(router);     c3600_show_hardware(router);
1376     return(0);     return(0);
# Line 1349  int c3600_init_platform(c3600_t *router) Line 1380  int c3600_init_platform(c3600_t *router)
1380  int c3600_boot_ios(c3600_t *router)  int c3600_boot_ios(c3600_t *router)
1381  {    {  
1382     vm_instance_t *vm = router->vm;     vm_instance_t *vm = router->vm;
1383       cpu_mips_t *cpu;
1384    
1385     if (!vm->boot_cpu)     if (!vm->boot_cpu)
1386        return(-1);        return(-1);
# Line 1363  int c3600_boot_ios(c3600_t *router) Line 1395  int c3600_boot_ios(c3600_t *router)
1395     }     }
1396    
1397     /* Reset the boot CPU */     /* Reset the boot CPU */
1398     mips64_reset(vm->boot_cpu);     cpu = CPU_MIPS64(vm->boot_cpu);
1399       mips64_reset(cpu);
1400    
1401     /* Load IOS image */     /* Load IOS image */
1402     if (mips64_load_elf_image(vm->boot_cpu,vm->ios_image,     if (mips64_load_elf_image(cpu,vm->ios_image,
1403                                 (vm->ghost_status == VM_GHOST_RAM_USE),
1404                               &vm->ios_entry_point) < 0)                               &vm->ios_entry_point) < 0)
1405     {     {
1406        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 1376  int c3600_boot_ios(c3600_t *router) Line 1410  int c3600_boot_ios(c3600_t *router)
1410     /* Launch the simulation */     /* Launch the simulation */
1411     printf("\nC3600 '%s': starting simulation (CPU0 PC=0x%llx), "     printf("\nC3600 '%s': starting simulation (CPU0 PC=0x%llx), "
1412            "JIT %sabled.\n",            "JIT %sabled.\n",
1413            vm->name,vm->boot_cpu->pc,vm->jit_use ? "en":"dis");            vm->name,cpu->pc,vm->jit_use ? "en":"dis");
1414    
1415     vm_log(vm,"C3600_BOOT",     vm_log(vm,"C3600_BOOT",
1416            "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",
1417            vm->boot_cpu->pc,vm->boot_cpu->idle_pc,vm->jit_use ? "on":"off");            cpu->pc,cpu->idle_pc,vm->jit_use ? "on":"off");
1418    
1419     /* Start main CPU */     /* Start main CPU */
1420     vm->status = VM_STATUS_RUNNING;     if (vm->ghost_status != VM_GHOST_RAM_GENERATE) {
1421     cpu_start(vm->boot_cpu);        vm->status = VM_STATUS_RUNNING;
1422          cpu_start(vm->boot_cpu);
1423       } else {
1424          vm->status = VM_STATUS_SHUTDOWN;
1425       }
1426     return(0);     return(0);
1427  }  }
1428    
# Line 1413  int c3600_init_instance(c3600_t *router) Line 1451  int c3600_init_instance(c3600_t *router)
1451     }     }
1452    
1453     /* Load ROM (ELF image or embedded) */     /* Load ROM (ELF image or embedded) */
1454     cpu0 = vm->boot_cpu;     cpu0 = CPU_MIPS64(vm->boot_cpu);
1455     rom_entry_point = (m_uint32_t)MIPS_ROM_PC;     rom_entry_point = (m_uint32_t)MIPS_ROM_PC;
1456    
1457     if ((vm->rom_filename != NULL) &&     if ((vm->rom_filename != NULL) &&
1458         (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))
1459     {     {
1460        vm_error(vm,"unable to load alternate ROM '%s', "        vm_error(vm,"unable to load alternate ROM '%s', "
1461                 "fallback to embedded ROM.\n\n",vm->rom_filename);                 "fallback to embedded ROM.\n\n",vm->rom_filename);

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

  ViewVC Help
Powered by ViewVC 1.1.26