From owner-dev-commits-src-main@freebsd.org Sat Jan 16 08:23:45 2021 Return-Path: Delivered-To: dev-commits-src-main@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id D189C4D87B4; Sat, 16 Jan 2021 08:23:45 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4DHrfn5cKsz3Hp3; Sat, 16 Jan 2021 08:23:45 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id B2D0D3AF3; Sat, 16 Jan 2021 08:23:45 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 10G8Njgn016926; Sat, 16 Jan 2021 08:23:45 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 10G8NjEi016925; Sat, 16 Jan 2021 08:23:45 GMT (envelope-from git) Date: Sat, 16 Jan 2021 08:23:45 GMT Message-Id: <202101160823.10G8NjEi016925@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Toomas Soome Subject: git: ad1ebbe5cea8 - main - loader: create local copy of mode list provided by vbeinfoblock MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: tsoome X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: ad1ebbe5cea8ffac0037966990ddf0f80faa55d5 Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-main@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commit messages for the main branch of the src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 16 Jan 2021 08:23:45 -0000 The branch main has been updated by tsoome: URL: https://cgit.FreeBSD.org/src/commit/?id=ad1ebbe5cea8ffac0037966990ddf0f80faa55d5 commit ad1ebbe5cea8ffac0037966990ddf0f80faa55d5 Author: Toomas Soome AuthorDate: 2021-01-16 10:18:32 +0000 Commit: Toomas Soome CommitDate: 2021-01-16 10:23:22 +0000 loader: create local copy of mode list provided by vbeinfoblock Apparently some systems do corrupt mode list memory area, so we need to use local copy instead. --- stand/i386/libi386/vbe.c | 82 +++++++++++++++++++++++++++++------------------- 1 file changed, 49 insertions(+), 33 deletions(-) diff --git a/stand/i386/libi386/vbe.c b/stand/i386/libi386/vbe.c index 6a70cfe6f3e9..8b2c74ade92e 100644 --- a/stand/i386/libi386/vbe.c +++ b/stand/i386/libi386/vbe.c @@ -48,12 +48,14 @@ static struct vbeinfoblock *vbe; static struct modeinfoblock *vbe_mode; + +static uint16_t *vbe_mode_list; +static size_t vbe_mode_list_size; + /* The default VGA color palette format is 6 bits per primary color. */ int palette_format = 6; #define VESA_MODE_BASE 0x100 -#define VESA_MODE_MAX 0x1ff -#define VESA_MODE_COUNT (VESA_MODE_MAX - VESA_MODE_BASE + 1) /* * palette array for 8-bit indexed colors. In this case, cmap does store @@ -545,9 +547,17 @@ mode_set(struct env_var *ev, int flags __unused, const void *value) return (0); } +static void * +vbe_farptr(uint32_t farptr) +{ + return (PTOV((((farptr & 0xffff0000) >> 12) + (farptr & 0xffff)))); +} + void vbe_init(void) { + uint16_t *p, *ml; + /* First set FB for text mode. */ gfx_state.tg_fb_type = FB_TEXT; gfx_state.tg_fb.fb_height = TEXT_ROWS; @@ -573,6 +583,27 @@ vbe_init(void) vbe_mode = NULL; } + /* + * Copy mode list. We must do this because some systems do + * corrupt the provided list (vbox 6.1 is one example). + */ + p = ml = vbe_farptr(vbe->VideoModePtr); + while(*p++ != 0xFFFF) + ; + + vbe_mode_list_size = (uintptr_t)p - (uintptr_t)ml; + vbe_mode_list = malloc(vbe_mode_list_size); + if (vbe_mode_list == NULL) { + free(vbe); + vbe = NULL; + free(vbe_mode); + vbe_mode = NULL; + } + bcopy(ml, vbe_mode_list, vbe_mode_list_size); + + /* reset VideoModePtr, so we will not have chance to use bad data. */ + vbe->VideoModePtr = 0; + env_setenv("screen.textmode", EV_VOLATILE, "1", mode_set, env_nounset); env_setenv("vbe_max_resolution", EV_VOLATILE, NULL, mode_set, @@ -717,12 +748,6 @@ vbe_set_mode(int modenum) return (0); } -static void * -vbe_farptr(uint32_t farptr) -{ - return (PTOV((((farptr & 0xffff0000) >> 12) + (farptr & 0xffff)))); -} - /* * Verify existance of mode number or find mode by * dimensions. If depth is not given, walk values 32, 24, 16, 8. @@ -731,15 +756,13 @@ static int vbe_find_mode_xydm(int x, int y, int depth, int m) { struct modeinfoblock mi; - uint32_t farptr; + uint16_t *farptr; uint16_t mode; - int safety, i; + int idx, nitems, i; memset(vbe, 0, sizeof (*vbe)); if (biosvbe_info(vbe) != VBE_SUCCESS) return (0); - if (vbe->VideoModePtr == 0) - return (0); if (m != -1) i = 8; @@ -748,17 +771,17 @@ vbe_find_mode_xydm(int x, int y, int depth, int m) else i = depth; + nitems = vbe_mode_list_size / sizeof(*vbe_mode_list); while (i > 0) { - farptr = vbe->VideoModePtr; - safety = 0; - while ((mode = *(uint16_t *)vbe_farptr(farptr)) != 0xffff) { - safety++; - farptr += 2; - if (safety == VESA_MODE_COUNT) + for (idx = 0; idx < nitems; idx++) { + mode = vbe_mode_list[idx]; + if (mode == 0xffff) break; + if (biosvbe_get_mode_info(mode, &mi) != VBE_SUCCESS) { continue; } + /* we only care about linear modes here */ if (vbe_mode_is_supported(&mi) == 0) continue; @@ -910,9 +933,8 @@ void vbe_modelist(int depth) { struct modeinfoblock mi; - uint32_t farptr; uint16_t mode; - int nmodes = 0, safety = 0; + int nmodes, idx, nentries; int ddc_caps; uint32_t width, height; bool edid = false; @@ -948,6 +970,7 @@ vbe_modelist(int depth) if (vbe_get_flatpanel(&width, &height)) printf(": Panel %dx%d\n", width, height); + nmodes = 0; memset(vbe, 0, sizeof (*vbe)); memcpy(vbe->VbeSignature, "VBE2", 4); if (biosvbe_info(vbe) != VBE_SUCCESS) @@ -958,26 +981,19 @@ vbe_modelist(int depth) vbe_print_vbe_info(vbe); printf("Modes: "); - farptr = vbe->VideoModePtr; - if (farptr == 0) - goto done; - - while ((mode = *(uint16_t *)vbe_farptr(farptr)) != 0xffff) { - safety++; - farptr += 2; - if (safety == VESA_MODE_COUNT) { - printf("[?] "); + nentries = vbe_mode_list_size / sizeof(*vbe_mode_list); + for (idx = 0; idx < nentries; idx++) { + mode = vbe_mode_list[idx]; + if (mode == 0xffff) break; - } + if (biosvbe_get_mode_info(mode, &mi) != VBE_SUCCESS) continue; + /* we only care about linear modes here */ if (vbe_mode_is_supported(&mi) == 0) continue; - /* we found some mode so reset safety counter */ - safety = 0; - /* apply requested filter */ if (depth != -1 && mi.BitsPerPixel != depth) continue;