~ubuntu-branches/ubuntu/precise/seabios/precise-updates

« back to all changes in this revision

Viewing changes to src/bootsplash.c

  • Committer: Bazaar Package Importer
  • Author(s): Serge Hallyn
  • Date: 2010-10-22 11:04:31 UTC
  • Revision ID: james.westby@ubuntu.com-20101022110431-fnfj73ra6xkq623n
Tags: 0.6.0-0ubuntu2
Add all patches which were included in qemu-0.13.0-rc2 (per
commit on Jul 13, 2010).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
}