Subversion Repositories HelenOS-historic

Rev

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