HelenOS sources
This source file includes following definitions.
- ski_getchar
- poll_keyboard
- kskipoll
- ski_init
- ski_do_putchar
- ski_putuchar
- skiout_init
- skiin_init
- skiin_wire
#include <arch/drivers/ski.h>
#include <assert.h>
#include <console/console.h>
#include <console/chardev.h>
#include <ddi/ddi.h>
#include <sysinfo/sysinfo.h>
#include <stdint.h>
#include <proc/thread.h>
#include <synch/spinlock.h>
#include <arch/asm.h>
#include <arch/drivers/kbd.h>
#include <str.h>
#include <arch.h>
#include <stdlib.h>
enum {
POLL_INTERVAL = 10000,
POLL_LIMIT = 30,
SKI_INIT_CONSOLE = 20,
SKI_GETCHAR = 21,
SKI_PUTCHAR = 31
};
static void ski_putuchar(outdev_t *, const char32_t);
static outdev_operations_t skidev_ops = {
.write = ski_putuchar,
.redraw = NULL,
.scroll_up = NULL,
.scroll_down = NULL
};
static ski_instance_t *instance = NULL;
static parea_t ski_parea;
static char32_t ski_getchar(void)
{
uint64_t ch;
asm volatile (
"mov r15 = %1\n"
"break 0x80000;;\n"
"mov %0 = r8;;\n"
: "=r" (ch)
: "i" (SKI_GETCHAR)
: "r15", "r8"
);
return (char32_t) ch;
}
static void poll_keyboard(ski_instance_t *instance)
{
int count = POLL_LIMIT;
if (ski_parea.mapped && !console_override)
return;
while (count > 0) {
char32_t ch = ski_getchar();
if (ch == '\0')
break;
indev_push_character(instance->srlnin, ch);
--count;
}
}
static void kskipoll(void *arg)
{
ski_instance_t *instance = (ski_instance_t *) arg;
while (true) {
poll_keyboard(instance);
thread_usleep(POLL_INTERVAL);
}
}
static void ski_init(void)
{
uintptr_t faddr;
if (instance)
return;
asm volatile (
"mov r15 = %0\n"
"break 0x80000\n"
:
: "i" (SKI_INIT_CONSOLE)
: "r15", "r8"
);
faddr = frame_alloc(1, FRAME_LOWMEM | FRAME_ATOMIC, 0);
if (faddr == 0)
panic("Cannot allocate page for ski console.");
ddi_parea_init(&ski_parea);
ski_parea.pbase = faddr;
ski_parea.frames = 1;
ski_parea.unpriv = false;
ski_parea.mapped = false;
ddi_parea_register(&ski_parea);
sysinfo_set_item_val("ski.paddr", NULL, (sysarg_t) faddr);
instance = malloc(sizeof(ski_instance_t));
if (instance) {
instance->thread = thread_create(kskipoll, instance, TASK,
THREAD_FLAG_UNCOUNTED, "kskipoll");
if (!instance->thread) {
free(instance);
instance = NULL;
return;
}
instance->srlnin = NULL;
}
}
static void ski_do_putchar(char ch)
{
asm volatile (
"mov r15 = %[cmd]\n"
"mov r32 = %[ch]\n"
"break 0x80000\n"
:
: [cmd] "i" (SKI_PUTCHAR), [ch] "r" (ch)
: "r15", "in0", "r8"
);
}
static void ski_putuchar(outdev_t *dev, char32_t ch)
{
if (ski_parea.mapped && !console_override)
return;
if (ascii_check(ch)) {
if (ch == '\n')
ski_do_putchar('\r');
ski_do_putchar(ch);
} else {
ski_do_putchar('?');
}
}
outdev_t *skiout_init(void)
{
ski_init();
if (!instance)
return NULL;
outdev_t *skidev = malloc(sizeof(outdev_t));
if (!skidev)
return NULL;
outdev_initialize("skidev", skidev, &skidev_ops);
skidev->data = instance;
if (!fb_exported) {
sysinfo_set_item_val("fb", NULL, true);
sysinfo_set_item_val("fb.kind", NULL, 6);
fb_exported = true;
}
return skidev;
}
ski_instance_t *skiin_init(void)
{
ski_init();
return instance;
}
void skiin_wire(ski_instance_t *instance, indev_t *srlnin)
{
assert(instance);
assert(srlnin);
instance->srlnin = srlnin;
thread_start(instance->thread);
sysinfo_set_item_val("kbd", NULL, true);
sysinfo_set_item_val("kbd.type", NULL, KBD_SKI);
}
HelenOS homepage, sources at GitHub