summaryrefslogtreecommitdiff
path: root/kernel/drivers/vbe.c
diff options
context:
space:
mode:
authorAnton Kling <anton@kling.gg>2023-10-30 22:12:14 +0100
committerAnton Kling <anton@kling.gg>2023-10-31 00:18:38 +0100
commit8a9208612eec8ddae4c418485d848ecfa0613699 (patch)
tree2f4b29200c2f0c19ae52f45bdb9b38a41b356e30 /kernel/drivers/vbe.c
parentca76600acc8bf7a02346efa5bd8f17072210ec01 (diff)
Meta: Move kernel and userland to their own folders.
This is to allow both the kernel and the userland to share certain header files and to make the folder structure a bit more clear.
Diffstat (limited to 'kernel/drivers/vbe.c')
-rw-r--r--kernel/drivers/vbe.c73
1 files changed, 73 insertions, 0 deletions
diff --git a/kernel/drivers/vbe.c b/kernel/drivers/vbe.c
new file mode 100644
index 0000000..c67b7b4
--- /dev/null
+++ b/kernel/drivers/vbe.c
@@ -0,0 +1,73 @@
+#include <assert.h>
+#include <drivers/vbe.h>
+#include <fs/devfs.h>
+#include <fs/vfs.h>
+#include <mmu.h>
+#include <stdio.h>
+
+uint8_t *framebuffer;
+uint32_t framebuffer_physical;
+uint32_t framebuffer_width;
+uint32_t framebuffer_height;
+uint64_t framebuffer_size;
+
+vfs_vm_object_t vbe_vm_object;
+
+#define CHECK_FLAG(flags, bit) ((flags) & (1 << (bit)))
+#define min(_a, _b) (((_a) > (_b)) ? (_b) : (_a))
+
+struct DISPLAY_INFO {
+ uint32_t width;
+ uint32_t height;
+ uint8_t bpp;
+};
+
+struct DISPLAY_INFO vbe_info;
+
+void display_driver_init(multiboot_info_t *mbi) {
+ assert(CHECK_FLAG(mbi->flags, 12));
+ framebuffer_width = mbi->framebuffer_width;
+ framebuffer_height = mbi->framebuffer_height;
+
+ uint32_t bits_pp = mbi->framebuffer_bpp;
+ uint32_t bytes_pp = (bits_pp / 8) + (8 - (bits_pp % 8));
+
+ framebuffer_size = bytes_pp * framebuffer_width * framebuffer_height;
+
+ framebuffer_physical = mbi->framebuffer_addr;
+ framebuffer =
+ mmu_map_frames((void *)(uint32_t)mbi->framebuffer_addr, framebuffer_size);
+
+ vbe_info.width = framebuffer_width;
+ vbe_info.height = framebuffer_height;
+ vbe_info.bpp = mbi->framebuffer_bpp;
+}
+
+vfs_vm_object_t *vbe_get_vm_object(uint64_t length, uint64_t offset,
+ vfs_fd_t *fd) {
+ (void)fd;
+ (void)length;
+ (void)offset;
+ vbe_vm_object.size = framebuffer_size;
+ int n = (uintptr_t)align_page((void *)(uint32_t)framebuffer_size) / 0x1000;
+ vbe_vm_object.object = kmalloc(sizeof(void *) * n);
+ for (int i = 0; i < n; i++) {
+ vbe_vm_object.object[i] = (void *)framebuffer_physical + (i * 0x1000);
+ }
+ return &vbe_vm_object;
+}
+
+int display_info_read(uint8_t *buffer, uint64_t offset, uint64_t len,
+ vfs_fd_t *fd) {
+ (void)offset;
+ int read_len = min(sizeof(struct DISPLAY_INFO), len);
+ memcpy(buffer, &vbe_info, read_len);
+ return read_len;
+}
+
+void add_vbe_device(void) {
+ devfs_add_file("/vbe", NULL, NULL, vbe_get_vm_object, 1, 1,
+ FS_TYPE_BLOCK_DEVICE);
+ devfs_add_file("/display_info", display_info_read, NULL, NULL, 1, 0,
+ FS_TYPE_BLOCK_DEVICE);
+}