[PATCH] fpga zynq: Check the bitstream for validity

Michal Simek michal.simek at xilinx.com
Thu Oct 27 00:42:03 PDT 2016


On 27.10.2016 00:54, Jason Gunthorpe wrote:
> There is no sense in sending a bitstream we know will not work, and
> with the variety of options for bitstream generation in Xilinx tools
> it is not terribly clear or very well documented what the correct
> input should be, especially since auto-detection was removed from this
> driver.
> 
> All Zynq full configuration bitstreams must start with the sync word in
> the correct byte order.
> 
> Zynq is also only able to DMA dword quantities, so bitstreams must be
> a multiple of 4 bytes. This also fixes a DMA-past the end bug.
> 
> Signed-off-by: Jason Gunthorpe <jgunthorpe at obsidianresearch.com>
> ---
>  drivers/fpga/zynq-fpga.c | 25 ++++++++++++++++---------
>  1 file changed, 16 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/fpga/zynq-fpga.c b/drivers/fpga/zynq-fpga.c
> index c2fb4120bd62..46a38772e7ee 100644
> --- a/drivers/fpga/zynq-fpga.c
> +++ b/drivers/fpga/zynq-fpga.c
> @@ -184,12 +184,26 @@ static int zynq_fpga_ops_write_init(struct fpga_manager *mgr, u32 flags,
>  
>  	priv = mgr->priv;
>  
> +	/* All valid bitstreams are multiples of 32 bits */
> +	if ((count % 4) != 0)
> +		return -EINVAL;
> +
>  	err = clk_enable(priv->clk);
>  	if (err)
>  		return err;
>  
>  	/* don't globally reset PL if we're doing partial reconfig */
>  	if (!(flags & FPGA_MGR_PARTIAL_RECONFIG)) {
> +		/* Sanity check the proposed bitstream. It must start with the
> +		 * sync word in the correct byte order and be a multiple of 4
> +		 * bytes.
> +		 */
> +		if (count <= 4 || buf[0] != 0x66 || buf[1] != 0x55 ||
> +		    buf[2] != 0x99 || buf[3] != 0xaa) {
> +			err = -EINVAL;
> +			goto out_err;
> +		}

I am not quite sure about this and I didn't try it on real hw.
But minimum bitstream size 52+B and more likely much more than this.

This is taken from u-boot source code and this is full BIN header.
The code above is checking only the last word.

#define DUMMY_WORD      0xffffffff

/* Xilinx binary format header */
static const u32 bin_format[] = {
        DUMMY_WORD, /* Dummy words */
        DUMMY_WORD,
        DUMMY_WORD,
        DUMMY_WORD,
        DUMMY_WORD,
        DUMMY_WORD,
        DUMMY_WORD,
        DUMMY_WORD,
        0x000000bb, /* Sync word */
        0x11220044, /* Sync word */
        DUMMY_WORD,
        DUMMY_WORD,
        0xaa995566, /* Sync word */
};

Thanks,
Michal



More information about the linux-arm-kernel mailing list