void vbe_set_graphics(void) { u8 rval; vbe_info_t info; rval = vbe_info(&info); if (rval != 0) return; DEBUG_PRINTF_VBE("VbeSignature: %s\n", info.signature); DEBUG_PRINTF_VBE("VbeVersion: 0x%04x\n", info.version); DEBUG_PRINTF_VBE("OemString: %s\n", info.oem_string_ptr); DEBUG_PRINTF_VBE("Capabilities:\n"); DEBUG_PRINTF_VBE("\tDAC: %s\n", (info.capabilities & 0x1) == 0 ? "fixed 6bit" : "switchable 6/8bit"); DEBUG_PRINTF_VBE("\tVGA: %s\n", (info.capabilities & 0x2) == 0 ? "compatible" : "not compatible"); DEBUG_PRINTF_VBE("\tRAMDAC: %s\n", (info.capabilities & 0x4) == 0 ? "normal" : "use blank bit in Function 09h"); mode_info.video_mode = (1 << 14) | CONFIG_FRAMEBUFFER_VESA_MODE; vbe_get_mode_info(&mode_info); vbe_set_mode(&mode_info); #if CONFIG_BOOTSPLASH unsigned char *framebuffer = (unsigned char *) le32_to_cpu(mode_info.vesa.phys_base_ptr); DEBUG_PRINTF_VBE("FRAMEBUFFER: 0x%p\n", framebuffer); struct jpeg_decdata *decdata; /* Switching Intel IGD to 1MB video memory will break this. Who * cares. */ // int imagesize = 1024*768*2; unsigned char *jpeg = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, "bootsplash.jpg", CBFS_TYPE_BOOTSPLASH, NULL); if (!jpeg) { DEBUG_PRINTF_VBE("Could not find bootsplash.jpg\n"); return; } DEBUG_PRINTF_VBE("Splash at %p ...\n", jpeg); dump(jpeg, 64); decdata = malloc(sizeof(*decdata)); int ret = 0; DEBUG_PRINTF_VBE("Decompressing boot splash screen...\n"); ret = jpeg_decode(jpeg, framebuffer, 1024, 768, 16, decdata); DEBUG_PRINTF_VBE("returns %x\n", ret); #endif }
status_t vesa_set_display_mode(vesa_info& info, uint32 mode) { if (mode >= info.shared_info->vesa_mode_count) return B_ENTRY_NOT_FOUND; // Prepare vm86 mode environment struct vm86_state vmState; status_t status = vm86_prepare(&vmState, 0x20000); if (status != B_OK) { dprintf(DEVICE_NAME": vesa_set_display_mode(): vm86_prepare failed\n"); return status; } // Get mode information struct vbe_mode_info modeInfo; status = vbe_get_mode_info(vmState, info.modes[mode].mode, &modeInfo); if (status != B_OK) { dprintf(DEVICE_NAME": vesa_set_display_mode(): cannot get mode info\n"); goto out; } // Set mode status = vbe_set_mode(vmState, info.modes[mode].mode); if (status != B_OK) { dprintf(DEVICE_NAME": vesa_set_display_mode(): cannot set mode\n"); goto out; } if (info.modes[mode].bits_per_pixel <= 8) vbe_set_bits_per_gun(vmState, info, 8); // Map new frame buffer if necessary status = remap_frame_buffer(info, modeInfo.physical_base, modeInfo.width, modeInfo.height, modeInfo.bits_per_pixel, modeInfo.bytes_per_row, false); if (status == B_OK) { // Update shared frame buffer information info.shared_info->current_mode.virtual_width = modeInfo.width; info.shared_info->current_mode.virtual_height = modeInfo.height; info.shared_info->current_mode.space = get_color_space_for_depth( modeInfo.bits_per_pixel); } out: vm86_cleanup(&vmState); return status; }
void *vg_init(unsigned short mode) { vbe_mode_info_t config; if ( vbe_set_mode(VBE_MODE, mode) == 1) //set graphic mode return NULL; if (vbe_get_mode_info(mode, &config) != 0) //get vbe info { return NULL; } h_res = config.XResolution; //store X Resolution v_res = config.YResolution; //store Y Resolution bits_per_pixel = config.BitsPerPixel; //store Bits Per Pixel vram_size = (config.XResolution * config.YResolution * config.BitsPerPixel) / 8; //store the size of the vram int r; struct mem_range mr; /* Allow memory mapping */ mr.mr_base = (config.PhysBasePtr); mr.mr_limit = mr.mr_base + (config.XResolution * config.YResolution * config.BitsPerPixel) / 8; if( OK != (r = sys_privctl(SELF, SYS_PRIV_ADD_MEM, &mr))) panic("video_txt: sys_privctl (ADD_MEM) failed: %d\n", r); /* Map memory */ video_mem = vm_map_phys(SELF, (void *)mr.mr_base, (config.XResolution * config.YResolution * config.BitsPerPixel) / 8); if(video_mem == MAP_FAILED) panic("video_txt couldn't map video memory"); if (video_mem == NULL) { printf("vg_init: Error!\n"); vg_exit(); return NULL; } return config.PhysBasePtr; }
static u32 vbe_get_info(void) { u8 rval; int i; // XXX FIXME these need to be filled with sane values // get a copy of input struct... screen_info_input_t input; // output is pointer to the address passed as argv[4] screen_info_t local_output; screen_info_t *output = &local_output; // zero input memset(&input, 0, sizeof(screen_info_input_t)); // zero output memset(&output, 0, sizeof(screen_info_t)); vbe_info_t info; rval = vbe_info(&info); if (rval != 0) return rval; DEBUG_PRINTF_VBE("VbeSignature: %s\n", info.signature); DEBUG_PRINTF_VBE("VbeVersion: 0x%04x\n", info.version); DEBUG_PRINTF_VBE("OemString: %s\n", info.oem_string_ptr); DEBUG_PRINTF_VBE("Capabilities:\n"); DEBUG_PRINTF_VBE("\tDAC: %s\n", (info.capabilities & 0x1) == 0 ? "fixed 6bit" : "switchable 6/8bit"); DEBUG_PRINTF_VBE("\tVGA: %s\n", (info.capabilities & 0x2) == 0 ? "compatible" : "not compatible"); DEBUG_PRINTF_VBE("\tRAMDAC: %s\n", (info.capabilities & 0x4) == 0 ? "normal" : "use blank bit in Function 09h"); // argv[4] may be a pointer with enough space to return screen_info_t // as input, it must contain a screen_info_input_t with the following content: // byte[0:3] = "DDC\0" (zero-terminated signature header) // byte[4:5] = reserved space for the return struct... just in case we ever change // the struct and don't have reserved enough memory (and let's hope the struct // never gets larger than 64KB) // byte[6] = monitor port number for DDC requests ("only" one byte... so lets hope we never have more than 255 monitors... // byte[7:8] = max. screen width (OF may want to limit this) // byte[9] = required color depth in bpp if (strncmp((char *) input.signature, "DDC", 4) != 0) { printf ("%s: Invalid input signature! expected: %s, is: %s\n", __func__, "DDC", input.signature); return -1; } if (input.size_reserved != sizeof(screen_info_t)) { printf ("%s: Size of return struct is wrong, required: %d, available: %d\n", __func__, (int) sizeof(screen_info_t), input.size_reserved); return -1; } vbe_ddc_info_t ddc_info; ddc_info.port_number = input.monitor_number; vbe_get_ddc_info(&ddc_info); #if 0 DEBUG_PRINTF_VBE("DDC: edid_tranfer_time: %d\n", ddc_info.edid_transfer_time); DEBUG_PRINTF_VBE("DDC: ddc_level: %x\n", ddc_info.ddc_level); DEBUG_PRINTF_VBE("DDC: EDID: \n"); CHECK_DBG(DEBUG_VBE) { dump(ddc_info.edid_block_zero, sizeof(ddc_info.edid_block_zero)); } #endif /* This could fail because of alignment issues, so use a longer form. *((u64 *) ddc_info.edid_block_zero) != (u64) 0x00FFFFFFFFFFFF00ULL */ if (ddc_info.edid_block_zero[0] != 0x00 || ddc_info.edid_block_zero[1] != 0xFF || ddc_info.edid_block_zero[2] != 0xFF || ddc_info.edid_block_zero[3] != 0xFF || ddc_info.edid_block_zero[4] != 0xFF || ddc_info.edid_block_zero[5] != 0xFF || ddc_info.edid_block_zero[6] != 0xFF || ddc_info.edid_block_zero[7] != 0x00 ) { // invalid EDID signature... probably no monitor output->display_type = 0x0; return 0; } else if ((ddc_info.edid_block_zero[20] & 0x80) != 0) { // digital display output->display_type = 2; } else { // analog output->display_type = 1; } DEBUG_PRINTF_VBE("DDC: found display type %d\n", output->display_type); memcpy(output->edid_block_zero, ddc_info.edid_block_zero, sizeof(ddc_info.edid_block_zero)); i = 0; vbe_mode_info_t mode_info; vbe_mode_info_t best_mode_info; // initialize best_mode to 0 memset(&best_mode_info, 0, sizeof(best_mode_info)); while ((mode_info.video_mode = info.video_mode_list[i]) != 0xFFFF) { //DEBUG_PRINTF_VBE("%x: Mode: %04x\n", i, mode_info.video_mode); vbe_get_mode_info(&mode_info); // FIXME all these values are little endian! DEBUG_PRINTF_VBE("Video Mode 0x%04x available, %s\n", mode_info.video_mode, (le16_to_cpu(mode_info.vesa.mode_attributes) & 0x1) == 0 ? "not supported" : "supported"); DEBUG_PRINTF_VBE("\tTTY: %s\n", (le16_to_cpu(mode_info.vesa.mode_attributes) & 0x4) == 0 ? "no" : "yes"); DEBUG_PRINTF_VBE("\tMode: %s %s\n", (le16_to_cpu(mode_info.vesa.mode_attributes) & 0x8) == 0 ? "monochrome" : "color", (le16_to_cpu(mode_info.vesa.mode_attributes) & 0x10) == 0 ? "text" : "graphics"); DEBUG_PRINTF_VBE("\tVGA: %s\n", (le16_to_cpu(mode_info.vesa.mode_attributes) & 0x20) == 0 ? "compatible" : "not compatible"); DEBUG_PRINTF_VBE("\tWindowed Mode: %s\n", (le16_to_cpu(mode_info.vesa.mode_attributes) & 0x40) == 0 ? "yes" : "no"); DEBUG_PRINTF_VBE("\tFramebuffer: %s\n", (le16_to_cpu(mode_info.vesa.mode_attributes) & 0x80) == 0 ? "no" : "yes"); DEBUG_PRINTF_VBE("\tResolution: %dx%d\n", le16_to_cpu(mode_info.vesa.x_resolution), le16_to_cpu(mode_info.vesa.y_resolution)); DEBUG_PRINTF_VBE("\tChar Size: %dx%d\n", mode_info.vesa.x_charsize, mode_info.vesa.y_charsize); DEBUG_PRINTF_VBE("\tColor Depth: %dbpp\n", mode_info.vesa.bits_per_pixel); DEBUG_PRINTF_VBE("\tMemory Model: 0x%x\n", mode_info.vesa.memory_model); DEBUG_PRINTF_VBE("\tFramebuffer Offset: %08x\n", le32_to_cpu(mode_info.vesa.phys_base_ptr)); if ((mode_info.vesa.bits_per_pixel == input.color_depth) && (le16_to_cpu(mode_info.vesa.x_resolution) <= input.max_screen_width) && ((le16_to_cpu(mode_info.vesa.mode_attributes) & 0x80) != 0) // framebuffer mode && ((le16_to_cpu(mode_info.vesa.mode_attributes) & 0x10) != 0) // graphics && ((le16_to_cpu(mode_info.vesa.mode_attributes) & 0x8) != 0) // color && (le16_to_cpu(mode_info.vesa.x_resolution) > le16_to_cpu(best_mode_info.vesa.x_resolution))) // better than previous best_mode { // yiiiihaah... we found a new best mode memcpy(&best_mode_info, &mode_info, sizeof(mode_info)); } i++; } if (best_mode_info.video_mode != 0) { DEBUG_PRINTF_VBE ("Best Video Mode found: 0x%x, %dx%d, %dbpp, framebuffer_address: 0x%x\n", best_mode_info.video_mode, best_mode_info.vesa.x_resolution, best_mode_info.vesa.y_resolution, best_mode_info.vesa.bits_per_pixel, le32_to_cpu(best_mode_info.vesa.phys_base_ptr)); //printf("Mode Info Dump:"); //dump(best_mode_info.mode_info_block, 64); // set the video mode vbe_set_mode(&best_mode_info); if ((info.capabilities & 0x1) != 0) { // switch to 8 bit palette format vbe_set_palette_format(8); } // setup a palette: // - first 216 colors are mixed colors for each component in 6 steps // (6*6*6=216) // - then 10 shades of the three primary colors // - then 10 shades of grey // ------- // = 256 colors // // - finally black is color 0 and white color FF (because SLOF expects it // this way...) // this resembles the palette that the kernel/X Server seems to expect... u8 mixed_color_values[6] = { 0xFF, 0xDA, 0xB3, 0x87, 0x54, 0x00 }; u8 primary_color_values[10] = { 0xF3, 0xE7, 0xCD, 0xC0, 0xA5, 0x96, 0x77, 0x66, 0x3F, 0x27 }; u8 mc_size = sizeof(mixed_color_values); u8 prim_size = sizeof(primary_color_values); u8 curr_color_index; u32 curr_color; u8 r, g, b; // 216 mixed colors for (r = 0; r < mc_size; r++) { for (g = 0; g < mc_size; g++) { for (b = 0; b < mc_size; b++) { curr_color_index = (r * mc_size * mc_size) + (g * mc_size) + b; curr_color = 0; curr_color |= ((u32) mixed_color_values[r]) << 16; //red value curr_color |= ((u32) mixed_color_values[g]) << 8; //green value curr_color |= (u32) mixed_color_values[b]; //blue value vbe_set_color(curr_color_index, curr_color); } } } // 10 shades of each primary color // red for (r = 0; r < prim_size; r++) { curr_color_index = mc_size * mc_size * mc_size + r; curr_color = ((u32) primary_color_values[r]) << 16; vbe_set_color(curr_color_index, curr_color); } //green for (g = 0; g < prim_size; g++) { curr_color_index = mc_size * mc_size * mc_size + prim_size + g; curr_color = ((u32) primary_color_values[g]) << 8; vbe_set_color(curr_color_index, curr_color); } //blue for (b = 0; b < prim_size; b++) { curr_color_index = mc_size * mc_size * mc_size + prim_size * 2 + b; curr_color = (u32) primary_color_values[b]; vbe_set_color(curr_color_index, curr_color); } // 10 shades of grey for (i = 0; i < prim_size; i++) { curr_color_index = mc_size * mc_size * mc_size + prim_size * 3 + i; curr_color = 0; curr_color |= ((u32) primary_color_values[i]) << 16; //red curr_color |= ((u32) primary_color_values[i]) << 8; //green curr_color |= ((u32) primary_color_values[i]); //blue vbe_set_color(curr_color_index, curr_color); } // SLOF is using color 0x0 (black) and 0xFF (white) to draw to the screen... vbe_set_color(0x00, 0x00000000); vbe_set_color(0xFF, 0x00FFFFFF); output->screen_width = le16_to_cpu(best_mode_info.vesa.x_resolution); output->screen_height = le16_to_cpu(best_mode_info.vesa.y_resolution); output->screen_linebytes = le16_to_cpu(best_mode_info.vesa.bytes_per_scanline); output->color_depth = best_mode_info.vesa.bits_per_pixel; output->framebuffer_address = le32_to_cpu(best_mode_info.vesa.phys_base_ptr); } else { printf("%s: No suitable video mode found!\n", __func__); //unset display_type... output->display_type = 0; } return 0; }
int gfx_init(int mode) { struct vbe_info info; struct vbe_mode_info mode_info; if (gfx_check_vbe_info(&info) != 0) return -1; if (gfx_check_vbe_mode_info(&info, mode, &mode_info) != 0) return -1; vga_get_mode(&gfx_saved_vga_mode); gfx_mode_info.mode = gfx_saved_vga_mode; if (vbe_set_mode(mode, VBE_LINEAR_FRAMEBUFFER | VBE_CLEAR_DISPLAY_MEMORY) != 0) { error("Setting VBE mode %Xh failed", mode); goto failure; } gfx_mode_info.mode = mode; gfx_mode_info.x_resolution = mode_info.x_resolution; gfx_mode_info.y_resolution = mode_info.y_resolution; gfx_mode_info.page_size = mode_info.bytes_per_scanline * mode_info.y_resolution; if (mode_info.phys_base_ptr <= 0xFFFFF) { error("Unsupported hardware configuration: Framebuffer in real-mode memory " "(physical base address = %Xh)", mode_info.phys_base_ptr); goto failure; } if (dpmi_map_physical_address(mode_info.phys_base_ptr, 2 * gfx_mode_info.page_size, &gfx_framebuffer_address) != 0) { error("Mapping graphics card framebuffer to memory failed"); goto failure; } if (vbe_set_display_start(0, 0, VBE_WAIT_FOR_RETRACE) != 0) { error("Setting display start failed"); goto failure; } init_image(&gfx_buffer_1, gfx_mode_info.x_resolution, gfx_mode_info.y_resolution, (uint8_t *) gfx_framebuffer_address); init_image(&gfx_buffer_2, gfx_mode_info.x_resolution, gfx_mode_info.y_resolution, gfx_buffer_1.data + gfx_mode_info.page_size); gfx_front_buffer = &gfx_buffer_1; gfx_back_buffer = &gfx_buffer_2; gfx_check_refresh_rate(); gfx_reset_clip_rect(); return 0; failure: gfx_exit(); return -1; }
void do_vesa_int() { int err_code = VBE_ERROR_GENERAL_FAIL; #if 0 v_printf( "VBE: function 0x%02x, bx = 0x%04x cx = 0x%04x, dx = 0x%04x, es = 0x%04x, di = 0x%04x\n", (unsigned) _AL, (unsigned) _BX, (unsigned) _CX, (unsigned) _DX, (unsigned) _ES, (unsigned) _DI ); #endif switch(_AL) { case 0x00: /* return VBE controller info */ err_code = vbe_info(SEGOFF2LINEAR(_ES, _DI)); break; case 0x01: /* return VBE mode info */ err_code = vbe_mode_info(_CX, SEGOFF2LINEAR(_ES, _DI)); break; case 0x02: /* set VBE mode */ err_code = vbe_set_mode(_BX); break; case 0x03: /* get current VBE mode */ err_code = vbe_get_mode(); break; case 0x04: /* save/restore state */ err_code = vbe_save_restore(_DL, _CX, SEGOFF2LINEAR(_ES, _BX)); break; case 0x05: /* display window control (aka set/get bank) */ err_code = vbe_display_window(_BH, _BL, _DL /* must be _DX !!!*/); break; case 0x06: /* set/get logical scan line length */ err_code = vbe_scan_length(_BL, _CX); break; case 0x07: /* set/get display start */ err_code = vbe_display_start(_BL, _CX, _DX); break; case 0x08: /* set/get DAC palette format */ err_code = vbe_dac_format(_BL, _BH); break; case 0x09: /* set/get palette data */ err_code = vbe_palette_data(_BL, _CX, _DX, SEGOFF2LINEAR(_ES, _DI)); break; case 0x0a: /* return VBE PM interface */ err_code = vbe_pm_interface(_BL); break; case 0x10: /* set/get display power state */ err_code = vbe_power_state(_BL, _BH); break; default: err_code = VBE_ERROR_UNSUP; #ifdef DEBUG_VBE v_printf( "VBE: unsupported function 0x%02x, retval = %d, bx = 0x%04x cx = 0x%04x, dx = 0x%04x, es = 0x%04x, di = 0x%04x\n", (unsigned) _AL, err_code, (unsigned) _BX, (unsigned) _CX, (unsigned) _DX, (unsigned) _ES, (unsigned) _DI ); #endif } if(err_code >= 0) { _AL = 0x4f; _AH = (unsigned char) err_code; } }
void isr_exception_handler(struct regs *r) { //Check if it is an exception if (r->int_no < 32) { /* //Red screen of death! video_setdriver(video_vgatext_getdriver(),0); cli_setrect(0); cli_settextcolour(0x4F);cli_cls(); cli_positioncursor(0,0); cli_puts("An exception has occurred.\nException: ("); cli_putu32(r->int_no, 10); cli_puts(") - "); cli_puts(exception_messages[r->int_no]); cli_puts("\n\nSystem Halted.\n\n"); //Put error code cli_puts("Technical Information:\n\nError Code: "); cli_putu32(r->err_code,16); //Put registers cli_puts("\nRegs: EAX: ");cli_putu32(r->eax,16); cli_puts("\n EBX: ");cli_putu32(r->ebx,16); cli_puts("\n ECX: ");cli_putu32(r->ecx,16); cli_puts("\n EDX: ");cli_putu32(r->edx,16); cli_puts("\n ESI: ");cli_putu32(r->esi,16); cli_puts("\n EDI: ");cli_putu32(r->edi,16); cli_puts("\n ESP: ");cli_putu32(r->esp,16); cli_puts("\n EBP: ");cli_putu32(r->ebp,16); cli_puts("\n CS: ");cli_putu32(r->cs,16); cli_puts("\n DS: ");cli_putu32(r->ds,16); cli_puts("\n ES: ");cli_putu32(r->es,16); cli_puts("\n FS: ");cli_putu32(r->fs,16); cli_puts("\n GS: ");cli_putu32(r->gs,16); cli_puts("\n SS: ");cli_putu32(r->ss,16); cli_puts("\n EIP: ");cli_putu32(r->eip,16); */ //Endless loop vbe_set_mode(0x3,0); console_error(); console_puts_protected("\nAn exception has occurred.\nException: (0x"); console_putu32_protected(r->err_code, 16); console_puts_protected(") - "); console_puts_protected(isr_exception_messages[r->int_no]); console_puts_protected("\n\nSystem Halted.\n\n"); //Put error code console_puts_protected("Technical Information:\n\nError Code: "); console_putu32_protected(r->err_code,16); //Put registers console_puts_protected("\nRegs: EAX: 0x");console_putu32_protected(r->eax,16); console_puts_protected("\n EBX: 0x");console_putu32_protected(r->ebx,16); console_puts_protected("\n ECX: 0x");console_putu32_protected(r->ecx,16); console_puts_protected("\n EDX: 0x");console_putu32_protected(r->edx,16); console_puts_protected("\n ESI: 0x");console_putu32_protected(r->esi,16); console_puts_protected("\n EDI: 0x");console_putu32_protected(r->edi,16); console_puts_protected("\n ESP: 0x");console_putu32_protected(r->esp,16); console_puts_protected("\n EBP: 0x");console_putu32_protected(r->ebp,16); console_puts_protected("\n CS: 0x");console_putu32_protected(r->cs,16); console_puts_protected("\n DS: 0x");console_putu32_protected(r->ds,16); console_puts_protected("\n ES: 0x");console_putu32_protected(r->es,16); console_puts_protected("\n FS: 0x");console_putu32_protected(r->fs,16); console_puts_protected("\n GS: 0x");console_putu32_protected(r->gs,16); console_puts_protected("\n SS: 0x");console_putu32_protected(r->ss,16); console_puts_protected("\n EIP: 0x");console_putu32_protected(r->eip,16); for(;;) __asm__ __volatile__ ("hlt"); } }