Subversion Repositories HelenOS

Rev

Rev 3022 | Rev 4156 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3022 Rev 4055
Line 47... Line 47...
47
#include <adt/list.h>
47
#include <adt/list.h>
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 <symtab.h>
53
#include <symtab.h>
53
#include <macros.h>
54
#include <macros.h>
-
 
55
#include <sysinfo/sysinfo.h>
-
 
56
#include <ddi/device.h>
54
 
57
 
55
/** Simple kernel console.
58
/** Simple kernel console.
56
 *
59
 *
57
 * The console is realized by kernel thread kconsole.
60
 * The console is realized by kernel thread kconsole.
58
 * It doesn't understand any useful command on its own,
61
 * It doesn't understand any useful command on its own,
Line 81... Line 84...
81
static cmd_info_t *parse_cmdline(char *cmdline, size_t len);
84
static cmd_info_t *parse_cmdline(char *cmdline, size_t len);
82
static bool parse_argument(char *cmdline, size_t len, index_t *start,
85
static bool parse_argument(char *cmdline, size_t len, index_t *start,
83
    index_t *end);
86
    index_t *end);
84
static char history[KCONSOLE_HISTORY][MAX_CMDLINE] = {};
87
static char history[KCONSOLE_HISTORY][MAX_CMDLINE] = {};
85
 
88
 
-
 
89
/*
-
 
90
 * For now, we use 0 as INR.
-
 
91
 * However, it is therefore desirable to have architecture specific
-
 
92
 * definition of KCONSOLE_VIRT_INR in the future.
-
 
93
 */
-
 
94
#define KCONSOLE_VIRT_INR  0
-
 
95
 
-
 
96
bool kconsole_notify = false;
-
 
97
irq_t kconsole_irq;
-
 
98
 
-
 
99
 
-
 
100
/** Allways refuse IRQ ownership.
-
 
101
 *
-
 
102
 * This is not a real IRQ, so we always decline.
-
 
103
 *
-
 
104
 * @return Always returns IRQ_DECLINE.
-
 
105
 *
-
 
106
 */
-
 
107
static irq_ownership_t kconsole_claim(irq_t *irq)
-
 
108
{
-
 
109
    return IRQ_DECLINE;
-
 
110
}
-
 
111
 
-
 
112
 
86
/** Initialize kconsole data structures. */
113
/** Initialize kconsole data structures
-
 
114
 *
-
 
115
 * This is the most basic initialization, almost no
-
 
116
 * other kernel subsystem is ready yet.
-
 
117
 *
-
 
118
 */
87
void kconsole_init(void)
119
void kconsole_init(void)
88
{
120
{
89
    int i;
121
    unsigned int i;
90
 
122
 
91
    cmd_init();
123
    cmd_init();
92
    for (i = 0; i < KCONSOLE_HISTORY; i++)
124
    for (i = 0; i < KCONSOLE_HISTORY; i++)
93
        history[i][0] = '\0';
125
        history[i][0] = '\0';
94
}
126
}
95
 
127
 
96
 
128
 
-
 
129
/** Initialize kconsole notification mechanism
-
 
130
 *
-
 
131
 * Initialize the virtual IRQ notification mechanism.
-
 
132
 *
-
 
133
 */
-
 
134
void kconsole_notify_init(void)
-
 
135
{
-
 
136
    devno_t devno = device_assign_devno();
-
 
137
   
-
 
138
    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);
-
 
141
   
-
 
142
    irq_initialize(&kconsole_irq);
-
 
143
    kconsole_irq.devno = devno;
-
 
144
    kconsole_irq.inr = KCONSOLE_VIRT_INR;
-
 
145
    kconsole_irq.claim = kconsole_claim;
-
 
146
    irq_register(&kconsole_irq);
-
 
147
   
-
 
148
    kconsole_notify = true;
-
 
149
}
-
 
150
 
-
 
151
 
97
/** Register kconsole command.
152
/** Register kconsole command.
98
 *
153
 *
99
 * @param cmd Structure describing the command.
154
 * @param cmd Structure describing the command.
100
 *
155
 *
101
 * @return 0 on failure, 1 on success.
156
 * @return 0 on failure, 1 on success.
Line 255... Line 310...
255
    while (1) {
310
    while (1) {
256
        c = _getc(input);
311
        c = _getc(input);
257
        if (c == '\n') {
312
        if (c == '\n') {
258
            putchar(c);
313
            putchar(c);
259
            break;
314
            break;
-
 
315
        }
260
        } if (c == '\b') { /* Backspace */
316
        if (c == '\b') { /* Backspace */
261
            if (position == 0)
317
            if (position == 0)
262
                continue;
318
                continue;
263
            for (i = position; i < curlen; i++)
319
            for (i = position; i < curlen; i++)
264
                current[i - 1] = current[i];
320
                current[i - 1] = current[i];
265
            curlen--;
321
            curlen--;
Line 398... Line 454...
398
    }
454
    }
399
    current[curlen] = '\0';
455
    current[curlen] = '\0';
400
    return current;
456
    return current;
401
}
457
}
402
 
458
 
