Rev 594 | Rev 601 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 594 | Rev 596 | ||
---|---|---|---|
Line 27... | Line 27... | ||
27 | */ |
27 | */ |
28 | 28 | ||
29 | #include <console/kconsole.h> |
29 | #include <console/kconsole.h> |
30 | #include <console/console.h> |
30 | #include <console/console.h> |
31 | #include <console/chardev.h> |
31 | #include <console/chardev.h> |
- | 32 | #include <console/cmd.h> |
|
32 | #include <print.h> |
33 | #include <print.h> |
33 | #include <panic.h> |
34 | #include <panic.h> |
34 | #include <typedefs.h> |
35 | #include <typedefs.h> |
35 | #include <arch/types.h> |
36 | #include <arch/types.h> |
36 | #include <list.h> |
37 | #include <list.h> |
37 | #include <arch.h> |
38 | #include <arch.h> |
38 | #include <func.h> |
- | |
39 | #include <macros.h> |
39 | #include <macros.h> |
40 | #include <debug.h> |
40 | #include <debug.h> |
- | 41 | #include <func.h> |
|
41 | #include <symtab.h> |
42 | #include <symtab.h> |
42 | 43 | ||
43 | #include <mm/tlb_cmd.h> |
- | |
44 | - | ||
45 | #define MAX_CMDLINE 256 |
- | |
46 | - | ||
47 | /** Simple kernel console. |
44 | /** Simple kernel console. |
48 | * |
45 | * |
49 | * The console is realized by kernel thread kconsole. |
46 | * The console is realized by kernel thread kconsole. |
50 | * It doesn't understand any useful command on its own, |
47 | * It doesn't understand any useful command on its own, |
51 | * but makes it possible for other kernel subsystems to |
48 | * but makes it possible for other kernel subsystems to |
Line 71... | Line 68... | ||
71 | link_t cmd_head; /**< Command list. */ |
68 | link_t cmd_head; /**< Command list. */ |
72 | 69 | ||
73 | static cmd_info_t *parse_cmdline(char *cmdline, size_t len); |
70 | static cmd_info_t *parse_cmdline(char *cmdline, size_t len); |
74 | static bool parse_argument(char *cmdline, size_t len, index_t *start, index_t *end); |
71 | static bool parse_argument(char *cmdline, size_t len, index_t *start, index_t *end); |
75 | 72 | ||
76 | /** Data and methods for 'help' command. */ |
- | |
77 | static int cmd_help(cmd_arg_t *argv); |
- | |
78 | static cmd_info_t help_info = { |
- | |
79 | .name = "help", |
- | |
80 | .description = "List of supported commands.", |
- | |
81 | .func = cmd_help, |
- | |
82 | .argc = 0 |
- | |
83 | }; |
- | |
84 | - | ||
85 | /** Data and methods for 'description' command. */ |
- | |
86 | static int cmd_desc(cmd_arg_t *argv); |
- | |
87 | static void desc_help(void); |
- | |
88 | static char desc_buf[MAX_CMDLINE+1]; |
- | |
89 | static cmd_arg_t desc_argv = { |
- | |
90 | .type = ARG_TYPE_STRING, |
- | |
91 | .buffer = desc_buf, |
- | |
92 | .len = sizeof(desc_buf) |
- | |
93 | }; |
- | |
94 | static cmd_info_t desc_info = { |
- | |
95 | .name = "describe", |
- | |
96 | .description = "Describe specified command.", |
- | |
97 | .help = desc_help, |
- | |
98 | .func = cmd_desc, |
- | |
99 | .argc = 1, |
- | |
100 | .argv = &desc_argv |
- | |
101 | }; |
- | |
102 | - | ||
103 | /** Data and methods for 'symaddr' command. */ |
- | |
104 | static int cmd_symaddr(cmd_arg_t *argv); |
- | |
105 | static char symaddr_buf[MAX_CMDLINE+1]; |
- | |
106 | static cmd_arg_t symaddr_argv = { |
- | |
107 | .type = ARG_TYPE_STRING, |
- | |
108 | .buffer = symaddr_buf, |
- | |
109 | .len = sizeof(symaddr_buf) |
- | |
110 | }; |
- | |
111 | static cmd_info_t symaddr_info = { |
- | |
112 | .name = "symaddr", |
- | |
113 | .description = "Return symbol address.", |
- | |
114 | .func = cmd_symaddr, |
- | |
115 | .argc = 1, |
- | |
116 | .argv = &symaddr_argv |
- | |
117 | }; |
- | |
118 | - | ||
119 | /** Call0 - call function with no parameters */ |
- | |
120 | static char call0_buf[MAX_CMDLINE+1]; |
- | |
121 | static char carg1_buf[MAX_CMDLINE+1]; |
- | |
122 | static char carg2_buf[MAX_CMDLINE+1]; |
- | |
123 | static char carg3_buf[MAX_CMDLINE+1]; |
- | |
124 | - | ||
125 | static int cmd_call0(cmd_arg_t *argv); |
- | |
126 | static cmd_arg_t call0_argv = { |
- | |
127 | .type = ARG_TYPE_STRING, |
- | |
128 | .buffer = call0_buf, |
- | |
129 | .len = sizeof(call0_buf) |
- | |
130 | }; |
- | |
131 | static cmd_info_t call0_info = { |
- | |
132 | .name = "call0", |
- | |
133 | .description = "call0 <function> -> call function().", |
- | |
134 | .func = cmd_call0, |
- | |
135 | .argc = 1, |
- | |
136 | .argv = &call0_argv |
- | |
137 | }; |
- | |
138 | - | ||
139 | static int cmd_call1(cmd_arg_t *argv); |
- | |
140 | static cmd_arg_t call1_argv[] = { |
- | |
141 | { |
- | |
142 | .type = ARG_TYPE_STRING, |
- | |
143 | .buffer = call0_buf, |
- | |
144 | .len = sizeof(call0_buf) |
- | |
145 | }, |
- | |
146 | { |
- | |
147 | .type = ARG_TYPE_VAR, |
- | |
148 | .buffer = carg1_buf, |
- | |
149 | .len = sizeof(carg1_buf) |
- | |
150 | } |
- | |
151 | }; |
- | |
152 | static cmd_info_t call1_info = { |
- | |
153 | .name = "call1", |
- | |
154 | .description = "call1 <function> <arg1> -> call function(arg1).", |
- | |
155 | .func = cmd_call1, |
- | |
156 | .argc = 2, |
- | |
157 | .argv = call1_argv |
- | |
158 | }; |
- | |
159 | - | ||
160 | static int cmd_call2(cmd_arg_t *argv); |
- | |
161 | static cmd_arg_t call2_argv[] = { |
- | |
162 | { |
- | |
163 | .type = ARG_TYPE_STRING, |
- | |
164 | .buffer = call0_buf, |
- | |
165 | .len = sizeof(call0_buf) |
- | |
166 | }, |
- | |
167 | { |
- | |
168 | .type = ARG_TYPE_VAR, |
- | |
169 | .buffer = carg1_buf, |
- | |
170 | .len = sizeof(carg1_buf) |
- | |
171 | }, |
- | |
172 | { |
- | |
173 | .type = ARG_TYPE_VAR, |
- | |
174 | .buffer = carg2_buf, |
- | |
175 | .len = sizeof(carg2_buf) |
- | |
176 | } |
- | |
177 | }; |
- | |
178 | static cmd_info_t call2_info = { |
- | |
179 | .name = "call2", |
- | |
180 | .description = "call2 <function> <arg1> <arg2> -> call function(arg1,arg2).", |
- | |
181 | .func = cmd_call2, |
- | |
182 | .argc = 3, |
- | |
183 | .argv = call2_argv |
- | |
184 | }; |
- | |
185 | - | ||
186 | static int cmd_call3(cmd_arg_t *argv); |
- | |
187 | static 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 | }; |
- | |
210 | static 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. */ |
- | |
219 | static int cmd_halt(cmd_arg_t *argv); |
- | |
220 | static cmd_info_t halt_info = { |
- | |
221 | .name = "halt", |
- | |
222 | .description = "Halt the kernel.", |
- | |
223 | .func = cmd_halt, |
- | |
224 | .argc = 0 |
- | |
225 | }; |
- | |
226 | - | ||
227 | /** Initialize kconsole data structures. */ |
73 | /** Initialize kconsole data structures. */ |
228 | void kconsole_init(void) |
74 | void kconsole_init(void) |
229 | { |
75 | { |
230 | spinlock_initialize(&cmd_lock, "kconsole_cmd"); |
76 | spinlock_initialize(&cmd_lock, "kconsole_cmd"); |
231 | list_initialize(&cmd_head); |
77 | list_initialize(&cmd_head); |
232 | - | ||
233 | spinlock_initialize(&help_info.lock, "kconsole_help"); |
- | |
234 | link_initialize(&help_info.link); |
- | |
235 | if (!cmd_register(&help_info)) |
- | |
236 | panic("could not register command %s\n", help_info.name); |
- | |
237 | - | ||
238 | - | ||
239 | spinlock_initialize(&desc_info.lock, "kconsole_desc"); |
- | |
240 | link_initialize(&desc_info.link); |
- | |
241 | if (!cmd_register(&desc_info)) |
- | |
242 | panic("could not register command %s\n", desc_info.name); |
- | |
243 | - | ||
244 | spinlock_initialize(&symaddr_info.lock, "kconsole_symaddr"); |
- | |
245 | link_initialize(&symaddr_info.link); |
- | |
246 | if (!cmd_register(&symaddr_info)) |
- | |
247 | panic("could not register command %s\n", symaddr_info.name); |
- | |
248 | - | ||
249 | spinlock_initialize(&call0_info.lock, "kconsole_call0"); |
- | |
250 | link_initialize(&call0_info.link); |
- | |
251 | if (!cmd_register(&call0_info)) |
- | |
252 | panic("could not register command %s\n", call0_info.name); |
- | |
253 | - | ||
254 | spinlock_initialize(&call1_info.lock, "kconsole_call1"); |
- | |
255 | link_initialize(&call1_info.link); |
- | |
256 | if (!cmd_register(&call1_info)) |
- | |
257 | panic("could not register command %s\n", call1_info.name); |
- | |
258 | - | ||
259 | - | ||
260 | spinlock_initialize(&call2_info.lock, "kconsole_call2"); |
- | |
261 | link_initialize(&call2_info.link); |
- | |
262 | if (!cmd_register(&call2_info)) |
- | |
263 | panic("could not register command %s\n", call2_info.name); |
- | |
264 | - | ||
265 | spinlock_initialize(&call3_info.lock, "kconsole_call3"); |
- | |
266 | link_initialize(&call3_info.link); |
- | |
267 | if (!cmd_register(&call3_info)) |
- | |
268 | panic("could not register command %s\n", call3_info.name); |
- | |
269 | - | ||
270 | spinlock_initialize(&halt_info.lock, "kconsole_halt"); |
- | |
271 | link_initialize(&halt_info.link); |
- | |
272 | if (!cmd_register(&halt_info)) |
- | |
273 | panic("could not register command %s\n", halt_info.name); |
- | |
274 | 78 | ||
275 | spinlock_initialize(&desc_ptlb.lock, "kconsole_ptlb"); |
- | |
276 | link_initialize(&desc_ptlb.link); |
- | |
277 | if (!cmd_register(&desc_ptlb)) |
79 | cmd_init(); |
278 | panic("could not register command %s\n", desc_ptlb.name); |
- | |
279 | } |
80 | } |
280 | 81 | ||
281 | 82 | ||
282 | /** Register kconsole command. |
83 | /** Register kconsole command. |
283 | * |
84 | * |
Line 544... | Line 345... | ||
544 | } |
345 | } |
545 | *end = i - 1; |
346 | *end = i - 1; |
546 | 347 | ||
547 | return found_start; |
348 | return found_start; |
548 | } |
349 | } |
549 | - | ||
550 | - | ||
551 | /** List supported commands. |
- | |
552 | * |
- | |
553 | * @param argv Argument vector. |
- | |
554 | * |
- | |
555 | * @return 0 on failure, 1 on success. |
- | |
556 | */ |
- | |
557 | int cmd_help(cmd_arg_t *argv) |
- | |
558 | { |
- | |
559 | link_t *cur; |
- | |
560 | ipl_t ipl; |
- | |
561 | - | ||
562 | spinlock_lock(&cmd_lock); |
- | |
563 | - | ||
564 | for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) { |
- | |
565 | cmd_info_t *hlp; |
- | |
566 | - | ||
567 | hlp = list_get_instance(cur, cmd_info_t, link); |
- | |
568 | spinlock_lock(&hlp->lock); |
- | |
569 | - | ||
570 | printf("%s - %s\n", hlp->name, hlp->description); |
- | |
571 | - | ||
572 | spinlock_unlock(&hlp->lock); |
- | |
573 | } |
- | |
574 | - | ||
575 | spinlock_unlock(&cmd_lock); |
- | |
576 | - | ||
577 | return 1; |
- | |
578 | } |
- | |
579 | - | ||
580 | /** Describe specified command. |
- | |
581 | * |
- | |
582 | * @param argv Argument vector. |
- | |
583 | * |
- | |
584 | * @return 0 on failure, 1 on success. |
- | |
585 | */ |
- | |
586 | int cmd_desc(cmd_arg_t *argv) |
- | |
587 | { |
- | |
588 | link_t *cur; |
- | |
589 | ipl_t ipl; |
- | |
590 | - | ||
591 | spinlock_lock(&cmd_lock); |
- | |
592 | - | ||
593 | for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) { |
- | |
594 | cmd_info_t *hlp; |
- | |
595 | - | ||
596 | hlp = list_get_instance(cur, cmd_info_t, link); |
- | |
597 | spinlock_lock(&hlp->lock); |
- | |
598 | - | ||
599 | if (strncmp(hlp->name, (const char *) argv->buffer, strlen(hlp->name)) == 0) { |
- | |
600 | printf("%s - %s\n", hlp->name, hlp->description); |
- | |
601 | if (hlp->help) |
- | |
602 | hlp->help(); |
- | |
603 | spinlock_unlock(&hlp->lock); |
- | |
604 | break; |
- | |
605 | } |
- | |
606 | - | ||
607 | spinlock_unlock(&hlp->lock); |
- | |
608 | } |
- | |
609 | - | ||
610 | spinlock_unlock(&cmd_lock); |
- | |
611 | - | ||
612 | return 1; |
- | |
613 | } |
- | |
614 | - | ||
615 | /** Search symbol table */ |
- | |
616 | int cmd_symaddr(cmd_arg_t *argv) |
- | |
617 | { |
- | |
618 | __address symaddr; |
- | |
619 | char *symbol; |
- | |
620 | - | ||
621 | symtab_print_search(argv->buffer); |
- | |
622 | - | ||
623 | return 1; |
- | |
624 | } |
- | |
625 | - | ||
626 | /** Call function with zero parameters */ |
- | |
627 | int cmd_call0(cmd_arg_t *argv) |
- | |
628 | { |
- | |
629 | __address symaddr; |
- | |
630 | char *symbol; |
- | |
631 | __native (*f)(void); |
- | |
632 | - | ||
633 | symaddr = get_symbol_addr(argv->buffer); |
- | |
634 | if (!symaddr) |
- | |
635 | printf("Symbol %s not found.\n", argv->buffer); |
- | |
636 | else if (symaddr == (__address) -1) { |
- | |
637 | symtab_print_search(argv->buffer); |
- | |
638 | printf("Duplicate symbol, be more specific.\n"); |
- | |
639 | } else { |
- | |
640 | symbol = get_symtab_entry(symaddr); |
- | |
641 | printf("Calling f(): 0x%p: %s\n", symaddr, symbol); |
- | |
642 | f = (__native (*)(void)) symaddr; |
- | |
643 | printf("Result: 0x%X\n", f()); |
- | |
644 | } |
- | |
645 | - | ||
646 | return 1; |
- | |
647 | } |
- | |
648 | - | ||
649 | /** Call function with one parameter */ |
- | |
650 | int cmd_call1(cmd_arg_t *argv) |
- | |
651 | { |
- | |
652 | __address symaddr; |
- | |
653 | char *symbol; |
- | |
654 | __native (*f)(__native); |
- | |
655 | __native arg1 = argv[1].intval; |
- | |
656 | - | ||
657 | symaddr = get_symbol_addr(argv->buffer); |
- | |
658 | if (!symaddr) |
- | |
659 | printf("Symbol %s not found.\n", argv->buffer); |
- | |
660 | else if (symaddr == (__address) -1) { |
- | |
661 | symtab_print_search(argv->buffer); |
- | |
662 | printf("Duplicate symbol, be more specific.\n"); |
- | |
663 | } else { |
- | |
664 | symbol = get_symtab_entry(symaddr); |
- | |
665 | printf("Calling f(0x%x): 0x%p: %s\n", arg1, symaddr, symbol); |
- | |
666 | f = (__native (*)(__native)) symaddr; |
- | |
667 | printf("Result: 0x%x\n", f(arg1)); |
- | |
668 | } |
- | |
669 | - | ||
670 | return 1; |
- | |
671 | } |
- | |
672 | - | ||
673 | /** Call function with two parameters */ |
- | |
674 | int cmd_call2(cmd_arg_t *argv) |
- | |
675 | { |
- | |
676 | __address symaddr; |
- | |
677 | char *symbol; |
- | |
678 | __native (*f)(__native,__native); |
- | |
679 | __native arg1 = argv[1].intval; |
- | |
680 | __native arg2 = argv[2].intval; |
- | |
681 | - | ||
682 | symaddr = get_symbol_addr(argv->buffer); |
- | |
683 | if (!symaddr) |
- | |
684 | printf("Symbol %s not found.\n", argv->buffer); |
- | |
685 | else if (symaddr == (__address) -1) { |
- | |
686 | symtab_print_search(argv->buffer); |
- | |
687 | printf("Duplicate symbol, be more specific.\n"); |
- | |
688 | } else { |
- | |
689 | symbol = get_symtab_entry(symaddr); |
- | |
690 | printf("Calling f(0x%x,0x%x): 0x%p: %s\n", |
- | |
691 | arg1, arg2, symaddr, symbol); |
- | |
692 | f = (__native (*)(__native,__native)) symaddr; |
- | |
693 | printf("Result: 0x%x\n", f(arg1, arg2)); |
- | |
694 | } |
- | |
695 | - | ||
696 | return 1; |
- | |
697 | } |
- | |
698 | - | ||
699 | /** Call function with three parameters */ |
- | |
700 | int cmd_call3(cmd_arg_t *argv) |
- | |
701 | { |
- | |
702 | __address symaddr; |
- | |
703 | char *symbol; |
- | |
704 | __native (*f)(__native,__native,__native); |
- | |
705 | __native arg1 = argv[1].intval; |
- | |
706 | __native arg2 = argv[2].intval; |
- | |
707 | __native arg3 = argv[3].intval; |
- | |
708 | - | ||
709 | symaddr = get_symbol_addr(argv->buffer); |
- | |
710 | if (!symaddr) |
- | |
711 | printf("Symbol %s not found.\n", argv->buffer); |
- | |
712 | else if (symaddr == (__address) -1) { |
- | |
713 | symtab_print_search(argv->buffer); |
- | |
714 | printf("Duplicate symbol, be more specific.\n"); |
- | |
715 | } else { |
- | |
716 | symbol = get_symtab_entry(symaddr); |
- | |
717 | printf("Calling f(0x%x,0x%x, 0x%x): 0x%p: %s\n", |
- | |
718 | arg1, arg2, arg3, symaddr, symbol); |
- | |
719 | f = (__native (*)(__native,__native,__native)) symaddr; |
- | |
720 | printf("Result: 0x%x\n", f(arg1, arg2, arg3)); |
- | |
721 | } |
- | |
722 | - | ||
723 | return 1; |
- | |
724 | } |
- | |
725 | - | ||
726 | - | ||
727 | /** Print detailed description of 'describe' command. */ |
- | |
728 | void desc_help(void) |
- | |
729 | { |
- | |
730 | printf("Syntax: describe command_name\n"); |
- | |
731 | } |
- | |
732 | - | ||
733 | /** Halt the kernel. |
- | |
734 | * |
- | |
735 | * @param argv Argument vector (ignored). |
- | |
736 | * |
- | |
737 | * @return 0 on failure, 1 on success (never returns). |
- | |
738 | */ |
- | |
739 | int cmd_halt(cmd_arg_t *argv) |
- | |
740 | { |
- | |
741 | halt(); |
- | |
742 | return 1; |
- | |
743 | } |
- |