source: mainline/kernel/generic/src/console/cmd.c@ 319e60e

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 319e60e was 319e60e, checked in by Martin Decky <martin@…>, 19 years ago

prepare for new test infrastructure

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