1 // Option rom scanning code.
3 // Copyright (C) 2009-2010 coresystems GmbH
4 // Copyright (C) 2010 Kevin O'Connor <kevin@koconnor.net>
6 // This file may be distributed under the terms of the GNU LGPLv3 license.
8 #include "bregs.h" // struct bregs
9 #include "farptr.h" // FLATPTR_TO_SEG
10 #include "config.h" // CONFIG_*
11 #include "util.h" // dprintf
12 #include "jpeg.h" // splash
13 #include "biosvar.h" // SET_EBDA
14 #include "paravirt.h" // romfile_find
15 #include "vbe.h" // struct vbe_info
18 /****************************************************************
20 ****************************************************************/
22 // Call int10 vga handler.
24 call16_int10(struct bregs *br)
33 /****************************************************************
34 * VGA text / graphics console
35 ****************************************************************/
38 enable_vga_console(void)
40 dprintf(1, "Turning on vga text mode console\n");
43 /* Enable VGA text mode */
44 memset(&br, 0, sizeof(br));
49 printf("SeaBIOS (version %s)\n\n", VERSION);
53 find_videomode(struct vbe_info *vesa_info, struct vbe_mode_info *mode_info
54 , int width, int height, int bpp_req)
56 dprintf(3, "Finding vesa mode with dimensions %d/%d\n", width, height);
57 u16 *videomodes = SEGOFF_TO_FLATPTR(vesa_info->video_mode);
58 for (;; videomodes++) {
59 u16 videomode = *videomodes;
60 if (videomode == 0xffff) {
61 dprintf(1, "Unable to find vesa video mode dimensions %d/%d\n"
66 memset(&br, 0, sizeof(br));
68 br.cx = (1 << 14) | videomode;
69 br.di = FLATPTR_TO_OFFSET(mode_info);
70 br.es = FLATPTR_TO_SEG(mode_info);
73 dprintf(1, "get_mode failed.\n");
76 if (mode_info->xres != width
77 || mode_info->yres != height)
79 u8 depth = mode_info->bits_per_pixel;
81 if (depth != 16 && depth != 24 && depth != 32)
91 static int BootsplashActive;
94 enable_bootsplash(void)
96 if (!CONFIG_BOOTSPLASH)
98 /* splash picture can be bmp or jpeg file */
99 dprintf(3, "Checking for bootsplash\n");
100 u8 type = 0; /* 0 means jpg, 1 means bmp, default is 0=jpg */
102 u8 *filedata = romfile_loadfile("bootsplash.jpg", &filesize);
104 filedata = romfile_loadfile("bootsplash.bmp", &filesize);
109 dprintf(3, "start showing bootsplash\n");
111 u8 *picture = NULL; /* data buff used to be flushed to the video buf */
112 struct jpeg_decdata *jpeg = NULL;
113 struct bmp_decdata *bmp = NULL;
114 struct vbe_info *vesa_info = malloc_tmplow(sizeof(*vesa_info));
115 struct vbe_mode_info *mode_info = malloc_tmplow(sizeof(*mode_info));
116 if (!vesa_info || !mode_info) {
121 /* Check whether we have a VESA 2.0 compliant BIOS */
122 memset(vesa_info, 0, sizeof(struct vbe_info));
123 vesa_info->signature = VBE2_SIGNATURE;
125 memset(&br, 0, sizeof(br));
127 br.di = FLATPTR_TO_OFFSET(vesa_info);
128 br.es = FLATPTR_TO_SEG(vesa_info);
130 if (vesa_info->signature != VESA_SIGNATURE) {
131 dprintf(1,"No VBE2 found.\n");
135 /* Print some debugging information about our card. */
136 char *vendor = SEGOFF_TO_FLATPTR(vesa_info->oem_vendor_string);
137 char *product = SEGOFF_TO_FLATPTR(vesa_info->oem_product_string);
138 dprintf(3, "VESA %d.%d\nVENDOR: %s\nPRODUCT: %s\n",
139 vesa_info->version>>8, vesa_info->version&0xff,
142 int ret, width, height;
150 /* Parse jpeg and get image size. */
151 dprintf(5, "Decoding bootsplash.jpg\n");
152 ret = jpeg_decode(jpeg, filedata);
154 dprintf(1, "jpeg_decode failed with return code %d...\n", ret);
157 jpeg_get_size(jpeg, &width, &height);
164 /* Parse bmp and get image size. */
165 dprintf(5, "Decoding bootsplash.bmp\n");
166 ret = bmp_decode(bmp, filedata, filesize);
168 dprintf(1, "bmp_decode failed with return code %d...\n", ret);
171 bmp_get_size(bmp, &width, &height);
174 /* jpeg would use 16 or 24 bpp video mode, BMP use 24bpp mode only */
176 // Try to find a graphics mode with the corresponding dimensions.
177 int videomode = find_videomode(vesa_info, mode_info, width, height,
180 dprintf(1, "failed to find a videomode with %dx%d %dbpp (0=any).\n",
181 width, height, bpp_require);
184 void *framebuffer = (void *)mode_info->phys_base;
185 int depth = mode_info->bits_per_pixel;
186 dprintf(3, "mode: %04x\n", videomode);
187 dprintf(3, "framebuffer: %p\n", framebuffer);
188 dprintf(3, "bytes per scanline: %d\n", mode_info->bytes_per_scanline);
189 dprintf(3, "bits per pixel: %d\n", depth);
191 // Allocate space for image and decompress it.
192 int imagesize = height * mode_info->bytes_per_scanline;
193 picture = malloc_tmphigh(imagesize);
200 dprintf(5, "Decompressing bootsplash.jpg\n");
201 ret = jpeg_show(jpeg, picture, width, height, depth,
202 mode_info->bytes_per_scanline);
204 dprintf(1, "jpeg_show failed with return code %d...\n", ret);
208 dprintf(5, "Decompressing bootsplash.bmp\n");
209 ret = bmp_show(bmp, picture, width, height, depth,
210 mode_info->bytes_per_scanline);
212 dprintf(1, "bmp_show failed with return code %d...\n", ret);
217 /* Switch to graphics mode */
218 dprintf(5, "Switching to graphics mode\n");
219 memset(&br, 0, sizeof(br));
221 br.bx = (1 << 14) | videomode;
224 dprintf(1, "set_mode failed.\n");
228 /* Show the picture */
229 dprintf(5, "Showing bootsplash picture\n");
230 iomemcpy(framebuffer, picture, imagesize);
231 dprintf(5, "Bootsplash copy complete\n");
232 BootsplashActive = 1;
245 disable_bootsplash(void)
247 if (!CONFIG_BOOTSPLASH || !BootsplashActive)
249 BootsplashActive = 0;
250 enable_vga_console();