Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/console/cmd.c

    rcb3d641a r0b0f4bb  
    4646#include <print.h>
    4747#include <panic.h>
    48 #include <arch/types.h>
     48#include <typedefs.h>
    4949#include <adt/list.h>
    5050#include <arch.h>
    5151#include <config.h>
    5252#include <func.h>
    53 #include <string.h>
     53#include <str.h>
    5454#include <macros.h>
    5555#include <debug.h>
     
    6666#include <ipc/irq.h>
    6767#include <ipc/event.h>
     68#include <sysinfo/sysinfo.h>
    6869#include <symtab.h>
    6970#include <errno.h>
     
    107108
    108109#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 
    117110static char test_buf[MAX_CMDLINE + 1];
    118111static int cmd_test(cmd_arg_t *argv);
    119112static cmd_arg_t test_argv[] = {
    120113        {
    121                 .type = ARG_TYPE_STRING,
     114                .type = ARG_TYPE_STRING_OPTIONAL,
    122115                .buffer = test_buf,
    123116                .len = sizeof(test_buf)
     
    126119static cmd_info_t test_info = {
    127120        .name = "test",
    128         .description = "Run kernel test.",
     121        .description = "Print list of kernel tests or run a test.",
    129122        .func = cmd_test,
    130123        .argc = 1,
     
    206199};
    207200
    208 /* Data and methods for 'call0' command. */
     201/* Data and methods for 'call0' and 'mcall0' command. */
    209202static char call0_buf[MAX_CMDLINE + 1];
    210203static char carg1_buf[MAX_CMDLINE + 1];
     
    354347};
    355348
     349static char flag_buf[MAX_CMDLINE + 1];
     350
    356351static int cmd_threads(cmd_arg_t *argv);
     352static cmd_arg_t threads_argv = {
     353        .type = ARG_TYPE_STRING_OPTIONAL,
     354        .buffer = flag_buf,
     355        .len = sizeof(flag_buf)
     356};
    357357static cmd_info_t threads_info = {
    358358        .name = "threads",
    359         .description = "List all threads.",
     359        .description = "List all threads (use -a for additional information).",
    360360        .func = cmd_threads,
    361         .argc = 0
     361        .argc = 1,
     362        .argv = &threads_argv
    362363};
    363364
    364365static int cmd_tasks(cmd_arg_t *argv);
     366static cmd_arg_t tasks_argv = {
     367        .type = ARG_TYPE_STRING_OPTIONAL,
     368        .buffer = flag_buf,
     369        .len = sizeof(flag_buf)
     370};
    365371static cmd_info_t tasks_info = {
    366372        .name = "tasks",
    367         .description = "List all tasks.",
     373        .description = "List all tasks (use -a for additional information).",
    368374        .func = cmd_tasks,
    369         .argc = 0
     375        .argc = 1,
     376        .argv = &tasks_argv
    370377};
    371378
     
    384391        .description = "List slab caches.",
    385392        .func = cmd_slabs,
     393        .argc = 0
     394};
     395
     396static int cmd_sysinfo(cmd_arg_t *argv);
     397static cmd_info_t sysinfo_info = {
     398        .name = "sysinfo",
     399        .description = "Dump sysinfo.",
     400        .func = cmd_sysinfo,
    386401        .argc = 0
    387402};
     
    475490        &set4_info,
    476491        &slabs_info,
     492        &sysinfo_info,
    477493        &symaddr_info,
    478494        &sched_info,
     
    485501        &zone_info,
    486502#ifdef CONFIG_TEST
    487         &tests_info,
    488503        &test_info,
    489504        &bench_info,
     
    500515void cmd_initialize(cmd_info_t *cmd)
    501516{
    502         spinlock_initialize(&cmd->lock, "cmd");
     517        spinlock_initialize(&cmd->lock, "cmd.lock");
    503518        link_initialize(&cmd->link);
    504519}
     
    539554        }
    540555       
     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       
    541562        for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
    542563                cmd_info_t *hlp;
     
    544565               
    545566                spinlock_lock(&hlp->lock);
    546                 printf("%-*s %s\n", len, hlp->name, hlp->description);
     567                printf("%-*s %s\n", _len, hlp->name, hlp->description);
    547568                spinlock_unlock(&hlp->lock);
    548569        }
     
    648669                printf("Duplicate symbol, be more specific.\n");
    649670        } else if (rc == EOK) {
     671                ipl_t ipl;
     672
     673                ipl = interrupts_disable();
    650674                fnc = (unative_t (*)(void)) arch_construct_function(&fptr,
    651675                    (void *) symaddr, (void *) cmd_call0);
    652                 printf("Calling %s() (%p)\n", symbol, symaddr);
     676                printf("Calling %s() (%p)\n", symbol, (void *) symaddr);
    653677                printf("Result: %#" PRIxn "\n", fnc());
     678                interrupts_restore(ipl);
    654679        } else {
    655680                printf("No symbol information available.\n");
     
    666691         */
    667692       
    668         size_t i;
     693        unsigned int i;
    669694        for (i = 0; i < config.cpu_count; i++) {
    670695                if (!cpus[i].active)
    671696                        continue;
    672697               
    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                       
    678705                        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);
    682710                } else
    683711                        printf("Unable to create thread for cpu%u\n", i);
     
    706734                printf("Duplicate symbol, be more specific.\n");
    707735        } 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);
    710744                printf("Result: %#" PRIxn "\n", fnc(arg1));
     745                interrupts_restore(ipl);
    711746        } else {
    712747                printf("No symbol information available.\n");
     
    736771                printf("Duplicate symbol, be more specific.\n");
    737772        } 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);
    739779                printf("Calling f(%#" PRIxn ", %#" PRIxn "): %p: %s\n",
    740                        arg1, arg2, symaddr, symbol);
     780                       arg1, arg2, (void *) symaddr, symbol);
    741781                printf("Result: %#" PRIxn "\n", fnc(arg1, arg2));
     782                interrupts_restore(ipl);
    742783        } else {
    743784                printf("No symbol information available.\n");
     
    767808                printf("Duplicate symbol, be more specific.\n");
    768809        } 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);
    772818                printf("Result: %#" PRIxn "\n", fnc(arg1, arg2, arg3));
     819                interrupts_restore(ipl);
    773820        } else {
    774821                printf("No symbol information available.\n");
     
    827874        bool pointer = false;
    828875        int rc;
    829 
    830         if (((char *)argv->buffer)[0] == '*') {
     876       
     877        if (((char *) argv->buffer)[0] == '*') {
    831878                rc = symtab_addr_lookup((char *) argv->buffer + 1, &addr);
    832879                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
    838887                rc = symtab_addr_lookup((char *) argv->buffer, &addr);
    839         }
    840 
     888       
    841889        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");
    843893        else if (rc == EOVERFLOW) {
    844894                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");
    846896        } else if (rc == EOK) {
    847897                if (pointer)
    848898                        addr = *(uintptr_t *) addr;
    849                 printf("Writing %#" PRIx64 " -> %p\n", arg1, addr);
     899                printf("Writing %#" PRIx32" -> %p\n", arg1, (void *) addr);
    850900                *(uint32_t *) addr = arg1;
    851         } else {
     901        } else
    852902                printf("No symbol information available.\n");
    853         }
    854903       
    855904        return 1;
     
    868917}
    869918
     919/** Command for dumping sysinfo
     920 *
     921 * @param argv Ignores
     922 *
     923 * @return Always 1
     924 */
     925int cmd_sysinfo(cmd_arg_t * argv)
     926{
     927        sysinfo_dump(NULL);
     928        return 1;
     929}
     930
    870931
    871932/** Command for listings Thread information
    872933 *
     934 * @param argv Ignored
     935 *
     936 * @return Always 1
     937 */
     938int 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 */
     956int 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 *
    873970 * @param argv Ignores
    874971 *
    875972 * @return Always 1
    876973 */
    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 }
    894 
    895 /** Command for listings Thread information
    896  *
    897  * @param argv Ignores
    898  *
    899  * @return Always 1
    900  */
    901974int cmd_sched(cmd_arg_t * argv)
    902975{
     
    913986int cmd_zones(cmd_arg_t * argv)
    914987{
    915         zone_print_list();
     988        zones_print_list();
    916989        return 1;
    917990}
     
    9971070
    9981071#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 
    10211072static bool run_test(const test_t *test)
    10221073{
     
    10251076        /* Update and read thread accounting
    10261077           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);
    10321082       
    10331083        /* Execute the test */
    10341084        test_quiet = false;
    1035         char *ret = test->entry();
     1085        const char *ret = test->entry();
    10361086       
    10371087        /* 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);
    10491100       
    10501101        if (ret == NULL) {
     
    10521103                return true;
    10531104        }
    1054 
     1105       
    10551106        printf("%s\n", ret);
    10561107        return false;
     
    10611112        uint32_t i;
    10621113        bool ret = true;
    1063         uint64_t cycles;
    1064         char suffix;
     1114        uint64_t ucycles, kcycles;
     1115        char usuffix, ksuffix;
    10651116       
    10661117        if (cnt < 1)
     
    10781129                /* Update and read thread accounting
    10791130                   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);
    10851135               
    10861136                /* Execute the test */
    10871137                test_quiet = true;
    1088                 char * ret = test->entry();
     1138                const char *ret = test->entry();
    10891139               
    10901140                /* 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);
    10961145               
    10971146                if (ret != NULL) {
     
    11011150                }
    11021151               
    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);
    11061157        }
    11071158       
     
    11151166                }
    11161167               
    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);
    11191170        }
    11201171       
     
    11241175}
    11251176
    1126 /** Command for returning kernel tests
     1177static 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
    11271201 *
    11281202 * @param argv Argument vector.
    11291203 *
    11301204 * return Always 1.
     1205 *
    11311206 */
    11321207int cmd_test(cmd_arg_t *argv)
     
    11421217                        }
    11431218                }
    1144         } else {
     1219        } else if (str_cmp((char *) argv->buffer, "") != 0) {
    11451220                bool fnd = false;
    11461221               
     
    11551230                if (!fnd)
    11561231                        printf("Unknown test\n");
    1157         }
     1232        } else
     1233                list_tests();
    11581234       
    11591235        return 1;
Note: See TracChangeset for help on using the changeset viewer.