Subversion Repositories HelenOS-historic

Rev

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