aboutsummaryrefslogtreecommitdiff
path: root/kernel/drivers
diff options
context:
space:
mode:
authorMarvin Borner2021-05-20 22:18:35 +0200
committerMarvin Borner2021-05-20 22:19:20 +0200
commitd8d17375291f89d37cad43df36c11d9c132e23be (patch)
treeed6ba70ac6bd6b4e50dde6e1a0b2d62b7881e721 /kernel/drivers
parent298aaf63f15350e6248d5a96e8c6a63b0ec93e0f (diff)
Added BGA driver and generic FB wrapper
Diffstat (limited to 'kernel/drivers')
-rw-r--r--kernel/drivers/bga.c127
-rw-r--r--kernel/drivers/ide.c6
-rw-r--r--kernel/drivers/rtl8139.c9
-rw-r--r--kernel/drivers/vbe.c34
4 files changed, 148 insertions, 28 deletions
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));
}