From nobody Tue Dec 16 08:36:45 2025 Delivered-To: importer@patchew.org Received-SPF: none (zoho.com: 80.81.252.135 is neither permitted nor denied by domain of seabios.org) client-ip=80.81.252.135; envelope-from=seabios-bounces@seabios.org; helo=mail.coreboot.org; Authentication-Results: mx.zoho.com; spf=none (zoho.com: 80.81.252.135 is neither permitted nor denied by domain of seabios.org) smtp.mailfrom=seabios-bounces@seabios.org; Return-Path: Received: from mail.coreboot.org (mail.coreboot.org [80.81.252.135]) by mx.zohomail.com with SMTPS id 1490372882114661.5582089774604; Fri, 24 Mar 2017 09:28:02 -0700 (PDT) Received: from [127.0.0.1] (helo=ra.coresystems.de) by mail.coreboot.org with esmtp (Exim 4.86_2) (envelope-from ) id 1crS4C-0001PK-2L; Fri, 24 Mar 2017 17:27:56 +0100 Received: from das-labor.org ([188.40.89.130]) by mail.coreboot.org with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.86_2) (envelope-from ) id 1crS3z-0001LH-TI for seabios@seabios.org; Fri, 24 Mar 2017 17:27:55 +0100 From: Patrick Rudolph Authentication-Results: das-labor.org; dkim=permerror (bad message/signature format) To: seabios@seabios.org Date: Fri, 24 Mar 2017 17:27:26 +0100 Message-ID: <20170324162727.26990-8-siro@das-labor.org> In-Reply-To: <20170324162727.26990-1-siro@das-labor.org> References: <20170324162727.26990-1-siro@das-labor.org> X-Spam-Score: -2.7 (--) Subject: [SeaBIOS] [PATCH 7/8] SeaVGABios/cbvga:: Add Intel VBT support X-BeenThere: seabios@seabios.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: SeaBIOS mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: seabios-bounces@seabios.org Sender: "SeaBIOS" X-Duff: Orig. Duff, Duff Lite, Duff Dry, Duff Dark, Raspberry Duff, Lady Duff, Red Duff, Tartar Control Duff X-ZohoMail: RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Add support for providing Intel VBT OpRegion. Intel's legacy VGA driver expect the VBT (Video BIOS Table) to be present in the VGA option ROM. As of now the VBT is not present and you will (not) see a BSOD as the legacy driver doesn't check the ASLS register, as newer versions of the driver do. Parse Intel's OpRegion and copy the VBT to the end of VGA option rom, if present, to prevent a BSOD. In case the ASLS register is not set or the OpRegion is invalid no VBT will be installed. Tested on GM45 (Lenovo T500) using the VBT extracted from Intel VBIOS, as the faked VBT, generated by coreboot, doesn't work. Signed-off-by: Patrick Rudolph diff --git a/vgasrc/cbvga.c b/vgasrc/cbvga.c index 42a50f7..bc5b79e 100644 --- a/vgasrc/cbvga.c +++ b/vgasrc/cbvga.c @@ -13,6 +13,9 @@ #include "vgabios.h" // SET_VGA #include "vgafb.h" // handle_gfx_op #include "vgautil.h" // VBE_total_memory +#include "hw/pci.h" // pci_config_readw +#include "hw/pci_regs.h" // PCI_VENDOR_ID +#include "hw/pci_ids.h" // PCI_VENDOR_ID_INTEL =20 static int CBmode VAR16; static struct vgamode_s CBmodeinfo VAR16; @@ -225,6 +228,117 @@ cbvga_get_linesize(struct vgamode_s *vmode_g) return GET_GLOBAL(CBlinelength); } =20 +struct optionrom_vbt { + u32 hdr_signature; + u8 reserved[16]; + u16 hdr_version; + u16 hdr_size; + u16 hdr_vbt_size; +}; + +struct opregion_header { + u8 signature[16]; + u32 size; + u32 version; +}; + +static const u8 igd_opregion_signature[] VAR16 =3D { + 'I', 'n', 't', 'e', 'l', 'G', 'r', 'a', 'p', 'h','i','c','s','M','e','= m' +}; + +#define VBT_SIGNATURE 0x54425624 +#define ASLS 0xfc +#define IGD_OPREGION_VBT_OFFSET 0x400 + +/* Compares to memory regions */ +static int +cbvga_memcpm(u8 *src1, u8 *src2, u8 len) +{ + while (len --) { + if (GET_FARVAR(0, *src1) !=3D GET_GLOBAL(*src2)) + return 1; + src1 ++; + src2 ++; + } + + return 0; +} + +/* Fetch and install Intel VBT OpRegion */ +static void +cbvga_setup_intel_vbt(void) +{ + struct optionrom_vbt *vbt; + struct opregion_header *oph; + u16 offset; + u8 size; + + /* Verify OpRegion Base address */ + if ((pci_config_readl(pci_to_bdf(0, 2, 0), ASLS) =3D=3D 0x00000000) + || (pci_config_readl(pci_to_bdf(0, 2, 0), ASLS) =3D=3D 0xffffffff)) + return; + + dprintf(3, "found valid ASLS.\n"); + + /* Get OpRegion Base address */ + oph =3D (void *)pci_config_readl(pci_to_bdf(0, 2, 0), ASLS); + + /* Verify OpRegion */ + if (cbvga_memcpm(oph->signature, (u8 *)igd_opregion_signature + , sizeof(oph->signature)) !=3D 0) + return; + + dprintf(3, "found valid Intel OpRegion version %d.\n" + , GET_FARVAR(0, oph->version)); + + /* Get VBT */ + vbt =3D ((void *)oph) + IGD_OPREGION_VBT_OFFSET; + + /* Verify VBT */ + if ((GET_FARVAR(0, vbt->hdr_signature) !=3D VBT_SIGNATURE) + || (GET_FARVAR(0, vbt->hdr_vbt_size) =3D=3D 0)) + return; + + dprintf(3, "Found valid VBT with size %d.\n", GET_FARVAR(0, vbt->hdr_v= bt_size)); + + /* Verify Option Rom free space */ + extern u8 _rom_header_size; + size =3D GET_GLOBAL(_rom_header_size); + offset =3D size * 512; + if ((GET_FARVAR(0, vbt->hdr_vbt_size) + offset) > 0xffff) + return; + + dprintf(3, "Enough space in rom to place VBT.\n"); + + /* Copy VBT */ + memcpy_high((void *)(offset + BUILD_ROM_START), vbt + , GET_FARVAR(0, vbt->hdr_vbt_size)); + + dprintf(3, "Copied VBT.\n"); + + /* Increment rom header size */ + size +=3D (GET_FARVAR(0, vbt->hdr_vbt_size) + 512 - 1) >> 9; + SET_VGA(_rom_header_size, size); + + dprintf(3, "Incremented rom size from %d to %d bytes.\n" + , offset, size * 512); + + /* Set VBT offset */ + extern u16 _rom_header_pnpdata; + SET_VGA(_rom_header_pnpdata, offset); + + dprintf(3, "Wrote VBT pointer.\n"); + + /* Verify */ + vbt =3D (void *)(offset + BUILD_ROM_START); + if ((GET_FARVAR(0, vbt->hdr_signature) !=3D VBT_SIGNATURE) + || (GET_FARVAR(0, vbt->hdr_vbt_size) =3D=3D 0)) + return; + + dprintf(1, "Successfully installed Intel VBT.\n"); +} + + #define CB_TAG_FRAMEBUFFER 0x0012 struct cb_framebuffer { u32 tag; @@ -254,6 +368,13 @@ cbvga_setup(void) if (GET_GLOBAL(HaveRunInit)) return 0; =20 + if (pci_config_readw(pci_to_bdf(0, 2, 0), PCI_VENDOR_ID) + =3D=3D PCI_VENDOR_ID_INTEL) { + dprintf(1, "Found Intel GPU, trying to install VBT.\n"); + + cbvga_setup_intel_vbt(); + } + struct cb_header *cbh =3D find_cb_table(); if (!cbh) { dprintf(1, "Unable to find coreboot table\n"); diff --git a/vgasrc/vgaentry.S b/vgasrc/vgaentry.S index 53be2b3..10b1b80 100644 --- a/vgasrc/vgaentry.S +++ b/vgasrc/vgaentry.S @@ -16,7 +16,7 @@ =20 .section .rom.header .code16 - .global _rom_header, _rom_header_size, _rom_header_checksum + .global _rom_header, _rom_header_size, _rom_header_checksum, _rom_= header_pnpdata _rom_header: .word 0xaa55 _rom_header_size: --=20 2.9.3 _______________________________________________ SeaBIOS mailing list SeaBIOS@seabios.org https://www.coreboot.org/mailman/listinfo/seabios