nb/intel/gm45: Use common code for SMM in TSEG

This makes i82801ix use the common smm southbridge code to set up smm
relocation and smi handler setup. This is needed in this change for the
the smm relocation code relies on some southbridge functions provided
in the common code. Some of the old code is kept for the Q35 qemu
target.

This also caches the TSEG region and therefore increases MTRR usage a
little in some cases.

Currently SMRR msr's are not set on model_1067x and model_6fx since this needs
the MSRR enable bit and lock set in IA32_FEATURE_CONTROL. This will be handled
properly in the subsequent parallel mp init patchset.

Tested on Thinkpad X200: boots and going to and resuming from S3 still
works fine.

Change-Id: Ic80c65ea42fcf554ea5695772e8828d2f3b00b98
Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
Reviewed-on: https://review.coreboot.org/23419
Reviewed-by: Patrick Rudolph <siro@das-labor.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
diff --git a/src/northbridge/intel/fsp_sandybridge/northbridge.c b/src/northbridge/intel/fsp_sandybridge/northbridge.c
index 24969d4..b192161 100644
--- a/src/northbridge/intel/fsp_sandybridge/northbridge.c
+++ b/src/northbridge/intel/fsp_sandybridge/northbridge.c
@@ -296,6 +296,11 @@
 	pci_write_config8(dev_find_slot(0, PCI_DEVFN(0, 0)), SMRAM, smram);
 }
 
+u32 northbridge_get_tseg_size(void)
+{
+	return CONFIG_SMM_TSEG_SIZE;
+}
+
 static struct pci_operations intel_pci_ops = {
 	.set_subsystem    = intel_set_subsystem,
 };
diff --git a/src/northbridge/intel/gm45/Kconfig b/src/northbridge/intel/gm45/Kconfig
index a45e841..7b4250f 100644
--- a/src/northbridge/intel/gm45/Kconfig
+++ b/src/northbridge/intel/gm45/Kconfig
@@ -30,6 +30,7 @@
 	select HAVE_VGA_TEXT_FRAMEBUFFER if MAINBOARD_DO_NATIVE_VGA_INIT
 	select POSTCAR_STAGE
 	select POSTCAR_CONSOLE
+	select SMM_TSEG
 
 config CBFS_SIZE
 	hex
diff --git a/src/northbridge/intel/gm45/gm45.h b/src/northbridge/intel/gm45/gm45.h
index 5373e5e..95863d9 100644
--- a/src/northbridge/intel/gm45/gm45.h
+++ b/src/northbridge/intel/gm45/gm45.h
@@ -434,6 +434,7 @@
 u32 decode_igd_memory_size(u32 gms);
 u32 decode_igd_gtt_size(u32 gsm);
 u32 decode_tseg_size(u8 esmramc);
+uintptr_t smm_region_start(void);
 
 void init_iommu(void);
 
diff --git a/src/northbridge/intel/gm45/northbridge.c b/src/northbridge/intel/gm45/northbridge.c
index 663a9ff..da37e33 100644
--- a/src/northbridge/intel/gm45/northbridge.c
+++ b/src/northbridge/intel/gm45/northbridge.c
@@ -25,6 +25,7 @@
 #include <boot/tables.h>
 #include <arch/acpi.h>
 #include <cbmem.h>
+#include <cpu/intel/smm/gen1/smi.h>
 #include "chip.h"
 #include "gm45.h"
 #include "arch/acpi.h"
@@ -207,6 +208,43 @@
 	return NULL;
 }
 
