lib/coreboot_table: Add Intel FSP version to coreboot table

Add a new LB_TAG_PLATFORM_BLOB_VERSION for FSP version, it would
add Intel FSP version to coreboot table LB_TAG_PLATFORM_BLOB_VERSION
when PLATFORM_USES_FSP2_0 is selected.

Tested=On OCP Delta Lake, with an updated LinuxBoot payload cbmem utility
can see "LB_TAG_PLATFORM_BLOB_VERSION": "2.1-0.0.1.120"

Change-Id: I92a13ca91b9f66a7517cfd6784f3f692ff34e765
Signed-off-by: Johnny Lin <johnny_lin@wiwynn.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/41809
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Nico Huber <nico.h@gmx.de>
Reviewed-by: Christian Walter <christian.walter@9elements.com>
Reviewed-by: Philipp Deppenwiese <zaolin.daisuki@gmail.com>
diff --git a/src/commonlib/include/commonlib/coreboot_tables.h b/src/commonlib/include/commonlib/coreboot_tables.h
index 3627996..b7e59ad 100644
--- a/src/commonlib/include/commonlib/coreboot_tables.h
+++ b/src/commonlib/include/commonlib/coreboot_tables.h
@@ -79,6 +79,7 @@
 	LB_TAG_MMC_INFO			= 0x0035,
 	LB_TAG_TCPA_LOG			= 0x0036,
 	LB_TAG_FMAP			= 0x0037,
+	LB_TAG_PLATFORM_BLOB_VERSION	= 0x0038,
 	LB_TAG_CMOS_OPTION_TABLE	= 0x00c8,
 	LB_TAG_OPTION			= 0x00c9,
 	LB_TAG_OPTION_ENUM		= 0x00ca,
diff --git a/src/drivers/intel/fsp2_0/include/fsp/util.h b/src/drivers/intel/fsp2_0/include/fsp/util.h
index ad6a4b5..f154a34 100644
--- a/src/drivers/intel/fsp2_0/include/fsp/util.h
+++ b/src/drivers/intel/fsp2_0/include/fsp/util.h
@@ -12,6 +12,8 @@
 #include <program_loading.h>
 #include <types.h>
 
+#define FSP_VER_LEN	30
+
 struct hob_header {
 	uint16_t type;
 	uint16_t length;
@@ -85,7 +87,8 @@
 const struct hob_header *fsp_next_hob(const struct hob_header *parent);
 bool fsp_guid_compare(const uint8_t guid1[16], const uint8_t guid2[16]);
 void fsp_find_bootloader_tolum(struct range_entry *re);
-
+void fsp_get_version(char *buf);
+void lb_string_platform_blob_version(struct lb_header *header);
 
 /* Fill in header and validate sanity of component within region device. */
 enum cb_err fsp_validate_component(struct fsp_header *hdr,
diff --git a/src/drivers/intel/fsp2_0/util.c b/src/drivers/intel/fsp2_0/util.c
index e8c5876..cfa83d7 100644
--- a/src/drivers/intel/fsp2_0/util.c
+++ b/src/drivers/intel/fsp2_0/util.c
@@ -1,5 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-or-later */
 
+#include <boot/coreboot_tables.h>
 #include <device/mmio.h>
 #include <cbfs.h>
 #include <cf9_reset.h>
@@ -208,3 +209,38 @@
 
 	return CB_SUCCESS;
 }
+
+/* Only call this function when FSP header has been read and validated */
+void fsp_get_version(char *buf)
+{
+	struct fsp_header *hdr = &fsps_hdr;
+	union {
+		uint32_t val;
+		struct {
+			uint8_t bld_num;
+			uint8_t revision;
+			uint8_t minor;
+			uint8_t major;
+		} rev;
+	} revision;
+
+	revision.val = hdr->fsp_revision;
+	snprintf(buf, FSP_VER_LEN, "%u.%u-%u.%u.%u.%u", (hdr->spec_version >> 4),
+		hdr->spec_version & 0xf, revision.rev.major,
+		revision.rev.minor, revision.rev.revision, revision.rev.bld_num);
+}
+
+/* Add FSP version to coreboot table LB_TAG_PLATFORM_BLOB_VERSION */
+void lb_string_platform_blob_version(struct lb_header *header)
+{
+	struct lb_string *rec;
+	size_t len;
+	char fsp_version[FSP_VER_LEN] = {0};
+
+	fsp_get_version(fsp_version);
+	rec = (struct lb_string *)lb_new_record(header);
+	rec->tag = LB_TAG_PLATFORM_BLOB_VERSION;
+	len = strlen(fsp_version);
+	rec->size = ALIGN_UP(sizeof(*rec) + len + 1, 8);
+	memcpy(rec->string, fsp_version, len+1);
+}
diff --git a/src/lib/coreboot_table.c b/src/lib/coreboot_table.c
index 12282fc..9148405 100644
--- a/src/lib/coreboot_table.c
+++ b/src/lib/coreboot_table.c
@@ -30,6 +30,11 @@
 #include <vendorcode/google/chromeos/chromeos.h>
 #include <vendorcode/google/chromeos/gnvs.h>
 #endif
+#if CONFIG(PLATFORM_USES_FSP2_0)
+#include <fsp/util.h>
+#else
+void lb_string_platform_blob_version(struct lb_header *header);
+#endif
 
 static struct lb_header *lb_table_init(unsigned long addr)
 {
@@ -515,6 +520,8 @@
 
 	/* Record our various random string information */
 	lb_strings(head);
+	if (CONFIG(PLATFORM_USES_FSP2_0))
+		lb_string_platform_blob_version(head);
 	lb_record_version_timestamp(head);
 	/* Record our framebuffer */
 	lb_framebuffer(head);