diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | vgasrc/Kconfig | 17 | ||||
-rw-r--r-- | vgasrc/bochsdisplay.c | 59 | ||||
-rw-r--r-- | vgasrc/vgahw.h | 28 | ||||
-rw-r--r-- | vgasrc/vgautil.h | 3 |
5 files changed, 95 insertions, 14 deletions
@@ -213,7 +213,7 @@ SRCVGA=src/output.c src/string.c src/hw/pci.c src/hw/serialio.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 \ - src/fw/coreboot.c vgasrc/cbvga.c + src/fw/coreboot.c vgasrc/cbvga.c vgasrc/bochsdisplay.c ifeq "$(CONFIG_VGA_FIXUP_ASM)" "y" $(OUT)vgaccode16.raw.s: $(OUT)autoconf.h $(patsubst %.c, $(OUT)%.o,$(SRCVGA)) ; $(call whole-compile, $(filter-out -fomit-frame-pointer,$(CFLAGS16)) -fno-omit-frame-pointer -S -Isrc, $(SRCVGA),$@) diff --git a/vgasrc/Kconfig b/vgasrc/Kconfig index f5098a4b..4443c0b3 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 00000000..e1f90f96 --- /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 2a85eba8..6d6ff1aa 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 e02ad3e6..d93da76b 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); |