nb/intel/broadwell: Add an option for where verstage starts

Previously broadwell used a romcc bootblock and starting verstage in
romstage was madatory but with C_ENVIRONMENT_BOOTBLOCK it is also
possible to have a separate verstage.

This selects using a separate verstage by default but still keeps the
option around to use verstage in romstage.

With a separate verstage the romstage becomes an RW stage.
The mrc.bin however is only added to the RO COREBOOT fmap region as it
requires to be run at a specific offset. This means that coreboot will
have to jump from a RW region to the RO region for that binary and
back to that RW region after that binary is done initializing the
memory.

Change-Id: I900233cadb3c76da329fb98f93917570e633365f
Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/30384
Reviewed-by: Nico Huber <nico.h@gmx.de>
Reviewed-by: Matt DeVillier <matt.devillier@gmail.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
diff --git a/src/soc/intel/broadwell/Kconfig b/src/soc/intel/broadwell/Kconfig
index 9dd2f4f..b685391 100644
--- a/src/soc/intel/broadwell/Kconfig
+++ b/src/soc/intel/broadwell/Kconfig
@@ -67,9 +67,25 @@
 	bool
 	default y
 
+config BROADWELL_VBOOT_IN_BOOTBLOCK
+	depends on VBOOT
+	bool "Start verstage in bootblock"
+	default y
+	select VBOOT_STARTS_IN_BOOTBLOCK
+	select VBOOT_SEPARATE_VERSTAGE
+	help
+	  Broadwell can either start verstage in a separate stage
+	  right after the bootblock has run or it can start it
+	  after romstage for compatibility reasons.
+	  Broadwell however uses a mrc.bin to initialse memory which
+	  needs to be located at a fixed offset. Therefore even with
+	  a separate verstage starting after the bootblock that same
+	  binary is used meaning a jump is made from RW to the RO region
+	  and back to the RW region after the binary is done.
+
 config VBOOT
 	select VBOOT_MUST_REQUEST_DISPLAY
-	select VBOOT_STARTS_IN_ROMSTAGE
+	select VBOOT_STARTS_IN_ROMSTAGE if !BROADWELL_VBOOT_IN_BOOTBLOCK
 
 config MMCONF_BASE_ADDRESS
 	hex
@@ -141,6 +157,13 @@
 	hex
 	default 0xfffa0000
 
+# The UEFI System Agent binary needs to be at a fixed offset in the flash
+# and can therefore only reside in the COREBOOT fmap region
+config RO_REGION_ONLY
+	string
+	depends on VBOOT
+	default "mrc.bin"
+
 endif # HAVE_MRC
 
 config PRE_GRAPHICS_DELAY
diff --git a/src/soc/intel/broadwell/Makefile.inc b/src/soc/intel/broadwell/Makefile.inc
index eab8b37..40017eb 100644
--- a/src/soc/intel/broadwell/Makefile.inc
+++ b/src/soc/intel/broadwell/Makefile.inc
@@ -49,6 +49,7 @@
 ramstage-y += pmutil.c
 romstage-y += pmutil.c
 smm-y      += pmutil.c
+verstage-y += pmutil.c
 ramstage-y += ramstage.c
 ramstage-$(CONFIG_HAVE_REFCODE_BLOB) += refcode.c
 ramstage-y += sata.c
@@ -70,6 +71,7 @@
 romstage-y += tsc_freq.c
 smm-y      += tsc_freq.c
 postcar-y  += tsc_freq.c
+verstage-y += tsc_freq.c
 bootblock-$(CONFIG_USBDEBUG) += usb_debug.c
 romstage-$(CONFIG_USBDEBUG) += usb_debug.c
 ramstage-$(CONFIG_USBDEBUG) += usb_debug.c
diff --git a/src/soc/intel/broadwell/romstage/raminit.c b/src/soc/intel/broadwell/romstage/raminit.c
index 8d43907..fc8b7c6 100644
--- a/src/soc/intel/broadwell/romstage/raminit.c
+++ b/src/soc/intel/broadwell/romstage/raminit.c
@@ -45,6 +45,8 @@
 	struct memory_info *mem_info;
 	pei_wrapper_entry_t entry;
 	int ret;
+	struct cbfsf f;
+	uint32_t type = CBFS_TYPE_MRC;
 
 	broadwell_fill_pei_data(pei_data);
 
@@ -77,7 +79,10 @@
 	}
 
 	/* Determine if mrc.bin is in the cbfs. */
-	entry = cbfs_boot_map_with_leak("mrc.bin", CBFS_TYPE_MRC, NULL);
+	if (cbfs_locate_file_in_region(&f, "COREBOOT", "mrc.bin", &type) < 0)
+		die("mrc.bin not found!");
+	/* We don't care about leaking the mapping */
+	entry = (pei_wrapper_entry_t)rdev_mmap_full(&f.data);
 	if (entry == NULL) {
 		printk(BIOS_DEBUG, "Couldn't find mrc.bin\n");
 		return;