summaryrefslogtreecommitdiff
path: root/kernel/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/drivers')
-rw-r--r--kernel/drivers/gpu.c95
-rw-r--r--kernel/drivers/gpu/bochs.c62
-rw-r--r--kernel/drivers/gpu/gop.c27
-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;