Subversion Repositories HelenOS

Rev

Rev 3386 | Rev 4263 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3386 Rev 4153
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 <symtab.h>
52
#include <string.h>
53
#include <macros.h>
53
#include <macros.h>
-
 
54
#include <sysinfo/sysinfo.h>
-
 
55
#include <ddi/device.h>
-
 
56
#include <symtab.h>
-
 
57
#include <errno.h>
54
 
58
 
55
/** Simple kernel console.
59
/** Simple kernel console.
56
 *
60
 *
57
 * The console is realized by kernel thread kconsole.
61
 * The console is realized by kernel thread kconsole.
58
 * It doesn't understand any useful command on its own,
62
 * It doesn't understand any useful command on its own,
Line 81... Line 85...
81
static cmd_info_t *parse_cmdline(char *cmdline, size_t len);
85
static cmd_info_t *parse_cmdline(char *cmdline, size_t len);
82
static bool parse_argument(char *cmdline, size_t len, index_t *start,
86
static bool parse_argument(char *cmdline, size_t len, index_t *start,
83
    index_t *end);
87
    index_t *end);
84
static char history[KCONSOLE_HISTORY][MAX_CMDLINE] = {};
88
static char history[KCONSOLE_HISTORY][MAX_CMDLINE] = {};
85
 
89
 
-
 
90
/*
-
 
91
 * For now, we use 0 as INR.
-
 
92
 * However, it is therefore desirable to have architecture specific
-
 
93
 * definition of KCONSOLE_VIRT_INR in the future.
-
 
94
 */
-
 
95
#define KCONSOLE_VIRT_INR  0
-
 
96
 
-
 
97
bool kconsole_notify = false;
-
 
98
irq_t kconsole_irq;
-
 
99
 
-
 
100
 
-
 
101
/** Allways refuse IRQ ownership.
-
 
102
 *
-
 
103
 * This is not a real IRQ, so we always decline.
-
 
104
 *
-
 
105
 * @return Always returns IRQ_DECLINE.
-
 
106
 *
-
 
107
 */
-
 
108
static irq_ownership_t kconsole_claim(irq_t *irq)
-
 
109
{
-
 
110
    return IRQ_DECLINE;
-
 
111
}
-
 
112
 
-
 
113
 
86
/** Initialize kconsole data structures. */
114
/** Initialize kconsole data structures
-
 
115
 *
-
 
116
 * This is the most basic initialization, almost no
-
 
117
 * other kernel subsystem is ready yet.
-
 
118
 *
-
 
119
 */
87
void kconsole_init(void)
120
void kconsole_init(void)
88
{
121
{
89
    int i;
122
    unsigned int i;
90
 
123
 
91
    cmd_init();
124
    cmd_init();
92
    for (i = 0; i < KCONSOLE_HISTORY; i++)
125
    for (i = 0; i < KCONSOLE_HISTORY; i++)
93
        history[i][0] = '\0';
126
        history[i][0] = '\0';
94
}
127
}
95
 
128
 
96
 
129
 
-
 
130
/** Initialize kconsole notification mechanism
-
 
131
 *
-
 
132
 * Initialize the virtual IRQ notification mechanism.
-
 
133
 *
-
 
134
 */
-
 
135
void kconsole_notify_init(void)
-
 
136
{
-
 
137
    sysinfo_set_item_val("kconsole.present", NULL, true);
-
 
138
    sysinfo_set_item_val("kconsole.inr", NULL, KCONSOLE_VIRT_INR);
-
 
139
   
-
 
140
    irq_initialize(&kconsole_irq);
-
 
141
    kconsole_irq.devno = device_assign_devno();
-
 
142
    kconsole_irq.inr = KCONSOLE_VIRT_INR;
-
 
143
    kconsole_irq.claim = kconsole_claim;
-
 
144
    irq_register(&kconsole_irq);
-
 
145
   
-
 
146
    kconsole_notify = true;
-
 
147
}
-
 
148
 
-
 
149
 
97
/** Register kconsole command.
150
/** Register kconsole command.
98
 *
151
 *
99
 * @param cmd Structure describing the command.
152
 * @param cmd Structure describing the command.
100
 *
153
 *
101
 * @return 0 on failure, 1 on success.
154
 * @return 0 on failure, 1 on success.
Line 201... Line 254...
201
 * @param name - string to match, changed to hint on exit
254
 * @param name - string to match, changed to hint on exit
202
 * @return number of found matches
255
 * @return number of found matches
203
 */
256
 */
204
static int cmdtab_compl(char *name)
257
static int cmdtab_compl(char *name)
205
{
258
{
206
    static char output[MAX_SYMBOL_NAME + 1];
259
    static char output[/*MAX_SYMBOL_NAME*/128 + 1];
207
    link_t *startpos = NULL;
260
    link_t *startpos = NULL;
208
    const char *foundtxt;
261
    const char *foundtxt;
209
    int found = 0;
262
    int found = 0;
210
    int i;
263
    int i;
211
 
264
 
Line 233... Line 286...
233
            hlp = list_get_instance(startpos, cmd_info_t, link);
286
            hlp = list_get_instance(startpos, cmd_info_t, link);
234
            printf("%s - %s\n", hlp->name, hlp->description);
287
            printf("%s - %s\n", hlp->name, hlp->description);
235
            startpos = startpos->next;
288
            startpos = startpos->next;
236
        }
289
        }
237
    }
290
    }
238
    strncpy(name, output, MAX_SYMBOL_NAME);
291
    strncpy(name, output, 128/*MAX_SYMBOL_NAME*/);
239
    return found;
292
    return found;
240
   
-
 
241
}
293
}
242
 
294
 
