/[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

Contents of /upstream/dynamips-0.2.6-RC3/dynamips.c

Parent Directory Parent Directory | Revision Log Revision Log


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

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 #include "dev_c2691.h"
31 #include "dev_c3725.h"
32 #include "dev_c3745.h"
33 #include "dev_vtty.h"
34 #include "ptask.h"
35 #include "timer.h"
36 #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 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 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 " -H <tcp_port> : Run in hypervisor mode\n\n"
216 " -P <platform> : Platform to emulate (7200, 3600, "
217 "2691, 3725 or 3745) "
218 "(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 " -G <ghost_file> : Use a ghost file to simulate RAM\n"
237 " -g <ghost_file> : Generate a ghost RAM file\n"
238 " -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
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 }
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 /* Show the possible NM drivers */
350 c3600_nm_show_drivers();
351 break;
352
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 }
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 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 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 /* 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 /* 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 c2691_t *c2691;
633 c3725_t *c3725;
634 c3745_t *c3745;
635
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 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 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 "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 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 /* 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 /* 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 break;
921 case VM_TYPE_C2691:
922 res = cli_parse_c2691_options(vm,option);
923 break;
924 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 }
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 /* Delete all virtual router instances */
1012 c7200_delete_all_instances();
1013 c3600_delete_all_instances();
1014 c2691_delete_all_instances();
1015 c3725_delete_all_instances();
1016 c3745_delete_all_instances();
1017
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 printf("Copyright (c) 2005,2006 Christophe Fillot.\n");
1044 printf("Build date: %s %s\n\n",__DATE__,__TIME__);
1045
1046 /* Initialize timers */
1047 timer_init();
1048
1049 /* 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 break;
1096 case VM_TYPE_C2691:
1097 res = c2691_init_instance(VM_C2691(vm));
1098 break;
1099 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 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