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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 12 - (show annotations)
Sat Oct 6 16:45:40 2007 UTC (11 years, 7 months ago) by dpavlin
File MIME type: text/plain
File size: 23319 byte(s)
make working copy

1 /*
2 * Cisco router 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 "dynamips.h"
24 #include "cpu.h"
25 #include "mips64_exec.h"
26 #include "mips64_jit.h"
27 #include "ppc32_exec.h"
28 #include "ppc32_jit.h"
29 #include "dev_c7200.h"
30 #include "dev_c3600.h"
31 #include "dev_c2691.h"
32 #include "dev_c3725.h"
33 #include "dev_c3745.h"
34 #include "dev_c2600.h"
35 #include "dev_c1700.h"
36 #include "dev_c6msfc1.h"
37 #include "dev_c6sup1.h"
38 #include "ppc32_vmtest.h"
39 #include "dev_vtty.h"
40 #include "ptask.h"
41 #include "timer.h"
42 #include "plugin.h"
43 #include "registry.h"
44 #include "hypervisor.h"
45 #include "net_io.h"
46 #include "net_io_bridge.h"
47 #include "net_io_filter.h"
48 #include "crc.h"
49 #include "atm.h"
50 #include "frame_relay.h"
51 #include "eth_switch.h"
52 #ifdef GEN_ETH
53 #include "gen_eth.h"
54 #endif
55 #ifdef PROFILE
56 #include "profiler.h"
57 #endif
58
59 /* Default name for logfile */
60 #define LOGFILE_DEFAULT_NAME "dynamips_log.txt"
61
62 /* Software version */
63 const char *sw_version = DYNAMIPS_VERSION"-"JIT_ARCH;
64
65 /* Software version tag */
66 const char *sw_version_tag = "2007050300";
67
68 /* Hypervisor */
69 int hypervisor_mode = 0;
70 int hypervisor_tcp_port = 0;
71 char *hypervisor_ip_address = NULL;
72
73 /* Log file */
74 char *log_file_name = NULL;
75 FILE *log_file = NULL;
76
77 /* VM flags */
78 volatile int vm_save_state = 0;
79
80 /* Default platform */
81 static char *default_platform = "7200";
82
83 /* Generic signal handler */
84 void signal_gen_handler(int sig)
85 {
86 switch(sig) {
87 case SIGHUP:
88 /* For future use */
89 break;
90
91 case SIGQUIT:
92 /* save VM context */
93 vm_save_state = TRUE;
94 break;
95
96 case SIGINT:
97 /* CTRL+C has been pressed */
98 if (hypervisor_mode)
99 hypervisor_stopsig();
100 else {
101 /* In theory, this shouldn't happen thanks to VTTY settings */
102 vm_instance_t *vm;
103
104 if ((vm = vm_acquire("default")) != NULL) {
105 /* Only forward ctrl-c if user has requested local terminal */
106 if (vm->vtty_con_type == VTTY_TYPE_TERM) {
107 vtty_store_ctrlc(vm->vtty_con);
108 } else {
109 vm_stop(vm);
110 }
111 vm_release(vm);
112 } else {
113 fprintf(stderr,"Error: Cannot acquire instance handle.\n");
114 }
115 }
116 break;
117
118 default:
119 fprintf(stderr,"Unhandled signal %d\n",sig);
120 }
121 }
122
123 /* Setups signals */
124 static void setup_signals(void)
125 {
126 struct sigaction act;
127
128 memset(&act,0,sizeof(act));
129 act.sa_handler = signal_gen_handler;
130 act.sa_flags = SA_RESTART;
131 sigaction(SIGHUP,&act,NULL);
132 sigaction(SIGQUIT,&act,NULL);
133 sigaction(SIGINT,&act,NULL);
134 }
135
136 /* Create general log file */
137 static void create_log_file(void)
138 {
139 /* Set the default value of the log file name */
140 if (!log_file_name) {
141 if (!(log_file_name = strdup(LOGFILE_DEFAULT_NAME))) {
142 fprintf(stderr,"Unable to set log file name.\n");
143 exit(EXIT_FAILURE);
144 }
145 }
146
147 if (!(log_file = fopen(log_file_name,"w"))) {
148 fprintf(stderr,"Unable to create log file (%s).\n",strerror(errno));
149 exit(EXIT_FAILURE);
150 }
151 }
152
153 /* Close general log file */
154 static void close_log_file(void)
155 {
156 if (log_file) fclose(log_file);
157 free(log_file_name);
158
159 log_file = NULL;
160 log_file_name = NULL;
161 }
162
163 /* Display the command line use */
164 static void show_usage(vm_instance_t *vm,int argc,char *argv[])
165 {
166 printf("Usage: %s [options] <ios_image>\n\n",argv[0]);
167
168 printf("Available options:\n"
169 " -H [<ip_address>:]<tcp_port> : Run in hypervisor mode\n\n"
170 " -P <platform> : Platform to emulate (7200, 3600, "
171 "2691, 3725, 3745, 2600 or 1700) "
172 "(default: 7200)\n\n"
173 " -l <log_file> : Set logging file (default is %s)\n"
174 " -j : Disable the JIT compiler, very slow\n"
175 " --exec-area <size> : Set the exec area size (default: %d Mb)\n"
176 " --idle-pc <pc> : Set the idle PC (default: disabled)\n"
177 " --timer-itv <val> : Timer IRQ interval check (default: %u)\n"
178 "\n"
179 " -i <instance> : Set instance ID\n"
180 " -r <ram_size> : Set the virtual RAM size (default: %u Mb)\n"
181 " -o <rom_size> : Set the virtual ROM size (default: %u Mb)\n"
182 " -n <nvram_size> : Set the NVRAM size (default: %d Kb)\n"
183 " -c <conf_reg> : Set the configuration register "
184 "(default: 0x%04x)\n"
185 " -m <mac_addr> : Set the MAC address of the chassis\n"
186 " (default: automatically generated)\n"
187 " -C <cfg_file> : Import an IOS configuration file "
188 "into NVRAM\n"
189 " -X : Do not use a file to simulate RAM (faster)\n"
190 " -G <ghost_file> : Use a ghost file to simulate RAM\n"
191 " -g <ghost_file> : Generate a ghost RAM file\n"
192 " --sparse-mem : Use sparse memory\n"
193 " -R <rom_file> : Load an alternate ROM (default: embedded)\n"
194 " -k <clock_div> : Set the clock divisor (default: %d)\n"
195 "\n"
196 " -T <port> : Console is on TCP <port>\n"
197 " -U <si_desc> : Console in on serial interface <si_desc>\n"
198 " (default is on the terminal)\n"
199 "\n"
200 " -A <port> : AUX is on TCP <port>\n"
201 " -B <si_desc> : AUX is on serial interface <si_desc>\n"
202 " (default is no AUX port)\n"
203 "\n"
204 " --disk0 <size> : Set PCMCIA ATA disk0: size "
205 "(default: %u Mb)\n"
206 " --disk1 <size> : Set PCMCIA ATA disk1: size "
207 "(default: %u Mb)\n"
208 "\n",
209 LOGFILE_DEFAULT_NAME,MIPS_EXEC_AREA_SIZE,VM_TIMER_IRQ_CHECK_ITV,
210 vm->ram_size,vm->rom_size,vm->nvram_size,vm->conf_reg_setup,
211 vm->clock_divisor,vm->pcmcia_disk_size[0],vm->pcmcia_disk_size[1]);
212
213 if (vm->platform->cli_show_options != NULL)
214 vm->platform->cli_show_options(vm);
215
216 printf("\n"
217 #if DEBUG_SYM_TREE
218 " -S <sym_file> : Load a symbol file\n"
219 #endif
220 " -a <cfg_file> : Virtual ATM switch configuration file\n"
221 " -f <cfg_file> : Virtual Frame-Relay switch configuration "
222 "file\n"
223 " -E <cfg_file> : Virtual Ethernet switch configuration file\n"
224 " -b <cfg_file> : Virtual bridge configuration file\n"
225 " -e : Show network device list of the "
226 "host machine\n"
227 "\n");
228
229 printf("<si_desc> format:\n"
230 " \"device{:baudrate{:databits{:parity{:stopbits{:hwflow}}}}}}\"\n"
231 "\n");
232
233 switch(vm->slots_type) {
234 case CISCO_CARD_TYPE_PA:
235 printf("<pa_desc> format:\n"
236 " \"slot:sub_slot:pa_driver\"\n"
237 "\n");
238
239 printf("<pa_nio> format:\n"
240 " \"slot:port:netio_type{:netio_parameters}\"\n"
241 "\n");
242 break;
243
244 case CISCO_CARD_TYPE_NM:
245 printf("<nm_desc> format:\n"
246 " \"slot:sub_slot:nm_driver\"\n"
247 "\n");
248
249 printf("<nm_nio> format:\n"
250 " \"slot:port:netio_type{:netio_parameters}\"\n"
251 "\n");
252 break;
253
254 case CISCO_CARD_TYPE_WIC:
255 printf("<wic_desc> format:\n"
256 " \"slot:wic_driver\"\n"
257 "\n");
258
259 printf("<wic_nio> format:\n"
260 " \"slot:port:netio_type{:netio_parameters}\"\n"
261 "\n");
262 break;
263 }
264
265 if (vm->platform->show_spec_drivers != NULL)
266 vm->platform->show_spec_drivers();
267
268 /* Show possible slot drivers */
269 vm_slot_show_drivers(vm);
270
271 /* Show the possible NETIO types */
272 netio_show_types();
273 }
274
275 /* Find an option in the command line */
276 static char *cli_find_option(int argc,char *argv[],char *opt)
277 {
278 int i;
279
280 for(i=1;i<argc;i++) {
281 if (!strncmp(argv[i],opt,2)) {
282 if (argv[i][2] != 0)
283 return(&argv[i][2]);
284 else {
285 if (argv[i+1] != NULL)
286 return(argv[i+1]);
287 else {
288 fprintf(stderr,"Error: option '%s': no argument specified.\n",
289 opt);
290 exit(EXIT_FAILURE);
291 }
292 }
293 }
294 }
295
296 return NULL;
297 }
298
299 /* Load plugins */
300 static void cli_load_plugins(int argc,char *argv[])
301 {
302 char *str;
303 int i;
304
305 for(i=1;i<argc;i++) {
306 if (!strncmp(argv[i],"-L",2)) {
307 if (argv[i][2] != 0)
308 str = &argv[i][2];
309 else {
310 if (argv[i+1] != NULL)
311 str = argv[i+1];
312 else {
313 fprintf(stderr,"Plugin error: no argument specified.\n");
314 exit(EXIT_FAILURE);
315 }
316 }
317
318 if (!plugin_load(str))
319 fprintf(stderr,"Unable to load plugin '%s'!\n",str);
320 }
321 }
322 }
323
324 /* Determine the platform (Cisco 3600, 7200). Default is Cisco 7200 */
325 static vm_platform_t *cli_get_platform_type(int argc,char *argv[])
326 {
327 vm_platform_t *platform;
328 char *str;
329
330 if (!(str = cli_find_option(argc,argv,"-P")))
331 str = default_platform;
332
333 if (!(platform = vm_platform_find_cli_name(str)))
334 fprintf(stderr,"Invalid platform type '%s'\n",str);
335
336 return platform;
337 }
338
339 static struct option cmd_line_lopts[] = {
340 { "disk0" , 1, NULL, OPT_DISK0_SIZE },
341 { "disk1" , 1, NULL, OPT_DISK1_SIZE },
342 { "exec-area" , 1, NULL, OPT_EXEC_AREA },
343 { "idle-pc" , 1, NULL, OPT_IDLE_PC },
344 { "timer-itv" , 1, NULL, OPT_TIMER_ITV },
345 { "vm-debug" , 1, NULL, OPT_VM_DEBUG },
346 { "iomem-size" , 1, NULL, OPT_IOMEM_SIZE },
347 { "sparse-mem" , 0, NULL, OPT_SPARSE_MEM },
348 { NULL , 0, NULL, 0 },
349 };
350
351 /* Create a router instance */
352 static vm_instance_t *cli_create_instance(char *name,char *platform_name,
353 int instance_id)
354 {
355 vm_instance_t *vm;
356
357 vm = vm_create_instance(name,instance_id,platform_name);
358
359 if (vm == NULL) {
360 fprintf(stderr,"C7200: unable to create instance!\n");
361 return NULL;
362 }
363
364 return vm;
365 }
366
367 /* Parse the command line */
368 static int parse_std_cmd_line(int argc,char *argv[])
369 {
370 char *options_list =
371 "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:L:";
372 vm_platform_t *platform;
373 vm_instance_t *vm;
374 int instance_id;
375 int option;
376 char *str;
377
378 /* Get the instance ID */
379 instance_id = 0;
380
381 /* Use the old VM file naming type */
382 vm_file_naming_type = 1;
383
384 cli_load_plugins(argc,argv);
385
386 if ((str = cli_find_option(argc,argv,"-i"))) {
387 instance_id = atoi(str);
388 printf("Instance ID set to %d.\n",instance_id);
389 }
390
391 if ((str = cli_find_option(argc,argv,"-N")))
392 vm_file_naming_type = atoi(str);
393
394 /* Get the platform type */
395 if (!(platform = cli_get_platform_type(argc,argv)))
396 exit(EXIT_FAILURE);
397
398 /* Create the default instance */
399 if (!(vm = cli_create_instance("default",platform->name,instance_id)))
400 exit(EXIT_FAILURE);
401
402 opterr = 0;
403
404 while((option = getopt_long(argc,argv,options_list,
405 cmd_line_lopts,NULL)) != -1)
406 {
407 switch(option)
408 {
409 /* Instance ID (already managed) */
410 case 'i':
411 break;
412
413 /* Platform (already managed) */
414 case 'P':
415 break;
416
417 /* RAM size */
418 case 'r':
419 vm->ram_size = strtol(optarg, NULL, 10);
420 printf("Virtual RAM size set to %d MB.\n",vm->ram_size);
421 break;
422
423 /* ROM size */
424 case 'o':
425 vm->rom_size = strtol(optarg, NULL, 10);
426 printf("Virtual ROM size set to %d MB.\n",vm->rom_size);
427 break;
428
429 /* NVRAM size */
430 case 'n':
431 vm->nvram_size = strtol(optarg, NULL, 10);
432 printf("NVRAM size set to %d KB.\n",vm->nvram_size);
433 break;
434
435 /* Execution area size */
436 case OPT_EXEC_AREA:
437 vm->exec_area_size = atoi(optarg);
438 break;
439
440 /* PCMCIA disk0 size */
441 case OPT_DISK0_SIZE:
442 vm->pcmcia_disk_size[0] = atoi(optarg);
443 printf("PCMCIA ATA disk0 size set to %u MB.\n",
444 vm->pcmcia_disk_size[0]);
445 break;
446
447 /* PCMCIA disk1 size */
448 case OPT_DISK1_SIZE:
449 vm->pcmcia_disk_size[1] = atoi(optarg);
450 printf("PCMCIA ATA disk1 size set to %u MB.\n",
451 vm->pcmcia_disk_size[1]);
452 break;
453
454 /* Config Register */
455 case 'c':
456 vm->conf_reg_setup = strtol(optarg, NULL, 0);
457 printf("Config. Register set to 0x%x.\n",vm->conf_reg_setup);
458 break;
459
460 /* IOS configuration file */
461 case 'C':
462 vm_ios_set_config(vm,optarg);
463 break;
464
465 /* Use physical memory to emulate RAM (no-mapped file) */
466 case 'X':
467 vm->ram_mmap = 0;
468 break;
469
470 /* Use a ghost file to simulate RAM */
471 case 'G':
472 vm->ghost_ram_filename = strdup(optarg);
473 vm->ghost_status = VM_GHOST_RAM_USE;
474 break;
475
476 /* Generate a ghost RAM image */
477 case 'g':
478 vm->ghost_ram_filename = strdup(optarg);
479 vm->ghost_status = VM_GHOST_RAM_GENERATE;
480 break;
481
482 /* Use sparse memory */
483 case OPT_SPARSE_MEM:
484 vm->sparse_mem = TRUE;
485 break;
486
487 /* Alternate ROM */
488 case 'R':
489 vm->rom_filename = optarg;
490 break;
491
492 /* Idle PC */
493 case OPT_IDLE_PC:
494 vm->idle_pc = strtoull(optarg,NULL,0);
495 printf("Idle PC set to 0x%llx.\n",vm->idle_pc);
496 break;
497
498 /* Timer IRQ check interval */
499 case OPT_TIMER_ITV:
500 vm->timer_irq_check_itv = atoi(optarg);
501 break;
502
503 /* Clock divisor */
504 case 'k':
505 vm->clock_divisor = atoi(optarg);
506
507 if (!vm->clock_divisor) {
508 fprintf(stderr,"Invalid Clock Divisor specified!\n");
509 exit(EXIT_FAILURE);
510 }
511
512 printf("Using a clock divisor of %d.\n",vm->clock_divisor);
513 break;
514
515 /* Disable JIT */
516 case 'j':
517 vm->jit_use = FALSE;
518 break;
519
520 /* VM debug level */
521 case OPT_VM_DEBUG:
522 vm->debug_level = atoi(optarg);
523 break;
524
525 /* Log file */
526 case 'l':
527 if (!(log_file_name = strdup(optarg))) {
528 fprintf(stderr,"Unable to set log file name.\n");
529 exit(EXIT_FAILURE);
530 }
531 printf("Log file: writing to %s\n",log_file_name);
532 break;
533
534 #if DEBUG_SYM_TREE
535 /* Symbol file */
536 case 'S':
537 vm->sym_filename = strdup(optarg);
538 break;
539 #endif
540
541 /* TCP server for Console Port */
542 case 'T':
543 vm->vtty_con_type = VTTY_TYPE_TCP;
544 vm->vtty_con_tcp_port = atoi(optarg);
545 break;
546
547 /* Serial interface for Console port */
548 case 'U':
549 vm->vtty_con_type = VTTY_TYPE_SERIAL;
550 if (vtty_parse_serial_option(&vm->vtty_con_serial_option,optarg)) {
551 fprintf(stderr,
552 "Invalid Console serial interface descriptor!\n");
553 exit(EXIT_FAILURE);
554 }
555 break;
556
557 /* TCP server for AUX Port */
558 case 'A':
559 vm->vtty_aux_type = VTTY_TYPE_TCP;
560 vm->vtty_aux_tcp_port = atoi(optarg);
561 break;
562
563 /* Serial interface for AUX port */
564 case 'B':
565 vm->vtty_aux_type = VTTY_TYPE_SERIAL;
566 if (vtty_parse_serial_option(&vm->vtty_aux_serial_option,optarg)) {
567 fprintf(stderr,"Invalid AUX serial interface descriptor!\n");
568 exit(EXIT_FAILURE);
569 }
570 break;
571
572 /* Port settings */
573 case 'p':
574 vm_slot_cmd_create(vm,optarg);
575 break;
576
577 /* NIO settings */
578 case 's':
579 vm_slot_cmd_add_nio(vm,optarg);
580 break;
581
582 /* Virtual ATM switch */
583 case 'a':
584 if (atmsw_start(optarg) == -1)
585 exit(EXIT_FAILURE);
586 break;
587
588 /* Virtual Frame-Relay switch */
589 case 'f':
590 if (frsw_start(optarg) == -1)
591 exit(EXIT_FAILURE);
592 break;
593
594 /* Virtual Ethernet switch */
595 case 'E':
596 if (ethsw_start(optarg) == -1)
597 exit(EXIT_FAILURE);
598 break;
599
600 /* Virtual bridge */
601 case 'b':
602 if (netio_bridge_start(optarg) == -1)
603 exit(EXIT_FAILURE);
604 break;
605
606 #ifdef GEN_ETH
607 /* Ethernet device list */
608 case 'e':
609 gen_eth_show_dev_list();
610 exit(EXIT_SUCCESS);
611 #endif
612
613 /* Load plugin (already handled) */
614 case 'L':
615 break;
616
617 /* Oops ! */
618 case '?':
619 show_usage(vm,argc,argv);
620 exit(EXIT_FAILURE);
621
622 /* Parse options specific to the platform */
623 default:
624 if (vm->platform->cli_parse_options != NULL)
625 if (vm->platform->cli_parse_options(vm,option) == -1)
626 exit(EXIT_FAILURE);
627 }
628 }
629
630 /* Last argument, this is the IOS filename */
631 if (optind == (argc - 1)) {
632 /* setting IOS image file */
633 vm_ios_set_image(vm,argv[optind]);
634 printf("IOS image file: %s\n\n",vm->ios_image);
635 } else {
636 /* IOS missing */
637 fprintf(stderr,"Please specify an IOS image filename\n");
638 show_usage(vm,argc,argv);
639 exit(EXIT_FAILURE);
640 }
641
642 vm_release(vm);
643 return(0);
644 }
645
646 /*
647 * Run in hypervisor mode with a config file if the "-H" option
648 * is present in command line.
649 */
650 static int run_hypervisor(int argc,char *argv[])
651 {
652 char *options_list = "H:l:hN:L:";
653 int i,option;
654 char *index;
655 size_t len;
656
657 for(i=1;i<argc;i++)
658 if (!strcmp(argv[i],"-H")) {
659 hypervisor_mode = 1;
660 break;
661 }
662
663 /* standard mode with one instance */
664 if (!hypervisor_mode)
665 return(FALSE);
666
667 cli_load_plugins(argc,argv);
668
669 opterr = 0;
670 while((option = getopt(argc,argv,options_list)) != -1) {
671 switch(option)
672 {
673 /* Hypervisor TCP port */
674 case 'H':
675 index = strrchr(optarg,':');
676
677 if (!index) {
678 hypervisor_tcp_port = atoi(optarg);
679 } else {
680 len = index - optarg;
681 hypervisor_ip_address = malloc(len + 1);
682
683 if (!hypervisor_ip_address) {
684 fprintf(stderr,"Unable to set hypervisor IP address!\n");
685 exit(EXIT_FAILURE);
686 }
687
688 memcpy(hypervisor_ip_address,optarg,len);
689 hypervisor_ip_address[len] = '\0';
690 }
691 break;
692
693 /* Log file */
694 case 'l':
695 if (!(log_file_name = malloc(strlen(optarg)+1))) {
696 fprintf(stderr,"Unable to set log file name!\n");
697 exit(EXIT_FAILURE);
698 }
699 strcpy(log_file_name, optarg);
700 printf("Log file: writing to %s\n",log_file_name);
701 break;
702
703 /* VM file naming type */
704 case 'N':
705 vm_file_naming_type = atoi(optarg);
706 break;
707
708 /* Load plugin (already handled) */
709 case 'L':
710 break;
711
712 /* Oops ! */
713 case '?':
714 //show_usage(argc,argv,VM_TYPE_C7200);
715 exit(EXIT_FAILURE);
716 }
717 }
718
719 return(TRUE);
720 }
721
722 /* Delete all objects */
723 void dynamips_reset(void)
724 {
725 printf("Shutdown in progress...\n");
726
727 /* Delete all virtual router instances */
728 vm_delete_all_instances();
729
730 /* Delete ATM and Frame-Relay switches + bridges */
731 netio_bridge_delete_all();
732 atmsw_delete_all();
733 frsw_delete_all();
734 ethsw_delete_all();
735
736 /* Delete all NIO descriptors */
737 netio_delete_all();
738
739 printf("Shutdown completed.\n");
740 }
741
742 /* Default platforms */
743 static int (*platform_register[])(void) = {
744 c7200_platform_register,
745 c3600_platform_register,
746 c3725_platform_register,
747 c3745_platform_register,
748 c2691_platform_register,
749 c2600_platform_register,
750 c1700_platform_register,
751 c6sup1_platform_register,
752 c6msfc1_platform_register,
753 NULL,
754 };
755
756 /* Register default platforms */
757 static void register_default_platforms(void)
758 {
759 int i;
760
761 for(i=0;platform_register[i];i++)
762 platform_register[i]();
763 }
764
765 int main(int argc,char *argv[])
766 {
767 vm_instance_t *vm;
768
769 #ifdef PROFILE
770 atexit(profiler_savestat);
771 #endif
772
773 printf("Cisco Router Simulation Platform (version %s)\n",sw_version);
774 printf("Copyright (c) 2005-2007 Christophe Fillot.\n");
775 printf("Build date: %s %s\n\n",__DATE__,__TIME__);
776
777 /* Register platforms */
778 register_default_platforms();
779
780 /* Initialize timers */
781 timer_init();
782
783 /* Initialize object registry */
784 registry_init();
785
786 /* Initialize ATM module (for HEC checksums) */
787 atm_init();
788
789 /* Initialize CRC functions */
790 crc_init();
791
792 /* Initialize NetIO code */
793 netio_rxl_init();
794
795 /* Initialize NetIO packet filters */
796 netio_filter_load_all();
797
798 /* Initialize VTTY code */
799 vtty_init();
800
801 /* Parse standard command line */
802 if (!run_hypervisor(argc,argv))
803 parse_std_cmd_line(argc,argv);
804
805 /* Create general log file */
806 create_log_file();
807
808 /* Periodic tasks initialization */
809 if (ptask_init(0) == -1)
810 exit(EXIT_FAILURE);
811
812 /* Create instruction lookup tables */
813 mips64_jit_create_ilt();
814 mips64_exec_create_ilt();
815 ppc32_jit_create_ilt();
816 ppc32_exec_create_ilt();
817
818 setup_signals();
819
820 if (!hypervisor_mode) {
821 /* Initialize the default instance */
822 vm = vm_acquire("default");
823 assert(vm != NULL);
824
825 if (vm->platform->init_instance(vm) == -1) {
826 fprintf(stderr,"Unable to initialize router instance.\n");
827 exit(EXIT_FAILURE);
828 }
829
830 #if (DEBUG_INSN_PERF_CNT > 0) || (DEBUG_BLOCK_PERF_CNT > 0)
831 {
832 m_uint32_t counter,prev = 0,delta;
833 while(vm->status == VM_STATUS_RUNNING) {
834 counter = cpu_get_perf_counter(vm->boot_cpu);
835 delta = counter - prev;
836 prev = counter;
837 printf("delta = %u\n",delta);
838 sleep(1);
839 }
840 }
841 #else
842 /* Start instance monitoring */
843 vm_monitor(vm);
844 #endif
845
846 /* Free resources used by instance */
847 vm_release(vm);
848 } else {
849 hypervisor_tcp_server(hypervisor_ip_address,hypervisor_tcp_port);
850 }
851
852 dynamips_reset();
853 close_log_file();
854 return(0);
855 }

  ViewVC Help
Powered by ViewVC 1.1.26