/branches/network/kernel/generic/src/main/kinit.c |
---|
190,10 → 190,10 |
name = "<unknown>"; |
ASSERT(TASK_NAME_BUFLEN >= INIT_PREFIX_LEN); |
str_ncpy(namebuf, INIT_PREFIX, TASK_NAME_BUFLEN); |
str_ncpy(namebuf + INIT_PREFIX_LEN, name, |
TASK_NAME_BUFLEN - INIT_PREFIX_LEN); |
str_cpy(namebuf, TASK_NAME_BUFLEN, INIT_PREFIX); |
str_cpy(namebuf + INIT_PREFIX_LEN, |
TASK_NAME_BUFLEN - INIT_PREFIX_LEN, name); |
int rc = program_create_from_image((void *) init.tasks[i].addr, |
namebuf, &programs[i]); |
218,19 → 218,11 |
} |
/* |
* Run user tasks with small delays |
* to avoid intermixed klog output. |
* |
* TODO: This certainly does not guarantee |
* anything, it just works in most of the |
* cases. Some better way how to achieve |
* nice klog output should be found. |
* Run user tasks. |
*/ |
for (i = 0; i < init.cnt; i++) { |
if (programs[i].task != NULL) { |
if (programs[i].task != NULL) |
program_ready(&programs[i]); |
thread_usleep(10000); |
} |
} |
#ifdef CONFIG_KCONSOLE |
/branches/network/kernel/generic/src/debug/symtab.c |
---|
120,7 → 120,7 |
for (pos = *startpos; symbol_table[pos].address_le; pos++) { |
const char *curname = symbol_table[pos].symbol_name; |
/* Find a ':' in name */ |
/* Find a ':' in curname */ |
const char *colon = str_chr(curname, ':'); |
if (colon == NULL) |
continue; |
225,7 → 225,7 |
while ((hint = symtab_search_one(name, &pos))) { |
if ((found == 0) || (str_length(output) > str_length(hint))) |
str_ncpy(output, hint, MAX_SYMBOL_NAME); |
str_cpy(output, MAX_SYMBOL_NAME, hint); |
pos++; |
found++; |
241,7 → 241,7 |
} |
if (found > 0) |
str_ncpy(input, output, size); |
str_cpy(input, size, output); |
return found; |
/branches/network/kernel/generic/src/interrupt/interrupt.c |
---|
145,7 → 145,7 |
if (((i + 1) % 20) == 0) { |
printf(" -- Press any key to continue -- "); |
spinlock_unlock(&exctbl_lock); |
_getc(stdin); |
indev_pop_character(stdin); |
spinlock_lock(&exctbl_lock); |
printf("\n"); |
} |
/branches/network/kernel/generic/src/ddi/irq.c |
---|
351,11 → 351,12 |
/** Unlock IRQ structure after hash_table_remove(). |
* |
* @param lnk Link in the removed and locked IRQ structure. |
* @param lnk Link in the removed and locked IRQ structure. |
*/ |
void irq_ht_remove(link_t *lnk) |
{ |
irq_t *irq = hash_table_get_instance(lnk, irq_t, link); |
irq_t *irq __attribute__((unused)) |
= hash_table_get_instance(lnk, irq_t, link); |
spinlock_unlock(&irq->lock); |
} |
424,7 → 425,8 |
*/ |
void irq_lin_remove(link_t *lnk) |
{ |
irq_t *irq = hash_table_get_instance(lnk, irq_t, link); |
irq_t *irq __attribute__((unused)) |
= hash_table_get_instance(lnk, irq_t, link); |
spinlock_unlock(&irq->lock); |
} |
/branches/network/kernel/generic/src/console/console.c |
---|
44,7 → 44,6 |
#include <ipc/event.h> |
#include <ipc/irq.h> |
#include <arch.h> |
#include <func.h> |
#include <print.h> |
#include <putchar.h> |
#include <atomic.h> |
70,9 → 69,6 |
/** Number of stored kernel log characters for uspace */ |
static size_t klog_uspace = 0; |
/** Silence output */ |
bool silent = false; |
/** Kernel log spinlock */ |
SPINLOCK_INITIALIZE(klog_lock); |
79,10 → 75,28 |
/** Physical memory area used for klog buffer */ |
static parea_t klog_parea; |
static indev_operations_t stdin_ops = { |
.poll = NULL |
}; |
/** Silence output */ |
bool silent = false; |
/** Standard input and output character devices */ |
indev_t *stdin = NULL; |
outdev_t *stdout = NULL; |
indev_t *stdin_wire(void) |
{ |
if (stdin == NULL) { |
stdin = malloc(sizeof(indev_t), FRAME_ATOMIC); |
if (stdin != NULL) |
indev_initialize("stdin", stdin, &stdin_ops); |
} |
return stdin; |
} |
/** Initialize kernel logging facility |
* |
* The shared area contains kernel cyclic buffer. Userspace application may |
110,8 → 124,14 |
void grab_console(void) |
{ |
bool prev = silent; |
silent = false; |
arch_grab_console(); |
/* Force the console to print the prompt */ |
if ((stdin) && (prev)) |
indev_push_character(stdin, '\n'); |
} |
void release_console(void) |
138,55 → 158,6 |
return true; |
} |
bool check_poll(indev_t *indev) |
{ |
if (indev == NULL) |
return false; |
if (indev->op == NULL) |
return false; |
return (indev->op->poll != NULL); |
} |
/** Get character from input character device. Do not echo character. |
* |
* @param indev Input character device. |
* @return Character read. |
* |
*/ |
wchar_t _getc(indev_t *indev) |
{ |
if (atomic_get(&haltstate)) { |
/* If we are here, we are hopefully on the processor that |
* issued the 'halt' command, so proceed to read the character |
* directly from input |
*/ |
if (check_poll(indev)) |
return indev->op->poll(indev); |
/* No other way of interacting with user */ |
interrupts_disable(); |
if (CPU) |
printf("cpu%u: ", CPU->id); |
else |
printf("cpu: "); |
printf("halted (no polling input)\n"); |
cpu_halt(); |
} |
waitq_sleep(&indev->wq); |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&indev->lock); |
wchar_t ch = indev->buffer[(indev->index - indev->counter) % INDEV_BUFLEN]; |
indev->counter--; |
spinlock_unlock(&indev->lock); |
interrupts_restore(ipl); |
return ch; |
} |
/** Get string from input character device. |
* |
* Read characters from input character device until first occurrence |
206,7 → 177,7 |
buf[offset] = 0; |
wchar_t ch; |
while ((ch = _getc(indev)) != '\n') { |
while ((ch = indev_pop_character(indev)) != '\n') { |
if (ch == '\b') { |
if (count > 0) { |
/* Space, backspace, space */ |
232,7 → 203,7 |
/** Get character from input device & echo it to screen */ |
wchar_t getc(indev_t *indev) |
{ |
wchar_t ch = _getc(indev); |
wchar_t ch = indev_pop_character(indev); |
putchar(ch); |
return ch; |
} |
/branches/network/kernel/generic/src/console/cmd.c |
---|
956,6 → 956,7 |
release_console(); |
event_notify_0(EVENT_KCONSOLE); |
indev_pop_character(stdin); |
return 1; |
} |
/branches/network/kernel/generic/src/console/chardev.c |
---|
35,6 → 35,9 |
#include <console/chardev.h> |
#include <synch/waitq.h> |
#include <synch/spinlock.h> |
#include <print.h> |
#include <func.h> |
#include <arch.h> |
/** Initialize input character device. |
* |
79,6 → 82,46 |
spinlock_unlock(&indev->lock); |
} |
/** Pop character from input character device. |
* |
* @param indev Input character device. |
* |
* @return Character read. |
* |
*/ |
wchar_t indev_pop_character(indev_t *indev) |
{ |
if (atomic_get(&haltstate)) { |
/* If we are here, we are hopefully on the processor that |
* issued the 'halt' command, so proceed to read the character |
* directly from input |
*/ |
if (check_poll(indev)) |
return indev->op->poll(indev); |
/* No other way of interacting with user */ |
interrupts_disable(); |
if (CPU) |
printf("cpu%u: ", CPU->id); |
else |
printf("cpu: "); |
printf("halted (no polling input)\n"); |
cpu_halt(); |
} |
waitq_sleep(&indev->wq); |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&indev->lock); |
wchar_t ch = indev->buffer[(indev->index - indev->counter) % INDEV_BUFLEN]; |
indev->counter--; |
spinlock_unlock(&indev->lock); |
interrupts_restore(ipl); |
return ch; |
} |
/** Initialize output character device. |
* |
* @param outdev Output character device. |
93,5 → 136,16 |
outdev->op = op; |
} |
bool check_poll(indev_t *indev) |
{ |
if (indev == NULL) |
return false; |
if (indev->op == NULL) |
return false; |
return (indev->op->poll != NULL); |
} |
/** @} |
*/ |
/branches/network/kernel/generic/src/console/kconsole.c |
---|
214,7 → 214,7 |
while ((hint = cmdtab_search_one(name, &pos))) { |
if ((found == 0) || (str_length(output) > str_length(hint))) |
str_ncpy(output, hint, MAX_CMDLINE); |
str_cpy(output, MAX_CMDLINE, hint); |
pos = pos->next; |
found++; |
231,7 → 231,7 |
} |
if (found > 0) |
str_ncpy(input, output, size); |
str_cpy(input, size, output); |
return found; |
} |
245,7 → 245,7 |
current[0] = 0; |
while (true) { |
wchar_t ch = _getc(indev); |
wchar_t ch = indev_pop_character(indev); |
if (ch == '\n') { |
/* Enter */ |
302,6 → 302,16 |
if (found == 0) |
continue; |
if (found > 1) { |
/* No unique hint, list was printed */ |
printf("%s> ", prompt); |
printf("%ls", current); |
print_cc('\b', wstr_length(current) - position); |
continue; |
} |
/* We have a hint */ |
size_t off = 0; |
count_t i = 0; |
while ((ch = str_decode(tmp, &off, STR_NO_LIMIT)) != 0) { |
310,26 → 320,17 |
i++; |
} |
if ((str_length(tmp) > 0) || (found == 1)) { |
/* We have a hint */ |
printf("%ls", current + position); |
print_cc('\b', wstr_length(current) - position); |
position += str_length(tmp); |
if ((found == 1) && (position == wstr_length(current))) { |
if (wstr_linsert(current, ' ', position, MAX_CMDLINE)) { |
printf("%ls", current + position); |
position++; |
} |
printf("%ls", current + position); |
position += str_length(tmp); |
print_cc('\b', wstr_length(current) - position); |
if (position == wstr_length(current)) { |
/* Insert a space after the last completed argument */ |
if (wstr_linsert(current, ' ', position, MAX_CMDLINE)) { |
printf("%ls", current + position); |
position++; |
} |
} else { |
/* No unique hint, list was printed */ |
printf("%s> ", prompt); |
printf("%ls", current); |
position += str_length(tmp); |
} |
print_cc('\b', wstr_length(current) - position); |
continue; |
} |
438,7 → 439,7 |
if ((text[0] < '0') || (text[0] > '9')) { |
char symname[MAX_SYMBOL_NAME]; |
str_ncpy(symname, text, min(len + 1, MAX_SYMBOL_NAME)); |
str_ncpy(symname, MAX_SYMBOL_NAME, text, len + 1); |
uintptr_t symaddr; |
int rc = symtab_addr_lookup(symname, &symaddr); |
580,8 → 581,8 |
switch (cmd->argv[i].type) { |
case ARG_TYPE_STRING: |
buf = (char *) cmd->argv[i].buffer; |
str_ncpy(buf, cmdline + start, |
min((end - start) + 1, cmd->argv[i].len)); |
str_ncpy(buf, cmd->argv[i].len, cmdline + start, |
end - start); |
break; |
case ARG_TYPE_INT: |
if (!parse_int_arg(cmdline + start, end - start, |
592,8 → 593,9 |
if ((start < end - 1) && (cmdline[start] == '"')) { |
if (cmdline[end - 1] == '"') { |
buf = (char *) cmd->argv[i].buffer; |
str_ncpy(buf, cmdline + start + 1, |
min((end - start) - 1, cmd->argv[i].len)); |
str_ncpy(buf, cmd->argv[i].len, |
cmdline + start + 1, |
(end - start) - 1); |
cmd->argv[i].intval = (unative_t) buf; |
cmd->argv[i].vartype = ARG_TYPE_STRING; |
} else { |
651,7 → 653,7 |
printf("%s", msg); |
if (kcon) |
_getc(stdin); |
indev_pop_character(stdin); |
else |
printf("Type \"exit\" to leave the console.\n"); |
/branches/network/kernel/generic/src/proc/task.c |
---|
273,8 → 273,8 |
if (rc != 0) |
return (unative_t) rc; |
namebuf[name_len] = 0; |
str_ncpy(TASK->name, namebuf, TASK_NAME_BUFLEN); |
namebuf[name_len] = '\0'; |
str_cpy(TASK->name, TASK_NAME_BUFLEN, namebuf); |
return EOK; |
} |
/branches/network/kernel/generic/src/lib/string.c |
---|
108,6 → 108,7 |
#include <arch.h> |
#include <errno.h> |
#include <align.h> |
#include <debug.h> |
/** Byte mask consisting of lowest @n bits (out of 8) */ |
#define LO_MASK_8(n) ((uint8_t) ((1 << (n)) - 1)) |
528,38 → 529,70 |
} |
/** Copy NULL-terminated string. |
/** Copy string. |
* |
* Copy source string @a src to destination buffer @a dst. |
* No more than @a size bytes are written. NULL-terminator is always |
* written after the last succesfully copied character (i.e. if the |
* destination buffer is has at least 1 byte, it will be always |
* NULL-terminated). |
* Copy source string @a src to destination buffer @a dest. |
* No more than @a size bytes are written. If the size of the output buffer |
* is at least one byte, the output string will always be well-formed, i.e. |
* null-terminated and containing only complete characters. |
* |
* @param dst Destination buffer. |
* @param count Size of the destination buffer (must be > 0). |
* @param src Source string. |
*/ |
void str_cpy(char *dest, size_t size, const char *src) |
{ |
wchar_t ch; |
size_t src_off; |
size_t dest_off; |
/* There must be space for a null terminator in the buffer. */ |
ASSERT(size > 0); |
src_off = 0; |
dest_off = 0; |
while ((ch = str_decode(src, &src_off, STR_NO_LIMIT)) != 0) { |
if (chr_encode(ch, dest, &dest_off, size - 1) != EOK) |
break; |
} |
dest[dest_off] = '\0'; |
} |
/** Copy size-limited substring. |
* |
* Copy prefix of string @a src of max. size @a size to destination buffer |
* @a dest. No more than @a size bytes are written. The output string will |
* always be well-formed, i.e. null-terminated and containing only complete |
* characters. |
* |
* No more than @a n bytes are read from the input string, so it does not |
* have to be null-terminated. |
* |
* @param dst Destination buffer. |
* @param count Size of the destination buffer. |
* |
* @param count Size of the destination buffer (must be > 0). |
* @param src Source string. |
* @param n Maximum number of bytes to read from @a src. |
*/ |
void str_ncpy(char *dst, const char *src, size_t size) |
void str_ncpy(char *dest, size_t size, const char *src, size_t n) |
{ |
/* No space for the NULL-terminator in the buffer */ |
if (size == 0) |
return; |
wchar_t ch; |
size_t str_off = 0; |
size_t dst_off = 0; |
size_t src_off; |
size_t dest_off; |
/* There must be space for a null terminator in the buffer. */ |
ASSERT(size > 0); |
while ((ch = str_decode(src, &str_off, STR_NO_LIMIT)) != 0) { |
if (chr_encode(ch, dst, &dst_off, size) != EOK) |
src_off = 0; |
dest_off = 0; |
while ((ch = str_decode(src, &src_off, n)) != 0) { |
if (chr_encode(ch, dest, &dest_off, size - 1) != EOK) |
break; |
} |
if (dst_off >= size) |
dst[size - 1] = 0; |
else |
dst[dst_off] = 0; |
dest[dest_off] = '\0'; |
} |
/** Copy NULL-terminated wide string to string |
608,10 → 641,12 |
{ |
wchar_t acc; |
size_t off = 0; |
size_t last = 0; |
while ((acc = str_decode(str, &off, STR_NO_LIMIT)) != 0) { |
if (acc == ch) |
return (str + off); |
return (str + last); |
last = off; |
} |
return NULL; |
/branches/network/kernel/generic/src/mm/slab.c |
---|
936,7 → 936,7 |
void *malloc(unsigned int size, int flags) |
{ |
ASSERT(_slab_initialized); |
ASSERT(size && size <= (1 << SLAB_MAX_MALLOC_W)); |
ASSERT(size <= (1 << SLAB_MAX_MALLOC_W)); |
if (size < (1 << SLAB_MIN_MALLOC_W)) |
size = (1 << SLAB_MIN_MALLOC_W); |
/branches/network/kernel/generic/src/ipc/sysipc.c |
---|
332,7 → 332,7 |
src = IPC_GET_ARG1(call->data); |
size = IPC_GET_ARG2(call->data); |
if ((size <= 0) || (size > DATA_XFER_LIMIT)) |
if (size > DATA_XFER_LIMIT) |
return ELIMIT; |
call->buffer = (uint8_t *) malloc(size, 0); |
/branches/network/kernel/generic/src/ipc/irq.c |
---|
130,13 → 130,14 |
/** Register an answerbox as a receiving end for IRQ notifications. |
* |
* @param box Receiving answerbox. |
* @param inr IRQ number. |
* @param devno Device number. |
* @param method Method to be associated with the notification. |
* @param ucode Uspace pointer to top-half pseudocode. |
* @param box Receiving answerbox. |
* @param inr IRQ number. |
* @param devno Device number. |
* @param method Method to be associated with the notification. |
* @param ucode Uspace pointer to top-half pseudocode. |
* |
* @return EBADMEM, ENOENT or EEXISTS on failure or 0 on success. |
* @return EBADMEM, ENOENT or EEXISTS on failure or 0 on success. |
* |
*/ |
int ipc_irq_register(answerbox_t *box, inr_t inr, devno_t devno, |
unative_t method, irq_code_t *ucode) |
149,7 → 150,7 |
(unative_t) inr, |
(unative_t) devno |
}; |
if (ucode) { |
code = code_from_uspace(ucode); |
if (!code) |
157,7 → 158,7 |
} else { |
code = NULL; |
} |
/* |
* Allocate and populate the IRQ structure. |
*/ |
172,7 → 173,7 |
irq->notif_cfg.method = method; |
irq->notif_cfg.code = code; |
irq->notif_cfg.counter = 0; |
/* |
* Enlist the IRQ structure in the uspace IRQ hash table and the |
* answerbox's list. |
181,7 → 182,9 |
spinlock_lock(&irq_uspace_hash_table_lock); |
hlp = hash_table_find(&irq_uspace_hash_table, key); |
if (hlp) { |
irq_t *hirq = hash_table_get_instance(hlp, irq_t, link); |
irq_t *hirq __attribute__((unused)) |
= hash_table_get_instance(hlp, irq_t, link); |
/* hirq is locked */ |
spinlock_unlock(&hirq->lock); |
code_free(code); |
190,7 → 193,8 |
interrupts_restore(ipl); |
return EEXISTS; |
} |
spinlock_lock(&irq->lock); /* not really necessary, but paranoid */ |
spinlock_lock(&irq->lock); /* Not really necessary, but paranoid */ |
spinlock_lock(&box->irq_lock); |
hash_table_insert(&irq_uspace_hash_table, key, &irq->link); |
list_append(&irq->notif_cfg.link, &box->irq_head); |
197,13 → 201,10 |
spinlock_unlock(&box->irq_lock); |
spinlock_unlock(&irq->lock); |
spinlock_unlock(&irq_uspace_hash_table_lock); |
interrupts_restore(ipl); |
// explicitly enable irq |
/* different byteorder? |
* trap_virtual_enable_irqs( 1 << ( irq->inr - 1 )); |
*/ |
trap_virtual_enable_irqs( 1 << ( irq->inr + 7 )); |
trap_virtual_enable_irqs( 1 << irq->inr ); |
return EOK; |
} |