|
|
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.