source: mainline/generic/src/console/cmd.c@ 37c57f2

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 37c57f2 was 37c57f2, checked in by Ondrej Palkovsky <ondrap@…>, 19 years ago

Added task_print.
Fixed ipc to support connect_me_to.

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