46 #include "../x86emu/prim_ops.h"
65 u16 video_mode_list[256];
77 #if CONFIG(FRAMEBUFFER_SET_VESA_MODE)
102 M.x86.R_EAX = 0x4f00;
111 if (
M.x86.R_AL != 0x4f) {
113 __func__,
M.x86.R_AL);
117 if (
M.x86.R_AH != 0x0) {
119 (
"%s: VBE Info Function Return Code NOT OK! AH=%x\n",
120 __func__,
M.x86.R_AH);
136 info->oem_string_ptr =
151 info->video_mode_list[i] =
in16le(video_mode_ptr + i);
155 (
sizeof(
info->video_mode_list) /
156 sizeof(
info->video_mode_list[0])))
157 && (
info->video_mode_list[i - 1] != 0xFFFF));
165 static int mode_info_valid;
173 M.x86.R_EAX = 0x4f01;
183 if (
M.x86.R_AL != 0x4f) {
185 (
"%s: VBE Return Mode Info Function NOT supported! AL=%x\n",
186 __func__,
M.x86.R_AL);
190 if (
M.x86.R_AH != 0x0) {
192 (
"%s: VBE Return Mode Info (mode: %04x) Function Return Code NOT OK! AH=%02x\n",
199 biosmem + ((
M.x86.R_ES << 4) +
M.x86.R_DI),
215 M.x86.R_EAX = 0x4f02;
217 M.x86.R_BX |= 0x4000;
218 M.x86.R_BX &= 0x7FFF;
230 if (
M.x86.R_AL != 0x4f) {
232 (
"%s: VBE Set Mode Function NOT supported! AL=%x\n",
233 __func__,
M.x86.R_AL);
237 if (
M.x86.R_AH != 0x0) {
239 (
"%s: mode: %x VBE Set Mode Function Return Code NOT OK! AH=%x\n",
249 vbe_set_palette_format(
u8 format)
253 M.x86.R_EAX = 0x4f08;
267 if (
M.x86.R_AL != 0x4f) {
269 (
"%s: VBE Set Palette Format Function NOT supported! AL=%x\n",
270 __func__,
M.x86.R_AL);
274 if (
M.x86.R_AH != 0x0) {
276 (
"%s: VBE Set Palette Format Function Return Code NOT OK! AH=%x\n",
277 __func__,
M.x86.R_AH);
285 vbe_set_color(
u16 color_number,
u32 color_value)
289 M.x86.R_EAX = 0x4f09;
292 M.x86.R_DX = color_number;
301 color_number, color_value);
310 if (
M.x86.R_AL != 0x4f) {
312 (
"%s: VBE Set Palette Function NOT supported! AL=%x\n",
313 __func__,
M.x86.R_AL);
317 if (
M.x86.R_AH != 0x0) {
319 (
"%s: VBE Set Palette Function Return Code NOT OK! AH=%x\n",
320 __func__,
M.x86.R_AH);
327 vbe_get_color(
u16 color_number,
u32 *color_value)
331 M.x86.R_EAX = 0x4f09;
334 M.x86.R_DX = color_number;
346 if (
M.x86.R_AL != 0x4f) {
348 (
"%s: VBE Set Palette Function NOT supported! AL=%x\n",
349 __func__,
M.x86.R_AL);
353 if (
M.x86.R_AH != 0x0) {
355 (
"%s: VBE Set Palette Function Return Code NOT OK! AH=%x\n",
356 __func__,
M.x86.R_AH);
363 color_number, *color_value);
374 M.x86.R_EAX = 0x4f15;
387 if (
M.x86.R_AL != 0x4f) {
389 (
"%s: VBE Get DDC Info Function NOT supported! AL=%x\n",
390 __func__,
M.x86.R_AL);
394 if (
M.x86.R_AH != 0x0) {
396 (
"%s: port: %x VBE Get DDC Info Function Return Code NOT OK! AH=%x\n",
407 M.x86.R_EAX = 0x4f15;
422 if (
M.x86.R_AL != 0x4f) {
424 (
"%s: VBE Read EDID Function NOT supported! AL=%x\n",
425 __func__,
M.x86.R_AL);
429 if (
M.x86.R_AH != 0x0) {
431 (
"%s: port: %x VBE Read EDID Function Return Code NOT OK! AH=%x\n",
437 biosmem + (
M.x86.R_ES << 4) +
M.x86.R_DI,
452 screen_info_input_t input;
454 screen_info_t local_output;
455 screen_info_t *output = &local_output;
457 memset(&input, 0,
sizeof(screen_info_input_t));
459 memset(&output, 0,
sizeof(screen_info_t));
462 rval = vbe_info(&
info);
471 (
info.capabilities & 0x1) ==
472 0 ?
"fixed 6bit" :
"switchable 6/8bit");
474 (
info.capabilities & 0x2) ==
475 0 ?
"compatible" :
"not compatible");
477 (
info.capabilities & 0x4) ==
478 0 ?
"normal" :
"use blank bit in Function 09h");
489 if (
strncmp((
char *) input.signature,
"DDC", 4) != 0) {
491 (
"%s: Invalid input signature! expected: %s, is: %s\n",
492 __func__,
"DDC", input.signature);
495 if (input.size_reserved !=
sizeof(screen_info_t)) {
497 (
"%s: Size of return struct is wrong, required: %d, available: %d\n",
498 __func__, (
int)
sizeof(screen_info_t),
499 input.size_reserved);
505 vbe_get_ddc_info(&ddc_info);
530 output->display_type = 0x0;
534 output->display_type = 2;
537 output->display_type = 1;
546 memset(&best_mode_info, 0,
sizeof(best_mode_info));
547 while ((mode_info.
video_mode =
info.video_mode_list[i]) != 0xFFFF) {
549 vbe_get_mode_info(&mode_info);
555 (le16_to_cpu(mode_info.
vesa.mode_attributes) & 0x1) ==
556 0 ?
"not supported" :
"supported");
558 (le16_to_cpu(mode_info.
vesa.mode_attributes) & 0x4) ==
561 (le16_to_cpu(mode_info.
vesa.mode_attributes) & 0x8) ==
562 0 ?
"monochrome" :
"color",
563 (le16_to_cpu(mode_info.
vesa.mode_attributes) & 0x10) ==
564 0 ?
"text" :
"graphics");
566 (le16_to_cpu(mode_info.
vesa.mode_attributes) & 0x20) ==
567 0 ?
"compatible" :
"not compatible");
569 (le16_to_cpu(mode_info.
vesa.mode_attributes) & 0x40) ==
572 (le16_to_cpu(mode_info.
vesa.mode_attributes) & 0x80) ==
575 le16_to_cpu(mode_info.
vesa.x_resolution),
576 le16_to_cpu(mode_info.
vesa.y_resolution));
578 mode_info.
vesa.x_charsize, mode_info.
vesa.y_charsize);
580 mode_info.
vesa.bits_per_pixel);
582 mode_info.
vesa.memory_model);
584 le32_to_cpu(mode_info.
vesa.phys_base_ptr));
586 if ((mode_info.
vesa.bits_per_pixel == input.color_depth)
587 && (le16_to_cpu(mode_info.
vesa.x_resolution) <= input.max_screen_width)
588 && ((le16_to_cpu(mode_info.
vesa.mode_attributes) & 0x80) != 0)
589 && ((le16_to_cpu(mode_info.
vesa.mode_attributes) & 0x10) != 0)
590 && ((le16_to_cpu(mode_info.
vesa.mode_attributes) & 0x8) != 0)
591 && (le16_to_cpu(mode_info.
vesa.x_resolution) > le16_to_cpu(best_mode_info.
vesa.x_resolution)))
594 memcpy(&best_mode_info, &mode_info,
sizeof(mode_info));
601 (
"Best Video Mode found: 0x%x, %dx%d, %dbpp, framebuffer_address: 0x%x\n",
603 best_mode_info.
vesa.x_resolution,
604 best_mode_info.
vesa.y_resolution,
605 best_mode_info.
vesa.bits_per_pixel,
606 le32_to_cpu(best_mode_info.
vesa.phys_base_ptr));
612 vbe_set_mode(&best_mode_info);
614 if ((
info.capabilities & 0x1) != 0) {
616 vbe_set_palette_format(8);
630 u8 mixed_color_values[6] =
631 { 0xFF, 0xDA, 0xB3, 0x87, 0x54, 0x00 };
632 u8 primary_color_values[10] =
633 { 0xF3, 0xE7, 0xCD, 0xC0, 0xA5, 0x96, 0x77, 0x66, 0x3F,
636 u8 mc_size =
sizeof(mixed_color_values);
637 u8 prim_size =
sizeof(primary_color_values);
644 for (r = 0; r < mc_size; r++) {
645 for (g = 0; g < mc_size; g++) {
646 for (b = 0; b < mc_size; b++) {
648 (r * mc_size * mc_size) +
651 curr_color |= ((
u32) mixed_color_values[r]) << 16;
652 curr_color |= ((
u32) mixed_color_values[g]) << 8;
653 curr_color |= (
u32) mixed_color_values[b];
654 vbe_set_color(curr_color_index,
662 for (r = 0; r < prim_size; r++) {
663 curr_color_index = mc_size * mc_size * mc_size + r;
664 curr_color = ((
u32) primary_color_values[r]) << 16;
665 vbe_set_color(curr_color_index, curr_color);
668 for (g = 0; g < prim_size; g++) {
670 mc_size * mc_size * mc_size + prim_size + g;
671 curr_color = ((
u32) primary_color_values[g]) << 8;
672 vbe_set_color(curr_color_index, curr_color);
675 for (b = 0; b < prim_size; b++) {
677 mc_size * mc_size * mc_size + prim_size * 2 + b;
678 curr_color = (
u32) primary_color_values[b];
679 vbe_set_color(curr_color_index, curr_color);
682 for (i = 0; i < prim_size; i++) {
684 mc_size * mc_size * mc_size + prim_size * 3 + i;
686 curr_color |= ((
u32) primary_color_values[i]) << 16;
687 curr_color |= ((
u32) primary_color_values[i]) << 8;
688 curr_color |= ((
u32) primary_color_values[i]);
689 vbe_set_color(curr_color_index, curr_color);
693 vbe_set_color(0x00, 0x00000000);
694 vbe_set_color(0xFF, 0x00FFFFFF);
696 output->screen_width = le16_to_cpu(best_mode_info.
vesa.x_resolution);
697 output->screen_height = le16_to_cpu(best_mode_info.
vesa.y_resolution);
698 output->screen_linebytes = le16_to_cpu(best_mode_info.
vesa.bytes_per_scanline);
699 output->color_depth = best_mode_info.
vesa.bits_per_pixel;
700 output->framebuffer_address =
701 le32_to_cpu(best_mode_info.
vesa.phys_base_ptr);
703 printf(
"%s: No suitable video mode found!\n", __func__);
705 output->display_type = 0;
715 if (!mode_info_valid || !mode_info.
vesa.phys_base_ptr)
725 rval = vbe_info(&
info);
734 (
info.capabilities & 0x1) ==
735 0 ?
"fixed 6bit" :
"switchable 6/8bit");
737 (
info.capabilities & 0x2) ==
738 0 ?
"compatible" :
"not compatible");
740 (
info.capabilities & 0x4) ==
741 0 ?
"normal" :
"use blank bit in Function 09h");
743 mode_info.
video_mode = (1 << 14) | CONFIG_FRAMEBUFFER_VESA_MODE;
744 vbe_get_mode_info(&mode_info);
745 vbe_set_mode(&mode_info);
749 .x_resolution = le16_to_cpu(mode_info.
vesa.x_resolution),
750 .y_resolution = le16_to_cpu(mode_info.
vesa.y_resolution),
751 .bytes_per_line = le16_to_cpu(mode_info.
vesa.bytes_per_scanline),
752 .bits_per_pixel = mode_info.
vesa.bits_per_pixel,
753 .red_mask_pos = mode_info.
vesa.red_mask_pos,
754 .red_mask_size = mode_info.
vesa.red_mask_size,
755 .green_mask_pos = mode_info.
vesa.green_mask_pos,
756 .green_mask_size = mode_info.
vesa.green_mask_size,
757 .blue_mask_pos = mode_info.
vesa.blue_mask_pos,
758 .blue_mask_size = mode_info.
vesa.blue_mask_size,
759 .reserved_mask_pos = mode_info.
vesa.reserved_mask_pos,
760 .reserved_mask_size = mode_info.
vesa.reserved_mask_size,
772 M.x86.R_EAX = 0x0003;
void * memcpy(void *dest, const void *src, size_t n)
void * memset(void *dstpp, int c, size_t len)
@ LB_FB_ORIENTATION_NORMAL
void delay(unsigned int secs)
#define DEBUG_TRACE_X86EMU
#define DEBUG_PRINTF_VBE(_x...)
static u16 in16le(void *addr)
static u32 in32le(void *addr)
static void out32le(void *addr, u32 val)
static struct smmstore_params_info info
struct fb_info * fb_add_framebuffer_info_ex(const struct lb_framebuffer *fb)
int strncmp(const char *s1, const char *s2, int maxlen)
lb_uint64_t physical_address
void vbe_textmode_console(void)
const vbe_mode_info_t * vbe_mode_info(void)
Returns the mode_info struct from the vbe context, if initialized.
void vbe_set_graphics(void)
int X86EMU_trace_on(void)