1 |
/* |
/* |
2 |
* Cisco 7200 (Predator) simulation platform. |
* Cisco router simulation platform. |
3 |
* Copyright (c) 2005,2006 Christophe Fillot (cf@utc.fr) |
* Copyright (c) 2005,2006 Christophe Fillot (cf@utc.fr) |
4 |
* |
* |
5 |
* Virtual console TTY. |
* Virtual console TTY. |
27 |
|
|
28 |
#include <arpa/telnet.h> |
#include <arpa/telnet.h> |
29 |
|
|
30 |
#include "mips64.h" |
#include "utils.h" |
|
#include "cp0.h" |
|
31 |
#include "cpu.h" |
#include "cpu.h" |
32 |
|
#include "vm.h" |
33 |
#include "dynamips.h" |
#include "dynamips.h" |
34 |
#include "mips64_exec.h" |
#include "mips64_exec.h" |
35 |
|
#include "ppc32_exec.h" |
36 |
#include "device.h" |
#include "device.h" |
37 |
#include "memory.h" |
#include "memory.h" |
38 |
#include "dev_c7200.h" |
#include "dev_c7200.h" |
39 |
#include "dev_c3600.h" |
#include "dev_c3600.h" |
40 |
|
#include "dev_c2691.h" |
41 |
|
#include "dev_c3725.h" |
42 |
|
#include "dev_c3745.h" |
43 |
|
#include "dev_c2600.h" |
44 |
#include "dev_vtty.h" |
#include "dev_vtty.h" |
|
#include "vm.h" |
|
|
#include "utils.h" |
|
45 |
|
|
46 |
/* VTTY list */ |
/* VTTY list */ |
47 |
static pthread_mutex_t vtty_list_mutex = PTHREAD_MUTEX_INITIALIZER; |
static pthread_mutex_t vtty_list_mutex = PTHREAD_MUTEX_INITIALIZER; |
592 |
return(-1); |
return(-1); |
593 |
} |
} |
594 |
|
|
595 |
|
/* Remote control for MIPS64 processors */ |
596 |
|
static int remote_control_mips64(vtty_t *vtty,char c,cpu_mips_t *cpu) |
597 |
|
{ |
598 |
|
switch(c) { |
599 |
|
/* Show information about JIT compiled pages */ |
600 |
|
case 'b': |
601 |
|
printf("\nCPU0: %u JIT compiled pages [Exec Area Pages: %lu/%lu]\n", |
602 |
|
cpu->compiled_pages, |
603 |
|
(u_long)cpu->exec_page_alloc, |
604 |
|
(u_long)cpu->exec_page_count); |
605 |
|
break; |
606 |
|
|
607 |
|
/* Non-JIT mode statistics */ |
608 |
|
case 'j': |
609 |
|
mips64_dump_stats(cpu); |
610 |
|
break; |
611 |
|
|
612 |
|
default: |
613 |
|
return(FALSE); |
614 |
|
} |
615 |
|
|
616 |
|
return(TRUE); |
617 |
|
} |
618 |
|
|
619 |
|
/* Remote control for PPC32 processors */ |
620 |
|
static int remote_control_ppc32(vtty_t *vtty,char c,cpu_ppc_t *cpu) |
621 |
|
{ |
622 |
|
switch(c) { |
623 |
|
/* Show information about JIT compiled pages */ |
624 |
|
case 'b': |
625 |
|
printf("\nCPU0: %u JIT compiled pages [Exec Area Pages: %lu/%lu]\n", |
626 |
|
cpu->compiled_pages, |
627 |
|
(u_long)cpu->exec_page_alloc, |
628 |
|
(u_long)cpu->exec_page_count); |
629 |
|
break; |
630 |
|
|
631 |
|
/* Non-JIT mode statistics */ |
632 |
|
case 'j': |
633 |
|
ppc32_dump_stats(cpu); |
634 |
|
break; |
635 |
|
|
636 |
|
default: |
637 |
|
return(FALSE); |
638 |
|
} |
639 |
|
|
640 |
|
return(TRUE); |
641 |
|
} |
642 |
|
|
643 |
/* Process remote control char */ |
/* Process remote control char */ |
644 |
static void remote_control(vtty_t *vtty,u_char c) |
static void remote_control(vtty_t *vtty,u_char c) |
645 |
{ |
{ |
646 |
vm_instance_t *vm = vtty->vm; |
vm_instance_t *vm = vtty->vm; |
647 |
cpu_mips_t *cpu0 = cpu_group_find_id(vm->cpu_group,0); |
cpu_gen_t *cpu0; |
648 |
|
|
649 |
|
cpu0 = vm->boot_cpu; |
650 |
|
|
651 |
|
/* Specific commands for the different CPU models */ |
652 |
|
if (cpu0) { |
653 |
|
switch(cpu0->type) { |
654 |
|
case CPU_TYPE_MIPS64: |
655 |
|
if (remote_control_mips64(vtty,c,CPU_MIPS64(cpu0))) |
656 |
|
return; |
657 |
|
break; |
658 |
|
case CPU_TYPE_PPC32: |
659 |
|
if (remote_control_ppc32(vtty,c,CPU_PPC32(cpu0))) |
660 |
|
return; |
661 |
|
break; |
662 |
|
} |
663 |
|
} |
664 |
|
|
665 |
switch(c) { |
switch(c) { |
666 |
/* Show the object list */ |
/* Show the object list */ |
667 |
case 'o': |
case 'o': |
675 |
|
|
676 |
/* Reboot the C7200 */ |
/* Reboot the C7200 */ |
677 |
case 'k': |
case 'k': |
678 |
|
#if 0 |
679 |
if (vm->type == VM_TYPE_C7200) |
if (vm->type == VM_TYPE_C7200) |
680 |
c7200_boot_ios(VM_C7200(vm)); |
c7200_boot_ios(VM_C7200(vm)); |
681 |
|
#endif |
682 |
break; |
break; |
683 |
|
|
684 |
/* Show the device list */ |
/* Show the device list */ |
690 |
|
|
691 |
/* Show info about Port Adapters or Network Modules */ |
/* Show info about Port Adapters or Network Modules */ |
692 |
case 'p': |
case 'p': |
693 |
switch(vm->type) { |
vm_slot_show_all_info(vm); |
|
case VM_TYPE_C3600: |
|
|
c3600_nm_show_all_info(VM_C3600(vm)); |
|
|
break; |
|
|
case VM_TYPE_C7200: |
|
|
c7200_pa_show_all_info(VM_C7200(vm)); |
|
|
break; |
|
|
} |
|
694 |
break; |
break; |
695 |
|
|
696 |
/* Dump the MIPS registers */ |
/* Dump the MIPS registers */ |
697 |
case 'r': |
case 'r': |
698 |
if (cpu0) mips64_dump_regs(cpu0); |
if (cpu0) cpu0->reg_dump(cpu0); |
699 |
break; |
break; |
700 |
|
|
701 |
/* Dump the latest memory accesses */ |
/* Dump the latest memory accesses */ |
702 |
case 'm': |
case 'm': |
703 |
if (cpu0) memlog_dump(cpu0); |
if (cpu0) memlog_dump(cpu0); |
704 |
break; |
break; |
705 |
|
|
706 |
/* Suspend CPU emulation */ |
/* Suspend CPU emulation */ |
707 |
case 's': |
case 's': |
708 |
vm_suspend(vm); |
vm_suspend(vm); |
713 |
vm_resume(vm); |
vm_resume(vm); |
714 |
break; |
break; |
715 |
|
|
716 |
/* Dump the MIPS TLB */ |
/* Dump the MMU information */ |
717 |
case 't': |
case 't': |
718 |
if (cpu0) tlb_dump(cpu0); |
if (cpu0) cpu0->mmu_dump(cpu0); |
719 |
break; |
break; |
720 |
|
|
721 |
/* Dump the MIPS TLB (raw mode) */ |
/* Dump the MMU information (raw mode) */ |
722 |
case 'z': |
case 'z': |
723 |
if (cpu0) tlb_raw_dump(cpu0); |
if (cpu0) cpu0->mmu_raw_dump(cpu0); |
724 |
break; |
break; |
725 |
|
|
726 |
/* Show information about JIT compiled pages */ |
/* Memory translation cache statistics */ |
|
case 'b': |
|
|
if (cpu0) { |
|
|
printf("\nCPU0: %u JIT compiled pages " |
|
|
"[Exec Area Pages: %lu/%lu]\n", |
|
|
cpu0->compiled_pages, |
|
|
(u_long)cpu0->exec_page_alloc, |
|
|
(u_long)cpu0->exec_page_count); |
|
|
} |
|
|
break; |
|
|
|
|
|
/* MTS64 cache statistics */ |
|
727 |
case 'l': |
case 'l': |
728 |
if (cpu0) { |
if (cpu0) cpu0->mts_show_stats(cpu0); |
|
cpu0->mts_show_stats(cpu0); |
|
|
} |
|
729 |
break; |
break; |
730 |
|
|
731 |
/* Extract the configuration from the NVRAM */ |
/* Extract the configuration from the NVRAM */ |
732 |
case 'c': |
case 'c': |
733 |
vm_ios_save_config(vm); |
vm_ios_save_config(vm); |
734 |
break; |
break; |
735 |
|
|
|
/* Non-JIT mode statistics */ |
|
|
case 'j': |
|
|
if (cpu0) mips64_dump_stats(cpu0); |
|
|
break; |
|
|
|
|
736 |
/* Determine an idle pointer counter */ |
/* Determine an idle pointer counter */ |
737 |
case 'i': |
case 'i': |
738 |
if (cpu0) { |
if (cpu0) |
739 |
mips64_get_idling_pc(cpu0); |
cpu0->get_idling_pc(cpu0); |
|
} |
|
740 |
break; |
break; |
741 |
|
|
742 |
/* Experimentations / Tests */ |
/* Experimentations / Tests */ |
743 |
case 'x': |
case 'x': |
744 |
if (cpu0) { |
if (cpu0) { |
745 |
/* IRQ triggering */ |
/* IRQ triggering */ |
746 |
mips64_set_irq(cpu0,2/*C7200_PA_MGMT_IRQ*/); |
//vm_set_irq(vm,5); |
747 |
//mips64_set_irq(cpu0,3/*C7200_PA_MGMT_IRQ*/); |
|
748 |
//mips64_set_irq(cpu0,C7200_PA_MGMT_IRQ); |
CPU_MIPS64(cpu0)->irq_disable = TRUE; |
749 |
|
} |
750 |
|
break; |
751 |
|
|
752 |
|
case 'y': |
753 |
|
if (cpu0) { |
754 |
|
/* IRQ clearing */ |
755 |
|
vm_clear_irq(vm,5); |
756 |
} |
} |
757 |
break; |
break; |
758 |
|
|
767 |
|
|
768 |
printf("o - Show the VM object list\n" |
printf("o - Show the VM object list\n" |
769 |
"d - Show the device list\n" |
"d - Show the device list\n" |
770 |
"r - Dump MIPS CPU registers\n" |
"r - Dump CPU registers\n" |
771 |
"t - Dump MIPS TLB entries\n" |
"t - Dump MMU information\n" |
772 |
"z - Dump MIPS TLB entries (raw mode)\n" |
"z - Dump MMU information (raw mode)\n" |
773 |
"m - Dump the latest memory accesses\n" |
"m - Dump the latest memory accesses\n" |
774 |
"s - Suspend CPU emulation\n" |
"s - Suspend CPU emulation\n" |
775 |
"u - Resume CPU emulation\n" |
"u - Resume CPU emulation\n" |
776 |
"q - Quit the emulator\n" |
"q - Quit the emulator\n" |
777 |
"k - Reboot the virtual machine\n" |
"k - Reboot the virtual machine\n" |
778 |
"b - Show info about JIT compiled pages\n" |
"b - Show info about JIT compiled pages\n" |
779 |
"l - MTS64 cache statistics\n" |
"l - MTS cache statistics\n" |
780 |
"c - Write IOS configuration to disk\n" |
"c - Write IOS configuration to disk\n" |
781 |
"j - Non-JIT mode statistics\n" |
"j - Non-JIT mode statistics\n" |
782 |
"i - Determine an idling pointer counter\n" |
"i - Determine an idling pointer counter\n" |
969 |
return(res); |
return(res); |
970 |
} |
} |
971 |
|
|
972 |
/* put char to vtty */ |
/* Put char to vtty */ |
973 |
void vtty_put_char(vtty_t *vtty, char ch) |
void vtty_put_char(vtty_t *vtty, char ch) |
974 |
{ |
{ |
975 |
switch(vtty->type) { |
switch(vtty->type) { |
1002 |
} |
} |
1003 |
} |
} |
1004 |
|
|
1005 |
|
/* Put a buffer to vtty */ |
1006 |
|
void vtty_put_buffer(vtty_t *vtty,char *buf,size_t len) |
1007 |
|
{ |
1008 |
|
size_t i; |
1009 |
|
|
1010 |
|
for(i=0;i<len;i++) |
1011 |
|
vtty_put_char(vtty,buf[i]); |
1012 |
|
} |
1013 |
|
|
1014 |
/* Flush VTTY output */ |
/* Flush VTTY output */ |
1015 |
void vtty_flush(vtty_t *vtty) |
void vtty_flush(vtty_t *vtty) |
1016 |
{ |
{ |
1017 |
switch(vtty->type) { |
switch(vtty->type) { |
1018 |
case VTTY_TYPE_TERM: |
case VTTY_TYPE_TERM: |
1019 |
case VTTY_TYPE_TCP: |
case VTTY_TYPE_TCP: |
1020 |
if (vtty->fstream) |
if (vtty->fstream != NULL) |
1021 |
fflush(vtty->fstream); |
fflush(vtty->fstream); |
1022 |
break; |
break; |
1023 |
|
|
1024 |
case VTTY_TYPE_SERIAL: |
case VTTY_TYPE_SERIAL: |
1025 |
fsync(vtty->fd); |
if (vtty->fd != -1) |
1026 |
|
fsync(vtty->fd); |
1027 |
break; |
break; |
1028 |
} |
} |
1029 |
} |
} |