[SeaBIOS] [PATCH 2/2] vgabios: Initial support for coreboot native vga vgabios.

Kevin O'Connor kevin at koconnor.net
Mon Apr 7 01:02:04 CEST 2014


Signed-off-by: Kevin O'Connor <kevin at koconnor.net>
---
 Makefile         |   3 +-
 vgasrc/Kconfig   |  10 ++-
 vgasrc/cbvga.c   | 189 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 vgasrc/cbvga.h   |  20 ++++++
 vgasrc/vgabios.h |   2 +
 vgasrc/vgafb.c   |   4 +-
 vgasrc/vgahw.h   |  27 ++++++++
 7 files changed, 251 insertions(+), 4 deletions(-)
 create mode 100644 vgasrc/cbvga.c
 create mode 100644 vgasrc/cbvga.h

diff --git a/Makefile b/Makefile
index 488bd04..e567ba1 100644
--- a/Makefile
+++ b/Makefile
@@ -204,7 +204,8 @@ SRCVGA=src/output.c src/string.c src/hw/pci.c src/hw/serialio.c \
     vgasrc/vgainit.c vgasrc/vgabios.c vgasrc/vgafb.c \
     vgasrc/vgafonts.c vgasrc/vbe.c \
     vgasrc/stdvga.c vgasrc/stdvgamodes.c vgasrc/stdvgaio.c \
-    vgasrc/clext.c vgasrc/bochsvga.c vgasrc/geodevga.c
+    vgasrc/clext.c vgasrc/bochsvga.c vgasrc/geodevga.c \
+    src/fw/coreboot.c vgasrc/cbvga.c
 
 CFLAGS16VGA = $(CFLAGS16INC) -Isrc
 
diff --git a/vgasrc/Kconfig b/vgasrc/Kconfig
index f04fca7..951240c 100644
--- a/vgasrc/Kconfig
+++ b/vgasrc/Kconfig
@@ -46,6 +46,14 @@ menu "VGA ROM"
             select VGA_STDVGA_PORTS
             help
                 Build support for Geode LX vga.
+
+        config VGA_COREBOOT
+            depends on COREBOOT
+            bool "coreboot linear framebuffer"
+            help
+                Build support for a vgabios wrapper around video
+                devices initialized using coreboot native vga init.
+
     endchoice
 
     choice
@@ -98,7 +106,7 @@ menu "VGA ROM"
             Support VBE.
 
     config VGA_PCI
-        depends on BUILD_VGABIOS
+        depends on BUILD_VGABIOS && !VGA_COREBOOT
         bool "PCI ROM Headers"
         default y
         help