243
static char *clever_readline(const char *prompt, chardev_t *input)
295
static char *clever_readline(const char *prompt, indev_t *input)
244
{
296
{
245
    static int histposition = 0;
297
    static int histposition = 0;
246
 
298
 
247
    static char tmp[MAX_CMDLINE + 1];
299
    static char tmp[MAX_CMDLINE + 1];
248
    int curlen = 0, position = 0;
300
    int curlen = 0, position = 0;
Line 399... Line 451...
399
    }
451
    }
400
    current[curlen] = '\0';
452
    current[curlen] = '\0';
401
    return current;
453
    return current;
402
}
454
}
403
 
455
 
-
 
456
bool kconsole_check_poll(void)
-
 
457
{
-
 
458
    return check_poll(stdin);
-
 
459
}
-
 
460
 
404
/** Kernel console managing thread.
461
/** Kernel console prompt.
405
 *
462
 *
406
 * @param prompt Kernel console prompt (e.g kconsole/panic).
463
 * @param prompt Kernel console prompt (e.g kconsole/panic).
-
 
464
 * @param msg    Message to display in the beginning.
-
 
465
 * @param kcon   Wait for keypress to show the prompt
-
 
466
 *               and never exit.
-
 
467
 *
407
 */
468
 */
408
void kconsole(void *prompt)
469
void kconsole(char *prompt, char *msg, bool kcon)
409
{
470
{
410
    cmd_info_t *cmd_info;
471
    cmd_info_t *cmd_info;
411
    count_t len;
472
    count_t len;
412
    char *cmdline;
473
    char *cmdline;
413
 
474
   
414
    if (!stdin) {
475
    if (!stdin) {
415
        printf("%s: no stdin\n", __func__);
476
        LOG("No stdin for kernel console");
416
        return;
477
        return;
417
    }
478
    }
418
   
479
   
-
 
480
    if (msg)
-
 
481
        printf("%s", msg);
-
 
482
   
-
 
483
    if (kcon)
-
 
484
        _getc(stdin);
-
 
485
    else
-
 
486
        printf("Type \"exit\" to leave the console.\n");
-
 
487
   
419
    while (true) {
488
    while (true) {
420
        cmdline = clever_readline((char *) prompt, stdin);
489
        cmdline = clever_readline((char *) prompt, stdin);
421
        len = strlen(cmdline);
490
        len = strlen(cmdline);
422
        if (!len)
491
        if (!len)
423
            continue;
492
            continue;
-
 
493
       
-
 
494
        if ((!kcon) && (len == 4) && (strncmp(cmdline, "exit", 4) == 0))
-
 
495
            break;
-
 
496
       
424
        cmd_info = parse_cmdline(cmdline, len);
497
        cmd_info = parse_cmdline(cmdline, len);
425
        if (!cmd_info)
498
        if (!cmd_info)
426
            continue;
499
            continue;
427
        if (strncmp(cmd_info->name, "exit",
-
 
428
            min(strlen(cmd_info->name), 5)) == 0)
-
 
429
            break;
500
       
430
        (void) cmd_info->func(cmd_info->argv);
501
        (void) cmd_info->func(cmd_info->argv);
431
    }
502
    }
432
}
503
}
433
 
504
 
-
 
505
/** Kernel console managing thread.
-
 
506
 *
-
 
507
 */
-
 
508
void kconsole_thread(void *data)
-
 
509
{
-
 
510
    kconsole("kconsole", "Kernel console ready (press any key to activate)\n", true);
-
 
511
}
-
 
512
 
434
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)
435
{
514
{
436
    static char symname[MAX_SYMBOL_NAME];
-
 
437
    uintptr_t symaddr;
515
    uintptr_t symaddr;
438
    bool isaddr = false;
516
    bool isaddr = false;
439
    bool isptr = false;
517
    bool isptr = false;
-
 
518
    int rc;
-
 
519
 
-
 
520
    static char symname[MAX_SYMBOL_NAME];
440
   
521
   
441
    /* 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 */
442
    if (text[0] == '&') {
523
    if (text[0] == '&') {
443
        isaddr = true;
524
        isaddr = true;
444
        text++;
525
        text++;
Line 448... Line 529...
448
        text++;
529
        text++;
449
        len--;
530
        len--;
450
    }
531
    }
451
    if (text[0] < '0' || text[0] > '9') {
532
    if (text[0] < '0' || text[0] > '9') {
452
        strncpy(symname, text, min(len + 1, MAX_SYMBOL_NAME));
533
        strncpy(symname, text, min(len + 1, MAX_SYMBOL_NAME));
453
        symaddr = get_symbol_addr(symname);
534
        rc = symtab_addr_lookup(symname, &symaddr);
454
        if (!symaddr) {
535
        switch (rc) {
-
 
536
        case ENOENT:
455
            printf("Symbol %s not found.\n", symname);
537
            printf("Symbol %s not found.\n", symname);
456
            return -1;
538
            return -1;
457
        }
-
 
458
        if (symaddr == (uintptr_t) -1) {
539
        case EOVERFLOW:
459
            printf("Duplicate symbol %s.\n", symname);
540
            printf("Duplicate symbol %s.\n", symname);
460
            symtab_print_search(symname);
541
            symtab_print_search(symname);
461
            return -1;
542
            return -1;
-
 
543
        default:
-
 
544
            printf("No symbol information available.\n");
-
 
545
            return -1;
462
        }
546
        }
-
 
547
 
463
        if (isaddr)
548
        if (isaddr)
464
            *result = (unative_t)symaddr;
549
            *result = (unative_t)symaddr;
465
        else if (isptr)
550
        else if (isptr)
466
            *result = **((unative_t **)symaddr);
551
            *result = **((unative_t **)symaddr);
467
        else
552
        else