Changes in kernel/generic/src/console/cmd.c [0b0f4bb:cb3d641a] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/console/cmd.c
r0b0f4bb rcb3d641a 46 46 #include <print.h> 47 47 #include <panic.h> 48 #include < typedefs.h>48 #include <arch/types.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 .h>53 #include <string.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>69 68 #include <symtab.h> 70 69 #include <errno.h> … … 108 107 109 108 #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 = 0 115 }; 116 110 117 static char test_buf[MAX_CMDLINE + 1]; 111 118 static int cmd_test(cmd_arg_t *argv); 112 119 static cmd_arg_t test_argv[] = { 113 120 { 114 .type = ARG_TYPE_STRING _OPTIONAL,121 .type = ARG_TYPE_STRING, 115 122 .buffer = test_buf, 116 123 .len = sizeof(test_buf) … … 119 126 static cmd_info_t test_info = { 120 127 .name = "test", 121 .description = " Print list of kernel tests or run atest.",128 .description = "Run kernel test.", 122 129 .func = cmd_test, 123 130 .argc = 1, … … 199 206 }; 200 207 201 /* Data and methods for 'call0' and 'mcall0'command. */208 /* Data and methods for 'call0' command. */ 202 209 static char call0_buf[MAX_CMDLINE + 1]; 203 210 static char carg1_buf[MAX_CMDLINE + 1]; … … 347 354 }; 348 355 349 static char flag_buf[MAX_CMDLINE + 1];350 351 356 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 (use -a for additional information).",359 .description = "List all threads.", 360 360 .func = cmd_threads, 361 .argc = 1, 362 .argv = &threads_argv 361 .argc = 0 363 362 }; 364 363 365 364 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 };371 365 static cmd_info_t tasks_info = { 372 366 .name = "tasks", 373 .description = "List all tasks (use -a for additional information).",367 .description = "List all tasks.", 374 368 .func = cmd_tasks, 375 .argc = 1, 376 .argv = &tasks_argv 369 .argc = 0 377 370 }; 378 371 … … 391 384 .description = "List slab caches.", 392 385 .func = cmd_slabs, 393 .argc = 0394 };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,401 386 .argc = 0 402 387 }; … … 490 475 &set4_info, 491 476 &slabs_info, 492 &sysinfo_info,493 477 &symaddr_info, 494 478 &sched_info, … … 501 485 &zone_info, 502 486 #ifdef CONFIG_TEST 487 &tests_info, 503 488 &test_info, 504 489 &bench_info, … … 515 500 void cmd_initialize(cmd_info_t *cmd) 516 501 { 517 spinlock_initialize(&cmd->lock, "cmd .lock");502 spinlock_initialize(&cmd->lock, "cmd"); 518 503 link_initialize(&cmd->link); 519 504 } … … 554 539 } 555 540 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 562 541 for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) { 563 542 cmd_info_t *hlp; … … 565 544 566 545 spinlock_lock(&hlp->lock); 567 printf("%-*s %s\n", _len, hlp->name, hlp->description);546 printf("%-*s %s\n", len, hlp->name, hlp->description); 568 547 spinlock_unlock(&hlp->lock); 569 548 } … … 669 648 printf("Duplicate symbol, be more specific.\n"); 670 649 } else if (rc == EOK) { 671 ipl_t ipl;672 673 ipl = interrupts_disable();674 650 fnc = (unative_t (*)(void)) arch_construct_function(&fptr, 675 651 (void *) symaddr, (void *) cmd_call0); 676 printf("Calling %s() (%p)\n", symbol, (void *)symaddr);652 printf("Calling %s() (%p)\n", symbol, symaddr); 677 653 printf("Result: %#" PRIxn "\n", fnc()); 678 interrupts_restore(ipl);679 654 } else { 680 655 printf("No symbol information available.\n"); … … 691 666 */ 692 667 693 unsigned int i;668 size_t i; 694 669 for (i = 0; i < config.cpu_count; i++) { 695 670 if (!cpus[i].active) 696 671 continue; 697 672 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 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); 705 678 printf("cpu%u: ", i); 706 707 thread_ready(thread); 708 thread_join(thread); 709 thread_detach(thread); 679 thread_ready(t); 680 thread_join(t); 681 thread_detach(t); 710 682 } else 711 683 printf("Unable to create thread for cpu%u\n", i); … … 734 706 printf("Duplicate symbol, be more specific.\n"); 735 707 } else if (rc == EOK) { 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); 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); 744 710 printf("Result: %#" PRIxn "\n", fnc(arg1)); 745 interrupts_restore(ipl);746 711 } else { 747 712 printf("No symbol information available.\n"); … … 771 736 printf("Duplicate symbol, be more specific.\n"); 772 737 } else if (rc == EOK) { 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); 738 fnc = (unative_t (*)(unative_t, unative_t, ...)) arch_construct_function(&fptr, (void *) symaddr, (void *) cmd_call2); 779 739 printf("Calling f(%#" PRIxn ", %#" PRIxn "): %p: %s\n", 780 arg1, arg2, (void *)symaddr, symbol);740 arg1, arg2, symaddr, symbol); 781 741 printf("Result: %#" PRIxn "\n", fnc(arg1, arg2)); 782 interrupts_restore(ipl);783 742 } else { 784 743 printf("No symbol information available.\n"); … … 808 767 printf("Duplicate symbol, be more specific.\n"); 809 768 } else if (rc == EOK) { 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); 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); 818 772 printf("Result: %#" PRIxn "\n", fnc(arg1, arg2, arg3)); 819 interrupts_restore(ipl);820 773 } else { 821 774 printf("No symbol information available.\n"); … … 874 827 bool pointer = false; 875 828 int rc; 876 877 if (((char *) 829 830 if (((char *)argv->buffer)[0] == '*') { 878 831 rc = symtab_addr_lookup((char *) argv->buffer + 1, &addr); 879 832 pointer = true; 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 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 { 887 838 rc = symtab_addr_lookup((char *) argv->buffer, &addr); 888 839 } 840 889 841 if (rc == ENOENT) 890 printf("Symbol %s not found.\n", (char *) argv->buffer); 891 else if (rc == EINVAL) 892 printf("Invalid address.\n"); 842 printf("Symbol %s not found.\n", argv->buffer); 893 843 else if (rc == EOVERFLOW) { 894 844 symtab_print_search((char *) argv->buffer); 895 printf("Duplicate symbol (be more specific) or address overflow.\n");845 printf("Duplicate symbol, be more specific.\n"); 896 846 } else if (rc == EOK) { 897 847 if (pointer) 898 848 addr = *(uintptr_t *) addr; 899 printf("Writing %#" PRIx 32" -> %p\n", arg1, (void *)addr);849 printf("Writing %#" PRIx64 " -> %p\n", arg1, addr); 900 850 *(uint32_t *) addr = arg1; 901 } else 851 } else { 902 852 printf("No symbol information available.\n"); 853 } 903 854 904 855 return 1; … … 917 868 } 918 869 919 /** Command for dumping sysinfo 870 871 /** Command for listings Thread information 920 872 * 921 873 * @param argv Ignores … … 923 875 * @return Always 1 924 876 */ 925 int cmd_sysinfo(cmd_arg_t * argv) 926 { 927 sysinfo_dump(NULL); 928 return 1; 929 } 930 877 int cmd_threads(cmd_arg_t * argv) 878 { 879 thread_print_list(); 880 return 1; 881 } 882 883 /** Command for listings Task information 884 * 885 * @param argv Ignores 886 * 887 * @return Always 1 888 */ 889 int cmd_tasks(cmd_arg_t * argv) 890 { 891 task_print_list(); 892 return 1; 893 } 931 894 932 895 /** Command for listings Thread information 933 896 * 897 * @param argv Ignores 898 * 899 * @return Always 1 900 */ 901 int cmd_sched(cmd_arg_t * argv) 902 { 903 sched_print_list(); 904 return 1; 905 } 906 907 /** Command for listing memory zones 908 * 934 909 * @param argv Ignored 935 910 * 936 * @return Always 1937 */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 else945 printf("Unknown argument \"%s\".\n", flag_buf);946 947 return 1;948 }949 950 /** Command for listings Task information951 *952 * @param argv Ignored953 *954 * @return Always 1955 */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 else963 printf("Unknown argument \"%s\".\n", flag_buf);964 965 return 1;966 }967 968 /** Command for listings Thread information969 *970 * @param argv Ignores971 *972 * @return Always 1973 */974 int cmd_sched(cmd_arg_t * argv)975 {976 sched_print_list();977 return 1;978 }979 980 /** Command for listing memory zones981 *982 * @param argv Ignored983 *984 911 * return Always 1 985 912 */ 986 913 int cmd_zones(cmd_arg_t * argv) 987 914 { 988 zone s_print_list();915 zone_print_list(); 989 916 return 1; 990 917 } … … 1070 997 1071 998 #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 1072 1021 static bool run_test(const test_t *test) 1073 1022 { … … 1076 1025 /* Update and read thread accounting 1077 1026 for benchmarking */ 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); 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); 1082 1032 1083 1033 /* Execute the test */ 1084 1034 test_quiet = false; 1085 c onst char *ret = test->entry();1035 char *ret = test->entry(); 1086 1036 1087 1037 /* Update and read thread accounting */ 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); 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); 1100 1049 1101 1050 if (ret == NULL) { … … 1103 1052 return true; 1104 1053 } 1105 1054 1106 1055 printf("%s\n", ret); 1107 1056 return false; … … 1112 1061 uint32_t i; 1113 1062 bool ret = true; 1114 uint64_t ucycles, kcycles;1115 char usuffix, ksuffix;1063 uint64_t cycles; 1064 char suffix; 1116 1065 1117 1066 if (cnt < 1) … … 1129 1078 /* Update and read thread accounting 1130 1079 for benchmarking */ 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); 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); 1135 1085 1136 1086 /* Execute the test */ 1137 1087 test_quiet = true; 1138 c onst char *ret = test->entry();1088 char * ret = test->entry(); 1139 1089 1140 1090 /* Update and read thread accounting */ 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); 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); 1145 1096 1146 1097 if (ret != NULL) { … … 1150 1101 } 1151 1102 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); 1103 data[i] = dt; 1104 order(dt, &cycles, &suffix); 1105 printf("OK (%" PRIu64 "%c cycles)\n", cycles, suffix); 1157 1106 } 1158 1107 … … 1166 1115 } 1167 1116 1168 order _suffix(sum / (uint64_t) cnt, &ucycles, &usuffix);1169 printf("Average\t\t%" PRIu64 "%c\n", ucycles, usuffix);1117 order(sum / (uint64_t) cnt, &cycles, &suffix); 1118 printf("Average\t\t%" PRIu64 "%c\n", cycles, suffix); 1170 1119 } 1171 1120 … … 1175 1124 } 1176 1125 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 1126 /** Command for returning kernel tests 1201 1127 * 1202 1128 * @param argv Argument vector. 1203 1129 * 1204 1130 * return Always 1. 1205 *1206 1131 */ 1207 1132 int cmd_test(cmd_arg_t *argv) … … 1217 1142 } 1218 1143 } 1219 } else if (str_cmp((char *) argv->buffer, "") != 0){1144 } else { 1220 1145 bool fnd = false; 1221 1146 … … 1230 1155 if (!fnd) 1231 1156 printf("Unknown test\n"); 1232 } else 1233 list_tests(); 1157 } 1234 1158 1235 1159 return 1;
Note:
See TracChangeset
for help on using the changeset viewer.