nb/intel/nehalem/gma: Set up OpRegion in nb code

Set up IGD OpRegion in northbridge and fill in GNVS' aslb.
At this point GNVS already has been set up by SSDT injection.

Required for future VBT patches that will:
* Use ACPI memory instead of CBMEM
* Use common implementation to locate VBT
* Fill in platform specific values

Change-Id: I76b31fe5fd19b50b82f57748558fb04408e0fd23
Signed-off-by: Patrick Rudolph <siro@das-labor.org>
Reviewed-on: https://review.coreboot.org/19309
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
diff --git a/src/northbridge/intel/nehalem/gma.c b/src/northbridge/intel/nehalem/gma.c
index 4e57b0f..daa6ec4 100644
--- a/src/northbridge/intel/nehalem/gma.c
+++ b/src/northbridge/intel/nehalem/gma.c
@@ -29,6 +29,8 @@
 #include <pc80/vga.h>
 #include <pc80/vga_io.h>
 #include <drivers/intel/gma/intel_bios.h>
+#include <southbridge/intel/ibexpeak/nvs.h>
+#include <cbmem.h>
 
 #include "chip.h"
 #include "nehalem.h"
@@ -1095,6 +1097,30 @@
 	drivers_intel_gma_displays_ssdt_generate(gfx);
 }
 
+static unsigned long
+gma_write_acpi_tables(struct device *const dev,
+		      unsigned long current,
+		      struct acpi_rsdp *const rsdp)
+{
+	igd_opregion_t *opregion;
+	global_nvs_t *gnvs;
+
+	// FIXME: Replace by common VBT implementation writing to current
+	opregion = igd_make_opregion();
+	if (opregion) {
+		/* GNVS has been already set up */
+		gnvs = cbmem_find(CBMEM_ID_ACPI_GNVS);
+		if (gnvs) {
+			/* IGD OpRegion Base Address */
+			gnvs->aslb = (u32)(uintptr_t)opregion;
+		} else {
+			printk(BIOS_ERR, "Error: GNVS table not found.\n");
+		}
+	}
+
+	return current;
+}
+
 static struct pci_operations gma_pci_ops = {
 	.set_subsystem = gma_set_subsystem,
 };
@@ -1108,6 +1134,7 @@
 	.scan_bus = 0,
 	.enable = 0,
 	.ops_pci = &gma_pci_ops,
+	.write_acpi_tables	= gma_write_acpi_tables,
 };
 
 static const unsigned short pci_device_ids[] = {