jtagonizer

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

debug.c (2589B)


      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 <unistd.h>
     18 #include <string.h>
     19 
     20 #include "jtag.h"
     21 
     22 static JTAG *jtag;
     23 
     24 // Communicate with a simple JTAG debug register interface:
     25 //
     26 // 35  31                             0
     27 // |   |                              |
     28 // WAAADDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
     29 //
     30 // On DRUPDATE, if W=1, write data (D) to register address (A)
     31 //              if W=0, read from register address (A), ignore data (D)
     32 // On DRCAPTURE, set D to data from last read operation
     33 //
     34 // See an implementation for xilinx 7-series here:
     35 // https://github.com/swetland/zynq-sandbox/blob/master/hdl/jtag_debug_port.sv
     36 
     37 void jconnect(void) {
     38 	if (jtag_mpsse_open(&jtag)) goto fail;
     39 	if (jtag_enumerate(jtag) < 0) goto fail;
     40 	if (jtag_select_by_family(jtag, "Xilinx 7")) goto fail;
     41 	return;
     42 fail:
     43 	fprintf(stderr, "debug: cannot connect to fpga via jtag\n");
     44 	exit(1);
     45 }
     46 
     47 u32 jrd(u32 addr) {
     48 	u32 n = 0x23;
     49 	u64 u = 0;
     50 	jtag_ir_wr(jtag, 6, &n);
     51 	n = addr & 7;
     52 	jtag_dr_wr(jtag, 4, &n);
     53 	jtag_dr_rd(jtag, 36, &u);
     54 	jtag_commit(jtag);
     55 	return (u32) u;
     56 }
     57 
     58 void jwr(u32 addr, u32 val) {
     59 	u32 n = 0x23;
     60 	u64 u = ((u64)val) | (((u64) (addr & 7)) << 32) | 0x800000000ULL;
     61 	jtag_ir_wr(jtag, 6, &n);
     62 	jtag_dr_wr(jtag, 36, &u);
     63 	jtag_commit(jtag);
     64 }
     65 
     66 int main(int argc, char **argv) {
     67 	if (argc == 3) {
     68 		u32 addr = strtoul(argv[1], 0, 0);
     69 		u32 val = strtoul(argv[2], 0, 0);
     70 		jconnect();
     71 		jwr(addr, val);
     72 		return 0;
     73 	} else if (argc == 2) {
     74 		u32 addr = strtoul(argv[1], 0, 0);
     75 		u32 val;
     76 		jconnect();
     77 		if (!strcmp(argv[1],"dump")) {
     78 			int n, off;
     79 			for (off = 0, n = 0; n < 4096; n++, off++) {
     80 				unsigned x = jrd(1);
     81 				if (x & 0x100) {
     82 					off = -1;
     83 					continue;
     84 				}
     85 				if ((off & 15) == 0) printf("\n%08x", off);
     86 				printf(" %02x", x);
     87 			}
     88 			printf("\n");
     89 			return 0;
     90 		}
     91  		val = jrd(addr);
     92 		printf("%08x\n", val);
     93 		return 0;
     94 	} else {
     95 		fprintf(stderr,
     96 			"usage:\n"
     97 			"  write:  debug <addr> <val>\n"
     98 			"   read:  debug <addr>\n");
     99 		return -1;
    100 	}
    101 }