49,8 → 49,11 |
#include <macros.h> |
#include <debug.h> |
#include <func.h> |
#include <string.h> |
#include <symtab.h> |
#include <macros.h> |
#include <sysinfo/sysinfo.h> |
#include <ddi/device.h> |
|
/** Simple kernel console. |
* |
83,10 → 86,39 |
index_t *end); |
static char history[KCONSOLE_HISTORY][MAX_CMDLINE] = {}; |
|
/** Initialize kconsole data structures. */ |
/* |
* For now, we use 0 as INR. |
* However, it is therefore desirable to have architecture specific |
* definition of KCONSOLE_VIRT_INR in the future. |
*/ |
#define KCONSOLE_VIRT_INR 0 |
|
bool kconsole_notify = false; |
irq_t kconsole_irq; |
|
|
/** Allways refuse IRQ ownership. |
* |
* This is not a real IRQ, so we always decline. |
* |
* @return Always returns IRQ_DECLINE. |
* |
*/ |
static irq_ownership_t kconsole_claim(irq_t *irq) |
{ |
return IRQ_DECLINE; |
} |
|
|
/** Initialize kconsole data structures |
* |
* This is the most basic initialization, almost no |
* other kernel subsystem is ready yet. |
* |
*/ |
void kconsole_init(void) |
{ |
int i; |
unsigned int i; |
|
cmd_init(); |
for (i = 0; i < KCONSOLE_HISTORY; i++) |
94,6 → 126,29 |
} |
|
|
/** Initialize kconsole notification mechanism |
* |
* Initialize the virtual IRQ notification mechanism. |
* |
*/ |
void kconsole_notify_init(void) |
{ |
devno_t devno = device_assign_devno(); |
|
sysinfo_set_item_val("kconsole.present", NULL, true); |
sysinfo_set_item_val("kconsole.devno", NULL, devno); |
sysinfo_set_item_val("kconsole.inr", NULL, KCONSOLE_VIRT_INR); |
|
irq_initialize(&kconsole_irq); |
kconsole_irq.devno = devno; |
kconsole_irq.inr = KCONSOLE_VIRT_INR; |
kconsole_irq.claim = kconsole_claim; |
irq_register(&kconsole_irq); |
|
kconsole_notify = true; |
} |
|
|
/** Register kconsole command. |
* |
* @param cmd Structure describing the command. |
169,7 → 224,7 |
} |
|
/** Try to find a command beginning with prefix */ |
static const char * cmdtab_search_one(const char *name,link_t **startpos) |
static const char *cmdtab_search_one(const char *name,link_t **startpos) |
{ |
size_t namelen = strlen(name); |
const char *curname; |
203,7 → 258,7 |
*/ |
static int cmdtab_compl(char *name) |
{ |
static char output[MAX_SYMBOL_NAME+1]; |
static char output[MAX_SYMBOL_NAME + 1]; |
link_t *startpos = NULL; |
const char *foundtxt; |
int found = 0; |
213,7 → 268,7 |
while ((foundtxt = cmdtab_search_one(name, &startpos))) { |
startpos = startpos->next; |
if (!found) |
strncpy(output, foundtxt, strlen(foundtxt)+1); |
strncpy(output, foundtxt, strlen(foundtxt) + 1); |
else { |
for (i = 0; output[i] && foundtxt[i] && |
output[i] == foundtxt[i]; i++) |
240,11 → 295,11 |
|
} |
|
static char * clever_readline(const char *prompt, chardev_t *input) |
static char *clever_readline(const char *prompt, chardev_t *input) |
{ |
static int histposition = 0; |
|
static char tmp[MAX_CMDLINE+1]; |
static char tmp[MAX_CMDLINE + 1]; |
int curlen = 0, position = 0; |
char *current = history[histposition]; |
int i; |
257,7 → 312,8 |
if (c == '\n') { |
putchar(c); |
break; |
} if (c == '\b') { /* Backspace */ |
} |
if (c == '\b') { /* Backspace */ |
if (position == 0) |
continue; |
for (i = position; i < curlen; i++) |
400,11 → 456,15 |
return current; |
} |
|
/** Kernel console managing thread. |
/** Kernel console prompt. |
* |
* @param prompt Kernel console prompt (e.g kconsole/panic). |
* @param msg Message to display in the beginning. |
* @param kcon Wait for keypress to show the prompt |
* and never exit. |
* |
*/ |
void kconsole(void *prompt) |
void kconsole(char *prompt, char *msg, bool kcon) |
{ |
cmd_info_t *cmd_info; |
count_t len; |
411,25 → 471,42 |
char *cmdline; |
|
if (!stdin) { |
printf("%s: no stdin\n", __func__); |
LOG("No stdin for kernel console"); |
return; |
} |
|
if (msg) |
printf("%s", msg); |
|
if (kcon) |
_getc(stdin); |
|
while (true) { |
cmdline = clever_readline((char *) prompt, stdin); |
len = strlen(cmdline); |
if (!len) |
continue; |
|
cmd_info = parse_cmdline(cmdline, len); |
if (!cmd_info) |
continue; |
if (strncmp(cmd_info->name, "exit", |
min(strlen(cmd_info->name), 5)) == 0) |
|
if ((!kcon) |
&& (strncmp(cmd_info->name, "exit", min(strlen(cmd_info->name), 5)) == 0)) |
break; |
|
(void) cmd_info->func(cmd_info->argv); |
} |
} |
|
/** Kernel console managing thread. |
* |
*/ |
void kconsole_thread(void *data) |
{ |
kconsole("kconsole", "Kernel console ready (press any key to activate)\n", true); |
} |
|
static int parse_int_arg(char *text, size_t len, unative_t *result) |
{ |
static char symname[MAX_SYMBOL_NAME]; |
543,7 → 620,8 |
buf = (char *) cmd->argv[i].buffer; |
strncpy(buf, (const char *) &cmdline[start], |
min((end - start) + 2, cmd->argv[i].len)); |
buf[min((end - start) + 1, cmd->argv[i].len - 1)] = '\0'; |
buf[min((end - start) + 1, cmd->argv[i].len - 1)] = |
'\0'; |
break; |
case ARG_TYPE_INT: |
if (parse_int_arg(cmdline + start, end - start + 1, |
560,8 → 638,8 |
'\0'; |
cmd->argv[i].intval = (unative_t) buf; |
cmd->argv[i].vartype = ARG_TYPE_STRING; |
} else if (!parse_int_arg(cmdline + start, end - start + 1, |
&cmd->argv[i].intval)) { |
} else if (!parse_int_arg(cmdline + start, |
end - start + 1, &cmd->argv[i].intval)) { |
cmd->argv[i].vartype = ARG_TYPE_INT; |
} else { |
printf("Unrecognized variable argument.\n"); |