drivers/intel/fsp2_0: Add FSP 2.3 support

FSP 2.3 specification introduces following changes:

1. FSP_INFO_HEADER changes
   Updated SpecVersion from 0x22 to 0x23
   Updated HeaderRevision from 5 to 6
   Added ExtendedImageRevision
   FSP_INFO_HEADER length changed to 0x50

2. Added FSP_NON_VOLATILE_STORAGE_HOB2

Following changes are implemented in the patch to support FSP 2.3:

- Add Kconfig option
- Update FSP build binary version info based on ExtendedImageRevision
  field in header
- New NV HOB related changes will be pushed as part of another patch

Signed-off-by: Anil Kumar <anil.kumar.k@intel.com>
Change-Id: Ica1bd004286c785aa8a431f39d8efc69982874c1
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59324
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Werner Zeh <werner.zeh@siemens.com>
Reviewed-by: Subrata Banik <subratabanik@google.com>
diff --git a/src/drivers/intel/fsp2_0/Kconfig b/src/drivers/intel/fsp2_0/Kconfig
index a0e02a8..716e809 100644
--- a/src/drivers/intel/fsp2_0/Kconfig
+++ b/src/drivers/intel/fsp2_0/Kconfig
@@ -29,6 +29,16 @@
 	  3. Added EnableMultiPhaseSiliconInit, bootloaders designed for FSP2.0/2.1 can disable
 	      the FspMultiPhaseSiInit() API and continue to use FspSiliconInit() without change.
 
+config PLATFORM_USES_FSP2_3
+	bool
+	default n
+	select PLATFORM_USES_FSP2_2
+	help
+	  Include FSP 2.3 wrappers and functionality.
+	  Features added into FSP 2.3 specification that impact coreboot are:
+	  1. Added ExtendedImageRevision field in FSP_INFO_HEADER
+	  2. Added FSP_NON_VOLATILE_STORAGE_HOB2
+
 if PLATFORM_USES_FSP2_0
 
 config PLATFORM_USES_FSP2_X86_32
diff --git a/src/drivers/intel/fsp2_0/header_display.c b/src/drivers/intel/fsp2_0/header_display.c
index 4f93666..4c8085e 100644
--- a/src/drivers/intel/fsp2_0/header_display.c
+++ b/src/drivers/intel/fsp2_0/header_display.c
@@ -6,16 +6,22 @@
 void fsp_print_header_info(const struct fsp_header *hdr)
 {
 	union fsp_revision revision;
+	union extended_fsp_revision ext_revision;
+	ext_revision.val = 0;
+
+	/* For FSP 2.3 and later use extended image revision field present in header
+	 * for build number and revision calculation */
+	if (CONFIG(PLATFORM_USES_FSP2_3))
+		ext_revision.val = hdr->extended_fsp_revision;
 
 	revision.val = hdr->fsp_revision;
-
 	printk(BIOS_SPEW, "Spec version: v%u.%u\n", (hdr->spec_version >> 4),
 						     hdr->spec_version & 0xf);
 	printk(BIOS_SPEW, "Revision: %u.%u.%u, Build Number %u\n",
-							revision.rev.major,
-							revision.rev.minor,
-							revision.rev.revision,
-							revision.rev.bld_num);
+			revision.rev.major,
+			revision.rev.minor,
+			((ext_revision.rev.revision << 8) | revision.rev.revision),
+			((ext_revision.rev.bld_num << 8) | revision.rev.bld_num));
 	printk(BIOS_SPEW, "Type: %s/%s\n",
 			(hdr->component_attribute & 1) ? "release" : "debug",
 			(hdr->component_attribute & 2) ? "official" : "test");
diff --git a/src/drivers/intel/fsp2_0/include/fsp/info_header.h b/src/drivers/intel/fsp2_0/include/fsp/info_header.h
index 5b6318c..136fc2b 100644
--- a/src/drivers/intel/fsp2_0/include/fsp/info_header.h
+++ b/src/drivers/intel/fsp2_0/include/fsp/info_header.h
@@ -14,6 +14,7 @@
 #if CONFIG(PLATFORM_USES_FSP2_X86_32)
 struct fsp_header {
 	uint32_t fsp_revision;
+	uint16_t extended_fsp_revision;
 	uint32_t image_size;
 	uint32_t image_base;
 	uint16_t image_attribute;
diff --git a/src/drivers/intel/fsp2_0/include/fsp/util.h b/src/drivers/intel/fsp2_0/include/fsp/util.h
index d05b644..7347034 100644
--- a/src/drivers/intel/fsp2_0/include/fsp/util.h
+++ b/src/drivers/intel/fsp2_0/include/fsp/util.h
@@ -60,6 +60,14 @@
 	} rev;
 };
 
+union extended_fsp_revision {
+	uint16_t val;
+	struct {
+		uint8_t bld_num;
+		uint8_t revision;
+	} rev;
+};
+
 #if CONFIG_UDK_VERSION < CONFIG_UDK_2017_VERSION
 enum resource_type {
 	EFI_RESOURCE_SYSTEM_MEMORY		= 0,
diff --git a/src/drivers/intel/fsp2_0/util.c b/src/drivers/intel/fsp2_0/util.c
index 49934fe..ff79fc7 100644
--- a/src/drivers/intel/fsp2_0/util.c
+++ b/src/drivers/intel/fsp2_0/util.c
@@ -14,7 +14,9 @@
 
 static uint32_t fsp_hdr_get_expected_min_length(void)
 {
-	if (CONFIG(PLATFORM_USES_FSP2_2))
+	if (CONFIG(PLATFORM_USES_FSP2_3))
+		return 80;
+	else if (CONFIG(PLATFORM_USES_FSP2_2))
 		return 76;
 	else if (CONFIG(PLATFORM_USES_FSP2_1))
 		return 72;
@@ -70,6 +72,8 @@
 	hdr->silicon_init_entry_offset = read32(raw_hdr + 68);
 	if (CONFIG(PLATFORM_USES_FSP2_2))
 		hdr->multi_phase_si_init_entry_offset = read32(raw_hdr + 72);
+	if (CONFIG(PLATFORM_USES_FSP2_3))
+		hdr->extended_fsp_revision = read16(raw_hdr + 76);
 
 	return CB_SUCCESS;
 }