soc/intel/apollolake: Measure bootblock from IFWI

On Apollo Lake the bootblock is stitched into the IBBL IFWI region at
build time. At execution time TXE loads this IBBL into a shared SRAM
(which is read-only in this phase) and maps it at 4 GiB - 32 KiB. Then
the CPU starts to operate from this shared SRAM as it were flash space.

In order to provide a reliable CRTM init, the real executed bootblock
code needs to be measured into TPM if VBOOT is selected. This patch adds
the needed code to do this.

Change-Id: Ifb3f798de638a85029ebfe0d1b65770029297db3
Signed-off-by: Werner Zeh <werner.zeh@siemens.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/64493
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
diff --git a/src/soc/intel/apollolake/bootblock/bootblock_measure.c b/src/soc/intel/apollolake/bootblock/bootblock_measure.c
index 16ba154..bd8e5b0 100644
--- a/src/soc/intel/apollolake/bootblock/bootblock_measure.c
+++ b/src/soc/intel/apollolake/bootblock/bootblock_measure.c
@@ -1,8 +1,54 @@
 /* SPDX-License-Identifier: GPL-2.0-or-later */
 
+#include <commonlib/region.h>
 #include <security/tpm/tspi/crtm.h>
+#include <soc/iomap.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <symbols.h>
 
+/* This region device covers the shared SRAM that gets mapped at bootblock runtime. */
+static const struct mem_region_device sram_rdev =
+		MEM_REGION_DEV_RO_INIT(SHARED_SRAM_BASE, SHARED_SRAM_SIZE);
+
+
+static const struct region_device *shared_sram_device(void)
+{
+	return &sram_rdev.rdev;
+}
+
+static const size_t shared_sram_base(void)
+{
+	return (size_t)(sram_rdev.base);
+}
+
+/*
+ * The linker symbol _program provides the beginning of the .text section in the bootblock.
+ * Use it to get the start address offset of the bootblock in the shared SRAM.
+ */
+static int ifwi_bootblock_locate_as_rdev(struct region_device *rdev)
+{
+	size_t offset = (size_t)(_program - shared_sram_base());
+	size_t size = (size_t)(0x100000000ULL - (uint32_t)_program);
+
+	return rdev_chain(rdev, shared_sram_device(), offset, size);
+}
+
+/*
+ * On Apollo Lake the bootblock is stitched into the IBBL IFWI region at
+ * build time. At execution time TXE loads this IBBL into a shared SRAM
+ * (which is read-only in this phase) and maps it at 4 GiB - 32 KiB.
+ * Then the CPU starts to operate from this shared SRAM as it were flash space.
+ * In order to provide a reliable CRTM init, the real executed bootblock
+ * code needs to be measured into TPM if VBOOT is selected.
+ */
 int tspi_soc_measure_bootblock(int pcr_index)
 {
-	return 1;
+	struct region_device ifwi_bootblock;
+
+	if (ifwi_bootblock_locate_as_rdev(&ifwi_bootblock))
+		return 1;
+	if (tpm_measure_region(&ifwi_bootblock, pcr_index, "IFWI: bootblock"))
+		return 1;
+	return 0;
 }
diff --git a/src/soc/intel/apollolake/include/soc/iomap.h b/src/soc/intel/apollolake/include/soc/iomap.h
index 209e1c2..5f1b014 100644
--- a/src/soc/intel/apollolake/include/soc/iomap.h
+++ b/src/soc/intel/apollolake/include/soc/iomap.h
@@ -31,6 +31,8 @@
 #define SRAM_SIZE_0			(8 * KiB)
 #define SRAM_BASE_2			0xfe902000
 #define SRAM_SIZE_2			(4 * KiB)
+#define SHARED_SRAM_BASE		0xfffe0000
+#define SHARED_SRAM_SIZE		(128 * KiB)
 
 #define HECI1_BASE_ADDRESS		0xfed1a000
 #define PSF3_BASE_ADDRESS		0x1e00