Signed-off-by: Gerd Hoffmann kraxel@redhat.com --- Makefile | 2 +- vgasrc/vgahw.c | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++ vgasrc/vgahw.h | 141 +++++++-------------------------------------------------- 3 files changed, 144 insertions(+), 126 deletions(-) create mode 100644 vgasrc/vgahw.c
diff --git a/Makefile b/Makefile index 1588522..507d907 100644 --- a/Makefile +++ b/Makefile @@ -180,7 +180,7 @@ $(OUT)bios.bin.elf $(OUT)bios.bin: $(OUT)rom.o scripts/checkrom.py SRCVGA=src/output.c src/util.c src/pci.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 vgasrc/vgahw.c
CFLAGS16VGA = $(CFLAGS16INC) -Isrc
diff --git a/vgasrc/vgahw.c b/vgasrc/vgahw.c new file mode 100644 index 0000000..fc843c4 --- /dev/null +++ b/vgasrc/vgahw.c @@ -0,0 +1,127 @@ +#include "types.h" // u8 +#include "config.h" // CONFIG_* + +#include "clext.h" // clext_set_mode +#include "bochsvga.h" // bochsvga_set_mode +#include "stdvga.h" // stdvga_set_mode +#include "geodevga.h" // geodevga_setup + +struct vgamode_s *vgahw_find_mode(int mode) { + if (CONFIG_VGA_CIRRUS) + return clext_find_mode(mode); + if (CONFIG_VGA_BOCHS) + return bochsvga_find_mode(mode); + return stdvga_find_mode(mode); +} + +int vgahw_set_mode(struct vgamode_s *vmode_g, int flags) { + if (CONFIG_VGA_CIRRUS) + return clext_set_mode(vmode_g, flags); + if (CONFIG_VGA_BOCHS) + return bochsvga_set_mode(vmode_g, flags); + return stdvga_set_mode(vmode_g, flags); +} + +void vgahw_list_modes(u16 seg, u16 *dest, u16 *last) { + if (CONFIG_VGA_CIRRUS) + clext_list_modes(seg, dest, last); + else if (CONFIG_VGA_BOCHS) + bochsvga_list_modes(seg, dest, last); + else + stdvga_list_modes(seg, dest, last); +} + +int vgahw_setup(void) { + if (CONFIG_VGA_CIRRUS) + return clext_setup(); + if (CONFIG_VGA_BOCHS) + return bochsvga_setup(); + if (CONFIG_VGA_GEODEGX2 || CONFIG_VGA_GEODELX) + return geodevga_setup(); + return stdvga_setup(); +} + +int vgahw_get_window(struct vgamode_s *vmode_g, int window) { + if (CONFIG_VGA_CIRRUS) + return clext_get_window(vmode_g, window); + if (CONFIG_VGA_BOCHS) + return bochsvga_get_window(vmode_g, window); + return stdvga_get_window(vmode_g, window); +} + +int vgahw_set_window(struct vgamode_s *vmode_g, int window + , int val) { + if (CONFIG_VGA_CIRRUS) + return clext_set_window(vmode_g, window, val); + if (CONFIG_VGA_BOCHS) + return bochsvga_set_window(vmode_g, window, val); + return stdvga_set_window(vmode_g, window, val); +} + +int vgahw_get_linelength(struct vgamode_s *vmode_g) { + if (CONFIG_VGA_CIRRUS) + return clext_get_linelength(vmode_g); + if (CONFIG_VGA_BOCHS) + return bochsvga_get_linelength(vmode_g); + return stdvga_get_linelength(vmode_g); +} + +int vgahw_set_linelength(struct vgamode_s *vmode_g, int val) { + if (CONFIG_VGA_CIRRUS) + return clext_set_linelength(vmode_g, val); + if (CONFIG_VGA_BOCHS) + return bochsvga_set_linelength(vmode_g, val); + return stdvga_set_linelength(vmode_g, val); +} + +int vgahw_get_displaystart(struct vgamode_s *vmode_g) { + if (CONFIG_VGA_CIRRUS) + return clext_get_displaystart(vmode_g); + if (CONFIG_VGA_BOCHS) + return bochsvga_get_displaystart(vmode_g); + return stdvga_get_displaystart(vmode_g); +} + +int vgahw_set_displaystart(struct vgamode_s *vmode_g, int val) { + if (CONFIG_VGA_CIRRUS) + return clext_set_displaystart(vmode_g, val); + if (CONFIG_VGA_BOCHS) + return bochsvga_set_displaystart(vmode_g, val); + return stdvga_set_displaystart(vmode_g, val); +} + +int vgahw_get_dacformat(struct vgamode_s *vmode_g) { + if (CONFIG_VGA_BOCHS) + return bochsvga_get_dacformat(vmode_g); + return stdvga_get_dacformat(vmode_g); +} + +int vgahw_set_dacformat(struct vgamode_s *vmode_g, int val) { + if (CONFIG_VGA_BOCHS) + return bochsvga_set_dacformat(vmode_g, val); + return stdvga_set_dacformat(vmode_g, val); +} + +int vgahw_size_state(int states) { + if (CONFIG_VGA_CIRRUS) + return clext_size_state(states); + if (CONFIG_VGA_BOCHS) + return bochsvga_size_state(states); + return stdvga_size_state(states); +} + +int vgahw_save_state(u16 seg, void *data, int states) { + if (CONFIG_VGA_CIRRUS) + return clext_save_state(seg, data, states); + if (CONFIG_VGA_BOCHS) + return bochsvga_save_state(seg, data, states); + return stdvga_save_state(seg, data, states); +} + +int vgahw_restore_state(u16 seg, void *data, int states) { + if (CONFIG_VGA_CIRRUS) + return clext_restore_state(seg, data, states); + if (CONFIG_VGA_BOCHS) + return bochsvga_restore_state(seg, data, states); + return stdvga_restore_state(seg, data, states); +} diff --git a/vgasrc/vgahw.h b/vgasrc/vgahw.h index f69a5ac..7a82b0d 100644 --- a/vgasrc/vgahw.h +++ b/vgasrc/vgahw.h @@ -2,131 +2,22 @@ #define __VGAHW_H
#include "types.h" // u8 -#include "config.h" // CONFIG_*
-#include "clext.h" // clext_set_mode -#include "bochsvga.h" // bochsvga_set_mode -#include "stdvga.h" // stdvga_set_mode -#include "geodevga.h" // geodevga_setup - -static inline struct vgamode_s *vgahw_find_mode(int mode) { - if (CONFIG_VGA_CIRRUS) - return clext_find_mode(mode); - if (CONFIG_VGA_BOCHS) - return bochsvga_find_mode(mode); - return stdvga_find_mode(mode); -} - -static inline int vgahw_set_mode(struct vgamode_s *vmode_g, int flags) { - if (CONFIG_VGA_CIRRUS) - return clext_set_mode(vmode_g, flags); - if (CONFIG_VGA_BOCHS) - return bochsvga_set_mode(vmode_g, flags); - return stdvga_set_mode(vmode_g, flags); -} - -static inline void vgahw_list_modes(u16 seg, u16 *dest, u16 *last) { - if (CONFIG_VGA_CIRRUS) - clext_list_modes(seg, dest, last); - else if (CONFIG_VGA_BOCHS) - bochsvga_list_modes(seg, dest, last); - else - stdvga_list_modes(seg, dest, last); -} - -static inline int vgahw_setup(void) { - if (CONFIG_VGA_CIRRUS) - return clext_setup(); - if (CONFIG_VGA_BOCHS) - return bochsvga_setup(); - if (CONFIG_VGA_GEODEGX2 || CONFIG_VGA_GEODELX) - return geodevga_setup(); - return stdvga_setup(); -} - -static inline int vgahw_get_window(struct vgamode_s *vmode_g, int window) { - if (CONFIG_VGA_CIRRUS) - return clext_get_window(vmode_g, window); - if (CONFIG_VGA_BOCHS) - return bochsvga_get_window(vmode_g, window); - return stdvga_get_window(vmode_g, window); -} - -static inline int vgahw_set_window(struct vgamode_s *vmode_g, int window - , int val) { - if (CONFIG_VGA_CIRRUS) - return clext_set_window(vmode_g, window, val); - if (CONFIG_VGA_BOCHS) - return bochsvga_set_window(vmode_g, window, val); - return stdvga_set_window(vmode_g, window, val); -} - -static inline int vgahw_get_linelength(struct vgamode_s *vmode_g) { - if (CONFIG_VGA_CIRRUS) - return clext_get_linelength(vmode_g); - if (CONFIG_VGA_BOCHS) - return bochsvga_get_linelength(vmode_g); - return stdvga_get_linelength(vmode_g); -} - -static inline int vgahw_set_linelength(struct vgamode_s *vmode_g, int val) { - if (CONFIG_VGA_CIRRUS) - return clext_set_linelength(vmode_g, val); - if (CONFIG_VGA_BOCHS) - return bochsvga_set_linelength(vmode_g, val); - return stdvga_set_linelength(vmode_g, val); -} - -static inline int vgahw_get_displaystart(struct vgamode_s *vmode_g) { - if (CONFIG_VGA_CIRRUS) - return clext_get_displaystart(vmode_g); - if (CONFIG_VGA_BOCHS) - return bochsvga_get_displaystart(vmode_g); - return stdvga_get_displaystart(vmode_g); -} - -static inline int vgahw_set_displaystart(struct vgamode_s *vmode_g, int val) { - if (CONFIG_VGA_CIRRUS) - return clext_set_displaystart(vmode_g, val); - if (CONFIG_VGA_BOCHS) - return bochsvga_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); - 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); - return stdvga_set_dacformat(vmode_g, val); -} - -static inline int vgahw_size_state(int states) { - if (CONFIG_VGA_CIRRUS) - return clext_size_state(states); - if (CONFIG_VGA_BOCHS) - return bochsvga_size_state(states); - return stdvga_size_state(states); -} - -static inline int vgahw_save_state(u16 seg, void *data, int states) { - if (CONFIG_VGA_CIRRUS) - return clext_save_state(seg, data, states); - if (CONFIG_VGA_BOCHS) - return bochsvga_save_state(seg, data, states); - return stdvga_save_state(seg, data, states); -} - -static inline int vgahw_restore_state(u16 seg, void *data, int states) { - if (CONFIG_VGA_CIRRUS) - return clext_restore_state(seg, data, states); - if (CONFIG_VGA_BOCHS) - return bochsvga_restore_state(seg, data, states); - return stdvga_restore_state(seg, data, states); -} +struct vgamode_s *vgahw_find_mode(int mode); +int vgahw_set_mode(struct vgamode_s *vmode_g, int flags); +void vgahw_list_modes(u16 seg, u16 *dest, u16 *last); +int vgahw_setup(void); +int vgahw_get_window(struct vgamode_s *vmode_g, int window); +int vgahw_set_window(struct vgamode_s *vmode_g, int window + , int val); +int vgahw_get_linelength(struct vgamode_s *vmode_g); +int vgahw_set_linelength(struct vgamode_s *vmode_g, int val); +int vgahw_get_displaystart(struct vgamode_s *vmode_g); +int vgahw_set_displaystart(struct vgamode_s *vmode_g, int val); +int vgahw_get_dacformat(struct vgamode_s *vmode_g); +int vgahw_set_dacformat(struct vgamode_s *vmode_g, int val); +int vgahw_size_state(int states); +int vgahw_save_state(u16 seg, void *data, int states); +int vgahw_restore_state(u16 seg, void *data, int states);
#endif // vgahw.h
Happens in case a vga with bochs interface lives behind a pci bridge. stdvga ports are passed through with vgasnoop enabled, bochs interface ports are not. Better fallback to stdvga (so text mode works as usual) rather than bailing out.
Signed-off-by: Gerd Hoffmann kraxel@redhat.com --- vgasrc/vgahw.c | 67 ++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 37 insertions(+), 30 deletions(-)
diff --git a/vgasrc/vgahw.c b/vgasrc/vgahw.c index fc843c4..95482df 100644 --- a/vgasrc/vgahw.c +++ b/vgasrc/vgahw.c @@ -6,122 +6,129 @@ #include "stdvga.h" // stdvga_set_mode #include "geodevga.h" // geodevga_setup
+static int CirrusDetected VAR16 = 0; +static int BochsDetected VAR16 = 0; + struct vgamode_s *vgahw_find_mode(int mode) { - if (CONFIG_VGA_CIRRUS) + if (CONFIG_VGA_CIRRUS && CirrusDetected) return clext_find_mode(mode); - if (CONFIG_VGA_BOCHS) + if (CONFIG_VGA_BOCHS && BochsDetected) return bochsvga_find_mode(mode); return stdvga_find_mode(mode); }
int vgahw_set_mode(struct vgamode_s *vmode_g, int flags) { - if (CONFIG_VGA_CIRRUS) + if (CONFIG_VGA_CIRRUS && CirrusDetected) return clext_set_mode(vmode_g, flags); - if (CONFIG_VGA_BOCHS) + if (CONFIG_VGA_BOCHS && BochsDetected) return bochsvga_set_mode(vmode_g, flags); return stdvga_set_mode(vmode_g, flags); }
void vgahw_list_modes(u16 seg, u16 *dest, u16 *last) { - if (CONFIG_VGA_CIRRUS) + if (CONFIG_VGA_CIRRUS && CirrusDetected) clext_list_modes(seg, dest, last); - else if (CONFIG_VGA_BOCHS) + else if (CONFIG_VGA_BOCHS && BochsDetected) bochsvga_list_modes(seg, dest, last); else stdvga_list_modes(seg, dest, last); }
int vgahw_setup(void) { - if (CONFIG_VGA_CIRRUS) - return clext_setup(); - if (CONFIG_VGA_BOCHS) - return bochsvga_setup(); + if (CONFIG_VGA_CIRRUS && clext_setup() == 0) { + CirrusDetected = 1; + return 0; + } + if (CONFIG_VGA_BOCHS && bochsvga_setup() == 0) { + BochsDetected = 1; + return 0; + } if (CONFIG_VGA_GEODEGX2 || CONFIG_VGA_GEODELX) return geodevga_setup(); return stdvga_setup(); }
int vgahw_get_window(struct vgamode_s *vmode_g, int window) { - if (CONFIG_VGA_CIRRUS) + if (CONFIG_VGA_CIRRUS && CirrusDetected) return clext_get_window(vmode_g, window); - if (CONFIG_VGA_BOCHS) + if (CONFIG_VGA_BOCHS && BochsDetected) return bochsvga_get_window(vmode_g, window); return stdvga_get_window(vmode_g, window); }
int vgahw_set_window(struct vgamode_s *vmode_g, int window , int val) { - if (CONFIG_VGA_CIRRUS) + if (CONFIG_VGA_CIRRUS && CirrusDetected) return clext_set_window(vmode_g, window, val); - if (CONFIG_VGA_BOCHS) + if (CONFIG_VGA_BOCHS && BochsDetected) return bochsvga_set_window(vmode_g, window, val); return stdvga_set_window(vmode_g, window, val); }
int vgahw_get_linelength(struct vgamode_s *vmode_g) { - if (CONFIG_VGA_CIRRUS) + if (CONFIG_VGA_CIRRUS && CirrusDetected) return clext_get_linelength(vmode_g); - if (CONFIG_VGA_BOCHS) + if (CONFIG_VGA_BOCHS && BochsDetected) return bochsvga_get_linelength(vmode_g); return stdvga_get_linelength(vmode_g); }
int vgahw_set_linelength(struct vgamode_s *vmode_g, int val) { - if (CONFIG_VGA_CIRRUS) + if (CONFIG_VGA_CIRRUS && CirrusDetected) return clext_set_linelength(vmode_g, val); - if (CONFIG_VGA_BOCHS) + if (CONFIG_VGA_BOCHS && BochsDetected) return bochsvga_set_linelength(vmode_g, val); return stdvga_set_linelength(vmode_g, val); }
int vgahw_get_displaystart(struct vgamode_s *vmode_g) { - if (CONFIG_VGA_CIRRUS) + if (CONFIG_VGA_CIRRUS && CirrusDetected) return clext_get_displaystart(vmode_g); - if (CONFIG_VGA_BOCHS) + if (CONFIG_VGA_BOCHS && BochsDetected) return bochsvga_get_displaystart(vmode_g); return stdvga_get_displaystart(vmode_g); }
int vgahw_set_displaystart(struct vgamode_s *vmode_g, int val) { - if (CONFIG_VGA_CIRRUS) + if (CONFIG_VGA_CIRRUS && CirrusDetected) return clext_set_displaystart(vmode_g, val); - if (CONFIG_VGA_BOCHS) + if (CONFIG_VGA_BOCHS && BochsDetected) return bochsvga_set_displaystart(vmode_g, val); return stdvga_set_displaystart(vmode_g, val); }
int vgahw_get_dacformat(struct vgamode_s *vmode_g) { - if (CONFIG_VGA_BOCHS) + if (CONFIG_VGA_BOCHS && BochsDetected) return bochsvga_get_dacformat(vmode_g); return stdvga_get_dacformat(vmode_g); }
int vgahw_set_dacformat(struct vgamode_s *vmode_g, int val) { - if (CONFIG_VGA_BOCHS) + if (CONFIG_VGA_BOCHS && BochsDetected) return bochsvga_set_dacformat(vmode_g, val); return stdvga_set_dacformat(vmode_g, val); }
int vgahw_size_state(int states) { - if (CONFIG_VGA_CIRRUS) + if (CONFIG_VGA_CIRRUS && CirrusDetected) return clext_size_state(states); - if (CONFIG_VGA_BOCHS) + if (CONFIG_VGA_BOCHS && BochsDetected) return bochsvga_size_state(states); return stdvga_size_state(states); }
int vgahw_save_state(u16 seg, void *data, int states) { - if (CONFIG_VGA_CIRRUS) + if (CONFIG_VGA_CIRRUS && CirrusDetected) return clext_save_state(seg, data, states); - if (CONFIG_VGA_BOCHS) + if (CONFIG_VGA_BOCHS && BochsDetected) return bochsvga_save_state(seg, data, states); return stdvga_save_state(seg, data, states); }
int vgahw_restore_state(u16 seg, void *data, int states) { - if (CONFIG_VGA_CIRRUS) + if (CONFIG_VGA_CIRRUS && CirrusDetected) return clext_restore_state(seg, data, states); - if (CONFIG_VGA_BOCHS) + if (CONFIG_VGA_BOCHS && BochsDetected) return bochsvga_restore_state(seg, data, states); return stdvga_restore_state(seg, data, states); }
On Wed, Sep 04, 2013 at 12:00:23PM +0200, Gerd Hoffmann wrote:
Happens in case a vga with bochs interface lives behind a pci bridge. stdvga ports are passed through with vgasnoop enabled, bochs interface ports are not. Better fallback to stdvga (so text mode works as usual) rather than bailing out.
If bochsvga needs to fallback to stdvga, then I think that should be done in bochsvga.c, not in the vgahw layer.
-Kevin