+u32 northbridge_get_tseg_base(void)
+{
+	return (u32)smm_region_start();
+}
+
+u32 northbridge_get_tseg_size(void)
+{
+	const u8 esmramc = pci_read_config8(dev_find_slot(0, PCI_DEVFN(0, 0)),
+					D0F0_ESMRAMC);
+	return decode_tseg_size(esmramc) << 10;
+}
+
+void northbridge_write_smram(u8 smram)
+{
+	pci_write_config8(dev_find_slot(0, PCI_DEVFN(0, 0)), D0F0_SMRAM, smram);
+}
+
+/*
+ * Really doesn't belong here but will go away with parallel mp init,
+ * so let it be here for a while...
+ */
+int cpu_get_apic_id_map(int *apic_id_map)
+{
+	unsigned int i;
+
+	/* Logical processors (threads) per core */
+	const struct cpuid_result cpuid1 = cpuid(1);
+	/* Read number of cores. */
+	const char cores = (cpuid1.ebx >> 16) & 0xf;
+
+	/* TODO in parallel MP cpuid(1).ebx */
+	for (i = 0; i < cores; i++)
+		apic_id_map[i] = i;
+
+	return cores;
+}
+
 static struct device_operations pci_domain_ops = {
 	.read_resources   = mch_domain_read_resources,
 	.set_resources    = mch_domain_set_resources,
diff --git a/src/northbridge/intel/gm45/ram_calc.c b/src/northbridge/intel/gm45/ram_calc.c
index 011d903..0e95341 100644
--- a/src/northbridge/intel/gm45/ram_calc.c
+++ b/src/northbridge/intel/gm45/ram_calc.c
@@ -83,7 +83,7 @@
 	}
 }
 
-static uintptr_t smm_region_start(void)
+uintptr_t smm_region_start(void)
 {
 	const pci_devfn_t dev = PCI_DEV(0, 0, 0);
 
@@ -135,14 +135,12 @@
 	/* Cache RAM as WB from 0 -> CACHE_TMP_RAMTOP. */
 	postcar_frame_add_mtrr(&pcf, 0, CACHE_TMP_RAMTOP, MTRR_TYPE_WRBACK);
 
-	/* Cache two separate 4 MiB regions below the top of ram, this
-	 * satisfies MTRR alignment requirements. If you modify this to
-	 * cover TSEG, make sure UMA region is not set with WRBACK as it
-	 * causes hard-to-recover boot failures.
+	/* Cache a 8 MiB region below the top of ram and 8 MiB above top of
+	 * ram to cover both cbmem as the TSEG region.
 	 */
 	top_of_ram = (uintptr_t)cbmem_top();
-	postcar_frame_add_mtrr(&pcf, top_of_ram - 4*MiB, 4*MiB, MTRR_TYPE_WRBACK);
-	postcar_frame_add_mtrr(&pcf, top_of_ram - 8*MiB, 4*MiB, MTRR_TYPE_WRBACK);
+	postcar_frame_add_mtrr(&pcf, top_of_ram - 8*MiB, 16*MiB,
+			MTRR_TYPE_WRBACK);
 
 	run_postcar_phase(&pcf);
 
diff --git a/src/northbridge/intel/nehalem/northbridge.c b/src/northbridge/intel/nehalem/northbridge.c
index 6fc61c3..8f55e3c 100644
--- a/src/northbridge/intel/nehalem/northbridge.c
+++ b/src/northbridge/intel/nehalem/northbridge.c
@@ -180,6 +180,11 @@
 	return pci_read_config32(dev, TSEG) & ~1;
 }
 
+u32 northbridge_get_tseg_size(void)
+{
+	return CONFIG_SMM_TSEG_SIZE;
+}
+
 static void mc_set_resources(struct device *dev)
 {
 	/* And call the normal set_resources */
diff --git a/src/northbridge/intel/sandybridge/northbridge.c b/src/northbridge/intel/sandybridge/northbridge.c
index 8c2aaf3..aab3931 100644
--- a/src/northbridge/intel/sandybridge/northbridge.c
+++ b/src/northbridge/intel/sandybridge/northbridge.c
@@ -472,6 +472,11 @@
 	return northbridge_get_base_reg(dev, TSEG);
 }
 
+u32 northbridge_get_tseg_size(void)
+{
+	return CONFIG_SMM_TSEG_SIZE;
+}
+
 void northbridge_write_smram(u8 smram)
 {
 	pci_write_config8(dev_find_slot(0, PCI_DEVFN(0, 0)), SMRAM, smram);