/[dynamips]/upstream/dynamips-0.2.7-RC2/dynamips.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

Annotation of /upstream/dynamips-0.2.7-RC2/dynamips.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 7 - (hide annotations)
Sat Oct 6 16:23:47 2007 UTC (16 years, 6 months ago) by dpavlin
Original Path: upstream/dynamips-0.2.7-RC1/dynamips.c
File MIME type: text/plain
File size: 35737 byte(s)
dynamips-0.2.7-RC1

1 dpavlin 1 /*
2 dpavlin 7 * Cisco router simulation platform.
3 dpavlin 1 * Copyright (c) 2005,2006 Christophe Fillot (cf@utc.fr)
4     *
5     * Many thanks to Nicolas Szalay for his patch
6     * for the command line parsing and virtual machine
7     * settings (RAM, ROM, NVRAM, ...)
8     */
9    
10     #include <stdio.h>
11     #include <stdlib.h>
12     #include <unistd.h>
13     #include <string.h>
14     #include <errno.h>
15     #include <sys/types.h>
16     #include <sys/stat.h>
17     #include <sys/mman.h>
18     #include <signal.h>
19     #include <fcntl.h>
20     #include <assert.h>
21     #include <getopt.h>
22    
23     #include "dynamips.h"
24 dpavlin 7 #include "cpu.h"
25 dpavlin 1 #include "mips64_exec.h"
26 dpavlin 7 #include "mips64_jit.h"
27     #include "ppc32_exec.h"
28     #include "ppc32_jit.h"
29 dpavlin 1 #include "dev_c7200.h"
30     #include "dev_c3600.h"
31 dpavlin 4 #include "dev_c2691.h"
32     #include "dev_c3725.h"
33     #include "dev_c3745.h"
34 dpavlin 7 #include "dev_c2600.h"
35     #include "ppc32_vmtest.h"
36 dpavlin 1 #include "dev_vtty.h"
37     #include "ptask.h"
38 dpavlin 3 #include "timer.h"
39 dpavlin 1 #include "registry.h"
40     #include "hypervisor.h"
41     #include "net_io.h"
42     #include "net_io_bridge.h"
43     #include "net_io_filter.h"
44     #include "crc.h"
45     #include "atm.h"
46     #include "frame_relay.h"
47     #include "eth_switch.h"
48     #ifdef GEN_ETH
49     #include "gen_eth.h"
50     #endif
51     #ifdef PROFILE
52     #include "profiler.h"
53     #endif
54    
55     /* Default name for logfile */
56     #define LOGFILE_DEFAULT_NAME "dynamips_log.txt"
57    
58     /* Software version */
59     const char *sw_version = DYNAMIPS_VERSION"-"JIT_ARCH;
60    
61     /* Hypervisor */
62     int hypervisor_mode = 0;
63     int hypervisor_tcp_port = 0;
64    
65     /* Log file */
66     char *log_file_name = NULL;
67     FILE *log_file = NULL;
68    
69     /* VM flags */
70     volatile int vm_save_state = 0;
71    
72     /* Generic signal handler */
73     void signal_gen_handler(int sig)
74     {
75     switch(sig) {
76     case SIGHUP:
77     /* For future use */
78     break;
79    
80     case SIGQUIT:
81     /* save VM context */
82     vm_save_state = TRUE;
83     break;
84    
85     case SIGINT:
86     /* CTRL+C has been pressed */
87     if (hypervisor_mode)
88     hypervisor_stopsig();
89     else {
90     /* In theory, this shouldn't happen thanks to VTTY settings */
91     vm_instance_t *vm;
92    
93     if ((vm = vm_acquire("default")) != NULL) {
94     /* Only forward ctrl-c if user has requested local terminal */
95     if (vm->vtty_con_type == VTTY_TYPE_TERM) {
96     vtty_store_ctrlc(vm->vtty_con);
97     } else {
98     vm_stop(vm);
99     }
100     vm_release(vm);
101     } else {
102     fprintf(stderr,"Error: Cannot acquire instance handle.\n");
103     }
104     }
105     break;
106    
107     default:
108     fprintf(stderr,"Unhandled signal %d\n",sig);
109     }
110     }
111    
112     /* Setups signals */
113     static void setup_signals(void)
114     {
115     struct sigaction act;
116    
117     memset(&act,0,sizeof(act));
118     act.sa_handler = signal_gen_handler;
119     act.sa_flags = SA_RESTART;
120     sigaction(SIGHUP,&act,NULL);
121     sigaction(SIGQUIT,&act,NULL);
122     sigaction(SIGINT,&act,NULL);
123     }
124    
125     /* Create general log file */
126     static void create_log_file(void)
127     {
128     /* Set the default value of the log file name */
129     if (!log_file_name) {
130     if (!(log_file_name = strdup(LOGFILE_DEFAULT_NAME))) {
131     fprintf(stderr,"Unable to set log file name.\n");
132     exit(EXIT_FAILURE);
133     }
134     }
135    
136     if (!(log_file = fopen(log_file_name,"w"))) {
137     fprintf(stderr,"Unable to create log file (%s).\n",strerror(errno));
138     exit(EXIT_FAILURE);
139     }
140     }
141    
142     /* Close general log file */
143     static void close_log_file(void)
144     {
145     if (log_file) fclose(log_file);
146     free(log_file_name);
147    
148     log_file = NULL;
149     log_file_name = NULL;
150     }
151    
152     /* Display the command line use */
153     static void show_usage(int argc,char *argv[],int platform)
154     {
155     u_int def_ram_size,def_rom_size,def_nvram_size;
156     u_int def_conf_reg,def_clock_div;
157     u_int def_disk0_size,def_disk1_size;
158     u_int def_nm_iomem_size = 0;
159    
160     switch(platform) {
161     case VM_TYPE_C7200:
162     def_ram_size = C7200_DEFAULT_RAM_SIZE;
163     def_rom_size = C7200_DEFAULT_ROM_SIZE;
164     def_nvram_size = C7200_DEFAULT_NVRAM_SIZE;
165     def_conf_reg = C7200_DEFAULT_CONF_REG;
166     def_clock_div = C7200_DEFAULT_CLOCK_DIV;
167     def_disk0_size = C7200_DEFAULT_DISK0_SIZE;
168     def_disk1_size = C7200_DEFAULT_DISK1_SIZE;
169     break;
170     case VM_TYPE_C3600:
171     def_ram_size = C3600_DEFAULT_RAM_SIZE;
172     def_rom_size = C3600_DEFAULT_ROM_SIZE;
173     def_nvram_size = C3600_DEFAULT_NVRAM_SIZE;
174     def_conf_reg = C3600_DEFAULT_CONF_REG;
175     def_clock_div = C3600_DEFAULT_CLOCK_DIV;
176     def_disk0_size = C3600_DEFAULT_DISK0_SIZE;
177     def_disk1_size = C3600_DEFAULT_DISK1_SIZE;
178     def_nm_iomem_size = C3600_DEFAULT_IOMEM_SIZE;
179     break;
180 dpavlin 4 case VM_TYPE_C2691:
181     def_ram_size = C2691_DEFAULT_RAM_SIZE;
182     def_rom_size = C2691_DEFAULT_ROM_SIZE;
183     def_nvram_size = C2691_DEFAULT_NVRAM_SIZE;
184     def_conf_reg = C2691_DEFAULT_CONF_REG;
185     def_clock_div = C2691_DEFAULT_CLOCK_DIV;
186     def_disk0_size = C2691_DEFAULT_DISK0_SIZE;
187     def_disk1_size = C2691_DEFAULT_DISK1_SIZE;
188     def_nm_iomem_size = C2691_DEFAULT_IOMEM_SIZE;
189     break;
190     case VM_TYPE_C3725:
191     def_ram_size = C3725_DEFAULT_RAM_SIZE;
192     def_rom_size = C3725_DEFAULT_ROM_SIZE;
193     def_nvram_size = C3725_DEFAULT_NVRAM_SIZE;
194     def_conf_reg = C3725_DEFAULT_CONF_REG;
195     def_clock_div = C3725_DEFAULT_CLOCK_DIV;
196     def_disk0_size = C3725_DEFAULT_DISK0_SIZE;
197     def_disk1_size = C3725_DEFAULT_DISK1_SIZE;
198     def_nm_iomem_size = C3725_DEFAULT_IOMEM_SIZE;
199     break;
200     case VM_TYPE_C3745:
201     def_ram_size = C3745_DEFAULT_RAM_SIZE;
202     def_rom_size = C3745_DEFAULT_ROM_SIZE;
203     def_nvram_size = C3745_DEFAULT_NVRAM_SIZE;
204     def_conf_reg = C3745_DEFAULT_CONF_REG;
205     def_clock_div = C3745_DEFAULT_CLOCK_DIV;
206     def_disk0_size = C3745_DEFAULT_DISK0_SIZE;
207     def_disk1_size = C3745_DEFAULT_DISK1_SIZE;
208     def_nm_iomem_size = C3745_DEFAULT_IOMEM_SIZE;
209     break;
210 dpavlin 7 case VM_TYPE_C2600:
211     def_ram_size = C2600_DEFAULT_RAM_SIZE;
212     def_rom_size = C2600_DEFAULT_ROM_SIZE;
213     def_nvram_size = C2600_DEFAULT_NVRAM_SIZE;
214     def_conf_reg = C2600_DEFAULT_CONF_REG;
215     def_clock_div = C2600_DEFAULT_CLOCK_DIV;
216     def_disk0_size = C2600_DEFAULT_DISK0_SIZE;
217     def_disk1_size = C2600_DEFAULT_DISK1_SIZE;
218     def_nm_iomem_size = C3745_DEFAULT_IOMEM_SIZE;
219     break;
220     case VM_TYPE_PPC32_TEST:
221     def_ram_size = PPC32_VMTEST_DEFAULT_RAM_SIZE;
222 dpavlin 1 default:
223     fprintf(stderr,"show_usage: invalid platform.\n");
224     return;
225     }
226    
227     printf("Usage: %s [options] <ios_image>\n\n",argv[0]);
228    
229     printf("Available options:\n"
230 dpavlin 3 " -H <tcp_port> : Run in hypervisor mode\n\n"
231 dpavlin 4 " -P <platform> : Platform to emulate (7200, 3600, "
232     "2691, 3725 or 3745) "
233 dpavlin 1 "(default: 7200)\n\n"
234     " -l <log_file> : Set logging file (default is %s)\n"
235     " -j : Disable the JIT compiler, very slow\n"
236     " --exec-area <size> : Set the exec area size (default: %d Mb)\n"
237     " --idle-pc <pc> : Set the idle PC (default: disabled)\n"
238     " --timer-itv <val> : Timer IRQ interval check (default: %u)\n"
239     "\n"
240     " -i <instance> : Set instance ID\n"
241     " -r <ram_size> : Set the virtual RAM size (default: %u Mb)\n"
242     " -o <rom_size> : Set the virtual ROM size (default: %u Mb)\n"
243     " -n <nvram_size> : Set the NVRAM size (default: %d Kb)\n"
244     " -c <conf_reg> : Set the configuration register "
245     "(default: 0x%04x)\n"
246     " -m <mac_addr> : Set the MAC address of the chassis\n"
247     " (default: automatically generated)\n"
248     " -C <cfg_file> : Import an IOS configuration file "
249     "into NVRAM\n"
250     " -X : Do not use a file to simulate RAM (faster)\n"
251 dpavlin 4 " -G <ghost_file> : Use a ghost file to simulate RAM\n"
252     " -g <ghost_file> : Generate a ghost RAM file\n"
253 dpavlin 7 " --sparse-mem : Use sparse memory\n"
254 dpavlin 1 " -R <rom_file> : Load an alternate ROM (default: embedded)\n"
255     " -k <clock_div> : Set the clock divisor (default: %d)\n"
256     "\n"
257     " -T <port> : Console is on TCP <port>\n"
258     " -U <si_desc> : Console in on serial interface <si_desc>\n"
259     " (default is on the terminal)\n"
260     "\n"
261     " -A <port> : AUX is on TCP <port>\n"
262     " -B <si_desc> : AUX is on serial interface <si_desc>\n"
263     " (default is no AUX port)\n"
264     "\n"
265     " --disk0 <size> : Set PCMCIA ATA disk0: size "
266     "(default: %u Mb)\n"
267     " --disk1 <size> : Set PCMCIA ATA disk1: size "
268     "(default: %u Mb)\n"
269     "\n",
270     LOGFILE_DEFAULT_NAME,MIPS_EXEC_AREA_SIZE,VM_TIMER_IRQ_CHECK_ITV,
271     def_ram_size,def_rom_size,def_nvram_size,def_conf_reg,
272     def_clock_div,def_disk0_size,def_disk1_size);
273    
274     switch(platform) {
275     case VM_TYPE_C7200:
276     printf(" -t <npe_type> : Select NPE type (default: \"%s\")\n"
277     " -M <midplane> : Select Midplane (\"std\" or \"vxr\")\n"
278     " -p <pa_desc> : Define a Port Adapter\n"
279     " -s <pa_nio> : Bind a Network IO interface to a "
280     "Port Adapter\n",
281     C7200_DEFAULT_NPE_TYPE);
282     break;
283    
284     case VM_TYPE_C3600:
285     printf(" -t <chassis_type> : Select Chassis type "
286     "(default: \"%s\")\n"
287     " --iomem-size <val> : IO memory (in percents, default: %u)\n"
288     " -p <nm_desc> : Define a Network Module\n"
289     " -s <nm_nio> : Bind a Network IO interface to a "
290     "Network Module\n",
291     C3600_DEFAULT_CHASSIS,def_nm_iomem_size);
292     break;
293 dpavlin 4
294     case VM_TYPE_C2691:
295     printf(" --iomem-size <val> : IO memory (in percents, default: %u)\n"
296     " -p <nm_desc> : Define a Network Module\n"
297     " -s <nm_nio> : Bind a Network IO interface to a "
298     "Network Module\n",
299     def_nm_iomem_size);
300     break;
301    
302     case VM_TYPE_C3725:
303     printf(" --iomem-size <val> : IO memory (in percents, default: %u)\n"
304     " -p <nm_desc> : Define a Network Module\n"
305     " -s <nm_nio> : Bind a Network IO interface to a "
306     "Network Module\n",
307     def_nm_iomem_size);
308     break;
309    
310     case VM_TYPE_C3745:
311     printf(" --iomem-size <val> : IO memory (in percents, default: %u)\n"
312     " -p <nm_desc> : Define a Network Module\n"
313     " -s <nm_nio> : Bind a Network IO interface to a "
314     "Network Module\n",
315     def_nm_iomem_size);
316     break;
317 dpavlin 7
318     case VM_TYPE_C2600:
319     printf(" --iomem-size <val> : IO memory (in percents, default: %u)\n"
320     " -p <nm_desc> : Define a Network Module\n"
321     " -s <nm_nio> : Bind a Network IO interface to a "
322     "Network Module\n",
323     def_nm_iomem_size);
324     break;
325 dpavlin 1 }
326    
327     printf("\n"
328     #if DEBUG_SYM_TREE
329     " -S <sym_file> : Load a symbol file\n"
330     #endif
331     " -a <cfg_file> : Virtual ATM switch configuration file\n"
332     " -f <cfg_file> : Virtual Frame-Relay switch configuration "
333     "file\n"
334     " -E <cfg_file> : Virtual Ethernet switch configuration file\n"
335     " -b <cfg_file> : Virtual bridge configuration file\n"
336     " -e : Show network device list of the "
337     "host machine\n"
338     "\n");
339    
340     printf("<si_desc> format:\n"
341     " \"device{:baudrate{:databits{:parity{:stopbits{:hwflow}}}}}}\"\n"
342     "\n");
343    
344     switch(platform) {
345     case VM_TYPE_C7200:
346     printf("<pa_desc> format:\n"
347     " \"slot:pa_driver\"\n"
348     "\n");
349    
350     printf("<pa_nio> format:\n"
351     " \"slot:port:netio_type{:netio_parameters}\"\n"
352     "\n");
353    
354     /* Show the possible NPE drivers */
355     c7200_npe_show_drivers();
356    
357     /* Show the possible PA drivers */
358     c7200_pa_show_drivers();
359     break;
360    
361     case VM_TYPE_C3600:
362     printf("<nm_desc> format:\n"
363     " \"slot:nm_driver\"\n"
364     "\n");
365    
366     printf("<nm_nio> format:\n"
367     " \"slot:port:netio_type{:netio_parameters}\"\n"
368     "\n");
369    
370     /* Show the possible chassis types for C3600 platform */
371     c3600_chassis_show_drivers();
372    
373 dpavlin 4 /* Show the possible NM drivers */
374 dpavlin 1 c3600_nm_show_drivers();
375     break;
376 dpavlin 4
377     case VM_TYPE_C2691:
378     printf("<nm_desc> format:\n"
379     " \"slot:nm_driver\"\n"
380     "\n");
381    
382     printf("<nm_nio> format:\n"
383     " \"slot:port:netio_type{:netio_parameters}\"\n"
384     "\n");
385    
386     /* Show the possible NM drivers */
387     c2691_nm_show_drivers();
388     break;
389    
390     case VM_TYPE_C3725:
391     printf("<nm_desc> format:\n"
392     " \"slot:nm_driver\"\n"
393     "\n");
394    
395     printf("<nm_nio> format:\n"
396     " \"slot:port:netio_type{:netio_parameters}\"\n"
397     "\n");
398    
399     /* Show the possible NM drivers */
400     c3725_nm_show_drivers();
401     break;
402    
403     case VM_TYPE_C3745:
404     printf("<nm_desc> format:\n"
405     " \"slot:nm_driver\"\n"
406     "\n");
407    
408     printf("<nm_nio> format:\n"
409     " \"slot:port:netio_type{:netio_parameters}\"\n"
410     "\n");
411    
412     /* Show the possible NM drivers */
413     c3745_nm_show_drivers();
414     break;
415 dpavlin 7
416     case VM_TYPE_C2600:
417     printf("<nm_desc> format:\n"
418     " \"slot:nm_driver\"\n"
419     "\n");
420    
421     printf("<nm_nio> format:\n"
422     " \"slot:port:netio_type{:netio_parameters}\"\n"
423     "\n");
424    
425     /* Show the possible chassis types for C2600 platform */
426     c2600_mainboard_show_drivers();
427    
428     /* Show the possible NM drivers */
429     c2600_nm_show_drivers();
430     break;
431 dpavlin 1 }
432    
433     /* Show the possible NETIO types */
434     netio_show_types();
435     }
436    
437     /* Find an option in the command line */
438     static char *cli_find_option(int argc,char *argv[],char *opt)
439     {
440     int i;
441    
442     for(i=1;i<argc;i++) {
443     if (!strncmp(argv[i],opt,2)) {
444     if (argv[i][2] != 0)
445     return(&argv[i][2]);
446     else {
447     if (argv[i+1] != NULL)
448     return(argv[i+1]);
449     else {
450     fprintf(stderr,"Error: option '%s': no argument specified.\n",
451     opt);
452     exit(EXIT_FAILURE);
453     }
454     }
455     }
456     }
457    
458     return NULL;
459     }
460    
461     /* Determine the platform (Cisco 3600, 7200). Default is Cisco 7200 */
462     static int cli_get_platform_type(int argc,char *argv[])
463     {
464     int vm_type = VM_TYPE_C7200;
465     char *str;
466    
467     if ((str = cli_find_option(argc,argv,"-P"))) {
468     if (!strcmp(str,"3600"))
469     vm_type = VM_TYPE_C3600;
470     else if (!strcmp(str,"7200"))
471     vm_type = VM_TYPE_C7200;
472 dpavlin 4 else if (!strcmp(str,"2691"))
473     vm_type = VM_TYPE_C2691;
474     else if (!strcmp(str,"3725"))
475     vm_type = VM_TYPE_C3725;
476     else if (!strcmp(str,"3745"))
477     vm_type = VM_TYPE_C3745;
478 dpavlin 7 else if (!strcmp(str,"2600"))
479     vm_type = VM_TYPE_C2600;
480     else if (!strcmp(str,"PPC32_TEST"))
481     vm_type = VM_TYPE_PPC32_TEST;
482 dpavlin 1 else
483     fprintf(stderr,"Invalid platform type '%s'\n",str);
484     }
485    
486     return(vm_type);
487     }
488    
489     /* Command Line long options */
490     #define OPT_DISK0_SIZE 0x100
491     #define OPT_DISK1_SIZE 0x101
492     #define OPT_EXEC_AREA 0x102
493     #define OPT_IDLE_PC 0x103
494     #define OPT_TIMER_ITV 0x104
495     #define OPT_VM_DEBUG 0x105
496     #define OPT_IOMEM_SIZE 0x106
497 dpavlin 7 #define OPT_SPARSE_MEM 0x107
498 dpavlin 1
499     static struct option cmd_line_lopts[] = {
500     { "disk0" , 1, NULL, OPT_DISK0_SIZE },
501     { "disk1" , 1, NULL, OPT_DISK1_SIZE },
502     { "exec-area" , 1, NULL, OPT_EXEC_AREA },
503     { "idle-pc" , 1, NULL, OPT_IDLE_PC },
504     { "timer-itv" , 1, NULL, OPT_TIMER_ITV },
505     { "vm-debug" , 1, NULL, OPT_VM_DEBUG },
506     { "iomem-size" , 1, NULL, OPT_IOMEM_SIZE },
507 dpavlin 7 { "sparse-mem" , 0, NULL, OPT_SPARSE_MEM },
508 dpavlin 1 { NULL , 0, NULL, 0 },
509     };
510    
511     /* Parse specific options for the Cisco 7200 platform */
512     static int cli_parse_c7200_options(vm_instance_t *vm,int option)
513     {
514     c7200_t *router;
515    
516     router = VM_C7200(vm);
517    
518     switch(option) {
519     /* NPE type */
520     case 't':
521     c7200_npe_set_type(router,optarg);
522     break;
523    
524     /* Midplane type */
525     case 'M':
526     c7200_midplane_set_type(router,optarg);
527     break;
528    
529     /* Set the base MAC address */
530     case 'm':
531     if (!c7200_midplane_set_mac_addr(router,optarg))
532     printf("MAC address set to '%s'.\n",optarg);
533     break;
534    
535     /* PA settings */
536     case 'p':
537     return(c7200_cmd_pa_create(router,optarg));
538    
539     /* PA NIO settings */
540     case 's':
541     return(c7200_cmd_add_nio(router,optarg));
542    
543     /* Unknown option */
544     default:
545     return(-1);
546     }
547    
548     return(0);
549     }
550    
551     /* Parse specific options for the Cisco 3600 platform */
552     static int cli_parse_c3600_options(vm_instance_t *vm,int option)
553     {
554     c3600_t *router;
555    
556     router = VM_C3600(vm);
557    
558     switch(option) {
559     /* chassis type */
560     case 't':
561     c3600_chassis_set_type(router,optarg);
562     break;
563    
564     /* IO memory reserved for NMs (in percents!) */
565     case OPT_IOMEM_SIZE:
566     router->nm_iomem_size = 0x8000 | atoi(optarg);
567     break;
568    
569     /* NM settings */
570     case 'p':
571     return(c3600_cmd_nm_create(router,optarg));
572    
573     /* NM NIO settings */
574     case 's':
575     return(c3600_cmd_add_nio(router,optarg));
576    
577     /* Unknown option */
578     default:
579     return(-1);
580     }
581    
582     return(0);
583     }
584    
585 dpavlin 4 /* Parse specific options for the Cisco 2691 platform */
586     static int cli_parse_c2691_options(vm_instance_t *vm,int option)
587     {
588     c2691_t *router;
589    
590     router = VM_C2691(vm);
591    
592     switch(option) {
593     /* IO memory reserved for NMs (in percents!) */
594     case OPT_IOMEM_SIZE:
595     router->nm_iomem_size = 0x8000 | atoi(optarg);
596     break;
597    
598     /* NM settings */
599     case 'p':
600     return(c2691_cmd_nm_create(router,optarg));
601    
602     /* NM NIO settings */
603     case 's':
604     return(c2691_cmd_add_nio(router,optarg));
605    
606     /* Unknown option */
607     default:
608     return(-1);
609     }
610    
611     return(0);
612     }
613    
614     /* Parse specific options for the Cisco 3725 platform */
615     static int cli_parse_c3725_options(vm_instance_t *vm,int option)
616     {
617     c3725_t *router;
618    
619     router = VM_C3725(vm);
620    
621     switch(option) {
622     /* IO memory reserved for NMs (in percents!) */
623     case OPT_IOMEM_SIZE:
624     router->nm_iomem_size = 0x8000 | atoi(optarg);
625     break;
626    
627     /* NM settings */
628     case 'p':
629     return(c3725_cmd_nm_create(router,optarg));
630    
631     /* NM NIO settings */
632     case 's':
633     return(c3725_cmd_add_nio(router,optarg));
634    
635     /* Unknown option */
636     default:
637     return(-1);
638     }
639    
640     return(0);
641     }
642    
643     /* Parse specific options for the Cisco 3745 platform */
644     static int cli_parse_c3745_options(vm_instance_t *vm,int option)
645     {
646     c3745_t *router;
647    
648     router = VM_C3745(vm);
649    
650     switch(option) {
651     /* IO memory reserved for NMs (in percents!) */
652     case OPT_IOMEM_SIZE:
653     router->nm_iomem_size = 0x8000 | atoi(optarg);
654     break;
655    
656     /* NM settings */
657     case 'p':
658     return(c3745_cmd_nm_create(router,optarg));
659    
660     /* NM NIO settings */
661     case 's':
662     return(c3745_cmd_add_nio(router,optarg));
663    
664     /* Unknown option */
665     default:
666     return(-1);
667     }
668    
669     return(0);
670     }
671    
672 dpavlin 7 /* Parse specific options for the Cisco 2600 platform */
673     static int cli_parse_c2600_options(vm_instance_t *vm,int option)
674     {
675     c2600_t *router;
676    
677     router = VM_C2600(vm);
678    
679     switch(option) {
680     /* IO memory reserved for NMs (in percents!) */
681     case OPT_IOMEM_SIZE:
682     router->nm_iomem_size = 0x8000 | atoi(optarg);
683     break;
684    
685     /* Mainboard type */
686     case 't':
687     c2600_mainboard_set_type(router,optarg);
688     break;
689    
690     /* NM settings */
691     case 'p':
692     return(c2600_cmd_nm_create(router,optarg));
693    
694     /* NM NIO settings */
695     case 's':
696     return(c2600_cmd_add_nio(router,optarg));
697    
698     /* Unknown option */
699     default:
700     return(-1);
701     }
702    
703     return(0);
704     }
705    
706 dpavlin 1 /* Create a router instance */
707     static vm_instance_t *cli_create_instance(char *name,int platform_type,
708     int instance_id)
709     {
710 dpavlin 7 vm_instance_t *vm;
711 dpavlin 1 c7200_t *c7200;
712     c3600_t *c3600;
713 dpavlin 4 c2691_t *c2691;
714     c3725_t *c3725;
715     c3745_t *c3745;
716 dpavlin 7 c2600_t *c2600;
717 dpavlin 1
718     switch(platform_type) {
719     case VM_TYPE_C7200:
720     if (!(c7200 = c7200_create_instance(name,instance_id))) {
721     fprintf(stderr,"C7200: unable to create instance!\n");
722     return NULL;
723     }
724     return(c7200->vm);
725    
726     case VM_TYPE_C3600:
727     if (!(c3600 = c3600_create_instance(name,instance_id))) {
728     fprintf(stderr,"C3600: unable to create instance!\n");
729     return NULL;
730     }
731     return(c3600->vm);
732    
733 dpavlin 4 case VM_TYPE_C2691:
734     if (!(c2691 = c2691_create_instance(name,instance_id))) {
735     fprintf(stderr,"C2691: unable to create instance!\n");
736     return NULL;
737     }
738     return(c2691->vm);
739    
740     case VM_TYPE_C3725:
741     if (!(c3725 = c3725_create_instance(name,instance_id))) {
742     fprintf(stderr,"C3725: unable to create instance!\n");
743     return NULL;
744     }
745     return(c3725->vm);
746    
747     case VM_TYPE_C3745:
748     if (!(c3745 = c3745_create_instance(name,instance_id))) {
749     fprintf(stderr,"C3745: unable to create instance!\n");
750     return NULL;
751     }
752     return(c3745->vm);
753    
754 dpavlin 7 case VM_TYPE_C2600:
755     if (!(c2600 = c2600_create_instance(name,instance_id))) {
756     fprintf(stderr,"C2600: unable to create instance!\n");
757     return NULL;
758     }
759     return(c2600->vm);
760    
761     case VM_TYPE_PPC32_TEST:
762     if (!(vm = ppc32_vmtest_create_instance(name,instance_id))) {
763     fprintf(stderr,"PPC32_TEST: unable to create instance!\n");
764     return NULL;
765     }
766     return(vm);
767    
768 dpavlin 1 default:
769     fprintf(stderr,"Unknown platform type '%d'!\n",platform_type);
770     return NULL;
771     }
772     }
773    
774     /* Parse the command line */
775     static int parse_std_cmd_line(int argc,char *argv[],int *platform)
776     {
777     char *options_list =
778 dpavlin 4 "r:o:n:c:m:l:C:i:jt:p:s:k:T:U:A:B:a:f:E:b:S:R:M:eXP:N:G:g:";
779 dpavlin 1 vm_instance_t *vm;
780     int instance_id;
781     int res,option;
782     char *str;
783    
784     /* Get the instance ID */
785     instance_id = 0;
786    
787     /* Use the old VM file naming type */
788     vm_file_naming_type = 1;
789    
790     if ((str = cli_find_option(argc,argv,"-i"))) {
791     instance_id = atoi(str);
792     printf("Instance ID set to %d.\n",instance_id);
793     }
794    
795     if ((str = cli_find_option(argc,argv,"-N")))
796     vm_file_naming_type = atoi(str);
797    
798     /* Get the platform type */
799     *platform = cli_get_platform_type(argc,argv);
800    
801     /* Create the default instance */
802     if (!(vm = cli_create_instance("default",*platform,instance_id)))
803     exit(EXIT_FAILURE);
804    
805     opterr = 0;
806    
807     while((option = getopt_long(argc,argv,options_list,
808     cmd_line_lopts,NULL)) != -1)
809     {
810     switch(option)
811     {
812     /* Instance ID (already managed) */
813     case 'i':
814     break;
815    
816     /* Platform (already managed) */
817     case 'P':
818     break;
819    
820     /* RAM size */
821     case 'r':
822     vm->ram_size = strtol(optarg, NULL, 10);
823     printf("Virtual RAM size set to %d MB.\n",vm->ram_size);
824     break;
825    
826     /* ROM size */
827     case 'o':
828     vm->rom_size = strtol(optarg, NULL, 10);
829     printf("Virtual ROM size set to %d MB.\n",vm->rom_size);
830     break;
831    
832     /* NVRAM size */
833     case 'n':
834     vm->nvram_size = strtol(optarg, NULL, 10);
835     printf("NVRAM size set to %d KB.\n",vm->nvram_size);
836     break;
837    
838     /* Execution area size */
839     case OPT_EXEC_AREA:
840     vm->exec_area_size = atoi(optarg);
841     break;
842    
843     /* PCMCIA disk0 size */
844     case OPT_DISK0_SIZE:
845     vm->pcmcia_disk_size[0] = atoi(optarg);
846     printf("PCMCIA ATA disk0 size set to %u MB.\n",
847     vm->pcmcia_disk_size[0]);
848     break;
849    
850     /* PCMCIA disk1 size */
851     case OPT_DISK1_SIZE:
852     vm->pcmcia_disk_size[1] = atoi(optarg);
853     printf("PCMCIA ATA disk1 size set to %u MB.\n",
854     vm->pcmcia_disk_size[1]);
855     break;
856    
857     /* Config Register */
858     case 'c':
859     vm->conf_reg_setup = strtol(optarg, NULL, 0);
860     printf("Config. Register set to 0x%x.\n",vm->conf_reg_setup);
861     break;
862    
863     /* IOS configuration file */
864     case 'C':
865     vm_ios_set_config(vm,optarg);
866     break;
867    
868     /* Use physical memory to emulate RAM (no-mapped file) */
869     case 'X':
870     vm->ram_mmap = 0;
871     break;
872    
873 dpavlin 4 /* Use a ghost file to simulate RAM */
874     case 'G':
875     vm->ghost_ram_filename = strdup(optarg);
876     vm->ghost_status = VM_GHOST_RAM_USE;
877     break;
878    
879     /* Generate a ghost RAM image */
880     case 'g':
881     vm->ghost_ram_filename = strdup(optarg);
882     vm->ghost_status = VM_GHOST_RAM_GENERATE;
883     break;
884    
885 dpavlin 7 /* Use sparse memory */
886     case OPT_SPARSE_MEM:
887     vm->sparse_mem = TRUE;
888     break;
889    
890 dpavlin 1 /* Alternate ROM */
891     case 'R':
892     vm->rom_filename = optarg;
893     break;
894    
895     /* Idle PC */
896     case OPT_IDLE_PC:
897     vm->idle_pc = strtoull(optarg,NULL,0);
898     printf("Idle PC set to 0x%llx.\n",vm->idle_pc);
899     break;
900    
901     /* Timer IRQ check interval */
902     case OPT_TIMER_ITV:
903     vm->timer_irq_check_itv = atoi(optarg);
904     break;
905    
906     /* Clock divisor */
907     case 'k':
908     vm->clock_divisor = atoi(optarg);
909    
910     if (!vm->clock_divisor) {
911     fprintf(stderr,"Invalid Clock Divisor specified!\n");
912     exit(EXIT_FAILURE);
913     }
914    
915     printf("Using a clock divisor of %d.\n",vm->clock_divisor);
916     break;
917    
918     /* Disable JIT */
919     case 'j':
920     vm->jit_use = FALSE;
921     break;
922    
923     /* VM debug level */
924     case OPT_VM_DEBUG:
925     vm->debug_level = atoi(optarg);
926     break;
927    
928     /* Log file */
929     case 'l':
930     if (!(log_file_name = strdup(optarg))) {
931     fprintf(stderr,"Unable to set log file name.\n");
932     exit(EXIT_FAILURE);
933     }
934     printf("Log file: writing to %s\n",log_file_name);
935     break;
936    
937     #if DEBUG_SYM_TREE
938     /* Symbol file */
939     case 'S':
940     vm->sym_filename = strdup(optarg);
941     break;
942     #endif
943    
944     /* TCP server for Console Port */
945     case 'T':
946     vm->vtty_con_type = VTTY_TYPE_TCP;
947     vm->vtty_con_tcp_port = atoi(optarg);
948     break;
949    
950     /* Serial interface for Console port */
951     case 'U':
952     vm->vtty_con_type = VTTY_TYPE_SERIAL;
953     if (vtty_parse_serial_option(&vm->vtty_con_serial_option,optarg)) {
954     fprintf(stderr,
955     "Invalid Console serial interface descriptor!\n");
956     exit(EXIT_FAILURE);
957     }
958     break;
959    
960     /* TCP server for AUX Port */
961     case 'A':
962     vm->vtty_aux_type = VTTY_TYPE_TCP;
963     vm->vtty_aux_tcp_port = atoi(optarg);
964     break;
965    
966     /* Serial interface for AUX port */
967     case 'B':
968     vm->vtty_aux_type = VTTY_TYPE_SERIAL;
969     if (vtty_parse_serial_option(&vm->vtty_aux_serial_option,optarg)) {
970     fprintf(stderr,"Invalid AUX serial interface descriptor!\n");
971     exit(EXIT_FAILURE);
972     }
973     break;
974    
975     /* Virtual ATM switch */
976     case 'a':
977     if (atmsw_start(optarg) == -1)
978     exit(EXIT_FAILURE);
979     break;
980    
981     /* Virtual Frame-Relay switch */
982     case 'f':
983     if (frsw_start(optarg) == -1)
984     exit(EXIT_FAILURE);
985     break;
986    
987     /* Virtual Ethernet switch */
988     case 'E':
989     if (ethsw_start(optarg) == -1)
990     exit(EXIT_FAILURE);
991     break;
992    
993     /* Virtual bridge */
994     case 'b':
995     if (netio_bridge_start(optarg) == -1)
996     exit(EXIT_FAILURE);
997     break;
998    
999     #ifdef GEN_ETH
1000     /* Ethernet device list */
1001     case 'e':
1002     gen_eth_show_dev_list();
1003     exit(EXIT_SUCCESS);
1004     #endif
1005    
1006     /* Oops ! */
1007     case '?':
1008     show_usage(argc,argv,*platform);
1009     exit(EXIT_FAILURE);
1010    
1011     /* Parse options specific to the platform */
1012     default:
1013     res = 0;
1014    
1015     switch(vm->type) {
1016     case VM_TYPE_C7200:
1017     res = cli_parse_c7200_options(vm,option);
1018     break;
1019     case VM_TYPE_C3600:
1020     res = cli_parse_c3600_options(vm,option);
1021 dpavlin 4 break;
1022     case VM_TYPE_C2691:
1023     res = cli_parse_c2691_options(vm,option);
1024 dpavlin 1 break;
1025 dpavlin 4 case VM_TYPE_C3725:
1026     res = cli_parse_c3725_options(vm,option);
1027     break;
1028     case VM_TYPE_C3745:
1029     res = cli_parse_c3745_options(vm,option);
1030     break;
1031 dpavlin 7 case VM_TYPE_C2600:
1032     res = cli_parse_c2600_options(vm,option);
1033     break;
1034 dpavlin 1 }
1035    
1036     if (res == -1)
1037     exit(EXIT_FAILURE);
1038     }
1039     }
1040    
1041     /* Last argument, this is the IOS filename */
1042     if (optind == (argc - 1)) {
1043     /* setting IOS image file */
1044     vm_ios_set_image(vm,argv[optind]);
1045     printf("IOS image file: %s\n\n",vm->ios_image);
1046     } else {
1047     /* IOS missing */
1048     fprintf(stderr,"Please specify an IOS image filename\n");
1049     show_usage(argc,argv,*platform);
1050     exit(EXIT_FAILURE);
1051     }
1052    
1053     vm_release(vm);
1054     return(0);
1055     }
1056    
1057     /*
1058     * Run in hypervisor mode with a config file if the "-H" option
1059     * is present in command line.
1060     */
1061     static int run_hypervisor(int argc,char *argv[])
1062     {
1063     char *options_list = "H:l:hN:";
1064     int i,option;
1065    
1066     for(i=1;i<argc;i++)
1067     if (!strcmp(argv[i],"-H")) {
1068     hypervisor_mode = 1;
1069     break;
1070     }
1071    
1072     /* standard mode with one instance */
1073     if (!hypervisor_mode)
1074     return(FALSE);
1075    
1076     opterr = 0;
1077     while((option = getopt(argc,argv,options_list)) != -1) {
1078     switch(option)
1079     {
1080     /* Hypervisor TCP port */
1081     case 'H':
1082     hypervisor_tcp_port = atoi(optarg);
1083     break;
1084    
1085     /* Log file */
1086     case 'l':
1087     if (!(log_file_name = malloc(strlen(optarg)+1))) {
1088     fprintf(stderr,"Unable to set log file name.\n");
1089     exit(EXIT_FAILURE);
1090     }
1091     strcpy(log_file_name, optarg);
1092     printf("Log file: writing to %s\n",log_file_name);
1093     break;
1094    
1095     /* VM file naming type */
1096     case 'N':
1097     vm_file_naming_type = atoi(optarg);
1098     break;
1099    
1100     /* Oops ! */
1101     case '?':
1102     show_usage(argc,argv,VM_TYPE_C7200);
1103     exit(EXIT_FAILURE);
1104     }
1105     }
1106    
1107     return(TRUE);
1108     }
1109    
1110     /* Delete all objects */
1111     void dynamips_reset(void)
1112     {
1113     printf("Shutdown in progress...\n");
1114    
1115 dpavlin 4 /* Delete all virtual router instances */
1116 dpavlin 1 c7200_delete_all_instances();
1117     c3600_delete_all_instances();
1118 dpavlin 4 c2691_delete_all_instances();
1119     c3725_delete_all_instances();
1120     c3745_delete_all_instances();
1121 dpavlin 7 c2600_delete_all_instances();
1122     ppc32_vmtest_delete_all_instances();
1123 dpavlin 1
1124     /* Delete ATM and Frame-Relay switches + bridges */
1125     netio_bridge_delete_all();
1126     atmsw_delete_all();
1127     frsw_delete_all();
1128     ethsw_delete_all();
1129    
1130     /* Delete all NIO descriptors */
1131     netio_delete_all();
1132    
1133     printf("Shutdown completed.\n");
1134     }
1135    
1136     int main(int argc,char *argv[])
1137     {
1138     vm_instance_t *vm;
1139     int platform,res;
1140    
1141     /* Default emulation: Cisco 7200 */
1142     platform = VM_TYPE_C7200;
1143    
1144     #ifdef PROFILE
1145     atexit(profiler_savestat);
1146     #endif
1147    
1148 dpavlin 7 printf("Cisco Router Simulation Platform (version %s)\n",sw_version);
1149     printf("Copyright (c) 2005-2007 Christophe Fillot.\n");
1150 dpavlin 4 printf("Build date: %s %s\n\n",__DATE__,__TIME__);
1151 dpavlin 1
1152 dpavlin 3 /* Initialize timers */
1153     timer_init();
1154    
1155 dpavlin 1 /* Initialize object registry */
1156     registry_init();
1157    
1158     /* Initialize ATM module (for HEC checksums) */
1159     atm_init();
1160    
1161     /* Initialize CRC functions */
1162     crc_init();
1163    
1164     /* Initialize NetIO code */
1165     netio_rxl_init();
1166    
1167     /* Initialize NetIO packet filters */
1168     netio_filter_load_all();
1169    
1170     /* Initialize VTTY code */
1171     vtty_init();
1172    
1173     /* Parse standard command line */
1174     if (!run_hypervisor(argc,argv))
1175     parse_std_cmd_line(argc,argv,&platform);
1176    
1177     /* Create general log file */
1178     create_log_file();
1179    
1180     /* Periodic tasks initialization */
1181     if (ptask_init(0) == -1)
1182     exit(EXIT_FAILURE);
1183    
1184     /* Create instruction lookup tables */
1185     mips64_jit_create_ilt();
1186     mips64_exec_create_ilt();
1187 dpavlin 7 ppc32_jit_create_ilt();
1188     ppc32_exec_create_ilt();
1189 dpavlin 1
1190     setup_signals();
1191    
1192     if (!hypervisor_mode) {
1193     /* Initialize the default instance */
1194     vm = vm_acquire("default");
1195     assert(vm != NULL);
1196    
1197     switch(platform) {
1198     case VM_TYPE_C7200:
1199     res = c7200_init_instance(VM_C7200(vm));
1200     break;
1201     case VM_TYPE_C3600:
1202     res = c3600_init_instance(VM_C3600(vm));
1203 dpavlin 4 break;
1204     case VM_TYPE_C2691:
1205     res = c2691_init_instance(VM_C2691(vm));
1206 dpavlin 1 break;
1207 dpavlin 4 case VM_TYPE_C3725:
1208     res = c3725_init_instance(VM_C3725(vm));
1209     break;
1210     case VM_TYPE_C3745:
1211     res = c3745_init_instance(VM_C3745(vm));
1212     break;
1213 dpavlin 7 case VM_TYPE_C2600:
1214     res = c2600_init_instance(VM_C2600(vm));
1215     break;
1216     case VM_TYPE_PPC32_TEST:
1217     res = ppc32_vmtest_init_instance(vm);
1218     break;
1219 dpavlin 1 default:
1220     res = -1;
1221     }
1222    
1223     if (res == -1) {
1224     fprintf(stderr,"Unable to initialize router instance.\n");
1225     exit(EXIT_FAILURE);
1226     }
1227    
1228 dpavlin 5 #if (DEBUG_INSN_PERF_CNT > 0) || (DEBUG_BLOCK_PERF_CNT > 0)
1229 dpavlin 1 {
1230 dpavlin 7 m_uint64_t counter,prev = 0,delta;
1231 dpavlin 1 while(vm->status == VM_STATUS_RUNNING) {
1232 dpavlin 7 counter = cpu_get_perf_counter(vm->boot_cpu);
1233     delta = counter - prev;
1234     prev = counter;
1235 dpavlin 1 printf("delta = %llu\n",delta);
1236     sleep(1);
1237     }
1238     }
1239     #else
1240     /* Start instance monitoring */
1241     vm_monitor(vm);
1242     #endif
1243    
1244     /* Free resources used by instance */
1245     vm_release(vm);
1246     } else {
1247     hypervisor_tcp_server(hypervisor_tcp_port);
1248     }
1249    
1250     dynamips_reset();
1251     close_log_file();
1252     return(0);
1253     }

  ViewVC Help
Powered by ViewVC 1.1.26