/[dynamips]/upstream/dynamips-0.2.6-RC3/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.6-RC3/dynamips.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4 - (hide annotations)
Sat Oct 6 16:06:49 2007 UTC (16 years, 5 months ago) by dpavlin
File MIME type: text/plain
File size: 32164 byte(s)
dynamips-0.2.6-RC3

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

  ViewVC Help
Powered by ViewVC 1.1.26