summaryrefslogtreecommitdiff
path: root/vgasrc
diff options
context:
space:
mode:
Diffstat (limited to 'vgasrc')
-rw-r--r--vgasrc/Kconfig17
-rw-r--r--vgasrc/bochsdisplay.c59
-rw-r--r--vgasrc/vgahw.h28
-rw-r--r--vgasrc/vgautil.h3
4 files changed, 94 insertions, 13 deletions
diff --git a/vgasrc/Kconfig b/vgasrc/Kconfig
index f5098a4..4443c0b 100644
--- a/vgasrc/Kconfig
+++ b/vgasrc/Kconfig
@@ -55,6 +55,21 @@ menu "VGA ROM"
Build support for a vgabios wrapper around video
devices initialized using coreboot native vga init.
+ config DISPLAY_BOCHS
+ depends on QEMU
+ bool "qemu bochs-display support"
+ select VGA_EMULATE_TEXT
+ help
+ Build support for the qemu bochs-display device, which
+ is basically qemu stdvga without the legacy vga
+ emulation, supporting only 16+32 bpp VESA video modes
+ in a linear framebuffer. So this uses cbvga text mode
+ emulation.
+
+ The bochs-display device is available in qemu
+ v3.0+. The vgabios works with the qemu stdvga too (use
+ "qemu -device VGA,romfile=/path/to/vgabios.bin")".
+
endchoice
choice
@@ -166,6 +181,7 @@ menu "VGA ROM"
default 0x1af4 if VGA_BOCHS_VIRTIO
default 0x100b if VGA_GEODEGX2
default 0x1022 if VGA_GEODELX
+ default 0x1234 if DISPLAY_BOCHS
default 0x0000
help
Vendor ID for the PCI ROM
@@ -181,6 +197,7 @@ menu "VGA ROM"
default 0x1050 if VGA_BOCHS_VIRTIO
default 0x0030 if VGA_GEODEGX2
default 0x2081 if VGA_GEODELX
+ default 0x1111 if DISPLAY_BOCHS
default 0x0000
help
Device ID for the PCI ROM
diff --git a/vgasrc/bochsdisplay.c b/vgasrc/bochsdisplay.c
new file mode 100644
index 0000000..e1f90f9
--- /dev/null
+++ b/vgasrc/bochsdisplay.c
@@ -0,0 +1,59 @@
+#include "biosvar.h" // GET_BDA
+#include "output.h" // dprintf
+#include "string.h" // memset16_far
+#include "bochsvga.h" // VBE_BOCHS_*
+#include "hw/pci.h" // pci_config_readl
+#include "hw/pci_regs.h" // PCI_BASE_ADDRESS_0
+#include "vgautil.h" // VBE_total_memory
+
+#define FRAMEBUFFER_WIDTH 1024
+#define FRAMEBUFFER_HEIGHT 768
+#define FRAMEBUFFER_BPP 4
+#define FRAMEBUFFER_STRIDE (FRAMEBUFFER_BPP * FRAMEBUFFER_WIDTH)
+#define FRAMEBUFFER_SIZE (FRAMEBUFFER_STRIDE * FRAMEBUFFER_HEIGHT)
+
+int
+bochs_display_setup(void)
+{
+ dprintf(1, "bochs-display: setup called\n");
+
+ if (GET_GLOBAL(HaveRunInit))
+ return 0;
+
+ int bdf = GET_GLOBAL(VgaBDF);
+ if (bdf == 0)
+ return 0;
+
+ u32 bar = pci_config_readl(bdf, PCI_BASE_ADDRESS_0);
+ u32 lfb_addr = bar & PCI_BASE_ADDRESS_MEM_MASK;
+ bar = pci_config_readl(bdf, PCI_BASE_ADDRESS_2);
+ u32 io_addr = bar & PCI_BASE_ADDRESS_IO_MASK;
+ dprintf(1, "bochs-display: bdf %02x:%02x.%x, bar 0 at 0x%x, bar 1 at 0x%x\n"
+ , pci_bdf_to_bus(bdf) , pci_bdf_to_dev(bdf), pci_bdf_to_fn(bdf),
+ lfb_addr, io_addr);
+
+ u16 *dispi = (void*)(io_addr + 0x500);
+ u8 *vga = (void*)(io_addr + 0x400);
+ u16 id = readw(dispi + VBE_DISPI_INDEX_ID);
+ dprintf(1, "bochs-display: id is 0x%x, %s\n", id
+ , id == VBE_DISPI_ID5 ? "good" : "FAIL");
+ if (id != VBE_DISPI_ID5)
+ return 0;
+
+ dprintf(1, "bochs-display: using %dx%d, %d bpp (%d stride)\n"
+ , FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT
+ , FRAMEBUFFER_BPP * 8, FRAMEBUFFER_STRIDE);
+
+ cbvga_setup_modes(lfb_addr, FRAMEBUFFER_BPP * 8,
+ FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT,
+ FRAMEBUFFER_STRIDE);
+
+ writew(dispi + VBE_DISPI_INDEX_XRES, FRAMEBUFFER_WIDTH);
+ writew(dispi + VBE_DISPI_INDEX_YRES, FRAMEBUFFER_HEIGHT);
+ writew(dispi + VBE_DISPI_INDEX_BPP, FRAMEBUFFER_BPP * 8);
+ writew(dispi + VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED);
+
+ writeb(vga, 0x20); /* unblank (for qemu -device VGA) */
+
+ return 0;
+}
diff --git a/vgasrc/vgahw.h b/vgasrc/vgahw.h
index 2a85eba..6d6ff1a 100644
--- a/vgasrc/vgahw.h
+++ b/vgasrc/vgahw.h
@@ -14,7 +14,7 @@ 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)
+ if (CONFIG_VGA_COREBOOT || CONFIG_DISPLAY_BOCHS)
return cbvga_find_mode(mode);
return stdvga_find_mode(mode);
}
@@ -24,7 +24,7 @@ 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)
+ if (CONFIG_VGA_COREBOOT || CONFIG_DISPLAY_BOCHS)
return cbvga_set_mode(vmode_g, flags);
return stdvga_set_mode(vmode_g, flags);
}
@@ -34,7 +34,7 @@ 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)
+ else if (CONFIG_VGA_COREBOOT || CONFIG_DISPLAY_BOCHS)
cbvga_list_modes(seg, dest, last);
else
stdvga_list_modes(seg, dest, last);
@@ -49,6 +49,8 @@ static inline int vgahw_setup(void) {
return geodevga_setup();
if (CONFIG_VGA_COREBOOT)
return cbvga_setup();
+ if (CONFIG_DISPLAY_BOCHS)
+ return bochs_display_setup();
return stdvga_setup();
}
@@ -57,7 +59,7 @@ 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)
+ if (CONFIG_VGA_COREBOOT || CONFIG_DISPLAY_BOCHS)
return cbvga_get_window(vmode_g, window);
return stdvga_get_window(vmode_g, window);
}
@@ -68,7 +70,7 @@ 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)
+ if (CONFIG_VGA_COREBOOT || CONFIG_DISPLAY_BOCHS)
return cbvga_set_window(vmode_g, window, val);
return stdvga_set_window(vmode_g, window, val);
}
@@ -78,7 +80,7 @@ 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)
+ if (CONFIG_VGA_COREBOOT || CONFIG_DISPLAY_BOCHS)
return cbvga_get_linelength(vmode_g);
return stdvga_get_linelength(vmode_g);
}
@@ -88,7 +90,7 @@ 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)
+ if (CONFIG_VGA_COREBOOT || CONFIG_DISPLAY_BOCHS)
return cbvga_set_linelength(vmode_g, val);
return stdvga_set_linelength(vmode_g, val);
}
@@ -98,7 +100,7 @@ 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)
+ if (CONFIG_VGA_COREBOOT || CONFIG_DISPLAY_BOCHS)
return cbvga_get_displaystart(vmode_g);
return stdvga_get_displaystart(vmode_g);
}
@@ -108,7 +110,7 @@ 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)
+ if (CONFIG_VGA_COREBOOT || CONFIG_DISPLAY_BOCHS)
return cbvga_set_displaystart(vmode_g, val);
return stdvga_set_displaystart(vmode_g, val);
}
@@ -116,7 +118,7 @@ static inline int vgahw_set_displaystart(struct vgamode_s *vmode_g, int 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)
+ if (CONFIG_VGA_COREBOOT || CONFIG_DISPLAY_BOCHS)
return cbvga_get_dacformat(vmode_g);
return stdvga_get_dacformat(vmode_g);
}
@@ -124,7 +126,7 @@ static inline int vgahw_get_dacformat(struct vgamode_s *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)
+ if (CONFIG_VGA_COREBOOT || CONFIG_DISPLAY_BOCHS)
return cbvga_set_dacformat(vmode_g, val);
return stdvga_set_dacformat(vmode_g, val);
}
@@ -134,13 +136,13 @@ 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)
+ if (CONFIG_VGA_COREBOOT || CONFIG_DISPLAY_BOCHS)
return cbvga_save_restore(cmd, seg, data);
return stdvga_save_restore(cmd, seg, data);
}
static inline int vgahw_get_linesize(struct vgamode_s *vmode_g) {
- if (CONFIG_VGA_COREBOOT)
+ if (CONFIG_VGA_COREBOOT || CONFIG_DISPLAY_BOCHS)
return cbvga_get_linesize(vmode_g);
return stdvga_get_linesize(vmode_g);
}
diff --git a/vgasrc/vgautil.h b/vgasrc/vgautil.h
index e02ad3e..d93da76 100644
--- a/vgasrc/vgautil.h
+++ b/vgasrc/vgautil.h
@@ -21,6 +21,9 @@ int cbvga_get_linesize(struct vgamode_s *vmode_g);
void cbvga_setup_modes(u64 addr, u8 bpp, u32 xlines, u32 ylines, u32 linelength);
int cbvga_setup(void);
+// bochsdisplay.c
+int bochs_display_setup(void);
+
// clext.c
struct vgamode_s *clext_find_mode(int mode);
void clext_list_modes(u16 seg, u16 *dest, u16 *last);