Subversion Repositories HelenOS-historic

Rev

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