soc/amd/picasso: Add console & timestamp buffers to psp_verstage

Create areas for console & timestamp data in psp_verstage and pass it to
the x86 to save for use later.

BUG=b:159220781
TEST=Build & Boot trembyle

Signed-off-by: Martin Roth <martin@coreboot.org>
Change-Id: I41c8d7a1565e761187e941d7d6021805a9744d06
Reviewed-on: https://review.coreboot.org/c/coreboot/+/42830
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
diff --git a/src/include/symbols.h b/src/include/symbols.h
index 57c52ee..fe3f46a 100644
--- a/src/include/symbols.h
+++ b/src/include/symbols.h
@@ -60,6 +60,7 @@
 DECLARE_REGION(pdpt)
 DECLARE_REGION(opensbi)
 DECLARE_REGION(bl31)
+DECLARE_REGION(transfer_buffer)
 
 /*
  * Put this into a .c file accessing a linker script region to mark that region
diff --git a/src/soc/amd/picasso/include/soc/psp_transfer.h b/src/soc/amd/picasso/include/soc/psp_transfer.h
new file mode 100644
index 0000000..6a43b55
--- /dev/null
+++ b/src/soc/amd/picasso/include/soc/psp_transfer.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef PSP_VERSTAGE_PSP_TRANSFER_H
+#define PSP_VERSTAGE_PSP_TRANSFER_H
+
+#define TRANSFER_INFO_SIZE		64
+#define TIMESTAMP_BUFFER_SIZE		0x200
+
+#define TRANSFER_MAGIC_VAL		0x50544953
+
+/* Area for things that would cause errors in a linker script */
+#if !defined(__ASSEMBLER__)
+#include <stdint.h>
+
+struct transfer_info_struct {
+	uint32_t	magic_val;		/* Identifier */
+	uint32_t	struct_bytes;		/* Size of this structure */
+	uint32_t	buffer_size;		/* Size of the transfer buffer area */
+
+	/* Offsets from start of transfer buffer */
+	uint32_t	workbuf_offset;
+	uint32_t	console_offset;
+	uint32_t	timestamp_offset;
+	uint32_t	fmap_offset;
+	uint32_t	unused[9];		/* Pad to 64 bytes */
+};
+
+_Static_assert(sizeof(struct transfer_info_struct) == TRANSFER_INFO_SIZE, \
+		"TRANSFER_INFO_SIZE is incorrect");
+#endif
+
+#endif	/* PSP_VERSTAGE_PSP_TRANSFER_H */
diff --git a/src/soc/amd/picasso/memlayout_psp_verstage.ld b/src/soc/amd/picasso/memlayout_psp_verstage.ld
index 0fed7b0..4ad88b1 100644
--- a/src/soc/amd/picasso/memlayout_psp_verstage.ld
+++ b/src/soc/amd/picasso/memlayout_psp_verstage.ld
@@ -1,6 +1,8 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 
 #include <memlayout.h>
