[SeaBIOS] [PATCH 4/4] vgabios: Initial support for coreboot native vga vgabios.
Kevin O'Connor
kevin at koconnor.net
Wed Feb 12 18:32:08 CET 2014
Signed-off-by: Kevin O'Connor <kevin at koconnor.net>
---
Makefile | 3 +-
vgasrc/Kconfig | 9 +++
vgasrc/cbvga.c | 169 +++++++++++++++++++++++++++++++++++++++++++++++++++++
vgasrc/cbvga.h | 20 +++++++
vgasrc/vgabios.h | 1 +
vgasrc/vgahighfb.c | 2 +-
vgasrc/vgahw.h | 27 +++++++++
7 files changed, 229 insertions(+), 2 deletions(-)
create mode 100644 vgasrc/cbvga.c
create mode 100644 vgasrc/cbvga.h
diff --git a/Makefile b/Makefile
index ffe0650..fc1aabb 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/vgahighfb.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 bdb8f5b..20ac2ce 100644
--- a/vgasrc/Kconfig
+++ b/vgasrc/Kconfig
@@ -51,6 +51,15 @@ menu "VGA ROM"
select VGA_STDVGA_FRAMEBUFFER
help
Build support for Geode LX vga.
+
+ config VGA_COREBOOT
+ depends on COREBOOT
+ bool "coreboot linear framebuffer"
+ select VGA_HIGH_FRAMEBUFFER
+ help
+ Build support for a vgabios wrapper around video
+ devices initialized using coreboot native vga init.
+
endchoice
choice
diff --git a/vgasrc/cbvga.c b/vgasrc/cbvga.c
new file mode 100644
index 0000000..d3dc2a4
--- /dev/null
+++ b/vgasrc/cbvga.c
@@ -0,0 +1,169 @@
+// 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 "util.h" // find_cb_table
+#include "vgabios.h" // VGAREG_*
+
+#define CBMODENUM 0x140
+static struct vgamode_s CBmode VAR16 = {
+ MM_DIRECT, 0, 0, 0, 8, 16, 0
+};
+static u32 CBlinelength VAR16;
+
+struct vgamode_s *cbvga_find_mode(int mode)
+{
+ if (mode == CBMODENUM)
+ return &CBmode;
+ return NULL;
+}
+
+void
+cbvga_list_modes(u16 seg, u16 *dest, u16 *last)
+{
+ if (dest<last) {
+ SET_FARVAR(seg, *dest, CBMODENUM);
+ 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)) {
+ int i, lines = GET_GLOBAL(CBmode.height);
+ u32 stride = GET_GLOBAL(CBlinelength);
+ void *dest = (void*)GET_GLOBAL(VBE_framebuffer);
+ for (i=0; i<lines; i++, dest+=stride)
+ memset_high(vmode_g, dest, 0, stride);
+ }
+ 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) {
+ dprintf(1, "Unable to find coreboot framebuffer table\n");
+ return -1;
+ }
+
+ 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(VBE_framebuffer, addr);
+ SET_VGA(VBE_total_memory, linelength * ylines);
+ SET_VGA(CBlinelength, linelength);
+ SET_VGA(CBmode.width, xlines);
+ SET_VGA(CBmode.height, ylines);
+ SET_VGA(CBmode.depth, bpp);
+
+ // Setup BDA
+ vga_set_mode(CBMODENUM, MF_NOCLEARMEM);
+
+ 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 1e3b0b2..4940750 100644
--- a/vgasrc/vgabios.h
+++ b/vgasrc/vgabios.h
@@ -96,6 +96,7 @@ void vgafb_write_pixel(u8 color, u16 x, u16 y);
u8 vgafb_read_pixel(u16 x, u16 y);
// vgahighfb.c
+void memset_high(struct vgamode_s *vmode_g, void *dest, u32 attr, u32 len);
void scroll_direct(struct vgamode_s *vmode_g, int nblines, int attr
, struct cursorpos ul, struct cursorpos lr);
void write_gfx_char_direct(struct vgamode_s *vmode_g
diff --git a/vgasrc/vgahighfb.c b/vgasrc/vgahighfb.c
index 0498b16..dced86b 100644
--- a/vgasrc/vgahighfb.c
+++ b/vgasrc/vgahighfb.c
@@ -78,7 +78,7 @@ memcpy_high(struct vgamode_s *vmode_g, void *dest, void *src, u32 len)
: : "cc", "memory");
}
-static void
+void
memset_high(struct vgamode_s *vmode_g, void *dest, u32 attr, u32 len)
{
u32 pixels[8];
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.8.5.3
More information about the SeaBIOS
mailing list