Changes in kernel/generic/src/console/cmd.c [cb3d641a:0b0f4bb] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/console/cmd.c
rcb3d641a r0b0f4bb 46 46 #include <print.h> 47 47 #include <panic.h> 48 #include < arch/types.h>48 #include <typedefs.h> 49 49 #include <adt/list.h> 50 50 #include <arch.h> 51 51 #include <config.h> 52 52 #include <func.h> 53 #include <str ing.h>53 #include <str.h> 54 54 #include <macros.h> 55 55 #include <debug.h> … … 66 66 #include <ipc/irq.h> 67 67 #include <ipc/event.h> 68 #include <sysinfo/sysinfo.h> 68 69 #include <symtab.h> 69 70 #include <errno.h> … … 107 108 108 109 #ifdef CONFIG_TEST 109 static int cmd_tests(cmd_arg_t *argv);110 static cmd_info_t tests_info = {111 .name = "tests",112 .description = "Print available kernel tests.",113 .func = cmd_tests,114 .argc = 0115 };116 117 110 static char test_buf[MAX_CMDLINE + 1]; 118 111 static int cmd_test(cmd_arg_t *argv); 119 112 static cmd_arg_t test_argv[] = { 120 113 { 121 .type = ARG_TYPE_STRING ,114 .type = ARG_TYPE_STRING_OPTIONAL, 122 115 .buffer = test_buf, 123 116 .len = sizeof(test_buf) … … 126 119 static cmd_info_t test_info = { 127 120 .name = "test", 128 .description = " Run kerneltest.",121 .description = "Print list of kernel tests or run a test.", 129 122 .func = cmd_test, 130 123 .argc = 1, … … 206 199 }; 207 200 208 /* Data and methods for 'call0' command. */201 /* Data and methods for 'call0' and 'mcall0' command. */ 209 202 static char call0_buf[MAX_CMDLINE + 1]; 210 203 static char carg1_buf[MAX_CMDLINE + 1]; … … 354 347 }; 355 348 349 static char flag_buf[MAX_CMDLINE + 1]; 350 356 351 static int cmd_threads(cmd_arg_t *argv); 352 static cmd_arg_t threads_argv = { 353 .type = ARG_TYPE_STRING_OPTIONAL, 354 .buffer = flag_buf, 355 .len = sizeof(flag_buf) 356 }; 357 357 static cmd_info_t threads_info = { 358 358 .name = "threads", 359 .description = "List all threads .",359 .description = "List all threads (use -a for additional information).", 360 360 .func = cmd_threads, 361 .argc = 0 361 .argc = 1, 362 .argv = &threads_argv 362 363 }; 363 364 364 365 static int cmd_tasks(cmd_arg_t *argv); 366 static cmd_arg_t tasks_argv = { 367 .type = ARG_TYPE_STRING_OPTIONAL, 368 .buffer = flag_buf, 369 .len = sizeof(flag_buf) 370 }; 365 371 static cmd_info_t tasks_info = { 366 372 .name = "tasks", 367 .description = "List all tasks .",373 .description = "List all tasks (use -a for additional information).", 368 374 .func = cmd_tasks, 369 .argc = 0 375 .argc = 1, 376 .argv = &tasks_argv 370 377 }; 371 378 … … 384 391 .description = "List slab caches.", 385 392 .func = cmd_slabs, 393 .argc = 0 394 }; 395 396 static int cmd_sysinfo(cmd_arg_t *argv); 397 static cmd_info_t sysinfo_info = { 398 .name = "sysinfo", 399 .description = "Dump sysinfo.", 400 .func = cmd_sysinfo, 386 401 .argc = 0 387 402 }; … … 475 490 &set4_info, 476 491 &slabs_info, 492 &sysinfo_info, 477 493 &symaddr_info, 478 494 &sched_info, … … 485 501 &zone_info, 486 502 #ifdef CONFIG_TEST 487 &tests_info,488 503 &test_info, 489 504 &bench_info, … … 500 515 void cmd_initialize(cmd_info_t *cmd) 501 516 { 502 spinlock_initialize(&cmd->lock, "cmd ");517 spinlock_initialize(&cmd->lock, "cmd.lock"); 503 518 link_initialize(&cmd->link); 504 519 } … … 539 554 } 540 555 556 unsigned int _len = (unsigned int) len; 557 if ((_len != len) || (((int) _len) < 0)) { 558 printf("Command length overflow\n"); 559 return 1; 560 } 561 541 562 for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) { 542 563 cmd_info_t *hlp; … … 544 565 545 566 spinlock_lock(&hlp->lock); 546 printf("%-*s %s\n", len, hlp->name, hlp->description);567 printf("%-*s %s\n", _len, hlp->name, hlp->description); 547 568 spinlock_unlock(&hlp->lock); 548 569 } … … 648 669 printf("Duplicate symbol, be more specific.\n"); 649 670 } else if (rc == EOK) { 671 ipl_t ipl; 672 673 ipl = interrupts_disable(); 650 674 fnc = (unative_t (*)(void)) arch_construct_function(&fptr, 651 675 (void *) symaddr, (void *) cmd_call0); 652 printf("Calling %s() (%p)\n", symbol, symaddr);676 printf("Calling %s() (%p)\n", symbol, (void *) symaddr); 653 677 printf("Result: %#" PRIxn "\n", fnc()); 678 interrupts_restore(ipl); 654 679 } else { 655 680 printf("No symbol information available.\n"); … … 666 691 */ 667 692 668 size_t i;693 unsigned int i; 669 694 for (i = 0; i < config.cpu_count; i++) { 670 695 if (!cpus[i].active) 671 696 continue; 672 697 673 thread_t *t; 674 if ((t = thread_create((void (*)(void *)) cmd_call0, (void *) argv, TASK, THREAD_FLAG_WIRED, "call0", false))) { 675 spinlock_lock(&t->lock); 676 t->cpu = &cpus[i]; 677 spinlock_unlock(&t->lock); 698 thread_t *thread; 699 if ((thread = thread_create((void (*)(void *)) cmd_call0, 700 (void *) argv, TASK, THREAD_FLAG_WIRED, "call0", false))) { 701 irq_spinlock_lock(&thread->lock, true); 702 thread->cpu = &cpus[i]; 703 irq_spinlock_unlock(&thread->lock, true); 704 678 705 printf("cpu%u: ", i); 679 thread_ready(t); 680 thread_join(t); 681 thread_detach(t); 706 707 thread_ready(thread); 708 thread_join(thread); 709 thread_detach(thread); 682 710 } else 683 711 printf("Unable to create thread for cpu%u\n", i); … … 706 734 printf("Duplicate symbol, be more specific.\n"); 707 735 } else if (rc == EOK) { 708 fnc = (unative_t (*)(unative_t, ...)) arch_construct_function(&fptr, (void *) symaddr, (void *) cmd_call1); 709 printf("Calling f(%#" PRIxn "): %p: %s\n", arg1, symaddr, symbol); 736 ipl_t ipl; 737 738 ipl = interrupts_disable(); 739 fnc = (unative_t (*)(unative_t, ...)) 740 arch_construct_function(&fptr, (void *) symaddr, 741 (void *) cmd_call1); 742 printf("Calling f(%#" PRIxn "): %p: %s\n", arg1, 743 (void *) symaddr, symbol); 710 744 printf("Result: %#" PRIxn "\n", fnc(arg1)); 745 interrupts_restore(ipl); 711 746 } else { 712 747 printf("No symbol information available.\n"); … … 736 771 printf("Duplicate symbol, be more specific.\n"); 737 772 } else if (rc == EOK) { 738 fnc = (unative_t (*)(unative_t, unative_t, ...)) arch_construct_function(&fptr, (void *) symaddr, (void *) cmd_call2); 773 ipl_t ipl; 774 775 ipl = interrupts_disable(); 776 fnc = (unative_t (*)(unative_t, unative_t, ...)) 777 arch_construct_function(&fptr, (void *) symaddr, 778 (void *) cmd_call2); 739 779 printf("Calling f(%#" PRIxn ", %#" PRIxn "): %p: %s\n", 740 arg1, arg2, symaddr, symbol);780 arg1, arg2, (void *) symaddr, symbol); 741 781 printf("Result: %#" PRIxn "\n", fnc(arg1, arg2)); 782 interrupts_restore(ipl); 742 783 } else { 743 784 printf("No symbol information available.\n"); … … 767 808 printf("Duplicate symbol, be more specific.\n"); 768 809 } else if (rc == EOK) { 769 fnc = (unative_t (*)(unative_t, unative_t, unative_t, ...)) arch_construct_function(&fptr, (void *) symaddr, (void *) cmd_call3); 770 printf("Calling f(%#" PRIxn ",%#" PRIxn ", %#" PRIxn "): %p: %s\n", 771 arg1, arg2, arg3, symaddr, symbol); 810 ipl_t ipl; 811 812 ipl = interrupts_disable(); 813 fnc = (unative_t (*)(unative_t, unative_t, unative_t, ...)) 814 arch_construct_function(&fptr, (void *) symaddr, 815 (void *) cmd_call3); 816 printf("Calling f(%#" PRIxn ",%#" PRIxn ", %#" PRIxn "): %p: %s\n", 817 arg1, arg2, arg3, (void *) symaddr, symbol); 772 818 printf("Result: %#" PRIxn "\n", fnc(arg1, arg2, arg3)); 819 interrupts_restore(ipl); 773 820 } else { 774 821 printf("No symbol information available.\n"); … … 827 874 bool pointer = false; 828 875 int rc; 829 830 if (((char *) argv->buffer)[0] == '*') {876 877 if (((char *) argv->buffer)[0] == '*') { 831 878 rc = symtab_addr_lookup((char *) argv->buffer + 1, &addr); 832 879 pointer = true; 833 } else if (((char *) argv->buffer)[0] >= '0' && 834 ((char *)argv->buffer)[0] <= '9') { 835 rc = EOK; 836 addr = atoi((char *)argv->buffer); 837 } else { 880 } else if (((char *) argv->buffer)[0] >= '0' && 881 ((char *) argv->buffer)[0] <= '9') { 882 uint64_t value; 883 rc = str_uint64((char *) argv->buffer, NULL, 0, true, &value); 884 if (rc == EOK) 885 addr = (uintptr_t) value; 886 } else 838 887 rc = symtab_addr_lookup((char *) argv->buffer, &addr); 839 } 840 888 841 889 if (rc == ENOENT) 842 printf("Symbol %s not found.\n", argv->buffer); 890 printf("Symbol %s not found.\n", (char *) argv->buffer); 891 else if (rc == EINVAL) 892 printf("Invalid address.\n"); 843 893 else if (rc == EOVERFLOW) { 844 894 symtab_print_search((char *) argv->buffer); 845 printf("Duplicate symbol , be more specific.\n");895 printf("Duplicate symbol (be more specific) or address overflow.\n"); 846 896 } else if (rc == EOK) { 847 897 if (pointer) 848 898 addr = *(uintptr_t *) addr; 849 printf("Writing %#" PRIx 64 " -> %p\n", arg1,addr);899 printf("Writing %#" PRIx32" -> %p\n", arg1, (void *) addr); 850 900 *(uint32_t *) addr = arg1; 851 } else {901 } else 852 902 printf("No symbol information available.\n"); 853 }854 903 855 904 return 1; … … 868 917 } 869 918 919 /** Command for dumping sysinfo 920 * 921 * @param argv Ignores 922 * 923 * @return Always 1 924 */ 925 int cmd_sysinfo(cmd_arg_t * argv) 926 { 927 sysinfo_dump(NULL); 928 return 1; 929 } 930 870 931 871 932 /** Command for listings Thread information 872 933 * 934 * @param argv Ignored 935 * 936 * @return Always 1 937 */ 938 int cmd_threads(cmd_arg_t *argv) 939 { 940 if (str_cmp(flag_buf, "-a") == 0) 941 thread_print_list(true); 942 else if (str_cmp(flag_buf, "") == 0) 943 thread_print_list(false); 944 else 945 printf("Unknown argument \"%s\".\n", flag_buf); 946 947 return 1; 948 } 949 950 /** Command for listings Task information 951 * 952 * @param argv Ignored 953 * 954 * @return Always 1 955 */ 956 int cmd_tasks(cmd_arg_t *argv) 957 { 958 if (str_cmp(flag_buf, "-a") == 0) 959 task_print_list(true); 960 else if (str_cmp(flag_buf, "") == 0) 961 task_print_list(false); 962 else 963 printf("Unknown argument \"%s\".\n", flag_buf); 964 965 return 1; 966 } 967 968 /** Command for listings Thread information 969 * 873 970 * @param argv Ignores 874 971 * 875 972 * @return Always 1 876 973 */ 877 int cmd_threads(cmd_arg_t * argv)878 {879 thread_print_list();880 return 1;881 }882 883 /** Command for listings Task information884 *885 * @param argv Ignores886 *887 * @return Always 1888 */889 int cmd_tasks(cmd_arg_t * argv)890 {891 task_print_list();892 return 1;893 }894 895 /** Command for listings Thread information896 *897 * @param argv Ignores898 *899 * @return Always 1900 */901 974 int cmd_sched(cmd_arg_t * argv) 902 975 { … … 913 986 int cmd_zones(cmd_arg_t * argv) 914 987 { 915 zone _print_list();988 zones_print_list(); 916 989 return 1; 917 990 } … … 997 1070 998 1071 #ifdef CONFIG_TEST 999 /** Command for printing kernel tests list.1000 *1001 * @param argv Ignored.1002 *1003 * return Always 1.1004 */1005 int cmd_tests(cmd_arg_t *argv)1006 {1007 size_t len = 0;1008 test_t *test;1009 for (test = tests; test->name != NULL; test++) {1010 if (str_length(test->name) > len)1011 len = str_length(test->name);1012 }1013 1014 for (test = tests; test->name != NULL; test++)1015 printf("%-*s %s%s\n", len, test->name, test->desc, (test->safe ? "" : " (unsafe)"));1016 1017 printf("%-*s Run all safe tests\n", len, "*");1018 return 1;1019 }1020 1021 1072 static bool run_test(const test_t *test) 1022 1073 { … … 1025 1076 /* Update and read thread accounting 1026 1077 for benchmarking */ 1027 ipl_t ipl = interrupts_disable(); 1028 spinlock_lock(&TASK->lock); 1029 uint64_t t0 = task_get_accounting(TASK); 1030 spinlock_unlock(&TASK->lock); 1031 interrupts_restore(ipl); 1078 irq_spinlock_lock(&TASK->lock, true); 1079 uint64_t ucycles0, kcycles0; 1080 task_get_accounting(TASK, &ucycles0, &kcycles0); 1081 irq_spinlock_unlock(&TASK->lock, true); 1032 1082 1033 1083 /* Execute the test */ 1034 1084 test_quiet = false; 1035 c har *ret = test->entry();1085 const char *ret = test->entry(); 1036 1086 1037 1087 /* Update and read thread accounting */ 1038 ipl = interrupts_disable(); 1039 spinlock_lock(&TASK->lock); 1040 uint64_t dt = task_get_accounting(TASK) - t0; 1041 spinlock_unlock(&TASK->lock); 1042 interrupts_restore(ipl); 1043 1044 uint64_t cycles; 1045 char suffix; 1046 order(dt, &cycles, &suffix); 1047 1048 printf("Time: %" PRIu64 "%c cycles\n", cycles, suffix); 1088 uint64_t ucycles1, kcycles1; 1089 irq_spinlock_lock(&TASK->lock, true); 1090 task_get_accounting(TASK, &ucycles1, &kcycles1); 1091 irq_spinlock_unlock(&TASK->lock, true); 1092 1093 uint64_t ucycles, kcycles; 1094 char usuffix, ksuffix; 1095 order_suffix(ucycles1 - ucycles0, &ucycles, &usuffix); 1096 order_suffix(kcycles1 - kcycles0, &kcycles, &ksuffix); 1097 1098 printf("Time: %" PRIu64 "%c user cycles, %" PRIu64 "%c kernel cycles\n", 1099 ucycles, usuffix, kcycles, ksuffix); 1049 1100 1050 1101 if (ret == NULL) { … … 1052 1103 return true; 1053 1104 } 1054 1105 1055 1106 printf("%s\n", ret); 1056 1107 return false; … … 1061 1112 uint32_t i; 1062 1113 bool ret = true; 1063 uint64_t cycles;1064 char suffix;1114 uint64_t ucycles, kcycles; 1115 char usuffix, ksuffix; 1065 1116 1066 1117 if (cnt < 1) … … 1078 1129 /* Update and read thread accounting 1079 1130 for benchmarking */ 1080 ipl_t ipl = interrupts_disable(); 1081 spinlock_lock(&TASK->lock); 1082 uint64_t t0 = task_get_accounting(TASK); 1083 spinlock_unlock(&TASK->lock); 1084 interrupts_restore(ipl); 1131 irq_spinlock_lock(&TASK->lock, true); 1132 uint64_t ucycles0, kcycles0; 1133 task_get_accounting(TASK, &ucycles0, &kcycles0); 1134 irq_spinlock_unlock(&TASK->lock, true); 1085 1135 1086 1136 /* Execute the test */ 1087 1137 test_quiet = true; 1088 c har *ret = test->entry();1138 const char *ret = test->entry(); 1089 1139 1090 1140 /* Update and read thread accounting */ 1091 ipl = interrupts_disable(); 1092 spinlock_lock(&TASK->lock); 1093 uint64_t dt = task_get_accounting(TASK) - t0; 1094 spinlock_unlock(&TASK->lock); 1095 interrupts_restore(ipl); 1141 irq_spinlock_lock(&TASK->lock, true); 1142 uint64_t ucycles1, kcycles1; 1143 task_get_accounting(TASK, &ucycles1, &kcycles1); 1144 irq_spinlock_unlock(&TASK->lock, true); 1096 1145 1097 1146 if (ret != NULL) { … … 1101 1150 } 1102 1151 1103 data[i] = dt; 1104 order(dt, &cycles, &suffix); 1105 printf("OK (%" PRIu64 "%c cycles)\n", cycles, suffix); 1152 data[i] = ucycles1 - ucycles0 + kcycles1 - kcycles0; 1153 order_suffix(ucycles1 - ucycles0, &ucycles, &usuffix); 1154 order_suffix(kcycles1 - kcycles0, &kcycles, &ksuffix); 1155 printf("OK (%" PRIu64 "%c user cycles, %" PRIu64 "%c kernel cycles)\n", 1156 ucycles, usuffix, kcycles, ksuffix); 1106 1157 } 1107 1158 … … 1115 1166 } 1116 1167 1117 order (sum / (uint64_t) cnt, &cycles, &suffix);1118 printf("Average\t\t%" PRIu64 "%c\n", cycles,suffix);1168 order_suffix(sum / (uint64_t) cnt, &ucycles, &usuffix); 1169 printf("Average\t\t%" PRIu64 "%c\n", ucycles, usuffix); 1119 1170 } 1120 1171 … … 1124 1175 } 1125 1176 1126 /** Command for returning kernel tests 1177 static void list_tests(void) 1178 { 1179 size_t len = 0; 1180 test_t *test; 1181 1182 for (test = tests; test->name != NULL; test++) { 1183 if (str_length(test->name) > len) 1184 len = str_length(test->name); 1185 } 1186 1187 unsigned int _len = (unsigned int) len; 1188 if ((_len != len) || (((int) _len) < 0)) { 1189 printf("Command length overflow\n"); 1190 return; 1191 } 1192 1193 for (test = tests; test->name != NULL; test++) 1194 printf("%-*s %s%s\n", _len, test->name, test->desc, 1195 (test->safe ? "" : " (unsafe)")); 1196 1197 printf("%-*s Run all safe tests\n", _len, "*"); 1198 } 1199 1200 /** Command for listing and running kernel tests 1127 1201 * 1128 1202 * @param argv Argument vector. 1129 1203 * 1130 1204 * return Always 1. 1205 * 1131 1206 */ 1132 1207 int cmd_test(cmd_arg_t *argv) … … 1142 1217 } 1143 1218 } 1144 } else {1219 } else if (str_cmp((char *) argv->buffer, "") != 0) { 1145 1220 bool fnd = false; 1146 1221 … … 1155 1230 if (!fnd) 1156 1231 printf("Unknown test\n"); 1157 } 1232 } else 1233 list_tests(); 1158 1234 1159 1235 return 1;
Note:
See TracChangeset
for help on using the changeset viewer.