Annotation of qemu/roms/seabios/src/bootsplash.c, revision 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.