source: mainline/generic/src/console/cmd.c@ 4e147a6

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

Skeleton of SLAB allocator.

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