Subversion Repositories HelenOS-historic

Rev

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