Files
kernel/sys/tty.c
T

86 lines
1.9 KiB
C

#include "sys/tty.h"
#include "sys/chr.h"
#include "sys/errno.h"
#include "sys/debug.h"
#include "sys/panic.h"
#include "sys/string.h"
#include "sys/ring.h"
#include "sys/mm.h"
#include "sys/amd64/cpu.h"
#include "sys/amd64/hw/con.h"
#include "sys/dev.h"
#define DEV_TTY(n) (n ## ULL)
#define DEV_DATA_TTY(n) ((void *) n ## ULL)
#define DEV_DATA_GETTTY(d) ((uint64_t) (d)->dev_data)
static ssize_t tty_write(struct chrdev *tty, const void *buf, size_t pos, size_t lim);
static ssize_t tty_read(struct chrdev *tty, void *buf, size_t pos, size_t lim);
static struct chrdev _dev_tty0 = {
.dev_data = DEV_DATA_TTY(0),
.write = tty_write,
.read = tty_read
};
static struct dev_entry _ent_tty0 = {
.dev = &_dev_tty0,
.dev_class = DEV_CLASS_CHAR,
.dev_subclass = DEV_CHAR_TTY,
.dev_name = "tty0"
};
static struct ring tty_ring = {0};
// This function receives keystrokes from keyboard drivers
void tty_buffer_write(int tty_no, char c) {
ring_putc(&tty_ring, c);
}
void tty_init(void) {
ring_init(&tty_ring, 16);
dev_entry_add(&_ent_tty0);
}
// TODO: multiple ttys
static ssize_t tty_write(struct chrdev *tty, const void *buf, size_t pos, size_t lim) {
uint64_t tty_no = DEV_DATA_GETTTY(tty);
if (tty_no != DEV_TTY(0)) {
return -EINVAL;
}
// TODO: buffer sanity checks
for (size_t i = 0; i < lim; ++i) {
amd64_con_putc(((const char *) buf)[i]);
}
return lim;
}
static ssize_t tty_read(struct chrdev *tty, void *buf, size_t pos, size_t lim) {
uint64_t tty_no = DEV_DATA_GETTTY(tty);
char ibuf[16];
if (tty_no != DEV_TTY(0)) {
return -EINVAL;
}
if (lim == 0) {
return 0;
}
size_t rem = lim;
size_t p = 0;
while (rem) {
ssize_t rd = ring_read(get_cpu()->thread, &tty_ring, ibuf, MIN(16, rem));
if (rd < 0) {
break;
}
memcpy((char *) buf + p, ibuf, rd);
rem -= rd;
}
return p;
}