1 /* 2 * (C) Copyright 2015 - 2016, Xilinx, Inc, 3 * Michal Simek <michal.simek@xilinx.com> 4 * Siva Durga Prasad <siva.durga.paladugu@xilinx.com> 5 * 6 * SPDX-License-Identifier: GPL-2.0 7 */ 8 9 #include <console.h> 10 #include <common.h> 11 #include <zynqmppl.h> 12 #include <linux/sizes.h> 13 14 #define DUMMY_WORD 0xffffffff 15 16 /* Xilinx binary format header */ 17 static const u32 bin_format[] = { 18 DUMMY_WORD, /* Dummy words */ 19 DUMMY_WORD, 20 DUMMY_WORD, 21 DUMMY_WORD, 22 DUMMY_WORD, 23 DUMMY_WORD, 24 DUMMY_WORD, 25 DUMMY_WORD, 26 DUMMY_WORD, 27 DUMMY_WORD, 28 DUMMY_WORD, 29 DUMMY_WORD, 30 DUMMY_WORD, 31 DUMMY_WORD, 32 DUMMY_WORD, 33 DUMMY_WORD, 34 0x000000bb, /* Sync word */ 35 0x11220044, /* Sync word */ 36 DUMMY_WORD, 37 DUMMY_WORD, 38 0xaa995566, /* Sync word */ 39 }; 40 41 #define SWAP_NO 1 42 #define SWAP_DONE 2 43 44 /* 45 * Load the whole word from unaligned buffer 46 * Keep in your mind that it is byte loading on little-endian system 47 */ 48 static u32 load_word(const void *buf, u32 swap) 49 { 50 u32 word = 0; 51 u8 *bitc = (u8 *)buf; 52 int p; 53 54 if (swap == SWAP_NO) { 55 for (p = 0; p < 4; p++) { 56 word <<= 8; 57 word |= bitc[p]; 58 } 59 } else { 60 for (p = 3; p >= 0; p--) { 61 word <<= 8; 62 word |= bitc[p]; 63 } 64 } 65 66 return word; 67 } 68 69 static u32 check_header(const void *buf) 70 { 71 u32 i, pattern; 72 int swap = SWAP_NO; 73 u32 *test = (u32 *)buf; 74 75 debug("%s: Let's check bitstream header\n", __func__); 76 77 /* Checking that passing bin is not a bitstream */ 78 for (i = 0; i < ARRAY_SIZE(bin_format); i++) { 79 pattern = load_word(&test[i], swap); 80 81 /* 82 * Bitstreams in binary format are swapped 83 * compare to regular bistream. 84 * Do not swap dummy word but if swap is done assume 85 * that parsing buffer is binary format 86 */ 87 if ((__swab32(pattern) != DUMMY_WORD) && 88 (__swab32(pattern) == bin_format[i])) { 89 swap = SWAP_DONE; 90 debug("%s: data swapped - let's swap\n", __func__); 91 } 92 93 debug("%s: %d/%px: pattern %x/%x bin_format\n", __func__, i, 94 &test[i], pattern, bin_format[i]); 95 } 96 debug("%s: Found bitstream header at %px %s swapinng\n", __func__, 97 buf, swap == SWAP_NO ? "without" : "with"); 98 99 return swap; 100 } 101 102 static void *check_data(u8 *buf, size_t bsize, u32 *swap) 103 { 104 u32 word, p = 0; /* possition */ 105 106 /* Because buf doesn't need to be aligned let's read it by chars */ 107 for (p = 0; p < bsize; p++) { 108 word = load_word(&buf[p], SWAP_NO); 109 debug("%s: word %x %x/%px\n", __func__, word, p, &buf[p]); 110 111 /* Find the first bitstream dummy word */ 112 if (word == DUMMY_WORD) { 113 debug("%s: Found dummy word at position %x/%px\n", 114 __func__, p, &buf[p]); 115 *swap = check_header(&buf[p]); 116 if (*swap) { 117 /* FIXME add full bitstream checking here */ 118 return &buf[p]; 119 } 120 } 121 /* Loop can be huge - support CTRL + C */ 122 if (ctrlc()) 123 return NULL; 124 } 125 return NULL; 126 } 127 128 static ulong zynqmp_align_dma_buffer(u32 *buf, u32 len, u32 swap) 129 { 130 u32 *new_buf; 131 u32 i; 132 133 if ((ulong)buf != ALIGN((ulong)buf, ARCH_DMA_MINALIGN)) { 134 new_buf = (u32 *)ALIGN((ulong)buf, ARCH_DMA_MINALIGN); 135 136 /* 137 * This might be dangerous but permits to flash if 138 * ARCH_DMA_MINALIGN is greater than header size 139 */ 140 if (new_buf > (u32 *)buf) { 141 debug("%s: Aligned buffer is after buffer start\n", 142 __func__); 143 new_buf -= ARCH_DMA_MINALIGN; 144 } 145 printf("%s: Align buffer at %px to %px(swap %d)\n", __func__, 146 buf, new_buf, swap); 147 148 for (i = 0; i < (len/4); i++) 149 new_buf[i] = load_word(&buf[i], swap); 150 151 buf = new_buf; 152 } else if (swap != SWAP_DONE) { 153 /* For bitstream which are aligned */ 154 u32 *new_buf = (u32 *)buf; 155 156 printf("%s: Bitstream is not swapped(%d) - swap it\n", __func__, 157 swap); 158 159 for (i = 0; i < (len/4); i++) 160 new_buf[i] = load_word(&buf[i], swap); 161 } 162 163 return (ulong)buf; 164 } 165 166 static int zynqmp_validate_bitstream(xilinx_desc *desc, const void *buf, 167 size_t bsize, u32 blocksize, u32 *swap) 168 { 169 ulong *buf_start; 170 ulong diff; 171 172 buf_start = check_data((u8 *)buf, blocksize, swap); 173 174 if (!buf_start) 175 return FPGA_FAIL; 176 177 /* Check if data is postpone from start */ 178 diff = (ulong)buf_start - (ulong)buf; 179 if (diff) { 180 printf("%s: Bitstream is not validated yet (diff %lx)\n", 181 __func__, diff); 182 return FPGA_FAIL; 183 } 184 185 if ((ulong)buf < SZ_1M) { 186 printf("%s: Bitstream has to be placed up to 1MB (%px)\n", 187 __func__, buf); 188 return FPGA_FAIL; 189 } 190 191 return 0; 192 } 193 194 static int invoke_smc(ulong id, ulong reg0, ulong reg1, ulong reg2) 195 { 196 struct pt_regs regs; 197 regs.regs[0] = id; 198 regs.regs[1] = reg0; 199 regs.regs[2] = reg1; 200 regs.regs[3] = reg2; 201 202 smc_call(®s); 203 204 return regs.regs[0]; 205 } 206 207 static int zynqmp_load(xilinx_desc *desc, const void *buf, size_t bsize, 208 bitstream_type bstype) 209 { 210 u32 swap; 211 ulong bin_buf, flags; 212 int ret; 213 214 if (zynqmp_validate_bitstream(desc, buf, bsize, bsize, &swap)) 215 return FPGA_FAIL; 216 217 bin_buf = zynqmp_align_dma_buffer((u32 *)buf, bsize, swap); 218 219 debug("%s called!\n", __func__); 220 flush_dcache_range(bin_buf, bin_buf + bsize); 221 222 if (bsize % 4) 223 bsize = bsize / 4 + 1; 224 else 225 bsize = bsize / 4; 226 227 flags = (u32)bsize | ((u64)bstype << 32); 228 229 ret = invoke_smc(ZYNQMP_SIP_SVC_PM_FPGA_LOAD, bin_buf, flags, 0); 230 if (ret) 231 debug("PL FPGA LOAD fail\n"); 232 233 return ret; 234 } 235 236 struct xilinx_fpga_op zynqmp_op = { 237 .load = zynqmp_load, 238 }; 239