Subversion Repositories HelenOS

Rev

Rev 2020 | Rev 2030 | 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. /** @addtogroup genericconsole
  30.  * @{
  31.  */
  32.  
  33. /**
  34.  * @file    cmd.c
  35.  * @brief   Kernel console command wrappers.
  36.  *
  37.  * This file is meant to contain all wrapper functions for
  38.  * all kconsole commands. The point is in separating
  39.  * kconsole specific wrappers from kconsole-unaware functions
  40.  * from other subsystems.
  41.  */
  42.  
  43. #include <console/cmd.h>
  44. #include <console/console.h>
  45. #include <console/kconsole.h>
  46. #include <print.h>
  47. #include <panic.h>
  48. #include <typedefs.h>
  49. #include <arch/types.h>
  50. #include <adt/list.h>
  51. #include <arch.h>
  52. #include <func.h>
  53. #include <macros.h>
  54. #include <debug.h>
  55. #include <symtab.h>
  56. #include <cpu.h>
  57. #include <mm/tlb.h>
  58. #include <arch/mm/tlb.h>
  59. #include <mm/frame.h>
  60. #include <main/version.h>
  61. #include <mm/slab.h>
  62. #include <proc/scheduler.h>
  63. #include <proc/thread.h>
  64. #include <proc/task.h>
  65. #include <ipc/ipc.h>
  66. #include <ipc/irq.h>
  67.  
  68. #ifdef CONFIG_TEST
  69. #include <test.h>
  70. #endif
  71.  
  72. #ifdef CONFIG_BENCH
  73. #include <arch/cycle.h>
  74. #endif
  75.  
  76. /* Data and methods for 'help' command. */
  77. static int cmd_help(cmd_arg_t *argv);
  78. static cmd_info_t help_info = {
  79.     .name = "help",
  80.     .description = "List of supported commands.",
  81.     .func = cmd_help,
  82.     .argc = 0
  83. };
  84.  
  85. static cmd_info_t exit_info = {
  86.     .name = "exit",
  87.     .description = "Exit kconsole",
  88.     .argc = 0
  89. };
  90.  
  91. static int cmd_continue(cmd_arg_t *argv);
  92. static cmd_info_t continue_info = {
  93.     .name = "continue",
  94.     .description = "Return console back to userspace.",
  95.     .func = cmd_continue,
  96.     .argc = 0
  97. };
  98.  
  99. #ifdef CONFIG_TEST
  100. static int cmd_tests(cmd_arg_t *argv);
  101. static cmd_info_t tests_info = {
  102.     .name = "tests",
  103.     .description = "Print available kernel tests.",
  104.     .func = cmd_tests,
  105.     .argc = 0
  106. };
  107.  
  108. static char test_buf[MAX_CMDLINE + 1];
  109. static int cmd_test(cmd_arg_t *argv);
  110. static cmd_arg_t test_argv[] = {
  111.     {
  112.         .type = ARG_TYPE_STRING,
  113.         .buffer = test_buf,
  114.         .len = sizeof(test_buf)
  115.     }
  116. };
  117. static cmd_info_t test_info = {
  118.     .name = "test",
  119.     .description = "Run kernel test.",
  120.     .func = cmd_test,
  121.     .argc = 1,
  122.     .argv = test_argv
  123. };
  124. #endif
  125.  
  126. /* Data and methods for 'description' command. */
  127. static int cmd_desc(cmd_arg_t *argv);
  128. static void desc_help(void);
  129. static char desc_buf[MAX_CMDLINE+1];
  130. static cmd_arg_t desc_argv = {
  131.     .type = ARG_TYPE_STRING,
  132.     .buffer = desc_buf,
  133.     .len = sizeof(desc_buf)
  134. };
  135. static cmd_info_t desc_info = {
  136.     .name = "describe",
  137.     .description = "Describe specified command.",
  138.     .help = desc_help,
  139.     .func = cmd_desc,
  140.     .argc = 1,
  141.     .argv = &desc_argv
  142. };
  143.  
  144. /* Data and methods for 'symaddr' command. */
  145. static int cmd_symaddr(cmd_arg_t *argv);
  146. static char symaddr_buf[MAX_CMDLINE+1];
  147. static cmd_arg_t symaddr_argv = {
  148.     .type = ARG_TYPE_STRING,
  149.     .buffer = symaddr_buf,
  150.     .len = sizeof(symaddr_buf)
  151. };
  152. static cmd_info_t symaddr_info = {
  153.     .name = "symaddr",
  154.     .description = "Return symbol address.",
  155.     .func = cmd_symaddr,
  156.     .argc = 1,
  157.     .argv = &symaddr_argv
  158. };
  159.  
  160. static char set_buf[MAX_CMDLINE+1];
  161. static int cmd_set4(cmd_arg_t *argv);
  162. static cmd_arg_t set4_argv[] = {
  163.     {
  164.         .type = ARG_TYPE_STRING,
  165.         .buffer = set_buf,
  166.         .len = sizeof(set_buf)
  167.     },
  168.     {
  169.         .type = ARG_TYPE_INT
  170.     }
  171. };
  172. static cmd_info_t set4_info = {
  173.     .name = "set4",
  174.     .description = "set <dest_addr> <value> - 4byte version",
  175.     .func = cmd_set4,
  176.     .argc = 2,
  177.     .argv = set4_argv
  178. };
  179.  
  180. /* Data and methods for 'call0' command. */
  181. static char call0_buf[MAX_CMDLINE+1];
  182. static char carg1_buf[MAX_CMDLINE+1];
  183. static char carg2_buf[MAX_CMDLINE+1];
  184. static char carg3_buf[MAX_CMDLINE+1];
  185.  
  186. static int cmd_call0(cmd_arg_t *argv);
  187. static cmd_arg_t call0_argv = {
  188.     .type = ARG_TYPE_STRING,
  189.     .buffer = call0_buf,
  190.     .len = sizeof(call0_buf)
  191. };
  192. static cmd_info_t call0_info = {
  193.     .name = "call0",
  194.     .description = "call0 <function> -> call function().",
  195.     .func = cmd_call0,
  196.     .argc = 1,
  197.     .argv = &call0_argv
  198. };
  199.  
  200. /* Data and methods for 'call1' command. */
  201. static int cmd_call1(cmd_arg_t *argv);
  202. static cmd_arg_t call1_argv[] = {
  203.     {
  204.         .type = ARG_TYPE_STRING,
  205.         .buffer = call0_buf,
  206.         .len = sizeof(call0_buf)
  207.     },
  208.     {
  209.         .type = ARG_TYPE_VAR,
  210.         .buffer = carg1_buf,
  211.         .len = sizeof(carg1_buf)
  212.     }
  213. };
  214. static cmd_info_t call1_info = {
  215.     .name = "call1",
  216.     .description = "call1 <function> <arg1> -> call function(arg1).",
  217.     .func = cmd_call1,
  218.     .argc = 2,
  219.     .argv = call1_argv
  220. };
  221.  
  222. /* Data and methods for 'call2' command. */
  223. static int cmd_call2(cmd_arg_t *argv);
  224. static cmd_arg_t call2_argv[] = {
  225.     {
  226.         .type = ARG_TYPE_STRING,
  227.         .buffer = call0_buf,
  228.         .len = sizeof(call0_buf)
  229.     },
  230.     {
  231.         .type = ARG_TYPE_VAR,
  232.         .buffer = carg1_buf,
  233.         .len = sizeof(carg1_buf)
  234.     },
  235.     {
  236.         .type = ARG_TYPE_VAR,
  237.         .buffer = carg2_buf,
  238.         .len = sizeof(carg2_buf)
  239.     }
  240. };
  241. static cmd_info_t call2_info = {
  242.     .name = "call2",
  243.     .description = "call2 <function> <arg1> <arg2> -> call function(arg1,arg2).",
  244.     .func = cmd_call2,
  245.     .argc = 3,
  246.     .argv = call2_argv
  247. };
  248.  
  249. /* Data and methods for 'call3' command. */
  250. static int cmd_call3(cmd_arg_t *argv);
  251. static cmd_arg_t call3_argv[] = {
  252.     {
  253.         .type = ARG_TYPE_STRING,
  254.         .buffer = call0_buf,
  255.         .len = sizeof(call0_buf)
  256.     },
  257.     {
  258.         .type = ARG_TYPE_VAR,
  259.         .buffer = carg1_buf,
  260.         .len = sizeof(carg1_buf)
  261.     },
  262.     {
  263.         .type = ARG_TYPE_VAR,
  264.         .buffer = carg2_buf,
  265.         .len = sizeof(carg2_buf)
  266.     },
  267.     {
  268.         .type = ARG_TYPE_VAR,
  269.         .buffer = carg3_buf,
  270.         .len = sizeof(carg3_buf)
  271.     }
  272.  
  273. };
  274. static cmd_info_t call3_info = {
  275.     .name = "call3",
  276.     .description = "call3 <function> <arg1> <arg2> <arg3> -> call function(arg1,arg2,arg3).",
  277.     .func = cmd_call3,
  278.     .argc = 4,
  279.     .argv = call3_argv
  280. };
  281.  
  282. /* Data and methods for 'halt' command. */
  283. static int cmd_halt(cmd_arg_t *argv);
  284. static cmd_info_t halt_info = {
  285.     .name = "halt",
  286.     .description = "Halt the kernel.",
  287.     .func = cmd_halt,
  288.     .argc = 0
  289. };
  290.  
  291. /* Data and methods for 'tlb' command. */
  292. static int cmd_tlb(cmd_arg_t *argv);
  293. cmd_info_t tlb_info = {
  294.     .name = "tlb",
  295.     .description = "Print TLB of current processor.",
  296.     .help = NULL,
  297.     .func = cmd_tlb,
  298.     .argc = 0,
  299.     .argv = NULL
  300. };
  301.  
  302. static int cmd_threads(cmd_arg_t *argv);
  303. static cmd_info_t threads_info = {
  304.     .name = "threads",
  305.     .description = "List all threads.",
  306.     .func = cmd_threads,
  307.     .argc = 0
  308. };
  309.  
  310. static int cmd_tasks(cmd_arg_t *argv);
  311. static cmd_info_t tasks_info = {
  312.     .name = "tasks",
  313.     .description = "List all tasks.",
  314.     .func = cmd_tasks,
  315.     .argc = 0
  316. };
  317.  
  318.  
  319. static int cmd_sched(cmd_arg_t *argv);
  320. static cmd_info_t sched_info = {
  321.     .name = "scheduler",
  322.     .description = "List all scheduler information.",
  323.     .func = cmd_sched,
  324.     .argc = 0
  325. };
  326.  
  327. static int cmd_slabs(cmd_arg_t *argv);
  328. static cmd_info_t slabs_info = {
  329.     .name = "slabs",
  330.     .description = "List slab caches.",
  331.     .func = cmd_slabs,
  332.     .argc = 0
  333. };
  334.  
  335. /* Data and methods for 'zones' command */
  336. static int cmd_zones(cmd_arg_t *argv);
  337. static cmd_info_t zones_info = {
  338.     .name = "zones",
  339.     .description = "List of memory zones.",
  340.     .func = cmd_zones,
  341.     .argc = 0
  342. };
  343.  
  344. /* Data and methods for 'ipc_task' command */
  345. static int cmd_ipc_task(cmd_arg_t *argv);
  346. static cmd_arg_t ipc_task_argv = {
  347.     .type = ARG_TYPE_INT,
  348. };
  349. static cmd_info_t ipc_task_info = {
  350.     .name = "ipc_task",
  351.     .description = "ipc_task <taskid> Show IPC information of given task.",
  352.     .func = cmd_ipc_task,
  353.     .argc = 1,
  354.     .argv = &ipc_task_argv
  355. };
  356.  
  357. /* Data and methods for 'zone' command */
  358. static int cmd_zone(cmd_arg_t *argv);
  359. static cmd_arg_t zone_argv = {
  360.     .type = ARG_TYPE_INT,
  361. };
  362.  
  363. static cmd_info_t zone_info = {
  364.     .name = "zone",
  365.     .description = "Show memory zone structure.",
  366.     .func = cmd_zone,
  367.     .argc = 1,
  368.     .argv = &zone_argv
  369. };
  370.  
  371. /* Data and methods for 'cpus' command. */
  372. static int cmd_cpus(cmd_arg_t *argv);
  373. cmd_info_t cpus_info = {
  374.     .name = "cpus",
  375.     .description = "List all processors.",
  376.     .help = NULL,
  377.     .func = cmd_cpus,
  378.     .argc = 0,
  379.     .argv = NULL
  380. };
  381.  
  382. /* Data and methods for 'version' command. */
  383. static int cmd_version(cmd_arg_t *argv);
  384. cmd_info_t version_info = {
  385.     .name = "version",
  386.     .description = "Print version information.",
  387.     .help = NULL,
  388.     .func = cmd_version,
  389.     .argc = 0,
  390.     .argv = NULL
  391. };
  392.  
  393. static cmd_info_t *basic_commands[] = {
  394.     &call0_info,
  395.     &call1_info,
  396.     &call2_info,
  397.     &call3_info,
  398.     &continue_info,
  399.     &cpus_info,
  400.     &desc_info,
  401.     &exit_info,
  402.     &halt_info,
  403.     &help_info,
  404.     &ipc_task_info,
  405.     &set4_info,
  406.     &slabs_info,
  407.     &symaddr_info,
  408.     &sched_info,
  409.     &threads_info,
  410.     &tasks_info,
  411.     &tlb_info,
  412.     &version_info,
  413.     &zones_info,
  414.     &zone_info,
  415. #ifdef CONFIG_TEST
  416.     &tests_info,
  417.     &test_info,
  418. #endif
  419.     NULL
  420. };
  421.  
  422.  
  423. /** Initialize command info structure.
  424.  *
  425.  * @param cmd Command info structure.
  426.  *
  427.  */
  428. void cmd_initialize(cmd_info_t *cmd)
  429. {
  430.     spinlock_initialize(&cmd->lock, "cmd");
  431.     link_initialize(&cmd->link);
  432. }
  433.  
  434. /** Initialize and register commands. */
  435. void cmd_init(void)
  436. {
  437.     int i;
  438.  
  439.     for (i=0;basic_commands[i]; i++) {
  440.         cmd_initialize(basic_commands[i]);
  441.         if (!cmd_register(basic_commands[i]))
  442.             panic("could not register command %s\n",
  443.                   basic_commands[i]->name);
  444.     }
  445. }
  446.  
  447.  
  448. /** List supported commands.
  449.  *
  450.  * @param argv Argument vector.
  451.  *
  452.  * @return 0 on failure, 1 on success.
  453.  */
  454. int cmd_help(cmd_arg_t *argv)
  455. {
  456.     link_t *cur;
  457.  
  458.     spinlock_lock(&cmd_lock);
  459.    
  460.     for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
  461.         cmd_info_t *hlp;
  462.        
  463.         hlp = list_get_instance(cur, cmd_info_t, link);
  464.         spinlock_lock(&hlp->lock);
  465.        
  466.         printf("%s - %s\n", hlp->name, hlp->description);
  467.  
  468.         spinlock_unlock(&hlp->lock);
  469.     }
  470.    
  471.     spinlock_unlock(&cmd_lock);
  472.  
  473.     return 1;
  474. }
  475.  
  476. /** Describe specified command.
  477.  *
  478.  * @param argv Argument vector.
  479.  *
  480.  * @return 0 on failure, 1 on success.
  481.  */
  482. int cmd_desc(cmd_arg_t *argv)
  483. {
  484.     link_t *cur;
  485.  
  486.     spinlock_lock(&cmd_lock);
  487.    
  488.     for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
  489.         cmd_info_t *hlp;
  490.        
  491.         hlp = list_get_instance(cur, cmd_info_t, link);
  492.         spinlock_lock(&hlp->lock);
  493.  
  494.         if (strncmp(hlp->name, (const char *) argv->buffer, strlen(hlp->name)) == 0) {
  495.             printf("%s - %s\n", hlp->name, hlp->description);
  496.             if (hlp->help)
  497.                 hlp->help();
  498.             spinlock_unlock(&hlp->lock);
  499.             break;
  500.         }
  501.  
  502.         spinlock_unlock(&hlp->lock);
  503.     }
  504.    
  505.     spinlock_unlock(&cmd_lock);
  506.  
  507.     return 1;
  508. }
  509.  
  510. /** Search symbol table */
  511. int cmd_symaddr(cmd_arg_t *argv)
  512. {
  513.     symtab_print_search(argv->buffer);
  514.    
  515.     return 1;
  516. }
  517.  
  518. /** Call function with zero parameters */
  519. int cmd_call0(cmd_arg_t *argv)
  520. {
  521.     uintptr_t symaddr;
  522.     char *symbol;
  523.     unative_t (*f)(void);
  524. #ifdef ia64
  525.     struct {
  526.         unative_t f;
  527.         unative_t gp;
  528.     }fptr;
  529. #endif
  530.  
  531.     symaddr = get_symbol_addr(argv->buffer);
  532.     if (!symaddr)
  533.         printf("Symbol %s not found.\n", argv->buffer);
  534.     else if (symaddr == (uintptr_t) -1) {
  535.         symtab_print_search(argv->buffer);
  536.         printf("Duplicate symbol, be more specific.\n");
  537.     } else {
  538.         symbol = get_symtab_entry(symaddr);
  539.         printf("Calling f(): %.*p: %s\n", sizeof(uintptr_t) * 2, symaddr, symbol);
  540. #ifdef ia64
  541.         fptr.f = symaddr;
  542.         fptr.gp = ((unative_t *)cmd_call2)[1];
  543.         f =  (unative_t (*)(void)) &fptr;
  544. #else
  545.         f =  (unative_t (*)(void)) symaddr;
  546. #endif
  547.         printf("Result: %#zx\n", f());
  548.     }
  549.    
  550.     return 1;
  551. }
  552.  
  553. /** Call function with one parameter */
  554. int cmd_call1(cmd_arg_t *argv)
  555. {
  556.     uintptr_t symaddr;
  557.     char *symbol;
  558.     unative_t (*f)(unative_t,...);
  559.     unative_t arg1 = argv[1].intval;
  560. #ifdef ia64
  561.     struct {
  562.         unative_t f;
  563.         unative_t gp;
  564.     }fptr;
  565. #endif
  566.  
  567.     symaddr = get_symbol_addr(argv->buffer);
  568.     if (!symaddr)
  569.         printf("Symbol %s not found.\n", argv->buffer);
  570.     else if (symaddr == (uintptr_t) -1) {
  571.         symtab_print_search(argv->buffer);
  572.         printf("Duplicate symbol, be more specific.\n");
  573.     } else {
  574.         symbol = get_symtab_entry(symaddr);
  575.  
  576.         printf("Calling f(%#zx): %.*p: %s\n", arg1, sizeof(uintptr_t) * 2, symaddr, symbol);
  577. #ifdef ia64
  578.         fptr.f = symaddr;
  579.         fptr.gp = ((unative_t *)cmd_call2)[1];
  580.         f =  (unative_t (*)(unative_t,...)) &fptr;
  581. #else
  582.         f =  (unative_t (*)(unative_t,...)) symaddr;
  583. #endif
  584.         printf("Result: %#zx\n", f(arg1));
  585.     }
  586.    
  587.     return 1;
  588. }
  589.  
  590. /** Call function with two parameters */
  591. int cmd_call2(cmd_arg_t *argv)
  592. {
  593.     uintptr_t symaddr;
  594.     char *symbol;
  595.     unative_t (*f)(unative_t,unative_t,...);
  596.     unative_t arg1 = argv[1].intval;
  597.     unative_t arg2 = argv[2].intval;
  598. #ifdef ia64
  599.     struct {
  600.         unative_t f;
  601.         unative_t gp;
  602.     }fptr;
  603. #endif
  604.  
  605.     symaddr = get_symbol_addr(argv->buffer);
  606.     if (!symaddr)
  607.         printf("Symbol %s not found.\n", argv->buffer);
  608.     else if (symaddr == (uintptr_t) -1) {
  609.         symtab_print_search(argv->buffer);
  610.         printf("Duplicate symbol, be more specific.\n");
  611.     } else {
  612.         symbol = get_symtab_entry(symaddr);
  613.         printf("Calling f(0x%zx,0x%zx): %.*p: %s\n",
  614.                arg1, arg2, sizeof(uintptr_t) * 2, symaddr, symbol);
  615. #ifdef ia64
  616.         fptr.f = symaddr;
  617.         fptr.gp = ((unative_t *)cmd_call2)[1];
  618.         f =  (unative_t (*)(unative_t,unative_t,...)) &fptr;
  619. #else
  620.         f =  (unative_t (*)(unative_t,unative_t,...)) symaddr;
  621. #endif
  622.         printf("Result: %#zx\n", f(arg1, arg2));
  623.     }
  624.    
  625.     return 1;
  626. }
  627.  
  628. /** Call function with three parameters */
  629. int cmd_call3(cmd_arg_t *argv)
  630. {
  631.     uintptr_t symaddr;
  632.     char *symbol;
  633.     unative_t (*f)(unative_t,unative_t,unative_t,...);
  634.     unative_t arg1 = argv[1].intval;
  635.     unative_t arg2 = argv[2].intval;
  636.     unative_t arg3 = argv[3].intval;
  637. #ifdef ia64
  638.     struct {
  639.         unative_t f;
  640.         unative_t gp;
  641.     }fptr;
  642. #endif
  643.  
  644.     symaddr = get_symbol_addr(argv->buffer);
  645.     if (!symaddr)
  646.         printf("Symbol %s not found.\n", argv->buffer);
  647.     else if (symaddr == (uintptr_t) -1) {
  648.         symtab_print_search(argv->buffer);
  649.         printf("Duplicate symbol, be more specific.\n");
  650.     } else {
  651.         symbol = get_symtab_entry(symaddr);
  652.         printf("Calling f(0x%zx,0x%zx, 0x%zx): %.*p: %s\n",
  653.                arg1, arg2, arg3, sizeof(uintptr_t) * 2, symaddr, symbol);
  654. #ifdef ia64
  655.         fptr.f = symaddr;
  656.         fptr.gp = ((unative_t *)cmd_call2)[1];
  657.         f =  (unative_t (*)(unative_t,unative_t,unative_t,...)) &fptr;
  658. #else
  659.         f =  (unative_t (*)(unative_t,unative_t,unative_t,...)) symaddr;
  660. #endif
  661.         printf("Result: %#zx\n", f(arg1, arg2, arg3));
  662.     }
  663.    
  664.     return 1;
  665. }
  666.  
  667.  
  668. /** Print detailed description of 'describe' command. */
  669. void desc_help(void)
  670. {
  671.     printf("Syntax: describe command_name\n");
  672. }
  673.  
  674. /** Halt the kernel.
  675.  *
  676.  * @param argv Argument vector (ignored).
  677.  *
  678.  * @return 0 on failure, 1 on success (never returns).
  679.  */
  680. int cmd_halt(cmd_arg_t *argv)
  681. {
  682.     halt();
  683.     return 1;
  684. }
  685.  
  686. /** Command for printing TLB contents.
  687.  *
  688.  * @param argv Not used.
  689.  *
  690.  * @return Always returns 1.
  691.  */
  692. int cmd_tlb(cmd_arg_t *argv)
  693. {
  694.     tlb_print();
  695.     return 1;
  696. }
  697.  
  698. /** Write 4 byte value to address */
  699. int cmd_set4(cmd_arg_t *argv)
  700. {
  701.     uint32_t *addr ;
  702.     uint32_t arg1 = argv[1].intval;
  703.     bool pointer = false;
  704.  
  705.     if (((char *)argv->buffer)[0] == '*') {
  706.         addr = (uint32_t *) get_symbol_addr(argv->buffer+1);
  707.         pointer = true;
  708.     } else if (((char *)argv->buffer)[0] >= '0' &&
  709.            ((char *)argv->buffer)[0] <= '9')
  710.         addr = (uint32_t *)atoi((char *)argv->buffer);
  711.     else
  712.         addr = (uint32_t *)get_symbol_addr(argv->buffer);
  713.  
  714.     if (!addr)
  715.         printf("Symbol %s not found.\n", argv->buffer);
  716.     else if (addr == (uint32_t *) -1) {
  717.         symtab_print_search(argv->buffer);
  718.         printf("Duplicate symbol, be more specific.\n");
  719.     } else {
  720.         if (pointer)
  721.             addr = (uint32_t *)(*(unative_t *)addr);
  722.         printf("Writing 0x%x -> %.*p\n", arg1, sizeof(uintptr_t) * 2, addr);
  723.         *addr = arg1;
  724.        
  725.     }
  726.    
  727.     return 1;
  728. }
  729.  
  730. /** Command for listings SLAB caches
  731.  *
  732.  * @param argv Ignores
  733.  *
  734.  * @return Always 1
  735.  */
  736. int cmd_slabs(cmd_arg_t * argv) {
  737.     slab_print_list();
  738.     return 1;
  739. }
  740.  
  741.  
  742. /** Command for listings Thread information
  743.  *
  744.  * @param argv Ignores
  745.  *
  746.  * @return Always 1
  747.  */
  748. int cmd_threads(cmd_arg_t * argv) {
  749.     thread_print_list();
  750.     return 1;
  751. }
  752.  
  753. /** Command for listings Task information
  754.  *
  755.  * @param argv Ignores
  756.  *
  757.  * @return Always 1
  758.  */
  759. int cmd_tasks(cmd_arg_t * argv) {
  760.     task_print_list();
  761.     return 1;
  762. }
  763.  
  764. /** Command for listings Thread information
  765.  *
  766.  * @param argv Ignores
  767.  *
  768.  * @return Always 1
  769.  */
  770. int cmd_sched(cmd_arg_t * argv) {
  771.     sched_print_list();
  772.     return 1;
  773. }
  774.  
  775. /** Command for listing memory zones
  776.  *
  777.  * @param argv Ignored
  778.  *
  779.  * return Always 1
  780.  */
  781. int cmd_zones(cmd_arg_t * argv) {
  782.     zone_print_list();
  783.     return 1;
  784. }
  785.  
  786. /** Command for memory zone details
  787.  *
  788.  * @param argv Integer argument from cmdline expected
  789.  *
  790.  * return Always 1
  791.  */
  792. int cmd_zone(cmd_arg_t * argv) {
  793.     zone_print_one(argv[0].intval);
  794.     return 1;
  795. }
  796.  
  797. /** Command for printing task ipc details
  798.  *
  799.  * @param argv Integer argument from cmdline expected
  800.  *
  801.  * return Always 1
  802.  */
  803. int cmd_ipc_task(cmd_arg_t * argv) {
  804.     ipc_print_task(argv[0].intval);
  805.     return 1;
  806. }
  807.  
  808.  
  809. /** Command for listing processors.
  810.  *
  811.  * @param argv Ignored.
  812.  *
  813.  * return Always 1.
  814.  */
  815. int cmd_cpus(cmd_arg_t *argv)
  816. {
  817.     cpu_list();
  818.     return 1;
  819. }
  820.  
  821. /** Command for printing kernel version.
  822.  *
  823.  * @param argv Ignored.
  824.  *
  825.  * return Always 1.
  826.  */
  827. int cmd_version(cmd_arg_t *argv)
  828. {
  829.     version_print();
  830.     return 1;
  831. }
  832.  
  833. /** Command for returning console back to userspace.
  834.  *
  835.  * @param argv Ignored.
  836.  *
  837.  * return Always 1.
  838.  */
  839. int cmd_continue(cmd_arg_t *argv)
  840. {
  841.     printf("The kernel will now relinquish the console.\n");
  842.     printf("Use userspace controls to redraw the screen.\n");
  843.     arch_release_console();
  844.     return 1;
  845. }
  846.  
  847. #ifdef CONFIG_TEST
  848. /** Command for printing kernel tests list.
  849.  *
  850.  * @param argv Ignored.
  851.  *
  852.  * return Always 1.
  853.  */
  854. int cmd_tests(cmd_arg_t *argv)
  855. {
  856.     test_t *test;
  857.    
  858.     for (test = tests; test->name != NULL; test++)
  859.         printf("%s\t\t%s%s\n", test->name, test->desc, (test->safe ? "" : " (unsafe)"));
  860.    
  861.     printf("*\t\tRun all safe tests\n");
  862.     return 1;
  863. }
  864.  
  865. static bool run_test(const test_t * test)
  866. {
  867.     printf("%s\t\t%s\n", test->name, test->desc);
  868. #ifdef CONFIG_BENCH
  869.     uint64_t t0 = get_cycle();
  870. #endif
  871.     char * ret = test->entry();
  872. #ifdef CONFIG_BENCH
  873.     uint64_t dt = get_cycle() - t0;
  874.     printf("Time: %llu cycles\n", dt);
  875. #endif
  876.    
  877.     if (ret == NULL) {
  878.         printf("Test passed\n");
  879.         return true;
  880.     }
  881.  
  882.     printf("%s\n", ret);
  883.     return false;
  884. }
  885.  
  886. /** Command for returning kernel tests
  887.  *
  888.  * @param argv Argument vector.
  889.  *
  890.  * return Always 1.
  891.  */
  892. int cmd_test(cmd_arg_t *argv)
  893. {
  894.     test_t *test;
  895.    
  896.     if (strcmp(argv->buffer, "*") == 0) {
  897.         for (test = tests; test->name != NULL; test++) {
  898.             if (test->safe) {
  899.                 printf("\n");
  900.                 if (!run_test(test))
  901.                     break;
  902.             }
  903.         }
  904.     } else {
  905.         bool fnd = false;
  906.        
  907.         for (test = tests; test->name != NULL; test++) {
  908.             if (strcmp(test->name, argv->buffer) == 0) {
  909.                 fnd = true;
  910.                 run_test(test);
  911.                 break;
  912.             }
  913.         }
  914.        
  915.         if (!fnd)
  916.             printf("Unknown test\n");
  917.     }
  918.    
  919.     return 1;
  920. }
  921. #endif
  922.  
  923. /** @}
  924.  */
  925.