Subversion Repositories HelenOS

Rev

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