Subversion Repositories HelenOS-historic

Rev

Rev 602 | Rev 609 | 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. static char set_buf[MAX_CMDLINE+1];
  96. static int cmd_set4(cmd_arg_t *argv);
  97. static cmd_arg_t set4_argv[] = {
  98.     {
  99.         .type = ARG_TYPE_STRING,
  100.         .buffer = set_buf,
  101.         .len = sizeof(set_buf)
  102.     },
  103.     {
  104.         .type = ARG_TYPE_INT
  105.     }
  106. };
  107. static cmd_info_t set4_info = {
  108.     .name = "set4",
  109.     .description = "set <dest_addr> <value> - 4byte version",
  110.     .func = cmd_set4,
  111.     .argc = 2,
  112.     .argv = set4_argv
  113. };
  114.  
  115.  
  116. /** Data and methods for 'call0' command. */
  117. static char call0_buf[MAX_CMDLINE+1];
  118. static char carg1_buf[MAX_CMDLINE+1];
  119. static char carg2_buf[MAX_CMDLINE+1];
  120. static char carg3_buf[MAX_CMDLINE+1];
  121.  
  122. static int cmd_call0(cmd_arg_t *argv);
  123. static cmd_arg_t call0_argv = {
  124.     .type = ARG_TYPE_STRING,
  125.     .buffer = call0_buf,
  126.     .len = sizeof(call0_buf)
  127. };
  128. static cmd_info_t call0_info = {
  129.     .name = "call0",
  130.     .description = "call0 <function> -> call function().",
  131.     .func = cmd_call0,
  132.     .argc = 1,
  133.     .argv = &call0_argv
  134. };
  135.  
  136. /** Data and methods for 'call1' command. */
  137. static int cmd_call1(cmd_arg_t *argv);
  138. static cmd_arg_t call1_argv[] = {
  139.     {
  140.         .type = ARG_TYPE_STRING,
  141.         .buffer = call0_buf,
  142.         .len = sizeof(call0_buf)
  143.     },
  144.     {
  145.         .type = ARG_TYPE_VAR,
  146.         .buffer = carg1_buf,
  147.         .len = sizeof(carg1_buf)
  148.     }
  149. };
  150. static cmd_info_t call1_info = {
  151.     .name = "call1",
  152.     .description = "call1 <function> <arg1> -> call function(arg1).",
  153.     .func = cmd_call1,
  154.     .argc = 2,
  155.     .argv = call1_argv
  156. };
  157.  
  158. /** Data and methods for 'call2' command. */
  159. static int cmd_call2(cmd_arg_t *argv);
  160. static cmd_arg_t call2_argv[] = {
  161.     {
  162.         .type = ARG_TYPE_STRING,
  163.         .buffer = call0_buf,
  164.         .len = sizeof(call0_buf)
  165.     },
  166.     {
  167.         .type = ARG_TYPE_VAR,
  168.         .buffer = carg1_buf,
  169.         .len = sizeof(carg1_buf)
  170.     },
  171.     {
  172.         .type = ARG_TYPE_VAR,
  173.         .buffer = carg2_buf,
  174.         .len = sizeof(carg2_buf)
  175.     }
  176. };
  177. static cmd_info_t call2_info = {
  178.     .name = "call2",
  179.     .description = "call2 <function> <arg1> <arg2> -> call function(arg1,arg2).",
  180.     .func = cmd_call2,
  181.     .argc = 3,
  182.     .argv = call2_argv
  183. };
  184.  
  185. /** Data and methods for 'call3' command. */
  186. static int cmd_call3(cmd_arg_t *argv);
  187. static cmd_arg_t call3_argv[] = {
  188.     {
  189.         .type = ARG_TYPE_STRING,
  190.         .buffer = call0_buf,
  191.         .len = sizeof(call0_buf)
  192.     },
  193.     {
  194.         .type = ARG_TYPE_VAR,
  195.         .buffer = carg1_buf,
  196.         .len = sizeof(carg1_buf)
  197.     },
  198.     {
  199.         .type = ARG_TYPE_VAR,
  200.         .buffer = carg2_buf,
  201.         .len = sizeof(carg2_buf)
  202.     },
  203.     {
  204.         .type = ARG_TYPE_VAR,
  205.         .buffer = carg3_buf,
  206.         .len = sizeof(carg3_buf)
  207.     }
  208.  
  209. };
  210. static cmd_info_t call3_info = {
  211.     .name = "call3",
  212.     .description = "call3 <function> <arg1> <arg2> <arg3> -> call function(arg1,arg2,arg3).",
  213.     .func = cmd_call3,
  214.     .argc = 4,
  215.     .argv = call3_argv
  216. };
  217.  
  218. /** Data and methods for 'halt' command. */
  219. static int cmd_halt(cmd_arg_t *argv);
  220. static cmd_info_t halt_info = {
  221.     .name = "halt",
  222.     .description = "Halt the kernel.",
  223.     .func = cmd_halt,
  224.     .argc = 0
  225. };
  226.  
  227. /** Data and methods for 'ptlb' command. */
  228. static int cmd_ptlb(cmd_arg_t *argv);
  229. cmd_info_t ptlb_info = {
  230.     .name = "ptlb",
  231.     .description = "Print TLB of current processor.",
  232.     .help = NULL,
  233.     .func = cmd_ptlb,
  234.     .argc = 0,
  235.     .argv = NULL
  236. };
  237.  
  238. /** Initialize command info structure.
  239.  *
  240.  * @param cmd Command info structure.
  241.  *
  242.  */
  243. void cmd_initialize(cmd_info_t *cmd)
  244. {
  245.     spinlock_initialize(&cmd->lock, "cmd");
  246.     link_initialize(&cmd->link);
  247. }
  248.  
  249. /** Initialize and register commands. */
  250. void cmd_init(void)
  251. {
  252.     cmd_initialize(&help_info);
  253.     if (!cmd_register(&help_info))
  254.         panic("could not register command %s\n", help_info.name);
  255.  
  256.     cmd_initialize(&desc_info);
  257.     if (!cmd_register(&desc_info))
  258.         panic("could not register command %s\n", desc_info.name);
  259.    
  260.     cmd_initialize(&symaddr_info);
  261.     if (!cmd_register(&symaddr_info))
  262.         panic("could not register command %s\n", symaddr_info.name);
  263.  
  264.     cmd_initialize(&call0_info);
  265.     if (!cmd_register(&call0_info))
  266.         panic("could not register command %s\n", call0_info.name);
  267.  
  268.     cmd_initialize(&call1_info);
  269.     if (!cmd_register(&call1_info))
  270.         panic("could not register command %s\n", call1_info.name);
  271.  
  272.     cmd_initialize(&call2_info);
  273.     if (!cmd_register(&call2_info))
  274.         panic("could not register command %s\n", call2_info.name);
  275.  
  276.     cmd_initialize(&call3_info);
  277.     if (!cmd_register(&call3_info))
  278.         panic("could not register command %s\n", call3_info.name);
  279.  
  280.     cmd_initialize(&set4_info);
  281.     if (!cmd_register(&set4_info))
  282.         panic("could not register command %s\n", set4_info.name);
  283.    
  284.     cmd_initialize(&halt_info);
  285.     if (!cmd_register(&halt_info))
  286.         panic("could not register command %s\n", halt_info.name);
  287.  
  288.     cmd_initialize(&ptlb_info);
  289.     if (!cmd_register(&ptlb_info))
  290.         panic("could not register command %s\n", ptlb_info.name);
  291. }
  292.  
  293.  
  294. /** List supported commands.
  295.  *
  296.  * @param argv Argument vector.
  297.  *
  298.  * @return 0 on failure, 1 on success.
  299.  */
  300. int cmd_help(cmd_arg_t *argv)
  301. {
  302.     link_t *cur;
  303.     ipl_t ipl;
  304.  
  305.     spinlock_lock(&cmd_lock);
  306.    
  307.     for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
  308.         cmd_info_t *hlp;
  309.        
  310.         hlp = list_get_instance(cur, cmd_info_t, link);
  311.         spinlock_lock(&hlp->lock);
  312.        
  313.         printf("%s - %s\n", hlp->name, hlp->description);
  314.  
  315.         spinlock_unlock(&hlp->lock);
  316.     }
  317.    
  318.     spinlock_unlock(&cmd_lock);
  319.  
  320.     return 1;
  321. }
  322.  
  323. /** Describe specified command.
  324.  *
  325.  * @param argv Argument vector.
  326.  *
  327.  * @return 0 on failure, 1 on success.
  328.  */
  329. int cmd_desc(cmd_arg_t *argv)
  330. {
  331.     link_t *cur;
  332.     ipl_t ipl;
  333.  
  334.     spinlock_lock(&cmd_lock);
  335.    
  336.     for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
  337.         cmd_info_t *hlp;
  338.        
  339.         hlp = list_get_instance(cur, cmd_info_t, link);
  340.         spinlock_lock(&hlp->lock);
  341.  
  342.         if (strncmp(hlp->name, (const char *) argv->buffer, strlen(hlp->name)) == 0) {
  343.             printf("%s - %s\n", hlp->name, hlp->description);
  344.             if (hlp->help)
  345.                 hlp->help();
  346.             spinlock_unlock(&hlp->lock);
  347.             break;
  348.         }
  349.  
  350.         spinlock_unlock(&hlp->lock);
  351.     }
  352.    
  353.     spinlock_unlock(&cmd_lock);
  354.  
  355.     return 1;
  356. }
  357.  
  358. /** Search symbol table */
  359. int cmd_symaddr(cmd_arg_t *argv)
  360. {
  361.     __address symaddr;
  362.     char *symbol;
  363.  
  364.     symtab_print_search(argv->buffer);
  365.    
  366.     return 1;
  367. }
  368.  
  369. /** Call function with zero parameters */
  370. int cmd_call0(cmd_arg_t *argv)
  371. {
  372.     __address symaddr;
  373.     char *symbol;
  374.     __native (*f)(void);
  375.  
  376.     symaddr = get_symbol_addr(argv->buffer);
  377.     if (!symaddr)
  378.         printf("Symbol %s not found.\n", argv->buffer);
  379.     else if (symaddr == (__address) -1) {
  380.         symtab_print_search(argv->buffer);
  381.         printf("Duplicate symbol, be more specific.\n");
  382.     } else {
  383.         symbol = get_symtab_entry(symaddr);
  384.         printf("Calling f(): 0x%p: %s\n", symaddr, symbol);
  385.         f =  (__native (*)(void)) symaddr;
  386.         printf("Result: 0x%p\n", f());
  387.     }
  388.    
  389.     return 1;
  390. }
  391.  
  392. /** Call function with one parameter */
  393. int cmd_call1(cmd_arg_t *argv)
  394. {
  395.     __address symaddr;
  396.     char *symbol;
  397.     __native (*f)(__native);
  398.     __native arg1 = argv[1].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%p: %s\n", arg1, symaddr, symbol);
  409.         f =  (__native (*)(__native)) symaddr;
  410.         printf("Result: 0x%p\n", f(arg1));
  411.     }
  412.    
  413.     return 1;
  414. }
  415.  
  416. /** Call function with two parameters */
  417. int cmd_call2(cmd_arg_t *argv)
  418. {
  419.     __address symaddr;
  420.     char *symbol;
  421.     __native (*f)(__native,__native);
  422.     __native arg1 = argv[1].intval;
  423.     __native arg2 = argv[2].intval;
  424.  
  425.     symaddr = get_symbol_addr(argv->buffer);
  426.     if (!symaddr)
  427.         printf("Symbol %s not found.\n", argv->buffer);
  428.     else if (symaddr == (__address) -1) {
  429.         symtab_print_search(argv->buffer);
  430.         printf("Duplicate symbol, be more specific.\n");
  431.     } else {
  432.         symbol = get_symtab_entry(symaddr);
  433.         printf("Calling f(0x%x,0x%x): 0x%p: %s\n",
  434.                arg1, arg2, symaddr, symbol);
  435.         f =  (__native (*)(__native,__native)) symaddr;
  436.         printf("Result: 0x%p\n", f(arg1, arg2));
  437.     }
  438.    
  439.     return 1;
  440. }
  441.  
  442. /** Call function with three parameters */
  443. int cmd_call3(cmd_arg_t *argv)
  444. {
  445.     __address symaddr;
  446.     char *symbol;
  447.     __native (*f)(__native,__native,__native);
  448.     __native arg1 = argv[1].intval;
  449.     __native arg2 = argv[2].intval;
  450.     __native arg3 = argv[3].intval;
  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%x,0x%x, 0x%x): 0x%p: %s\n",
  461.                arg1, arg2, arg3, symaddr, symbol);
  462.         f =  (__native (*)(__native,__native,__native)) symaddr;
  463.         printf("Result: 0x%p\n", f(arg1, arg2, arg3));
  464.     }
  465.    
  466.     return 1;
  467. }
  468.  
  469.  
  470. /** Print detailed description of 'describe' command. */
  471. void desc_help(void)
  472. {
  473.     printf("Syntax: describe command_name\n");
  474. }
  475.  
  476. /** Halt the kernel.
  477.  *
  478.  * @param argv Argument vector (ignored).
  479.  *
  480.  * @return 0 on failure, 1 on success (never returns).
  481.  */
  482. int cmd_halt(cmd_arg_t *argv)
  483. {
  484.     halt();
  485.     return 1;
  486. }
  487.  
  488. /** Command for printing TLB contents.
  489.  *
  490.  * @param argv Not used.
  491.  *
  492.  * @return Always returns 1.
  493.  */
  494. int cmd_ptlb(cmd_arg_t *argv)
  495. {
  496.     tlb_print();
  497.     return 1;
  498. }
  499.  
  500. /** Write 4 byte value to address */
  501. int cmd_set4(cmd_arg_t *argv)
  502. {
  503.     char *symbol;
  504.     __u32 *addr ;
  505.     __u32 arg1 = argv[1].intval;
  506.     bool pointer = false;
  507.  
  508.     if (((char *)argv->buffer)[0] == '*') {
  509.         addr = (__u32 *) get_symbol_addr(argv->buffer+1);
  510.         pointer = true;
  511.     } else if (((char *)argv->buffer)[0] >= '0' &&
  512.            ((char *)argv->buffer)[0] <= '9')
  513.         addr = (__u32 *)atoi((char *)argv->buffer);
  514.     else
  515.         addr = (__u32 *)get_symbol_addr(argv->buffer);
  516.  
  517.     if (!addr)
  518.         printf("Symbol %s not found.\n", argv->buffer);
  519.     else if (addr == (__u32 *) -1) {
  520.         symtab_print_search(argv->buffer);
  521.         printf("Duplicate symbol, be more specific.\n");
  522.     } else {
  523.         if (pointer)
  524.             addr = (__u32 *)*addr;
  525.         printf("Writing 0x%x -> 0x%p\n", arg1, addr);
  526.         *addr = arg1;
  527.        
  528.     }
  529.    
  530.     return 1;
  531. }
  532.