403
/** Kernel console managing thread.
459
/** Kernel console prompt.
404
 *
460
 *
405
 * @param prompt Kernel console prompt (e.g kconsole/panic).
461
 * @param prompt Kernel console prompt (e.g kconsole/panic).
-
 
462
 * @param msg    Message to display in the beginning.
-
 
463
 * @param kcon   Wait for keypress to show the prompt
-
 
464
 *               and never exit.
-
 
465
 *
406
 */
466
 */
407
void kconsole(void *prompt)
467
void kconsole(char *prompt, char *msg, bool kcon)
408
{
468
{
409
    cmd_info_t *cmd_info;
469
    cmd_info_t *cmd_info;
410
    count_t len;
470
    count_t len;
411
    char *cmdline;
471
    char *cmdline;
412
 
472
 
413
    if (!stdin) {
473
    if (!stdin) {
414
        printf("%s: no stdin\n", __func__);
474
        LOG("No stdin for kernel console");
415
        return;
475
        return;
416
    }
476
    }
417
   
477
   
-
 
478
    if (msg)
-
 
479
        printf("%s", msg);
-
 
480
   
-
 
481
    if (kcon)
-
 
482
        _getc(stdin);
-
 
483
   
418
    while (true) {
484
    while (true) {
419
        cmdline = clever_readline((char *) prompt, stdin);
485
        cmdline = clever_readline((char *) prompt, stdin);
420
        len = strlen(cmdline);
486
        len = strlen(cmdline);
421
        if (!len)
487
        if (!len)
422
            continue;
488
            continue;
-
 
489
       
423
        cmd_info = parse_cmdline(cmdline, len);
490
        cmd_info = parse_cmdline(cmdline, len);
424
        if (!cmd_info)
491
        if (!cmd_info)
425
            continue;
492
            continue;
-
 
493
       
426
        if (strncmp(cmd_info->name, "exit",
494
        if ((!kcon)
427
            min(strlen(cmd_info->name), 5)) == 0)
495
            && (strncmp(cmd_info->name, "exit", min(strlen(cmd_info->name), 5)) == 0))
428
            break;
496
            break;
-
 
497
       
429
        (void) cmd_info->func(cmd_info->argv);
498
        (void) cmd_info->func(cmd_info->argv);
430
    }
499
    }
431
}
500
}
432
 
501
 
-
 
502
/** Kernel console managing thread.
-
 
503
 *
-
 
504
 */
-
 
505
void kconsole_thread(void *data)
-
 
506
{
-
 
507
    kconsole("kconsole", "Kernel console ready (press any key to activate)\n", true);
-
 
508
}
-
 
509
 
433
static int parse_int_arg(char *text, size_t len, unative_t *result)
510
static int parse_int_arg(char *text, size_t len, unative_t *result)
434
{
511
{
435
    static char symname[MAX_SYMBOL_NAME];
512
    static char symname[MAX_SYMBOL_NAME];
436
    uintptr_t symaddr;
513
    uintptr_t symaddr;
437
    bool isaddr = false;
514
    bool isaddr = false;
Line 541... Line 618...
541
        switch (cmd->argv[i].type) {
618
        switch (cmd->argv[i].type) {
542
        case ARG_TYPE_STRING:
619
        case ARG_TYPE_STRING:
543
            buf = (char *) cmd->argv[i].buffer;
620
            buf = (char *) cmd->argv[i].buffer;
544
            strncpy(buf, (const char *) &cmdline[start],
621
            strncpy(buf, (const char *) &cmdline[start],
545
                min((end - start) + 2, cmd->argv[i].len));
622
                min((end - start) + 2, cmd->argv[i].len));
546
            buf[min((end - start) + 1, cmd->argv[i].len - 1)] = '\0';
623
            buf[min((end - start) + 1, cmd->argv[i].len - 1)] =
-
 
624
                '\0';
547
            break;
625
            break;
548
        case ARG_TYPE_INT:
626
        case ARG_TYPE_INT:
549
            if (parse_int_arg(cmdline + start, end - start + 1,
627
            if (parse_int_arg(cmdline + start, end - start + 1,
550
                &cmd->argv[i].intval))
628
                &cmd->argv[i].intval))
551
                error = 1;
629
                error = 1;
Line 558... Line 636...
558
                    min((end-start), cmd->argv[i].len));
636
                    min((end-start), cmd->argv[i].len));
559
                buf[min((end - start), cmd->argv[i].len - 1)] =
637
                buf[min((end - start), cmd->argv[i].len - 1)] =
560
                    '\0';
638
                    '\0';
561
                cmd->argv[i].intval = (unative_t) buf;
639
                cmd->argv[i].intval = (unative_t) buf;
562
                cmd->argv[i].vartype = ARG_TYPE_STRING;
640
                cmd->argv[i].vartype = ARG_TYPE_STRING;
563
            } else if (!parse_int_arg(cmdline + start, end - start + 1,
641
            } else if (!parse_int_arg(cmdline + start,
564
                &cmd->argv[i].intval)) {
642
                end - start + 1, &cmd->argv[i].intval)) {
565
                cmd->argv[i].vartype = ARG_TYPE_INT;
643
                cmd->argv[i].vartype = ARG_TYPE_INT;
566
            } else {
644
            } else {
567
                printf("Unrecognized variable argument.\n");
645
                printf("Unrecognized variable argument.\n");
568
                error = 1;
646
                error = 1;
569
            }
647
            }