49,8 → 49,12 |
#include <macros.h> |
#include <debug.h> |
#include <func.h> |
#include <string.h> |
#include <macros.h> |
#include <sysinfo/sysinfo.h> |
#include <ddi/device.h> |
#include <symtab.h> |
#include <macros.h> |
#include <errno.h> |
|
/** Simple kernel console. |
* |
83,10 → 87,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 → 127,26 |
} |
|
|
/** Initialize kconsole notification mechanism |
* |
* Initialize the virtual IRQ notification mechanism. |
* |
*/ |
void kconsole_notify_init(void) |
{ |
sysinfo_set_item_val("kconsole.present", NULL, true); |
sysinfo_set_item_val("kconsole.inr", NULL, KCONSOLE_VIRT_INR); |
|
irq_initialize(&kconsole_irq); |
kconsole_irq.devno = device_assign_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. |
203,7 → 256,7 |
*/ |
static int cmdtab_compl(char *name) |
{ |
static char output[MAX_SYMBOL_NAME + 1]; |
static char output[/*MAX_SYMBOL_NAME*/128 + 1]; |
link_t *startpos = NULL; |
const char *foundtxt; |
int found = 0; |
235,12 → 288,11 |
startpos = startpos->next; |
} |
} |
strncpy(name, output, MAX_SYMBOL_NAME); |
strncpy(name, output, 128/*MAX_SYMBOL_NAME*/); |
return found; |
|
} |
|
static char *clever_readline(const char *prompt, chardev_t *input) |
static char *clever_readline(const char *prompt, indev_t *input) |
{ |
static int histposition = 0; |
|
401,42 → 453,71 |
return current; |
} |
|
/** Kernel console managing thread. |
bool kconsole_check_poll(void) |
{ |
return check_poll(stdin); |
} |
|
/** 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; |
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); |
else |
printf("Type \"exit\" to leave the console.\n"); |
|
while (true) { |
cmdline = clever_readline((char *) prompt, stdin); |
len = strlen(cmdline); |
if (!len) |
continue; |
|
if ((!kcon) && (len == 4) && (strncmp(cmdline, "exit", 4) == 0)) |
break; |
|
cmd_info = parse_cmdline(cmdline, len); |
if (!cmd_info) |
continue; |
if (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]; |
uintptr_t symaddr; |
bool isaddr = false; |
bool isptr = false; |
int rc; |
|
static char symname[MAX_SYMBOL_NAME]; |
|
/* If we get a name, try to find it in symbol table */ |
if (text[0] == '&') { |
450,16 → 531,20 |
} |
if (text[0] < '0' || text[0] > '9') { |
strncpy(symname, text, min(len + 1, MAX_SYMBOL_NAME)); |
symaddr = get_symbol_addr(symname); |
if (!symaddr) { |
rc = symtab_addr_lookup(symname, &symaddr); |
switch (rc) { |
case ENOENT: |
printf("Symbol %s not found.\n", symname); |
return -1; |
} |
if (symaddr == (uintptr_t) -1) { |
case EOVERFLOW: |
printf("Duplicate symbol %s.\n", symname); |
symtab_print_search(symname); |
return -1; |
default: |
printf("No symbol information available.\n"); |
return -1; |
} |
|
if (isaddr) |
*result = (unative_t)symaddr; |
else if (isptr) |