Subversion Repositories HelenOS-historic

Rev

Rev 596 | Rev 603 | 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.  
  49. #include <mm/tlb.h>
  50. #include <arch/mm/tlb.h>
  51.  
  52. /** Data and methods for 'help' command. */
  53. static int cmd_help(cmd_arg_t *argv);
  54. static cmd_info_t help_info = {
  55.     .name = "help",
  56.     .description = "List of supported commands.",
  57.     .func = cmd_help,
  58.     .argc = 0
  59. };
  60.  
  61. /** Data and methods for 'description' command. */
  62. static int cmd_desc(cmd_arg_t *argv);
  63. static void desc_help(void);
  64. static char desc_buf[MAX_CMDLINE+1];
  65. static cmd_arg_t desc_argv = {
  66.     .type = ARG_TYPE_STRING,
  67.     .buffer = desc_buf,
  68.     .len = sizeof(desc_buf)
  69. };
  70. static cmd_info_t desc_info = {
  71.     .name = "describe",
  72.     .description = "Describe specified command.",
  73.     .help = desc_help,
  74.     .func = cmd_desc,
  75.     .argc = 1,
  76.     .argv = &desc_argv
  77. };
  78.  
  79. /** Data and methods for 'symaddr' command. */
  80. static int cmd_symaddr(cmd_arg_t *argv);
  81. static char symaddr_buf[MAX_CMDLINE+1];
  82. static cmd_arg_t symaddr_argv = {
  83.     .type = ARG_TYPE_STRING,
  84.     .buffer = symaddr_buf,
  85.     .len = sizeof(symaddr_buf)
  86. };
  87. static cmd_info_t symaddr_info = {
  88.     .name = "symaddr",
  89.     .description = "Return symbol address.",
  90.     .func = cmd_symaddr,
  91.     .argc = 1,
  92.     .argv = &symaddr_argv
  93. };
  94.  
  95. /** Data and methods for 'call0' command. */
  96. static char call0_buf[MAX_CMDLINE+1];
  97. static char carg1_buf[MAX_CMDLINE+1];
  98. static char carg2_buf[MAX_CMDLINE+1];
  99. static char carg3_buf[MAX_CMDLINE+1];
  100.  
  101. static int cmd_call0(cmd_arg_t *argv);
  102. static cmd_arg_t call0_argv = {
  103.     .type = ARG_TYPE_STRING,
  104.     .buffer = call0_buf,
  105.     .len = sizeof(call0_buf)
  106. };
  107. static cmd_info_t call0_info = {
  108.     .name = "call0",
  109.     .description = "call0 <function> -> call function().",
  110.     .func = cmd_call0,
  111.     .argc = 1,
  112.     .argv = &call0_argv
  113. };
  114.  
  115. /** Data and methods for 'call1' command. */
  116. static int cmd_call1(cmd_arg_t *argv);
  117. static cmd_arg_t call1_argv[] = {
  118.     {
  119.         .type = ARG_TYPE_STRING,
  120.         .buffer = call0_buf,
  121.         .len = sizeof(call0_buf)
  122.     },
  123.     {
  124.         .type = ARG_TYPE_VAR,
  125.         .buffer = carg1_buf,
  126.         .len = sizeof(carg1_buf)
  127.     }
  128. };
  129. static cmd_info_t call1_info = {
  130.     .name = "call1",
  131.     .description = "call1 <function> <arg1> -> call function(arg1).",
  132.     .func = cmd_call1,
  133.     .argc = 2,
  134.     .argv = call1_argv
  135. };
  136.  
  137. /** Data and methods for 'call2' command. */
  138. static int cmd_call2(cmd_arg_t *argv);
  139. static cmd_arg_t call2_argv[] = {
  140.     {
  141.         .type = ARG_TYPE_STRING,
  142.         .buffer = call0_buf,
  143.         .len = sizeof(call0_buf)
  144.     },
  145.     {
  146.         .type = ARG_TYPE_VAR,
  147.         .buffer = carg1_buf,
  148.         .len = sizeof(carg1_buf)
  149.     },
  150.     {
  151.         .type = ARG_TYPE_VAR,
  152.         .buffer = carg2_buf,
  153.         .len = sizeof(carg2_buf)
  154.     }
  155. };
  156. static cmd_info_t call2_info = {
  157.     .name = "call2",
  158.     .description = "call2 <function> <arg1> <arg2> -> call function(arg1,arg2).",
  159.     .func = cmd_call2,
  160.     .argc = 3,
  161.     .argv = call2_argv
  162. };
  163.  
  164. /** Data and methods for 'call3' command. */
  165. static int cmd_call3(cmd_arg_t *argv);
  166. static cmd_arg_t call3_argv[] = {
  167.     {
  168.         .type = ARG_TYPE_STRING,
  169.         .buffer = call0_buf,
  170.         .len = sizeof(call0_buf)
  171.     },
  172.     {
  173.         .type = ARG_TYPE_VAR,
  174.         .buffer = carg1_buf,
  175.         .len = sizeof(carg1_buf)
  176.     },
  177.     {
  178.         .type = ARG_TYPE_VAR,
  179.         .buffer = carg2_buf,
  180.         .len = sizeof(carg2_buf)
  181.     },
  182.     {
  183.         .type = ARG_TYPE_VAR,
  184.         .buffer = carg3_buf,
  185.         .len = sizeof(carg3_buf)
  186.     }
  187.  
  188. };
  189. static cmd_info_t call3_info = {
  190.     .name = "call3",
  191.     .description = "call3 <function> <arg1> <arg2> <arg3> -> call function(arg1,arg2,arg3).",
  192.     .func = cmd_call3,
  193.     .argc = 4,
  194.     .argv = call3_argv
  195. };
  196.  
  197. /** Data and methods for 'halt' command. */
  198. static int cmd_halt(cmd_arg_t *argv);
  199. static cmd_info_t halt_info = {
  200.     .name = "halt",
  201.     .description = "Halt the kernel.",
  202.     .func = cmd_halt,
  203.     .argc = 0
  204. };
  205.  
  206. /** Data and methods for 'ptlb' command. */
  207. static int cmd_ptlb(cmd_arg_t *argv);
  208. cmd_info_t ptlb_info = {
  209.     .name = "ptlb",
  210.     .description = "Print TLB of current processor.",
  211.     .help = NULL,
  212.     .func = cmd_ptlb,
  213.     .argc = 0,
  214.     .argv = NULL
  215. };
  216.  
  217. /** Initialize command info structure.
  218.  *
  219.  * @param cmd Command info structure.
  220.  *
  221.  */
  222. void cmd_initialize(cmd_info_t *cmd)
  223. {
  224.     spinlock_initialize(&cmd->lock, "cmd");
  225.     link_initialize(&cmd->link);
  226. }
  227.  
  228. /** Initialize and register commands. */
  229. void cmd_init(void)
  230. {
  231.     cmd_initialize(&help_info);
  232.     if (!cmd_register(&help_info))
  233.         panic("could not register command %s\n", help_info.name);
  234.  
  235.     cmd_initialize(&desc_info);
  236.     if (!cmd_register(&desc_info))
  237.         panic("could not register command %s\n", desc_info.name);
  238.    
  239.     cmd_initialize(&symaddr_info);
  240.     if (!cmd_register(&symaddr_info))
  241.         panic("could not register command %s\n", symaddr_info.name);
  242.  
  243.     cmd_initialize(&call0_info);
  244.     if (!cmd_register(&call0_info))
  245.         panic("could not register command %s\n", call0_info.name);
  246.  
  247.     cmd_initialize(&call1_info);
  248.     if (!cmd_register(&call1_info))
  249.         panic("could not register command %s\n", call1_info.name);
  250.  
  251.     cmd_initialize(&call2_info);
  252.     if (!cmd_register(&call2_info))
  253.         panic("could not register command %s\n", call2_info.name);
  254.  
  255.     cmd_initialize(&call3_info);
  256.     if (!cmd_register(&call3_info))
  257.         panic("could not register command %s\n", call3_info.name);
  258.    
  259.     cmd_initialize(&halt_info);
  260.     if (!cmd_register(&halt_info))
  261.         panic("could not register command %s\n", halt_info.name);
  262.  
  263.     cmd_initialize(&ptlb_info);
  264.     if (!cmd_register(&ptlb_info))
  265.         panic("could not register command %s\n", ptlb_info.name);
  266. }
  267.  
  268.  
  269. /** List supported commands.
  270.  *
  271.  * @param argv Argument vector.
  272.  *
  273.  * @return 0 on failure, 1 on success.
  274.  */
  275. int cmd_help(cmd_arg_t *argv)
  276. {
  277.     link_t *cur;
  278.     ipl_t ipl;
  279.  
  280.     spinlock_lock(&cmd_lock);
  281.    
  282.     for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
  283.         cmd_info_t *hlp;
  284.        
  285.         hlp = list_get_instance(cur, cmd_info_t, link);
  286.         spinlock_lock(&hlp->lock);
  287.        
  288.         printf("%s - %s\n", hlp->name, hlp->description);
  289.  
  290.         spinlock_unlock(&hlp->lock);
  291.     }
  292.    
  293.     spinlock_unlock(&cmd_lock);
  294.  
  295.     return 1;
  296. }
  297.  
  298. /** Describe specified command.
  299.  *
  300.  * @param argv Argument vector.
  301.  *
  302.  * @return 0 on failure, 1 on success.
  303.  */
  304. int cmd_desc(cmd_arg_t *argv)
  305. {
  306.     link_t *cur;
  307.     ipl_t ipl;
  308.  
  309.     spinlock_lock(&cmd_lock);
  310.    
  311.     for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
  312.         cmd_info_t *hlp;
  313.        
  314.         hlp = list_get_instance(cur, cmd_info_t, link);
  315.         spinlock_lock(&hlp->lock);
  316.  
  317.         if (strncmp(hlp->name, (const char *) argv->buffer, strlen(hlp->name)) == 0) {
  318.             printf("%s - %s\n", hlp->name, hlp->description);
  319.             if (hlp->help)
  320.                 hlp->help();
  321.             spinlock_unlock(&hlp->lock);
  322.             break;
  323.         }
  324.  
  325.         spinlock_unlock(&hlp->lock);
  326.     }
  327.    
  328.     spinlock_unlock(&cmd_lock);
  329.  
  330.     return 1;
  331. }
  332.  
  333. /** Search symbol table */
  334. int cmd_symaddr(cmd_arg_t *argv)
  335. {
  336.     __address symaddr;
  337.     char *symbol;
  338.  
  339.     symtab_print_search(argv->buffer);
  340.    
  341.     return 1;
  342. }
  343.  
  344. /** Call function with zero parameters */
  345. int cmd_call0(cmd_arg_t *argv)
  346. {
  347.     __address symaddr;
  348.     char *symbol;
  349.     __native (*f)(void);
  350.  
  351.     symaddr = get_symbol_addr(argv->buffer);
  352.     if (!symaddr)
  353.         printf("Symbol %s not found.\n", argv->buffer);
  354.     else if (symaddr == (__address) -1) {
  355.         symtab_print_search(argv->buffer);
  356.         printf("Duplicate symbol, be more specific.\n");
  357.     } else {
  358.         symbol = get_symtab_entry(symaddr);
  359.         printf("Calling f(): 0x%p: %s\n", symaddr, symbol);
  360.         f =  (__native (*)(void)) symaddr;
  361.         printf("Result: 0x%p\n", f());
  362.     }
  363.    
  364.     return 1;
  365. }
  366.  
  367. /** Call function with one parameter */
  368. int cmd_call1(cmd_arg_t *argv)
  369. {
  370.     __address symaddr;
  371.     char *symbol;
  372.     __native (*f)(__native);
  373.     __native arg1 = argv[1].intval;
  374.  
  375.     symaddr = get_symbol_addr(argv->buffer);
  376.     if (!symaddr)
  377.         printf("Symbol %s not found.\n", argv->buffer);
  378.     else if (symaddr == (__address) -1) {
  379.         symtab_print_search(argv->buffer);
  380.         printf("Duplicate symbol, be more specific.\n");
  381.     } else {
  382.         symbol = get_symtab_entry(symaddr);
  383.         printf("Calling f(0x%x): 0x%p: %s\n", arg1, symaddr, symbol);
  384.         f =  (__native (*)(__native)) symaddr;
  385.         printf("Result: 0x%p\n", f(arg1));
  386.     }
  387.    
  388.     return 1;
  389. }
  390.  
  391. /** Call function with two parameters */
  392. int cmd_call2(cmd_arg_t *argv)
  393. {
  394.     __address symaddr;
  395.     char *symbol;
  396.     __native (*f)(__native,__native);
  397.     __native arg1 = argv[1].intval;
  398.     __native arg2 = argv[2].intval;
  399.  
  400.     symaddr = get_symbol_addr(argv->buffer);
  401.     if (!symaddr)
  402.         printf("Symbol %s not found.\n", argv->buffer);
  403.     else if (symaddr == (__address) -1) {
  404.         symtab_print_search(argv->buffer);
  405.         printf("Duplicate symbol, be more specific.\n");
  406.     } else {
  407.         symbol = get_symtab_entry(symaddr);
  408.         printf("Calling f(0x%x,0x%x): 0x%p: %s\n",
  409.                arg1, arg2, symaddr, symbol);
  410.         f =  (__native (*)(__native,__native)) symaddr;
  411.         printf("Result: 0x%p\n", f(arg1, arg2));
  412.     }
  413.    
  414.     return 1;
  415. }
  416.  
  417. /** Call function with three parameters */
  418. int cmd_call3(cmd_arg_t *argv)
  419. {
  420.     __address symaddr;
  421.     char *symbol;
  422.     __native (*f)(__native,__native,__native);
  423.     __native arg1 = argv[1].intval;
  424.     __native arg2 = argv[2].intval;
  425.     __native arg3 = argv[3].intval;
  426.  
  427.     symaddr = get_symbol_addr(argv->buffer);
  428.     if (!symaddr)
  429.         printf("Symbol %s not found.\n", argv->buffer);
  430.     else if (symaddr == (__address) -1) {
  431.         symtab_print_search(argv->buffer);
  432.         printf("Duplicate symbol, be more specific.\n");
  433.     } else {
  434.         symbol = get_symtab_entry(symaddr);
  435.         printf("Calling f(0x%x,0x%x, 0x%x): 0x%p: %s\n",
  436.                arg1, arg2, arg3, symaddr, symbol);
  437.         f =  (__native (*)(__native,__native,__native)) symaddr;
  438.         printf("Result: 0x%p\n", f(arg1, arg2, arg3));
  439.     }
  440.    
  441.     return 1;
  442. }
  443.  
  444.  
  445. /** Print detailed description of 'describe' command. */
  446. void desc_help(void)
  447. {
  448.     printf("Syntax: describe command_name\n");
  449. }
  450.  
  451. /** Halt the kernel.
  452.  *
  453.  * @param argv Argument vector (ignored).
  454.  *
  455.  * @return 0 on failure, 1 on success (never returns).
  456.  */
  457. int cmd_halt(cmd_arg_t *argv)
  458. {
  459.     halt();
  460.     return 1;
  461. }
  462.  
  463. /** Command for printing TLB contents.
  464.  *
  465.  * @param argv Not used.
  466.  *
  467.  * @return Always returns 1.
  468.  */
  469. int cmd_ptlb(cmd_arg_t *argv)
  470. {
  471.     tlb_print();
  472.     return 1;
  473. }
  474.