|
|
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 root 15:
16:
17: /****************************************************************
18: * VESA structures
19: ****************************************************************/
20:
1.1.1.2 root 21: struct vesa_info {
22: u32 vesa_signature;
1.1 root 23: u16 vesa_version;
1.1.1.2 root 24: struct segoff_s oem_string_ptr;
1.1 root 25: u8 capabilities[4];
1.1.1.2 root 26: struct segoff_s video_mode_ptr;
1.1 root 27: u16 total_memory;
28: u16 oem_software_rev;
1.1.1.2 root 29: struct segoff_s oem_vendor_name_ptr;
30: struct segoff_s oem_product_name_ptr;
31: struct segoff_s oem_product_rev_ptr;
1.1 root 32: u8 reserved[222];
33: u8 oem_data[256];
34: } PACKED;
35:
1.1.1.2 root 36: #define VESA_SIGNATURE 0x41534556 // VESA
37: #define VBE2_SIGNATURE 0x32454256 // VBE2
38:
39: struct vesa_mode_info {
1.1 root 40: u16 mode_attributes;
41: u8 win_a_attributes;
42: u8 win_b_attributes;
43: u16 win_granularity;
44: u16 win_size;
45: u16 win_a_segment;
46: u16 win_b_segment;
47: u32 win_func_ptr;
48: u16 bytes_per_scanline;
49: u16 x_resolution;
50: u16 y_resolution;
51: u8 x_charsize;
52: u8 y_charsize;
53: u8 number_of_planes;
54: u8 bits_per_pixel;
55: u8 number_of_banks;
56: u8 memory_model;
57: u8 bank_size;
58: u8 number_of_image_pages;
59: u8 reserved_page;
60: u8 red_mask_size;
61: u8 red_mask_pos;
62: u8 green_mask_size;
63: u8 green_mask_pos;
64: u8 blue_mask_size;
65: u8 blue_mask_pos;
66: u8 reserved_mask_size;
67: u8 reserved_mask_pos;
68: u8 direct_color_mode_info;
1.1.1.2 root 69: void *phys_base_ptr;
1.1 root 70: u32 offscreen_mem_offset;
71: u16 offscreen_mem_size;
72: u8 reserved[206];
73: } PACKED;
74:
1.1.1.2 root 75:
1.1 root 76: /****************************************************************
77: * Helper functions
78: ****************************************************************/
79:
1.1.1.2 root 80: // Call int10 vga handler.
81: static void
82: call16_int10(struct bregs *br)
83: {
84: br->flags = F_IF;
85: start_preempt();
86: call16_int(0x10, br);
87: finish_preempt();
88: }
89:
90:
1.1 root 91: /****************************************************************
92: * VGA text / graphics console
93: ****************************************************************/
1.1.1.2 root 94:
95: void
96: enable_vga_console(void)
1.1 root 97: {
98: dprintf(1, "Turning on vga text mode console\n");
99: struct bregs br;
100:
101: /* Enable VGA text mode */
102: memset(&br, 0, sizeof(br));
103: br.ax = 0x0003;
1.1.1.2 root 104: call16_int10(&br);
105:
106: // Write to screen.
107: printf("SeaBIOS (version %s)\n\n", VERSION);
108: }
1.1 root 109:
1.1.1.2 root 110: static int
111: find_videomode(struct vesa_info *vesa_info, struct vesa_mode_info *mode_info
112: , int width, int height)
113: {
114: dprintf(3, "Finding vesa mode with dimensions %d/%d\n", width, height);
115: u16 *videomodes = SEGOFF_TO_FLATPTR(vesa_info->video_mode_ptr);
116: for (;; videomodes++) {
117: u16 videomode = *videomodes;
118: if (videomode == 0xffff) {
119: dprintf(1, "Unable to find vesa video mode dimensions %d/%d\n"
120: , width, height);
121: return -1;
122: }
123: struct bregs br;
1.1 root 124: memset(&br, 0, sizeof(br));
1.1.1.2 root 125: br.ax = 0x4f01;
126: br.cx = (1 << 14) | videomode;
127: br.di = FLATPTR_TO_OFFSET(mode_info);
128: br.es = FLATPTR_TO_SEG(mode_info);
129: call16_int10(&br);
130: if (br.ax != 0x4f) {
131: dprintf(1, "get_mode failed.\n");
132: continue;
133: }
134: if (mode_info->x_resolution != width
135: || mode_info->y_resolution != height)
136: continue;
137: u8 depth = mode_info->bits_per_pixel;
138: if (depth != 16 && depth != 24 && depth != 32)
139: continue;
140: return videomode;
1.1 root 141: }
142: }
143:
1.1.1.2 root 144: static int BootsplashActive;
145:
146: void
147: enable_bootsplash(void)
1.1 root 148: {
1.1.1.2 root 149: if (!CONFIG_BOOTSPLASH)
1.1 root 150: return;
1.1.1.2 root 151: dprintf(3, "Checking for bootsplash\n");
1.1.1.3 ! root 152: int filesize;
! 153: u8 *filedata = romfile_loadfile("bootsplash.jpg", &filesize);
! 154: if (!filedata)
1.1.1.2 root 155: return;
1.1 root 156:
1.1.1.2 root 157: u8 *picture = NULL;
158: struct vesa_info *vesa_info = malloc_tmplow(sizeof(*vesa_info));
159: struct vesa_mode_info *mode_info = malloc_tmplow(sizeof(*mode_info));
160: struct jpeg_decdata *jpeg = jpeg_alloc();
1.1.1.3 ! root 161: if (!jpeg || !vesa_info || !mode_info) {
1.1.1.2 root 162: warn_noalloc();
163: goto done;
164: }
1.1 root 165:
166: /* Check whether we have a VESA 2.0 compliant BIOS */
167: memset(vesa_info, 0, sizeof(struct vesa_info));
1.1.1.2 root 168: vesa_info->vesa_signature = VBE2_SIGNATURE;
169: struct bregs br;
1.1 root 170: memset(&br, 0, sizeof(br));
171: br.ax = 0x4f00;
172: br.di = FLATPTR_TO_OFFSET(vesa_info);
173: br.es = FLATPTR_TO_SEG(vesa_info);
1.1.1.2 root 174: call16_int10(&br);
175: if (vesa_info->vesa_signature != VESA_SIGNATURE) {
1.1 root 176: dprintf(1,"No VBE2 found.\n");
1.1.1.2 root 177: goto done;
1.1 root 178: }
179:
180: /* Print some debugging information about our card. */
1.1.1.2 root 181: char *vendor = SEGOFF_TO_FLATPTR(vesa_info->oem_vendor_name_ptr);
182: char *product = SEGOFF_TO_FLATPTR(vesa_info->oem_product_name_ptr);
183: dprintf(3, "VESA %d.%d\nVENDOR: %s\nPRODUCT: %s\n",
184: vesa_info->vesa_version>>8, vesa_info->vesa_version&0xff,
185: vendor, product);
186:
187: // Parse jpeg and get image size.
188: dprintf(5, "Decoding bootsplash.jpg\n");
189: int ret = jpeg_decode(jpeg, filedata);
190: if (ret) {
191: dprintf(1, "jpeg_decode failed with return code %d...\n", ret);
192: goto done;
1.1 root 193: }
1.1.1.2 root 194: int width, height;
195: jpeg_get_size(jpeg, &width, &height);
1.1 root 196:
1.1.1.2 root 197: // Try to find a graphics mode with the corresponding dimensions.
198: int videomode = find_videomode(vesa_info, mode_info, width, height);
199: if (videomode < 0)
200: goto done;
201: void *framebuffer = mode_info->phys_base_ptr;
202: int depth = mode_info->bits_per_pixel;
203: dprintf(3, "mode: %04x\n", videomode);
204: dprintf(3, "framebuffer: %p\n", framebuffer);
205: dprintf(3, "bytes per scanline: %d\n", mode_info->bytes_per_scanline);
206: dprintf(3, "bits per pixel: %d\n", depth);
207:
208: // Allocate space for image and decompress it.
209: int imagesize = width * height * (depth / 8);
210: picture = malloc_tmphigh(imagesize);
211: if (!picture) {
212: warn_noalloc();
213: goto done;
1.1 root 214: }
1.1.1.2 root 215: dprintf(5, "Decompressing bootsplash.jpg\n");
216: ret = jpeg_show(jpeg, picture, width, height, depth);
1.1 root 217: if (ret) {
1.1.1.2 root 218: dprintf(1, "jpeg_show failed with return code %d...\n", ret);
219: goto done;
1.1 root 220: }
221:
1.1.1.2 root 222: /* Switch to graphics mode */
223: dprintf(5, "Switching to graphics mode\n");
1.1 root 224: memset(&br, 0, sizeof(br));
1.1.1.2 root 225: br.ax = 0x4f02;
226: br.bx = (1 << 14) | videomode;
227: call16_int10(&br);
1.1 root 228: if (br.ax != 0x4f) {
1.1.1.2 root 229: dprintf(1, "set_mode failed.\n");
230: goto done;
1.1 root 231: }
232:
1.1.1.2 root 233: /* Show the picture */
234: dprintf(5, "Showing bootsplash.jpg\n");
235: iomemcpy(framebuffer, picture, imagesize);
236: dprintf(5, "Bootsplash copy complete\n");
237: BootsplashActive = 1;
238:
239: done:
240: free(filedata);
241: free(picture);
242: free(vesa_info);
243: free(mode_info);
244: free(jpeg);
245: return;
1.1 root 246: }
247:
248: void
249: disable_bootsplash(void)
250: {
1.1.1.2 root 251: if (!CONFIG_BOOTSPLASH || !BootsplashActive)
1.1 root 252: return;
1.1.1.2 root 253: BootsplashActive = 0;
254: enable_vga_console();
1.1 root 255: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.