mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-31 22:48:21 +00:00
proper limine terminal interface
This commit is contained in:
@@ -18,6 +18,8 @@
|
|||||||
#include <arch/smp.h>
|
#include <arch/smp.h>
|
||||||
#include <kernel/timer.h>
|
#include <kernel/timer.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
static volatile struct limine_terminal_request liminettyr = {
|
static volatile struct limine_terminal_request liminettyr = {
|
||||||
.id = LIMINE_TERMINAL_REQUEST,
|
.id = LIMINE_TERMINAL_REQUEST,
|
||||||
.revision = 0
|
.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();
|
bsp_setcls();
|
||||||
|
|
||||||
gdt_init();
|
gdt_init();
|
||||||
@@ -65,7 +64,7 @@ void kmain(){
|
|||||||
|
|
||||||
vmm_init();
|
vmm_init();
|
||||||
|
|
||||||
liminettyctx = arch_getcls()->context;
|
liminetty_setcontext(arch_getcls()->context);
|
||||||
|
|
||||||
alloc_init();
|
alloc_init();
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -64,4 +64,5 @@ bool vmm_setfree(void* addr, size_t pagec);
|
|||||||
bool vmm_allocnowat(void* addr, size_t mmuflags, size_t size);
|
bool vmm_allocnowat(void* addr, size_t mmuflags, size_t size);
|
||||||
void* vmm_allocfrom(void* addr, size_t mmuflags, size_t size);
|
void* vmm_allocfrom(void* addr, size_t mmuflags, size_t size);
|
||||||
vmm_context* vmm_newcontext();
|
vmm_context* vmm_newcontext();
|
||||||
|
void vmm_switchcontext(vmm_context*);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user