source: mainline/kernel/generic/src/console/cmd.c@ 62b6d17

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

introduce uncounted threads, whose accounting doesn't affect accumulated task accounting
run tests in kconsole thread again

  • Property mode set to 100644
File size: 19.2 KB
RevLine 
[442d0ae]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
[06e1e95]29/** @addtogroup genericconsole
[b45c443]30 * @{
31 */
32
[442d0ae]33/**
[cf26ba9]34 * @file cmd.c
35 * @brief Kernel console command wrappers.
36 *
[442d0ae]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>
[41d33ac]44#include <console/console.h>
[442d0ae]45#include <console/kconsole.h>
46#include <print.h>
47#include <panic.h>
48#include <typedefs.h>
49#include <arch/types.h>
[5c9a08b]50#include <adt/list.h>
[442d0ae]51#include <arch.h>
52#include <func.h>
53#include <macros.h>
54#include <debug.h>
55#include <symtab.h>
[0132630]56#include <cpu.h>
[442d0ae]57#include <mm/tlb.h>
58#include <arch/mm/tlb.h>
[80bff342]59#include <mm/frame.h>
[0132630]60#include <main/version.h>
[4e147a6]61#include <mm/slab.h>
[10e16a7]62#include <proc/scheduler.h>
[55ab0f1]63#include <proc/thread.h>
[37c57f2]64#include <proc/task.h>
[c4e4507]65#include <ipc/ipc.h>
[62939f7]66#include <ipc/irq.h>
[442d0ae]67
[319e60e]68#ifdef CONFIG_TEST
69#include <test.h>
70#endif
71
[b45c443]72/* Data and methods for 'help' command. */
[442d0ae]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
[e07fe0c]81static cmd_info_t exit_info = {
82 .name = "exit",
[319e60e]83 .description = "Exit kconsole",
[e07fe0c]84 .argc = 0
85};
86
[41d33ac]87static int cmd_continue(cmd_arg_t *argv);
88static cmd_info_t continue_info = {
89 .name = "continue",
[319e60e]90 .description = "Return console back to userspace.",
[41d33ac]91 .func = cmd_continue,
92 .argc = 0
93};
94
[319e60e]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
[b45c443]122/* Data and methods for 'description' command. */
[442d0ae]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
[b45c443]140/* Data and methods for 'symaddr' command. */
[442d0ae]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
[ba276f7]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
[b45c443]176/* Data and methods for 'call0' command. */
[442d0ae]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
[b45c443]196/* Data and methods for 'call1' command. */
[442d0ae]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
[b45c443]218/* Data and methods for 'call2' command. */
[442d0ae]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
[b45c443]245/* Data and methods for 'call3' command. */
[442d0ae]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
[b45c443]278/* Data and methods for 'halt' command. */
[442d0ae]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
[b45c443]287/* Data and methods for 'tlb' command. */
[0132630]288static int cmd_tlb(cmd_arg_t *argv);
289cmd_info_t tlb_info = {
290 .name = "tlb",
[442d0ae]291 .description = "Print TLB of current processor.",
292 .help = NULL,
[0132630]293 .func = cmd_tlb,
[442d0ae]294 .argc = 0,
295 .argv = NULL
296};
297
[55ab0f1]298static int cmd_threads(cmd_arg_t *argv);
299static cmd_info_t threads_info = {
300 .name = "threads",
[dd054bc2]301 .description = "List all threads.",
[55ab0f1]302 .func = cmd_threads,
303 .argc = 0
304};
305
[37c57f2]306static int cmd_tasks(cmd_arg_t *argv);
307static cmd_info_t tasks_info = {
308 .name = "tasks",
[dd054bc2]309 .description = "List all tasks.",
[37c57f2]310 .func = cmd_tasks,
311 .argc = 0
312};
313
[80bff342]314
[10e16a7]315static int cmd_sched(cmd_arg_t *argv);
316static cmd_info_t sched_info = {
317 .name = "scheduler",
[dd054bc2]318 .description = "List all scheduler information.",
[10e16a7]319 .func = cmd_sched,
320 .argc = 0
321};
322
[4e147a6]323static int cmd_slabs(cmd_arg_t *argv);
324static cmd_info_t slabs_info = {
325 .name = "slabs",
[dd054bc2]326 .description = "List slab caches.",
[4e147a6]327 .func = cmd_slabs,
328 .argc = 0
329};
330
[b45c443]331/* Data and methods for 'zones' command */
[80bff342]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
[b45c443]340/* Data and methods for 'ipc_task' command */
[c4e4507]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",
[dd054bc2]347 .description = "ipc_task <taskid> Show IPC information of given task.",
[c4e4507]348 .func = cmd_ipc_task,
349 .argc = 1,
350 .argv = &ipc_task_argv
351};
352
[b45c443]353/* Data and methods for 'zone' command */
[80bff342]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
[b45c443]367/* Data and methods for 'cpus' command. */
[0132630]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
[b45c443]378/* Data and methods for 'version' command. */
[0132630]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
[10e16a7]389static cmd_info_t *basic_commands[] = {
390 &call0_info,
391 &call1_info,
392 &call2_info,
393 &call3_info,
[41d33ac]394 &continue_info,
[10e16a7]395 &cpus_info,
396 &desc_info,
397 &exit_info,
398 &halt_info,
399 &help_info,
[c4e4507]400 &ipc_task_info,
[10e16a7]401 &set4_info,
402 &slabs_info,
403 &symaddr_info,
404 &sched_info,
[55ab0f1]405 &threads_info,
[37c57f2]406 &tasks_info,
[10e16a7]407 &tlb_info,
408 &version_info,
409 &zones_info,
410 &zone_info,
[319e60e]411#ifdef CONFIG_TEST
412 &tests_info,
413 &test_info,
414#endif
[10e16a7]415 NULL
416};
[80bff342]417
418
[442d0ae]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{
[10e16a7]433 int i;
[80bff342]434
[10e16a7]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 }
[442d0ae]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{
[7f1c620]517 uintptr_t symaddr;
[442d0ae]518 char *symbol;
[7f1c620]519 unative_t (*f)(void);
[3701250]520#ifdef ia64
521 struct {
[7f1c620]522 unative_t f;
523 unative_t gp;
[3701250]524 }fptr;
525#endif
[442d0ae]526
527 symaddr = get_symbol_addr(argv->buffer);
528 if (!symaddr)
529 printf("Symbol %s not found.\n", argv->buffer);
[7f1c620]530 else if (symaddr == (uintptr_t) -1) {
[442d0ae]531 symtab_print_search(argv->buffer);
532 printf("Duplicate symbol, be more specific.\n");
533 } else {
534 symbol = get_symtab_entry(symaddr);
[7f1c620]535 printf("Calling f(): %.*p: %s\n", sizeof(uintptr_t) * 2, symaddr, symbol);
[3701250]536#ifdef ia64
537 fptr.f = symaddr;
[7f1c620]538 fptr.gp = ((unative_t *)cmd_call2)[1];
539 f = (unative_t (*)(void)) &fptr;
[3701250]540#else
[7f1c620]541 f = (unative_t (*)(void)) symaddr;
[3701250]542#endif
[ad45bde9]543 printf("Result: %#zx\n", f());
[442d0ae]544 }
545
546 return 1;
547}
548
549/** Call function with one parameter */
550int cmd_call1(cmd_arg_t *argv)
551{
[7f1c620]552 uintptr_t symaddr;
[442d0ae]553 char *symbol;
[7f1c620]554 unative_t (*f)(unative_t,...);
555 unative_t arg1 = argv[1].intval;
[3701250]556#ifdef ia64
557 struct {
[7f1c620]558 unative_t f;
559 unative_t gp;
[3701250]560 }fptr;
561#endif
[442d0ae]562
563 symaddr = get_symbol_addr(argv->buffer);
564 if (!symaddr)
565 printf("Symbol %s not found.\n", argv->buffer);
[7f1c620]566 else if (symaddr == (uintptr_t) -1) {
[442d0ae]567 symtab_print_search(argv->buffer);
568 printf("Duplicate symbol, be more specific.\n");
569 } else {
570 symbol = get_symtab_entry(symaddr);
[3701250]571
[7f1c620]572 printf("Calling f(%#zx): %.*p: %s\n", arg1, sizeof(uintptr_t) * 2, symaddr, symbol);
[3701250]573#ifdef ia64
574 fptr.f = symaddr;
[7f1c620]575 fptr.gp = ((unative_t *)cmd_call2)[1];
576 f = (unative_t (*)(unative_t,...)) &fptr;
[3701250]577#else
[7f1c620]578 f = (unative_t (*)(unative_t,...)) symaddr;
[3701250]579#endif
[ad45bde9]580 printf("Result: %#zx\n", f(arg1));
[442d0ae]581 }
582
583 return 1;
584}
585
586/** Call function with two parameters */
587int cmd_call2(cmd_arg_t *argv)
588{
[7f1c620]589 uintptr_t symaddr;
[442d0ae]590 char *symbol;
[7f1c620]591 unative_t (*f)(unative_t,unative_t,...);
592 unative_t arg1 = argv[1].intval;
593 unative_t arg2 = argv[2].intval;
[3701250]594#ifdef ia64
595 struct {
[7f1c620]596 unative_t f;
597 unative_t gp;
[3701250]598 }fptr;
599#endif
[442d0ae]600
601 symaddr = get_symbol_addr(argv->buffer);
602 if (!symaddr)
603 printf("Symbol %s not found.\n", argv->buffer);
[7f1c620]604 else if (symaddr == (uintptr_t) -1) {
[442d0ae]605 symtab_print_search(argv->buffer);
606 printf("Duplicate symbol, be more specific.\n");
607 } else {
608 symbol = get_symtab_entry(symaddr);
[ad45bde9]609 printf("Calling f(0x%zx,0x%zx): %.*p: %s\n",
[7f1c620]610 arg1, arg2, sizeof(uintptr_t) * 2, symaddr, symbol);
[3701250]611#ifdef ia64
612 fptr.f = symaddr;
[7f1c620]613 fptr.gp = ((unative_t *)cmd_call2)[1];
614 f = (unative_t (*)(unative_t,unative_t,...)) &fptr;
[3701250]615#else
[7f1c620]616 f = (unative_t (*)(unative_t,unative_t,...)) symaddr;
[3701250]617#endif
[ad45bde9]618 printf("Result: %#zx\n", f(arg1, arg2));
[442d0ae]619 }
620
621 return 1;
622}
623
624/** Call function with three parameters */
625int cmd_call3(cmd_arg_t *argv)
626{
[7f1c620]627 uintptr_t symaddr;
[442d0ae]628 char *symbol;
[7f1c620]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;
[3701250]633#ifdef ia64
634 struct {
[7f1c620]635 unative_t f;
636 unative_t gp;
[3701250]637 }fptr;
638#endif
[442d0ae]639
640 symaddr = get_symbol_addr(argv->buffer);
641 if (!symaddr)
642 printf("Symbol %s not found.\n", argv->buffer);
[7f1c620]643 else if (symaddr == (uintptr_t) -1) {
[442d0ae]644 symtab_print_search(argv->buffer);
645 printf("Duplicate symbol, be more specific.\n");
646 } else {
647 symbol = get_symtab_entry(symaddr);
[ad45bde9]648 printf("Calling f(0x%zx,0x%zx, 0x%zx): %.*p: %s\n",
[7f1c620]649 arg1, arg2, arg3, sizeof(uintptr_t) * 2, symaddr, symbol);
[3701250]650#ifdef ia64
651 fptr.f = symaddr;
[7f1c620]652 fptr.gp = ((unative_t *)cmd_call2)[1];
653 f = (unative_t (*)(unative_t,unative_t,unative_t,...)) &fptr;
[3701250]654#else
[7f1c620]655 f = (unative_t (*)(unative_t,unative_t,unative_t,...)) symaddr;
[3701250]656#endif
[ad45bde9]657 printf("Result: %#zx\n", f(arg1, arg2, arg3));
[442d0ae]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 */
[0132630]688int cmd_tlb(cmd_arg_t *argv)
[442d0ae]689{
690 tlb_print();
691 return 1;
692}
[ba276f7]693
694/** Write 4 byte value to address */
695int cmd_set4(cmd_arg_t *argv)
696{
[7f1c620]697 uint32_t *addr ;
698 uint32_t arg1 = argv[1].intval;
[ba276f7]699 bool pointer = false;
700
701 if (((char *)argv->buffer)[0] == '*') {
[7f1c620]702 addr = (uint32_t *) get_symbol_addr(argv->buffer+1);
[ba276f7]703 pointer = true;
704 } else if (((char *)argv->buffer)[0] >= '0' &&
705 ((char *)argv->buffer)[0] <= '9')
[7f1c620]706 addr = (uint32_t *)atoi((char *)argv->buffer);
[ba276f7]707 else
[7f1c620]708 addr = (uint32_t *)get_symbol_addr(argv->buffer);
[ba276f7]709
710 if (!addr)
711 printf("Symbol %s not found.\n", argv->buffer);
[7f1c620]712 else if (addr == (uint32_t *) -1) {
[ba276f7]713 symtab_print_search(argv->buffer);
714 printf("Duplicate symbol, be more specific.\n");
715 } else {
716 if (pointer)
[7f1c620]717 addr = (uint32_t *)(*(unative_t *)addr);
718 printf("Writing 0x%x -> %.*p\n", arg1, sizeof(uintptr_t) * 2, addr);
[ba276f7]719 *addr = arg1;
720
721 }
722
723 return 1;
724}
[80bff342]725
[4e147a6]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
[55ab0f1]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
[37c57f2]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
[10e16a7]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
[96cacc1]771/** Command for listing memory zones
772 *
773 * @param argv Ignored
774 *
775 * return Always 1
776 */
[80bff342]777int cmd_zones(cmd_arg_t * argv) {
[dfd9186]778 zone_print_list();
[80bff342]779 return 1;
780}
[0132630]781
[96cacc1]782/** Command for memory zone details
783 *
784 * @param argv Integer argument from cmdline expected
785 *
786 * return Always 1
787 */
[80bff342]788int cmd_zone(cmd_arg_t * argv) {
[dfd9186]789 zone_print_one(argv[0].intval);
[80bff342]790 return 1;
791}
792
[c4e4507]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
[0132630]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}
[41d33ac]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{
[dd054bc2]837 printf("The kernel will now relinquish the console.\n");
838 printf("Use userspace controls to redraw the screen.\n");
[41d33ac]839 arch_release_console();
840 return 1;
841}
[b45c443]842
[50661ab]843#ifdef CONFIG_TEST
[319e60e]844/** Command for printing kernel tests list.
845 *
846 * @param argv Ignored.
847 *
848 * return Always 1.
849 */
850int cmd_tests(cmd_arg_t *argv)
851{
852 test_t *test;
853
854 for (test = tests; test->name != NULL; test++)
[50661ab]855 printf("%s\t\t%s%s\n", test->name, test->desc, (test->safe ? "" : " (unsafe)"));
[319e60e]856
[50661ab]857 printf("*\t\tRun all safe tests\n");
[319e60e]858 return 1;
859}
860
[62b6d17]861static bool run_test(const test_t *test)
[34db7fa]862{
[62b6d17]863 printf("%s\t\t%s\n", test->name, test->desc);
[cce6acf]864
865 /* Update and read thread accounting
866 for benchmarking */
867 ipl_t ipl = interrupts_disable();
[0313ff0]868 spinlock_lock(&TASK->lock);
869 uint64_t t0 = task_get_accounting(TASK);
870 spinlock_unlock(&TASK->lock);
[cce6acf]871 interrupts_restore(ipl);
872
873 /* Execute the test */
[34db7fa]874 char * ret = test->entry();
[cce6acf]875
876 /* Update and read thread accounting */
877 ipl = interrupts_disable();
[0313ff0]878 spinlock_lock(&TASK->lock);
879 uint64_t dt = task_get_accounting(TASK) - t0;
880 spinlock_unlock(&TASK->lock);
[cce6acf]881 interrupts_restore(ipl);
882
[34db7fa]883 printf("Time: %llu cycles\n", dt);
884
885 if (ret == NULL) {
886 printf("Test passed\n");
[62b6d17]887 return true;
[34db7fa]888 }
889
890 printf("%s\n", ret);
[62b6d17]891 return false;
[34db7fa]892}
893
[319e60e]894/** Command for returning kernel tests
895 *
896 * @param argv Argument vector.
897 *
898 * return Always 1.
899 */
900int cmd_test(cmd_arg_t *argv)
901{
902 test_t *test;
903
[50661ab]904 if (strcmp(argv->buffer, "*") == 0) {
905 for (test = tests; test->name != NULL; test++) {
906 if (test->safe) {
[34db7fa]907 printf("\n");
908 if (!run_test(test))
909 break;
[50661ab]910 }
911 }
912 } else {
913 bool fnd = false;
914
915 for (test = tests; test->name != NULL; test++) {
916 if (strcmp(test->name, argv->buffer) == 0) {
917 fnd = true;
[34db7fa]918 run_test(test);
[50661ab]919 break;
920 }
[319e60e]921 }
[50661ab]922
923 if (!fnd)
[34db7fa]924 printf("Unknown test\n");
[319e60e]925 }
926
927 return 1;
928}
[50661ab]929#endif
[319e60e]930
[06e1e95]931/** @}
[b45c443]932 */
Note: See TracBrowser for help on using the repository browser.