1 /* ----------------------------------------------------------------------- *
3 * Copyright 1999-2008 H. Peter Anvin - All Rights Reserved
5 * Permission is hereby granted, free of charge, to any person
6 * obtaining a copy of this software and associated documentation
7 * files (the "Software"), to deal in the Software without
8 * restriction, including without limitation the rights to use,
9 * copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom
11 * the Software is furnished to do so, subject to the following
14 * The above copyright notice and this permission notice shall
15 * be included in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 * OTHER DEALINGS IN THE SOFTWARE.
26 * ----------------------------------------------------------------------- */
31 * Query the VESA BIOS and select a 640x480x32 mode with local mapping
32 * support, if one exists.
40 #include <syslinux/video.h>
46 struct vesa_info __vesa_info
;
48 struct vesa_char
*__vesacon_text_display
;
50 int __vesacon_font_height
;
51 int __vesacon_text_rows
;
52 int __vesacon_text_cols
;
53 enum vesa_pixel_format __vesacon_pixel_format
= PXF_NONE
;
54 unsigned int __vesacon_bytes_per_pixel
;
55 uint8_t __vesacon_graphics_font
[FONT_MAX_CHARS
][FONT_MAX_HEIGHT
];
57 uint32_t *__vesacon_background
, *__vesacon_shadowfb
;
59 static void unpack_font(uint8_t * dst
, uint8_t * src
, int height
)
63 for (i
= 0; i
< FONT_MAX_CHARS
; i
++) {
64 memcpy(dst
, src
, height
);
65 memset(dst
+ height
, 0, FONT_MAX_HEIGHT
- height
);
67 dst
+= FONT_MAX_HEIGHT
;
72 static int vesacon_set_mode(int *x
, int *y
)
75 struct vesa_mode_info
*mi
;
76 enum vesa_pixel_format bestpxf
;
79 debug("Hello, World!\r\n");
81 /* Free any existing data structures */
82 if (__vesacon_background
) {
83 free(__vesacon_background
);
84 __vesacon_background
= NULL
;
86 if (__vesacon_shadowfb
) {
87 free(__vesacon_shadowfb
);
88 __vesacon_shadowfb
= NULL
;
91 rv
= firmware
->vesa
->set_mode(&__vesa_info
, x
, y
, &bestpxf
);
96 __vesacon_bytes_per_pixel
= (mi
->bpp
+ 7) >> 3;
97 __vesacon_format_pixels
= __vesacon_format_pixels_list
[bestpxf
];
99 /* Download the SYSLINUX- or firmware-provided font */
100 __vesacon_font_height
= syslinux_font_query(&rom_font
);
101 if (!__vesacon_font_height
)
102 __vesacon_font_height
= firmware
->vesa
->font_query(&rom_font
);
104 unpack_font((uint8_t *) __vesacon_graphics_font
, rom_font
,
105 __vesacon_font_height
);
107 __vesacon_background
= calloc(mi
->h_res
*mi
->v_res
, 4);
108 __vesacon_shadowfb
= calloc(mi
->h_res
*mi
->v_res
, 4);
110 __vesacon_init_copy_to_screen();
112 /* Tell syslinux we changed video mode */
113 /* In theory this should be:
115 flags = (mi->mode_attr & 4) ? 0x0007 : 0x000f;
117 However, that would assume all systems that claim to handle text
118 output in VESA modes actually do that... */
119 syslinux_report_video_mode(0x000f, mi
->h_res
, mi
->v_res
);
121 __vesacon_pixel_format
= bestpxf
;
127 * Does init_text_display need an EFI counterpart?
128 * e.g. vesa_char may need to setup UNICODE char for EFI
129 * and the number of screen chars may need to be sized up
130 * accordingly. This may also require turning byte strings
131 * into unicode strings in the framebuffer
132 * Possibly, revisit vesacon_fill() for EFI.
134 static int init_text_display(void)
137 struct vesa_char
*ptr
;
138 struct vesa_char def_char
= {
143 if (__vesacon_text_display
)
144 free(__vesacon_text_display
);
146 __vesacon_text_cols
= TEXT_PIXEL_COLS
/ FONT_WIDTH
;
147 __vesacon_text_rows
= TEXT_PIXEL_ROWS
/ __vesacon_font_height
;
148 nchars
= (__vesacon_text_cols
+2) * (__vesacon_text_rows
+2);
150 __vesacon_text_display
= ptr
= malloc(nchars
* sizeof(struct vesa_char
));
155 vesacon_fill(ptr
, def_char
, nchars
);
156 __vesacon_init_cursor(__vesacon_font_height
);
162 * On input, VESA initialization is passed a desirable resolution. On
163 * return, either the requested resolution is set or the system
164 * supported default resolution is set and returned to the caller.
166 int __vesacon_init(int *x
, int *y
)
170 /* We need the FPU for graphics, at least libpng et al will need it... */
174 rv
= vesacon_set_mode(x
, y
);
176 /* Try to see if we can just patch the BIOS... */
177 if (__vesacon_i915resolution(*x
, *y
))
179 if (vesacon_set_mode(x
, y
))
185 debug("Mode set, now drawing at %#p\r\n", __vesa_info
.mi
.lfb_ptr
);
187 __vesacon_init_background();