proper limine terminal interface

This commit is contained in:
Matheus
2022-08-20 14:16:26 -03:00
parent df9977b7db
commit f7e5b5ba67
4 changed files with 155 additions and 9 deletions
+8 -9
View File
@@ -18,6 +18,8 @@
#include <arch/smp.h>
#include <kernel/timer.h>
/*
static volatile struct limine_terminal_request liminettyr = {
.id = LIMINE_TERMINAL_REQUEST,
.revision = 0
@@ -43,15 +45,12 @@ void liminewrite(char* str, size_t c){
}
void kmain(){
if(!liminettyr.response)
return;
*/
void kmain(){
liminetty_init();
liminetty = liminettyr.response;
liminetty->write += 0xFFFF800000000000;
console_setwritehook(liminewrite);
bsp_setcls();
gdt_init();
@@ -65,7 +64,7 @@ void kmain(){
vmm_init();
liminettyctx = arch_getcls()->context;
liminetty_setcontext(arch_getcls()->context);
alloc_init();
+16
View File
@@ -0,0 +1,16 @@
#ifndef _LIMINETTY_H_INCLUDE
#define _LIMINETTY_H_INCLUDE
#include <limine.h>
#include <kernel/vmm.h>
void liminetty_write(int tty, const char* str, size_t len);
struct limine_framebuffer* liminetty_getfb(int tty);
void liminetty_setcallback(int tty, limine_terminal_callback callback);
struct limine_terminal* liminetty_get(int tty);
size_t liminetty_ttycount();
void liminetty_setcontext(vmm_context* ctx);
void liminetty_writeuser(const char* str, size_t len);
void liminetty_writekernel(const char* str, size_t len);
#endif
+1
View File
@@ -64,4 +64,5 @@ bool vmm_setfree(void* addr, size_t pagec);
bool vmm_allocnowat(void* addr, size_t mmuflags, size_t size);
void* vmm_allocfrom(void* addr, size_t mmuflags, size_t size);
vmm_context* vmm_newcontext();
void vmm_switchcontext(vmm_context*);
#endif
+130
View File
@@ -0,0 +1,130 @@
#include <kernel/liminetty.h>
#include <arch/spinlock.h>
#include <kernel/console.h>
#include <arch/cls.h>
#include <kernel/alloc.h>
#include <arch/panic.h>
static struct limine_terminal** ttys;
static size_t ttycount;
static int usertty; // accessed by /dev/console
static int kerneltty; // libc and kernel logs
static limine_terminal_write writetty;
static bool shared = false;
static int lock; // for shared access between user and kernel
static vmm_context* liminectx = NULL;
static limine_terminal_callback* callbacks = NULL;
static void callbackhandler(struct limine_terminal *terminal, uint64_t type, uint64_t arg1, uint64_t arg2, uint64_t arg3){
uintmax_t tty = 0;
for(;tty < ttycount; ++tty){
if(ttys[tty] == terminal)
break;
}
if(callbacks == NULL || tty == ttycount || callbacks[tty] == NULL);
return;
callbacks[tty](terminal, type, arg1, arg2, arg3);
}
static volatile struct limine_terminal_request req = {
.id = LIMINE_TERMINAL_REQUEST,
.revision = 0,
.callback = callbackhandler
};
void liminetty_setcontext(vmm_context* ctx){
liminectx = ctx;
}
void liminetty_setcallback(int tty, limine_terminal_callback callback){
if(!callbacks){ // allocate space for the callbacks
callbacks = alloc(sizeof(limine_terminal_callback)*ttycount);
if(!callbacks)
_panic("Failed to allocate callbacks", 0);
}
if(tty >= ttycount)
return;
callbacks[tty] = callback;
}
struct limine_terminal* liminetty_get(int tty){
if(tty >= ttycount)
return NULL;
return ttys[tty];
}
size_t liminetty_ttycount(){
return ttycount;
}
void liminetty_write(int tty, const char* str, size_t len){
if(tty >= ttycount) return;
vmm_context* old = arch_getcls()->context;
if(liminectx)
vmm_switchcontext(liminectx);
writetty(ttys[usertty], str, len);
if(liminectx)
vmm_switchcontext(old);
}
struct limine_framebuffer* liminetty_getfb(int tty){
if(tty >= ttycount) return NULL;
return ttys[tty]->framebuffer;
}
void liminetty_writeuser(const char* str, size_t len){
if(shared)
spinlock_acquire(&lock);
liminetty_write(usertty, str, len);
if(shared)
spinlock_release(&lock);
}
void liminetty_writekernel(const char* str, size_t len){
if(shared)
spinlock_acquire(&lock);
liminetty_write(kerneltty, str, len);
if(shared)
spinlock_release(&lock);
}
void liminetty_init(){
if(!req.response)
for(;;); // not a lot that can be done I guess
struct limine_terminal_response* r = req.response;
ttys = r->terminals;
ttycount = r->terminal_count;
usertty = 0;
shared = ttycount == 1;
kerneltty = shared ? 0 : 1;
writetty = r->write;
console_setwritehook(liminetty_writekernel);
}