diff --git a/vgasrc/cbvga.c b/vgasrc/cbvga.c
new file mode 100644
index 0000000..a9c6d3a
--- /dev/null
+++ b/vgasrc/cbvga.c
@@ -0,0 +1,189 @@
+// Simple framebuffer vgabios for use with coreboot native vga init.
+//
+// Copyright (C) 2014  Kevin O'Connor <kevin at koconnor.net>
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+#include "biosvar.h" // GET_BDA
+#include "cbvga.h" // cbvga_setup
+#include "output.h" // dprintf
+#include "stdvga.h" // SEG_CTEXT
+#include "string.h" // memset16_far
+#include "util.h" // find_cb_table
+#include "vgabios.h" // VGAREG_*
+
+static int CBmode VAR16;
+static struct vgamode_s CBmodeinfo VAR16;
+static u32 CBlinelength VAR16;
+
+struct vgamode_s *cbvga_find_mode(int mode)
+{
+    if (mode == GET_GLOBAL(CBmode))
+        return &CBmodeinfo;
+    return NULL;
+}
+
+void
+cbvga_list_modes(u16 seg, u16 *dest, u16 *last)
+{
+    if (dest<last) {
+        SET_FARVAR(seg, *dest, GET_GLOBAL(CBmode));
+        dest++;
+    }
+    SET_FARVAR(seg, *dest, 0xffff);
+}
+
+int
+cbvga_get_window(struct vgamode_s *vmode_g, int window)
+{
+    return -1;
+}
+
+int
+cbvga_set_window(struct vgamode_s *vmode_g, int window, int val)
+{
+    return -1;
+}
+
+int
+cbvga_get_linelength(struct vgamode_s *vmode_g)
+{
+    return GET_GLOBAL(CBlinelength);
+}
+
+int
+cbvga_set_linelength(struct vgamode_s *vmode_g, int val)
+{
+    return -1;
+}
+
+int
+cbvga_get_displaystart(struct vgamode_s *vmode_g)
+{
+    return 0;
+}
+
+int
+cbvga_set_displaystart(struct vgamode_s *vmode_g, int val)
+{
+    return -1;
+}
+
+int
+cbvga_get_dacformat(struct vgamode_s *vmode_g)
+{
+    return -1;
+}
+
+int
+cbvga_set_dacformat(struct vgamode_s *vmode_g, int val)
+{
+    return -1;
+}
+
+int
+cbvga_save_restore(int cmd, u16 seg, void *data)
+{
+    if (cmd & (SR_HARDWARE|SR_DAC|SR_REGISTERS))
+        return -1;
+    return bda_save_restore(cmd, seg, data);
+}
+
+int
+cbvga_set_mode(struct vgamode_s *vmode_g, int flags)
+{
+    if (!(flags & MF_NOCLEARMEM)) {
+        if (GET_GLOBAL(CBmodeinfo.memmodel) == MM_TEXT) {
+            memset16_far(SEG_CTEXT, (void*)0, 0x0720, 80*25*2);
+            return 0;
+        }
+        struct gfx_op op;
+        init_gfx_op(&op, vmode_g);
+        op.x = op.y = 0;
+        op.xlen = GET_GLOBAL(CBmodeinfo.width);
+        op.ylen = GET_GLOBAL(CBmodeinfo.height);
+        op.op = GO_MEMSET;
+        handle_gfx_op(&op);
+    }
+    return 0;
+}
+
+#define CB_TAG_FRAMEBUFFER      0x0012
+struct cb_framebuffer {
+    u32 tag;
+    u32 size;
+
+    u64 physical_address;
+    u32 x_resolution;
+    u32 y_resolution;
+    u32 bytes_per_line;
+    u8 bits_per_pixel;
+    u8 red_mask_pos;
+    u8 red_mask_size;
+    u8 green_mask_pos;
+    u8 green_mask_size;
+    u8 blue_mask_pos;
+    u8 blue_mask_size;
+    u8 reserved_mask_pos;
+    u8 reserved_mask_size;
+};
+
+int
+cbvga_setup(void)
+{
+    dprintf(1, "coreboot vga init\n");
+
+    if (GET_GLOBAL(HaveRunInit))
+        return 0;
+
+    struct cb_header *cbh = find_cb_table();
+    if (!cbh) {
+        dprintf(1, "Unable to find coreboot table\n");
+        return -1;
+    }
+    struct cb_framebuffer *cbfb = find_cb_subtable(cbh, CB_TAG_FRAMEBUFFER);
+    if (!cbfb) {
+        // Assume there is an EGA text framebuffer.
+        dprintf(1, "Did not find coreboot framebuffer - assuming EGA text\n");
+        SET_VGA(CBmode, 0x03);
+        SET_VGA(CBlinelength, 80*2);
+        SET_VGA(CBmodeinfo.memmodel, MM_TEXT);
+        SET_VGA(CBmodeinfo.width, 80);
+        SET_VGA(CBmodeinfo.height, 25);
+        SET_VGA(CBmodeinfo.depth, 4);
+        SET_VGA(CBmodeinfo.cwidth, 9);
+        SET_VGA(CBmodeinfo.cheight, 16);
+        SET_VGA(CBmodeinfo.sstart, SEG_CTEXT);
+        return 0;
+    }
+
+    u64 addr = GET_FARVAR(0, cbfb->physical_address);
+    u8 bpp = GET_FARVAR(0, cbfb->bits_per_pixel);
+    u32 xlines = GET_FARVAR(0, cbfb->x_resolution);
+    u32 ylines = GET_FARVAR(0, cbfb->y_resolution);
+    u32 linelength = GET_FARVAR(0, cbfb->bytes_per_line);
+    dprintf(1, "Found FB @ %llx %dx%d with %d bpp (%d stride)\n"
+            , addr, xlines, ylines, bpp, linelength);
+
+    if (!addr || addr > 0xffffffff
+        || (bpp != 15 && bpp != 16 && bpp != 24 && bpp != 32)) {
+        dprintf(1, "Unable to use FB\n");
+        return -1;
+    }
+
+    SET_VGA(CBmode, 0x140);
+    SET_VGA(VBE_framebuffer, addr);
+    SET_VGA(VBE_total_memory, linelength * ylines);
+    SET_VGA(CBlinelength, linelength);
+    SET_VGA(CBmodeinfo.memmodel, MM_DIRECT);
+    SET_VGA(CBmodeinfo.width, xlines);
+    SET_VGA(CBmodeinfo.height, ylines);
+    SET_VGA(CBmodeinfo.depth, bpp);
+    SET_VGA(CBmodeinfo.cwidth, 8);
+    SET_VGA(CBmodeinfo.cheight, 16);
+
+    // Setup BDA and clear screen.
+    vga_set_mode(GET_GLOBAL(CBmode), 0);
+
+    return 0;
+}
diff --git a/vgasrc/cbvga.h b/vgasrc/cbvga.h
new file mode 100644
index 0000000..fb892c8
--- /dev/null
+++ b/vgasrc/cbvga.h
@@ -0,0 +1,20 @@
+#ifndef __CBVGA_H
+#define __CBVGA_H
+
+#include "types.h" // u16
+
+struct vgamode_s *cbvga_find_mode(int mode);
+void cbvga_list_modes(u16 seg, u16 *dest, u16 *last);
+int cbvga_get_window(struct vgamode_s *vmode_g, int window);
+int cbvga_set_window(struct vgamode_s *vmode_g, int window, int val);
+int cbvga_get_linelength(struct vgamode_s *vmode_g);
+int cbvga_set_linelength(struct vgamode_s *vmode_g, int val);
+int cbvga_get_displaystart(struct vgamode_s *vmode_g);
+int cbvga_set_displaystart(struct vgamode_s *vmode_g, int val);
+int cbvga_get_dacformat(struct vgamode_s *vmode_g);
+int cbvga_set_dacformat(struct vgamode_s *vmode_g, int val);
+int cbvga_save_restore(int cmd, u16 seg, void *data);
+int cbvga_set_mode(struct vgamode_s *vmode_g, int flags);
+int cbvga_setup(void);
+
+#endif // cbvga.h
diff --git a/vgasrc/vgabios.h b/vgasrc/vgabios.h
index 8fe65d4..02cf3e3 100644
--- a/vgasrc/vgabios.h
+++ b/vgasrc/vgabios.h
@@ -106,6 +106,8 @@ struct vgamode_s *get_current_mode(void);
 int vga_set_mode(int mode, int flags);
 
 // vgafb.c
