Subversion Repositories HelenOS

Rev

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