fpga: zynqmp: support loading authenticated images

Add supporting new compatible string "u-boot,zynqmp-fpga-ddrauth" to
handle loading authenticated images (DDR).

Based on solution by Jorge Ramirez-Ortiz <jorge@foundries.io>

Signed-off-by: Oleksandr Suvorov <oleksandr.suvorov@foundries.io>
Tested-by: Ricardo Salveti <ricardo@foundries.io>
Link: https://lore.kernel.org/r/20220722141614.297383-13-oleksandr.suvorov@foundries.io
Signed-off-by: Michal Simek <michal.simek@amd.com>
This commit is contained in:
Oleksandr Suvorov 2022-07-22 17:16:13 +03:00 committed by Michal Simek
parent 5ab6a84634
commit a3a1afb747
5 changed files with 39 additions and 8 deletions

View file

@ -210,8 +210,8 @@ config SPL_LOAD_FIT
1. "loadables" images, other than FDTs, which do not have a "load" 1. "loadables" images, other than FDTs, which do not have a "load"
property will not be loaded. This limitation also applies to FPGA property will not be loaded. This limitation also applies to FPGA
images with the correct "compatible" string. images with the correct "compatible" string.
2. For FPGA images, only the "compatible" = "u-boot,fpga-legacy" 2. For FPGA images, the supported "compatible" list is in the
loading method is supported. doc/uImage.FIT/source_file_format.txt.
3. FDTs are only loaded for images with an "os" property of "u-boot". 3. FDTs are only loaded for images with an "os" property of "u-boot".
"linux" images are also supported with Falcon boot mode. "linux" images are also supported with Falcon boot mode.

View file

@ -184,7 +184,10 @@ the '/images' node should have the following layout:
Mandatory for types: "firmware", and "kernel". Mandatory for types: "firmware", and "kernel".
- compatible : compatible method for loading image. - compatible : compatible method for loading image.
Mandatory for types: "fpga", and images that do not specify a load address. Mandatory for types: "fpga", and images that do not specify a load address.
To use the generic fpga loading routine, use "u-boot,fpga-legacy". Supported compatible methods:
"u-boot,fpga-legacy" - the generic fpga loading routine.
"u-boot,zynqmp-fpga-ddrauth" - signed non-encrypted FPGA bitstream for
Xilinx Zynq UltraScale+ (ZymqMP) device.
Optional nodes: Optional nodes:
- hash-1 : Each hash sub-node represents separate hash or checksum - hash-1 : Each hash sub-node represents separate hash or checksum

View file