+void init_gfx_op(struct gfx_op *op, struct vgamode_s *vmode_g);
+void handle_gfx_op(struct gfx_op *op);
 void *text_address(struct cursorpos cp);
 void vgafb_move_chars(struct vgamode_s *vmode_g, struct cursorpos dest
                       , struct cursorpos src, struct cursorpos movesize);
diff --git a/vgasrc/vgafb.c b/vgasrc/vgafb.c
index b90a956..fdc525d 100644
--- a/vgasrc/vgafb.c
+++ b/vgasrc/vgafb.c
@@ -292,7 +292,7 @@ gfx_direct(struct gfx_op *op)
  ****************************************************************/
 
 // Prepare a struct gfx_op for use.
-static void
+void
 init_gfx_op(struct gfx_op *op, struct vgamode_s *vmode_g)
 {
     memset(op, 0, sizeof(*op));
@@ -302,7 +302,7 @@ init_gfx_op(struct gfx_op *op, struct vgamode_s *vmode_g)
 }
 
 // Issue a graphics operation.
-static void
+void
 handle_gfx_op(struct gfx_op *op)
 {
     switch (GET_GLOBAL(op->vmode_g->memmodel)) {
diff --git a/vgasrc/vgahw.h b/vgasrc/vgahw.h
index 3e84357..39f818a 100644
--- a/vgasrc/vgahw.h
+++ b/vgasrc/vgahw.h
@@ -4,6 +4,7 @@
 #include "types.h" // u8
 #include "config.h" // CONFIG_*
 
+#include "cbvga.h" // cbvga_setup
 #include "clext.h" // clext_set_mode
 #include "bochsvga.h" // bochsvga_set_mode
 #include "stdvga.h" // stdvga_set_mode
@@ -14,6 +15,8 @@ static inline struct vgamode_s *vgahw_find_mode(int mode) {
         return clext_find_mode(mode);
     if (CONFIG_VGA_BOCHS)
         return bochsvga_find_mode(mode);
+    if (CONFIG_VGA_COREBOOT)
+        return cbvga_find_mode(mode);
     return stdvga_find_mode(mode);
 }
 
@@ -22,6 +25,8 @@ static inline int vgahw_set_mode(struct vgamode_s *vmode_g, int flags) {
         return clext_set_mode(vmode_g, flags);
     if (CONFIG_VGA_BOCHS)
         return bochsvga_set_mode(vmode_g, flags);
+    if (CONFIG_VGA_COREBOOT)
+        return cbvga_set_mode(vmode_g, flags);
     return stdvga_set_mode(vmode_g, flags);
 }
 
@@ -30,6 +35,8 @@ static inline void vgahw_list_modes(u16 seg, u16 *dest, u16 *last) {
         clext_list_modes(seg, dest, last);
     else if (CONFIG_VGA_BOCHS)
         bochsvga_list_modes(seg, dest, last);
+    else if (CONFIG_VGA_COREBOOT)
+        cbvga_list_modes(seg, dest, last);
     else
         stdvga_list_modes(seg, dest, last);
 }
@@ -41,6 +48,8 @@ static inline int vgahw_setup(void) {
         return bochsvga_setup();
     if (CONFIG_VGA_GEODEGX2 || CONFIG_VGA_GEODELX)
         return geodevga_setup();
+    if (CONFIG_VGA_COREBOOT)
+        return cbvga_setup();
     return stdvga_setup();
 }
 
@@ -49,6 +58,8 @@ static inline int vgahw_get_window(struct vgamode_s *vmode_g, int window) {
         return clext_get_window(vmode_g, window);
     if (CONFIG_VGA_BOCHS)
         return bochsvga_get_window(vmode_g, window);
+    if (CONFIG_VGA_COREBOOT)
+        return cbvga_get_window(vmode_g, window);
     return stdvga_get_window(vmode_g, window);
 }
 
@@ -58,6 +69,8 @@ static inline int vgahw_set_window(struct vgamode_s *vmode_g, int window
         return clext_set_window(vmode_g, window, val);
     if (CONFIG_VGA_BOCHS)
         return bochsvga_set_window(vmode_g, window, val);
+    if (CONFIG_VGA_COREBOOT)
+        return cbvga_set_window(vmode_g, window, val);
     return stdvga_set_window(vmode_g, window, val);
 }
 
@@ -66,6 +79,8 @@ static inline int vgahw_get_linelength(struct vgamode_s *vmode_g) {
         return clext_get_linelength(vmode_g);
     if (CONFIG_VGA_BOCHS)
         return bochsvga_get_linelength(vmode_g);
+    if (CONFIG_VGA_COREBOOT)
+        return cbvga_get_linelength(vmode_g);
     return stdvga_get_linelength(vmode_g);
 }
 
@@ -74,6 +89,8 @@ static inline int vgahw_set_linelength(struct vgamode_s *vmode_g, int val) {
         return clext_set_linelength(vmode_g, val);
     if (CONFIG_VGA_BOCHS)
         return bochsvga_set_linelength(vmode_g, val);
+    if (CONFIG_VGA_COREBOOT)
+        return cbvga_set_linelength(vmode_g, val);
     return stdvga_set_linelength(vmode_g, val);
 }
 
@@ -82,6 +99,8 @@ static inline int vgahw_get_displaystart(struct vgamode_s *vmode_g) {
         return clext_get_displaystart(vmode_g);
     if (CONFIG_VGA_BOCHS)
         return bochsvga_get_displaystart(vmode_g);
+    if (CONFIG_VGA_COREBOOT)
+        return cbvga_get_displaystart(vmode_g);
     return stdvga_get_displaystart(vmode_g);
 }
 
@@ -90,18 +109,24 @@ static inline int vgahw_set_displaystart(struct vgamode_s *vmode_g, int val) {
         return clext_set_displaystart(vmode_g, val);
     if (CONFIG_VGA_BOCHS)
         return bochsvga_set_displaystart(vmode_g, val);
+    if (CONFIG_VGA_COREBOOT)
+        return cbvga_set_displaystart(vmode_g, val);
     return stdvga_set_displaystart(vmode_g, val);
 }
 
 static inline int vgahw_get_dacformat(struct vgamode_s *vmode_g) {
     if (CONFIG_VGA_BOCHS)
         return bochsvga_get_dacformat(vmode_g);
+    if (CONFIG_VGA_COREBOOT)
+        return cbvga_get_dacformat(vmode_g);
     return stdvga_get_dacformat(vmode_g);
 }
 
 static inline int vgahw_set_dacformat(struct vgamode_s *vmode_g, int val) {
     if (CONFIG_VGA_BOCHS)
         return bochsvga_set_dacformat(vmode_g, val);
+    if (CONFIG_VGA_COREBOOT)
+        return cbvga_set_dacformat(vmode_g, val);
     return stdvga_set_dacformat(vmode_g, val);
 }
 
@@ -110,6 +135,8 @@ static inline int vgahw_save_restore(int cmd, u16 seg, void *data) {
         return clext_save_restore(cmd, seg, data);
     if (CONFIG_VGA_BOCHS)
         return bochsvga_save_restore(cmd, seg, data);
+    if (CONFIG_VGA_COREBOOT)
+        return cbvga_save_restore(cmd, seg, data);
     return stdvga_save_restore(cmd, seg, data);
 }
 
-- 
1.9.0




More information about the SeaBIOS mailing list