|
|
1.1 root 1: // Option rom scanning code.
2: //
3: // Copyright (C) 2009-2010 coresystems GmbH
1.1.1.2 root 4: // Copyright (C) 2010 Kevin O'Connor <[email protected]>
1.1 root 5: //
6: // This file may be distributed under the terms of the GNU LGPLv3 license.
7:
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
1.1.1.2 root 13: #include "biosvar.h" // SET_EBDA
14: #include "paravirt.h" // romfile_find
1.1.1.5 ! root 15: #include "vbe.h" // struct vbe_info
1.1.1.4 root 16: #include "bmp.h"
1.1 root 17:
18: /****************************************************************
19: * Helper functions
20: ****************************************************************/
21:
1.1.1.2 root 22: // Call int10 vga handler.
23: static void
24: call16_int10(struct bregs *br)
25: {
26: br->flags = F_IF;
27: start_preempt();
28: call16_int(0x10, br);
29: finish_preempt();
30: }
31:
32:
1.1 root 33: /****************************************************************
34: * VGA text / graphics console
35: ****************************************************************/
1.1.1.2 root 36:
37: void
38: enable_vga_console(void)
1.1 root 39: {
40: dprintf(1, "Turning on vga text mode console\n");
41: struct bregs br;
42:
43: /* Enable VGA text mode */
44: memset(&br, 0, sizeof(br));
45: br.ax = 0x0003;
1.1.1.2 root 46: call16_int10(&br);
47:
48: // Write to screen.
49: printf("SeaBIOS (version %s)\n\n", VERSION);
50: }
1.1 root 51:
1.1.1.2 root 52: static int
1.1.1.5 ! root 53: find_videomode(struct vbe_info *vesa_info, struct vbe_mode_info *mode_info
1.1.1.4 root 54: , int width, int height, int bpp_req)
1.1.1.2 root 55: {
56: dprintf(3, "Finding vesa mode with dimensions %d/%d\n", width, height);
1.1.1.5 ! root 57: u16 *videomodes = SEGOFF_TO_FLATPTR(vesa_info->video_mode);
1.1.1.2 root 58: for (;; videomodes++) {
59: u16 videomode = *videomodes;
60: if (videomode == 0xffff) {
61: dprintf(1, "Unable to find vesa video mode dimensions %d/%d\n"
62: , width, height);
63: return -1;
64: }
65: struct bregs br;
1.1 root 66: memset(&br, 0, sizeof(br));
1.1.1.2 root 67: br.ax = 0x4f01;
68: br.cx = (1 << 14) | videomode;
69: br.di = FLATPTR_TO_OFFSET(mode_info);
70: br.es = FLATPTR_TO_SEG(mode_info);
71: call16_int10(&br);
72: if (br.ax != 0x4f) {
73: dprintf(1, "get_mode failed.\n");
74: continue;
75: }
1.1.1.5 ! root 76: if (mode_info->xres != width
! 77: || mode_info->yres != height)
1.1.1.2 root 78: continue;
79: u8 depth = mode_info->bits_per_pixel;
1.1.1.4 root 80: if (bpp_req == 0) {
81: if (depth != 16 && depth != 24 && depth != 32)
82: continue;
83: } else {
84: if (depth != bpp_req)
85: continue;
86: }
1.1.1.2 root 87: return videomode;
1.1 root 88: }
89: }
90:
1.1.1.2 root 91: static int BootsplashActive;
92:
93: void
94: enable_bootsplash(void)
1.1 root 95: {
1.1.1.2 root 96: if (!CONFIG_BOOTSPLASH)
1.1 root 97: return;
1.1.1.4 root 98: /* splash picture can be bmp or jpeg file */
1.1.1.2 root 99: dprintf(3, "Checking for bootsplash\n");
1.1.1.4 root 100: u8 type = 0; /* 0 means jpg, 1 means bmp, default is 0=jpg */
1.1.1.3 root 101: int filesize;
102: u8 *filedata = romfile_loadfile("bootsplash.jpg", &filesize);
1.1.1.4 root 103: if (!filedata) {
104: filedata = romfile_loadfile("bootsplash.bmp", &filesize);
105: if (!filedata)
106: return;
107: type = 1;
108: }
109: dprintf(3, "start showing bootsplash\n");
1.1 root 110:
1.1.1.4 root 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;
1.1.1.5 ! root 114: struct vbe_info *vesa_info = malloc_tmplow(sizeof(*vesa_info));
! 115: struct vbe_mode_info *mode_info = malloc_tmplow(sizeof(*mode_info));
1.1.1.4 root 116: if (!vesa_info || !mode_info) {
1.1.1.2 root 117: warn_noalloc();
118: goto done;
119: }
1.1 root 120:
121: /* Check whether we have a VESA 2.0 compliant BIOS */
1.1.1.5 ! root 122: memset(vesa_info, 0, sizeof(struct vbe_info));
! 123: vesa_info->signature = VBE2_SIGNATURE;
1.1.1.2 root 124: struct bregs br;
1.1 root 125: memset(&br, 0, sizeof(br));
126: br.ax = 0x4f00;
127: br.di = FLATPTR_TO_OFFSET(vesa_info);
128: br.es = FLATPTR_TO_SEG(vesa_info);
1.1.1.2 root 129: call16_int10(&br);
1.1.1.5 ! root 130: if (vesa_info->signature != VESA_SIGNATURE) {
1.1 root 131: dprintf(1,"No VBE2 found.\n");
1.1.1.2 root 132: goto done;
1.1 root 133: }
134:
135: /* Print some debugging information about our card. */
1.1.1.5 ! root 136: char *vendor = SEGOFF_TO_FLATPTR(vesa_info->oem_vendor_string);
! 137: char *product = SEGOFF_TO_FLATPTR(vesa_info->oem_product_string);
1.1.1.2 root 138: dprintf(3, "VESA %d.%d\nVENDOR: %s\nPRODUCT: %s\n",
1.1.1.5 ! root 139: vesa_info->version>>8, vesa_info->version&0xff,
1.1.1.2 root 140: vendor, product);
141:
1.1.1.4 root 142: int ret, width, height;
143: int bpp_require = 0;
144: if (type == 0) {
145: jpeg = jpeg_alloc();
146: if (!jpeg) {
147: warn_noalloc();
148: goto done;
149: }
150: /* Parse jpeg and get image size. */
151: dprintf(5, "Decoding bootsplash.jpg\n");
152: ret = jpeg_decode(jpeg, filedata);
153: if (ret) {
154: dprintf(1, "jpeg_decode failed with return code %d...\n", ret);
155: goto done;
156: }
157: jpeg_get_size(jpeg, &width, &height);
158: } else {
159: bmp = bmp_alloc();
160: if (!bmp) {
161: warn_noalloc();
162: goto done;
163: }
164: /* Parse bmp and get image size. */
165: dprintf(5, "Decoding bootsplash.bmp\n");
166: ret = bmp_decode(bmp, filedata, filesize);
167: if (ret) {
168: dprintf(1, "bmp_decode failed with return code %d...\n", ret);
169: goto done;
170: }
171: bmp_get_size(bmp, &width, &height);
172: bpp_require = 24;
1.1 root 173: }
1.1.1.4 root 174: /* jpeg would use 16 or 24 bpp video mode, BMP use 24bpp mode only */
1.1 root 175:
1.1.1.2 root 176: // Try to find a graphics mode with the corresponding dimensions.
1.1.1.4 root 177: int videomode = find_videomode(vesa_info, mode_info, width, height,
178: bpp_require);
179: if (videomode < 0) {
180: dprintf(1, "failed to find a videomode with %dx%d %dbpp (0=any).\n",
181: width, height, bpp_require);
1.1.1.2 root 182: goto done;
1.1.1.4 root 183: }
1.1.1.5 ! root 184: void *framebuffer = (void *)mode_info->phys_base;
1.1.1.2 root 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);
190:
191: // Allocate space for image and decompress it.
1.1.1.4 root 192: int imagesize = height * mode_info->bytes_per_scanline;
1.1.1.2 root 193: picture = malloc_tmphigh(imagesize);
194: if (!picture) {
195: warn_noalloc();
196: goto done;
1.1 root 197: }
1.1.1.4 root 198:
199: if (type == 0) {
200: dprintf(5, "Decompressing bootsplash.jpg\n");
201: ret = jpeg_show(jpeg, picture, width, height, depth,
202: mode_info->bytes_per_scanline);
203: if (ret) {
204: dprintf(1, "jpeg_show failed with return code %d...\n", ret);
205: goto done;
206: }
207: } else {
208: dprintf(5, "Decompressing bootsplash.bmp\n");
209: ret = bmp_show(bmp, picture, width, height, depth,
210: mode_info->bytes_per_scanline);
211: if (ret) {
212: dprintf(1, "bmp_show failed with return code %d...\n", ret);
213: goto done;
214: }
1.1 root 215: }
216:
1.1.1.2 root 217: /* Switch to graphics mode */
218: dprintf(5, "Switching to graphics mode\n");
1.1 root 219: memset(&br, 0, sizeof(br));
1.1.1.2 root 220: br.ax = 0x4f02;
221: br.bx = (1 << 14) | videomode;
222: call16_int10(&br);
1.1 root 223: if (br.ax != 0x4f) {
1.1.1.2 root 224: dprintf(1, "set_mode failed.\n");
225: goto done;
1.1 root 226: }
227:
1.1.1.2 root 228: /* Show the picture */
1.1.1.4 root 229: dprintf(5, "Showing bootsplash picture\n");
1.1.1.2 root 230: iomemcpy(framebuffer, picture, imagesize);
231: dprintf(5, "Bootsplash copy complete\n");
232: BootsplashActive = 1;
233:
234: done:
235: free(filedata);
236: free(picture);
237: free(vesa_info);
238: free(mode_info);
239: free(jpeg);
1.1.1.4 root 240: free(bmp);
1.1.1.2 root 241: return;
1.1 root 242: }
243:
244: void
245: disable_bootsplash(void)
246: {
1.1.1.2 root 247: if (!CONFIG_BOOTSPLASH || !BootsplashActive)
1.1 root 248: return;
1.1.1.2 root 249: BootsplashActive = 0;
250: enable_vga_console();
1.1 root 251: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.