From 177928d49aa4ad028739017fecbe1f537af86735 Mon Sep 17 00:00:00 2001 From: Matheus Date: Sat, 24 Sep 2022 14:55:06 -0300 Subject: [PATCH] framebuffer: initial implementation --- src/arch/x86_64/main.c | 2 + src/video/framebuffer.c | 91 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 src/video/framebuffer.c diff --git a/src/arch/x86_64/main.c b/src/arch/x86_64/main.c index 0ab4c114..bc0848d1 100644 --- a/src/arch/x86_64/main.c +++ b/src/arch/x86_64/main.c @@ -64,6 +64,8 @@ void kmain(){ consoledev_init(); pseudodevs_init(); + + fb_init(); pci_enumerate(); diff --git a/src/video/framebuffer.c b/src/video/framebuffer.c new file mode 100644 index 00000000..2ba8b753 --- /dev/null +++ b/src/video/framebuffer.c @@ -0,0 +1,91 @@ +#include +#include +#include +#include + +static volatile struct limine_framebuffer_request fbreq = { + .id = LIMINE_FRAMEBUFFER_REQUEST, + .revision = 0 +}; + +static struct limine_framebuffer** fbs; +static size_t fbcount; + +static int devchecks(int fb, size_t* count, size_t offset){ + + if(fb >= fbcount) + return ENODEV; + + size_t end = fbs[fb]->pitch * fbs[fb]->height; + + if(*count + offset > end) + *count = end - offset; + + return 0; + + +} + +int read(int* error, int minor, void* buff, size_t count, size_t offset){ + + *error = devchecks(minor, &count, offset); + + if(*error) + return -1; + + memcpy(buff, fbs[minor]->address + offset, count); + + return count; + +} + +int write(int* error, int minor, void* buff, size_t count, size_t offset){ + + *error = devchecks(minor, &count, offset); + + if(*error) + return -1; + + memcpy(fbs[minor]->address + offset, buff, count); + + return count; +} + +int isatty(int minor){ + return ENOTTY; +} + +static int isseekable(int minor, size_t* max){ + + if(minor >= fbcount) + return ENODEV; + + *max = fbs[minor]->pitch * fbs[minor]->height; + + return 0; +} + + +static devcalls calls = { + read, write, isatty, isseekable +}; + +void fb_init(){ + + if(!fbreq.response) + return; + + fbcount = fbreq.response->framebuffer_count; + fbs = fbreq.response->framebuffers; + + char name[] = { 'f', 'b', '0', 0}; + + for(uintmax_t fb = 0; fb < fbcount; ++fb){ + + devman_newdevice(name, TYPE_CHARDEV, MAJOR_FB, fb, &calls); + + ++name[2]; // increase the fbX num + + } + +}