Annotation of cf/dynamips.c, revision 1.1.1.1

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>
                     14: #include <sys/types.h>
                     15: #include <sys/stat.h>
                     16: #include <sys/mman.h>
                     17: #include <signal.h>
                     18: #include <fcntl.h>
                     19: #include <assert.h>
                     20: 
                     21: #include ARCH_INC_FILE
                     22: 
                     23: #include "rbtree.h"
                     24: #include "cp0.h"
                     25: #include "memory.h"
                     26: #include "cpu.h"
                     27: #include "device.h"
                     28: #include "mips64_exec.h"
                     29: #include "dev_c7200.h"
                     30: #include "dev_c7200_bay.h"
                     31: #include "dev_vtty.h"
                     32: #include "ptask.h"
                     33: #include "atm.h"
                     34: #include "net_io_bridge.h"
                     35: 
                     36: #ifdef PROFILE
                     37: #include "profiler.h"
                     38: #endif
                     39: 
                     40: /* Default name for logfile */
                     41: #define LOGFILE_DEFAULT_NAME  "pred_log0.txt"
                     42: 
                     43: /* Software version */
                     44: static const char *sw_version = "0.2.3b-"JIT_ARCH;
                     45: 
                     46: /* Log file */
                     47: FILE *log_file = NULL;
                     48: 
                     49: /* Instruction block trace (produces tons of logs!) */
                     50: int insn_itrace = 0;
                     51: 
                     52: /* JIT use */
                     53: int jit_use = JIT_SUPPORT;
                     54: 
                     55: /* VM flags */
                     56: volatile int vm_save_state = 0;
                     57: volatile int vm_running = 0;
                     58: 
                     59: /* Cisco 7200 router instance */
                     60: c7200_t c7200_router;
                     61: 
                     62: /* By default, use embedded ROM */
                     63: char *rom_filename = NULL;
                     64: 
                     65: /* RAM size (in Mb, by default 256) */
                     66: u_int ram_size = 256;
                     67: 
                     68: /* ROM size (in Mb, by default 4) */
                     69: u_int rom_size = 4;
                     70: 
                     71: /* NVRAM size (in Kb, by default 128) */
                     72: u_int nvram_size = 128;
                     73: 
                     74: /* Config register */
                     75: u_int conf_reg = 0x2102;
                     76: 
                     77: /* Clock divisor (see cp0.c) */
                     78: u_int clock_divisor = 2;
                     79: 
                     80: /* Port Adapter descriptions */
                     81: static char *pa_desc[MAX_PA_BAYS];
                     82: static int pa_index = 0;
                     83: 
                     84: /* Console port VTTY type and parameters */
                     85: int vtty_con_type = VTTY_TYPE_TERM;
                     86: int vtty_con_tcp_port;
                     87: 
                     88: /* AUX port VTTY type and parameters */
                     89: int vtty_aux_type = VTTY_TYPE_NONE;
                     90: int vtty_aux_tcp_port;
                     91: 
                     92: /* Symbols */
                     93: rbtree_tree *sym_tree = NULL;
                     94: 
                     95: /* ELF entry point */
                     96: m_uint32_t ios_entry_point;
                     97: 
                     98: /* Symbol lookup */
                     99: struct symbol *sym_lookup(m_uint64_t addr)
                    100: {
                    101:    return(rbtree_lookup(sym_tree,&addr));
                    102: }
                    103: 
                    104: /* Insert a new symbol */
                    105: struct symbol *sym_insert(char *name,m_uint64_t addr)
                    106: {
                    107:    struct symbol *sym;
                    108:    size_t len;
                    109: 
                    110:    len = strlen(name);
                    111: 
                    112:    if (!(sym = malloc(len + sizeof(*sym))))
                    113:       return NULL;
                    114:    
                    115:    memcpy(sym->name,name,len+1);
                    116:    sym->addr = addr;
                    117: 
                    118:    if (rbtree_insert(sym_tree,sym,sym) == -1) {
                    119:       free(sym);
                    120:       return NULL;
                    121:    }
                    122: 
                    123:    return sym;
                    124: }
                    125: 
                    126: /* Symbol comparison function */
                    127: static int sym_compare(m_uint64_t *a1,struct symbol *sym)
                    128: {
                    129:    if (*a1 > sym->addr)
                    130:       return(1);
                    131: 
                    132:    if (*a1 < sym->addr)
                    133:       return(-1);
                    134: 
                    135:    return(0);
                    136: }
                    137: 
                    138: /* Create the symbol tree */
                    139: int sym_create_tree(void)
                    140: {
                    141:    sym_tree = rbtree_create((tree_fcompare)sym_compare,NULL);
                    142:    return(sym_tree ? 0 : -1);
                    143: }
                    144: 
                    145: /* Generic signal handler */
                    146: void signal_gen_handler(int sig)
                    147: {
                    148:    switch(sig) {
                    149:       case SIGHUP:
                    150:          insn_itrace = 1 - insn_itrace;
                    151:          printf("Instruction block trace %sabled\n",
                    152:                 insn_itrace ? "en" : "dis");
                    153:          break;
                    154: 
                    155:       case SIGQUIT:
                    156:          /* save VM context */
                    157:          vm_save_state = TRUE;
                    158:          vm_running = FALSE;
                    159:          break;
                    160: 
                    161:       default:
                    162:          fprintf(stderr,"Unhandled signal %d\n",sig);
                    163:    }
                    164: }
                    165: 
                    166: /* Setups signals */
                    167: static void setup_signals(void)
                    168: {
                    169:    struct sigaction act;
                    170: 
                    171:    memset(&act,0,sizeof(act));
                    172:    act.sa_handler = signal_gen_handler;
                    173:    act.sa_flags = SA_RESTART;
                    174:    sigaction(SIGHUP,&act,NULL);
                    175:    sigaction(SIGQUIT,&act,NULL);
                    176: }
                    177: 
                    178: /* Load a raw image into the simulated memory */
                    179: int load_raw_image(cpu_mips_t *cpu,char *filename,m_uint64_t vaddr)
                    180: {   
                    181:    struct stat file_info;
                    182:    size_t len,clen;
                    183:    void *haddr;
                    184:    FILE *bfd;
                    185: 
                    186:    if (!(bfd = fopen(filename,"r"))) {
                    187:       perror("fopen");
                    188:       return(-1);
                    189:    }
                    190: 
                    191:    if (fstat(fileno(bfd),&file_info) == -1) {
                    192:       perror("stat");
                    193:       return(-1);
                    194:    }
                    195: 
                    196:    len = file_info.st_size;
                    197: 
                    198:    printf("Loading RAW file '%s' at virtual address 0x%llx (size=%lu)\n",
                    199:           filename,vaddr,(u_long)len);
                    200: 
                    201:    while(len > 0)
                    202:    {
                    203:       haddr = cpu->mem_op_lookup(cpu,vaddr);
                    204:    
                    205:       if (!haddr) {
                    206:          fprintf(stderr,"load_raw_image: invalid load address 0x%llx\n",
                    207:                  vaddr);
                    208:          return(-1);
                    209:       }
                    210: 
                    211:       if (len > MIPS_MIN_PAGE_SIZE)
                    212:          clen = MIPS_MIN_PAGE_SIZE;
                    213:       else
                    214:          clen = len;
                    215: 
                    216:       clen = fread((u_char *)haddr,clen,1,bfd);
                    217: 
                    218:       if (clen != 1)
                    219:          break;
                    220:       
                    221:       vaddr += MIPS_MIN_PAGE_SIZE;
                    222:       len -= clen;
                    223:    }
                    224:    
                    225:    fclose(bfd);
                    226:    return(0);
                    227: }
                    228: 
                    229: /* Load an ELF image into the simulated memory */
                    230: int load_elf_image(cpu_mips_t *cpu,char *filename,m_uint32_t *entry_point)
                    231: {
                    232:    m_uint64_t vaddr;
                    233:    void *haddr;
                    234:    Elf32_Ehdr *ehdr;
                    235:    Elf32_Phdr *phdr;
                    236:    Elf *img_elf;
                    237:    size_t len,clen;
                    238:    int i,fd;
                    239:    FILE *bfd;
                    240:    
                    241:    if ((fd = open(filename,O_RDONLY)) == -1)
                    242:       return(-1);
                    243: 
                    244:    if (elf_version(EV_CURRENT) == EV_NONE) {
                    245:       fprintf(stderr,"load_elf_image: library out of date\n");
                    246:       return(-1);
                    247:    }
                    248: 
                    249:    if (!(img_elf = elf_begin(fd,ELF_C_READ,NULL))) {
                    250:       fprintf(stderr,"load_elf_image: elf_begin: %s\n",
                    251:               elf_errmsg(elf_errno()));
                    252:       return(-1);
                    253:    }
                    254: 
                    255:    if (!(phdr = elf32_getphdr(img_elf))) {
                    256:       fprintf(stderr,"load_elf_image: elf32_getphdr: %s\n",
                    257:               elf_errmsg(elf_errno()));
                    258:       return(-1);
                    259:    }
                    260: 
                    261:    ehdr = elf32_getehdr(img_elf);
                    262:    phdr = elf32_getphdr(img_elf);
                    263: 
                    264:    printf("Loading ELF file '%s'...\n",filename);
                    265:    bfd = fdopen(fd,"rb");
                    266: 
                    267:    if (!bfd) {
                    268:       perror("load_elf_image: fdopen");
                    269:       return(-1);
                    270:    }
                    271: 
                    272:    for(i=0;i<ehdr->e_phnum;i++,phdr++)
                    273:    {
                    274:       fseek(bfd,phdr->p_offset,SEEK_SET);
                    275: 
                    276:       vaddr = (m_uint64_t)phdr->p_vaddr;
                    277:       len = phdr->p_filesz;
                    278: 
                    279:       printf("   * Adding section at virtual address 0x%llx\n",vaddr);
                    280: 
                    281:       while(len > 0)
                    282:       {
                    283:          haddr = cpu->mem_op_lookup(cpu,vaddr);
                    284:    
                    285:          if (!haddr) {
                    286:             fprintf(stderr,"load_elf_image: invalid load address 0x%llx\n",
                    287:                     vaddr);
                    288:             return(-1);
                    289:          }
                    290: 
                    291:          if (len > MIPS_MIN_PAGE_SIZE)
                    292:             clen = MIPS_MIN_PAGE_SIZE;
                    293:          else
                    294:             clen = len;
                    295: 
                    296:          clen = fread((u_char *)haddr,clen,1,bfd);
                    297: 
                    298:          if (clen != 1)
                    299:             break;
                    300: 
                    301:          vaddr += MIPS_MIN_PAGE_SIZE;
                    302:          len -= clen;
                    303:       }
                    304:    }
                    305: 
                    306:    printf("ELF entry point: 0x%x\n",ehdr->e_entry);
                    307: 
                    308:    if (entry_point)
                    309:       *entry_point = ehdr->e_entry;
                    310: 
                    311:    return(0);
                    312: }
                    313: 
                    314: /* Load a symbol file */
                    315: int load_sym_file(char *filename)
                    316: {
                    317:    char buffer[4096],func_name[128];
                    318:    m_uint64_t addr;
                    319:    char sym_type;
                    320:    FILE *fd;
                    321: 
                    322:    if ((!sym_tree) && (sym_create_tree() == -1)) {
                    323:       fprintf(stderr,"Unable to create symbol tree.\n");
                    324:       return(-1);
                    325:    }
                    326: 
                    327:    if (!(fd = fopen(filename,"r"))) {
                    328:       perror("load_sym_file: fopen");
                    329:       return(-1);
                    330:    }
                    331: 
                    332:    while(!feof(fd)) {
                    333:       fgets(buffer,sizeof(buffer),fd);
                    334: 
                    335:       if (sscanf(buffer,"%llx %c %s",&addr,&sym_type,func_name) == 3) {
                    336:          sym_insert(func_name,addr);
                    337:       }
                    338:    }
                    339: 
                    340:    fclose(fd);
                    341:    return(0);
                    342: }
                    343: 
                    344: /* Display the command line use */
                    345: static void show_usage(int argc,char *argv[])
                    346: {
                    347:    printf("Usage: %s [options] <ios_image>\n\n",argv[0]);
                    348:    
                    349:    printf("Available options:\n"
                    350:           "  -r <ram_size>   : Set the virtual RAM size (default is %d Mb)\n"
                    351:           "  -o <rom_size>   : Set the virtual ROM size (default is %d Mb)\n"
                    352:           "  -n <nvram_size> : Set the NVRAM size (default is %d Kb)\n"
                    353:           "  -l <log_file>   : Set logging file (default is %s)\n"
                    354:           "  -C <cfg_file>   : Import an IOS configuration file into NVRAM\n"
                    355:           "  -R <rom_file>   : Load an alternate ROM (default is embedded)\n"
                    356:           "  -s <sym_file>   : Load symbol file\n"
                    357:           "  -c <conf_reg>   : Set the configuration register "
                    358:           "(default is 0x%04x)\n"
                    359:           "  -m <mac_addr>   : Set the MAC address of the chassis "
                    360:           "(IOS chooses default)\n"
                    361:           "  -k <clock_div>  : Set the clock divisor (default is %d)\n"
                    362:           "  -T <port>       : Console is on TCP <port> "
                    363:           "(default is on the terminal)\n"
                    364:           "  -A <port>       : AUX is on TCP <port> (default is no AUX port)\n"
                    365:           "  -i              : Instruction block trace, very slow\n"
                    366:           "  -j              : Disable the JIT compiler, very slow\n"
                    367:           "  -t <npe_type>   : Select NPE type\n"
                    368:           "  -M <midplane>   : Select Midplane (\"std\" or \"vxr\")\n"
                    369:           "  -p <pa_desc>    : Define a Port Adapter\n"
                    370:           "  -a <cfg_file>   : Virtual ATM switch configuration file\n"
                    371:           "  -b <cfg_file>   : Virtual bridge configuration file\n"
                    372:           "\n",
                    373:           ram_size,rom_size,nvram_size,LOGFILE_DEFAULT_NAME,
                    374:           conf_reg,clock_divisor);
                    375: 
                    376:    printf("<pa_desc> format:\n"
                    377:           "   \"slot:pa_driver:netio_type{:netio_parameters}\"\n"
                    378:           "\n");
                    379:    
                    380:    /* Show the possible NPE drivers */
                    381:    c7200_npe_show_drivers();
                    382: 
                    383:    /* Show the possible PA drivers */
                    384:    c7200_pa_show_drivers();
                    385: 
                    386:    /* Show the possible NETIO types */
                    387:    netio_show_types();
                    388: }
                    389: 
                    390: int main(int argc,char *argv[])
                    391: {
                    392:    char *options_list = "r:o:n:c:m:l:C:ijt:p:k:T:A:a:b:s:R:M:";
                    393:    char *log_file_name = NULL;
                    394:    char *ios_image_name;
                    395:    char *ios_cfg_file = NULL;
                    396:    char *mac_addr = NULL;
                    397:    int option;
                    398:    cpu_mips_t *cpu0;
                    399:    m_uint32_t rom_entry_point;
                    400: 
                    401: #ifdef PROFILE
                    402:    atexit(profiler_savestat);
                    403: #endif
                    404: 
                    405:    printf("Cisco 7200 Simulation Platform (version %s)\n",sw_version);
                    406:    printf("Copyright (c) 2005,2006 Christophe Fillot.\n\n");
                    407: 
                    408:    memset(&c7200_router,0,sizeof(c7200_router));
                    409: 
                    410:    /* Initialize ATM code */
                    411:    atm_init();
                    412: 
                    413:    /* Command line arguments : early try */
                    414:    opterr = 0;
                    415: 
                    416:    while((option = getopt(argc,argv,options_list)) != -1) {
                    417:       switch(option)
                    418:       {
                    419:          /* RAM size */
                    420:          case 'r':
                    421:             ram_size = strtol(optarg, NULL, 10);
                    422:             printf("Virtual RAM size set to %d MB.\n",ram_size);
                    423:             break;
                    424: 
                    425:          /* ROM size */
                    426:          case 'o':
                    427:             rom_size = strtol(optarg, NULL, 10);
                    428:             printf("Virtual ROM size set to %d MB.\n",rom_size);
                    429:             break;
                    430: 
                    431:          /* NVRAM size */
                    432:          case 'n':
                    433:             nvram_size = strtol(optarg, NULL, 10);
                    434:             printf("NVRAM size set to %d KB.\n", nvram_size);
                    435:             break;
                    436: 
                    437:          /* Config Register */
                    438:          case 'c':
                    439:             conf_reg = strtol(optarg, NULL, 0);
                    440:             printf("Config. Register set to 0x%x.\n",conf_reg);
                    441:             break;
                    442: 
                    443:          /* Set the base MAC address */
                    444:          case 'm':
                    445:             mac_addr = optarg;
                    446:             printf("MAC address set to '%s'.\n",mac_addr);
                    447:             break;
                    448: 
                    449:          /* Log file */
                    450:          case 'l':
                    451:             if (!(log_file_name = malloc(strlen(optarg)+1))) {
                    452:                fprintf(stderr,"Unable to set log file name.\n");
                    453:                exit(EXIT_FAILURE);
                    454:             }
                    455:             strcpy(log_file_name, optarg);
                    456:             printf("Log file: writing to %s\n",log_file_name);
                    457:             break;
                    458: 
                    459:          /* IOS configuration file */
                    460:          case 'C':
                    461:             ios_cfg_file = optarg;
                    462:             break;
                    463: 
                    464:          /* Alternate ROM */
                    465:          case 'R':
                    466:             rom_filename = optarg;
                    467:             break;
                    468: 
                    469:          /* Symbol file */
                    470:          case 's':
                    471:             load_sym_file(optarg);
                    472:             break;
                    473:             
                    474:          /* Instruction block trace */
                    475:          case 'i':
                    476:             insn_itrace = TRUE;
                    477:             break;
                    478:          
                    479:          /* Disable JIT */
                    480:          case 'j':
                    481:             jit_use = FALSE;
                    482:             break;
                    483: 
                    484:          /* NPE type */
                    485:          case 't':
                    486:             c7200_router.npe_type = optarg;
                    487:             break;
                    488: 
                    489:          /* Midplane type */
                    490:          case 'M':
                    491:             c7200_router.midplane_type = optarg;
                    492:             break;
                    493:             
                    494:          /* PA settings */
                    495:          case 'p':
                    496:             if (pa_index == MAX_PA_BAYS)
                    497:                fprintf(stderr,"All PA slots are filled.\n");               
                    498:             else
                    499:                pa_desc[pa_index++] = optarg;
                    500:             break;
                    501: 
                    502:          /* Clock divisor */
                    503:          case 'k':
                    504:             clock_divisor = atoi(optarg);
                    505: 
                    506:             if (!clock_divisor) {
                    507:                fprintf(stderr,"Invalid Clock Divisor specified!\n");
                    508:                exit(EXIT_FAILURE);
                    509:             }
                    510: 
                    511:             printf("Using a clock divisor of %d.\n",clock_divisor);
                    512:             break;
                    513: 
                    514:          /* TCP server for Console Port */
                    515:          case 'T':
                    516:             vtty_con_type = VTTY_TYPE_TCP;
                    517:             vtty_con_tcp_port = atoi(optarg);
                    518:             break;
                    519: 
                    520:          /* TCP server for AUX Port */
                    521:          case 'A':
                    522:             vtty_aux_type = VTTY_TYPE_TCP;
                    523:             vtty_aux_tcp_port = atoi(optarg);
                    524:             break;
                    525: 
                    526:          /* Virtual ATM switch */
                    527:          case 'a':
                    528:             if (atmsw_start(optarg) == -1)
                    529:                exit(EXIT_FAILURE);
                    530:             break;
                    531: 
                    532:          /* Virtual bridge */
                    533:          case 'b':
                    534:             if (netio_bridge_start(optarg) == -1)
                    535:                exit(EXIT_FAILURE);
                    536:             break;
                    537: 
                    538:          /* Oops ! */
                    539:          case '?':
                    540:             show_usage(argc,argv);
                    541:             exit(EXIT_FAILURE);
                    542:       }
                    543:    }
                    544: 
                    545:    /* Last argument, this is the IOS filename */
                    546:    if (optind == (argc - 1)) {
                    547:       /* setting IOS image file        */
                    548:       ios_image_name = argv[optind];
                    549:       printf("IOS image file: %s\n\n", ios_image_name);
                    550:    } else { 
                    551:       /* IOS missing */
                    552:       fprintf(stderr,"Please specify an IOS image filename\n");
                    553:       show_usage(argc,argv);
                    554:       exit(EXIT_FAILURE);
                    555:    }
                    556: 
                    557:    /* Set the default value of the log file name */
                    558:    if (!log_file_name) {
                    559:       if (!(log_file_name = malloc(strlen(LOGFILE_DEFAULT_NAME)+1))) {
                    560:          fprintf(stderr,"Unable to set log file name.\n");
                    561:          exit(EXIT_FAILURE);
                    562:       }
                    563:       strcpy(log_file_name,LOGFILE_DEFAULT_NAME);
                    564:    }
                    565: 
                    566:    if (!(log_file = fopen(log_file_name,"w"))) {
                    567:       fprintf(stderr,"Unable to create log file.\n");
                    568:       exit(EXIT_FAILURE);
                    569:    }
                    570: 
                    571:    /* Periodic tasks initialization */
                    572:    if (ptask_init(0) == -1)
                    573:       exit(EXIT_FAILURE);
                    574: 
                    575:    /* Create instruction lookup tables */
                    576:    mips64_jit_create_ilt();
                    577:    mips64_exec_create_ilt();
                    578: 
                    579:    /* Create a CPU group */
                    580:    sys_cpu_group = cpu_group_create("System CPU Group");
                    581: 
                    582:    /* Initialize the virtual MIPS processor */
                    583:    if (!(cpu0 = cpu_create(0))) {
                    584:       fprintf(stderr,"Unable to create CPU0!\n");
                    585:       exit(EXIT_FAILURE);
                    586:    }
                    587: 
                    588:    /* Add this CPU to the system CPU group */
                    589:    cpu_group_add(sys_cpu_group,cpu0);
                    590:    c7200_router.cpu_group = sys_cpu_group;
                    591: 
                    592:    /* Initialize the C7200 platform */
                    593:    if (c7200_init_platform(&c7200_router,pa_desc,mac_addr) == -1) {
                    594:       fprintf(stderr,"Unable to initialize the C7200 platform hardware.\n");
                    595:       exit(EXIT_FAILURE);
                    596:    }
                    597: 
                    598:    /* Load IOS configuration file */
                    599:    if (ios_cfg_file != NULL) {
                    600:       dev_nvram_push_config(sys_cpu_group,ios_cfg_file);
                    601:       conf_reg &= ~0x40;
                    602:    }
                    603: 
                    604:    /* Load ROM (ELF image or embedded) */
                    605:    rom_entry_point = 0xbfc00000;
                    606: 
                    607:    if (rom_filename) {
                    608:       if (load_elf_image(cpu0,rom_filename,&rom_entry_point) < 0) {
                    609:          fprintf(stderr,"Unable to load alternate ROM '%s', "
                    610:                  "fallback to embedded ROM.\n\n",rom_filename);
                    611:          rom_filename = NULL;
                    612:       }
                    613:    }
                    614: 
                    615:    /* Load IOS image */
                    616:    if (load_elf_image(cpu0,ios_image_name,&ios_entry_point) < 0) {
                    617:       fprintf(stderr,"Cisco IOS load failed.\n");
                    618:       exit(EXIT_FAILURE);
                    619:    }
                    620: 
                    621:    cpu0->pc = sign_extend(rom_entry_point,32);
                    622:    cpu0->cp0.reg[MIPS_CP0_PRID] = 0x2012ULL;
                    623:    cpu0->cp0.reg[MIPS_CP0_CONFIG] = 0x00c08ff0ULL;
                    624: 
                    625:    setup_signals();
                    626: 
                    627:    /* Launch the simulation */
                    628:    printf("\nStarting simulation (CPU0 PC=0x%llx), JIT is %sabled.\n",
                    629:           cpu0->pc,jit_use ? "en":"dis");
                    630: 
                    631:    cpu_start(cpu0);
                    632: 
                    633:    /* Run until all CPU of the system CPU group are halted */
                    634:    while(!cpu_group_check_state(sys_cpu_group,MIPS_CPU_HALTED))
                    635:       usleep(200000);
                    636: 
                    637:    printf("\n\nSimulation halted (CPU0 PC=0x%llx).\n\n",cpu0->pc);
                    638:    return(0);
                    639: }

unix.superglobalmegacorp.com

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