source: mainline/generic/src/console/cmd.c@ 3550c393

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

Symtab returns correct addresses even when symtab is befor bss.
Some tab completion optimization.

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