diff options
author | Marvin Borner | 2021-05-20 22:18:35 +0200 |
---|---|---|
committer | Marvin Borner | 2021-05-20 22:19:20 +0200 |
commit | d8d17375291f89d37cad43df36c11d9c132e23be (patch) | |
tree | ed6ba70ac6bd6b4e50dde6e1a0b2d62b7881e721 | |
parent | 298aaf63f15350e6248d5a96e8c6a63b0ec93e0f (diff) |
Added BGA driver and generic FB wrapper
-rw-r--r-- | apps/wm/main.c | 4 | ||||
-rw-r--r-- | kernel/Makefile | 2 | ||||
-rw-r--r-- | kernel/drivers/bga.c | 127 | ||||
-rw-r--r-- | kernel/drivers/ide.c | 6 | ||||
-rw-r--r-- | kernel/drivers/rtl8139.c | 9 | ||||
-rw-r--r-- | kernel/drivers/vbe.c | 34 | ||||
-rw-r--r-- | kernel/features/fb.c | 32 | ||||
-rw-r--r-- | kernel/features/io.c | 11 | ||||
-rw-r--r-- | kernel/features/mm.c | 4 | ||||
-rw-r--r-- | kernel/inc/drivers/bga.h | 11 | ||||
-rw-r--r-- | kernel/inc/fb.h | 14 | ||||
-rw-r--r-- | libs/libc/inc/sys.h | 8 | ||||
-rw-r--r-- | libs/libgui/gfx.c | 1 | ||||
-rw-r--r-- | libs/libgui/gfx.h | 1 | ||||
-rw-r--r-- | libs/libgui/vesa.h | 46 |
15 files changed, 222 insertions, 88 deletions
diff --git a/apps/wm/main.c b/apps/wm/main.c index 83dc20b..0d00427 100644 --- a/apps/wm/main.c +++ b/apps/wm/main.c @@ -8,10 +8,10 @@ #include <libgui/gfx.h> #include <libgui/gui.h> #include <libgui/msg.h> -#include <libgui/vesa.h> #include <libtxt/keymap.h> #include <list.h> #include <rand.h> +#include <sys.h> #define WINDOW_MOVE_TIMEOUT 20 @@ -37,7 +37,7 @@ struct rectangle { // Global vars ftw! static u8 bypp = 4; -static struct vbe screen = { 0 }; +static struct fb_generic screen = { 0 }; static struct list *windows = NULL; // THIS LIST SHALL BE SORTED BY Z-INDEX! static struct window *direct = NULL; static struct window *wallpaper = NULL; diff --git a/kernel/Makefile b/kernel/Makefile index 853f03f..263f08b 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -13,6 +13,7 @@ COBJS = entry_asm.o \ drivers/mbr.o \ drivers/ide.o \ drivers/vbe.o \ + drivers/bga.o \ drivers/timer.o \ drivers/vmware.o \ drivers/ps2/ps2.o \ @@ -22,6 +23,7 @@ COBJS = entry_asm.o \ features/fs.o \ features/io.o \ features/bus.o \ + features/fb.o \ features/logger.o \ features/load.o \ features/proc.o \ diff --git a/kernel/drivers/bga.c b/kernel/drivers/bga.c new file mode 100644 index 0000000..2f3b1fa --- /dev/null +++ b/kernel/drivers/bga.c @@ -0,0 +1,127 @@ +// MIT License, Copyright (c) 2021 Marvin Borner + +#include <assert.h> +#include <def.h> +#include <drivers/bga.h> +#include <drivers/cpu.h> +#include <drivers/pci.h> +#include <fb.h> +#include <io.h> +#include <mem.h> +#include <mm.h> + +#define BGA_ADDRESS 0x01ce +#define BGA_DATA 0x01cf + +#define BGA_VERSION 0 +#define BGA_XRES 1 +#define BGA_YRES 2 +#define BGA_BPP 3 +#define BGA_ENABLE 4 +#define BGA_BANK 5 +#define BGA_VWIDTH 6 +#define BGA_VHEIGHT 7 +#define BGA_XOFF 8 +#define BGA_YOFF 9 + +#define BGA_LINEAR_FB 0x40 + +#define BGA_V0 0xb0c0 +#define BGA_V1 0xb0c1 +#define BGA_V2 0xb0c2 +#define BGA_V3 0xb0c3 +#define BGA_V4 0xb0c4 +#define BGA_V5 0xb0c5 + +PROTECTED static u32 bga_device_pci = 0; +PROTECTED static struct fb_generic generic = { 0 }; + +CLEAR static void bga_find(u32 device, u16 vendor_id, u16 device_id, void *extra) +{ + if ((vendor_id == 0x1234) && (device_id == 0x1111)) + *((u32 *)extra) = device; +} + +static void bga_write_reg(u16 address, u16 data) +{ + outw(BGA_ADDRESS, address); + outw(BGA_DATA, data); +} + +static u16 bga_read_reg(u16 index) +{ + outw(BGA_ADDRESS, index); + return inw(BGA_DATA); +} + +CLEAR u8 bga_available(void) +{ + pci_scan(&bga_find, -1, &bga_device_pci); + u16 status = bga_read_reg(BGA_VERSION); + return bga_device_pci != 0 && status >= BGA_V0 && status <= BGA_V5; +} + +CLEAR static u32 bga_fb_base(void) +{ + u32 bar0 = pci_read_field(bga_device_pci, PCI_BAR0, 4); + assert(!(bar0 & 7)); // MMIO32 + return bar0 & 0xfffffff0; +} + +// TODO: BGA resolution using control calls +static u32 fb_owner = 0; +static res bga_control(u32 request, void *arg1, void *arg2, void *arg3) +{ + UNUSED(arg3); + + switch (request) { + case IOCTL_FB_GET: { + if (!generic.fb) + return -ENOENT; + + u32 size = MIN(sizeof(generic), (u32)arg2); + if (!memory_writable_range(memory_range(arg1, size))) + return -EFAULT; + + if (fb_owner != 0 && proc_from_pid(fb_owner)) + return -EBUSY; + fb_owner = proc_current()->pid; + + u32 fb = fb_map_buffer(proc_current()->page_dir, &generic); + + stac(); + memcpy(arg1, &generic, size); + ((struct fb_generic *)arg1)->fb = (u8 *)fb; + clac(); + + return EOK; + } + default: + return -EINVAL; + } +} + +CLEAR static void bga_enable(u16 width, u16 height, u16 depth) +{ + bga_write_reg(BGA_ENABLE, 0); + bga_write_reg(BGA_XRES, width); + bga_write_reg(BGA_YRES, height); + bga_write_reg(BGA_BPP, depth); + bga_write_reg(BGA_ENABLE, 1 | BGA_LINEAR_FB); + + generic.pitch = width * (depth >> 3); + generic.bpp = depth; + generic.width = width; + generic.height = height; + generic.fb = (u8 *)bga_fb_base(); + fb_protect(&generic); +} + +CLEAR void bga_install(void) +{ + bga_enable(1920, 1200, 32); + + struct io_dev *dev = zalloc(sizeof(*dev)); + dev->control = bga_control; + io_add(IO_FRAMEBUFFER, dev); +} diff --git a/kernel/drivers/ide.c b/kernel/drivers/ide.c index 9e09860..324b453 100644 --- a/kernel/drivers/ide.c +++ b/kernel/drivers/ide.c @@ -1,13 +1,13 @@ // MIT License, Copyright (c) 2020 Marvin Borner #include <assert.h> -#include <drivers/cpu.h> #include <def.h> -#include <fs.h> +#include <drivers/cpu.h> #include <drivers/ide.h> #include <drivers/mbr.h> -#include <mem.h> #include <drivers/pci.h> +#include <fs.h> +#include <mem.h> #include <print.h> #include <str.h> diff --git a/kernel/drivers/rtl8139.c b/kernel/drivers/rtl8139.c index fdbc0c8..8e7bc88 100644 --- a/kernel/drivers/rtl8139.c +++ b/kernel/drivers/rtl8139.c @@ -2,14 +2,14 @@ // Uses parts of the ToAruOS Project, released under the terms of the NCSA // Copyright (C) 2011-2018 K. Lange -#include <drivers/cpu.h> #include <def.h> +#include <drivers/cpu.h> #include <drivers/interrupts.h> +#include <drivers/pci.h> +#include <drivers/rtl8139.h> #include <mem.h> #include <net.h> -#include <drivers/pci.h> #include <print.h> -#include <drivers/rtl8139.h> static int rtl_irq = 0; static u8 mac[6] = { 0 }; @@ -77,9 +77,8 @@ void rtl8139_send_packet(void *data, u32 len) static void rtl8139_find(u32 device, u16 vendor_id, u16 device_id, void *extra) { - if ((vendor_id == 0x10ec) && (device_id == 0x8139)) { + if ((vendor_id == 0x10ec) && (device_id == 0x8139)) *((u32 *)extra) = device; - } } static void rtl8139_irq_handler(struct regs *r) diff --git a/kernel/drivers/vbe.c b/kernel/drivers/vbe.c index b384936..fd91062 100644 --- a/kernel/drivers/vbe.c +++ b/kernel/drivers/vbe.c @@ -5,6 +5,7 @@ #include <drivers/cpu.h> #include <drivers/vbe.h> #include <errno.h> +#include <fb.h> #include <io.h> #include <mem.h> #include <mm.h> @@ -12,8 +13,6 @@ #include <str.h> #include <sys.h> -#define FB_SIZE (vbe->height * vbe->pitch) - struct vbe_basic { u8 stuff1[16]; u16 pitch; @@ -24,15 +23,7 @@ struct vbe_basic { u8 stuff3[212]; }; -PROTECTED static struct vbe_basic *vbe = NULL; - -static u32 vbe_map_buffer(struct page_dir *dir) -{ - assert(vbe); - struct memory_range r = - virtual_alloc(dir, memory_range_around((u32)vbe->fb, FB_SIZE), MEMORY_USER); - return r.base; -} +PROTECTED static struct fb_generic generic = { 0 }; static u32 fb_owner = 0; static res vbe_control(u32 request, void *arg1, void *arg2, void *arg3) @@ -41,10 +32,10 @@ static res vbe_control(u32 request, void *arg1, void *arg2, void *arg3) switch (request) { case IOCTL_FB_GET: { - if (!vbe) + if (!generic.fb) return -ENOENT; - u32 size = MIN(sizeof(*vbe), (u32)arg2); + u32 size = MIN(sizeof(generic), (u32)arg2); if (!memory_writable_range(memory_range(arg1, size))) return -EFAULT; @@ -52,11 +43,11 @@ static res vbe_control(u32 request, void *arg1, void *arg2, void *arg3) return -EBUSY; fb_owner = proc_current()->pid; - u32 fb = vbe_map_buffer(proc_current()->page_dir); + u32 fb = fb_map_buffer(proc_current()->page_dir, &generic); stac(); - memcpy(arg1, vbe, size); - ((struct vbe_basic *)arg1)->fb = (u8 *)fb; + memcpy(arg1, &generic, size); + ((struct fb_generic *)arg1)->fb = (u8 *)fb; clac(); return EOK; @@ -68,12 +59,15 @@ static res vbe_control(u32 request, void *arg1, void *arg2, void *arg3) CLEAR void vbe_install(u32 data) { - vbe = (void *)data; + struct vbe_basic *vbe = (void *)data; + generic.bpp = (vbe->pitch / vbe->width) << 3; + generic.pitch = vbe->pitch; + generic.width = vbe->width; + generic.height = vbe->height; + generic.fb = vbe->fb; + fb_protect(&generic); struct io_dev *dev = zalloc(sizeof(*dev)); dev->control = vbe_control; io_add(IO_FRAMEBUFFER, dev); - - // Set framebuffer range used to prevent unwanted writing - physical_set_used(memory_range_around((u32)vbe->fb, FB_SIZE)); } diff --git a/kernel/features/fb.c b/kernel/features/fb.c new file mode 100644 index 0000000..08d99df --- /dev/null +++ b/kernel/features/fb.c @@ -0,0 +1,32 @@ +// MIT License, Copyright (c) 2021 Marvin Borner + +#include <def.h> +#include <drivers/bga.h> +#include <drivers/vbe.h> +#include <fb.h> +#include <multiboot.h> +#include <print.h> + +#define FB_SIZE (generic->height * generic->pitch) + +u32 fb_map_buffer(struct page_dir *dir, struct fb_generic *generic) +{ + struct memory_range r = + virtual_alloc(dir, memory_range_around((u32)generic->fb, FB_SIZE), MEMORY_USER); + return r.base; +} + +CLEAR void fb_protect(struct fb_generic *generic) +{ + physical_set_used(memory_range_around((u32)generic->fb, FB_SIZE)); +} + +CLEAR void fb_install(void) +{ + if (bga_available()) + bga_install(); + else if (multiboot_vbe()) + vbe_install(multiboot_vbe()); + else + panic("No framebuffer driver found!\n"); +} diff --git a/kernel/features/io.c b/kernel/features/io.c index 4bbc4e0..28388ae 100644 --- a/kernel/features/io.c +++ b/kernel/features/io.c @@ -3,12 +3,14 @@ #include <assert.h> #include <bus.h> #include <def.h> +#include <drivers/bga.h> #include <drivers/cpu.h> #include <drivers/interrupts.h> #include <drivers/ps2.h> #include <drivers/timer.h> #include <drivers/vbe.h> #include <drivers/vmware.h> +#include <fb.h> #include <io.h> #include <list.h> #include <logger.h> @@ -232,17 +234,10 @@ CLEAR void io_install(void) } /** - * Framebuffer detection - */ - - u32 vbe = multiboot_vbe(); - if (vbe) - vbe_install(vbe); - - /** * Other devices */ + fb_install(); timer_install(); logger_install(); bus_install(); diff --git a/kernel/features/mm.c b/kernel/features/mm.c index 81645af..227ba0a 100644 --- a/kernel/features/mm.c +++ b/kernel/features/mm.c @@ -2,10 +2,10 @@ // MIT License, Copyright (c) 2021 Marvin Borner #include <assert.h> -#include <drivers/cpu.h> #include <def.h> -#include <errno.h> +#include <drivers/cpu.h> #include <drivers/vbe.h> +#include <errno.h> #include <mem.h> #include <mm.h> #include <multiboot.h> diff --git a/kernel/inc/drivers/bga.h b/kernel/inc/drivers/bga.h new file mode 100644 index 0000000..53c153c --- /dev/null +++ b/kernel/inc/drivers/bga.h @@ -0,0 +1,11 @@ +// MIT License, Copyright (c) 2021 Marvin Borner + +#ifndef BGA_H +#define BGA_H + +#include <def.h> + +u8 bga_available(void); +void bga_install(void); + +#endif diff --git a/kernel/inc/fb.h b/kernel/inc/fb.h new file mode 100644 index 0000000..0f94b28 --- /dev/null +++ b/kernel/inc/fb.h @@ -0,0 +1,14 @@ +// MIT License, Copyright (c) 2021 Marvin Borner + +#ifndef FB_H +#define FB_H + +#include <def.h> +#include <mm.h> +#include <sys.h> + +u32 fb_map_buffer(struct page_dir *dir, struct fb_generic *generic); +void fb_protect(struct fb_generic *generic); +void fb_install(void); + +#endif diff --git a/libs/libc/inc/sys.h b/libs/libc/inc/sys.h index 7d81f33..14d9698 100644 --- a/libs/libc/inc/sys.h +++ b/libs/libc/inc/sys.h @@ -52,6 +52,14 @@ enum io_type { #define IOCTL_BUS_CONNECT_CONN 1 #define IOCTL_BUS_REGISTER 2 +struct fb_generic { + u16 bpp; + u16 pitch; + u16 width; + u16 height; + u8 *fb; +}; + struct bus_header { u32 conn; // Data starts here diff --git a/libs/libgui/gfx.c b/libs/libgui/gfx.c index e68c2ad..3ed8375 100644 --- a/libs/libgui/gfx.c +++ b/libs/libgui/gfx.c @@ -10,7 +10,6 @@ #include <libgui/msg.h> #include <libgui/png.h> #include <libgui/psf.h> -#include <libgui/vesa.h> #include <list.h> #include <mem.h> #include <str.h> diff --git a/libs/libgui/gfx.h b/libs/libgui/gfx.h index d0d0e1e..1dfa96d 100644 --- a/libs/libgui/gfx.h +++ b/libs/libgui/gfx.h @@ -5,7 +5,6 @@ #define GFX_H #include <def.h> -#include <libgui/vesa.h> #include <sys.h> #include <vec.h> diff --git a/libs/libgui/vesa.h b/libs/libgui/vesa.h deleted file mode 100644 index 892bd89..0000000 --- a/libs/libgui/vesa.h +++ /dev/null @@ -1,46 +0,0 @@ -// MIT License, Copyright (c) 2020 Marvin Borner - -#ifndef VBE_H -#define VBE_H - -#include <def.h> - -struct vbe { - u16 attributes; - u8 window_a; - u8 window_b; - u16 granularity; - u16 window_size; - u16 segment_a; - u16 segment_b; - u32 win_func_ptr; - u16 pitch; - u16 width; - u16 height; - u8 w_char; - u8 y_char; - u8 planes; - u8 bpp; - u8 banks; - u8 memory_model; - u8 bank_size; - u8 image_pages; - u8 reserved0; - - u8 red_mask; - u8 red_position; - u8 green_mask; - u8 green_position; - u8 blue_mask; - u8 blue_position; - u8 reserved_mask; - u8 reserved_position; - u8 direct_color_attributes; - - u8 *fb; - u32 off_screen_mem_off; - u16 off_screen_mem_size; - u8 reserved1[206]; -}; - -#endif |