soc/amd/common/psp_verstage: Make SPI ROM mapping configurable

Earlier entire SPI ROM was mapped to memory. With limited TLB resources
in PSP, this approach hit the limit on systems using 32 MiB SPI ROM.
Therefore regions in SPI ROM were mapped on need basis. This works well
on Picasso, Mendocino and Phoenix SoCs. But unfortunately this causes
boot hangs in Cezanne SoC. Add a configuration to map the entire SPI ROM
and enable it in Cezanne SoC. For other SoCs, keep the configuration
disabled so that only the required SPI ROM region is mapped.

BUG=b:309690716
TEST=Build and boot to OS in both Dewatt and Skyrim.

Change-Id: I166ac7b50b367c067e1a743fc94686e69dd07844
Signed-off-by: Karthikeyan Ramasubramanian <kramasub@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/79155
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Matt DeVillier <matt.devillier@gmail.com>
Reviewed-by: Tim Van Patten <timvp@google.com>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
diff --git a/src/soc/amd/common/psp_verstage/Kconfig b/src/soc/amd/common/psp_verstage/Kconfig
index dc6ea1c..118ef61 100644
--- a/src/soc/amd/common/psp_verstage/Kconfig
+++ b/src/soc/amd/common/psp_verstage/Kconfig
@@ -43,3 +43,11 @@
 	help
 	  This configuration indicates whether the PSP Verstage stack is mapped to a virtual
 	  address space. This has been the case so far only in Picasso SoC.
+
+config PSP_VERSTAGE_MAP_ENTIRE_SPIROM
+	bool
+	default y if SOC_AMD_CEZANNE
+	default n
+	help
+	  This configuration indicates whether PSP Verstage needs to map the entire SPI ROM.
+	  This is required only in Cezanne SoC at the moment.
diff --git a/src/soc/amd/common/psp_verstage/boot_dev.c b/src/soc/amd/common/psp_verstage/boot_dev.c
index c129479..6ff1e2b 100644
--- a/src/soc/amd/common/psp_verstage/boot_dev.c
+++ b/src/soc/amd/common/psp_verstage/boot_dev.c
@@ -20,6 +20,8 @@
 	uint32_t ret;
 
 	mdev = container_of(rd, __typeof__(*mdev), rdev);
+	if (CONFIG(PSP_VERSTAGE_MAP_ENTIRE_SPIROM))
+		return &(mdev->base[offset]);
 
 	if (mdev->base) {
 		if ((ret = svc_map_spi_rom(&mdev->base[offset], size, (void **)&mapping))
@@ -37,6 +39,9 @@
 {
 	uint32_t ret;
 
+	if (CONFIG(PSP_VERSTAGE_MAP_ENTIRE_SPIROM))
+		return 0;
+
 	active_map_count--;
 	if ((ret = svc_unmap_spi_rom(mapping)) != BL_OK)
 		printk(BIOS_ERR, "Failed(%d) to unmap SPI ROM mapping %p\n", ret, mapping);
diff --git a/src/soc/amd/common/psp_verstage/fch.c b/src/soc/amd/common/psp_verstage/fch.c
index 0517545..5e46e68 100644
--- a/src/soc/amd/common/psp_verstage/fch.c
+++ b/src/soc/amd/common/psp_verstage/fch.c
@@ -97,6 +97,13 @@
 	if (svc_get_spi_rom_info(&spi))
 		printk(BIOS_DEBUG, "Error getting SPI ROM info.\n");
 
+	if (CONFIG(PSP_VERSTAGE_MAP_ENTIRE_SPIROM) && spi.SpiBiosSmnBase != 0) {
+		uintptr_t *addr = NULL;
+
+		if (svc_map_spi_rom(spi.SpiBiosSmnBase, CONFIG_ROM_SIZE, (void **)&addr))
+			printk(BIOS_DEBUG, "Error mapping SPI ROM to address.\n");
+		return addr;
+	}
 	return spi.SpiBiosSmnBase;
 }
 
diff --git a/src/soc/amd/common/psp_verstage/psp_verstage.c b/src/soc/amd/common/psp_verstage/psp_verstage.c
index 87d126f2..7d9ef35 100644
--- a/src/soc/amd/common/psp_verstage/psp_verstage.c
+++ b/src/soc/amd/common/psp_verstage/psp_verstage.c
@@ -235,6 +235,7 @@
 	uint32_t retval;
 	struct vb2_context *ctx = NULL;
 	uint32_t bootmode;
+	void *boot_dev_base;
 
 	/*
 	 * Do not use printk() before console_init()
@@ -350,7 +351,16 @@
 	if (retval)
 		reboot_into_recovery(ctx, retval);
 
+	if (CONFIG(PSP_VERSTAGE_MAP_ENTIRE_SPIROM)) {
+		post_code(POSTCODE_UNMAP_SPI_ROM);
+		boot_dev_base = rdev_mmap_full(boot_device_ro());
+		if (boot_dev_base) {
+			if (svc_unmap_spi_rom((void *)boot_dev_base))
+				printk(BIOS_ERR, "Error unmapping SPI rom\n");
+		}
+	}
 	assert(!boot_dev_get_active_map_count());
+
 	post_code(POSTCODE_UNMAP_FCH_DEVICES);
 	unmap_fch_devices();