diff --git a/src/include/symbols.h b/src/include/symbols.h index 57c52eed53..fe3f46ab80 100644 --- a/src/include/symbols.h +++ b/src/include/symbols.h @@ -60,6 +60,7 @@ DECLARE_REGION(framebuffer) 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 0000000000..6a43b55a6c --- /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 + +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 0fed7b0e83..4ad88b1108 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 +#include +#include /* * 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 @@ SECTIONS _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 6f43ba18af..7930793275 100644 --- a/src/soc/amd/picasso/memlayout_x86.ld +++ b/src/soc/amd/picasso/memlayout_x86.ld @@ -2,6 +2,7 @@ #include #include +#include #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 @@ SECTIONS #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 2524651142..55687976df 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 #include #include +#include #include #include #include @@ -120,8 +121,9 @@ static uint32_t update_boot_region(struct vb2_context *ctx) 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 @@ static uint32_t save_buffers(struct vb2_context **ctx) 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 @@ void Main(void) 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 ad422fc825..3c7574d82b 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 +#include #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 */