aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2012-11-14 19:32:23 +0000
committerMatt Fleming <matt.fleming@intel.com>2012-11-15 12:26:42 +0000
commit4b0851493dce7cb5a6ada6e525da0bda6f5048dd (patch)
treeed512ff09b7554ef73b20d3b9c1070be6fb6a45d
parentbd7ce1bbf3393be32ee63a5139fffd1aae11c7fd (diff)
downloadsyslinux-4b0851493dce7cb5a6ada6e525da0bda6f5048dd.tar.gz
syslinux-4b0851493dce7cb5a6ada6e525da0bda6f5048dd.tar.xz
syslinux-4b0851493dce7cb5a6ada6e525da0bda6f5048dd.zip
sys/vesa: Modularise common vesa code
There's lots of the vesa infrastructure that can be shared for both BIOS and EFI, so share the things that are common and split out the things that are not into firmware-specific functions and use the 'firmware' structure to access them. This commit is part of a series of changes that removes all EFI-specific code from everywhere except efi/, which means we can delete inclusion of any gnu-efi header files and remove gnu-efi paths from CFLAGS. Signed-off-by: Matt Fleming <matt.fleming@intel.com>
-rw-r--r--com32/include/syslinux/firmware.h11
-rw-r--r--com32/lib/Makefile15
-rw-r--r--com32/lib/sys/vesa/efi/background.c456
-rw-r--r--com32/lib/sys/vesa/efi/debug.h36
-rw-r--r--com32/lib/sys/vesa/efi/drawtxt.c317
-rw-r--r--com32/lib/sys/vesa/efi/fill.h63
-rw-r--r--com32/lib/sys/vesa/efi/fmtpixel.c101
-rw-r--r--com32/lib/sys/vesa/efi/i915resolution.c795
-rw-r--r--com32/lib/sys/vesa/efi/screencpy.c75
-rw-r--r--com32/lib/sys/vesa/efi/vesa.h129
-rw-r--r--com32/lib/sys/vesa/efi/video.h98
-rw-r--r--com32/lib/sys/vesa/initvesa.c218
-rw-r--r--com32/lib/sys/vesa/screencpy.c46
-rw-r--r--com32/lib/sys/vesa/vesa.h1
-rw-r--r--com32/lib/sys/vesa/video.h8
-rw-r--r--com32/lib/sys/vesacon_write.c4
-rw-r--r--core/bios.c258
-rw-r--r--core/font.c9
-rw-r--r--core/graphics.c2
-rw-r--r--efi/cp865_8x16.h (renamed from com32/lib/sys/vesa/efi/cp865_8x16.h)0
-rw-r--r--efi/main.c3
-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
diff --git a/efi/main.c b/efi/main.c
index 371879c0..99dc2087 100644
--- a/efi/main.c
+++ b/efi/main.c
@@ -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,
+};