Rev 4055 | Rev 4201 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 4055 | Rev 4156 | ||
|---|---|---|---|
| Line 48... | Line 48... | ||
| 48 | #include <arch.h> |
48 | #include <arch.h> |
| 49 | #include <macros.h> |
49 | #include <macros.h> |
| 50 | #include <debug.h> |
50 | #include <debug.h> |
| 51 | #include <func.h> |
51 | #include <func.h> |
| 52 | #include <string.h> |
52 | #include <string.h> |
| 53 | #include <symtab.h> |
- | |
| 54 | #include <macros.h> |
53 | #include <macros.h> |
| 55 | #include <sysinfo/sysinfo.h> |
54 | #include <sysinfo/sysinfo.h> |
| 56 | #include <ddi/device.h> |
55 | #include <ddi/device.h> |
| - | 56 | #include <symtab.h> |
|
| - | 57 | #include <errno.h> |
|
| 57 | 58 | ||
| 58 | /** Simple kernel console. |
59 | /** Simple kernel console. |
| 59 | * |
60 | * |
| 60 | * The console is realized by kernel thread kconsole. |
61 | * The console is realized by kernel thread kconsole. |
| 61 | * It doesn't understand any useful command on its own, |
62 | * It doesn't understand any useful command on its own, |
| Line 131... | Line 132... | ||
| 131 | * Initialize the virtual IRQ notification mechanism. |
132 | * Initialize the virtual IRQ notification mechanism. |
| 132 | * |
133 | * |
| 133 | */ |
134 | */ |
| 134 | void kconsole_notify_init(void) |
135 | void kconsole_notify_init(void) |
| 135 | { |
136 | { |
| 136 | devno_t devno = device_assign_devno(); |
- | |
| 137 | - | ||
| 138 | sysinfo_set_item_val("kconsole.present", NULL, true); |
137 | sysinfo_set_item_val("kconsole.present", NULL, true); |
| 139 | sysinfo_set_item_val("kconsole.devno", NULL, devno); |
- | |
| 140 | sysinfo_set_item_val("kconsole.inr", NULL, KCONSOLE_VIRT_INR); |
138 | sysinfo_set_item_val("kconsole.inr", NULL, KCONSOLE_VIRT_INR); |
| 141 | 139 | ||
| 142 | irq_initialize(&kconsole_irq); |
140 | irq_initialize(&kconsole_irq); |
| 143 | kconsole_irq.devno = devno; |
141 | kconsole_irq.devno = device_assign_devno(); |
| 144 | kconsole_irq.inr = KCONSOLE_VIRT_INR; |
142 | kconsole_irq.inr = KCONSOLE_VIRT_INR; |
| 145 | kconsole_irq.claim = kconsole_claim; |
143 | kconsole_irq.claim = kconsole_claim; |
| 146 | irq_register(&kconsole_irq); |
144 | irq_register(&kconsole_irq); |
| 147 | 145 | ||
| 148 | kconsole_notify = true; |
146 | kconsole_notify = true; |
| Line 256... | Line 254... | ||
| 256 | * @param name - string to match, changed to hint on exit |
254 | * @param name - string to match, changed to hint on exit |
| 257 | * @return number of found matches |
255 | * @return number of found matches |
| 258 | */ |
256 | */ |
| 259 | static int cmdtab_compl(char *name) |
257 | static int cmdtab_compl(char *name) |
| 260 | { |
258 | { |
| 261 | static char output[MAX_SYMBOL_NAME + 1]; |
259 | static char output[/*MAX_SYMBOL_NAME*/128 + 1]; |
| 262 | link_t *startpos = NULL; |
260 | link_t *startpos = NULL; |
| 263 | const char *foundtxt; |
261 | const char *foundtxt; |
| 264 | int found = 0; |
262 | int found = 0; |
| 265 | int i; |
263 | int i; |
| 266 | 264 | ||
| Line 288... | Line 286... | ||
| 288 | hlp = list_get_instance(startpos, cmd_info_t, link); |
286 | hlp = list_get_instance(startpos, cmd_info_t, link); |
| 289 | printf("%s - %s\n", hlp->name, hlp->description); |
287 | printf("%s - %s\n", hlp->name, hlp->description); |
| 290 | startpos = startpos->next; |
288 | startpos = startpos->next; |
| 291 | } |
289 | } |
| 292 | } |
290 | } |
| 293 | strncpy(name, output, MAX_SYMBOL_NAME); |
291 | strncpy(name, output, 128/*MAX_SYMBOL_NAME*/); |
| 294 | return found; |
292 | return found; |
| 295 | - | ||
| 296 | } |
293 | } |
| 297 | 294 | ||
| 298 | static char *clever_readline(const char *prompt, chardev_t *input) |
295 | static char *clever_readline(const char *prompt, indev_t *input) |
| 299 | { |
296 | { |
| 300 | static int histposition = 0; |
297 | static int histposition = 0; |
| 301 | 298 | ||
| 302 | static char tmp[MAX_CMDLINE + 1]; |
299 | static char tmp[MAX_CMDLINE + 1]; |
| 303 | int curlen = 0, position = 0; |
300 | int curlen = 0, position = 0; |
| Line 454... | Line 451... | ||
| 454 | } |
451 | } |
| 455 | current[curlen] = '\0'; |
452 | current[curlen] = '\0'; |
| 456 | return current; |
453 | return current; |
| 457 | } |
454 | } |
| 458 | 455 | ||
| - | 456 | bool kconsole_check_poll(void) |
|
| - | 457 | { |
|
| - | 458 | return check_poll(stdin); |
|
| - | 459 | } |
|
| - | 460 | ||
| 459 | /** Kernel console prompt. |
461 | /** Kernel console prompt. |
| 460 | * |
462 | * |
| 461 | * @param prompt Kernel console prompt (e.g kconsole/panic). |
463 | * @param prompt Kernel console prompt (e.g kconsole/panic). |
| 462 | * @param msg Message to display in the beginning. |
464 | * @param msg Message to display in the beginning. |
| 463 | * @param kcon Wait for keypress to show the prompt |
465 | * @param kcon Wait for keypress to show the prompt |
| Line 467... | Line 469... | ||
| 467 | void kconsole(char *prompt, char *msg, bool kcon) |
469 | void kconsole(char *prompt, char *msg, bool kcon) |
| 468 | { |
470 | { |
| 469 | cmd_info_t *cmd_info; |
471 | cmd_info_t *cmd_info; |
| 470 | count_t len; |
472 | count_t len; |
| 471 | char *cmdline; |
473 | char *cmdline; |
| 472 | 474 | ||
| 473 | if (!stdin) { |
475 | if (!stdin) { |
| 474 | LOG("No stdin for kernel console"); |
476 | LOG("No stdin for kernel console"); |
| 475 | return; |
477 | return; |
| 476 | } |
478 | } |
| 477 | 479 | ||
| 478 | if (msg) |
480 | if (msg) |
| 479 | printf("%s", msg); |
481 | printf("%s", msg); |
| 480 | 482 | ||
| 481 | if (kcon) |
483 | if (kcon) |
| 482 | _getc(stdin); |
484 | _getc(stdin); |
| - | 485 | else |
|
| - | 486 | printf("Type \"exit\" to leave the console.\n"); |
|
| 483 | 487 | ||
| 484 | while (true) { |
488 | while (true) { |
| 485 | cmdline = clever_readline((char *) prompt, stdin); |
489 | cmdline = clever_readline((char *) prompt, stdin); |
| 486 | len = strlen(cmdline); |
490 | len = strlen(cmdline); |
| 487 | if (!len) |
491 | if (!len) |
| 488 | continue; |
492 | continue; |
| 489 | 493 | ||
| - | 494 | if ((!kcon) && (len == 4) && (strncmp(cmdline, "exit", 4) == 0)) |
|
| - | 495 | break; |
|
| - | 496 | ||
| 490 | cmd_info = parse_cmdline(cmdline, len); |
497 | cmd_info = parse_cmdline(cmdline, len); |
| 491 | if (!cmd_info) |
498 | if (!cmd_info) |
| 492 | continue; |
499 | continue; |
| 493 | 500 | ||
| 494 | if ((!kcon) |
- | |
| 495 | && (strncmp(cmd_info->name, "exit", min(strlen(cmd_info->name), 5)) == 0)) |
- | |
| 496 | break; |
- | |
| 497 | - | ||
| 498 | (void) cmd_info->func(cmd_info->argv); |
501 | (void) cmd_info->func(cmd_info->argv); |
| 499 | } |
502 | } |
| 500 | } |
503 | } |
| 501 | 504 | ||
| 502 | /** Kernel console managing thread. |
505 | /** Kernel console managing thread. |
| Line 507... | Line 510... | ||
| 507 | kconsole("kconsole", "Kernel console ready (press any key to activate)\n", true); |
510 | kconsole("kconsole", "Kernel console ready (press any key to activate)\n", true); |
| 508 | } |
511 | } |
| 509 | 512 | ||
| 510 | static int parse_int_arg(char *text, size_t len, unative_t *result) |
513 | static int parse_int_arg(char *text, size_t len, unative_t *result) |
| 511 | { |
514 | { |
| 512 | static char symname[MAX_SYMBOL_NAME]; |
- | |
| 513 | uintptr_t symaddr; |
515 | uintptr_t symaddr; |
| 514 | bool isaddr = false; |
516 | bool isaddr = false; |
| 515 | bool isptr = false; |
517 | bool isptr = false; |
| - | 518 | int rc; |
|
| - | 519 | ||
| - | 520 | static char symname[MAX_SYMBOL_NAME]; |
|
| 516 | 521 | ||
| 517 | /* If we get a name, try to find it in symbol table */ |
522 | /* If we get a name, try to find it in symbol table */ |
| 518 | if (text[0] == '&') { |
523 | if (text[0] == '&') { |
| 519 | isaddr = true; |
524 | isaddr = true; |
| 520 | text++; |
525 | text++; |
| Line 524... | Line 529... | ||
| 524 | text++; |
529 | text++; |
| 525 | len--; |
530 | len--; |
| 526 | } |
531 | } |
| 527 | if (text[0] < '0' || text[0] > '9') { |
532 | if (text[0] < '0' || text[0] > '9') { |
| 528 | strncpy(symname, text, min(len + 1, MAX_SYMBOL_NAME)); |
533 | strncpy(symname, text, min(len + 1, MAX_SYMBOL_NAME)); |
| 529 | symaddr = get_symbol_addr(symname); |
534 | rc = symtab_addr_lookup(symname, &symaddr); |
| 530 | if (!symaddr) { |
535 | switch (rc) { |
| - | 536 | case ENOENT: |
|
| 531 | printf("Symbol %s not found.\n", symname); |
537 | printf("Symbol %s not found.\n", symname); |
| 532 | return -1; |
538 | return -1; |
| 533 | } |
- | |
| 534 | if (symaddr == (uintptr_t) -1) { |
539 | case EOVERFLOW: |
| 535 | printf("Duplicate symbol %s.\n", symname); |
540 | printf("Duplicate symbol %s.\n", symname); |
| 536 | symtab_print_search(symname); |
541 | symtab_print_search(symname); |
| 537 | return -1; |
542 | return -1; |
| - | 543 | default: |
|
| - | 544 | printf("No symbol information available.\n"); |
|
| - | 545 | return -1; |
|
| 538 | } |
546 | } |
| - | 547 | ||
| 539 | if (isaddr) |
548 | if (isaddr) |
| 540 | *result = (unative_t)symaddr; |
549 | *result = (unative_t)symaddr; |
| 541 | else if (isptr) |
550 | else if (isptr) |
| 542 | *result = **((unative_t **)symaddr); |
551 | *result = **((unative_t **)symaddr); |
| 543 | else |
552 | else |