|
|
1.1 root 1: // Option rom scanning code.
2: //
3: // Copyright (C) 2009-2010 coresystems GmbH
4: //
5: // This file may be distributed under the terms of the GNU LGPLv3 license.
6:
7: #include "bregs.h" // struct bregs
8: #include "farptr.h" // FLATPTR_TO_SEG
9: #include "config.h" // CONFIG_*
10: #include "util.h" // dprintf
11: #include "jpeg.h" // splash
12:
13: /****************************************************************
14: * Definitions
15: ****************************************************************/
16:
17: /****************************************************************
18: * VESA structures
19: ****************************************************************/
20:
21: struct vesa_info
22: {
23: u8 vesa_signature[4];
24: u16 vesa_version;
25: u32 oem_string_ptr;
26: u8 capabilities[4];
27: u32 video_mode_ptr;
28: u16 total_memory;
29: u16 oem_software_rev;
30: u32 oem_vendor_name_ptr;
31: u32 oem_product_name_ptr;
32: u32 oem_product_rev_ptr;
33: u8 reserved[222];
34: u8 oem_data[256];
35: } PACKED;
36:
37: struct vesa_mode_info
38: {
39: u16 mode_attributes;
40: u8 win_a_attributes;
41: u8 win_b_attributes;
42: u16 win_granularity;
43: u16 win_size;
44: u16 win_a_segment;
45: u16 win_b_segment;
46: u32 win_func_ptr;
47: u16 bytes_per_scanline;
48: u16 x_resolution;
49: u16 y_resolution;
50: u8 x_charsize;
51: u8 y_charsize;
52: u8 number_of_planes;
53: u8 bits_per_pixel;
54: u8 number_of_banks;
55: u8 memory_model;
56: u8 bank_size;
57: u8 number_of_image_pages;
58: u8 reserved_page;
59: u8 red_mask_size;
60: u8 red_mask_pos;
61: u8 green_mask_size;
62: u8 green_mask_pos;
63: u8 blue_mask_size;
64: u8 blue_mask_pos;
65: u8 reserved_mask_size;
66: u8 reserved_mask_pos;
67: u8 direct_color_mode_info;
68: u32 phys_base_ptr;
69: u32 offscreen_mem_offset;
70: u16 offscreen_mem_size;
71: u8 reserved[206];
72: } PACKED;
73:
74: /****************************************************************
75: * Helper functions
76: ****************************************************************/
77:
78: /****************************************************************
79: * VGA text / graphics console
80: ****************************************************************/
81: static void enable_vga_text_console(void)
82: {
83: dprintf(1, "Turning on vga text mode console\n");
84: struct bregs br;
85:
86: /* Enable VGA text mode */
87: memset(&br, 0, sizeof(br));
88: br.flags = F_IF;
89: br.ax = 0x0003;
90: start_preempt();
91: call16_int(0x10, &br);
92: finish_preempt();
93:
94: if (CONFIG_BOOTSPLASH) {
95: /* Switch back to start of the framebuffer
96: * (disable "double buffering")
97: */
98: memset(&br, 0, sizeof(br));
99: br.flags = F_IF;
100: br.ax = 0x4f07;
101: br.bl = 0x02;
102: br.ecx = 0;
103:
104: start_preempt();
105: call16_int(0x10, &br);
106: finish_preempt();
107: }
108:
109: // Write to screen.
110: printf("Starting SeaBIOS (version %s)\n\n", VERSION);
111: }
112:
113: void enable_vga_console(void)
114: {
115: /* Needs coreboot support for CBFS */
116: if (!CONFIG_BOOTSPLASH || !CONFIG_COREBOOT) {
117: enable_vga_text_console();
118: return;
119: }
120:
121: struct bregs br;
122: struct vesa_info *vesa_info;
123: struct vesa_mode_info *mode_info;
124: struct jpeg_decdata *decdata;
125:
126: vesa_info = malloc_tmphigh(sizeof(*vesa_info));
127: mode_info = malloc_tmphigh(sizeof(*mode_info));
128: decdata = malloc_tmphigh(sizeof(*decdata));
129:
130: /* Check whether we have a VESA 2.0 compliant BIOS */
131: memset(vesa_info, 0, sizeof(struct vesa_info));
132: memcpy(vesa_info, "VBE2", 4);
133:
134: memset(&br, 0, sizeof(br));
135: br.flags = F_IF;
136: br.ax = 0x4f00;
137: br.di = FLATPTR_TO_OFFSET(vesa_info);
138: br.es = FLATPTR_TO_SEG(vesa_info);
139: start_preempt();
140: call16_int(0x10, &br);
141: finish_preempt();
142:
143: if(strcmp("VESA", (char *)vesa_info) != 0) {
144: dprintf(1,"No VBE2 found.\n");
145: goto cleanup;
146: }
147:
148: /* Print some debugging information about our card. */
149: char *vendor, *product;
150: vendor = (char *)(((vesa_info->oem_vendor_name_ptr & 0xffff0000) >> 12) |
151: (vesa_info->oem_vendor_name_ptr & 0xffff));
152:
153: product = (char *)(((vesa_info->oem_product_name_ptr & 0xffff0000) >> 12) |
154: (vesa_info->oem_product_name_ptr & 0xffff));
155:
156: dprintf(8, "VESA %d.%d\nVENDOR: %s\nPRODUCT: %s\n",
157: vesa_info->vesa_version>>8,vesa_info->vesa_version&0xff,
158: vendor, product);
159:
160: /* Get information about our graphics mode, like the
161: * framebuffer start address
162: */
163: memset(&br, 0, sizeof(br));
164: br.flags = F_IF;
165: br.ax = 0x4f01;
166: br.cx = (1 << 14) | CONFIG_BOOTSPLASH_VESA_MODE;
167: br.di = FLATPTR_TO_OFFSET(mode_info);
168: br.es = FLATPTR_TO_SEG(mode_info);
169: start_preempt();
170: call16_int(0x10, &br);
171: finish_preempt();
172: if (br.ax != 0x4f) {
173: dprintf(1, "get_mode failed.\n");
174: enable_vga_text_console();
175: goto cleanup;
176: }
177: unsigned char *framebuffer = (unsigned char *) (mode_info->phys_base_ptr);
178:
179: /* Switch to graphics mode */
180: memset(&br, 0, sizeof(br));
181: br.flags = F_IF;
182: br.ax = 0x4f02;
183: br.bx = (1 << 14) | CONFIG_BOOTSPLASH_VESA_MODE;
184: start_preempt();
185: call16_int(0x10, &br);
186: finish_preempt();
187: if (br.ax != 0x4f) {
188: dprintf(1, "set_mode failed.\n");
189: enable_vga_text_console();
190: goto cleanup;
191: }
192:
193: /* Switching Intel IGD to 1MB video memory will break this. Who cares. */
194: int imagesize = CONFIG_BOOTSPLASH_X * CONFIG_BOOTSPLASH_Y *
195: (CONFIG_BOOTSPLASH_DEPTH / 8);
196:
197: /* We use "double buffering" to make things look nicer */
198: framebuffer += imagesize;
199:
200: dprintf(9, "framebuffer: %x\n", (u32)framebuffer);
201: dprintf(9, "bytes per scanline: %d\n", mode_info->bytes_per_scanline);
202: dprintf(9, "bits per pixel: %d\n", mode_info->bits_per_pixel);
203:
204: /* Look for bootsplash.jpg in CBFS and decompress it... */
205: int ret = 0;
206: unsigned char *jpeg = NULL;
207:
208: struct cbfs_file *file = cbfs_finddatafile("bootsplash.jpg");
209: int filesize = 0;
210:
211: if (file) {
212: filesize = cbfs_datasize(file);
213: jpeg = malloc_tmphigh(filesize);
214: } else {
215: dprintf(1, "Could not find boot splash screen \"bootsplash.jpg\"\n");
216: }
217: if(jpeg) {
218: dprintf(9, "Copying boot splash screen...\n");
219: cbfs_copyfile(file, jpeg, filesize);
220: dprintf(9, "Decompressing boot splash screen...\n");
221: start_preempt();
222: ret = jpeg_decode(jpeg, framebuffer, CONFIG_BOOTSPLASH_X,
223: CONFIG_BOOTSPLASH_Y, CONFIG_BOOTSPLASH_DEPTH, decdata);
224: finish_preempt();
225: if (ret)
226: dprintf(1, "Failed with return code %x...\n", ret);
227: } else {
228: ret = -1;
229: }
230: free(jpeg);
231: if (ret) {
232: enable_vga_text_console();
233: goto cleanup;
234: }
235:
236: /* Show the picture */
237: memset(&br, 0, sizeof(br));
238: br.flags = F_IF;
239: br.ax = 0x4f07;
240: br.bl = 0x02;
241: br.ecx = imagesize;
242: start_preempt();
243: call16_int(0x10, &br);
244: finish_preempt();
245: if (br.ax != 0x4f) {
246: dprintf(1, "display_start failed.\n");
247: enable_vga_text_console();
248: }
249:
250: cleanup:
251: free (vesa_info);
252: free (mode_info);
253: free (decdata);
254: }
255:
256: void
257: disable_bootsplash(void)
258: {
259: if (! CONFIG_BOOTSPLASH)
260: return;
261: enable_vga_text_console();
262: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.