source: mainline/generic/src/console/cmd.c@ 0132630

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

Add 'version' and 'cpus' kconsole commands.
Remove leading p from names of p* commands.

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