00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00043 #include <console/cmd.h>
00044 #include <console/console.h>
00045 #include <console/kconsole.h>
00046 #include <print.h>
00047 #include <panic.h>
00048 #include <typedefs.h>
00049 #include <arch/types.h>
00050 #include <adt/list.h>
00051 #include <arch.h>
00052 #include <func.h>
00053 #include <macros.h>
00054 #include <debug.h>
00055 #include <symtab.h>
00056 #include <cpu.h>
00057 #include <mm/tlb.h>
00058 #include <arch/mm/tlb.h>
00059 #include <mm/frame.h>
00060 #include <main/version.h>
00061 #include <mm/slab.h>
00062 #include <proc/scheduler.h>
00063 #include <proc/thread.h>
00064 #include <proc/task.h>
00065 #include <ipc/ipc.h>
00066 #include <ipc/irq.h>
00067
00068
00069 static int cmd_help(cmd_arg_t *argv);
00070 static cmd_info_t help_info = {
00071 .name = "help",
00072 .description = "List of supported commands.",
00073 .func = cmd_help,
00074 .argc = 0
00075 };
00076
00077 static cmd_info_t exit_info = {
00078 .name = "exit",
00079 .description ="Exit kconsole",
00080 .argc = 0
00081 };
00082
00083 static int cmd_continue(cmd_arg_t *argv);
00084 static cmd_info_t continue_info = {
00085 .name = "continue",
00086 .description ="Return console back to userspace.",
00087 .func = cmd_continue,
00088 .argc = 0
00089 };
00090
00091
00092 static int cmd_desc(cmd_arg_t *argv);
00093 static void desc_help(void);
00094 static char desc_buf[MAX_CMDLINE+1];
00095 static cmd_arg_t desc_argv = {
00096 .type = ARG_TYPE_STRING,
00097 .buffer = desc_buf,
00098 .len = sizeof(desc_buf)
00099 };
00100 static cmd_info_t desc_info = {
00101 .name = "describe",
00102 .description = "Describe specified command.",
00103 .help = desc_help,
00104 .func = cmd_desc,
00105 .argc = 1,
00106 .argv = &desc_argv
00107 };
00108
00109
00110 static int cmd_symaddr(cmd_arg_t *argv);
00111 static char symaddr_buf[MAX_CMDLINE+1];
00112 static cmd_arg_t symaddr_argv = {
00113 .type = ARG_TYPE_STRING,
00114 .buffer = symaddr_buf,
00115 .len = sizeof(symaddr_buf)
00116 };
00117 static cmd_info_t symaddr_info = {
00118 .name = "symaddr",
00119 .description = "Return symbol address.",
00120 .func = cmd_symaddr,
00121 .argc = 1,
00122 .argv = &symaddr_argv
00123 };
00124
00125 static char set_buf[MAX_CMDLINE+1];
00126 static int cmd_set4(cmd_arg_t *argv);
00127 static cmd_arg_t set4_argv[] = {
00128 {
00129 .type = ARG_TYPE_STRING,
00130 .buffer = set_buf,
00131 .len = sizeof(set_buf)
00132 },
00133 {
00134 .type = ARG_TYPE_INT
00135 }
00136 };
00137 static cmd_info_t set4_info = {
00138 .name = "set4",
00139 .description = "set <dest_addr> <value> - 4byte version",
00140 .func = cmd_set4,
00141 .argc = 2,
00142 .argv = set4_argv
00143 };
00144
00145
00146 static char call0_buf[MAX_CMDLINE+1];
00147 static char carg1_buf[MAX_CMDLINE+1];
00148 static char carg2_buf[MAX_CMDLINE+1];
00149 static char carg3_buf[MAX_CMDLINE+1];
00150
00151 static int cmd_call0(cmd_arg_t *argv);
00152 static cmd_arg_t call0_argv = {
00153 .type = ARG_TYPE_STRING,
00154 .buffer = call0_buf,
00155 .len = sizeof(call0_buf)
00156 };
00157 static cmd_info_t call0_info = {
00158 .name = "call0",
00159 .description = "call0 <function> -> call function().",
00160 .func = cmd_call0,
00161 .argc = 1,
00162 .argv = &call0_argv
00163 };
00164
00165
00166 static int cmd_call1(cmd_arg_t *argv);
00167 static cmd_arg_t call1_argv[] = {
00168 {
00169 .type = ARG_TYPE_STRING,
00170 .buffer = call0_buf,
00171 .len = sizeof(call0_buf)
00172 },
00173 {
00174 .type = ARG_TYPE_VAR,
00175 .buffer = carg1_buf,
00176 .len = sizeof(carg1_buf)
00177 }
00178 };
00179 static cmd_info_t call1_info = {
00180 .name = "call1",
00181 .description = "call1 <function> <arg1> -> call function(arg1).",
00182 .func = cmd_call1,
00183 .argc = 2,
00184 .argv = call1_argv
00185 };
00186
00187
00188 static int cmd_call2(cmd_arg_t *argv);
00189 static cmd_arg_t call2_argv[] = {
00190 {
00191 .type = ARG_TYPE_STRING,
00192 .buffer = call0_buf,
00193 .len = sizeof(call0_buf)
00194 },
00195 {
00196 .type = ARG_TYPE_VAR,
00197 .buffer = carg1_buf,
00198 .len = sizeof(carg1_buf)
00199 },
00200 {
00201 .type = ARG_TYPE_VAR,
00202 .buffer = carg2_buf,
00203 .len = sizeof(carg2_buf)
00204 }
00205 };
00206 static cmd_info_t call2_info = {
00207 .name = "call2",
00208 .description = "call2 <function> <arg1> <arg2> -> call function(arg1,arg2).",
00209 .func = cmd_call2,
00210 .argc = 3,
00211 .argv = call2_argv
00212 };
00213
00214
00215 static int cmd_call3(cmd_arg_t *argv);
00216 static cmd_arg_t call3_argv[] = {
00217 {
00218 .type = ARG_TYPE_STRING,
00219 .buffer = call0_buf,
00220 .len = sizeof(call0_buf)
00221 },
00222 {
00223 .type = ARG_TYPE_VAR,
00224 .buffer = carg1_buf,
00225 .len = sizeof(carg1_buf)
00226 },
00227 {
00228 .type = ARG_TYPE_VAR,
00229 .buffer = carg2_buf,
00230 .len = sizeof(carg2_buf)
00231 },
00232 {
00233 .type = ARG_TYPE_VAR,
00234 .buffer = carg3_buf,
00235 .len = sizeof(carg3_buf)
00236 }
00237
00238 };
00239 static cmd_info_t call3_info = {
00240 .name = "call3",
00241 .description = "call3 <function> <arg1> <arg2> <arg3> -> call function(arg1,arg2,arg3).",
00242 .func = cmd_call3,
00243 .argc = 4,
00244 .argv = call3_argv
00245 };
00246
00247
00248 static int cmd_halt(cmd_arg_t *argv);
00249 static cmd_info_t halt_info = {
00250 .name = "halt",
00251 .description = "Halt the kernel.",
00252 .func = cmd_halt,
00253 .argc = 0
00254 };
00255
00256
00257 static int cmd_tlb(cmd_arg_t *argv);
00258 cmd_info_t tlb_info = {
00259 .name = "tlb",
00260 .description = "Print TLB of current processor.",
00261 .help = NULL,
00262 .func = cmd_tlb,
00263 .argc = 0,
00264 .argv = NULL
00265 };
00266
00267 static int cmd_threads(cmd_arg_t *argv);
00268 static cmd_info_t threads_info = {
00269 .name = "threads",
00270 .description = "List all threads.",
00271 .func = cmd_threads,
00272 .argc = 0
00273 };
00274
00275 static int cmd_tasks(cmd_arg_t *argv);
00276 static cmd_info_t tasks_info = {
00277 .name = "tasks",
00278 .description = "List all tasks.",
00279 .func = cmd_tasks,
00280 .argc = 0
00281 };
00282
00283
00284 static int cmd_sched(cmd_arg_t *argv);
00285 static cmd_info_t sched_info = {
00286 .name = "scheduler",
00287 .description = "List all scheduler information.",
00288 .func = cmd_sched,
00289 .argc = 0
00290 };
00291
00292 static int cmd_slabs(cmd_arg_t *argv);
00293 static cmd_info_t slabs_info = {
00294 .name = "slabs",
00295 .description = "List slab caches.",
00296 .func = cmd_slabs,
00297 .argc = 0
00298 };
00299
00300
00301 static int cmd_zones(cmd_arg_t *argv);
00302 static cmd_info_t zones_info = {
00303 .name = "zones",
00304 .description = "List of memory zones.",
00305 .func = cmd_zones,
00306 .argc = 0
00307 };
00308
00309
00310 static int cmd_ipc_task(cmd_arg_t *argv);
00311 static cmd_arg_t ipc_task_argv = {
00312 .type = ARG_TYPE_INT,
00313 };
00314 static cmd_info_t ipc_task_info = {
00315 .name = "ipc_task",
00316 .description = "ipc_task <taskid> Show IPC information of given task.",
00317 .func = cmd_ipc_task,
00318 .argc = 1,
00319 .argv = &ipc_task_argv
00320 };
00321
00322
00323 static int cmd_zone(cmd_arg_t *argv);
00324 static cmd_arg_t zone_argv = {
00325 .type = ARG_TYPE_INT,
00326 };
00327
00328 static cmd_info_t zone_info = {
00329 .name = "zone",
00330 .description = "Show memory zone structure.",
00331 .func = cmd_zone,
00332 .argc = 1,
00333 .argv = &zone_argv
00334 };
00335
00336
00337 static int cmd_cpus(cmd_arg_t *argv);
00338 cmd_info_t cpus_info = {
00339 .name = "cpus",
00340 .description = "List all processors.",
00341 .help = NULL,
00342 .func = cmd_cpus,
00343 .argc = 0,
00344 .argv = NULL
00345 };
00346
00347
00348 static int cmd_version(cmd_arg_t *argv);
00349 cmd_info_t version_info = {
00350 .name = "version",
00351 .description = "Print version information.",
00352 .help = NULL,
00353 .func = cmd_version,
00354 .argc = 0,
00355 .argv = NULL
00356 };
00357
00358 static cmd_info_t *basic_commands[] = {
00359 &call0_info,
00360 &call1_info,
00361 &call2_info,
00362 &call3_info,
00363 &continue_info,
00364 &cpus_info,
00365 &desc_info,
00366 &exit_info,
00367 &halt_info,
00368 &help_info,
00369 &ipc_task_info,
00370 &set4_info,
00371 &slabs_info,
00372 &symaddr_info,
00373 &sched_info,
00374 &threads_info,
00375 &tasks_info,
00376 &tlb_info,
00377 &version_info,
00378 &zones_info,
00379 &zone_info,
00380 NULL
00381 };
00382
00383
00389 void cmd_initialize(cmd_info_t *cmd)
00390 {
00391 spinlock_initialize(&cmd->lock, "cmd");
00392 link_initialize(&cmd->link);
00393 }
00394
00396 void cmd_init(void)
00397 {
00398 int i;
00399
00400 for (i=0;basic_commands[i]; i++) {
00401 cmd_initialize(basic_commands[i]);
00402 if (!cmd_register(basic_commands[i]))
00403 panic("could not register command %s\n",
00404 basic_commands[i]->name);
00405 }
00406 }
00407
00408
00415 int cmd_help(cmd_arg_t *argv)
00416 {
00417 link_t *cur;
00418
00419 spinlock_lock(&cmd_lock);
00420
00421 for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
00422 cmd_info_t *hlp;
00423
00424 hlp = list_get_instance(cur, cmd_info_t, link);
00425 spinlock_lock(&hlp->lock);
00426
00427 printf("%s - %s\n", hlp->name, hlp->description);
00428
00429 spinlock_unlock(&hlp->lock);
00430 }
00431
00432 spinlock_unlock(&cmd_lock);
00433
00434 return 1;
00435 }
00436
00443 int cmd_desc(cmd_arg_t *argv)
00444 {
00445 link_t *cur;
00446
00447 spinlock_lock(&cmd_lock);
00448
00449 for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
00450 cmd_info_t *hlp;
00451
00452 hlp = list_get_instance(cur, cmd_info_t, link);
00453 spinlock_lock(&hlp->lock);
00454
00455 if (strncmp(hlp->name, (const char *) argv->buffer, strlen(hlp->name)) == 0) {
00456 printf("%s - %s\n", hlp->name, hlp->description);
00457 if (hlp->help)
00458 hlp->help();
00459 spinlock_unlock(&hlp->lock);
00460 break;
00461 }
00462
00463 spinlock_unlock(&hlp->lock);
00464 }
00465
00466 spinlock_unlock(&cmd_lock);
00467
00468 return 1;
00469 }
00470
00472 int cmd_symaddr(cmd_arg_t *argv)
00473 {
00474 symtab_print_search(argv->buffer);
00475
00476 return 1;
00477 }
00478
00480 int cmd_call0(cmd_arg_t *argv)
00481 {
00482 __address symaddr;
00483 char *symbol;
00484 __native (*f)(void);
00485 #ifdef ia64
00486 struct {
00487 __native f;
00488 __native gp;
00489 }fptr;
00490 #endif
00491
00492 symaddr = get_symbol_addr(argv->buffer);
00493 if (!symaddr)
00494 printf("Symbol %s not found.\n", argv->buffer);
00495 else if (symaddr == (__address) -1) {
00496 symtab_print_search(argv->buffer);
00497 printf("Duplicate symbol, be more specific.\n");
00498 } else {
00499 symbol = get_symtab_entry(symaddr);
00500 printf("Calling f(): %.*p: %s\n", sizeof(__address) * 2, symaddr, symbol);
00501 #ifdef ia64
00502 fptr.f = symaddr;
00503 fptr.gp = ((__native *)cmd_call2)[1];
00504 f = (__native (*)(void)) &fptr;
00505 #else
00506 f = (__native (*)(void)) symaddr;
00507 #endif
00508 printf("Result: %#zx\n", f());
00509 }
00510
00511 return 1;
00512 }
00513
00515 int cmd_call1(cmd_arg_t *argv)
00516 {
00517 __address symaddr;
00518 char *symbol;
00519 __native (*f)(__native,...);
00520 __native arg1 = argv[1].intval;
00521 #ifdef ia64
00522 struct {
00523 __native f;
00524 __native gp;
00525 }fptr;
00526 #endif
00527
00528 symaddr = get_symbol_addr(argv->buffer);
00529 if (!symaddr)
00530 printf("Symbol %s not found.\n", argv->buffer);
00531 else if (symaddr == (__address) -1) {
00532 symtab_print_search(argv->buffer);
00533 printf("Duplicate symbol, be more specific.\n");
00534 } else {
00535 symbol = get_symtab_entry(symaddr);
00536
00537 printf("Calling f(%#zx): %.*p: %s\n", arg1, sizeof(__address) * 2, symaddr, symbol);
00538 #ifdef ia64
00539 fptr.f = symaddr;
00540 fptr.gp = ((__native *)cmd_call2)[1];
00541 f = (__native (*)(__native,...)) &fptr;
00542 #else
00543 f = (__native (*)(__native,...)) symaddr;
00544 #endif
00545 printf("Result: %#zx\n", f(arg1));
00546 }
00547
00548 return 1;
00549 }
00550
00552 int cmd_call2(cmd_arg_t *argv)
00553 {
00554 __address symaddr;
00555 char *symbol;
00556 __native (*f)(__native,__native,...);
00557 __native arg1 = argv[1].intval;
00558 __native arg2 = argv[2].intval;
00559 #ifdef ia64
00560 struct {
00561 __native f;
00562 __native gp;
00563 }fptr;
00564 #endif
00565
00566 symaddr = get_symbol_addr(argv->buffer);
00567 if (!symaddr)
00568 printf("Symbol %s not found.\n", argv->buffer);
00569 else if (symaddr == (__address) -1) {
00570 symtab_print_search(argv->buffer);
00571 printf("Duplicate symbol, be more specific.\n");
00572 } else {
00573 symbol = get_symtab_entry(symaddr);
00574 printf("Calling f(0x%zx,0x%zx): %.*p: %s\n",
00575 arg1, arg2, sizeof(__address) * 2, symaddr, symbol);
00576 #ifdef ia64
00577 fptr.f = symaddr;
00578 fptr.gp = ((__native *)cmd_call2)[1];
00579 f = (__native (*)(__native,__native,...)) &fptr;
00580 #else
00581 f = (__native (*)(__native,__native,...)) symaddr;
00582 #endif
00583 printf("Result: %#zx\n", f(arg1, arg2));
00584 }
00585
00586 return 1;
00587 }
00588
00590 int cmd_call3(cmd_arg_t *argv)
00591 {
00592 __address symaddr;
00593 char *symbol;
00594 __native (*f)(__native,__native,__native,...);
00595 __native arg1 = argv[1].intval;
00596 __native arg2 = argv[2].intval;
00597 __native arg3 = argv[3].intval;
00598 #ifdef ia64
00599 struct {
00600 __native f;
00601 __native gp;
00602 }fptr;
00603 #endif
00604
00605 symaddr = get_symbol_addr(argv->buffer);
00606 if (!symaddr)
00607 printf("Symbol %s not found.\n", argv->buffer);
00608 else if (symaddr == (__address) -1) {
00609 symtab_print_search(argv->buffer);
00610 printf("Duplicate symbol, be more specific.\n");
00611 } else {
00612 symbol = get_symtab_entry(symaddr);
00613 printf("Calling f(0x%zx,0x%zx, 0x%zx): %.*p: %s\n",
00614 arg1, arg2, arg3, sizeof(__address) * 2, symaddr, symbol);
00615 #ifdef ia64
00616 fptr.f = symaddr;
00617 fptr.gp = ((__native *)cmd_call2)[1];
00618 f = (__native (*)(__native,__native,__native,...)) &fptr;
00619 #else
00620 f = (__native (*)(__native,__native,__native,...)) symaddr;
00621 #endif
00622 printf("Result: %#zx\n", f(arg1, arg2, arg3));
00623 }
00624
00625 return 1;
00626 }
00627
00628
00630 void desc_help(void)
00631 {
00632 printf("Syntax: describe command_name\n");
00633 }
00634
00641 int cmd_halt(cmd_arg_t *argv)
00642 {
00643 halt();
00644 return 1;
00645 }
00646
00653 int cmd_tlb(cmd_arg_t *argv)
00654 {
00655 tlb_print();
00656 return 1;
00657 }
00658
00660 int cmd_set4(cmd_arg_t *argv)
00661 {
00662 __u32 *addr ;
00663 __u32 arg1 = argv[1].intval;
00664 bool pointer = false;
00665
00666 if (((char *)argv->buffer)[0] == '*') {
00667 addr = (__u32 *) get_symbol_addr(argv->buffer+1);
00668 pointer = true;
00669 } else if (((char *)argv->buffer)[0] >= '0' &&
00670 ((char *)argv->buffer)[0] <= '9')
00671 addr = (__u32 *)atoi((char *)argv->buffer);
00672 else
00673 addr = (__u32 *)get_symbol_addr(argv->buffer);
00674
00675 if (!addr)
00676 printf("Symbol %s not found.\n", argv->buffer);
00677 else if (addr == (__u32 *) -1) {
00678 symtab_print_search(argv->buffer);
00679 printf("Duplicate symbol, be more specific.\n");
00680 } else {
00681 if (pointer)
00682 addr = (__u32 *)(*(__native *)addr);
00683 printf("Writing 0x%x -> %.*p\n", arg1, sizeof(__address) * 2, addr);
00684 *addr = arg1;
00685
00686 }
00687
00688 return 1;
00689 }
00690
00697 int cmd_slabs(cmd_arg_t * argv) {
00698 slab_print_list();
00699 return 1;
00700 }
00701
00702
00709 int cmd_threads(cmd_arg_t * argv) {
00710 thread_print_list();
00711 return 1;
00712 }
00713
00720 int cmd_tasks(cmd_arg_t * argv) {
00721 task_print_list();
00722 return 1;
00723 }
00724
00731 int cmd_sched(cmd_arg_t * argv) {
00732 sched_print_list();
00733 return 1;
00734 }
00735
00742 int cmd_zones(cmd_arg_t * argv) {
00743 zone_print_list();
00744 return 1;
00745 }
00746
00753 int cmd_zone(cmd_arg_t * argv) {
00754 zone_print_one(argv[0].intval);
00755 return 1;
00756 }
00757
00764 int cmd_ipc_task(cmd_arg_t * argv) {
00765 ipc_print_task(argv[0].intval);
00766 return 1;
00767 }
00768
00769
00776 int cmd_cpus(cmd_arg_t *argv)
00777 {
00778 cpu_list();
00779 return 1;
00780 }
00781
00788 int cmd_version(cmd_arg_t *argv)
00789 {
00790 version_print();
00791 return 1;
00792 }
00793
00800 int cmd_continue(cmd_arg_t *argv)
00801 {
00802 printf("The kernel will now relinquish the console.\n");
00803 printf("Use userspace controls to redraw the screen.\n");
00804 arch_release_console();
00805 ipc_irq_send_msg(IPC_IRQ_KBDRESTART, 0, 0, 0);
00806 return 1;
00807 }
00808