Annotation of qemu/roms/seabios/src/bootsplash.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.