Subversion Repositories HelenOS-historic

Rev

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