diff options
author | Freya Murphy <freya@freyacat.org> | 2025-04-19 16:36:51 -0400 |
---|---|---|
committer | Freya Murphy <freya@freyacat.org> | 2025-04-19 16:37:54 -0400 |
commit | 472ec944d2ed81d0304cc6cac80946a6a44776be (patch) | |
tree | f6cae641c143a0b45bb289d9d9fc6145706025b0 /kernel/drivers | |
parent | set mmap limit (diff) | |
download | comus-472ec944d2ed81d0304cc6cac80946a6a44776be.tar.gz comus-472ec944d2ed81d0304cc6cac80946a6a44776be.tar.bz2 comus-472ec944d2ed81d0304cc6cac80946a6a44776be.zip |
UEFI and republicans
Diffstat (limited to 'kernel/drivers')
-rw-r--r-- | kernel/drivers/gpu.c | 95 | ||||
-rw-r--r-- | kernel/drivers/gpu/bochs.c | 62 | ||||
-rw-r--r-- | kernel/drivers/gpu/gop.c | 27 | ||||
-rw-r--r-- | kernel/drivers/gpu/vga_text.c (renamed from kernel/drivers/vga.c) | 6 |
4 files changed, 72 insertions, 118 deletions
diff --git a/kernel/drivers/gpu.c b/kernel/drivers/gpu.c index 730fa42..17e7e18 100644 --- a/kernel/drivers/gpu.c +++ b/kernel/drivers/gpu.c @@ -1,91 +1,44 @@ #include <lib.h> #include <comus/drivers/gpu.h> +#include <comus/drivers/gpu/gop.h> #include <comus/drivers/gpu/bochs.h> +#include <comus/drivers/gpu/vga_text.h> #include <comus/error.h> #include <comus/term.h> #include <comus/asm.h> -enum gpu_type { - GPU_UNSET = 0, - GPU_BOCHS = 1, - N_GPU_TYPE, -}; - -static enum gpu_type type = GPU_UNSET; - -static const char *gpu_type_str[N_GPU_TYPE] = { "Unknown", "Bochs" }; - -struct psf2_font { - uint8_t magic[4]; - uint32_t version; - uint32_t header_size; - uint32_t flags; - uint32_t length; - uint32_t glyph_size; - uint32_t height; - uint32_t width; - uint8_t data[]; -}; - -extern struct psf2_font en_font; +struct gpu *gpu_dev = NULL; int gpu_init(void) { - if (bochs_init() == SUCCESS) - type = GPU_BOCHS; - - if (type != GPU_UNSET) { - uint16_t width = gpu_width() / en_font.width; - uint16_t height = gpu_height() / en_font.height; - term_switch_handler(width, height, gpu_draw_char); + // try to get a gpu device + if (!gpu_dev && gop_init(&gpu_dev) == SUCCESS) { } - - return type != GPU_UNSET; -} - -uint32_t gpu_width(void) -{ - switch (type) { - case GPU_BOCHS: - return bochs_width(); - default: - return 0; + if (!gpu_dev && bochs_init(&gpu_dev) == SUCCESS) { } -} -uint32_t gpu_height(void) -{ - switch (type) { - case GPU_BOCHS: - return bochs_height(); - default: - return 0; - } -} + // if we did (yay!) resize terminal + if (gpu_dev) + term_resize(gpu_dev->width, gpu_dev->height); -uint8_t gpu_bit_depth(void) -{ - switch (type) { - case GPU_BOCHS: - return bochs_bit_depth(); - default: - return 0; - } + return gpu_dev != NULL; } void gpu_set_pixel(uint32_t x, uint32_t y, uint32_t r, uint32_t g, uint32_t b) { - switch (type) { - case GPU_BOCHS: - bochs_set_pixel(x, y, r, g, b); - break; - default: - break; - } + // TODO: handle other bpp + volatile uint32_t *fb = (volatile uint32_t *)gpu_dev->framebuffer; + int offset = y * gpu_dev->width + x; + fb[offset] = (b << 0) | (g << 8) | (r << 16); } void gpu_draw_char(char c, uint16_t cx, uint16_t cy) { + if (gpu_dev == NULL) { + vga_text_draw_char(c, cx, cy); + return; + } + uint32_t sx = en_font.width * cx; uint32_t sy = en_font.height * cy; @@ -107,11 +60,11 @@ void gpu_draw_char(char c, uint16_t cx, uint16_t cy) void gpu_report(void) { - if (type == GPU_UNSET) + if (gpu_dev == NULL) return; - kprintf("GPU (%s)\n", gpu_type_str[type]); - kprintf("Width: %d\n", gpu_width()); - kprintf("Height: %d\n", gpu_height()); - kprintf("Bit depth: %d\n\n", gpu_bit_depth()); + kprintf("GPU (%s)\n", gpu_dev->name); + kprintf("Width: %d\n", gpu_dev->width); + kprintf("Height: %d\n", gpu_dev->height); + kprintf("Bit depth: %d\n\n", gpu_dev->bit_depth); } diff --git a/kernel/drivers/gpu/bochs.c b/kernel/drivers/gpu/bochs.c index a100908..3438ab5 100644 --- a/kernel/drivers/gpu/bochs.c +++ b/kernel/drivers/gpu/bochs.c @@ -2,6 +2,7 @@ #include <comus/asm.h> #include <comus/memory.h> #include <comus/drivers/pci.h> +#include <comus/drivers/gpu.h> #include <comus/drivers/gpu/bochs.h> #define INDEX 0x1CE @@ -30,10 +31,7 @@ #define BOCHS_HEIGHT 768 #define BOCHS_BIT_DEPTH 32 -static volatile uint32_t *framebuffer; -static uint16_t width = BOCHS_WIDTH; -static uint16_t height = BOCHS_HEIGHT; -static uint8_t bit_depth = BOCHS_BIT_DEPTH; +struct gpu bochs_dev = { 0 }; static void write(uint16_t index, uint16_t data) { @@ -47,23 +45,7 @@ static uint16_t read(uint16_t value) return inw(DATA); } -static int is_available(void) -{ - return (read(INDEX_ID) == 0xB0C5); -} - -static void set_mode(uint16_t width, uint16_t height, uint16_t bit_depth, - int lfb, int clear) -{ - write(INDEX_ENABLE, DATA_DISP_DISABLE); - write(INDEX_XRES, width); - write(INDEX_YRES, height); - write(INDEX_BPP, bit_depth); - write(INDEX_ENABLE, DATA_DISP_ENABLE | (lfb ? DATA_LFB_ENABLE : 0) | - (clear ? 0 : DATA_NO_CLEAR_MEM)); -} - -int bochs_init(void) +int bochs_init(struct gpu **gpu_dev) { struct pci_device bochs = { 0 }; bool found = @@ -71,34 +53,24 @@ int bochs_init(void) if (!found) return 1; - set_mode(width, height, bit_depth, true, true); - if (!is_available()) + write(INDEX_ENABLE, DATA_DISP_DISABLE); + write(INDEX_XRES, BOCHS_WIDTH); + write(INDEX_YRES, BOCHS_HEIGHT); + write(INDEX_BPP, BOCHS_BIT_DEPTH); + write(INDEX_ENABLE, DATA_DISP_ENABLE | DATA_LFB_ENABLE); + if (read(INDEX_ID) != 0xB0C5) return 1; uint32_t bar0 = pci_rcfg_d(bochs, PCI_BAR0_D); uint32_t *addr = (uint32_t *)(uintptr_t)bar0; - framebuffer = kmapaddr(addr, NULL, width * height * bit_depth, F_WRITEABLE); - return 0; -} + bochs_dev.name = "Bochs"; + bochs_dev.width = BOCHS_WIDTH; + bochs_dev.height = BOCHS_HEIGHT; + bochs_dev.bit_depth = BOCHS_BIT_DEPTH; + bochs_dev.framebuffer = kmapaddr( + addr, NULL, BOCHS_WIDTH * BOCHS_HEIGHT * BOCHS_BIT_DEPTH, F_WRITEABLE); + *gpu_dev = &bochs_dev; -uint32_t bochs_width(void) -{ - return width; -} - -uint32_t bochs_height(void) -{ - return height; -} - -uint8_t bochs_bit_depth(void) -{ - return bit_depth; -} - -void bochs_set_pixel(uint32_t x, uint32_t y, uint32_t r, uint32_t g, uint32_t b) -{ - uint32_t index = x + y * width; - framebuffer[index] = (b << 0) | (g << 8) | (r << 16); + return 0; } diff --git a/kernel/drivers/gpu/gop.c b/kernel/drivers/gpu/gop.c new file mode 100644 index 0000000..47da952 --- /dev/null +++ b/kernel/drivers/gpu/gop.c @@ -0,0 +1,27 @@ +#include <lib.h> +#include <comus/asm.h> +#include <comus/drivers/gpu.h> +#include <comus/drivers/gpu/gop.h> +#include <comus/efi.h> +#include <efi.h> + +struct gpu gop_dev = { 0 }; + +static EFI_GRAPHICS_OUTPUT_PROTOCOL *gop; + +int gop_init(struct gpu **gpu_dev) +{ + gop = efi_get_gop(); + if (gop == NULL || gop->Mode == NULL) + return 1; + + gop_dev.name = "GOP"; + gop_dev.width = gop->Mode->Info->HorizontalResolution; + gop_dev.height = gop->Mode->Info->VerticalResolution; + gop_dev.bit_depth = 32; // we only allow 8bit color in efi/gop.c + gop_dev.framebuffer = kmapaddr((void *)gop->Mode->FrameBufferBase, NULL, + gop->Mode->FrameBufferSize, F_WRITEABLE); + *gpu_dev = &gop_dev; + + return 1; +} diff --git a/kernel/drivers/vga.c b/kernel/drivers/gpu/vga_text.c index d73fa9f..e3359c3 100644 --- a/kernel/drivers/vga.c +++ b/kernel/drivers/gpu/vga_text.c @@ -2,15 +2,17 @@ #include <comus/term.h> #include <comus/asm.h> #include <comus/memory.h> -#include <comus/drivers/vga.h> +#include <comus/drivers/gpu/vga_text.h> #define VGA_ADDR 0xB8000 +#define VGA_WIDTH 80 +#define VGA_HEIGHT 25 static volatile uint16_t *buffer = (uint16_t *)VGA_ADDR; // color static uint8_t fg = 15, bg = 0; -void vga_draw_char(char c, uint16_t x, uint16_t y) +void vga_text_draw_char(char c, uint16_t x, uint16_t y) { // output character const size_t index = y * VGA_WIDTH + x; |