From d10c89544cc8141608dd76a1b228aa2031e314f2 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Sun, 11 Jun 2023 09:24:22 +0100 Subject: [PATCH] kexts: fbcon: implement VGA text mode tty driver --- init/main.c | 21 +++++++++++++++------ kexts/drivers/tty/fbcon/main.c | 28 ++++++---------------------- kexts/drivers/tty/fbcon/vgacon.c | 15 +++++++++------ kexts/drivers/video/qemufb/main.c | 24 ++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 34 deletions(-) diff --git a/init/main.c b/init/main.c index ac036ce..be01fe3 100644 --- a/init/main.c +++ b/init/main.c @@ -188,12 +188,6 @@ void kernel_init(uintptr_t arg) printk("kernel_init() running on processor %u", this_cpu()); - create_kernel_thread(background_thread); - - struct object *kbd; - - run_all_tests(); - #ifdef KEXT_NET_DOORSTUCK_SOCKS_FBCON struct object *fb; status = object_get("/dev/video/fb0", &fb); @@ -202,6 +196,21 @@ void kernel_init(uintptr_t arg) } #endif + create_kernel_thread(background_thread); + + struct object *kbd; + + run_all_tests(); + + struct object *tty0; + status = object_get("/dev/tty/tty0", &tty0); + if (status == KERN_OK) { + size_t q; + object_write(tty0, "hello", 5, &q, 0); + } else { + printk("tty: unavailable"); + } + status = object_get("/dev/input/input0", &kbd); if (status != KERN_OK) { printk("no keyboard available"); diff --git a/kexts/drivers/tty/fbcon/main.c b/kexts/drivers/tty/fbcon/main.c index fcdb99b..9646980 100644 --- a/kexts/drivers/tty/fbcon/main.c +++ b/kexts/drivers/tty/fbcon/main.c @@ -6,25 +6,6 @@ #include "fbcon.h" static struct tty_driver *fbcon_driver = NULL; -static struct device *tty0 = NULL; - -static void tty_console_write(struct console *con, const char *s, unsigned int len) -{ - if (!tty0) { - return; - } -} - -static int tty_console_read(struct console *con, char *s, unsigned int len) -{ - return 0; -} - -static struct console tty_console = { - .c_name = "tty0", - .c_write = tty_console_write, - .c_read = tty_console_read, -}; static void tty_clear(struct device *dev, int x, int y, int width, int height) { @@ -72,9 +53,9 @@ static kern_status_t online(struct kext *self) } fbcon_driver->tty_ops = &tty_ops; + fbcon_driver->tty_type = TTY_DRIVER_FULL; tty_driver_register(fbcon_driver); - console_register(&tty_console); return KERN_OK; } @@ -98,8 +79,11 @@ kern_status_t start_console_on_framebuffer(struct device *fb) return status; } - if (!tty0) { - tty0 = tty; + status = tty_device_register(tty, fbcon_driver, misc_device()); + + if (status != KERN_OK) { + /* TODO destroy tty device */ + return status; } return status; diff --git a/kexts/drivers/tty/fbcon/vgacon.c b/kexts/drivers/tty/fbcon/vgacon.c index 105cbf2..0c75cd0 100644 --- a/kexts/drivers/tty/fbcon/vgacon.c +++ b/kexts/drivers/tty/fbcon/vgacon.c @@ -150,7 +150,9 @@ static void vgacon_clear(struct device *dev, int x, int y, int width, int height static void vgacon_putc(struct device *dev, int c, int xpos, int ypos, tty_attrib_t attrib) { - + struct tty_device *ttydev = TTY_DEVICE(dev); + struct fbcon_priv *priv = dev->dev_priv; + priv->fb_cells[(ypos * ttydev->tty_xcells) + xpos] = VGA_CHAR(c, attrib); } static void vgacon_set_cursor(struct device *dev, enum tty_cursor cur) @@ -160,7 +162,7 @@ static void vgacon_set_cursor(struct device *dev, enum tty_cursor cur) static void vgacon_move_cursor(struct device *dev, int x, int y) { - + move_vga_cursor(x, y); } static void vgacon_scroll(struct device *dev, enum tty_scroll_dir dir, int lines) @@ -186,7 +188,7 @@ kern_status_t init_vgacon_console(struct device *tty, struct device *fb) struct framebuffer_fixedinfo fixedinfo; struct tty_device *ttydev = cdev->c_tty; - struct fbcon_priv *priv = kmalloc(sizeof *priv, VM_NORMAL); + struct fbcon_priv *priv = kzalloc(sizeof *priv, VM_NORMAL); if (!priv) { return KERN_NO_MEMORY; } @@ -207,12 +209,13 @@ kern_status_t init_vgacon_console(struct device *tty, struct device *fb) ttydev->tty_xcells = fb_mode.fb_xcells; ttydev->tty_ycells = fb_mode.fb_ycells; - ttydev->tty_xcur = 0; - ttydev->tty_ycur = 0; + ttydev->tty_xcur = g_console_cursor_xpos; + ttydev->tty_ycur = g_console_cursor_ypos; + ttydev->tty_curattrib = DEFAULT_ATTRIB; priv->fbdev = fb; priv->fb_pitch = fb_mode.fb_stride; - priv->fb_pixels = vm_phys_to_virt(fixedinfo.fb_baseptr); + priv->fb_cells = vm_phys_to_virt(fixedinfo.fb_baseptr); priv->tty_ops = &vgacon_ops; tty->dev_priv = priv; diff --git a/kexts/drivers/video/qemufb/main.c b/kexts/drivers/video/qemufb/main.c index f3bc712..3874386 100644 --- a/kexts/drivers/video/qemufb/main.c +++ b/kexts/drivers/video/qemufb/main.c @@ -62,6 +62,30 @@ static kern_status_t qemufb_probe(struct pci_driver *driver, struct device *dev) fb->fb_ops = &qemufb_ops; + uint32_t mmio_base = pci_device_read_field(dev, PCI_REG_BAR2, 4); + uint16_t *mmio = vm_phys_to_virt(mmio_base); + + struct framebuffer_varinfo *varinfo = &fb->fb_varinfo; + struct framebuffer_fixedinfo *fixedinfo = &fb->fb_fixedinfo; + + varinfo->fb_flags = FB_MODE_RGB; + varinfo->fb_xres = mmio[dispi_mmio_offset(VBE_DISPI_INDEX_XRES)]; + varinfo->fb_yres = mmio[dispi_mmio_offset(VBE_DISPI_INDEX_YRES)]; + varinfo->fb_bpp = mmio[dispi_mmio_offset(VBE_DISPI_INDEX_BPP)]; + fixedinfo->fb_baseptr = pci_device_read_field(dev, PCI_REG_BAR0, 4); + + if (!varinfo->fb_xres) { + /* no mode data. assume that we're in VGA text mode */ + varinfo->fb_xres = 640; + varinfo->fb_yres = 400; + varinfo->fb_bpp = 16; + varinfo->fb_flags = FB_MODE_VGATEXT; + varinfo->fb_xcells = 80; + varinfo->fb_ycells = 25; + varinfo->fb_stride = 80 * 25 * 2; + fixedinfo->fb_baseptr = 0xb8000; + } + return device_register(dev, pci_driver_base(qemufb_driver), NULL); }