source: mainline/kernel/generic/src/console/cmd.c@ 0313ff0

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

accumulate task accounting, run tests as separate kernel task

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