/[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 7 - (show annotations)
Sat Oct 6 16:23:47 2007 UTC (16 years, 5 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 /*
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 "ppc32_vmtest.h"
36 #include "dev_vtty.h"
37 #include "ptask.h"
38 #include "timer.h"
39 #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 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 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 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 " -H <tcp_port> : Run in hypervisor mode\n\n"
231 " -P <platform> : Platform to emulate (7200, 3600, "
232 "2691, 3725 or 3745) "
233 "(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 " -G <ghost_file> : Use a ghost file to simulate RAM\n"
252 " -g <ghost_file> : Generate a ghost RAM file\n"
253 " --sparse-mem : Use sparse memory\n"
254 " -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
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
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 }
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 /* Show the possible NM drivers */
374 c3600_nm_show_drivers();
375 break;
376
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
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 }
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 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 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 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 #define OPT_SPARSE_MEM 0x107
498
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 { "sparse-mem" , 0, NULL, OPT_SPARSE_MEM },
508 { 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 /* 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 /* 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 /* Create a router instance */
707 static vm_instance_t *cli_create_instance(char *name,int platform_type,
708 int instance_id)
709 {
710 vm_instance_t *vm;
711 c7200_t *c7200;
712 c3600_t *c3600;
713 c2691_t *c2691;
714 c3725_t *c3725;
715 c3745_t *c3745;
716 c2600_t *c2600;
717
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 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 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 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 "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 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 /* 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 /* Use sparse memory */
886 case OPT_SPARSE_MEM:
887 vm->sparse_mem = TRUE;
888 break;
889
890 /* 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 break;
1022 case VM_TYPE_C2691:
1023 res = cli_parse_c2691_options(vm,option);
1024 break;
1025 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 case VM_TYPE_C2600:
1032 res = cli_parse_c2600_options(vm,option);
1033 break;
1034 }
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 /* Delete all virtual router instances */
1116 c7200_delete_all_instances();
1117 c3600_delete_all_instances();
1118 c2691_delete_all_instances();
1119 c3725_delete_all_instances();
1120 c3745_delete_all_instances();
1121 c2600_delete_all_instances();
1122 ppc32_vmtest_delete_all_instances();
1123
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 printf("Cisco Router Simulation Platform (version %s)\n",sw_version);
1149 printf("Copyright (c) 2005-2007 Christophe Fillot.\n");
1150 printf("Build date: %s %s\n\n",__DATE__,__TIME__);
1151
1152 /* Initialize timers */
1153 timer_init();
1154
1155 /* 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 ppc32_jit_create_ilt();
1188 ppc32_exec_create_ilt();
1189
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 break;
1204 case VM_TYPE_C2691:
1205 res = c2691_init_instance(VM_C2691(vm));
1206 break;
1207 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 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 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 #if (DEBUG_INSN_PERF_CNT > 0) || (DEBUG_BLOCK_PERF_CNT > 0)
1229 {
1230 m_uint64_t counter,prev = 0,delta;
1231 while(vm->status == VM_STATUS_RUNNING) {
1232 counter = cpu_get_perf_counter(vm->boot_cpu);
1233 delta = counter - prev;
1234 prev = counter;
1235 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