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 }