<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>