<p>Patrick Rudolph would like Matt DeVillier to <strong>review</strong> this change.</p><p><a href="https://review.coreboot.org/20969">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">[WIP] drv/intel/gma/opregion: Add common init_idg_opregion()<br><br>Add a new common method to initialize ACPI OpRegion.<br>* Try to locate vbt.bin in CBFS.<br>* Try to locate VBIOS in CBFS.<br>* Keep existing code to probe at 0xc0000.<br><br>Change-Id: I8ee50ea9900537bd9e3ca5ab0cd3f48d2acec970<br>Signed-off-by: Matt DeVillier <matt.devillier@gmail.com><br>Signed-off-by: Patrick Rudolph <siro@das-labor.org><br>---<br>M src/drivers/intel/gma/opregion.c<br>1 file changed, 115 insertions(+), 48 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/69/20969/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/src/drivers/intel/gma/opregion.c b/src/drivers/intel/gma/opregion.c<br>index e9cbba1..d557204 100644<br>--- a/src/drivers/intel/gma/opregion.c<br>+++ b/src/drivers/intel/gma/opregion.c<br>@@ -17,6 +17,7 @@<br> #include <arch/acpi.h><br> #include <types.h><br> #include <string.h><br>+#include <cbfs.h><br> #include <device/device.h><br> #include <device/pci.h><br> #include <device/pci_ids.h><br>@@ -67,12 +68,14 @@<br> }<br> }<br> <br>+/*<br>+ * Try to locate Intel VBIOS at 0xc0000. It might have been placed by<br>+ * Native Graphics Init as fake Option ROM or when coreboot did run the<br>+ * VBIOS on legacy platforms.<br>+ * TODO: Place generated fake VBT in CBMEM and get rid of this.<br>+ */<br> static void *get_intel_vbios(void)<br> {<br>- /* This should probably be looking at CBFS or we should always<br>- * deploy the VBIOS on Intel systems, even if we don't run it<br>- * in coreboot (e.g. SeaBIOS only scenarios).<br>- */<br> u8 *vbios = (u8 *)0xc0000;<br> <br> optionrom_header_t *oprom = (optionrom_header_t *)vbios;<br>@@ -80,61 +83,129 @@<br> oprom->pcir_offset);<br> <br> printk(BIOS_DEBUG, "GET_VBIOS: %x %x %x %x %x\n",<br>- oprom->signature, pcir->vendor, pcir->classcode[0],<br>- pcir->classcode[1], pcir->classcode[2]);<br>+ oprom->signature, pcir->vendor, pcir->classcode[0],<br>+ pcir->classcode[1], pcir->classcode[2]);<br> <br> <br> if ((oprom->signature == OPROM_SIGNATURE) &&<br>- (pcir->vendor == PCI_VENDOR_ID_INTEL) &&<br>- (pcir->classcode[0] == 0x00) &&<br>- (pcir->classcode[1] == 0x00) &&<br>- (pcir->classcode[2] == 0x03))<br>+ (pcir->vendor == PCI_VENDOR_ID_INTEL) &&<br>+ (pcir->classcode[0] == 0x00) &&<br>+ (pcir->classcode[1] == 0x00) &&<br>+ (pcir->classcode[2] == 0x03))<br> return (void *)vbios;<br> <br> return NULL;<br> }<br> <br>-static enum cb_err init_opregion_vbt(igd_opregion_t *opregion)<br>-{<br>- void *vbios;<br>- vbios = get_intel_vbios();<br>- if (!vbios) {<br>- printk(BIOS_DEBUG, "VBIOS not found.\n");<br>- return CB_ERR;<br>- }<br>-<br>- printk(BIOS_DEBUG, " ... VBIOS found at %p\n", vbios);<br>- optionrom_header_t *oprom = (optionrom_header_t *)vbios;<br>- optionrom_vbt_t *vbt = (optionrom_vbt_t *)(vbios +<br>- oprom->vbt_offset);<br>-<br>- if (read32(vbt->hdr_signature) != VBT_SIGNATURE) {<br>- printk(BIOS_DEBUG, "VBT not found!\n");<br>- return CB_ERR;<br>- }<br>-<br>- memcpy(opregion->header.vbios_version, vbt->coreblock_biosbuild, 4);<br>- memcpy(opregion->vbt.gvd1, vbt, vbt->hdr_vbt_size < 7168 ?<br>- vbt->hdr_vbt_size : 7168);<br>-<br>- return CB_SUCCESS;<br>-}<br>-<br> /* Initialize IGD OpRegion, called from ACPI code and OS drivers */<br>-enum cb_err intel_gma_init_igd_opregion(igd_opregion_t *opregion)<br>+enum cb_err<br>+intel_gma_init_igd_opregion(igd_opregion_t *opregion)<br> {<br>- enum cb_err ret;<br>+ struct region_device vbt_rdev;<br>+ optionrom_vbt_t *vbt = NULL;<br>+ optionrom_vbt_t *ext_vbt;<br>+ struct cbfsf file_desc;<br>+ bool need_unmap = false;<br> <br>- memset((void *)opregion, 0, sizeof(igd_opregion_t));<br>+ /* try to locate vbt.bin in CBFS */<br>+ if (cbfs_boot_locate(&file_desc, "vbt.bin", NULL) == CB_SUCCESS) {<br>+ cbfs_file_data(&vbt_rdev, &file_desc);<br>+ vbt = rdev_mmap_full(&vbt_rdev);<br>+ if (vbt) {<br>+ uint32_t vbtsig = 0;<br>+ /* Validate the vbt file */<br>+ memcpy(&vbtsig, vbt, sizeof(uint32_t));<br>+ if (vbtsig == VBT_SIGNATURE) {<br>+ need_unmap = true;<br>+ } else {<br>+ printk(BIOS_ERR,<br>+ "GMA: Invalid signature in VBT data"<br>+ " file (vbt.bin)!\n");<br>+ rdev_munmap(&vbt_rdev, vbt);<br>+ vbt = NULL;<br>+ }<br>+ } else {<br>+ printk(BIOS_ERR, "GMA: VBT couldn't be read\n");<br>+ }<br>+ } else {<br>+ printk(BIOS_NOTICE,<br>+ "GMA: Could not locate a VBT file in CBFS\n");<br>+ }<br> <br>- // FIXME if IGD is disabled, we should exit here.<br>+ /* If no vbt.bin, try to load from VBIOS in CBFS */<br>+ if (!vbt) {<br>+ optionrom_header_t *oprom = (optionrom_header_t *)<br>+ pci_rom_probe(dev_find_slot(0, PCI_DEVFN(0x2, 0)));<br>+ if (oprom) {<br>+ printk(BIOS_DEBUG, "GMA: VBIOS found at %p\n", oprom);<br>+ vbt = (optionrom_vbt_t *)(oprom + oprom->vbt_offset);<br>+ if (read32(vbt->hdr_signature) != VBT_SIGNATURE) {<br>+ printk(BIOS_DEBUG,<br>+ "GMA: Invalid signature in VBT\n");<br>+ vbt = NULL;<br>+ }<br>+ } else {<br>+ printk(BIOS_NOTICE, "GMA: VBIOS not found in CFBS\n");<br>+ }<br>+ }<br>+<br>+ /* 3rd option - use generated fake VBT */<br>+ if (!vbt) {<br>+ /* FIXME: Read from CBMEM or generate using devicetree */<br>+ void *vbios = get_intel_vbios();<br>+ if (!vbios) {<br>+ printk(BIOS_NOTICE,<br>+ "GMA: VBIOS not found at 0xc0000\n");<br>+ } else {<br>+ printk(BIOS_DEBUG, " ... VBIOS found at %p\n", vbios);<br>+ optionrom_header_t *oprom =<br>+ (optionrom_header_t *)vbios;<br>+ vbt = (optionrom_vbt_t *)(vbios + oprom->vbt_offset);<br>+ if (read32(vbt->hdr_signature) != VBT_SIGNATURE) {<br>+ printk(BIOS_NOTICE,<br>+ "GMA: Invalid signature in VBT\n");<br>+ vbt = NULL;<br>+ }<br>+ }<br>+ }<br>+<br>+ if (!vbt) {<br>+ printk(BIOS_ERR, "GMA: VBT not found\n");<br>+ return CB_ERR;<br>+ }<br>+<br>+ memset(opregion, 0, sizeof(igd_opregion_t));<br> <br> memcpy(&opregion->header.signature, IGD_OPREGION_SIGNATURE,<br>- sizeof(opregion->header.signature));<br>+ sizeof(opregion->header.signature));<br>+ memcpy(opregion->header.vbios_version, vbt->coreblock_biosbuild,<br>+ ARRAY_SIZE(vbt->coreblock_biosbuild));<br>+ /* Extended VBT support */<br>+ if (vbt->hdr_vbt_size > sizeof(opregion->vbt.gvd1)) {<br>+ ext_vbt = cbmem_add(CBMEM_ID_EXT_VBT, vbt->hdr_vbt_size);<br> <br>- /* 8kb */<br>- opregion->header.size = sizeof(igd_opregion_t) / 1024;<br>- opregion->header.version = IGD_OPREGION_VERSION;<br>+ if (ext_vbt == NULL) {<br>+ printk(BIOS_ERR,<br>+ "GMA: Unable to add Ext VBT to cbmem!\n");<br>+ if (need_unmap)<br>+ rdev_munmap(&vbt_rdev, vbt);<br>+ return CB_ERR;<br>+ }<br>+<br>+ memcpy(ext_vbt, vbt, vbt->hdr_vbt_size);<br>+ opregion->mailbox3.rvda = (uintptr_t)ext_vbt;<br>+ opregion->mailbox3.rvds = vbt->hdr_vbt_size;<br>+ } else {<br>+ /* Raw VBT size which can fit in gvd1 */<br>+ memcpy(opregion->vbt.gvd1, vbt, vbt->hdr_vbt_size);<br>+ }<br>+<br>+ if (need_unmap)<br>+ rdev_munmap(&vbt_rdev, vbt);<br>+<br>+ /* 8KiB */<br>+ opregion->header.size = sizeof(igd_opregion_t) / KiB;<br>+ opregion->header.version = (IGD_OPREGION_VERSION << 24);<br> <br> // FIXME We just assume we're mobile for now<br> opregion->header.mailboxes = MAILBOXES_MOBILE;<br>@@ -157,10 +228,6 @@<br> opregion->mailbox3.bclm[8] = IGD_WORD_FIELD_VALID + 0x50cc;<br> opregion->mailbox3.bclm[9] = IGD_WORD_FIELD_VALID + 0x5ae5;<br> opregion->mailbox3.bclm[10] = IGD_WORD_FIELD_VALID + 0x64ff;<br>-<br>- ret = init_opregion_vbt(opregion);<br>- if (ret != CB_SUCCESS)<br>- return ret;<br> <br> /* Write ASLS PCI register and prepare SWSCI register. */<br> intel_gma_opregion_register((uintptr_t)opregion);<br></pre><p>To view, visit <a href="https://review.coreboot.org/20969">change 20969</a>. To unsubscribe, visit <a href="https://review.coreboot.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://review.coreboot.org/20969"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: coreboot </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I8ee50ea9900537bd9e3ca5ab0cd3f48d2acec970 </div>
<div style="display:none"> Gerrit-Change-Number: 20969 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Patrick Rudolph <siro@das-labor.org> </div>
<div style="display:none"> Gerrit-Reviewer: Matt DeVillier <matt.devillier@gmail.com> </div>