Subversion Repositories HelenOS-historic

Rev

Rev 668 | Rev 676 | 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 char zone_buf[MAX_CMDLINE+1];
  258. static cmd_arg_t zone_argv = {
  259.     .type = ARG_TYPE_INT,
  260.     .buffer = zone_buf,
  261.     .len = sizeof(zone_buf)
  262. };
  263.  
  264. static cmd_info_t zone_info = {
  265.     .name = "zone",
  266.     .description = "Show memory zone structure.",
  267.     .func = cmd_zone,
  268.     .argc = 1,
  269.     .argv = &zone_argv
  270. };
  271.  
  272. /** Data and methods for 'cpus' command. */
  273. static int cmd_cpus(cmd_arg_t *argv);
  274. cmd_info_t cpus_info = {
  275.     .name = "cpus",
  276.     .description = "List all processors.",
  277.     .help = NULL,
  278.     .func = cmd_cpus,
  279.     .argc = 0,
  280.     .argv = NULL
  281. };
  282.  
  283. /** Data and methods for 'version' command. */
  284. static int cmd_version(cmd_arg_t *argv);
  285. cmd_info_t version_info = {
  286.     .name = "version",
  287.     .description = "Print version information.",
  288.     .help = NULL,
  289.     .func = cmd_version,
  290.     .argc = 0,
  291.     .argv = NULL
  292. };
  293.  
  294.  
  295.  
  296.  
  297. /** Initialize command info structure.
  298.  *
  299.  * @param cmd Command info structure.
  300.  *
  301.  */
  302. void cmd_initialize(cmd_info_t *cmd)
  303. {
  304.     spinlock_initialize(&cmd->lock, "cmd");
  305.     link_initialize(&cmd->link);
  306. }
  307.  
  308. /** Initialize and register commands. */
  309. void cmd_init(void)
  310. {
  311.     cmd_initialize(&help_info);
  312.     if (!cmd_register(&help_info))
  313.         panic("could not register command %s\n", help_info.name);
  314.  
  315.     cmd_initialize(&desc_info);
  316.     if (!cmd_register(&desc_info))
  317.         panic("could not register command %s\n", desc_info.name);
  318.  
  319.     cmd_initialize(&exit_info);
  320.     if (!cmd_register(&exit_info))
  321.         panic("could not register command %s\n", exit_info.name);
  322.    
  323.     cmd_initialize(&symaddr_info);
  324.     if (!cmd_register(&symaddr_info))
  325.         panic("could not register command %s\n", symaddr_info.name);
  326.  
  327.     cmd_initialize(&call0_info);
  328.     if (!cmd_register(&call0_info))
  329.         panic("could not register command %s\n", call0_info.name);
  330.  
  331.     cmd_initialize(&call1_info);
  332.     if (!cmd_register(&call1_info))
  333.         panic("could not register command %s\n", call1_info.name);
  334.  
  335.     cmd_initialize(&call2_info);
  336.     if (!cmd_register(&call2_info))
  337.         panic("could not register command %s\n", call2_info.name);
  338.  
  339.     cmd_initialize(&call3_info);
  340.     if (!cmd_register(&call3_info))
  341.         panic("could not register command %s\n", call3_info.name);
  342.  
  343.     cmd_initialize(&set4_info);
  344.     if (!cmd_register(&set4_info))
  345.         panic("could not register command %s\n", set4_info.name);
  346.    
  347.     cmd_initialize(&halt_info);
  348.     if (!cmd_register(&halt_info))
  349.         panic("could not register command %s\n", halt_info.name);
  350.  
  351.     cmd_initialize(&tlb_info);
  352.     if (!cmd_register(&tlb_info))
  353.         panic("could not register command %s\n", tlb_info.name);
  354.  
  355.     cmd_initialize(&zones_info);
  356.     if (!cmd_register(&zones_info))
  357.         panic("could not register command %s\n", zones_info.name);
  358.  
  359.     cmd_initialize(&zone_info);
  360.     if (!cmd_register(&zone_info))
  361.         panic("could not register command %s\n", zone_info.name);
  362.  
  363.     cmd_initialize(&cpus_info);
  364.     if (!cmd_register(&cpus_info))
  365.         panic("could not register command %s\n", cpus_info.name);
  366.        
  367.     cmd_initialize(&version_info);
  368.     if (!cmd_register(&version_info))
  369.         panic("could not register command %s\n", version_info.name);
  370.        
  371.        
  372.  
  373. }
  374.  
  375.  
  376. /** List supported commands.
  377.  *
  378.  * @param argv Argument vector.
  379.  *
  380.  * @return 0 on failure, 1 on success.
  381.  */
  382. int cmd_help(cmd_arg_t *argv)
  383. {
  384.     link_t *cur;
  385.  
  386.     spinlock_lock(&cmd_lock);
  387.    
  388.     for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
  389.         cmd_info_t *hlp;
  390.        
  391.         hlp = list_get_instance(cur, cmd_info_t, link);
  392.         spinlock_lock(&hlp->lock);
  393.        
  394.         printf("%s - %s\n", hlp->name, hlp->description);
  395.  
  396.         spinlock_unlock(&hlp->lock);
  397.     }
  398.    
  399.     spinlock_unlock(&cmd_lock);
  400.  
  401.     return 1;
  402. }
  403.  
  404. /** Describe specified command.
  405.  *
  406.  * @param argv Argument vector.
  407.  *
  408.  * @return 0 on failure, 1 on success.
  409.  */
  410. int cmd_desc(cmd_arg_t *argv)
  411. {
  412.     link_t *cur;
  413.  
  414.     spinlock_lock(&cmd_lock);
  415.    
  416.     for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
  417.         cmd_info_t *hlp;
  418.        
  419.         hlp = list_get_instance(cur, cmd_info_t, link);
  420.         spinlock_lock(&hlp->lock);
  421.  
  422.         if (strncmp(hlp->name, (const char *) argv->buffer, strlen(hlp->name)) == 0) {
  423.             printf("%s - %s\n", hlp->name, hlp->description);
  424.             if (hlp->help)
  425.                 hlp->help();
  426.             spinlock_unlock(&hlp->lock);
  427.             break;
  428.         }
  429.  
  430.         spinlock_unlock(&hlp->lock);
  431.     }
  432.    
  433.     spinlock_unlock(&cmd_lock);
  434.  
  435.     return 1;
  436. }
  437.  
  438. /** Search symbol table */
  439. int cmd_symaddr(cmd_arg_t *argv)
  440. {
  441.     symtab_print_search(argv->buffer);
  442.    
  443.     return 1;
  444. }
  445.  
  446. /** Call function with zero parameters */
  447. int cmd_call0(cmd_arg_t *argv)
  448. {
  449.     __address symaddr;
  450.     char *symbol;
  451.     __native (*f)(void);
  452.  
  453.     symaddr = get_symbol_addr(argv->buffer);
  454.     if (!symaddr)
  455.         printf("Symbol %s not found.\n", argv->buffer);
  456.     else if (symaddr == (__address) -1) {
  457.         symtab_print_search(argv->buffer);
  458.         printf("Duplicate symbol, be more specific.\n");
  459.     } else {
  460.         symbol = get_symtab_entry(symaddr);
  461.         printf("Calling f(): 0x%p: %s\n", symaddr, symbol);
  462.         f =  (__native (*)(void)) symaddr;
  463.         printf("Result: 0x%p\n", f());
  464.     }
  465.    
  466.     return 1;
  467. }
  468.  
  469. /** Call function with one parameter */
  470. int cmd_call1(cmd_arg_t *argv)
  471. {
  472.     __address symaddr;
  473.     char *symbol;
  474.     __native (*f)(__native);
  475.     __native arg1 = argv[1].intval;
  476.  
  477.     symaddr = get_symbol_addr(argv->buffer);
  478.     if (!symaddr)
  479.         printf("Symbol %s not found.\n", argv->buffer);
  480.     else if (symaddr == (__address) -1) {
  481.         symtab_print_search(argv->buffer);
  482.         printf("Duplicate symbol, be more specific.\n");
  483.     } else {
  484.         symbol = get_symtab_entry(symaddr);
  485.         printf("Calling f(0x%x): 0x%p: %s\n", arg1, symaddr, symbol);
  486.         f =  (__native (*)(__native)) symaddr;
  487.         printf("Result: 0x%p\n", f(arg1));
  488.     }
  489.    
  490.     return 1;
  491. }
  492.  
  493. /** Call function with two parameters */
  494. int cmd_call2(cmd_arg_t *argv)
  495. {
  496.     __address symaddr;
  497.     char *symbol;
  498.     __native (*f)(__native,__native);
  499.     __native arg1 = argv[1].intval;
  500.     __native arg2 = argv[2].intval;
  501.  
  502.     symaddr = get_symbol_addr(argv->buffer);
  503.     if (!symaddr)
  504.         printf("Symbol %s not found.\n", argv->buffer);
  505.     else if (symaddr == (__address) -1) {
  506.         symtab_print_search(argv->buffer);
  507.         printf("Duplicate symbol, be more specific.\n");
  508.     } else {
  509.         symbol = get_symtab_entry(symaddr);
  510.         printf("Calling f(0x%x,0x%x): 0x%p: %s\n",
  511.                arg1, arg2, symaddr, symbol);
  512.         f =  (__native (*)(__native,__native)) symaddr;
  513.         printf("Result: 0x%p\n", f(arg1, arg2));
  514.     }
  515.    
  516.     return 1;
  517. }
  518.  
  519. /** Call function with three parameters */
  520. int cmd_call3(cmd_arg_t *argv)
  521. {
  522.     __address symaddr;
  523.     char *symbol;
  524.     __native (*f)(__native,__native,__native);
  525.     __native arg1 = argv[1].intval;
  526.     __native arg2 = argv[2].intval;
  527.     __native arg3 = argv[3].intval;
  528.  
  529.     symaddr = get_symbol_addr(argv->buffer);
  530.     if (!symaddr)
  531.         printf("Symbol %s not found.\n", argv->buffer);
  532.     else if (symaddr == (__address) -1) {
  533.         symtab_print_search(argv->buffer);
  534.         printf("Duplicate symbol, be more specific.\n");
  535.     } else {
  536.         symbol = get_symtab_entry(symaddr);
  537.         printf("Calling f(0x%x,0x%x, 0x%x): 0x%p: %s\n",
  538.                arg1, arg2, arg3, symaddr, symbol);
  539.         f =  (__native (*)(__native,__native,__native)) symaddr;
  540.         printf("Result: 0x%p\n", f(arg1, arg2, arg3));
  541.     }
  542.    
  543.     return 1;
  544. }
  545.  
  546.  
  547. /** Print detailed description of 'describe' command. */
  548. void desc_help(void)
  549. {
  550.     printf("Syntax: describe command_name\n");
  551. }
  552.  
  553. /** Halt the kernel.
  554.  *
  555.  * @param argv Argument vector (ignored).
  556.  *
  557.  * @return 0 on failure, 1 on success (never returns).
  558.  */
  559. int cmd_halt(cmd_arg_t *argv)
  560. {
  561.     halt();
  562.     return 1;
  563. }
  564.  
  565. /** Command for printing TLB contents.
  566.  *
  567.  * @param argv Not used.
  568.  *
  569.  * @return Always returns 1.
  570.  */
  571. int cmd_tlb(cmd_arg_t *argv)
  572. {
  573.     tlb_print();
  574.     return 1;
  575. }
  576.  
  577. /** Write 4 byte value to address */
  578. int cmd_set4(cmd_arg_t *argv)
  579. {
  580.     __u32 *addr ;
  581.     __u32 arg1 = argv[1].intval;
  582.     bool pointer = false;
  583.  
  584.     if (((char *)argv->buffer)[0] == '*') {
  585.         addr = (__u32 *) get_symbol_addr(argv->buffer+1);
  586.         pointer = true;
  587.     } else if (((char *)argv->buffer)[0] >= '0' &&
  588.            ((char *)argv->buffer)[0] <= '9')
  589.         addr = (__u32 *)atoi((char *)argv->buffer);
  590.     else
  591.         addr = (__u32 *)get_symbol_addr(argv->buffer);
  592.  
  593.     if (!addr)
  594.         printf("Symbol %s not found.\n", argv->buffer);
  595.     else if (addr == (__u32 *) -1) {
  596.         symtab_print_search(argv->buffer);
  597.         printf("Duplicate symbol, be more specific.\n");
  598.     } else {
  599.         if (pointer)
  600.             addr = (__u32 *)(*(__native *)addr);
  601.         printf("Writing 0x%x -> 0x%p\n", arg1, addr);
  602.         *addr = arg1;
  603.        
  604.     }
  605.    
  606.     return 1;
  607. }
  608.  
  609. int cmd_zones(cmd_arg_t * argv) {
  610.     printf("Zones listing not implemented\n");
  611.     return 1;
  612. }
  613.  
  614. int cmd_zone(cmd_arg_t * argv) {
  615.     printf("Zone details not implemented\n");
  616.     return 1;
  617. }
  618.  
  619. /** Command for listing processors.
  620.  *
  621.  * @param argv Ignored.
  622.  *
  623.  * return Always 1.
  624.  */
  625. int cmd_cpus(cmd_arg_t *argv)
  626. {
  627.     cpu_list();
  628.     return 1;
  629. }
  630.  
  631. /** Command for printing kernel version.
  632.  *
  633.  * @param argv Ignored.
  634.  *
  635.  * return Always 1.
  636.  */
  637. int cmd_version(cmd_arg_t *argv)
  638. {
  639.     version_print();
  640.     return 1;
  641. }
  642.