source: mainline/generic/src/console/cmd.c@ 5c9a08b

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 5c9a08b was 5c9a08b, checked in by Jakub Jermar <jakub@…>, 19 years ago

Move list and fifo data types to adt/.

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