diff options
-rw-r--r-- | com32/include/syslinux/firmware.h | 11 | ||||
-rw-r--r-- | com32/lib/Makefile | 15 | ||||
-rw-r--r-- | com32/lib/sys/vesa/efi/background.c | 456 | ||||
-rw-r--r-- | com32/lib/sys/vesa/efi/debug.h | 36 | ||||
-rw-r--r-- | com32/lib/sys/vesa/efi/drawtxt.c | 317 | ||||
-rw-r--r-- | com32/lib/sys/vesa/efi/fill.h | 63 | ||||
-rw-r--r-- | com32/lib/sys/vesa/efi/fmtpixel.c | 101 | ||||
-rw-r--r-- | com32/lib/sys/vesa/efi/i915resolution.c | 795 | ||||
-rw-r--r-- | com32/lib/sys/vesa/efi/screencpy.c | 75 | ||||
-rw-r--r-- | com32/lib/sys/vesa/efi/vesa.h | 129 | ||||
-rw-r--r-- | com32/lib/sys/vesa/efi/video.h | 98 | ||||
-rw-r--r-- | com32/lib/sys/vesa/initvesa.c | 218 | ||||
-rw-r--r-- | com32/lib/sys/vesa/screencpy.c | 46 | ||||
-rw-r--r-- | com32/lib/sys/vesa/vesa.h | 1 | ||||
-rw-r--r-- | com32/lib/sys/vesa/video.h | 8 | ||||
-rw-r--r-- | com32/lib/sys/vesacon_write.c | 4 | ||||
-rw-r--r-- | core/bios.c | 258 | ||||
-rw-r--r-- | core/font.c | 9 | ||||
-rw-r--r-- | core/graphics.c | 2 | ||||
-rw-r--r-- | efi/cp865_8x16.h (renamed from com32/lib/sys/vesa/efi/cp865_8x16.h) | 0 | ||||
-rw-r--r-- | efi/main.c | 3 | ||||
-rw-r--r-- | efi/vesa.c (renamed from com32/lib/sys/vesa/efi/initvesa.c) | 210 |
22 files changed, 378 insertions, 2477 deletions
diff --git a/com32/include/syslinux/firmware.h b/com32/include/syslinux/firmware.h index 05f97630..cfe3b8df 100644 --- a/com32/include/syslinux/firmware.h +++ b/com32/include/syslinux/firmware.h @@ -27,6 +27,16 @@ struct adv_ops { int (*write)(void); }; +struct vesa_info; +enum vesa_pixel_format; +struct win_info; + +struct vesa_ops { + int (*set_mode)(struct vesa_info *, int *, int *, enum vesa_pixel_format *); + void (*screencpy)(size_t, const uint32_t *, size_t, struct win_info *); + int (*font_query)(uint8_t **); +}; + struct disk_private; struct initramfs; struct setup_data; @@ -44,6 +54,7 @@ struct firmware { struct adv_ops *adv_ops; int (*boot_linux)(void *, size_t, struct initramfs *, struct setup_data *, char *); + struct vesa_ops *vesa; }; extern struct firmware *firmware; diff --git a/com32/lib/Makefile b/com32/lib/Makefile index 81e6fcd1..46a53b5c 100644 --- a/com32/lib/Makefile +++ b/com32/lib/Makefile @@ -22,19 +22,11 @@ LIBJPG_OBJS = \ jpeg/rgb24.o jpeg/bgr24.o jpeg/yuv420p.o jpeg/grey.o \ jpeg/rgba32.o jpeg/bgra32.o -ifndef EFI_BUILD LIBVESA_OBJS = \ sys/vesacon_write.o sys/vesaserial_write.o \ sys/vesa/initvesa.o sys/vesa/drawtxt.o sys/vesa/background.o \ - sys/vesa/alphatbl.o sys/vesa/screencpy.o sys/vesa/fmtpixel.o \ + sys/vesa/alphatbl.o sys/vesa/fmtpixel.o \ sys/vesa/i915resolution.o -else -LIBVESA_OBJS = \ - sys/vesacon_write.o sys/vesaserial_write.o \ - sys/vesa/efi/initvesa.o sys/vesa/efi/drawtxt.o sys/vesa/efi/background.o \ - sys/vesa/alphatbl.o sys/vesa/efi/screencpy.o sys/vesa/efi/fmtpixel.o \ - sys/vesa/efi/i915resolution.o -endif LIBMISC_OBJS = \ sys/libansi.o sys/gpxe.o @@ -124,12 +116,7 @@ errlist.c: makeerrlist.pl $(SRC)/../include/errno.h $(PERL) $< $(CFLAGS) -errlist > $@ || rm -f $@ # These files are performance critical, and doesn't compile well with -Os -#FIXME: determine if drawtxt.c is really EFI-dependent -#ifndef EFI_BUILD sys/vesa/drawtxt.o: sys/vesa/drawtxt.c -#else -sys/vesa/efi/drawtxt.o: sys/vesa/efi/drawtxt.c -#endif $(CC) $(MAKEDEPS) $(CFLAGS) -O3 -c -o $@ $< sys/vesa/alphatbl.c: sys/vesa/alphatbl.pl diff --git a/com32/lib/sys/vesa/efi/background.c b/com32/lib/sys/vesa/efi/background.c deleted file mode 100644 index 93577461..00000000 --- a/com32/lib/sys/vesa/efi/background.c +++ /dev/null @@ -1,456 +0,0 @@ -/* ----------------------------------------------------------------------- * - * - * Copyright 2006-2008 H. Peter Anvin - All Rights Reserved - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall - * be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * ----------------------------------------------------------------------- */ - -#include <stdio.h> -#include <png.h> -#include <tinyjpeg.h> -#include <com32.h> -#include <unistd.h> -#include <stdlib.h> -#include <sys/stat.h> -#include <minmax.h> -#include <stdbool.h> -#include <ilog2.h> -#include <syslinux/loadfile.h> -#include "vesa.h" -#include "video.h" - -/*** FIX: This really should be alpha-blended with color index 0 ***/ - -/* For best performance, "start" should be a multiple of 4, to assure - aligned dwords. */ -static void draw_background_line(int line, int start, int npixels) -{ - uint32_t *bgptr = &__vesacon_background[line*__vesa_info.mi.h_res+start]; - unsigned int bytes_per_pixel = __vesacon_bytes_per_pixel; - size_t fbptr = line * __vesa_info.mi.logical_scan + start*bytes_per_pixel; - - __vesacon_copy_to_screen(fbptr, bgptr, npixels); -} - -/* This draws the border, then redraws the text area */ -static void draw_background(void) -{ - int i; - const int bottom_border = VIDEO_BORDER + - (TEXT_PIXEL_ROWS % __vesacon_font_height); - const int right_border = VIDEO_BORDER + (TEXT_PIXEL_COLS % FONT_WIDTH); - - for (i = 0; i < VIDEO_BORDER; i++) - draw_background_line(i, 0, __vesa_info.mi.h_res); - - for (i = VIDEO_BORDER; i < __vesa_info.mi.v_res - bottom_border; i++) { - draw_background_line(i, 0, VIDEO_BORDER); - draw_background_line(i, __vesa_info.mi.h_res - right_border, - right_border); - } - - for (i = __vesa_info.mi.v_res - bottom_border; - i < __vesa_info.mi.v_res; i++) - draw_background_line(i, 0, __vesa_info.mi.h_res); - - __vesacon_redraw_text(); -} - -/* - * Tile an image in the UL corner across the entire screen - */ -static void tile_image(int width, int height) -{ - int xsize = __vesa_info.mi.h_res; - int ysize = __vesa_info.mi.v_res; - int x, y, yr; - int xl, yl; - uint32_t *sp, *dp, *drp, *dtp; - - drp = __vesacon_background; - for (y = 0 ; y < ysize ; y += height) { - yl = min(height, ysize-y); - dtp = drp; - for (x = 0 ; x < xsize ; x += width) { - xl = min(width, xsize-x); - if (x || y) { - sp = __vesacon_background; - dp = dtp; - for (yr = 0 ; yr < yl ; yr++) { - memcpy(dp, sp, xl*sizeof(uint32_t)); - dp += xsize; - sp += xsize; - } - } - dtp += xl; - } - drp += xsize*height; - } -} - -static int read_png_file(FILE * fp) -{ - png_structp png_ptr = NULL; - png_infop info_ptr = NULL; -#if 0 - png_color_16p image_background; - static const png_color_16 my_background = { 0, 0, 0, 0, 0 }; -#endif - png_bytep row_pointers[__vesa_info.mi.v_res], rp; - int i; - int rv = -1; - - png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - info_ptr = png_create_info_struct(png_ptr); - - if (!png_ptr || !info_ptr || setjmp(png_jmpbuf(png_ptr))) - goto err; - - png_init_io(png_ptr, fp); - png_set_sig_bytes(png_ptr, 8); - - png_set_user_limits(png_ptr, __vesa_info.mi.h_res, __vesa_info.mi.v_res); - - png_read_info(png_ptr, info_ptr); - - /* Set the appropriate set of transformations. We need to end up - with 32-bit BGRA format, no more, no less. */ - - /* Expand to RGB first... */ - if (info_ptr->color_type & PNG_COLOR_MASK_PALETTE) - png_set_palette_to_rgb(png_ptr); - else if (!(info_ptr->color_type & PNG_COLOR_MASK_COLOR)) - png_set_gray_to_rgb(png_ptr); - - /* Add alpha channel, if need be */ - if (!(png_ptr->color_type & PNG_COLOR_MASK_ALPHA)) { - if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) - png_set_tRNS_to_alpha(png_ptr); - else - png_set_add_alpha(png_ptr, ~0, PNG_FILLER_AFTER); - } - - /* Adjust the byte order, if necessary */ - png_set_bgr(png_ptr); - - /* Make sure we end up with 8-bit data */ - if (info_ptr->bit_depth == 16) - png_set_strip_16(png_ptr); - else if (info_ptr->bit_depth < 8) - png_set_packing(png_ptr); - -#if 0 - if (png_get_bKGD(png_ptr, info_ptr, &image_background)) - png_set_background(png_ptr, image_background, - PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); - else - png_set_background(png_ptr, &my_background, - PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); -#endif - - /* Whew! Now we should get the stuff we want... */ - rp = (png_bytep)__vesacon_background; - for (i = 0; i < (int)info_ptr->height; i++) { - row_pointers[i] = rp; - rp += __vesa_info.mi.h_res << 2; - } - - png_read_image(png_ptr, row_pointers); - - tile_image(info_ptr->width, info_ptr->height); - - rv = 0; - -err: - if (png_ptr) - png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL); - return rv; -} - -static int jpeg_sig_cmp(uint8_t * bytes, int len) -{ - (void)len; - - return (bytes[0] == 0xff && bytes[1] == 0xd8) ? 0 : -1; -} - -static int read_jpeg_file(FILE * fp, uint8_t * header, int len) -{ - struct jdec_private *jdec = NULL; - void *jpeg_file = NULL; - size_t length_of_file; - unsigned int width, height; - int rv = -1; - unsigned char *components[1]; - unsigned int bytes_per_row[1]; - - rv = floadfile(fp, &jpeg_file, &length_of_file, header, len); - fclose(fp); - if (rv) - goto err; - - jdec = tinyjpeg_init(); - if (!jdec) - goto err; - - if (tinyjpeg_parse_header(jdec, jpeg_file, length_of_file) < 0) - goto err; - - tinyjpeg_get_size(jdec, &width, &height); - if (width > __vesa_info.mi.h_res || height > __vesa_info.mi.v_res) - goto err; - - components[0] = (void *)__vesacon_background; - tinyjpeg_set_components(jdec, components, 1); - bytes_per_row[0] = __vesa_info.mi.h_res << 2; - tinyjpeg_set_bytes_per_row(jdec, bytes_per_row, 1); - - tinyjpeg_decode(jdec, TINYJPEG_FMT_BGRA32); - tile_image(width, height); - - rv = 0; - -err: - /* Don't use tinyjpeg_free() here, since we didn't allow tinyjpeg - to allocate the frame buffer */ - if (jdec) - free(jdec); - - if (jpeg_file) - free(jpeg_file); - - return rv; -} - -/* Simple grey Gaussian hole, enough to look interesting */ -int vesacon_default_background(void) -{ - int x, y, dx, dy, dy2; - int z; - unsigned int shft; - uint8_t *bgptr = (uint8_t *)__vesacon_background; - uint8_t k; - - if (__vesacon_pixel_format == PXF_NONE) - return 0; /* Not in graphics mode */ - - z = max(__vesa_info.mi.v_res, __vesa_info.mi.h_res) >> 1; - z = ((z*z) >> 11) - 1; - shft = ilog2(z) + 1; - - for (y = 0, dy = -(__vesa_info.mi.v_res >> 1); - y < __vesa_info.mi.v_res; y++, dy++) { - dy2 = dy * dy; - for (x = 0, dx = -(__vesa_info.mi.h_res >> 1); - x < __vesa_info.mi.h_res; x++, dx++) { - k = __vesacon_linear_to_srgb[500 + ((dx*dx + dy2) >> shft)]; - bgptr[0] = k; /* Blue */ - bgptr[1] = k; /* Green */ - bgptr[2] = k; /* Red */ - bgptr += 4; /* Dummy alpha */ - } - } - - draw_background(); - return 0; -} - -/* Set the background to a single flat color */ -int vesacon_set_background(unsigned int rgb) -{ - void *bgptr = __vesacon_background; - unsigned int count = __vesa_info.mi.h_res * __vesa_info.mi.v_res; - - if (__vesacon_pixel_format == PXF_NONE) - return 0; /* Not in graphics mode */ - - asm volatile ("rep; stosl":"+D" (bgptr), "+c"(count) - :"a"(rgb) - :"memory"); - - draw_background(); - return 0; -} - -struct lss16_header { - uint32_t magic; - uint16_t xsize; - uint16_t ysize; -}; - -#define LSS16_MAGIC 0x1413f33d - -static inline int lss16_sig_cmp(const void *header, int len) -{ - const struct lss16_header *h = header; - - if (len != 8) - return 1; - - return !(h->magic == LSS16_MAGIC && - h->xsize <= __vesa_info.mi.h_res && - h->ysize <= __vesa_info.mi.v_res); -} - -static int read_lss16_file(FILE * fp, const void *header, int header_len) -{ - const struct lss16_header *h = header; - uint32_t colors[16], color; - bool has_nybble; - uint8_t byte; - int count; - int nybble, prev; - enum state { - st_start, - st_c0, - st_c1, - st_c2, - } state; - int i, x, y; - uint32_t *bgptr = __vesacon_background; - - /* Assume the header, 8 bytes, has already been loaded. */ - if (header_len != 8) - return -1; - - for (i = 0; i < 16; i++) { - uint8_t rgb[3]; - if (fread(rgb, 1, 3, fp) != 3) - return -1; - - colors[i] = (((rgb[0] & 63) * 255 / 63) << 16) + - (((rgb[1] & 63) * 255 / 63) << 8) + - ((rgb[2] & 63) * 255 / 63); - } - - /* By spec, the state machine is per row */ - for (y = 0; y < h->ysize; y++) { - state = st_start; - has_nybble = false; - color = colors[prev = 0]; /* By specification */ - count = 0; - - x = 0; - while (x < h->xsize) { - if (!has_nybble) { - if (fread(&byte, 1, 1, fp) != 1) - return -1; - nybble = byte & 0xf; - has_nybble = true; - } else { - nybble = byte >> 4; - has_nybble = false; - } - - switch (state) { - case st_start: - if (nybble != prev) { - *bgptr++ = color = colors[prev = nybble]; - x++; - } else { - state = st_c0; - } - break; - - case st_c0: - if (nybble == 0) { - state = st_c1; - } else { - count = nybble; - goto do_run; - } - break; - - case st_c1: - count = nybble + 16; - state = st_c2; - break; - - case st_c2: - count += nybble << 4; - goto do_run; - -do_run: - count = min(count, h->xsize - x); - x += count; - asm volatile ("rep; stosl":"+D" (bgptr), - "+c"(count):"a"(color)); - state = st_start; - break; - } - } - - /* Zero-fill rest of row */ - i = __vesa_info.mi.h_res - x; - asm volatile ("rep; stosl":"+D" (bgptr), "+c"(i):"a"(0):"memory"); - } - - /* Zero-fill rest of screen */ - i = (__vesa_info.mi.v_res - y) * __vesa_info.mi.h_res; - asm volatile ("rep; stosl":"+D" (bgptr), "+c"(i):"a"(0):"memory"); - - return 0; -} - -int vesacon_load_background(const char *filename) -{ - FILE *fp = NULL; - uint8_t header[8]; - int rv = 1; - - if (__vesacon_pixel_format == PXF_NONE) - return 0; /* Not in graphics mode */ - - fp = fopen(filename, "r"); - - if (!fp) - goto err; - - if (fread(header, 1, 8, fp) != 8) - goto err; - - if (!png_sig_cmp(header, 0, 8)) { - rv = read_png_file(fp); - } else if (!jpeg_sig_cmp(header, 8)) { - rv = read_jpeg_file(fp, header, 8); - } else if (!lss16_sig_cmp(header, 8)) { - rv = read_lss16_file(fp, header, 8); - } - - /* This actually displays the stuff */ - draw_background(); - -err: - if (fp) - fclose(fp); - - return rv; -} - -int __vesacon_init_background(void) -{ - /* __vesacon_background was cleared by calloc() */ - - /* The VESA BIOS has already cleared the screen */ - return 0; -} diff --git a/com32/lib/sys/vesa/efi/debug.h b/com32/lib/sys/vesa/efi/debug.h deleted file mode 100644 index 86d085f1..00000000 --- a/com32/lib/sys/vesa/efi/debug.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef LIB_SYS_VESA_DEBUG_H -#define LIB_SYS_VESA_DEBUG_H - -#if 0 - -#include <stdio.h> -#include <unistd.h> - -ssize_t __serial_write(void *fp, const void *buf, size_t count); - -static void debug(const char *str, ...) -{ - va_list va; - char buf[65536]; - size_t len; - - va_start(va, str); - len = vsnprintf(buf, sizeof buf, str, va); - va_end(va); - - if (len >= sizeof buf) - len = sizeof buf - 1; - - __serial_write(NULL, buf, len); -} - -#else - -static inline void debug(const char *str, ...) -{ - (void)str; -} - -#endif - -#endif /* LIB_SYS_VESA_DEBUG_H */ diff --git a/com32/lib/sys/vesa/efi/drawtxt.c b/com32/lib/sys/vesa/efi/drawtxt.c deleted file mode 100644 index 85a9e974..00000000 --- a/com32/lib/sys/vesa/efi/drawtxt.c +++ /dev/null @@ -1,317 +0,0 @@ -/* ----------------------------------------------------------------------- * - * - * Copyright 2006-2008 H. Peter Anvin - All Rights Reserved - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall - * be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * ----------------------------------------------------------------------- */ - -#include <inttypes.h> -#include <colortbl.h> -#include <string.h> -#include "vesa.h" -#include "video.h" -#include "fill.h" - -/* - * Visible cursor information - */ -static uint8_t cursor_pattern[FONT_MAX_HEIGHT]; -static struct vesa_char *cursor_pointer = NULL; -static int cursor_x, cursor_y; - -static inline void *copy_dword(void *dst, void *src, size_t dword_count) -{ - asm volatile ("rep; movsl":"+D" (dst), "+S"(src), "+c"(dword_count)); - return dst; /* Updated destination pointer */ -} - -static inline __attribute__ ((always_inline)) -uint8_t alpha_val(uint8_t fg, uint8_t bg, uint8_t alpha) -{ - unsigned int tmp; - - tmp = __vesacon_srgb_to_linear[fg] * alpha; - tmp += __vesacon_srgb_to_linear[bg] * (255 - alpha); - - return __vesacon_linear_to_srgb[tmp >> 12]; -} - -static uint32_t alpha_pixel(uint32_t fg, uint32_t bg) -{ - uint8_t alpha = fg >> 24; - uint8_t fg_r = fg >> 16; - uint8_t fg_g = fg >> 8; - uint8_t fg_b = fg; - uint8_t bg_r = bg >> 16; - uint8_t bg_g = bg >> 8; - uint8_t bg_b = bg; - - return - (alpha_val(fg_r, bg_r, alpha) << 16) | - (alpha_val(fg_g, bg_g, alpha) << 8) | (alpha_val(fg_b, bg_b, alpha)); -} - -static void vesacon_update_characters(int row, int col, int nrows, int ncols) -{ - const int height = __vesacon_font_height; - const int width = FONT_WIDTH; - uint32_t *bgrowptr, *bgptr, bgval, fgval; - uint32_t fgcolor = 0, bgcolor = 0, color; - uint8_t chbits = 0, chxbits = 0, chsbits = 0; - int i, j, jx, pixrow, pixsrow; - struct vesa_char *rowptr, *rowsptr, *cptr, *csptr; - unsigned int bytes_per_pixel = __vesacon_bytes_per_pixel; - unsigned long pixel_offset; - uint32_t row_buffer[__vesa_info.mi.h_res], *rowbufptr; - size_t fbrowptr; - uint8_t sha; - - pixel_offset = ((row * height + VIDEO_BORDER) * __vesa_info.mi.h_res) + - (col * width + VIDEO_BORDER); - - bgrowptr = &__vesacon_background[pixel_offset]; - fbrowptr = (row * height + VIDEO_BORDER) * __vesa_info.mi.logical_scan + - (col * width + VIDEO_BORDER) * bytes_per_pixel; - - /* Note that we keep a 1-character guard area around the real text area... */ - rowptr = &__vesacon_text_display[(row+1)*(__vesacon_text_cols+2)+(col+1)]; - rowsptr = rowptr - ((__vesacon_text_cols+2)+1); - pixrow = 0; - pixsrow = height - 1; - - for (i = height * nrows; i >= 0; i--) { - bgptr = bgrowptr; - rowbufptr = row_buffer; - - cptr = rowptr; - csptr = rowsptr; - - chsbits = __vesacon_graphics_font[csptr->ch][pixsrow]; - if (__unlikely(csptr == cursor_pointer)) - chsbits |= cursor_pattern[pixsrow]; - sha = console_color_table[csptr->attr].shadow; - chsbits &= (sha & 0x02) ? 0xff : 0x00; - chsbits ^= (sha & 0x01) ? 0xff : 0x00; - chsbits <<= (width - 2); - csptr++; - - /* Draw two pixels beyond the end of the line. One for the shadow, - and one to make sure we have a whole dword of data for the copy - operation at the end. Note that this code depends on the fact that - all characters begin on dword boundaries in the frame buffer. */ - - for (jx = 1, j = width * ncols + 1; j >= 0; j--) { - chbits <<= 1; - chsbits <<= 1; - chxbits <<= 1; - - switch (jx) { - case 1: - chbits = __vesacon_graphics_font[cptr->ch][pixrow]; - if (__unlikely(cptr == cursor_pointer)) - chbits |= cursor_pattern[pixrow]; - sha = console_color_table[cptr->attr].shadow; - chxbits = chbits; - chxbits &= (sha & 0x02) ? 0xff : 0x00; - chxbits ^= (sha & 0x01) ? 0xff : 0x00; - fgcolor = console_color_table[cptr->attr].argb_fg; - bgcolor = console_color_table[cptr->attr].argb_bg; - cptr++; - jx--; - break; - case 0: - chsbits = __vesacon_graphics_font[csptr->ch][pixsrow]; - if (__unlikely(csptr == cursor_pointer)) - chsbits |= cursor_pattern[pixsrow]; - sha = console_color_table[csptr->attr].shadow; - chsbits &= (sha & 0x02) ? 0xff : 0x00; - chsbits ^= (sha & 0x01) ? 0xff : 0x00; - csptr++; - jx = width - 1; - break; - default: - jx--; - break; - } - - /* If this pixel is raised, use the offsetted value */ - bgval = (chxbits & 0x80) - ? bgptr[__vesa_info.mi.h_res + 1] : *bgptr; - bgptr++; - - /* If this pixel is set, use the fg color, else the bg color */ - fgval = (chbits & 0x80) ? fgcolor : bgcolor; - - /* Produce the combined color pixel value */ - color = alpha_pixel(fgval, bgval); - - /* Apply the shadow (75% shadow) */ - if ((chsbits & ~chxbits) & 0x80) { - color >>= 2; - color &= 0x3f3f3f; - } - - *rowbufptr++ = color; - } - - /* Copy to frame buffer */ - __vesacon_copy_to_screen(fbrowptr, row_buffer, rowbufptr - row_buffer); - - bgrowptr += __vesa_info.mi.h_res; - fbrowptr += __vesa_info.mi.logical_scan; - - if (++pixrow == height) { - rowptr += __vesacon_text_cols + 2; - pixrow = 0; - } - if (++pixsrow == height) { - rowsptr += __vesacon_text_cols + 2; - pixsrow = 0; - } - } -} - -/* Bounding box for changed text. The (x1, y1) coordinates are +1! */ -static unsigned int upd_x0 = -1U, upd_x1, upd_y0 = -1U, upd_y1; - -/* Update the range already touched by various variables */ -void __vesacon_doit(void) -{ - if (upd_x1 > upd_x0 && upd_y1 > upd_y0) { - vesacon_update_characters(upd_y0, upd_x0, upd_y1 - upd_y0, - upd_x1 - upd_x0); - upd_x0 = upd_y0 = -1U; - upd_x1 = upd_y1 = 0; - } -} - -/* Mark a range for update; note argument sequence is the same as - vesacon_update_characters() */ -static inline void vesacon_touch(int row, int col, int rows, int cols) -{ - unsigned int y0 = row; - unsigned int x0 = col; - unsigned int y1 = y0 + rows; - unsigned int x1 = x0 + cols; - - if (y0 < upd_y0) - upd_y0 = y0; - if (y1 > upd_y1) - upd_y1 = y1; - if (x0 < upd_x0) - upd_x0 = x0; - if (x1 > upd_x1) - upd_x1 = x1; -} - -/* Erase a region of the screen */ -void __vesacon_erase(int x0, int y0, int x1, int y1, attr_t attr) -{ - int y; - struct vesa_char *ptr = &__vesacon_text_display - [(y0 + 1) * (__vesacon_text_cols + 2) + (x0 + 1)]; - struct vesa_char fill = { - .ch = ' ', - .attr = attr, - }; - int ncols = x1 - x0 + 1; - - for (y = y0; y <= y1; y++) { - vesacon_fill(ptr, fill, ncols); - ptr += __vesacon_text_cols + 2; - } - - vesacon_touch(y0, x0, y1 - y0 + 1, ncols); -} - -/* Scroll the screen up */ -void __vesacon_scroll_up(int nrows, attr_t attr) -{ - struct vesa_char *fromptr = &__vesacon_text_display - [(nrows + 1) * (__vesacon_text_cols + 2)]; - struct vesa_char *toptr = &__vesacon_text_display - [(__vesacon_text_cols + 2)]; - int dword_count = - (__vesacon_text_rows - nrows) * (__vesacon_text_cols + 2); - struct vesa_char fill = { - .ch = ' ', - .attr = attr, - }; - - toptr = copy_dword(toptr, fromptr, dword_count); - - dword_count = nrows * (__vesacon_text_cols + 2); - - vesacon_fill(toptr, fill, dword_count); - - vesacon_touch(0, 0, __vesacon_text_rows, __vesacon_text_cols); -} - -/* Draw one character text at a specific area of the screen */ -void __vesacon_write_char(int x, int y, uint8_t ch, attr_t attr) -{ - struct vesa_char *ptr = &__vesacon_text_display - [(y + 1) * (__vesacon_text_cols + 2) + (x + 1)]; - - ptr->ch = ch; - ptr->attr = attr; - - vesacon_touch(y, x, 1, 1); -} - -void __vesacon_set_cursor(int x, int y, bool visible) -{ - struct vesa_char *ptr = &__vesacon_text_display - [(y + 1) * (__vesacon_text_cols + 2) + (x + 1)]; - - if (cursor_pointer) - vesacon_touch(cursor_y, cursor_x, 1, 1); - - if (!visible) { - /* Invisible cursor */ - cursor_pointer = NULL; - } else { - cursor_pointer = ptr; - vesacon_touch(y, x, 1, 1); - } - - cursor_x = x; - cursor_y = y; -} - -void __vesacon_init_cursor(int font_height) -{ - int r0 = font_height - (font_height < 10 ? 2 : 3); - - if (r0 < 0) - r0 = 0; - - memset(cursor_pattern, 0, font_height); - cursor_pattern[r0] = 0xff; - cursor_pattern[r0 + 1] = 0xff; -} - -void __vesacon_redraw_text(void) -{ - vesacon_update_characters(0, 0, __vesacon_text_rows, __vesacon_text_cols); -} diff --git a/com32/lib/sys/vesa/efi/fill.h b/com32/lib/sys/vesa/efi/fill.h deleted file mode 100644 index 5a43c728..00000000 --- a/com32/lib/sys/vesa/efi/fill.h +++ /dev/null @@ -1,63 +0,0 @@ -/* ----------------------------------------------------------------------- * - * - * Copyright 2006-2008 H. Peter Anvin - All Rights Reserved - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall - * be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * ----------------------------------------------------------------------- */ - -#ifndef LIB_SYS_VESA_FILL_H -#define LIB_SYS_VESA_FILL_H - -#include "video.h" - -/* Fill a number of characters. */ -static inline struct vesa_char *vesacon_fill(struct vesa_char *ptr, - struct vesa_char fill, - unsigned int count) -{ - switch (sizeof(struct vesa_char)) { - case 1: - asm volatile ("rep; stosb":"+D" (ptr), "+c"(count) - :"a"(fill) - :"memory"); - break; - case 2: - asm volatile ("rep; stosw":"+D" (ptr), "+c"(count) - :"a"(fill) - :"memory"); - break; - case 4: - asm volatile ("rep; stosl":"+D" (ptr), "+c"(count) - :"a"(fill) - :"memory"); - break; - default: - while (count--) - *ptr++ = fill; - break; - } - - return ptr; -} - -#endif /* LIB_SYS_VESA_FILL_H */ diff --git a/com32/lib/sys/vesa/efi/fmtpixel.c b/com32/lib/sys/vesa/efi/fmtpixel.c deleted file mode 100644 index 381fc216..00000000 --- a/com32/lib/sys/vesa/efi/fmtpixel.c +++ /dev/null @@ -1,101 +0,0 @@ -/* ----------------------------------------------------------------------- * - * - * Copyright 2006-2008 H. Peter Anvin - All Rights Reserved - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall - * be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * ----------------------------------------------------------------------- */ - -/* - * fmtpixel.c - * - * Functions to format a single pixel - */ - -#include <inttypes.h> -#include "video.h" - -/* - * Format a sequence of pixels. The first argument is the line buffer; - * we can use it to write up to 4 bytes past the end of the last pixel. - * Return the place we should be copying from, this is usually the - * buffer address, but doesn't *have* to be. - */ - -static const void *format_pxf_bgra32(void *ptr, const uint32_t * p, size_t n) -{ - (void)ptr; - (void)n; - return p; /* No conversion needed! */ -} - -static const void *format_pxf_bgr24(void *ptr, const uint32_t * p, size_t n) -{ - char *q = ptr; - - while (n--) { - *(uint32_t *) q = *p++; - q += 3; - } - return ptr; -} - -static const void *format_pxf_le_rgb16_565(void *ptr, const uint32_t * p, - size_t n) -{ - uint32_t bgra; - uint16_t *q = ptr; - - while (n--) { - bgra = *p++; - *q++ = - ((bgra >> 3) & 0x1f) + - ((bgra >> (2 + 8 - 5)) & (0x3f << 5)) + - ((bgra >> (3 + 16 - 11)) & (0x1f << 11)); - } - return ptr; -} - -static const void *format_pxf_le_rgb15_555(void *ptr, const uint32_t * p, - size_t n) -{ - uint32_t bgra; - uint16_t *q = ptr; - - while (n--) { - bgra = *p++; - *q++ = - ((bgra >> 3) & 0x1f) + - ((bgra >> (2 + 8 - 5)) & (0x1f << 5)) + - ((bgra >> (3 + 16 - 10)) & (0x1f << 10)); - } - return ptr; -} - -__vesacon_format_pixels_t __vesacon_format_pixels; - -const __vesacon_format_pixels_t __vesacon_format_pixels_list[PXF_NONE] = { - [PXF_BGRA32] = format_pxf_bgra32, - [PXF_BGR24] = format_pxf_bgr24, - [PXF_LE_RGB16_565] = format_pxf_le_rgb16_565, - [PXF_LE_RGB15_555] = format_pxf_le_rgb15_555, -}; diff --git a/com32/lib/sys/vesa/efi/i915resolution.c b/com32/lib/sys/vesa/efi/i915resolution.c deleted file mode 100644 index ac66175f..00000000 --- a/com32/lib/sys/vesa/efi/i915resolution.c +++ /dev/null @@ -1,795 +0,0 @@ -/* ----------------------------------------------------------------------- * - * - * Copyright 2010 Intel Corporation; author: H. Peter Anvin - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall - * be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * ----------------------------------------------------------------------- */ - -/* - * Based on: - * - * 915 resolution by steve tomljenovic - * - * This was tested only on Sony VGN-FS550. Use at your own risk - * - * This code is based on the techniques used in : - * - * - 855patch. Many thanks to Christian Zietz (czietz gmx net) - * for demonstrating how to shadow the VBIOS into system RAM - * and then modify it. - * - * - 1280patch by Andrew Tipton (andrewtipton null li). - * - * - 855resolution by Alain Poirier - * - * This source code is into the public domain. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#define __USE_GNU -#include <string.h> -#include <sys/io.h> -#include <sys/cpu.h> -#include <sys/pci.h> -#include <unistd.h> -#include <assert.h> -#include <stdbool.h> -#include "video.h" -#include "debug.h" - -#define VBIOS_START 0xc0000 -#define VBIOS_SIZE 0x10000 - -#define MODE_TABLE_OFFSET_845G 617 - -#define VERSION "0.5.3" - -#define ATI_SIGNATURE1 "ATI MOBILITY RADEON" -#define ATI_SIGNATURE2 "ATI Technologies Inc" -#define NVIDIA_SIGNATURE "NVIDIA Corp" -#define INTEL_SIGNATURE "Intel Corp" - -typedef unsigned char * address; - -typedef enum { - CT_UNKWN, CT_830, CT_845G, CT_855GM, CT_865G, CT_915G, CT_915GM, - CT_945G, CT_945GM, CT_946GZ, CT_G965, CT_Q965, CT_945GME, - CHIPSET_TYPES -} chipset_type; - -typedef enum { - BT_UNKWN, BT_1, BT_2, BT_3 -} bios_type; - -static int freqs[] = { 60, 75, 85 }; - -typedef struct { - uint8_t mode; - uint8_t bits_per_pixel; - uint16_t resolution; - uint8_t unknown; -} __attribute__((packed)) vbios_mode; - -typedef struct { - uint16_t clock; /* Clock frequency in 10 kHz */ - uint8_t x1; - uint8_t x_total; - uint8_t x2; - uint8_t y1; - uint8_t y_total; - uint8_t y2; -} __attribute__((packed)) vbios_resolution_type1; - -typedef struct { - uint32_t clock; - - uint16_t x1; - uint16_t htotal; - uint16_t x2; - uint16_t hblank; - uint16_t hsyncstart; - uint16_t hsyncend; - - uint16_t y1; - uint16_t vtotal; - uint16_t y2; - uint16_t vblank; - uint16_t vsyncstart; - uint16_t vsyncend; -} __attribute__((packed)) vbios_modeline_type2; - -typedef struct { - uint8_t xchars; - uint8_t ychars; - uint8_t unknown[4]; - - vbios_modeline_type2 modelines[]; -} __attribute__((packed)) vbios_resolution_type2; - -typedef struct { - uint32_t clock; - - uint16_t x1; - uint16_t htotal; - uint16_t x2; - uint16_t hblank; - uint16_t hsyncstart; - uint16_t hsyncend; - - uint16_t y1; - uint16_t vtotal; - uint16_t y2; - uint16_t vblank; - uint16_t vsyncstart; - uint16_t vsyncend; - - uint16_t timing_h; - uint16_t timing_v; - - uint8_t unknown[6]; -} __attribute__((packed)) vbios_modeline_type3; - -typedef struct { - unsigned char unknown[6]; - - vbios_modeline_type3 modelines[]; -} __attribute__((packed)) vbios_resolution_type3; - - -typedef struct { - unsigned int chipset_id; - chipset_type chipset; - bios_type bios; - - address bios_ptr; - - vbios_mode * mode_table; - unsigned int mode_table_size; - - uint8_t b1, b2; - - bool unlocked; -} vbios_map; - -#if 0 /* Debugging hacks */ -static void good_marker(int x) -{ - ((uint16_t *)0xb8000)[x] = 0x2f30 - ((x & 0xf0) << 4) + (x & 0x0f); -} - -static void bad_marker(int x) -{ - ((uint16_t *)0xb8000)[x] = 0x4f30 - ((x & 0xf0) << 4) + (x & 0x0f); -} - -static void status(const char *fmt, ...) -{ - va_list ap; - char msg[81], *p; - int i; - uint16_t *q; - - memset(msg, 0, sizeof msg); - va_start(ap, fmt); - vsnprintf(msg, sizeof msg, fmt, ap); - va_end(ap); - p = msg; - q = (uint16_t *)0xb8000 + 80; - for (i = 0; i < 80; i++) - *q++ = *p++ + 0x1f00; -} -#else -static inline void good_marker(int x) { (void)x; } -static inline void bad_marker(int x) { (void)x; } -static inline void status(const char *fmt, ...) { (void)fmt; } -#endif - -static unsigned int get_chipset_id(void) { - return pci_readl(0x80000000); -} - -static chipset_type get_chipset(unsigned int id) { - chipset_type type; - - switch (id) { - case 0x35758086: - type = CT_830; - break; - - case 0x25608086: - type = CT_845G; - break; - - case 0x35808086: - type = CT_855GM; - break; - - case 0x25708086: - type = CT_865G; - break; - - case 0x25808086: - type = CT_915G; - break; - - case 0x25908086: - type = CT_915GM; - break; - - case 0x27708086: - type = CT_945G; - break; - - case 0x27a08086: - type = CT_945GM; - break; - - case 0x29708086: - type = CT_946GZ; - break; - - case 0x29a08086: - type = CT_G965; - break; - - case 0x29908086: - type = CT_Q965; - break; - - case 0x27ac8086: - type = CT_945GME; - break; - - default: - type = CT_UNKWN; - break; - } - - return type; -} - - -static vbios_resolution_type1 * map_type1_resolution(vbios_map * map, - uint16_t res) -{ - vbios_resolution_type1 * ptr = ((vbios_resolution_type1*)(map->bios_ptr + res)); - return ptr; -} - -static vbios_resolution_type2 * map_type2_resolution(vbios_map * map, - uint16_t res) -{ - vbios_resolution_type2 * ptr = ((vbios_resolution_type2*)(map->bios_ptr + res)); - return ptr; -} - -static vbios_resolution_type3 * map_type3_resolution(vbios_map * map, - uint16_t res) -{ - vbios_resolution_type3 * ptr = ((vbios_resolution_type3*)(map->bios_ptr + res)); - return ptr; -} - - -static bool detect_bios_type(vbios_map * map, int entry_size) -{ - unsigned int i; - uint16_t r1, r2; - - r1 = r2 = 32000; - - for (i = 0; i < map->mode_table_size; i++) { - if (map->mode_table[i].resolution <= r1) { - r1 = map->mode_table[i].resolution; - } else if (map->mode_table[i].resolution <= r2) { - r2 = map->mode_table[i].resolution; - } - } - - return ((r2-r1-6) % entry_size) == 0; -} - -static inline void close_vbios(vbios_map *map) -{ - (void)map; -} - -static vbios_map * open_vbios(void) -{ - static vbios_map _map; - vbios_map * const map = &_map; - - memset(&_map, 0, sizeof _map); - - /* - * Determine chipset - */ - map->chipset_id = get_chipset_id(); - good_marker(0x10); - map->chipset = get_chipset(map->chipset_id); - good_marker(0x11); - - /* - * Map the video bios to memory - */ - map->bios_ptr = (void *)VBIOS_START; - - /* - * check if we have ATI Radeon - */ - - if (memmem(map->bios_ptr, VBIOS_SIZE, ATI_SIGNATURE1, strlen(ATI_SIGNATURE1)) || - memmem(map->bios_ptr, VBIOS_SIZE, ATI_SIGNATURE2, strlen(ATI_SIGNATURE2)) ) { - debug("ATI chipset detected. 915resolution only works with Intel 800/900 series graphic chipsets.\r\n"); - return NULL; - } - - /* - * check if we have NVIDIA - */ - - if (memmem(map->bios_ptr, VBIOS_SIZE, NVIDIA_SIGNATURE, strlen(NVIDIA_SIGNATURE))) { - debug("NVIDIA chipset detected. 915resolution only works with Intel 800/900 series graphic chipsets.\r\n"); - return NULL; - } - - /* - * check if we have Intel - */ - - if (map->chipset == CT_UNKWN && memmem(map->bios_ptr, VBIOS_SIZE, INTEL_SIGNATURE, strlen(INTEL_SIGNATURE))) { - debug("Intel chipset detected. However, 915resolution was unable to determine the chipset type.\r\n"); - - debug("Chipset Id: %x\r\n", map->chipset_id); - - debug("Please report this problem to stomljen@yahoo.com\r\n"); - - close_vbios(map); - return NULL; - } - - /* - * check for others - */ - - if (map->chipset == CT_UNKWN) { - debug("Unknown chipset type and unrecognized bios.\r\n"); - debug("915resolution only works with Intel 800/900 series graphic chipsets.\r\n"); - - debug("Chipset Id: %x\r\n", map->chipset_id); - close_vbios(map); - return NULL; - } - - /* - * Figure out where the mode table is - */ - good_marker(0x12); - - { - address p = map->bios_ptr + 16; - address limit = map->bios_ptr + VBIOS_SIZE - (3 * sizeof(vbios_mode)); - - while (p < limit && map->mode_table == 0) { - vbios_mode * mode_ptr = (vbios_mode *) p; - - if (((mode_ptr[0].mode & 0xf0) == 0x30) && ((mode_ptr[1].mode & 0xf0) == 0x30) && - ((mode_ptr[2].mode & 0xf0) == 0x30) && ((mode_ptr[3].mode & 0xf0) == 0x30)) { - - map->mode_table = mode_ptr; - } - - p++; - } - - if (map->mode_table == 0) { - debug("Unable to locate the mode table.\r\n"); - close_vbios(map); - return NULL; - } - } - good_marker(0x13); - - /* - * Determine size of mode table - */ - - { - vbios_mode * mode_ptr = map->mode_table; - - while (mode_ptr->mode != 0xff) { - map->mode_table_size++; - mode_ptr++; - } - } - good_marker(0x14); - status("mode_table_size = %d", map->mode_table_size); - - /* - * Figure out what type of bios we have - * order of detection is important - */ - - if (detect_bios_type(map, sizeof(vbios_modeline_type3))) { - map->bios = BT_3; - } - else if (detect_bios_type(map, sizeof(vbios_modeline_type2))) { - map->bios = BT_2; - } - else if (detect_bios_type(map, sizeof(vbios_resolution_type1))) { - map->bios = BT_1; - } - else { - debug("Unable to determine bios type.\r\n"); - debug("Mode Table Offset: $C0000 + $%x\r\n", ((unsigned long)map->mode_table) - ((unsigned long)map->bios_ptr)); - debug("Mode Table Entries: %u\r\n", map->mode_table_size); - bad_marker(0x15); - return NULL; - } - good_marker(0x15); - - return map; -} - -static void unlock_vbios(vbios_map * map) -{ - assert(!map->unlocked); - - map->unlocked = true; - - switch (map->chipset) { - case CT_UNKWN: - case CHIPSET_TYPES: /* Shut up gcc */ - break; - case CT_830: - case CT_855GM: - map->b1 = pci_readb(0x8000005a); - pci_writeb(0x33, 0x8000005a); - break; - case CT_845G: - case CT_865G: - case CT_915G: - case CT_915GM: - case CT_945G: - case CT_945GM: - case CT_945GME: - case CT_946GZ: - case CT_G965: - case CT_Q965: - map->b1 = pci_readb(0x80000091); - map->b2 = pci_readb(0x80000092); - pci_writeb(0x33, 0x80000091); - pci_writeb(0x33, 0x80000092); - break; - } - -#if DEBUG - { - unsigned int t = inl(0xcfc); - debug("unlock PAM: (0x%08x)\r\n", t); - } -#endif -} - -static void relock_vbios(vbios_map * map) -{ - assert(map->unlocked); - map->unlocked = false; - - switch (map->chipset) { - case CT_UNKWN: - case CHIPSET_TYPES: /* Shut up gcc */ - break; - case CT_830: - case CT_855GM: - pci_writeb(map->b1, 0x8000005a); - break; - case CT_845G: - case CT_865G: - case CT_915G: - case CT_915GM: - case CT_945G: - case CT_945GM: - case CT_945GME: - case CT_946GZ: - case CT_G965: - case CT_Q965: - pci_writeb(map->b1, 0x80000091); - pci_writeb(map->b2, 0x80000092); - break; - } - -#if DEBUG - { - unsigned int t = inl(0xcfc); - debug("relock PAM: (0x%08x)\r\n", t); - } -#endif -} - -#if 0 -static void list_modes(vbios_map *map, unsigned int raw) -{ - unsigned int i, x, y; - - for (i=0; i < map->mode_table_size; i++) { - switch(map->bios) { - case BT_1: - { - vbios_resolution_type1 * res = map_type1_resolution(map, map->mode_table[i].resolution); - - x = ((((unsigned int) res->x2) & 0xf0) << 4) | res->x1; - y = ((((unsigned int) res->y2) & 0xf0) << 4) | res->y1; - - if (x != 0 && y != 0) { - debug("Mode %02x : %dx%d, %d bits/pixel\r\n", map->mode_table[i].mode, x, y, map->mode_table[i].bits_per_pixel); - } - - if (raw) - { - debug("Mode %02x (raw) :\r\n\t%02x %02x\r\n\t%02x\r\n\t%02x\r\n\t%02x\r\n\t%02x\r\n\t%02x\r\n\t%02x\r\n", map->mode_table[i].mode, res->unknow1[0],res->unknow1[1], res->x1,res->x_total,res->x2,res->y1,res->y_total,res->y2); - } - - } - break; - case BT_2: - { - vbios_resolution_type2 * res = map_type2_resolution(map, map->mode_table[i].resolution); - - x = res->modelines[0].x1+1; - y = res->modelines[0].y1+1; - - if (x != 0 && y != 0) { - debug("Mode %02x : %dx%d, %d bits/pixel\r\n", map->mode_table[i].mode, x, y, map->mode_table[i].bits_per_pixel); - } - } - break; - case BT_3: - { - vbios_resolution_type3 * res = map_type3_resolution(map, map->mode_table[i].resolution); - - x = res->modelines[0].x1+1; - y = res->modelines[0].y1+1; - - if (x != 0 && y != 0) { - debug("Mode %02x : %dx%d, %d bits/pixel\r\n", map->mode_table[i].mode, x, y, map->mode_table[i].bits_per_pixel); - } - } - break; - case BT_UNKWN: - break; - } - } -} -#endif - -static void gtf_timings(int x, int y, int freq, uint32_t *clock, - uint16_t *hsyncstart, uint16_t *hsyncend, uint16_t *hblank, - uint16_t *vsyncstart, uint16_t *vsyncend, uint16_t *vblank) -{ - int hbl, vbl, vfreq; - - vbl = y + (y+1)/(20000.0/(11*freq) - 1) + 1.5; - vfreq = vbl * freq; - hbl = 16 * (int)(x * (30.0 - 300000.0 / vfreq) / - (70.0 + 300000.0 / vfreq) / 16.0 + 0.5); - - *vsyncstart = y; - *vsyncend = y + 3; - *vblank = vbl - 1; - *hsyncstart = x + hbl / 2 - (x + hbl + 50) / 100 * 8 - 1; - *hsyncend = x + hbl / 2 - 1; - *hblank = x + hbl - 1; - *clock = (x + hbl) * vfreq / 1000; -} - -static int set_mode(vbios_map * map, unsigned int mode, - unsigned int x, unsigned int y, unsigned int bp, - unsigned int htotal, unsigned int vtotal) -{ - int xprev, yprev; - unsigned int i, j; - int rv = -1; - - for (i=0; i < map->mode_table_size; i++) { - if (map->mode_table[i].mode == mode) { - switch(map->bios) { - case BT_1: - { - vbios_resolution_type1 * res = map_type1_resolution(map, map->mode_table[i].resolution); - uint32_t clock; - uint16_t hsyncstart, hsyncend, hblank; - uint16_t vsyncstart, vsyncend, vblank; - - if (bp) { - map->mode_table[i].bits_per_pixel = bp; - } - - gtf_timings(x, y, freqs[0], &clock, - &hsyncstart, &hsyncend, &hblank, - &vsyncstart, &vsyncend, &vblank); - - status("x = %d, y = %d, clock = %lu, h = %d %d %d, v = %d %d %d\n", - x, y, clock, - hsyncstart, hsyncend, hblank, - vsyncstart, vsyncend, vblank); - - htotal = htotal ? htotal : (unsigned int)hblank+1; - vtotal = vtotal ? vtotal : (unsigned int)vblank+1; - - res->clock = clock/10; /* Units appear to be 10 kHz */ - res->x2 = (((htotal-x) >> 8) & 0x0f) | ((x >> 4) & 0xf0); - res->x1 = (x & 0xff); - - res->y2 = (((vtotal-y) >> 8) & 0x0f) | ((y >> 4) & 0xf0); - res->y1 = (y & 0xff); - if (htotal) - res->x_total = ((htotal-x) & 0xff); - - if (vtotal) - res->y_total = ((vtotal-y) & 0xff); - - rv = 0; - } - break; - case BT_2: - { - vbios_resolution_type2 * res = map_type2_resolution(map, map->mode_table[i].resolution); - - res->xchars = x / 8; - res->ychars = y / 16 - 1; - xprev = res->modelines[0].x1; - yprev = res->modelines[0].y1; - - for(j=0; j < 3; j++) { - vbios_modeline_type2 * modeline = &res->modelines[j]; - - if (modeline->x1 == xprev && modeline->y1 == yprev) { - modeline->x1 = modeline->x2 = x-1; - modeline->y1 = modeline->y2 = y-1; - - gtf_timings(x, y, freqs[j], &modeline->clock, - &modeline->hsyncstart, &modeline->hsyncend, - &modeline->hblank, &modeline->vsyncstart, - &modeline->vsyncend, &modeline->vblank); - - if (htotal) - modeline->htotal = htotal; - else - modeline->htotal = modeline->hblank; - - if (vtotal) - modeline->vtotal = vtotal; - else - modeline->vtotal = modeline->vblank; - } - } - - rv = 0; - } - break; - case BT_3: - { - vbios_resolution_type3 * res = map_type3_resolution(map, map->mode_table[i].resolution); - - xprev = res->modelines[0].x1; - yprev = res->modelines[0].y1; - - for (j=0; j < 3; j++) { - vbios_modeline_type3 * modeline = &res->modelines[j]; - - if (modeline->x1 == xprev && modeline->y1 == yprev) { - modeline->x1 = modeline->x2 = x-1; - modeline->y1 = modeline->y2 = y-1; - - gtf_timings(x, y, freqs[j], &modeline->clock, - &modeline->hsyncstart, &modeline->hsyncend, - &modeline->hblank, &modeline->vsyncstart, - &modeline->vsyncend, &modeline->vblank); - if (htotal) - modeline->htotal = htotal; - else - modeline->htotal = modeline->hblank; - if (vtotal) - modeline->vtotal = vtotal; - else - modeline->vtotal = modeline->vblank; - - modeline->timing_h = y-1; - modeline->timing_v = x-1; - } - } - - rv = 0; - } - break; - case BT_UNKWN: - break; - } - } - } - - return rv; -} - -static inline void display_map_info(vbios_map * map) { -#ifdef DEBUG - static const char * bios_type_names[] = - {"UNKNOWN", "TYPE 1", "TYPE 2", "TYPE 3"}; - static const char * chipset_type_names[] = { - "UNKNOWN", "830", "845G", "855GM", "865G", "915G", "915GM", "945G", - "945GM", "946GZ", "G965", "Q965", "945GME" - }; - - debug("Chipset: %s\r\n", chipset_type_names[map->chipset]); - debug("BIOS: %s\r\n", bios_type_names[map->bios]); - - debug("Mode Table Offset: $C0000 + $%x\r\n", - ((unsigned int)map->mode_table) - ((unsigned int)map->bios_ptr)); - debug("Mode Table Entries: %u\r\n", map->mode_table_size); -#endif - (void)map; -} - -int __vesacon_i915resolution(int x, int y) -{ - vbios_map * map; - unsigned int mode = 0x52; /* 800x600x32 mode in known BIOSes */ - unsigned int bp = 32; /* 32 bits per pixel */ - int rv = 0; - - good_marker(0); - - map = open_vbios(); - if (!map) - return -1; - - good_marker(1); - - display_map_info(map); - - debug("\r\n"); - - if (mode && x && y) { - good_marker(2); - cli(); - good_marker(3); - unlock_vbios(map); - good_marker(4); - rv = set_mode(map, mode, x, y, bp, 0, 0); - if (rv) - bad_marker(5); - else - good_marker(5); - relock_vbios(map); - good_marker(6); - sti(); - - debug("Patch mode %02x to resolution %dx%d complete\r\n", mode, x, y); - } - close_vbios(map); - - return rv; -} diff --git a/com32/lib/sys/vesa/efi/screencpy.c b/com32/lib/sys/vesa/efi/screencpy.c deleted file mode 100644 index 2e191c7e..00000000 --- a/com32/lib/sys/vesa/efi/screencpy.c +++ /dev/null @@ -1,75 +0,0 @@ -/* ----------------------------------------------------------------------- * - * - * Copyright 2008 H. Peter Anvin - All Rights Reserved - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall - * be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * ----------------------------------------------------------------------- */ - -#include <inttypes.h> -#include <minmax.h> -#include <klibc/compiler.h> -#include <string.h> -#include <com32.h> -#include <ilog2.h> -#include "vesa.h" -#include "video.h" - -static struct win_info { - char *win_base; - size_t win_pos; - size_t win_size; - int win_gshift; - int win_num; -} wi; - -void __vesacon_init_copy_to_screen(void) -{ - struct vesa_mode_info *const mi = &__vesa_info.mi; - - if (mi->mode_attr & 0x0080) { - /* Linear frame buffer */ - - wi.win_base = (char *)mi->lfb_ptr; - wi.win_size = mi->lfb_line_size*mi->v_res; /* one giant window */ - wi.win_pos = 0; /* Already positioned (only one position...) */ - wi.win_num = -1; /* Not a window */ - } - /* FIXME: PixelBltOnly mode is unsupported */ -} - -void __vesacon_copy_to_screen(size_t dst, const uint32_t * src, size_t npixels) -{ - size_t win_off; - char *win_base = wi.win_base; - size_t bytes = npixels * __vesacon_bytes_per_pixel; - char rowbuf[bytes + 4] __aligned(4); - const char *s; - - s = (const char *)__vesacon_format_pixels(rowbuf, src, npixels); - - /* For EFI, we simply take the offset from the framebuffer and write to it - * FIXME: any gotchas? - */ - win_off = dst; - memcpy(win_base + win_off, s, bytes); -} diff --git a/com32/lib/sys/vesa/efi/vesa.h b/com32/lib/sys/vesa/efi/vesa.h deleted file mode 100644 index 81583c6b..00000000 --- a/com32/lib/sys/vesa/efi/vesa.h +++ /dev/null @@ -1,129 +0,0 @@ -/* ----------------------------------------------------------------------- * - * - * Copyright 1999-2008 H. Peter Anvin - All Rights Reserved - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall - * be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * ----------------------------------------------------------------------- */ - -#ifndef LIB_SYS_VESA_H -#define LIB_SYS_VESA_H - -#include <inttypes.h> -#include <com32.h> - -/* VESA General Information table */ -struct vesa_general_info { - uint32_t signature; /* Magic number = "VESA" */ - uint16_t version; - far_ptr_t vendor_string; - uint8_t capabilities[4]; - far_ptr_t video_mode_ptr; - uint16_t total_memory; - - uint16_t oem_software_rev; - far_ptr_t oem_vendor_name_ptr; - far_ptr_t oem_product_name_ptr; - far_ptr_t oem_product_rev_ptr; - - uint8_t reserved[222]; - uint8_t oem_data[256]; -} __attribute__ ((packed)); - -#define VESA_MAGIC ('V' + ('E' << 8) + ('S' << 16) + ('A' << 24)) -#define VBE2_MAGIC ('V' + ('B' << 8) + ('E' << 16) + ('2' << 24)) - -struct vesa_mode_info { - uint16_t mode_attr; - uint8_t win_attr[2]; - uint16_t win_grain; - uint16_t win_size; - uint16_t win_seg[2]; - far_ptr_t win_scheme; - uint16_t logical_scan; - - uint16_t h_res; - uint16_t v_res; - uint8_t char_width; - uint8_t char_height; - uint8_t memory_planes; - uint8_t bpp; - uint8_t banks; - uint8_t memory_layout; - uint8_t bank_size; - uint8_t image_pages; - uint8_t page_function; - - uint8_t rmask; - uint8_t rpos; - uint8_t gmask; - uint8_t gpos; - uint8_t bmask; - uint8_t bpos; - uint8_t resv_mask; - uint8_t resv_pos; - uint8_t dcm_info; - - uint8_t *lfb_ptr; /* Linear frame buffer address */ -#ifdef SYSLINUX_EFI - /* GOP provides info about FrameBufferBase and Size - * Are these types consistent with EFI definition? - */ - uint32_t lfb_size; /* frame buffer size */ - uint16_t lfb_line_size; /* length of a line in bytes in frame buffer */ - /* the following pixel sizes are relevant only if the - * pixel format for the GOP mode is PixelBitMask - */ - uint8_t resv_size; - uint8_t lfb_rsize; - uint8_t lfb_gsize; - uint8_t lfb_bsize; - uint8_t lfb_resv_size; -#endif - uint8_t *offscreen_ptr; /* Offscreen memory address */ - uint16_t offscreen_size; - - uint8_t reserved[206]; -} __attribute__ ((packed)); - -struct vesa_info { - struct vesa_general_info gi; - struct vesa_mode_info mi; -}; - -extern struct vesa_info __vesa_info; - -#if 0 -static inline void vesa_debug(uint32_t color, int pos) -{ - uint32_t *stp = (uint32_t *) __vesa_info.mi.lfb_ptr; - stp[pos * 3] = color; -} -#else -static inline void vesa_debug(uint32_t color, int pos) -{ - (void)color; - (void)pos; -} -#endif - -#endif /* LIB_SYS_VESA_H */ diff --git a/com32/lib/sys/vesa/efi/video.h b/com32/lib/sys/vesa/efi/video.h deleted file mode 100644 index bc24af6b..00000000 --- a/com32/lib/sys/vesa/efi/video.h +++ /dev/null @@ -1,98 +0,0 @@ -/* ----------------------------------------------------------------------- * - * - * Copyright 2006-2008 H. Peter Anvin - All Rights Reserved - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall - * be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * ----------------------------------------------------------------------- */ - -#ifndef LIB_SYS_VESA_VIDEO_H -#define LIB_SYS_VESA_VIDEO_H - -#include <stdbool.h> -#include <colortbl.h> -#include "vesa.h" - -#define FONT_MAX_CHARS 256 -#define FONT_MAX_HEIGHT 32 -#define FONT_WIDTH 8 - -#define DEFAULT_VESA_X_SIZE 640 -#define DEFAULT_VESA_Y_SIZE 480 - -#define VIDEO_BORDER 8 -#define TEXT_PIXEL_ROWS (__vesa_info.mi.v_res - 2*VIDEO_BORDER) -#define TEXT_PIXEL_COLS (__vesa_info.mi.h_res - 2*VIDEO_BORDER) - -typedef uint16_t attr_t; - -struct vesa_char { - uint8_t ch; /* Character */ - uint8_t _filler; /* Currently unused */ - attr_t attr; /* Color table index */ -}; - -/* Pixel formats in order of decreasing preference; PXF_NONE should be last */ -/* BGR24 is preferred over BGRA32 since the I/O overhead is smaller. */ -enum vesa_pixel_format { - PXF_BGR24, /* 24-bit BGR */ - PXF_BGRA32, /* 32-bit BGRA */ - PXF_LE_RGB16_565, /* 16-bit littleendian 5:6:5 RGB */ - PXF_LE_RGB15_555, /* 15-bit littleendian 5:5:5 RGB */ - PXF_NONE -}; -extern enum vesa_pixel_format __vesacon_pixel_format; -extern unsigned int __vesacon_bytes_per_pixel; -typedef const void *(*__vesacon_format_pixels_t) - (void *, const uint32_t *, size_t); -extern __vesacon_format_pixels_t __vesacon_format_pixels; -extern const __vesacon_format_pixels_t __vesacon_format_pixels_list[PXF_NONE]; - -extern struct vesa_char *__vesacon_text_display; - -extern int __vesacon_font_height; -extern int __vesacon_text_rows; -extern int __vesacon_text_cols; -extern uint8_t __vesacon_graphics_font[FONT_MAX_CHARS][FONT_MAX_HEIGHT]; -extern uint32_t *__vesacon_background; -extern uint32_t *__vesacon_shadowfb; - -extern const uint16_t __vesacon_srgb_to_linear[256]; -extern const uint8_t __vesacon_linear_to_srgb[4080]; - -int __vesacon_init_background(void); -int vesacon_load_background(const char *); -/* Prototype changes to deal with video mode resolution changes */ -int __vesacon_init(int *, int *); -void __vesacon_init_cursor(int); -void __vesacon_erase(int, int, int, int, attr_t); -void __vesacon_scroll_up(int, attr_t); -void __vesacon_write_char(int, int, uint8_t, attr_t); -void __vesacon_redraw_text(void); -void __vesacon_doit(void); -void __vesacon_set_cursor(int, int, bool); -void __vesacon_copy_to_screen(size_t, const uint32_t *, size_t); -void __vesacon_init_copy_to_screen(void); - -int __vesacon_i915resolution(int x, int y); - -#endif /* LIB_SYS_VESA_VIDEO_H */ diff --git a/com32/lib/sys/vesa/initvesa.c b/com32/lib/sys/vesa/initvesa.c index d227629d..c2721b8d 100644 --- a/com32/lib/sys/vesa/initvesa.c +++ b/com32/lib/sys/vesa/initvesa.c @@ -69,37 +69,12 @@ static void unpack_font(uint8_t * dst, uint8_t * src, int height) } } -static int __constfunc is_power_of_2(unsigned int x) +static int vesacon_set_mode(int *x, int *y) { - return x && !(x & (x - 1)); -} - -static int vesacon_paged_mode_ok(const struct vesa_mode_info *mi) -{ - int i; - - if (!is_power_of_2(mi->win_size) || - !is_power_of_2(mi->win_grain) || mi->win_grain > mi->win_size) - return 0; /* Impossible... */ - - for (i = 0; i < 2; i++) { - if ((mi->win_attr[i] & 0x05) == 0x05 && mi->win_seg[i]) - return 1; /* Usable window */ - } - - return 0; /* Nope... */ -} - -static int vesacon_set_mode(int x, int y) -{ - com32sys_t rm; uint8_t *rom_font; - uint16_t mode, bestmode, *mode_ptr; - struct vesa_info *vi; - struct vesa_general_info *gi; struct vesa_mode_info *mi; - enum vesa_pixel_format pxf, bestpxf; - int err = 0; + enum vesa_pixel_format bestpxf; + int rv; debug("Hello, World!\r\n"); @@ -113,172 +88,22 @@ static int vesacon_set_mode(int x, int y) __vesacon_shadowfb = NULL; } - /* Allocate space in the bounce buffer for these structures */ - vi = lzalloc(sizeof *vi); - if (!vi) { - err = 10; /* Out of memory */ - goto exit; - } - gi = &vi->gi; - mi = &vi->mi; - - memset(&rm, 0, sizeof rm); - - gi->signature = VBE2_MAGIC; /* Get VBE2 extended data */ - rm.eax.w[0] = 0x4F00; /* Get SVGA general information */ - rm.edi.w[0] = OFFS(gi); - rm.es = SEG(gi); - __intcall(0x10, &rm, &rm); - - if (rm.eax.w[0] != 0x004F) { - err = 1; /* Function call failed */ - goto exit; - } - if (gi->signature != VESA_MAGIC) { - err = 2; /* No magic */ - goto exit; - } - if (gi->version < 0x0102) { - err = 3; /* VESA 1.2+ required */ - goto exit; - } - - /* Copy general info */ - memcpy(&__vesa_info.gi, gi, sizeof *gi); - - /* Search for the proper mode with a suitable color and memory model... */ - - mode_ptr = GET_PTR(gi->video_mode_ptr); - bestmode = 0; - bestpxf = PXF_NONE; - - while ((mode = *mode_ptr++) != 0xFFFF) { - mode &= 0x1FF; /* The rest are attributes of sorts */ - - debug("Found mode: 0x%04x\r\n", mode); - - memset(mi, 0, sizeof *mi); - rm.eax.w[0] = 0x4F01; /* Get SVGA mode information */ - rm.ecx.w[0] = mode; - rm.edi.w[0] = OFFS(mi); - rm.es = SEG(mi); - __intcall(0x10, &rm, &rm); - - /* Must be a supported mode */ - if (rm.eax.w[0] != 0x004f) - continue; - - debug - ("mode_attr 0x%04x, h_res = %4d, v_res = %4d, bpp = %2d, layout = %d (%d,%d,%d)\r\n", - mi->mode_attr, mi->h_res, mi->v_res, mi->bpp, mi->memory_layout, - mi->rpos, mi->gpos, mi->bpos); - - /* Must be an LFB color graphics mode supported by the hardware. - - The bits tested are: - 4 - graphics mode - 3 - color mode - 1 - mode information available (mandatory in VBE 1.2+) - 0 - mode supported by hardware - */ - if ((mi->mode_attr & 0x001b) != 0x001b) - continue; - - /* Must be the chosen size */ - if (mi->h_res != x || mi->v_res != y) - continue; - - /* We don't support multibank (interlaced memory) modes */ - /* - * Note: The Bochs VESA BIOS (vbe.c 1.58 2006/08/19) violates the - * specification which states that banks == 1 for unbanked modes; - * fortunately it does report bank_size == 0 for those. - */ - if (mi->banks > 1 && mi->bank_size) { - debug("bad: banks = %d, banksize = %d, pages = %d\r\n", - mi->banks, mi->bank_size, mi->image_pages); - continue; - } - - /* Must be either a flat-framebuffer mode, or be an acceptable - paged mode */ - if (!(mi->mode_attr & 0x0080) && !vesacon_paged_mode_ok(mi)) { - debug("bad: invalid paged mode\r\n"); - continue; - } - - /* Must either be a packed-pixel mode or a direct color mode - (depending on VESA version ); must be a supported pixel format */ - pxf = PXF_NONE; /* Not usable */ - - if (mi->bpp == 32 && - (mi->memory_layout == 4 || - (mi->memory_layout == 6 && mi->rpos == 16 && mi->gpos == 8 && - mi->bpos == 0))) - pxf = PXF_BGRA32; - else if (mi->bpp == 24 && - (mi->memory_layout == 4 || - (mi->memory_layout == 6 && mi->rpos == 16 && mi->gpos == 8 && - mi->bpos == 0))) - pxf = PXF_BGR24; - else if (mi->bpp == 16 && - (mi->memory_layout == 4 || - (mi->memory_layout == 6 && mi->rpos == 11 && mi->gpos == 5 && - mi->bpos == 0))) - pxf = PXF_LE_RGB16_565; - else if (mi->bpp == 15 && - (mi->memory_layout == 4 || - (mi->memory_layout == 6 && mi->rpos == 10 && mi->gpos == 5 && - mi->bpos == 0))) - pxf = PXF_LE_RGB15_555; - - if (pxf < bestpxf) { - debug("Best mode so far, pxf = %d\r\n", pxf); - - /* Best mode so far... */ - bestmode = mode; - bestpxf = pxf; - - /* Copy mode info */ - memcpy(&__vesa_info.mi, mi, sizeof *mi); - } - } - - if (bestpxf == PXF_NONE) { - err = 4; /* No mode found */ - goto exit; - } + rv = firmware->vesa->set_mode(&__vesa_info, x, y, &bestpxf); + if (rv) + return rv; mi = &__vesa_info.mi; - mode = bestmode; __vesacon_bytes_per_pixel = (mi->bpp + 7) >> 3; __vesacon_format_pixels = __vesacon_format_pixels_list[bestpxf]; - /* Download the SYSLINUX- or BIOS-provided font */ + /* Download the SYSLINUX- or firmware-provided font */ __vesacon_font_height = syslinux_font_query(&rom_font); - if (!__vesacon_font_height) { - /* Get BIOS 8x16 font */ - - rm.eax.w[0] = 0x1130; /* Get Font Information */ - rm.ebx.w[0] = 0x0600; /* Get 8x16 ROM font */ - __intcall(0x10, &rm, &rm); - rom_font = MK_PTR(rm.es, rm.ebp.w[0]); - __vesacon_font_height = 16; - } + if (!__vesacon_font_height) + __vesacon_font_height = firmware->vesa->font_query(&rom_font); + unpack_font((uint8_t *) __vesacon_graphics_font, rom_font, __vesacon_font_height); - /* Now set video mode */ - rm.eax.w[0] = 0x4F02; /* Set SVGA video mode */ - if (mi->mode_attr & 0x0080) - mode |= 0x4000; /* Request linear framebuffer if supported */ - rm.ebx.w[0] = mode; - __intcall(0x10, &rm, &rm); - if (rm.eax.w[0] != 0x004F) { - err = 9; /* Failed to set mode */ - goto exit; - } - __vesacon_background = calloc(mi->h_res*mi->v_res, 4); __vesacon_shadowfb = calloc(mi->h_res*mi->v_res, 4); @@ -295,13 +120,17 @@ static int vesacon_set_mode(int x, int y) __vesacon_pixel_format = bestpxf; -exit: - if (vi) - lfree(vi); - - return err; + return 0; } +/* FIXME: + * Does init_text_display need an EFI counterpart? + * e.g. vesa_char may need to setup UNICODE char for EFI + * and the number of screen chars may need to be sized up + * accordingly. This may also require turning byte strings + * into unicode strings in the framebuffer + * Possibly, revisit vesacon_fill() for EFI. + */ static int init_text_display(void) { size_t nchars; @@ -329,6 +158,11 @@ static int init_text_display(void) return 0; } +/* + * On input, VESA initialization is passed a desirable resolution. On + * return, either the requested resolution is set or the system + * supported default resolution is set and returned to the caller. + */ int __vesacon_init(int *x, int *y) { int rv; @@ -337,12 +171,12 @@ int __vesacon_init(int *x, int *y) if (x86_init_fpu()) return 10; - rv = vesacon_set_mode(*x, *y); + rv = vesacon_set_mode(x, y); if (rv) { /* Try to see if we can just patch the BIOS... */ if (__vesacon_i915resolution(*x, *y)) return rv; - if (vesacon_set_mode(*x, *y)) + if (vesacon_set_mode(x, y)) return rv; } diff --git a/com32/lib/sys/vesa/screencpy.c b/com32/lib/sys/vesa/screencpy.c index 32dce9e6..5c6d9151 100644 --- a/com32/lib/sys/vesa/screencpy.c +++ b/com32/lib/sys/vesa/screencpy.c @@ -34,13 +34,8 @@ #include "vesa.h" #include "video.h" -static struct win_info { - char *win_base; - size_t win_pos; - size_t win_size; - int win_gshift; - int win_num; -} wi; + +static struct win_info wi; void __vesacon_init_copy_to_screen(void) { @@ -71,47 +66,12 @@ void __vesacon_init_copy_to_screen(void) } } -static void set_window_pos(size_t win_pos) -{ - static com32sys_t ireg; - - wi.win_pos = win_pos; - - if (wi.win_num < 0) - return; /* This should never happen... */ - - ireg.eax.w[0] = 0x4F05; - ireg.ebx.b[0] = wi.win_num; - ireg.edx.w[0] = win_pos >> wi.win_gshift; - - __intcall(0x10, &ireg, NULL); -} - void __vesacon_copy_to_screen(size_t dst, const uint32_t * src, size_t npixels) { - size_t win_pos, win_off; - size_t win_size = wi.win_size; - size_t omask = win_size - 1; - char *win_base = wi.win_base; - size_t l; size_t bytes = npixels * __vesacon_bytes_per_pixel; char rowbuf[bytes + 4] __aligned(4); const char *s; s = (const char *)__vesacon_format_pixels(rowbuf, src, npixels); - - while (bytes) { - win_off = dst & omask; - win_pos = dst & ~omask; - - if (__unlikely(win_pos != wi.win_pos)) - set_window_pos(win_pos); - - l = min(bytes, win_size - win_off); - memcpy(win_base + win_off, s, l); - - bytes -= l; - s += l; - dst += l; - } + firmware->vesa->screencpy(dst, s, bytes, &wi); } diff --git a/com32/lib/sys/vesa/vesa.h b/com32/lib/sys/vesa/vesa.h index 3926c329..7a3d87ae 100644 --- a/com32/lib/sys/vesa/vesa.h +++ b/com32/lib/sys/vesa/vesa.h @@ -28,6 +28,7 @@ #ifndef LIB_SYS_VESA_H #define LIB_SYS_VESA_H +#include <syslinux/firmware.h> #include <inttypes.h> #include <com32.h> diff --git a/com32/lib/sys/vesa/video.h b/com32/lib/sys/vesa/video.h index de068457..f57e34f9 100644 --- a/com32/lib/sys/vesa/video.h +++ b/com32/lib/sys/vesa/video.h @@ -51,6 +51,14 @@ struct vesa_char { attr_t attr; /* Color table index */ }; +struct win_info { + char *win_base; + size_t win_pos; + size_t win_size; + int win_gshift; + int win_num; +}; + /* Pixel formats in order of decreasing preference; PXF_NONE should be last */ /* BGR24 is preferred over BGRA32 since the I/O overhead is smaller. */ enum vesa_pixel_format { diff --git a/com32/lib/sys/vesacon_write.c b/com32/lib/sys/vesacon_write.c index 88f8348d..823a66af 100644 --- a/com32/lib/sys/vesacon_write.c +++ b/com32/lib/sys/vesacon_write.c @@ -43,11 +43,7 @@ #include <syslinux/config.h> #include "ansi.h" #include "file.h" -#ifndef SYSLINUX_EFI #include "vesa/video.h" -#else -#include "vesa/efi/video.h" /* FIXME: move to video.h */ -#endif static void vesacon_erase(const struct term_state *, int, int, int, int); static void vesacon_write_char(int, int, uint8_t, const struct term_state *); diff --git a/core/bios.c b/core/bios.c index 31adf2fd..5207a5d0 100644 --- a/core/bios.c +++ b/core/bios.c @@ -7,6 +7,11 @@ #include <syslinux/memscan.h> #include <syslinux/firmware.h> +#include <sys/vesa/vesa.h> +#include <sys/vesa/video.h> +#include <sys/vesa/debug.h> +#include <minmax.h> + struct firmware *firmware = NULL; extern struct ansi_ops bios_ansi_ops; @@ -202,6 +207,258 @@ struct adv_ops bios_adv_ops = { .write = bios_adv_write, }; + +static int __constfunc is_power_of_2(unsigned int x) +{ + return x && !(x & (x - 1)); +} + +static int vesacon_paged_mode_ok(const struct vesa_mode_info *mi) +{ + int i; + + if (!is_power_of_2(mi->win_size) || + !is_power_of_2(mi->win_grain) || mi->win_grain > mi->win_size) + return 0; /* Impossible... */ + + for (i = 0; i < 2; i++) { + if ((mi->win_attr[i] & 0x05) == 0x05 && mi->win_seg[i]) + return 1; /* Usable window */ + } + + return 0; /* Nope... */ +} + +static int bios_vesacon_set_mode(struct vesa_info *vesa_info, int *px, int *py, + enum vesa_pixel_format *bestpxf) +{ + com32sys_t rm; + uint16_t mode, bestmode, *mode_ptr; + struct vesa_info *vi; + struct vesa_general_info *gi; + struct vesa_mode_info *mi; + enum vesa_pixel_format pxf; + int x = *px, y = *py; + int err = 0; + + /* Allocate space in the bounce buffer for these structures */ + vi = lzalloc(sizeof *vi); + if (!vi) { + err = 10; /* Out of memory */ + goto exit; + } + gi = &vi->gi; + mi = &vi->mi; + + memset(&rm, 0, sizeof rm); + + gi->signature = VBE2_MAGIC; /* Get VBE2 extended data */ + rm.eax.w[0] = 0x4F00; /* Get SVGA general information */ + rm.edi.w[0] = OFFS(gi); + rm.es = SEG(gi); + __intcall(0x10, &rm, &rm); + + if (rm.eax.w[0] != 0x004F) { + err = 1; /* Function call failed */ + goto exit; + } + if (gi->signature != VESA_MAGIC) { + err = 2; /* No magic */ + goto exit; + } + if (gi->version < 0x0102) { + err = 3; /* VESA 1.2+ required */ + goto exit; + } + + /* Copy general info */ + memcpy(&vesa_info->gi, gi, sizeof *gi); + + /* Search for the proper mode with a suitable color and memory model... */ + + mode_ptr = GET_PTR(gi->video_mode_ptr); + bestmode = 0; + *bestpxf = PXF_NONE; + + while ((mode = *mode_ptr++) != 0xFFFF) { + mode &= 0x1FF; /* The rest are attributes of sorts */ + + debug("Found mode: 0x%04x\r\n", mode); + + memset(mi, 0, sizeof *mi); + rm.eax.w[0] = 0x4F01; /* Get SVGA mode information */ + rm.ecx.w[0] = mode; + rm.edi.w[0] = OFFS(mi); + rm.es = SEG(mi); + __intcall(0x10, &rm, &rm); + + /* Must be a supported mode */ + if (rm.eax.w[0] != 0x004f) + continue; + + debug + ("mode_attr 0x%04x, h_res = %4d, v_res = %4d, bpp = %2d, layout = %d (%d,%d,%d)\r\n", + mi->mode_attr, mi->h_res, mi->v_res, mi->bpp, mi->memory_layout, + mi->rpos, mi->gpos, mi->bpos); + + /* Must be an LFB color graphics mode supported by the hardware. + + The bits tested are: + 4 - graphics mode + 3 - color mode + 1 - mode information available (mandatory in VBE 1.2+) + 0 - mode supported by hardware + */ + if ((mi->mode_attr & 0x001b) != 0x001b) + continue; + + /* Must be the chosen size */ + if (mi->h_res != x || mi->v_res != y) + continue; + + /* We don't support multibank (interlaced memory) modes */ + /* + * Note: The Bochs VESA BIOS (vbe.c 1.58 2006/08/19) violates the + * specification which states that banks == 1 for unbanked modes; + * fortunately it does report bank_size == 0 for those. + */ + if (mi->banks > 1 && mi->bank_size) { + debug("bad: banks = %d, banksize = %d, pages = %d\r\n", + mi->banks, mi->bank_size, mi->image_pages); + continue; + } + + /* Must be either a flat-framebuffer mode, or be an acceptable + paged mode */ + if (!(mi->mode_attr & 0x0080) && !vesacon_paged_mode_ok(mi)) { + debug("bad: invalid paged mode\r\n"); + continue; + } + + /* Must either be a packed-pixel mode or a direct color mode + (depending on VESA version ); must be a supported pixel format */ + pxf = PXF_NONE; /* Not usable */ + + if (mi->bpp == 32 && + (mi->memory_layout == 4 || + (mi->memory_layout == 6 && mi->rpos == 16 && mi->gpos == 8 && + mi->bpos == 0))) + pxf = PXF_BGRA32; + else if (mi->bpp == 24 && + (mi->memory_layout == 4 || + (mi->memory_layout == 6 && mi->rpos == 16 && mi->gpos == 8 && + mi->bpos == 0))) + pxf = PXF_BGR24; + else if (mi->bpp == 16 && + (mi->memory_layout == 4 || + (mi->memory_layout == 6 && mi->rpos == 11 && mi->gpos == 5 && + mi->bpos == 0))) + pxf = PXF_LE_RGB16_565; + else if (mi->bpp == 15 && + (mi->memory_layout == 4 || + (mi->memory_layout == 6 && mi->rpos == 10 && mi->gpos == 5 && + mi->bpos == 0))) + pxf = PXF_LE_RGB15_555; + + if (pxf < *bestpxf) { + debug("Best mode so far, pxf = %d\r\n", pxf); + + /* Best mode so far... */ + bestmode = mode; + *bestpxf = pxf; + + /* Copy mode info */ + memcpy(&vesa_info->mi, mi, sizeof *mi); + } + } + + if (*bestpxf == PXF_NONE) { + err = 4; /* No mode found */ + goto exit; + } + + mi = &vesa_info->mi; + mode = bestmode; + + /* Now set video mode */ + rm.eax.w[0] = 0x4F02; /* Set SVGA video mode */ + if (mi->mode_attr & 0x0080) + mode |= 0x4000; /* Request linear framebuffer if supported */ + rm.ebx.w[0] = mode; + __intcall(0x10, &rm, &rm); + if (rm.eax.w[0] != 0x004F) { + err = 9; /* Failed to set mode */ + goto exit; + } + +exit: + if (vi) + lfree(vi); + + return err; +} + +static void set_window_pos(struct win_info *wi, size_t win_pos) +{ + static com32sys_t ireg; + + wi->win_pos = win_pos; + + if (wi->win_num < 0) + return; /* This should never happen... */ + + ireg.eax.w[0] = 0x4F05; + ireg.ebx.b[0] = wi->win_num; + ireg.edx.w[0] = win_pos >> wi->win_gshift; + + __intcall(0x10, &ireg, NULL); +} + +static void bios_vesacon_screencpy(size_t dst, const uint32_t * src, + size_t bytes, struct win_info *wi) +{ + size_t win_pos, win_off; + size_t win_size = wi->win_size; + size_t omask = win_size - 1; + char *win_base = wi->win_base; + size_t l; + + while (bytes) { + win_off = dst & omask; + win_pos = dst & ~omask; + + if (__unlikely(win_pos != wi->win_pos)) + set_window_pos(wi, win_pos); + + l = min(bytes, win_size - win_off); + memcpy(win_base + win_off, src, l); + + bytes -= l; + src += l; + dst += l; + } +} + +static int bios_font_query(uint8_t **font) +{ + com32sys_t rm; + + /* Get BIOS 8x16 font */ + + rm.eax.w[0] = 0x1130; /* Get Font Information */ + rm.ebx.w[0] = 0x0600; /* Get 8x16 ROM font */ + __intcall(0x10, &rm, &rm); + *font = MK_PTR(rm.es, rm.ebp.w[0]); + + return 16; + +} +struct vesa_ops bios_vesa_ops = { + .set_mode = bios_vesacon_set_mode, + .screencpy = bios_vesacon_screencpy, + .font_query = bios_font_query, +}; + static uint32_t min_lowmem_heap = 65536; extern char __lowmem_heap[]; uint8_t KbdFlags; /* Check for keyboard escapes */ @@ -293,6 +550,7 @@ struct firmware bios_fw = { .ipappend_strings = bios_ipappend_strings, .get_serial_console_info = bios_get_serial_console_info, .adv_ops = &bios_adv_ops, + .vesa = &bios_vesa_ops, }; void syslinux_register_bios(void) diff --git a/core/font.c b/core/font.c index a0f73332..1e4e606d 100644 --- a/core/font.c +++ b/core/font.c @@ -18,6 +18,7 @@ * */ +#include <syslinux/firmware.h> #include <sys/io.h> #include <stdio.h> #include <fs.h> @@ -174,9 +175,15 @@ void bios_adjust_screen(void) VidCols = --cols; /* Store count-1 (same as rows) */ } +void adjust_screen(void) +{ + if (firmware->adjust_screen) + firmware->adjust_screen(); +} + void pm_adjust_screen(com32sys_t *regs __unused) { - bios_adjust_screen(); + adjust_screen(); } void pm_userfont(com32sys_t *regs) diff --git a/core/graphics.c b/core/graphics.c index e9fea617..bdf48a85 100644 --- a/core/graphics.c +++ b/core/graphics.c @@ -363,7 +363,7 @@ void using_vga(uint8_t vga, uint16_t pix_cols, uint16_t pix_rows) GXPixRows = pix_rows; if (!(UsingVGA & 0x08)) - bios_adjust_screen(); + adjust_screen(); } void pm_using_vga(com32sys_t *regs) diff --git a/com32/lib/sys/vesa/efi/cp865_8x16.h b/efi/cp865_8x16.h index 358a5638..358a5638 100644 --- a/com32/lib/sys/vesa/efi/cp865_8x16.h +++ b/efi/cp865_8x16.h @@ -1044,7 +1044,7 @@ bail: extern struct disk *efi_disk_init(EFI_HANDLE); extern void serialcfg(uint16_t *, uint16_t *, uint16_t *); - +extern struct vesa_ops efi_vesa_ops; struct firmware efi_fw = { .init = efi_init, @@ -1056,6 +1056,7 @@ struct firmware efi_fw = { .ipappend_strings = efi_ipappend_strings, .adv_ops = &efi_adv_ops, .boot_linux = efi_boot_linux, + .vesa = &efi_vesa_ops, }; static inline void syslinux_register_efi(void) diff --git a/com32/lib/sys/vesa/efi/initvesa.c b/efi/vesa.c index 83673c1e..473d3a55 100644 --- a/com32/lib/sys/vesa/efi/initvesa.c +++ b/efi/vesa.c @@ -26,13 +26,6 @@ * * ----------------------------------------------------------------------- */ -/* - * initvesa.c - * - * Query the VESA BIOS and select a 640x480x32 mode with local mapping - * support, if one exists. - */ - #include <inttypes.h> #include <com32.h> #include <stdlib.h> @@ -40,7 +33,6 @@ #include <sys/fpu.h> #include <syslinux/video.h> #include <dprintf.h> -#ifdef SYSLINUX_EFI #include <efi.h> #include <efilib.h> #include <efistdarg.h> @@ -48,37 +40,10 @@ * the header file below contains raw data parsed from cp865_8x16.psf */ #include "cp865_8x16.h" -#endif -#include "vesa.h" -#include "video.h" -#include "fill.h" -#include "debug.h" - -struct vesa_info __vesa_info; - -struct vesa_char *__vesacon_text_display; - -int __vesacon_font_height; -int __vesacon_text_rows; -int __vesacon_text_cols; -enum vesa_pixel_format __vesacon_pixel_format = PXF_NONE; -unsigned int __vesacon_bytes_per_pixel; -uint8_t __vesacon_graphics_font[FONT_MAX_CHARS][FONT_MAX_HEIGHT]; - -uint32_t *__vesacon_background, *__vesacon_shadowfb; - -static void unpack_font(uint8_t * dst, uint8_t * src, int height) -{ - int i; - - for (i = 0; i < FONT_MAX_CHARS; i++) { - memcpy(dst, src, height); - memset(dst + height, 0, FONT_MAX_HEIGHT - height); - - dst += FONT_MAX_HEIGHT; - src += height; - } -} +#include "sys/vesa/vesa.h" +#include "sys/vesa/video.h" +#include "sys/vesa/fill.h" +#include "sys/vesa/debug.h" /* EFI GOP support * Note GOP support uses the VESA info structure as much as possible and @@ -104,7 +69,16 @@ static void find_pixmask_bits(uint32_t mask, uint8_t *first_bit, uint8_t *len) { *first_bit = bit_pos; *len = bit_len; } -static int vesacon_set_mode(int *x, int *y) + +unsigned long lfb_size; +uint16_t lfb_line_size; +uint8_t lfb_rsize; +uint8_t lfb_gsize; +uint8_t lfb_bsize; +uint8_t lfb_resv_size; + +static int efi_vesacon_set_mode(struct vesa_info *vesa_info, int *x, int *y, + enum vesa_pixel_format *bestpxf) { EFI_GUID GraphicsOutputProtocolGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput = NULL; @@ -116,7 +90,6 @@ static int vesacon_set_mode(int *x, int *y) UINTN sz_info; struct vesa_info *vi; struct vesa_mode_info *mi; - enum vesa_pixel_format bestpxf = PXF_NONE; int err = 0; //debug("Hello, World!\r\n"); @@ -177,7 +150,7 @@ static int vesacon_set_mode(int *x, int *y) mi->h_res = *x; mi->v_res = *y; mi->lfb_ptr = (uint8_t *)(VOID *)(UINTN)gop_mode->FrameBufferBase; - mi->lfb_size = gop_mode->FrameBufferSize; + lfb_size = gop_mode->FrameBufferSize; /* FIXME: * The code below treats bpp == lfb_depth ; verify @@ -192,9 +165,9 @@ static int vesacon_set_mode(int *x, int *y) mi->gpos = 8; mi->bpos = 16; mi->resv_pos = 24; - mi->resv_size = 8; - mi->logical_scan = mi->lfb_line_size = (mode_info->PixelsPerScanLine * mi->bpp) / 8; - bestpxf = PXF_BGRA32; + lfb_resv_size = 8; + mi->logical_scan = lfb_line_size = (mode_info->PixelsPerScanLine * mi->bpp) / 8; + *bestpxf = PXF_BGRA32; dprintf("bpp %d pixperScanLine %d logical_scan %d bytesperPix %d\n", mi->bpp, mode_info->PixelsPerScanLine, mi->logical_scan, (mi->bpp + 7)>>3); break; @@ -206,9 +179,9 @@ static int vesacon_set_mode(int *x, int *y) mi->gpos = 8; mi->rpos = 16; mi->resv_pos = 24; - mi->resv_size = 8; - mi->logical_scan = mi->lfb_line_size = (mode_info->PixelsPerScanLine * mi->bpp) / 8; - bestpxf = PXF_BGRA32; + lfb_resv_size = 8; + mi->logical_scan = lfb_line_size = (mode_info->PixelsPerScanLine * mi->bpp) / 8; + *bestpxf = PXF_BGRA32; dprintf("bpp %d pixperScanLine %d logical_scan %d bytesperPix %d\n", mi->bpp, mode_info->PixelsPerScanLine, mi->logical_scan, (mi->bpp + 7)>>3); break; @@ -220,28 +193,28 @@ static int vesacon_set_mode(int *x, int *y) mode_info->PixelInformation.BlueMask, mode_info->PixelInformation.ReservedMask); find_pixmask_bits(mode_info->PixelInformation.RedMask, - &mi->rpos, &mi->lfb_rsize); + &mi->rpos, &lfb_rsize); find_pixmask_bits(mode_info->PixelInformation.GreenMask, - &mi->gpos, &mi->lfb_gsize); + &mi->gpos, &lfb_gsize); find_pixmask_bits(mode_info->PixelInformation.BlueMask, - &mi->bpos, &mi->lfb_bsize); + &mi->bpos, &lfb_bsize); find_pixmask_bits(mode_info->PixelInformation.ReservedMask, - &mi->resv_pos, &mi->lfb_resv_size); - mi->bpp = mi->lfb_rsize + mi->lfb_gsize + - mi->lfb_bsize + mi->lfb_resv_size; - mi->logical_scan = mi->lfb_line_size = (mode_info->PixelsPerScanLine * mi->bpp) / 8; - dprintf("RPos %d Rsize %d GPos %d Gsize %d\n", mi->rpos, mi->lfb_rsize, mi->gpos, mi->lfb_gsize); - dprintf("BPos %d Bsize %d RsvP %d RsvSz %d\n", mi->bpos, mi->lfb_bsize, mi->resv_pos, mi->lfb_resv_size); + &mi->resv_pos, &lfb_resv_size); + mi->bpp = lfb_rsize + lfb_gsize + + lfb_bsize + lfb_resv_size; + mi->logical_scan = lfb_line_size = (mode_info->PixelsPerScanLine * mi->bpp) / 8; + dprintf("RPos %d Rsize %d GPos %d Gsize %d\n", mi->rpos, lfb_rsize, mi->gpos, lfb_gsize); + dprintf("BPos %d Bsize %d RsvP %d RsvSz %d\n", mi->bpos, lfb_bsize, mi->resv_pos, lfb_resv_size); dprintf("bpp %d logical_scan %d bytesperPix %d\n", mi->bpp, mi->logical_scan, (mi->bpp + 7)>>3); switch (mi->bpp) { case 32: - bestpxf = PXF_BGRA32; + *bestpxf = PXF_BGRA32; break; case 24: - bestpxf = PXF_BGR24; + *bestpxf = PXF_BGR24; break; case 16: - bestpxf = PXF_LE_RGB16_565; + *bestpxf = PXF_LE_RGB16_565; break; default: dprintf("Unable to handle bits per pixel %d, bailing out\n", mi->bpp); @@ -262,31 +235,7 @@ static int vesacon_set_mode(int *x, int *y) break; } - memcpy(&__vesa_info.mi, mi, sizeof *mi); - mi = &__vesa_info.mi; - /* set up font info - * For now, font info is stored as raw data and used - * as such. Altenatively, the font data stored in a file - * could be read and parsed. (note: for this, EFI - * file support should be exposed via firmware structure) - */ - __vesacon_font_height = cp865_8x16_font_height; - unpack_font((uint8_t *) __vesacon_graphics_font, - (uint8_t *)cp865_8x16_font_data, - __vesacon_font_height); - - /* Free any existing data structures */ - if (__vesacon_background) { - free(__vesacon_background); - __vesacon_background = NULL; - } - if (__vesacon_shadowfb) { - free(__vesacon_shadowfb); - __vesacon_shadowfb = NULL; - } - - __vesacon_bytes_per_pixel = (mi->bpp + 7) >> 3; - __vesacon_format_pixels = __vesacon_format_pixels_list[bestpxf]; + memcpy(&vesa_info->mi, mi, sizeof *mi); /* Now set video mode */ st = uefi_call_wrapper(GraphicsOutput->SetMode, 2, GraphicsOutput, bestmode); @@ -318,18 +267,6 @@ static int vesacon_set_mode(int *x, int *y) * those values can coincide. */ - __vesacon_background = calloc(mi->lfb_line_size*mi->v_res, 4); - __vesacon_shadowfb = calloc(mi->lfb_line_size*mi->v_res, 4); - - __vesacon_init_copy_to_screen(); - - /* Tell syslinux we changed video mode - * FIXME: The following call is BIOS-centric. I don't see an EFI-equivalent - * syslinux_report_video_mode(0x000f, mi->h_res, mi->v_res); - */ - - __vesacon_pixel_format = bestpxf; - exit: if (vi) free(vi); @@ -337,62 +274,33 @@ exit: return err; } -/* FIXME: - * Does init_text_display need an EFI counterpart? - * e.g. vesa_char may need to setup UNICODE char for EFI - * and the number of screen chars may need to be sized up - * accordingly. This may also require turning byte strings - * into unicode strings in the framebuffer - * Possibly, revisit vesacon_fill() for EFI. - */ - -static int init_text_display(void) +static void efi_vesacon_screencpy(size_t dst, const char *s, + size_t bytes, struct win_info *wi) { - size_t nchars; - struct vesa_char *ptr; - struct vesa_char def_char = { - .ch = ' ', - .attr = 0, - }; - - if (__vesacon_text_display) - free(__vesacon_text_display); - - __vesacon_text_cols = TEXT_PIXEL_COLS / FONT_WIDTH; - __vesacon_text_rows = TEXT_PIXEL_ROWS / __vesacon_font_height; - nchars = (__vesacon_text_cols+2) * (__vesacon_text_rows+2); - - __vesacon_text_display = ptr = malloc(nchars * sizeof(struct vesa_char)); - - if (!ptr) - return -1; - - vesacon_fill(ptr, def_char, nchars); - __vesacon_init_cursor(__vesacon_font_height); - - return 0; + size_t win_off; + char *win_base = wi->win_base; + + /* For EFI, we simply take the offset from the framebuffer and write to it + * FIXME: any gotchas? + */ + win_off = dst; + memcpy(win_base + win_off, s, bytes); } -/* On input, VESA initialization is passed a desirable resolution - * On return, either the requested resolution is set or the system - * supported default resolution is set and returned to the caller - * This change is added for EFI enabled platforms. - */ -int __vesacon_init(int *x, int *y) +static int efi_vesacon_font_query(uint8_t **font) { - /* We need the FPU for graphics, at least libpng et al will need it... */ - if (x86_init_fpu()) - return 10; - - vesacon_set_mode(x, y); - /* FIXME: Accessing Video BIOS from EFI will probably not work, skip it for now */ - - init_text_display(); - - debug("Mode set, now drawing at %#p\r\n", __vesa_info.mi.lfb_ptr); - - __vesacon_init_background(); - - debug("Ready!\r\n"); - return 0; + /* set up font info + * For now, font info is stored as raw data and used + * as such. Altenatively, the font data stored in a file + * could be read and parsed. (note: for this, EFI + * file support should be exposed via firmware structure) + */ + *font = (uint8_t *)cp865_8x16_font_data; + return cp865_8x16_font_height; } + +struct vesa_ops efi_vesa_ops = { + .set_mode = efi_vesacon_set_mode, + .screencpy = efi_vesacon_screencpy, + .font_query = efi_vesacon_font_query, +}; |