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

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

unix.superglobalmegacorp.com

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