[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 1/2][v2][BIOS] Add splash image support
From: |
Laurent Vivier |
Subject: |
[Qemu-devel] [PATCH 1/2][v2][BIOS] Add splash image support |
Date: |
Thu, 18 Dec 2008 15:51:36 +0100 |
This patch adds Qemu firmware configuration device interface to display
a splash image at BIOS startup.
Idea stollen from VirtualBox.
Signed-off-by: Laurent Vivier <address@hidden>
---
bios/Makefile | 4 +-
bios/rombios.c | 142 ++++++++++++++++++++++++++++++++++++-------------------
bios/splash.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
bios/splash.h | 32 ++++++++++++
4 files changed, 271 insertions(+), 51 deletions(-)
create mode 100644 bios/splash.c
create mode 100644 bios/splash.h
Changelog:
v2: totally remove code from VirtualBox to not bring GPLv2 to bios.
diff --git a/bios/Makefile b/bios/Makefile
index a2759a9..605d31f 100644
--- a/bios/Makefile
+++ b/bios/Makefile
@@ -79,7 +79,7 @@ dist-clean: clean
bios-clean:
rm -f BIOS-bochs-*
-BIOS-bochs-legacy: rombios.c apmbios.S biossums rombios.h
+BIOS-bochs-legacy: rombios.c apmbios.S biossums rombios.h splash.c splash.h
$(GCC) $(BIOS_BUILD_DATE) -DLEGACY -E -P $< > _rombiosl_.c
$(BCC) -o rombiosl.s -C-c -D__i86__ -0 -S _rombiosl_.c
sed -e 's/^\.text//' -e 's/^\.data//' rombiosl.s > _rombiosl_.s
@@ -90,7 +90,7 @@ BIOS-bochs-legacy: rombios.c apmbios.S biossums rombios.h
rm -f _rombiosl_.s
-rombios16.bin: rombios.c apmbios.S biossums rombios.h
+rombios16.bin: rombios.c apmbios.S biossums rombios.h splash.c splash.h
$(GCC) $(BIOS_BUILD_DATE) -E -P $< > _rombios_.c
$(BCC) -o rombios.s -C-c -D__i86__ -0 -S _rombios_.c
sed -e 's/^\.text//' -e 's/^\.data//' rombios.s > _rombios_.s
diff --git a/bios/rombios.c b/bios/rombios.c
index 9a1cdd6..a02b50f 100644
--- a/bios/rombios.c
+++ b/bios/rombios.c
@@ -1433,6 +1433,22 @@ void uart_tx_byte(base_port, data)
#endif
void
+set_video(mode)
+ Bit8u mode;
+{
+ ASM_START
+ push bp
+ mov bp, sp
+
+ mov ah, #0x00
+ mov al, 4[bp]
+ int #0x10
+
+ pop bp
+ ASM_END
+}
+
+ void
wrch(c)
Bit8u c;
{
@@ -1533,6 +1549,8 @@ void put_str(action, segment, offset)
}
}
+#define TICKS_PER_SECONDS 18
+
void
delay_ticks(ticks)
Bit16u ticks;
@@ -1917,6 +1935,10 @@ shutdown_status_panic(status)
BX_PANIC("Unimplemented shutdown status: %02x\n",(Bit8u)status);
}
+#ifdef BX_QEMU
+#include "splash.c"
+#endif
+
//--------------------------------------------------------------------------
// print_bios_banner
// displays a the bios version
@@ -1924,6 +1946,10 @@ shutdown_status_panic(status)
void
print_bios_banner()
{
+#ifdef BX_QEMU
+ if (splash_enabled())
+ return;
+#endif
printf(BX_APPNAME" BIOS - build: %s\n%s\nOptions: ",
BIOS_BUILD_DATE, bios_cvs_version_string);
printf(
@@ -2021,65 +2047,77 @@ interactive_bootkey()
Bit16u ss = get_SS();
Bit16u valid_choice = 0;
+#ifdef BX_QEMU
+ if (splash_enabled()) {
+ Bit16u duration;
+
+ splash_show();
+ duration = splash_duration();
+ if (!check_for_keystroke())
+ delay_ticks_and_check_for_keystroke(TICKS_PER_SECONDS, duration / 1000);
+ splash_hide();
+ if (!splash_display_boot_list())
+ return;
+ } else
+#endif // BX_QEMU
+ {
+ while (check_for_keystroke())
+ get_keystroke();
+ printf("Press F12 for boot menu.\n\n");
+ delay_ticks_and_check_for_keystroke(11, 5); /* ~3 seconds */
+ }
+ if (!check_for_keystroke())
+ return;
+ scan_code = get_keystroke();
+ if (scan_code != 0x58) /* F12 */
+ return;
+
while (check_for_keystroke())
get_keystroke();
- printf("Press F12 for boot menu.\n\n");
+ printf("Select boot device:\n\n");
- delay_ticks_and_check_for_keystroke(11, 5); /* ~3 seconds */
- if (check_for_keystroke())
+ count = read_word(IPL_SEG, IPL_COUNT_OFFSET);
+ for (i = 0; i < count; i++)
{
- scan_code = get_keystroke();
- if (scan_code == 0x58) /* F12 */
+ memcpyb(ss, &e, IPL_SEG, IPL_TABLE_OFFSET + i * sizeof (e), sizeof (e));
+ printf("%d. ", i+1);
+ switch(e.type)
{
- while (check_for_keystroke())
- get_keystroke();
-
- printf("Select boot device:\n\n");
-
- count = read_word(IPL_SEG, IPL_COUNT_OFFSET);
- for (i = 0; i < count; i++)
- {
- memcpyb(ss, &e, IPL_SEG, IPL_TABLE_OFFSET + i * sizeof (e), sizeof
(e));
- printf("%d. ", i+1);
- switch(e.type)
+ case IPL_TYPE_FLOPPY:
+ case IPL_TYPE_HARDDISK:
+ case IPL_TYPE_CDROM:
+ printf("%s\n", drivetypes[e.type]);
+ break;
+ case IPL_TYPE_BEV:
+ printf("%s", drivetypes[4]);
+ if (e.description != 0)
{
- case IPL_TYPE_FLOPPY:
- case IPL_TYPE_HARDDISK:
- case IPL_TYPE_CDROM:
- printf("%s\n", drivetypes[e.type]);
- break;
- case IPL_TYPE_BEV:
- printf("%s", drivetypes[4]);
- if (e.description != 0)
- {
- memcpyb(ss, &description, (Bit16u)(e.description >> 16),
(Bit16u)(e.description & 0xffff), 32);
- description[32] = 0;
- printf(" [%S]", ss, description);
- }
- printf("\n");
- break;
- }
- }
+ memcpyb(ss, &description, (Bit16u)(e.description >> 16),
(Bit16u)(e.description & 0xffff), 32);
+ description[32] = 0;
+ printf(" [%S]", ss, description);
+ }
+ printf("\n");
+ break;
+ }
+ }
- count++;
- while (!valid_choice) {
- scan_code = get_keystroke();
- if (scan_code == 0x01 || scan_code == 0x58) /* ESC or F12 */
- {
- valid_choice = 1;
- }
- else if (scan_code <= count)
- {
- valid_choice = 1;
- scan_code -= 1;
- /* Set user selected device */
- write_word(IPL_SEG, IPL_BOOTFIRST_OFFSET, scan_code);
- }
- }
- printf("\n");
+ count++;
+ while (!valid_choice) {
+ scan_code = get_keystroke();
+ if (scan_code == 0x01 || scan_code == 0x58) /* ESC or F12 */
+ {
+ valid_choice = 1;
+ }
+ else if (scan_code <= count)
+ {
+ valid_choice = 1;
+ scan_code -= 1;
+ /* Set user selected device */
+ write_word(IPL_SEG, IPL_BOOTFIRST_OFFSET, scan_code);
}
}
+ printf("\n");
}
#endif // BX_ELTORITO_BOOT
@@ -2706,6 +2744,9 @@ void ata_detect( )
break;
}
+#ifdef BX_QEMU
+ if (!splash_enabled()) {
+#endif
switch (type) {
case ATA_TYPE_ATA:
printf("ata%d %s: ",channel,slave?" slave":"master");
@@ -2727,6 +2768,9 @@ void ata_detect( )
printf("ata%d %s: Unknown device\n",channel,slave?" slave":"master");
break;
}
+#ifdef BX_QEMU
+ }
+#endif
}
}
diff --git a/bios/splash.c b/bios/splash.c
new file mode 100644
index 0000000..07921b3
--- /dev/null
+++ b/bios/splash.c
@@ -0,0 +1,144 @@
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
USA
+
+#include "splash.h"
+
+#define BIOS_CFG_IOPORT 0x0510
+#define BIOS_CFG_SIGNATURE 0x0000
+#define BIOS_CFG_SPLASH 0x4007
+
+#define SPLASH_VALUE(_field) splash_offset( splash_offsetof(_field), \
+ splash_sizeof(_field) )
+Bit16u
+splash_offset(offset, size)
+ Bit8u offset;
+ Bit8u size;
+{
+ Bit16u word;
+
+ outw(BIOS_CFG_IOPORT, BIOS_CFG_SPLASH);
+ outb(BIOS_CFG_IOPORT + 1, SPLASH_CMD_SET_OFFSET);
+ outb(BIOS_CFG_IOPORT + 1, offset);
+
+ word = inb(BIOS_CFG_IOPORT + 1);
+ if (size == 2)
+ word = (inb(BIOS_CFG_IOPORT + 1) << 8) | word;
+
+ return word;
+}
+
+void
+splash_show_bmp(step)
+ Bit16u step;
+{
+ outw(BIOS_CFG_IOPORT, BIOS_CFG_SPLASH);
+ outb(BIOS_CFG_IOPORT + 1, SPLASH_CMD_SHOW_BMP);
+ outb(BIOS_CFG_IOPORT + 1, step);
+
+ return;
+}
+
+Bit8u
+splash_enabled()
+{
+ Bit8u fadein, fadeout, bootmenu;
+ Bit16u duration;
+
+ /* check QEMU signature */
+
+ outw(BIOS_CFG_IOPORT, BIOS_CFG_SIGNATURE);
+ if (inb(BIOS_CFG_IOPORT + 1) != 'Q')
+ return 0;
+ if (inb(BIOS_CFG_IOPORT + 1) != 'E')
+ return 0;
+ if (inb(BIOS_CFG_IOPORT + 1) != 'M')
+ return 0;
+ if (inb(BIOS_CFG_IOPORT + 1) != 'U')
+ return 0;
+
+ /* check splash signature */
+
+ if (SPLASH_VALUE(signature) != SPLASH_MAGIC)
+ return 0;
+
+ /* Get options */
+
+ fadein = SPLASH_VALUE(fadein);
+ fadeout = SPLASH_VALUE(fadeout);
+ duration = SPLASH_VALUE(duration);
+
+ return (fadein || fadeout || duration);
+}
+
+void
+splash_show()
+{
+ Bit8u fadein;
+ Bit16u i;
+
+ set_video(0x12); /* 640x480 */
+
+ fadein = SPLASH_VALUE(fadein);
+
+ if (fadein)
+ {
+ delay_ticks_and_check_for_keystroke(TICKS_PER_SECONDS / 18, 1);
+ /* "0" means unload image from memory, used in splash_hide() */
+ for (i = 1; !check_for_keystroke() && i < SPLASH_SHOW_STEPS; i++)
+ {
+ splash_show_bmp(i);
+ delay_ticks_and_check_for_keystroke(TICKS_PER_SECONDS / 18, 1);
+ }
+ }
+
+ if (!check_for_keystroke())
+ splash_show_bmp(SPLASH_SHOW_STEPS);
+
+ return;
+}
+
+void
+splash_hide()
+{
+ Bit8u fadeout;
+ Bit16u i;
+
+ fadeout = SPLASH_VALUE(fadeout);
+
+ if (fadeout)
+ {
+ for (i = SPLASH_SHOW_STEPS; !check_for_keystroke() && i > 0 ; i--)
+ {
+ splash_show_bmp(i);
+ delay_ticks_and_check_for_keystroke(TICKS_PER_SECONDS / 18, 1);
+ }
+ }
+ splash_show_bmp(0);
+
+ set_video(0x03); /* text mode */
+
+ return;
+}
+
+Bit8u
+splash_display_boot_list()
+{
+ return SPLASH_VALUE(bootmenu);
+}
+
+Bit16u
+splash_duration()
+{
+ return SPLASH_VALUE(duration);
+}
diff --git a/bios/splash.h b/bios/splash.h
new file mode 100644
index 0000000..1b34978
--- /dev/null
+++ b/bios/splash.h
@@ -0,0 +1,32 @@
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
USA
+
+struct splash_header {
+ Bit16u signature;
+ Bit16u duration;
+ Bit8u fadein;
+ Bit8u fadeout;
+ Bit8u bootmenu;
+ Bit8u pad;
+ Bit32u size;
+};
+
+#define SPLASH_MAGIC 0x66BB
+#define SPLASH_CMD_NOP 0x00
+#define SPLASH_CMD_SET_OFFSET 0x01
+#define SPLASH_CMD_SHOW_BMP 0x02
+#define SPLASH_SHOW_STEPS 16
+
+#define splash_offsetof(_field) (&((struct splash_header *)0)->_field)
+#define splash_sizeof(_field) (sizeof(((struct splash_header *)0)->_field))
--
1.5.6.5