cmd.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2005 Jakub Jermar
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  * - Redistributions in binary form must reproduce the above copyright
00012  *   notice, this list of conditions and the following disclaimer in the
00013  *   documentation and/or other materials provided with the distribution.
00014  * - The name of the author may not be used to endorse or promote products
00015  *   derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00019  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00022  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00024  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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 /* Data and methods for 'help' command. */
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 /* Data and methods for 'description' command. */
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 /* Data and methods for 'symaddr' command. */
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 /* Data and methods for 'call0' command. */
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 /* Data and methods for 'call1' command. */
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 /* Data and methods for 'call2' command. */
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 /* Data and methods for 'call3' command. */
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 /* Data and methods for 'halt' command. */
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 /* Data and methods for 'tlb' command. */
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 /* Data and methods for 'zones' command */
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 /* Data and methods for 'ipc_task' command */
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 /* Data and methods for 'zone' command */
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 /* Data and methods for 'cpus' command. */
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 /* Data and methods for 'version' command. */
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 

Generated on Sun Jun 18 17:28:03 2006 for HelenOS Kernel (ppc64) by  doxygen 1.4.6