jtagonizer

yet another JTAG tool
git clone http://frotz.net/git/jtagonizer.git
Log | Files | Refs | README

fpga.c (6194B)


      1 // Copyright 2014 Brian Swetland <swetland@frotz.net>
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 // http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 #include <stdio.h>
     16 #include <stdlib.h>
     17 #include <string.h>
     18 
     19 #include <unistd.h>
     20 #include <fcntl.h>
     21 
     22 #include "jtag.h"
     23 
     24 // See: UG470 Xilinx 7 Series FPGAs Configuration
     25 
     26 // 7-Series JTAG IR
     27 #define IR_LEN		6
     28 #define IR_CFG_OUT	4
     29 #define IR_CFG_IN	5
     30 #define IR_JSHUTDOWN	13
     31 
     32 // Config Packet Headers
     33 #define CFG_DUMMY	0xFFFFFFFF
     34 #define CFG_SYNC	0xAA995566
     35 #define CFG_NOP		0x20000000
     36 #define CFG_RD(addr,n)	(0x28000000 | ((addr)<<13) | (n))
     37 #define CFG_WR(addr,n)	(0x30000000 | ((addr)<<13) | (n))
     38 
     39 // Config Registers
     40 #define CR_CRC		0
     41 #define CR_FAR		1
     42 #define CR_FDRI		2
     43 #define CR_FDRO		3
     44 #define CR_CMD		4
     45 #define CR_CTL0		5
     46 #define CR_MASK		6
     47 #define CR_STAT		7
     48 #define CR_LOUT		8
     49 #define CR_COR0		9
     50 #define CR_MFWR		10
     51 #define CR_CBC		11
     52 #define CR_IDCODE	12
     53 #define CR_AXSS		13
     54 #define CR_COR1		14
     55 #define CR_WBSTAR	16
     56 #define CR_TIMER	17
     57 #define CR_BOOTSTS	22
     58 #define CR_CTL1		24
     59 
     60 // CR_CMD commands
     61 #define CMD_NULL	0
     62 #define CMD_WCFG	1
     63 #define CMD_MFW		2
     64 #define CMD_LFRM	3
     65 #define CMD_RCFG	4
     66 #define CMD_START	5
     67 #define CMD_RCAP	6
     68 #define CMD_RCRC	7
     69 #define CMD_AGHIGH	8
     70 #define CMD_SWITCH	9
     71 #define CMD_GRESTORE	10
     72 #define CMD_SHUTDOWN	11
     73 #define CMD_GCAPTURE	12
     74 #define CMD_DESYNC	13
     75 #define CMD_IPROG	15
     76 #define CMD_CRCC	16
     77 #define CMD_LTIMER	17
     78 
     79 // CR_STAT bits
     80 #define STAT_DEC_ERROR		(1 << 16)
     81 #define STAT_ID_ERROR		(1 << 15)
     82 #define STAT_DONE		(1 << 14)
     83 #define STAT_RELEASE_DONE	(1 << 13)
     84 #define STAT_INIT_B		(1 << 12)
     85 #define STAT_INIT_COMPLETE	(1 << 11)
     86 #define STAT_GHIGH_B		(1 << 7)
     87 #define STAT_GWE		(1 << 6)
     88 #define STAT_GTS_CFG_B		(1 << 5)	// 0 = IOs are HIGH-Z
     89 #define STAT_EOS		(1 << 4)	// EndOfStartup 
     90 #define STAT_DCI_MATCH		(1 << 3)
     91 #define STAT_MMCM_LOCK		(1 << 2)	// all used MMCMs have locked
     92 #define STAT_PART_SECURED	(1 << 1)
     93 #define STAT_CRC_ERROR		(1 << 0)
     94 
     95 #define STAT_STATE(n)	(((n) >> 18) & 7)
     96 #define STAT_MODE(n)	(((n) >> 8) & 7)
     97 
     98 #if 0
     99 static void *loadfile(const char *fn, u32 *sz) {
    100 	int fd;
    101 	off_t end;
    102 	void *data = NULL;
    103 	if ((fd = open(fn, O_RDONLY)) < 0) return NULL;
    104 	if ((end = lseek(fd, 0, SEEK_END)) < 0) goto oops;
    105 	if (lseek(fd, 0, SEEK_SET) < 0) goto oops;
    106 	if ((data = malloc(end + 4)) == NULL) goto oops;
    107 	if (read(fd, data, end) != end) goto oops;
    108 	close(fd);
    109 	*sz = end;
    110 	return data;
    111 
    112 oops:
    113 	free(data);
    114 	close(fd);
    115 	return NULL;
    116 }
    117 #endif
    118 
    119 static u8 bitrev(u8 x) {
    120 	x = (x << 4) | (x >> 4);
    121 	x = ((x << 2) & 0xcc) | ((x >> 2) & 0x33);
    122 	x = ((x << 1) & 0xaa) | ((x >> 1) & 0x55);
    123 	return x;
    124 }
    125 
    126 static void swizzle(u32 *_data, int count) {
    127 	u8 *data = (void*) _data;
    128 	u8 a, b, c, d;
    129 	while (count-- > 0) {
    130 		a = data[0];
    131 		b = data[1];
    132 		c = data[2];
    133 		d = data[3];
    134 		data[0] = bitrev(d);
    135 		data[1] = bitrev(c);
    136 		data[2] = bitrev(b);
    137 		data[3] = bitrev(a);
    138 		data += 4;
    139 	}
    140 }
    141 
    142 static int txn(JTAG *jtag, u32 *send, int scount, u32 *recv, int rcount) {
    143 	u32 n;
    144 
    145 	swizzle(send, scount);
    146 
    147 	jtag_goto(jtag, JTAG_RESET);
    148 	n = IR_CFG_IN;
    149 	jtag_ir_wr(jtag, IR_LEN, &n);
    150 	jtag_dr_wr(jtag, 32 * scount, send);
    151 	if (rcount) {
    152 		n = IR_CFG_OUT;
    153 		jtag_ir_wr(jtag, IR_LEN, &n);
    154 		jtag_dr_rd(jtag, 32 * rcount, recv);
    155 		jtag_goto(jtag, JTAG_RESET);
    156 	}
    157 
    158 	if (jtag_commit(jtag)) {
    159 		return -1;
    160 	} else {
    161 		swizzle(recv, rcount);
    162 		return 0;
    163 	}
    164 }
    165 
    166 static int fpga_rd_status(JTAG *jtag, u32 *status) {
    167 	u32 tx[5];
    168 	tx[0] = CFG_SYNC;
    169 	tx[1] = CFG_NOP;
    170 	tx[2] = CFG_RD(CR_STAT, 1);
    171 	tx[3] = CFG_NOP;
    172 	tx[4] = CFG_NOP;
    173 	return txn(jtag, tx, 5, status, 1);
    174 }
    175 
    176 static int fpga_warm_boot(JTAG *jtag) {
    177 	u32 tx[8];
    178 
    179 	tx[0] = CFG_SYNC;
    180 	tx[1] = CFG_NOP;
    181 	tx[2] = CFG_WR(CR_CMD, 1);
    182 	tx[3] = CMD_IPROG;
    183 	tx[4] = CFG_WR(CR_FAR, 1);
    184 	tx[5] = 0;
    185 	tx[6] = CFG_NOP;
    186 	tx[7] = CFG_NOP;
    187 
    188 	return txn(jtag, tx, 8, NULL, 0);
    189 
    190 #if 0
    191 	n = IR_JSHUTDOWN;
    192 	jtag_ir_wr(jtag, IR_LEN, &n);
    193 	jtag_idle(jtag, 12);
    194 	return jtag_commit(jtag);
    195 #endif
    196 }
    197 
    198 int fpga_prepare_bitfile(u8 *data, u32 sz) {
    199 	u32 n;
    200 	for (n = 0; n < sz; n++) {
    201 		data[n] = bitrev(data[n]);
    202 	}
    203 	return 0;
    204 }
    205 
    206 int fpga_send_bitfile(JTAG *jtag, void *data, u32 sz, int warmboot) {
    207 	u32 n;
    208 
    209 	if (jtag_enumerate(jtag) < 0) return -1;
    210 	if (jtag_select_by_family(jtag, "Xilinx 7")) return -1;
    211 
    212 	n = 0;
    213 	if (fpga_rd_status(jtag, &n)) {
    214 		fprintf(stderr, "error: failed to read status\n");
    215 		return -1;
    216 	}
    217 	fprintf(stderr, "status: %08x S%d\n", n, STAT_STATE(n));
    218 	if (data == NULL) return 0;
    219 
    220 	if (warmboot) {
    221 		fpga_warm_boot(jtag);
    222 
    223 		//TODO: detect ready via status register
    224 		usleep(100000);
    225 
    226 		n = 0;
    227 		if (fpga_rd_status(jtag, &n)) {
    228 			fprintf(stderr, "error: failed to read status\n");
    229 			return -1;
    230 		}
    231 		fprintf(stderr, "status: %08x S%d\n", n, STAT_STATE(n));
    232 	}
    233 
    234 	fprintf(stderr, "fpga: downloading...\n");
    235 	jtag_goto(jtag, JTAG_RESET);
    236 	n = IR_CFG_IN;
    237 	jtag_ir_wr(jtag, IR_LEN, &n);
    238 	jtag_dr_wr(jtag, sz * 8, data);
    239 
    240 	if (jtag_commit(jtag)) return -1;
    241 
    242 	n = 0;
    243 	if (fpga_rd_status(jtag, &n)) {
    244 		fprintf(stderr, "failed to read status\n");
    245 		return -1;
    246 	}
    247 	if (n & STAT_CRC_ERROR) {
    248 		fprintf(stderr, "error: bitstream CRC error\n");
    249 		return -1;
    250 	}
    251 	if (n & STAT_ID_ERROR) {
    252 		fprintf(stderr, "error: bitstream part ID does not match\n");
    253 		return -1;
    254 	}
    255 	if (n & STAT_INIT_COMPLETE) {
    256 		fprintf(stderr, "fpga: init complete\n");
    257 		return 0;
    258 	}
    259 	return -1;
    260 }
    261 
    262 #if 0
    263 int main(int argc, char **argv) {
    264 	JTAG *jtag;
    265 	u8 *data = NULL;
    266 	u32 sz, n;
    267 
    268 	if (argc == 2) {
    269 		if ((data = loadfile(argv[1], &sz)) == NULL) {
    270 			fprintf(stderr, "error: cannot load '%s'\n", argv[1]);
    271 			return -1;
    272 		}
    273 		for (n = 0; n < sz; n++) {
    274 			data[n] = bitrev(data[n]);
    275 		}
    276 	}
    277 
    278 	if (jtag_mpsse_open(&jtag)) return -1;
    279 	if (jtag_enumerate(jtag) < 0) return -1;
    280 
    281 	return fpga_send_bitfile(jtag, data, sz);
    282 }
    283 #endif