+#include <soc/psp_transfer.h>
+#include <fmap_config.h>
 
 /*
  * Start of available space is 0x15000 and this is where the
@@ -11,8 +13,6 @@
 #define PSP_SRAM_SIZE			160K
 
 #define VERSTAGE_START			0x15000
-#define VBOOT_WORK_SIZE			12K
-#define FMAP_CACHE_SIZE			2K
 
 /*
  * The temp stack can be made much smaller if needed - even 256 bytes
@@ -52,9 +52,15 @@
 	_everstage = .;
 
 	ALIGN_COUNTER(64)
-	REGION(vboot2_work, ., VBOOT_WORK_SIZE, 64)
-
+	_transfer_buffer = .;
+	REGION(transfer_info, ., TRANSFER_INFO_SIZE, 4)
+	ALIGN_COUNTER(64)
+	REGION(vboot2_work, ., VB2_FIRMWARE_WORKBUF_RECOMMENDED_SIZE, 64)
+	ALIGN_COUNTER(64)
+	PRERAM_CBMEM_CONSOLE(., CONFIG_PRERAM_CBMEM_CONSOLE_SIZE)
+	TIMESTAMP(., TIMESTAMP_BUFFER_SIZE)
 	FMAP_CACHE(., FMAP_SIZE)
+	_etransfer_buffer = .;
 
 	PSP_VERSTAGE_TEMP_STACK_END = (PSP_VERSTAGE_TEMP_STACK_START + PSP_VERSTAGE_TEMP_STACK_SIZE );
 
diff --git a/src/soc/amd/picasso/memlayout_x86.ld b/src/soc/amd/picasso/memlayout_x86.ld
index 6f43ba1..7930793 100644
--- a/src/soc/amd/picasso/memlayout_x86.ld
+++ b/src/soc/amd/picasso/memlayout_x86.ld
@@ -2,6 +2,7 @@
 
 #include <memlayout.h>
 #include <arch/header.ld>
+#include <soc/psp_transfer.h>
 
 #define EARLY_RESERVED_DRAM_START(addr)		SYMBOL(early_reserved_dram, addr)
 #define EARLY_RESERVED_DRAM_END(addr)		SYMBOL(eearly_reserved_dram, addr)
@@ -38,14 +39,16 @@
  *                     |          Unused hole           |
  *                     +--------------------------------+
  *                     |     FMAP cache (FMAP_SIZE)     |
- *                     +--------------------------------+ PSP_SHAREDMEM_BASE + PSP_SHAREDMEM_SIZE + PRERAM_CBMEM_CONSOLE_SIZE + 0x200
+ *                     +--------------------------------+ PSP_SHAREDMEM_BASE + 0x40 + PSP_SHAREDMEM_SIZE + PRERAM_CBMEM_CONSOLE_SIZE + 0x200
  *                     |  Early Timestamp region (512B) |
- *                     +--------------------------------+ PSP_SHAREDMEM_BASE + PSP_SHAREDMEM_SIZE + PRERAM_CBMEM_CONSOLE_SIZE
+ *                     +--------------------------------+ PSP_SHAREDMEM_BASE + 0x40 + PSP_SHAREDMEM_SIZE + PRERAM_CBMEM_CONSOLE_SIZE
  *                     |      Preram CBMEM console      |
  *                     |   (PRERAM_CBMEM_CONSOLE_SIZE)  |
- *                     +--------------------------------+ PSP_SHAREDMEM_BASE + PSP_SHAREDMEM_SIZE
+ *                     +--------------------------------+ PSP_SHAREDMEM_BASE + 0x40 + PSP_SHAREDMEM_SIZE
  *                     |   PSP shared (vboot workbuf)   |
  *                     |      (PSP_SHAREDMEM_SIZE)      |
+ *                     +--------------------------------+ PSP_SHAREDMEM_BASE + 0x40
+ *                     |     Transfer Info Structure    |
  *                     +--------------------------------+ PSP_SHAREDMEM_BASE
  *                     |          APOB (64KiB)          |
  *                     +--------------------------------+ PSP_APOB_DRAM_ADDRESS
@@ -72,14 +75,18 @@
 
 #if CONFIG(VBOOT)
 	PSP_SHAREDMEM_DRAM_START(CONFIG_PSP_SHAREDMEM_BASE)
+	_transfer_buffer = .;
+	REGION(transfer_info, ., TRANSFER_INFO_SIZE, 4)
 	VBOOT2_WORK(., VB2_FIRMWARE_WORKBUF_RECOMMENDED_SIZE)
 	PSP_SHAREDMEM_DRAM_END(CONFIG_PSP_SHAREDMEM_BASE + CONFIG_PSP_SHAREDMEM_SIZE)
 #endif
 
 	PRERAM_CBMEM_CONSOLE(., CONFIG_PRERAM_CBMEM_CONSOLE_SIZE)
-	TIMESTAMP(., 0x200)
+	TIMESTAMP(., TIMESTAMP_BUFFER_SIZE)
 	FMAP_CACHE(., FMAP_SIZE)
-
+#if CONFIG(VBOOT)
+	_etransfer_buffer = .;
+#endif
 	_ = ASSERT((CONFIG_BOOTBLOCK_ADDR + CONFIG_C_ENV_BOOTBLOCK_SIZE - 0x10) == CONFIG_X86_RESET_VECTOR, "Reset vector should be -0x10 from end of bootblock");
 	_ = ASSERT(CONFIG_BOOTBLOCK_ADDR == ((CONFIG_BOOTBLOCK_ADDR + 0xFFFF) & 0xFFFF0000), "Bootblock must be 16 bit aligned");
 	BOOTBLOCK(CONFIG_BOOTBLOCK_ADDR, CONFIG_C_ENV_BOOTBLOCK_SIZE)
diff --git a/src/soc/amd/picasso/psp_verstage/psp_verstage.c b/src/soc/amd/picasso/psp_verstage/psp_verstage.c
index 2524651..5568797 100644
--- a/src/soc/amd/picasso/psp_verstage/psp_verstage.c
+++ b/src/soc/amd/picasso/psp_verstage/psp_verstage.c
@@ -8,6 +8,7 @@
 #include <commonlib/region.h>
 #include <console/console.h>
 #include <fmap.h>
+#include <soc/psp_transfer.h>
 #include <security/vboot/misc.h>
 #include <security/vboot/symbols.h>
 #include <security/vboot/vboot_common.h>
@@ -120,8 +121,9 @@
 static uint32_t save_buffers(struct vb2_context **ctx)
 {
 	uint32_t retval;
-	uint32_t buffer_size = DEFAULT_WORKBUF_TRANSFER_SIZE;
+	uint32_t buffer_size = MIN_TRANSFER_BUFFER_SIZE;
 	uint32_t max_buffer_size;
+	struct transfer_info_struct buffer_info = {0};
 
 	/*
 	 * This should never fail, but if it does, we should still try to
@@ -130,28 +132,47 @@
 	if (svc_get_max_workbuf_size(&max_buffer_size)) {
 		post_code(POSTCODE_DEFAULT_BUFFER_SIZE_NOTICE);
 		printk(BIOS_NOTICE, "Notice: using default transfer buffer size.\n");
-		max_buffer_size = DEFAULT_WORKBUF_TRANSFER_SIZE;
+		max_buffer_size = MIN_TRANSFER_BUFFER_SIZE;
 	}
 	printk(BIOS_DEBUG, "\nMaximum buffer size: %d bytes\n", max_buffer_size);
 
-	retval = vb2api_relocate(_vboot2_work, _vboot2_work, buffer_size, ctx);
-	if (retval != VB2_SUCCESS) {
-		printk(BIOS_ERR, "Error shrinking workbuf. Error code %#x\n", retval);
-		buffer_size = VB2_FIRMWARE_WORKBUF_RECOMMENDED_SIZE;
-		post_code(POSTCODE_WORKBUF_RESIZE_WARNING);
+	/* Shrink workbuf if MP2 is in use and cannot be used to save buffer */
+	if (max_buffer_size < VB2_FIRMWARE_WORKBUF_RECOMMENDED_SIZE) {
+		retval = vb2api_relocate(_vboot2_work, _vboot2_work, MIN_WORKBUF_TRANSFER_SIZE,
+				ctx);
+		if (retval != VB2_SUCCESS) {
+			printk(BIOS_ERR, "Error shrinking workbuf. Error code %#x\n", retval);
+			buffer_size = VB2_FIRMWARE_WORKBUF_RECOMMENDED_SIZE;
+			post_code(POSTCODE_WORKBUF_RESIZE_WARNING);
+		}
+	} else {
+		buffer_size =
+			(uint32_t)((uintptr_t)_etransfer_buffer - (uintptr_t)_transfer_buffer);
+
+		buffer_info.console_offset = (uint32_t)((uintptr_t)_preram_cbmem_console -
+					(uintptr_t)_transfer_buffer);
+		buffer_info.timestamp_offset = (uint32_t)((uintptr_t)_timestamp -
+					(uintptr_t)_transfer_buffer);
+		buffer_info.fmap_offset = (uint32_t)((uintptr_t)_fmap_cache -
+					(uintptr_t)_transfer_buffer);
 	}
 
 	if (buffer_size > max_buffer_size) {
-		printk(BIOS_ERR, "Error: Workbuf is larger than max buffer size.\n");
+		printk(BIOS_ERR, "Error: Buffer is larger than max buffer size.\n");
 		post_code(POSTCODE_WORKBUF_BUFFER_SIZE_ERROR);
 		return POSTCODE_WORKBUF_BUFFER_SIZE_ERROR;
 	}
 
