Subversion Repositories HelenOS

Rev

Rev 3022 | Rev 4201 | Go to most recent revision | Show entire file | Ignore 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 167... Line 222...
167
        str[i] = str[i - 1];
222
        str[i] = str[i - 1];
168
    str[pos] = ch;
223
    str[pos] = ch;
169
}
224
}
170
 
225
 
171
/** Try to find a command beginning with prefix */
226
/** Try to find a command beginning with prefix */
172
static const char * cmdtab_search_one(const char *name,link_t **startpos)
227
static const char *cmdtab_search_one(const char *name,link_t **startpos)
173
{
228
{
174
    size_t namelen = strlen(name);
229
    size_t namelen = strlen(name);
175
    const char *curname;
230
    const char *curname;
176
 
231
 
177
    spinlock_lock(&cmd_lock);
232
    spinlock_lock(&cmd_lock);
Line 201... Line 256...
201
 * @param name - string to match, changed to hint on exit
256
 * @param name - string to match, changed to hint on exit
202
 * @return number of found matches
257
 * @return number of found matches
203
 */
258
 */
204
static int cmdtab_compl(char *name)
259
static int cmdtab_compl(char *name)
205
{
260
{
206
    static char output[MAX_SYMBOL_NAME+1];
261
    static char output[MAX_SYMBOL_NAME + 1];
207
    link_t *startpos = NULL;
262
    link_t *startpos = NULL;
208
    const char *foundtxt;
263
    const char *foundtxt;
209
    int found = 0;
264
    int found = 0;
210
    int i;
265
    int i;
211
 
266
 
212
    output[0] = '\0';
267
    output[0] = '\0';
213
    while ((foundtxt = cmdtab_search_one(name, &startpos))) {
268
    while ((foundtxt = cmdtab_search_one(name, &startpos))) {
214
        startpos = startpos->next;
269
        startpos = startpos->next;
215
        if (!found)
270
        if (!found)
216
            strncpy(output, foundtxt, strlen(foundtxt)+1);
271
            strncpy(output, foundtxt, strlen(foundtxt) + 1);
217
        else {
272
        else {
218
            for (i = 0; output[i] && foundtxt[i] &&
273
            for (i = 0; output[i] && foundtxt[i] &&
219
                output[i] == foundtxt[i]; i++)
274
                output[i] == foundtxt[i]; i++)
220
                ;
275
                ;
221
            output[i] = '\0';
276
            output[i] = '\0';
Line 238... Line 293...
238
    strncpy(name, output, MAX_SYMBOL_NAME);
293
    strncpy(name, output, MAX_SYMBOL_NAME);
239
    return found;
294
    return found;
240
   
295
   
241
}
296
}
242
 
297
 
243
static char * clever_readline(const char *prompt, chardev_t *input)
298
static char *clever_readline(const char *prompt, chardev_t *input)
244
{
299
{
245
    static int histposition = 0;
300
    static int histposition = 0;
246
 
301
 
247
    static char tmp[MAX_CMDLINE+1];
302
    static char tmp[MAX_CMDLINE + 1];
248
    int curlen = 0, position = 0;
303
    int curlen = 0, position = 0;
249
    char *current = history[histposition];
304
    char *current = history[histposition];
250
    int i;
305
    int i;
251
    char mod; /* Command Modifier */
306
    char mod; /* Command Modifier */
252
    char c;
307
    char c;
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
            }