Subversion Repositories HelenOS-historic

Rev

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