86 lines
1.9 KiB
C
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;
|
|
}
|