jtag-mpsse

JTAG tools for FTDI MPSSE transports
git clone http://frotz.net/git/jtag-mpsse.git
Log | Files | Refs

mem.c (3781B)


      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 
     16 #include <stdio.h>
     17 #include <stdlib.h>
     18 #include <unistd.h>
     19 #include <string.h>
     20 #include <fcntl.h>
     21 #include <errno.h>
     22 
     23 #include "jtag.h"
     24 #include "zynq.h"
     25 
     26 static JTAG *jtag;
     27 
     28 void jconnect(void) {
     29 	if (!(jtag = jtag_open())) {
     30 		fprintf(stderr, "jconnect: cannot open usb jtag ifc\n");
     31 		exit(-1);
     32 	}
     33 	if (jtag_enumerate(jtag) <= 0) {
     34 		fprintf(stderr, "jconnect: cannot enumerate jtag devices\n");
     35 		exit(-1);
     36 	}
     37 	if (jtag_select(jtag, 0x13722093)) {
     38 		fprintf(stderr, "jconnect: cannot connect to ZYNQ\n");
     39 		exit(-1);
     40 	}
     41 
     42 	jtag_ir_wr(jtag, XIL_USER4);
     43 }
     44 
     45 u32 jrd(u32 addr) {
     46 	u64 u;
     47 	jtag_dr_io(jtag, 4, addr & 7, &u);
     48 	jtag_dr_io(jtag, 36, 0, &u);
     49 	return (u32) u;
     50 }
     51 
     52 void jwr(u32 addr, u32 val) {
     53 	u64 u = ((u64)val) | (((u64) (addr & 7)) << 32) | 0x800000000ULL;
     54 	jtag_dr_io(jtag, 36, u, &u);
     55 }
     56 
     57 #define DBG_IDCODE		     0x4158494d
     58 
     59 #define DBG_R_IDCODE                 0
     60 #define DBG_R_GETDATA                1
     61 #define DBG_R_GETADDR                2
     62 #define DBG_R_STATUS                 7
     63 
     64 #define DBG_W_SETADDR_READ           1
     65 #define DBG_W_SETADDR                2
     66 #define DBG_W_SETDATA_WRITE          3
     67 #define DBG_W_SETDATA_INCADDR_WRITE  4
     68 
     69 void mem_connect(void) {
     70 	jconnect();
     71 	if (jrd(0) != DBG_IDCODE) {
     72 		fprintf(stderr,"axi master not detected\n");
     73 		exit(-1);
     74 	}
     75 }
     76 
     77 int main(int argc, char **argv) {
     78 	if ((argc == 4) && (!strcmp(argv[1],"-download"))) {
     79 		u32 addr = strtoul(argv[2], 0, 0);
     80 		int fd = 0;
     81 		int r;
     82 		u32 n;
     83 		if (strcmp(argv[3], "-")) {
     84 			fd = open(argv[3], O_RDONLY);
     85 			if (fd < 0) {
     86 				fprintf(stderr,"cannot open '%s'\n",argv[3]);
     87 				return -1;
     88 			}
     89 		}
     90 		mem_connect();
     91 		jwr(DBG_W_SETADDR, addr-4);
     92 		for (;;) {
     93 			r = read(fd, &n, sizeof(n));
     94 			if (r < 0) {
     95 				if (errno == EINTR)
     96 					continue;
     97 				break;
     98 			}
     99 			if (r < 1)
    100 				break;
    101 			//fprintf(stderr,"%08x\n",n);
    102 			jwr(DBG_W_SETDATA_INCADDR_WRITE, n);
    103 			usleep(5000);
    104 			//jwr(DBG_W_SETADDR, addr);
    105 			//jwr(DBG_W_SETDATA_WRITE, n);
    106 			//addr += 4;
    107 		}
    108 		close(fd);
    109 		return 0;
    110 	}
    111 	if ((argc == 5) && (!strcmp(argv[1],"-upload"))) {
    112 		u32 addr = strtoul(argv[2], 0, 0);
    113 		u32 count = strtoul(argv[3], 0, 0) / 4;
    114 		int fd = 1;
    115 		if (strcmp(argv[4], "-")) {
    116 			fd = open(argv[4], O_WRONLY|O_CREAT|O_TRUNC, 0640);
    117 			if (fd < 0) {
    118 				fprintf(stderr,"cannot open '%s'\n",argv[4]);
    119 				return -1;
    120 			}
    121 		}
    122 		mem_connect();
    123 		while (count > 0) {
    124 			jwr(DBG_W_SETADDR_READ, addr);
    125 			u32 n = jrd(DBG_R_GETDATA);
    126 			write(fd, &n, sizeof(n));
    127 			addr += 4;
    128 			count--;
    129 		}
    130 		close(fd);
    131 		return 0;
    132 	}
    133 	if (argc == 3) {
    134 		u32 addr = strtoul(argv[1], 0, 0);
    135 		u32 val = strtoul(argv[2], 0, 0);
    136 		if (argv[1][0] == '-') goto usage;
    137 		mem_connect();
    138 		jwr(DBG_W_SETADDR, addr);
    139 		jwr(DBG_W_SETDATA_WRITE, val);
    140 		return 0;
    141 	} else if (argc == 2) {
    142 		u32 addr = strtoul(argv[1], 0, 0);
    143 		u32 val;
    144 		if (argv[1][0] == '-') goto usage;
    145 		mem_connect();
    146 		jwr(DBG_W_SETADDR_READ, addr);
    147  		val = jrd(DBG_R_GETDATA);
    148 		printf("%08x\n", val);
    149 		return 0;
    150 	}
    151 
    152 usage:
    153 	fprintf(stderr,
    154 		"usage:\n"
    155 		"  write:  mem <addr> <val>\n"
    156 		"   read:  mem <addr>\n"
    157 		"  write:  mem -download <addr> <filename>\n"
    158 		"   read:  mem -upload <addr> <length> <filename>\n");
    159 		return -1;
    160 }