Subversion Repositories HelenOS-historic

Rev

Rev 608 | Rev 625 | 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.     ipl_t ipl;
  314.  
  315.     spinlock_lock(&cmd_lock);
  316.    
  317.     for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
  318.         cmd_info_t *hlp;
  319.        
  320.         hlp = list_get_instance(cur, cmd_info_t, link);
  321.         spinlock_lock(&hlp->lock);
  322.        
  323.         printf("%s - %s\n", hlp->name, hlp->description);
  324.  
  325.         spinlock_unlock(&hlp->lock);
  326.     }
  327.    
  328.     spinlock_unlock(&cmd_lock);
  329.  
  330.     return 1;
  331. }
  332.  
  333. /** Describe specified command.
  334.  *
  335.  * @param argv Argument vector.
  336.  *
  337.  * @return 0 on failure, 1 on success.
  338.  */
  339. int cmd_desc(cmd_arg_t *argv)
  340. {
  341.     link_t *cur;
  342.     ipl_t ipl;
  343.  
  344.     spinlock_lock(&cmd_lock);
  345.    
  346.     for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
  347.         cmd_info_t *hlp;
  348.        
  349.         hlp = list_get_instance(cur, cmd_info_t, link);
  350.         spinlock_lock(&hlp->lock);
  351.  
  352.         if (strncmp(hlp->name, (const char *) argv->buffer, strlen(hlp->name)) == 0) {
  353.             printf("%s - %s\n", hlp->name, hlp->description);
  354.             if (hlp->help)
  355.                 hlp->help();
  356.             spinlock_unlock(&hlp->lock);
  357.             break;
  358.         }
  359.  
  360.         spinlock_unlock(&hlp->lock);
  361.     }
  362.    
  363.     spinlock_unlock(&cmd_lock);
  364.  
  365.     return 1;
  366. }
  367.  
  368. /** Search symbol table */
  369. int cmd_symaddr(cmd_arg_t *argv)
  370. {
  371.     __address symaddr;
  372.     char *symbol;
  373.  
  374.     symtab_print_search(argv->buffer);
  375.    
  376.     return 1;
  377. }
  378.  
  379. /** Call function with zero parameters */
  380. int cmd_call0(cmd_arg_t *argv)
  381. {
  382.     __address symaddr;
  383.     char *symbol;
  384.     __native (*f)(void);
  385.  
  386.     symaddr = get_symbol_addr(argv->buffer);
  387.     if (!symaddr)
  388.         printf("Symbol %s not found.\n", argv->buffer);
  389.     else if (symaddr == (__address) -1) {
  390.         symtab_print_search(argv->buffer);
  391.         printf("Duplicate symbol, be more specific.\n");
  392.     } else {
  393.         symbol = get_symtab_entry(symaddr);
  394.         printf("Calling f(): 0x%p: %s\n", symaddr, symbol);
  395.         f =  (__native (*)(void)) symaddr;
  396.         printf("Result: 0x%p\n", f());
  397.     }
  398.    
  399.     return 1;
  400. }
  401.  
  402. /** Call function with one parameter */
  403. int cmd_call1(cmd_arg_t *argv)
  404. {
  405.     __address symaddr;
  406.     char *symbol;
  407.     __native (*f)(__native);
  408.     __native arg1 = argv[1].intval;
  409.  
  410.     symaddr = get_symbol_addr(argv->buffer);
  411.     if (!symaddr)
  412.         printf("Symbol %s not found.\n", argv->buffer);
  413.     else if (symaddr == (__address) -1) {
  414.         symtab_print_search(argv->buffer);
  415.         printf("Duplicate symbol, be more specific.\n");
  416.     } else {
  417.         symbol = get_symtab_entry(symaddr);
  418.         printf("Calling f(0x%x): 0x%p: %s\n", arg1, symaddr, symbol);
  419.         f =  (__native (*)(__native)) symaddr;
  420.         printf("Result: 0x%p\n", f(arg1));
  421.     }
  422.    
  423.     return 1;
  424. }
  425.  
  426. /** Call function with two parameters */
  427. int cmd_call2(cmd_arg_t *argv)
  428. {
  429.     __address symaddr;
  430.     char *symbol;
  431.     __native (*f)(__native,__native);
  432.     __native arg1 = argv[1].intval;
  433.     __native arg2 = argv[2].intval;
  434.  
  435.     symaddr = get_symbol_addr(argv->buffer);
  436.     if (!symaddr)
  437.         printf("Symbol %s not found.\n", argv->buffer);
  438.     else if (symaddr == (__address) -1) {
  439.         symtab_print_search(argv->buffer);
  440.         printf("Duplicate symbol, be more specific.\n");
  441.     } else {
  442.         symbol = get_symtab_entry(symaddr);
  443.         printf("Calling f(0x%x,0x%x): 0x%p: %s\n",
  444.                arg1, arg2, symaddr, symbol);
  445.         f =  (__native (*)(__native,__native)) symaddr;
  446.         printf("Result: 0x%p\n", f(arg1, arg2));
  447.     }
  448.    
  449.     return 1;
  450. }
  451.  
  452. /** Call function with three parameters */
  453. int cmd_call3(cmd_arg_t *argv)
  454. {
  455.     __address symaddr;
  456.     char *symbol;
  457.     __native (*f)(__native,__native,__native);
  458.     __native arg1 = argv[1].intval;
  459.     __native arg2 = argv[2].intval;
  460.     __native arg3 = argv[3].intval;
  461.  
  462.     symaddr = get_symbol_addr(argv->buffer);
  463.     if (!symaddr)
  464.         printf("Symbol %s not found.\n", argv->buffer);
  465.     else if (symaddr == (__address) -1) {
  466.         symtab_print_search(argv->buffer);
  467.         printf("Duplicate symbol, be more specific.\n");
  468.     } else {
  469.         symbol = get_symtab_entry(symaddr);
  470.         printf("Calling f(0x%x,0x%x, 0x%x): 0x%p: %s\n",
  471.                arg1, arg2, arg3, symaddr, symbol);
  472.         f =  (__native (*)(__native,__native,__native)) symaddr;
  473.         printf("Result: 0x%p\n", f(arg1, arg2, arg3));
  474.     }
  475.    
  476.     return 1;
  477. }
  478.  
  479.  
  480. /** Print detailed description of 'describe' command. */
  481. void desc_help(void)
  482. {
  483.     printf("Syntax: describe command_name\n");
  484. }
  485.  
  486. /** Halt the kernel.
  487.  *
  488.  * @param argv Argument vector (ignored).
  489.  *
  490.  * @return 0 on failure, 1 on success (never returns).
  491.  */
  492. int cmd_halt(cmd_arg_t *argv)
  493. {
  494.     halt();
  495.     return 1;
  496. }
  497.  
  498. /** Command for printing TLB contents.
  499.  *
  500.  * @param argv Not used.
  501.  *
  502.  * @return Always returns 1.
  503.  */
  504. int cmd_ptlb(cmd_arg_t *argv)
  505. {
  506.     tlb_print();
  507.     return 1;
  508. }
  509.  
  510. /** Write 4 byte value to address */
  511. int cmd_set4(cmd_arg_t *argv)
  512. {
  513.     char *symbol;
  514.     __u32 *addr ;
  515.     __u32 arg1 = argv[1].intval;
  516.     bool pointer = false;
  517.  
  518.     if (((char *)argv->buffer)[0] == '*') {
  519.         addr = (__u32 *) get_symbol_addr(argv->buffer+1);
  520.         pointer = true;
  521.     } else if (((char *)argv->buffer)[0] >= '0' &&
  522.            ((char *)argv->buffer)[0] <= '9')
  523.         addr = (__u32 *)atoi((char *)argv->buffer);
  524.     else
  525.         addr = (__u32 *)get_symbol_addr(argv->buffer);
  526.  
  527.     if (!addr)
  528.         printf("Symbol %s not found.\n", argv->buffer);
  529.     else if (addr == (__u32 *) -1) {
  530.         symtab_print_search(argv->buffer);
  531.         printf("Duplicate symbol, be more specific.\n");
  532.     } else {
  533.         if (pointer)
  534.             addr = (__u32 *)(*(__native *)addr);
  535.         printf("Writing 0x%x -> 0x%p\n", arg1, addr);
  536.         *addr = arg1;
  537.        
  538.     }
  539.    
  540.     return 1;
  541. }
  542.