@ -9,6 +9,7 @@
#include <common.h> #include <common.h>
#include <compiler.h> #include <compiler.h>
#include <cpu_func.h> #include <cpu_func.h>
#include <fpga.h>
#include <log.h> #include <log.h>
#include <zynqmppl.h> #include <zynqmppl.h>
#include <zynqmp_firmware.h> #include <zynqmp_firmware.h>
@ -202,9 +203,12 @@ static int zynqmp_validate_bitstream(xilinx_desc *desc, const void *buf,
#if CONFIG_IS_ENABLED(FPGA_LOAD_SECURE) #if CONFIG_IS_ENABLED(FPGA_LOAD_SECURE)
static int zynqmp_check_compatible(xilinx_desc *desc, int flags) static int zynqmp_check_compatible(xilinx_desc *desc, int flags)
{ {
/* If no flags set, the image is legacy */ /*
* If no flags set, the image may be legacy, but we need to
* signal caller this situation with specific error code.
*/
if (!flags) if (!flags)
return 0; return -ENODATA;
/* For legacy bitstream images no need for other methods exist */ /* For legacy bitstream images no need for other methods exist */
if ((flags & desc->flags) && flags == FPGA_LEGACY) if ((flags & desc->flags) && flags == FPGA_LEGACY)
@ -217,7 +221,7 @@ static int zynqmp_check_compatible(xilinx_desc *desc, int flags)
if (desc->operations->loads && (flags & desc->flags)) if (desc->operations->loads && (flags & desc->flags))
return 0; return 0;
return FPGA_FAIL; return -ENODEV;
} }
#endif #endif
@ -231,8 +235,9 @@ static int zynqmp_load(xilinx_desc *desc, const void *buf, size_t bsize,
u32 buf_lo, buf_hi; u32 buf_lo, buf_hi;
u32 bsize_req = (u32)bsize; u32 bsize_req = (u32)bsize;
u32 ret_payload[PAYLOAD_ARG_CNT]; u32 ret_payload[PAYLOAD_ARG_CNT];
#if CONFIG_IS_ENABLED(FPGA_LOAD_SECURE) #if CONFIG_IS_ENABLED(FPGA_LOAD_SECURE)
struct fpga_secure_info info = { 0 };
ret = zynqmp_check_compatible(desc, flags); ret = zynqmp_check_compatible(desc, flags);
if (ret) { if (ret) {
if (ret != -ENODATA) { if (ret != -ENODATA) {
@ -242,6 +247,21 @@ static int zynqmp_load(xilinx_desc *desc, const void *buf, size_t bsize,
/* If flags is not set, the image treats as legacy */ /* If flags is not set, the image treats as legacy */
flags = FPGA_LEGACY; flags = FPGA_LEGACY;
} }
switch (flags) {
case FPGA_LEGACY:
break; /* Handle the legacy image later in this function */
#if CONFIG_IS_ENABLED(FPGA_LOAD_SECURE)
case FPGA_XILINX_ZYNQMP_DDRAUTH:
/* DDR authentication */
info.authflag = ZYNQMP_FPGA_AUTH_DDR;
info.encflag = FPGA_NO_ENC_OR_NO_AUTH;
return desc->operations->loads(desc, buf, bsize, &info);
#endif
default:
printf("Unsupported bitstream type %d\n", flags);
return FPGA_FAIL;
}
#endif #endif
if (zynqmp_firmware_version() <= PMUFW_V1_0) { if (zynqmp_firmware_version() <= PMUFW_V1_0) {
@ -337,7 +357,10 @@ static int __maybe_unused zynqmp_str2flag(xilinx_desc *desc, const char *str)
{ {
if (!strncmp(str, "u-boot,fpga-legacy", 18)) if (!strncmp(str, "u-boot,fpga-legacy", 18))
return FPGA_LEGACY; return FPGA_LEGACY;
#if CONFIG_IS_ENABLED(FPGA_LOAD_SECURE)
if (!strncmp(str, "u-boot,zynqmp-fpga-ddrauth", 26))
return FPGA_XILINX_ZYNQMP_DDRAUTH;
#endif
return 0; return 0;
} }

View file

@ -39,6 +39,7 @@ typedef enum { /* typedef xilinx_family */
/* FPGA bitstream supported types */ /* FPGA bitstream supported types */
#define FPGA_LEGACY BIT(0) #define FPGA_LEGACY BIT(0)
#define FPGA_XILINX_ZYNQMP_DDRAUTH BIT(1)
typedef struct { /* typedef xilinx_desc */ typedef struct { /* typedef xilinx_desc */
xilinx_family family; /* part type */ xilinx_family family; /* part type */

View file

@ -25,6 +25,10 @@
extern struct xilinx_fpga_op zynqmp_op; extern struct xilinx_fpga_op zynqmp_op;
#if CONFIG_IS_ENABLED(FPGA_LOAD_SECURE)
#define ZYNQMP_FPGA_FLAGS (FPGA_LEGACY | FPGA_XILINX_ZYNQMP_DDRAUTH)
#else
#define ZYNQMP_FPGA_FLAGS (FPGA_LEGACY) #define ZYNQMP_FPGA_FLAGS (FPGA_LEGACY)
#endif
#endif /* _ZYNQMPPL_H_ */ #endif /* _ZYNQMPPL_H_ */