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

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

Added set4 command.

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