Annotation of cf/dynamips.c, revision 1.1.1.5

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.