source: mainline/generic/src/console/cmd.c@ 93e90c7

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 93e90c7 was 80bff342, checked in by Sergey Bondari <bondari@…>, 20 years ago

Zones related commands infrastructure for console. Also fixed small bug that caused infinite loop during command parsing

  • Property mode set to 100644
File size: 13.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
49#include <mm/tlb.h>
50#include <arch/mm/tlb.h>
51#include <mm/frame.h>
52
53/** Data and methods for 'help' command. */
54static int cmd_help(cmd_arg_t *argv);
55static cmd_info_t help_info = {
56 .name = "help",
57 .description = "List of supported commands.",
58 .func = cmd_help,
59 .argc = 0
60};
61
62static cmd_info_t exit_info = {
63 .name = "exit",
64 .description ="Exit kconsole",
65 .argc = 0
66};
67
68/** Data and methods for 'description' command. */
69static int cmd_desc(cmd_arg_t *argv);
70static void desc_help(void);
71static char desc_buf[MAX_CMDLINE+1];
72static cmd_arg_t desc_argv = {
73 .type = ARG_TYPE_STRING,
74 .buffer = desc_buf,
75 .len = sizeof(desc_buf)
76};
77static cmd_info_t desc_info = {
78 .name = "describe",
79 .description = "Describe specified command.",
80 .help = desc_help,
81 .func = cmd_desc,
82 .argc = 1,
83 .argv = &desc_argv
84};
85
86/** Data and methods for 'symaddr' command. */
87static int cmd_symaddr(cmd_arg_t *argv);
88static char symaddr_buf[MAX_CMDLINE+1];
89static cmd_arg_t symaddr_argv = {
90 .type = ARG_TYPE_STRING,
91 .buffer = symaddr_buf,
92 .len = sizeof(symaddr_buf)
93};
94static cmd_info_t symaddr_info = {
95 .name = "symaddr",
96 .description = "Return symbol address.",
97 .func = cmd_symaddr,
98 .argc = 1,
99 .argv = &symaddr_argv
100};
101
102static char set_buf[MAX_CMDLINE+1];
103static int cmd_set4(cmd_arg_t *argv);
104static cmd_arg_t set4_argv[] = {
105 {
106 .type = ARG_TYPE_STRING,
107 .buffer = set_buf,
108 .len = sizeof(set_buf)
109 },
110 {
111 .type = ARG_TYPE_INT
112 }
113};
114static cmd_info_t set4_info = {
115 .name = "set4",
116 .description = "set <dest_addr> <value> - 4byte version",
117 .func = cmd_set4,
118 .argc = 2,
119 .argv = set4_argv
120};
121
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 'ptlb' command. */
236static int cmd_ptlb(cmd_arg_t *argv);
237cmd_info_t ptlb_info = {
238 .name = "ptlb",
239 .description = "Print TLB of current processor.",
240 .help = NULL,
241 .func = cmd_ptlb,
242 .argc = 0,
243 .argv = NULL
244};
245
246
247/** Data and methods for 'zones' command */
248static int cmd_zones(cmd_arg_t *argv);
249static cmd_info_t zones_info = {
250 .name = "zones",
251 .description = "List of memory zones.",
252 .func = cmd_zones,
253 .argc = 0
254};
255
256/** Data and methods for 'zone' command */
257static int cmd_zone(cmd_arg_t *argv);
258static char zone_buf[MAX_CMDLINE+1];
259static cmd_arg_t zone_argv = {
260 .type = ARG_TYPE_INT,
261 .buffer = zone_buf,
262 .len = sizeof(zone_buf)
263};
264
265
266static cmd_info_t zone_info = {
267 .name = "zone",
268 .description = "Show memory zone structure.",
269 .func = cmd_zone,
270 .argc = 1,
271 .argv = &zone_argv
272};
273
274
275
276/** Initialize command info structure.
277 *
278 * @param cmd Command info structure.
279 *
280 */
281void cmd_initialize(cmd_info_t *cmd)
282{
283 spinlock_initialize(&cmd->lock, "cmd");
284 link_initialize(&cmd->link);
285}
286
287/** Initialize and register commands. */
288void cmd_init(void)
289{
290 cmd_initialize(&help_info);
291 if (!cmd_register(&help_info))
292 panic("could not register command %s\n", help_info.name);
293
294 cmd_initialize(&desc_info);
295 if (!cmd_register(&desc_info))
296 panic("could not register command %s\n", desc_info.name);
297
298 cmd_initialize(&exit_info);
299 if (!cmd_register(&exit_info))
300 panic("could not register command %s\n", exit_info.name);
301
302 cmd_initialize(&symaddr_info);
303 if (!cmd_register(&symaddr_info))
304 panic("could not register command %s\n", symaddr_info.name);
305
306 cmd_initialize(&call0_info);
307 if (!cmd_register(&call0_info))
308 panic("could not register command %s\n", call0_info.name);
309
310 cmd_initialize(&call1_info);
311 if (!cmd_register(&call1_info))
312 panic("could not register command %s\n", call1_info.name);
313
314 cmd_initialize(&call2_info);
315 if (!cmd_register(&call2_info))
316 panic("could not register command %s\n", call2_info.name);
317
318 cmd_initialize(&call3_info);
319 if (!cmd_register(&call3_info))
320 panic("could not register command %s\n", call3_info.name);
321
322 cmd_initialize(&set4_info);
323 if (!cmd_register(&set4_info))
324 panic("could not register command %s\n", set4_info.name);
325
326 cmd_initialize(&halt_info);
327 if (!cmd_register(&halt_info))
328 panic("could not register command %s\n", halt_info.name);
329
330 cmd_initialize(&ptlb_info);
331 if (!cmd_register(&ptlb_info))
332 panic("could not register command %s\n", ptlb_info.name);
333
334 cmd_initialize(&zones_info);
335 if (!cmd_register(&zones_info))
336 panic("could not register command %s\n", zones_info.name);
337
338 cmd_initialize(&zone_info);
339 if (!cmd_register(&zone_info))
340 panic("could not register command %s\n", zone_info.name);
341
342
343}
344
345
346/** List supported commands.
347 *
348 * @param argv Argument vector.
349 *
350 * @return 0 on failure, 1 on success.
351 */
352int cmd_help(cmd_arg_t *argv)
353{
354 link_t *cur;
355
356 spinlock_lock(&cmd_lock);
357
358 for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
359 cmd_info_t *hlp;
360
361 hlp = list_get_instance(cur, cmd_info_t, link);
362 spinlock_lock(&hlp->lock);
363
364 printf("%s - %s\n", hlp->name, hlp->description);
365
366 spinlock_unlock(&hlp->lock);
367 }
368
369 spinlock_unlock(&cmd_lock);
370
371 return 1;
372}
373
374/** Describe specified command.
375 *
376 * @param argv Argument vector.
377 *
378 * @return 0 on failure, 1 on success.
379 */
380int cmd_desc(cmd_arg_t *argv)
381{
382 link_t *cur;
383
384 spinlock_lock(&cmd_lock);
385
386 for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
387 cmd_info_t *hlp;
388
389 hlp = list_get_instance(cur, cmd_info_t, link);
390 spinlock_lock(&hlp->lock);
391
392 if (strncmp(hlp->name, (const char *) argv->buffer, strlen(hlp->name)) == 0) {
393 printf("%s - %s\n", hlp->name, hlp->description);
394 if (hlp->help)
395 hlp->help();
396 spinlock_unlock(&hlp->lock);
397 break;
398 }
399
400 spinlock_unlock(&hlp->lock);
401 }
402
403 spinlock_unlock(&cmd_lock);
404
405 return 1;
406}
407
408/** Search symbol table */
409int cmd_symaddr(cmd_arg_t *argv)
410{
411 symtab_print_search(argv->buffer);
412
413 return 1;
414}
415
416/** Call function with zero parameters */
417int cmd_call0(cmd_arg_t *argv)
418{
419 __address symaddr;
420 char *symbol;
421 __native (*f)(void);
422
423 symaddr = get_symbol_addr(argv->buffer);
424 if (!symaddr)
425 printf("Symbol %s not found.\n", argv->buffer);
426 else if (symaddr == (__address) -1) {
427 symtab_print_search(argv->buffer);
428 printf("Duplicate symbol, be more specific.\n");
429 } else {
430 symbol = get_symtab_entry(symaddr);
431 printf("Calling f(): 0x%p: %s\n", symaddr, symbol);
432 f = (__native (*)(void)) symaddr;
433 printf("Result: 0x%p\n", f());
434 }
435
436 return 1;
437}
438
439/** Call function with one parameter */
440int cmd_call1(cmd_arg_t *argv)
441{
442 __address symaddr;
443 char *symbol;
444 __native (*f)(__native);
445 __native arg1 = argv[1].intval;
446
447 symaddr = get_symbol_addr(argv->buffer);
448 if (!symaddr)
449 printf("Symbol %s not found.\n", argv->buffer);
450 else if (symaddr == (__address) -1) {
451 symtab_print_search(argv->buffer);
452 printf("Duplicate symbol, be more specific.\n");
453 } else {
454 symbol = get_symtab_entry(symaddr);
455 printf("Calling f(0x%x): 0x%p: %s\n", arg1, symaddr, symbol);
456 f = (__native (*)(__native)) symaddr;
457 printf("Result: 0x%p\n", f(arg1));
458 }
459
460 return 1;
461}
462
463/** Call function with two parameters */
464int cmd_call2(cmd_arg_t *argv)
465{
466 __address symaddr;
467 char *symbol;
468 __native (*f)(__native,__native);
469 __native arg1 = argv[1].intval;
470 __native arg2 = argv[2].intval;
471
472 symaddr = get_symbol_addr(argv->buffer);
473 if (!symaddr)
474 printf("Symbol %s not found.\n", argv->buffer);
475 else if (symaddr == (__address) -1) {
476 symtab_print_search(argv->buffer);
477 printf("Duplicate symbol, be more specific.\n");
478 } else {
479 symbol = get_symtab_entry(symaddr);
480 printf("Calling f(0x%x,0x%x): 0x%p: %s\n",
481 arg1, arg2, symaddr, symbol);
482 f = (__native (*)(__native,__native)) symaddr;
483 printf("Result: 0x%p\n", f(arg1, arg2));
484 }
485
486 return 1;
487}
488
489/** Call function with three parameters */
490int cmd_call3(cmd_arg_t *argv)
491{
492 __address symaddr;
493 char *symbol;
494 __native (*f)(__native,__native,__native);
495 __native arg1 = argv[1].intval;
496 __native arg2 = argv[2].intval;
497 __native arg3 = argv[3].intval;
498
499 symaddr = get_symbol_addr(argv->buffer);
500 if (!symaddr)
501 printf("Symbol %s not found.\n", argv->buffer);
502 else if (symaddr == (__address) -1) {
503 symtab_print_search(argv->buffer);
504 printf("Duplicate symbol, be more specific.\n");
505 } else {
506 symbol = get_symtab_entry(symaddr);
507 printf("Calling f(0x%x,0x%x, 0x%x): 0x%p: %s\n",
508 arg1, arg2, arg3, symaddr, symbol);
509 f = (__native (*)(__native,__native,__native)) symaddr;
510 printf("Result: 0x%p\n", f(arg1, arg2, arg3));
511 }
512
513 return 1;
514}
515
516
517/** Print detailed description of 'describe' command. */
518void desc_help(void)
519{
520 printf("Syntax: describe command_name\n");
521}
522
523/** Halt the kernel.
524 *
525 * @param argv Argument vector (ignored).
526 *
527 * @return 0 on failure, 1 on success (never returns).
528 */
529int cmd_halt(cmd_arg_t *argv)
530{
531 halt();
532 return 1;
533}
534
535/** Command for printing TLB contents.
536 *
537 * @param argv Not used.
538 *
539 * @return Always returns 1.
540 */
541int cmd_ptlb(cmd_arg_t *argv)
542{
543 tlb_print();
544 return 1;
545}
546
547/** Write 4 byte value to address */
548int cmd_set4(cmd_arg_t *argv)
549{
550 __u32 *addr ;
551 __u32 arg1 = argv[1].intval;
552 bool pointer = false;
553
554 if (((char *)argv->buffer)[0] == '*') {
555 addr = (__u32 *) get_symbol_addr(argv->buffer+1);
556 pointer = true;
557 } else if (((char *)argv->buffer)[0] >= '0' &&
558 ((char *)argv->buffer)[0] <= '9')
559 addr = (__u32 *)atoi((char *)argv->buffer);
560 else
561 addr = (__u32 *)get_symbol_addr(argv->buffer);
562
563 if (!addr)
564 printf("Symbol %s not found.\n", argv->buffer);
565 else if (addr == (__u32 *) -1) {
566 symtab_print_search(argv->buffer);
567 printf("Duplicate symbol, be more specific.\n");
568 } else {
569 if (pointer)
570 addr = (__u32 *)(*(__native *)addr);
571 printf("Writing 0x%x -> 0x%p\n", arg1, addr);
572 *addr = arg1;
573
574 }
575
576 return 1;
577}
578
579
580int cmd_zones(cmd_arg_t * argv) {
581 printf("Zones listing not implemented\n");
582 return 1;
583}
584int cmd_zone(cmd_arg_t * argv) {
585 printf("Zone details not implemented\n");
586 return 1;
587}
588
Note: See TracBrowser for help on using the repository browser.