summaryrefslogtreecommitdiff
path: root/drivers/fpga
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/fpga')
-rw-r--r--drivers/fpga/zynq-fpga.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/drivers/fpga/zynq-fpga.c b/drivers/fpga/zynq-fpga.c
index f674e32832ec..c3fc2a231e28 100644
--- a/drivers/fpga/zynq-fpga.c
+++ b/drivers/fpga/zynq-fpga.c
@@ -161,6 +161,19 @@ static irqreturn_t zynq_fpga_isr(int irq, void *data)
return IRQ_HANDLED;
}
+/* Sanity check the proposed bitstream. It must start with the sync word in
+ * the correct byte order, and be dword aligned. The input is a Xilinx .bin
+ * file with every 32 bit quantity swapped.
+ */
+static bool zynq_fpga_has_sync(const u8 *buf, size_t count)
+{
+ for (; count >= 4; buf += 4, count -= 4)
+ if (buf[0] == 0x66 && buf[1] == 0x55 && buf[2] == 0x99 &&
+ buf[3] == 0xaa)
+ return true;
+ return false;
+}
+
static int zynq_fpga_ops_write_init(struct fpga_manager *mgr,
struct fpga_image_info *info,
const char *buf, size_t count)
@@ -177,6 +190,13 @@ static int zynq_fpga_ops_write_init(struct fpga_manager *mgr,
/* don't globally reset PL if we're doing partial reconfig */
if (!(info->flags & FPGA_MGR_PARTIAL_RECONFIG)) {
+ if (!zynq_fpga_has_sync(buf, count)) {
+ dev_err(&mgr->dev,
+ "Invalid bitstream, could not find a sync word. Bitstream must be a byte swapped .bin file\n");
+ err = -EINVAL;
+ goto out_err;
+ }
+
/* assert AXI interface resets */
regmap_write(priv->slcr, SLCR_FPGA_RST_CTRL_OFFSET,
FPGA_RST_ALL_MASK);
@@ -410,6 +430,7 @@ static enum fpga_mgr_states zynq_fpga_ops_state(struct fpga_manager *mgr)
}
static const struct fpga_manager_ops zynq_fpga_ops = {
+ .initial_header_size = 128,
.state = zynq_fpga_ops_state,
.write_init = zynq_fpga_ops_write_init,
.write = zynq_fpga_ops_write,