-	retval = svc_save_uapp_data(UAPP_COPYBUF_CHROME_WORKBUF, (void *)_vboot2_work,
-			buffer_size);
+	buffer_info.magic_val = TRANSFER_MAGIC_VAL;
+	buffer_info.struct_bytes = sizeof(buffer_info);
+	buffer_info.buffer_size = buffer_size;
+	buffer_info.workbuf_offset = (uint32_t)((uintptr_t)_fmap_cache -
+					(uintptr_t)_vboot2_work);
+
+	retval = svc_save_uapp_data(UAPP_COPYBUF_CHROME_WORKBUF, (void *)_transfer_buffer,
+				    buffer_size);
 	if (retval) {
-		printk(BIOS_ERR, "Error: Could not save workbuf. Error code 0x%08x\n",
-				retval);
+		printk(BIOS_ERR, "Error: Could not save workbuf. Error code 0x%08x\n", retval);
 		return POSTCODE_WORKBUF_SAVE_ERROR;
 	}
 
@@ -193,6 +214,9 @@
 
 	verstage_main();
 
+	vb2api_relocate(_vboot2_work, _vboot2_work, VB2_FIRMWARE_WORKBUF_RECOMMENDED_SIZE,
+			&ctx);
+
 	post_code(POSTCODE_SAVE_BUFFERS);
 	retval = save_buffers(&ctx);
 	if (retval)
diff --git a/src/soc/amd/picasso/psp_verstage/psp_verstage.h b/src/soc/amd/picasso/psp_verstage/psp_verstage.h
index ad422fc..3c7574d 100644
--- a/src/soc/amd/picasso/psp_verstage/psp_verstage.h
+++ b/src/soc/amd/picasso/psp_verstage/psp_verstage.h
@@ -4,6 +4,7 @@
 #define PSP_VERSTAGE_H
 
 #include <stdint.h>
+#include <soc/psp_transfer.h>
 
 #define EMBEDDED_FW_SIGNATURE			0x55aa55aa
 #define PSP_COOKIE				0x50535024	/* 'PSP$' */
@@ -36,7 +37,8 @@
 #define POSTCODE_LEAVING_VERSTAGE		0xF2
 
 #define SPI_ADDR_MASK				0x00ffffff
-#define DEFAULT_WORKBUF_TRANSFER_SIZE		(8 * KiB)
+#define MIN_TRANSFER_BUFFER_SIZE		(8 * KiB)
+#define MIN_WORKBUF_TRANSFER_SIZE		(MIN_TRANSFER_BUFFER_SIZE - TRANSFER_INFO_SIZE)
 
 struct psp_ef_table {
 	uint32_t signature; /* 0x55aa55aa */