diff options
Diffstat (limited to 'drivers/fpga/zynq-fpga.c')
-rw-r--r-- | drivers/fpga/zynq-fpga.c | 21 |
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) | |||
161 | return IRQ_HANDLED; | 161 | return IRQ_HANDLED; |
162 | } | 162 | } |
163 | 163 | ||
164 | /* Sanity check the proposed bitstream. It must start with the sync word in | ||
165 | * the correct byte order, and be dword aligned. The input is a Xilinx .bin | ||
166 | * file with every 32 bit quantity swapped. | ||
167 | */ | ||
168 | static bool zynq_fpga_has_sync(const u8 *buf, size_t count) | ||
169 | { | ||
170 | for (; count >= 4; buf += 4, count -= 4) | ||
171 | if (buf[0] == 0x66 && buf[1] == 0x55 && buf[2] == 0x99 && | ||
172 | buf[3] == 0xaa) | ||
173 | return true; | ||
174 | return false; | ||
175 | } | ||
176 | |||
164 | static int zynq_fpga_ops_write_init(struct fpga_manager *mgr, | 177 | static int zynq_fpga_ops_write_init(struct fpga_manager *mgr, |
165 | struct fpga_image_info *info, | 178 | struct fpga_image_info *info, |
166 | const char *buf, size_t count) | 179 | const char *buf, size_t count) |
@@ -177,6 +190,13 @@ static int zynq_fpga_ops_write_init(struct fpga_manager *mgr, | |||
177 | 190 | ||
178 | /* don't globally reset PL if we're doing partial reconfig */ | 191 | /* don't globally reset PL if we're doing partial reconfig */ |
179 | if (!(info->flags & FPGA_MGR_PARTIAL_RECONFIG)) { | 192 | if (!(info->flags & FPGA_MGR_PARTIAL_RECONFIG)) { |
193 | if (!zynq_fpga_has_sync(buf, count)) { | ||
194 | dev_err(&mgr->dev, | ||
195 | "Invalid bitstream, could not find a sync word. Bitstream must be a byte swapped .bin file\n"); | ||
196 | err = -EINVAL; | ||
197 | goto out_err; | ||
198 | } | ||
199 | |||
180 | /* assert AXI interface resets */ | 200 | /* assert AXI interface resets */ |
181 | regmap_write(priv->slcr, SLCR_FPGA_RST_CTRL_OFFSET, | 201 | regmap_write(priv->slcr, SLCR_FPGA_RST_CTRL_OFFSET, |
182 | FPGA_RST_ALL_MASK); | 202 | FPGA_RST_ALL_MASK); |
@@ -410,6 +430,7 @@ static enum fpga_mgr_states zynq_fpga_ops_state(struct fpga_manager *mgr) | |||
410 | } | 430 | } |
411 | 431 | ||
412 | static const struct fpga_manager_ops zynq_fpga_ops = { | 432 | static const struct fpga_manager_ops zynq_fpga_ops = { |
433 | .initial_header_size = 128, | ||
413 | .state = zynq_fpga_ops_state, | 434 | .state = zynq_fpga_ops_state, |
414 | .write_init = zynq_fpga_ops_write_init, | 435 | .write_init = zynq_fpga_ops_write_init, |
415 | .write = zynq_fpga_ops_write, | 436 | .write = zynq_fpga_ops_write, |