Subversion Repositories HelenOS-historic

Rev

Rev 788 | Rev 1060 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (C) 2005 Jakub Jermar
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  *
  9.  * - Redistributions of source code must retain the above copyright
  10.  *   notice, this list of conditions and the following disclaimer.
  11.  * - Redistributions in binary form must reproduce the above copyright
  12.  *   notice, this list of conditions and the following disclaimer in the
  13.  *   documentation and/or other materials provided with the distribution.
  14.  * - The name of the author may not be used to endorse or promote products
  15.  *   derived from this software without specific prior written permission.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  */
  28.  
  29. /**
  30.  * This file is meant to contain all wrapper functions for
  31.  * all kconsole commands. The point is in separating
  32.  * kconsole specific wrappers from kconsole-unaware functions
  33.  * from other subsystems.
  34.  */
  35.  
  36. #include <console/cmd.h>
  37. #include <console/kconsole.h>
  38. #include <print.h>
  39. #include <panic.h>
  40. #include <typedefs.h>
  41. #include <arch/types.h>
  42. #include <adt/list.h>
  43. #include <arch.h>
  44. #include <func.h>
  45. #include <macros.h>
  46. #include <debug.h>
  47. #include <symtab.h>
  48. #include <cpu.h>
  49. #include <mm/tlb.h>
  50. #include <arch/mm/tlb.h>
  51. #include <mm/frame.h>
  52. #include <main/version.h>
  53. #include <mm/slab.h>
  54. #include <proc/scheduler.h>
  55. #include <proc/thread.h>
  56.  
  57. /** Data and methods for 'help' command. */
  58. static int cmd_help(cmd_arg_t *argv);
  59. static cmd_info_t help_info = {
  60.     .name = "help",
  61.     .description = "List of supported commands.",
  62.     .func = cmd_help,
  63.     .argc = 0
  64. };
  65.  
  66. static cmd_info_t exit_info = {
  67.     .name = "exit",
  68.     .description ="Exit kconsole",
  69.     .argc = 0
  70. };
  71.  
  72. /** Data and methods for 'description' command. */
  73. static int cmd_desc(cmd_arg_t *argv);
  74. static void desc_help(void);
  75. static char desc_buf[MAX_CMDLINE+1];
  76. static cmd_arg_t desc_argv = {
  77.     .type = ARG_TYPE_STRING,
  78.     .buffer = desc_buf,
  79.     .len = sizeof(desc_buf)
  80. };
  81. static cmd_info_t desc_info = {
  82.     .name = "describe",
  83.     .description = "Describe specified command.",
  84.     .help = desc_help,
  85.     .func = cmd_desc,
  86.     .argc = 1,
  87.     .argv = &desc_argv
  88. };
  89.  
  90. /** Data and methods for 'symaddr' command. */
  91. static int cmd_symaddr(cmd_arg_t *argv);
  92. static char symaddr_buf[MAX_CMDLINE+1];
  93. static cmd_arg_t symaddr_argv = {
  94.     .type = ARG_TYPE_STRING,
  95.     .buffer = symaddr_buf,
  96.     .len = sizeof(symaddr_buf)
  97. };
  98. static cmd_info_t symaddr_info = {
  99.     .name = "symaddr",
  100.     .description = "Return symbol address.",
  101.     .func = cmd_symaddr,
  102.     .argc = 1,
  103.     .argv = &symaddr_argv
  104. };
  105.  
  106. static char set_buf[MAX_CMDLINE+1];
  107. static int cmd_set4(cmd_arg_t *argv);
  108. static cmd_arg_t set4_argv[] = {
  109.     {
  110.         .type = ARG_TYPE_STRING,
  111.         .buffer = set_buf,
  112.         .len = sizeof(set_buf)
  113.     },
  114.     {
  115.         .type = ARG_TYPE_INT
  116.     }
  117. };
  118. static cmd_info_t set4_info = {
  119.     .name = "set4",
  120.     .description = "set <dest_addr> <value> - 4byte version",
  121.     .func = cmd_set4,
  122.     .argc = 2,
  123.     .argv = set4_argv
  124. };
  125.  
  126. /** Data and methods for 'call0' command. */
  127. static char call0_buf[MAX_CMDLINE+1];
  128. static char carg1_buf[MAX_CMDLINE+1];
  129. static char carg2_buf[MAX_CMDLINE+1];
  130. static char carg3_buf[MAX_CMDLINE+1];
  131.  
  132. static int cmd_call0(cmd_arg_t *argv);
  133. static cmd_arg_t call0_argv = {
  134.     .type = ARG_TYPE_STRING,
  135.     .buffer = call0_buf,
  136.     .len = sizeof(call0_buf)
  137. };
  138. static cmd_info_t call0_info = {
  139.     .name = "call0",
  140.     .description = "call0 <function> -> call function().",
  141.     .func = cmd_call0,
  142.     .argc = 1,
  143.     .argv = &call0_argv
  144. };
  145.  
  146. /** Data and methods for 'call1' command. */
  147. static int cmd_call1(cmd_arg_t *argv);
  148. static cmd_arg_t call1_argv[] = {
  149.     {
  150.         .type = ARG_TYPE_STRING,
  151.         .buffer = call0_buf,
  152.         .len = sizeof(call0_buf)
  153.     },
  154.     {
  155.         .type = ARG_TYPE_VAR,
  156.         .buffer = carg1_buf,
  157.         .len = sizeof(carg1_buf)
  158.     }
  159. };
  160. static cmd_info_t call1_info = {
  161.     .name = "call1",
  162.     .description = "call1 <function> <arg1> -> call function(arg1).",
  163.     .func = cmd_call1,
  164.     .argc = 2,
  165.     .argv = call1_argv
  166. };
  167.  
  168. /** Data and methods for 'call2' command. */
  169. static int cmd_call2(cmd_arg_t *argv);
  170. static cmd_arg_t call2_argv[] = {
  171.     {
  172.         .type = ARG_TYPE_STRING,
  173.         .buffer = call0_buf,
  174.         .len = sizeof(call0_buf)
  175.     },
  176.     {
  177.         .type = ARG_TYPE_VAR,
  178.         .buffer = carg1_buf,
  179.         .len = sizeof(carg1_buf)
  180.     },
  181.     {
  182.         .type = ARG_TYPE_VAR,
  183.         .buffer = carg2_buf,
  184.         .len = sizeof(carg2_buf)
  185.     }
  186. };
  187. static cmd_info_t call2_info = {
  188.     .name = "call2",
  189.     .description = "call2 <function> <arg1> <arg2> -> call function(arg1,arg2).",
  190.     .func = cmd_call2,
  191.     .argc = 3,
  192.     .argv = call2_argv
  193. };
  194.  
  195. /** Data and methods for 'call3' command. */
  196. static int cmd_call3(cmd_arg_t *argv);
  197. static cmd_arg_t call3_argv[] = {
  198.     {
  199.         .type = ARG_TYPE_STRING,
  200.         .buffer = call0_buf,
  201.         .len = sizeof(call0_buf)
  202.     },
  203.     {
  204.         .type = ARG_TYPE_VAR,
  205.         .buffer = carg1_buf,
  206.         .len = sizeof(carg1_buf)
  207.     },
  208.     {
  209.         .type = ARG_TYPE_VAR,
  210.         .buffer = carg2_buf,
  211.         .len = sizeof(carg2_buf)
  212.     },
  213.     {
  214.         .type = ARG_TYPE_VAR,
  215.         .buffer = carg3_buf,
  216.         .len = sizeof(carg3_buf)
  217.     }
  218.  
  219. };
  220. static cmd_info_t call3_info = {
  221.     .name = "call3",
  222.     .description = "call3 <function> <arg1> <arg2> <arg3> -> call function(arg1,arg2,arg3).",
  223.     .func = cmd_call3,
  224.     .argc = 4,
  225.     .argv = call3_argv
  226. };
  227.  
  228. /** Data and methods for 'halt' command. */
  229. static int cmd_halt(cmd_arg_t *argv);
  230. static cmd_info_t halt_info = {
  231.     .name = "halt",
  232.     .description = "Halt the kernel.",
  233.     .func = cmd_halt,
  234.     .argc = 0
  235. };
  236.  
  237. /** Data and methods for 'tlb' command. */
  238. static int cmd_tlb(cmd_arg_t *argv);
  239. cmd_info_t tlb_info = {
  240.     .name = "tlb",
  241.     .description = "Print TLB of current processor.",
  242.     .help = NULL,
  243.     .func = cmd_tlb,
  244.     .argc = 0,
  245.     .argv = NULL
  246. };
  247.  
  248. static int cmd_threads(cmd_arg_t *argv);
  249. static cmd_info_t threads_info = {
  250.     .name = "threads",
  251.     .description = "List all threads",
  252.     .func = cmd_threads,
  253.     .argc = 0
  254. };
  255.  
  256.  
  257. static int cmd_sched(cmd_arg_t *argv);
  258. static cmd_info_t sched_info = {
  259.     .name = "scheduler",
  260.     .description = "List all scheduler information",
  261.     .func = cmd_sched,
  262.     .argc = 0
  263. };
  264.  
  265. static int cmd_slabs(cmd_arg_t *argv);
  266. static cmd_info_t slabs_info = {
  267.     .name = "slabs",
  268.     .description = "List SLAB caches.",
  269.     .func = cmd_slabs,
  270.     .argc = 0
  271. };
  272.  
  273. /** Data and methods for 'zones' command */
  274. static int cmd_zones(cmd_arg_t *argv);
  275. static cmd_info_t zones_info = {
  276.     .name = "zones",
  277.     .description = "List of memory zones.",
  278.     .func = cmd_zones,
  279.     .argc = 0
  280. };
  281.  
  282. /** Data and methods for 'zone' command */
  283. static int cmd_zone(cmd_arg_t *argv);
  284. static cmd_arg_t zone_argv = {
  285.     .type = ARG_TYPE_INT,
  286. };
  287.  
  288. static cmd_info_t zone_info = {
  289.     .name = "zone",
  290.     .description = "Show memory zone structure.",
  291.     .func = cmd_zone,
  292.     .argc = 1,
  293.     .argv = &zone_argv
  294. };
  295.  
  296. static int cmd_hello(cmd_arg_t *argv);
  297. static cmd_info_t hello_info = {
  298.     .name = "hello",
  299.     .description = "Hello Message",
  300.     .func = cmd_hello,
  301.     .argc = 0
  302. };
  303.  
  304. /** Data and methods for 'cpus' command. */
  305. static int cmd_cpus(cmd_arg_t *argv);
  306. cmd_info_t cpus_info = {
  307.     .name = "cpus",
  308.     .description = "List all processors.",
  309.     .help = NULL,
  310.     .func = cmd_cpus,
  311.     .argc = 0,
  312.     .argv = NULL
  313. };
  314.  
  315. /** Data and methods for 'version' command. */
  316. static int cmd_version(cmd_arg_t *argv);
  317. cmd_info_t version_info = {
  318.     .name = "version",
  319.     .description = "Print version information.",
  320.     .help = NULL,
  321.     .func = cmd_version,
  322.     .argc = 0,
  323.     .argv = NULL
  324. };
  325.  
  326. static cmd_info_t *basic_commands[] = {
  327.     &call0_info,
  328.     &call1_info,
  329.     &call2_info,
  330.     &call3_info,
  331.     &cpus_info,
  332.     &desc_info,
  333.     &exit_info,
  334.     &halt_info,
  335.     &help_info,
  336.     &set4_info,
  337.     &slabs_info,
  338.     &symaddr_info,
  339.     &sched_info,
  340.     &threads_info,
  341.     &tlb_info,
  342.     &version_info,
  343.     &zones_info,
  344.     &zone_info,
  345.     &hello_info,
  346.     NULL
  347. };
  348.  
  349.  
  350. /** Initialize command info structure.
  351.  *
  352.  * @param cmd Command info structure.
  353.  *
  354.  */
  355. void cmd_initialize(cmd_info_t *cmd)
  356. {
  357.     spinlock_initialize(&cmd->lock, "cmd");
  358.     link_initialize(&cmd->link);
  359. }
  360.  
  361. /** Initialize and register commands. */
  362. void cmd_init(void)
  363. {
  364.     int i;
  365.  
  366.     for (i=0;basic_commands[i]; i++) {
  367.         cmd_initialize(basic_commands[i]);
  368.         if (!cmd_register(basic_commands[i]))
  369.             panic("could not register command %s\n",
  370.                   basic_commands[i]->name);
  371.     }
  372. }
  373.  
  374.  
  375. /** List supported commands.
  376.  *
  377.  * @param argv Argument vector.
  378.  *
  379.  * @return 0 on failure, 1 on success.
  380.  */
  381. int cmd_help(cmd_arg_t *argv)
  382. {
  383.     link_t *cur;
  384.  
  385.     spinlock_lock(&cmd_lock);
  386.    
  387.     for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
  388.         cmd_info_t *hlp;
  389.        
  390.         hlp = list_get_instance(cur, cmd_info_t, link);
  391.         spinlock_lock(&hlp->lock);
  392.        
  393.         printf("%s - %s\n", hlp->name, hlp->description);
  394.  
  395.         spinlock_unlock(&hlp->lock);
  396.     }
  397.    
  398.     spinlock_unlock(&cmd_lock);
  399.  
  400.     return 1;
  401. }
  402.  
  403. /** Describe specified command.
  404.  *
  405.  * @param argv Argument vector.
  406.  *
  407.  * @return 0 on failure, 1 on success.
  408.  */
  409. int cmd_desc(cmd_arg_t *argv)
  410. {
  411.     link_t *cur;
  412.  
  413.     spinlock_lock(&cmd_lock);
  414.    
  415.     for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
  416.         cmd_info_t *hlp;
  417.        
  418.         hlp = list_get_instance(cur, cmd_info_t, link);
  419.         spinlock_lock(&hlp->lock);
  420.  
  421.         if (strncmp(hlp->name, (const char *) argv->buffer, strlen(hlp->name)) == 0) {
  422.             printf("%s - %s\n", hlp->name, hlp->description);
  423.             if (hlp->help)
  424.                 hlp->help();
  425.             spinlock_unlock(&hlp->lock);
  426.             break;
  427.         }
  428.  
  429.         spinlock_unlock(&hlp->lock);
  430.     }
  431.    
  432.     spinlock_unlock(&cmd_lock);
  433.  
  434.     return 1;
  435. }
  436.  
  437. /** Search symbol table */
  438. int cmd_symaddr(cmd_arg_t *argv)
  439. {
  440.     symtab_print_search(argv->buffer);
  441.    
  442.     return 1;
  443. }
  444.  
  445. /** Call function with zero parameters */
  446. int cmd_call0(cmd_arg_t *argv)
  447. {
  448.     __address symaddr;
  449.     char *symbol;
  450.     __native (*f)(void);
  451.  
  452.     symaddr = get_symbol_addr(argv->buffer);
  453.     if (!symaddr)
  454.         printf("Symbol %s not found.\n", argv->buffer);
  455.     else if (symaddr == (__address) -1) {
  456.         symtab_print_search(argv->buffer);
  457.         printf("Duplicate symbol, be more specific.\n");
  458.     } else {
  459.         symbol = get_symtab_entry(symaddr);
  460.         printf("Calling f(): 0x%p: %s\n", symaddr, symbol);
  461.         f =  (__native (*)(void)) symaddr;
  462.         printf("Result: 0x%p\n", f());
  463.     }
  464.    
  465.     return 1;
  466. }
  467.  
  468. /** Call function with one parameter */
  469. int cmd_call1(cmd_arg_t *argv)
  470. {
  471.     __address symaddr;
  472.     char *symbol;
  473.     __native (*f)(__native,...);
  474.     __native arg1 = argv[1].intval;
  475.  
  476.     symaddr = get_symbol_addr(argv->buffer);
  477.     if (!symaddr)
  478.         printf("Symbol %s not found.\n", argv->buffer);
  479.     else if (symaddr == (__address) -1) {
  480.         symtab_print_search(argv->buffer);
  481.         printf("Duplicate symbol, be more specific.\n");
  482.     } else {
  483.         symbol = get_symtab_entry(symaddr);
  484.         printf("Calling f(0x%x): 0x%p: %s\n", arg1, symaddr, symbol);
  485.         f =  (__native (*)(__native,...)) symaddr;
  486.         printf("Result: 0x%p\n", f(arg1));
  487.     }
  488.    
  489.     return 1;
  490. }
  491.  
  492. /** Call function with two parameters */
  493. int cmd_call2(cmd_arg_t *argv)
  494. {
  495.     __address symaddr;
  496.     char *symbol;
  497.     __native (*f)(__native,__native,...);
  498.     __native arg1 = argv[1].intval;
  499.     __native arg2 = argv[2].intval;
  500.  
  501.     symaddr = get_symbol_addr(argv->buffer);
  502.     if (!symaddr)
  503.         printf("Symbol %s not found.\n", argv->buffer);
  504.     else if (symaddr == (__address) -1) {
  505.         symtab_print_search(argv->buffer);
  506.         printf("Duplicate symbol, be more specific.\n");
  507.     } else {
  508.         symbol = get_symtab_entry(symaddr);
  509.         printf("Calling f(0x%x,0x%x): 0x%p: %s\n",
  510.                arg1, arg2, symaddr, symbol);
  511.         f =  (__native (*)(__native,__native,...)) symaddr;
  512.         printf("Result: 0x%p\n", f(arg1, arg2));
  513.     }
  514.    
  515.     return 1;
  516. }
  517.  
  518. /** Call function with three parameters */
  519. int cmd_call3(cmd_arg_t *argv)
  520. {
  521.     __address symaddr;
  522.     char *symbol;
  523.     __native (*f)(__native,__native,__native,...);
  524.     __native arg1 = argv[1].intval;
  525.     __native arg2 = argv[2].intval;
  526.     __native arg3 = argv[3].intval;
  527.  
  528.     symaddr = get_symbol_addr(argv->buffer);
  529.     if (!symaddr)
  530.         printf("Symbol %s not found.\n", argv->buffer);
  531.     else if (symaddr == (__address) -1) {
  532.         symtab_print_search(argv->buffer);
  533.         printf("Duplicate symbol, be more specific.\n");
  534.     } else {
  535.         symbol = get_symtab_entry(symaddr);
  536.         printf("Calling f(0x%x,0x%x, 0x%x): 0x%p: %s\n",
  537.                arg1, arg2, arg3, symaddr, symbol);
  538.         f =  (__native (*)(__native,__native,__native,...)) symaddr;
  539.         printf("Result: 0x%p\n", f(arg1, arg2, arg3));
  540.     }
  541.    
  542.     return 1;
  543. }
  544.  
  545.  
  546. /** Print detailed description of 'describe' command. */
  547. void desc_help(void)
  548. {
  549.     printf("Syntax: describe command_name\n");
  550. }
  551.  
  552. /** Halt the kernel.
  553.  *
  554.  * @param argv Argument vector (ignored).
  555.  *
  556.  * @return 0 on failure, 1 on success (never returns).
  557.  */
  558. int cmd_halt(cmd_arg_t *argv)
  559. {
  560.     halt();
  561.     return 1;
  562. }
  563.  
  564. /** Command for printing TLB contents.
  565.  *
  566.  * @param argv Not used.
  567.  *
  568.  * @return Always returns 1.
  569.  */
  570. int cmd_tlb(cmd_arg_t *argv)
  571. {
  572.     tlb_print();
  573.     return 1;
  574. }
  575.  
  576. /** Write 4 byte value to address */
  577. int cmd_set4(cmd_arg_t *argv)
  578. {
  579.     __u32 *addr ;
  580.     __u32 arg1 = argv[1].intval;
  581.     bool pointer = false;
  582.  
  583.     if (((char *)argv->buffer)[0] == '*') {
  584.         addr = (__u32 *) get_symbol_addr(argv->buffer+1);
  585.         pointer = true;
  586.     } else if (((char *)argv->buffer)[0] >= '0' &&
  587.            ((char *)argv->buffer)[0] <= '9')
  588.         addr = (__u32 *)atoi((char *)argv->buffer);
  589.     else
  590.         addr = (__u32 *)get_symbol_addr(argv->buffer);
  591.  
  592.     if (!addr)
  593.         printf("Symbol %s not found.\n", argv->buffer);
  594.     else if (addr == (__u32 *) -1) {
  595.         symtab_print_search(argv->buffer);
  596.         printf("Duplicate symbol, be more specific.\n");
  597.     } else {
  598.         if (pointer)
  599.             addr = (__u32 *)(*(__native *)addr);
  600.         printf("Writing 0x%x -> 0x%p\n", arg1, addr);
  601.         *addr = arg1;
  602.        
  603.     }
  604.    
  605.     return 1;
  606. }
  607.  
  608. /** Command for listings SLAB caches
  609.  *
  610.  * @param argv Ignores
  611.  *
  612.  * @return Always 1
  613.  */
  614. int cmd_slabs(cmd_arg_t * argv) {
  615.     slab_print_list();
  616.     return 1;
  617. }
  618.  
  619.  
  620. /** Command for listings Thread information
  621.  *
  622.  * @param argv Ignores
  623.  *
  624.  * @return Always 1
  625.  */
  626. int cmd_threads(cmd_arg_t * argv) {
  627.     thread_print_list();
  628.     return 1;
  629. }
  630.  
  631. /** Command for listings Thread information
  632.  *
  633.  * @param argv Ignores
  634.  *
  635.  * @return Always 1
  636.  */
  637. int cmd_sched(cmd_arg_t * argv) {
  638.     sched_print_list();
  639.     return 1;
  640. }
  641.  
  642. /** Command for listing memory zones
  643.  *
  644.  * @param argv Ignored
  645.  *
  646.  * return Always 1
  647.  */
  648. int cmd_zones(cmd_arg_t * argv) {
  649.     zone_print_list();
  650.     return 1;
  651. }
  652.  
  653. /** Command for memory zone details
  654.  *
  655.  * @param argv Integer argument from cmdline expected
  656.  *
  657.  * return Always 1
  658.  */
  659. int cmd_zone(cmd_arg_t * argv) {
  660.     zone_print_one(argv[0].intval);
  661.     return 1;
  662. }
  663.  
  664. /** Command for listing processors.
  665.  *
  666.  * @param argv Ignored.
  667.  *
  668.  * return Always 1.
  669.  */
  670. int cmd_cpus(cmd_arg_t *argv)
  671. {
  672.     cpu_list();
  673.     return 1;
  674. }
  675.  
  676. /** Command for printing kernel version.
  677.  *
  678.  * @param argv Ignored.
  679.  *
  680.  * return Always 1.
  681.  */
  682. int cmd_version(cmd_arg_t *argv)
  683. {
  684.     version_print();
  685.     return 1;
  686. }
  687.  
  688.  
  689. int cmd_hello(cmd_arg_t *argv)
  690. {
  691.     printf("\nHello, World !!!\n");
  692.     return 1;
  693. }
  694.